forked from SanDisk-Open-Source/ufs-utils
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathufs_vendor.c
130 lines (111 loc) · 2.98 KB
/
ufs_vendor.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// SPDX-License-Identifier: GPL-2.0-or-later
/* Copyright (C) 2019 Western Digital Corporation or its affiliates */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <errno.h>
#include "ufs.h"
#include "ufs_cmds.h"
#include "options.h"
#include "options.h"
#include "scsi_bsg_util.h"
#include "ufs_vendor.h"
static int write_data(struct tool_options *opt, int dev_fd, void *p_data);
static int read_data(struct tool_options *opt, int dev_fd, void *p_data);
int do_vendor(struct tool_options *opt)
{
int rc = INVALID;
int fd;
void *p_data;
WRITE_LOG("Start : %s", __func__);
p_data = malloc(opt->len);
if (!p_data) {
print_error("Cannot allocate %d Bytes", opt->len);
return ERROR;
}
fd = open(opt->path, O_RDWR | O_SYNC);
if (fd < 0) {
perror("Device open");
goto out;
}
if (opt->opr == WRITE)
rc = write_data(opt, fd, p_data);
else
rc = read_data(opt, fd, p_data);
out:
free(p_data);
if (fd != INVALID)
close(fd);
return rc;
}
static int write_data(struct tool_options *opt, int dev_fd, void *p_data)
{
int input_fd;
int rc = INVALID;
off_t file_size;
char mode;
input_fd = open(opt->data, O_RDONLY | O_SYNC);
if (input_fd < 0) {
perror("Input file open");
return ERROR;
}
file_size = lseek(input_fd, 0, SEEK_END);
if ((file_size <= 0) || (file_size < opt->len)) {
print_error("Wrong input data file length = %d",
file_size);
goto out;
}
lseek(input_fd, 0, SEEK_SET);
if (read(input_fd, p_data, opt->len) != opt->len) {
print_error("Read %d data bytes from input file failed",
opt->len);
goto out;
}
if (opt->mode == INVALID)
mode = BUFFER_VENDOR_MODE;
else
mode = opt->mode;
rc = write_buffer(dev_fd, p_data, mode, opt->index,
opt->offset, opt->len, opt->sg_type);
if (!rc)
printf("The vendor buffer was written\n");
out:
close(input_fd);
return rc;
}
static int read_data(struct tool_options *opt, int dev_fd, void *p_data)
{
int rc = INVALID;
char mode;
if (opt->mode == INVALID)
mode = BUFFER_VENDOR_MODE;
else
mode = opt->mode;
rc = read_buffer(dev_fd, p_data, mode, opt->index,
opt->offset, opt->len, opt->sg_type);
if (!rc) {
write_file("read_vendor_buffer.dat", p_data, opt->len);
printf("read_vendor_buffer.dat created\n");
}
return rc;
}
void vendor_help(char *tool_name)
{
printf("\n Vendor Write/Read Buffer command usage:\n");
printf("\n\t%s vendor [-r ][-w] <path to data file> [-L] <data_len>\n"
"\t\t[-O] <buf offset> [-M] <mode> [-p] <path to device>\n",
tool_name);
printf("\n\t-r\tRead vendor buffer command[default operation]\n");
printf("\n\t-w\tInput file path for write buffer vendor command\n");
printf("\n\t-L\tData buffer length, up to 512 Bytes[default value 512B]\n");
printf("\n\t-i\tBuffer ID\n");
printf("\n\t-g\t sg struct ver - 0: SG_IO_VER3 (default), 1: SG_IO_VER4\n");
printf("\n\t-O\tBuffer Offset\n");
printf("\n\t-p\tDevice path\n");
}