2
* Copyright (c) 2005-2006 Douglas Gilbert.
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
* 3. The name of the author may not be used to endorse or promote products
14
* derived from this software without specific prior written permission.
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40
/* A utility program for the Linux OS SCSI subsystem.
43
* This program issues these SCSI commands: REPORT DEVICE IDENTIFIER,
44
* SET DEVICE IDENTIFIER and/or INQUIRY (VPD=0x83 [device identifier]).
47
static char * version_str = "1.02 20060623";
49
#define ME "sg_ident: "
51
#define REPORT_DEV_ID_SANITY_LEN 512
54
static struct option long_options[] = {
60
{"verbose", 0, 0, 'v'},
61
{"version", 0, 0, 'V'},
67
fprintf(stderr, "Usage: "
68
"sg_ident [--ascii] [--clear] [--help] [--raw] [--set] "
70
" [--version] <scsi_device>\n"
71
" where: --ascii|-A report device identifier as ASCII "
73
" --clear|-C clear (set to zero length) device "
75
" --help|-h print out usage message\n"
76
" --raw|-r output device identifier to stdout\n"
77
" fetch from stdin (when '--set')\n"
78
" --set|-S invoke set device identifier with data "
80
" --verbose|-v set device identifier\n"
81
" --version|-V print version string and exit\n\n"
82
"Performs a REPORT or SET DEVICE IDENTIFIER SCSI command\n"
86
int main(int argc, char * argv[])
88
int sg_fd, res, c, di_len, n;
89
unsigned char rdi_buff[REPORT_DEV_ID_SANITY_LEN + 4];
90
unsigned char * ucp = NULL;
96
char device_name[512];
99
memset(device_name, 0, sizeof device_name);
101
int option_index = 0;
103
c = getopt_long(argc, argv, "AChrSvV", long_options,
129
fprintf(stderr, ME "version: %s\n", version_str);
132
fprintf(stderr, "unrecognised switch code 0x%x ??\n", c);
134
return SG_LIB_SYNTAX_ERROR;
138
if ('\0' == device_name[0]) {
139
strncpy(device_name, argv[optind], sizeof(device_name) - 1);
140
device_name[sizeof(device_name) - 1] = '\0';
144
for (; optind < argc; ++optind)
145
fprintf(stderr, "Unexpected extra argument: %s\n",
148
return SG_LIB_SYNTAX_ERROR;
152
if (0 == device_name[0]) {
153
fprintf(stderr, "missing device name!\n");
155
return SG_LIB_SYNTAX_ERROR;
157
if (do_set && do_clear) {
158
fprintf(stderr, "only one of '--clear' and '--set' can be given\n");
160
return SG_LIB_SYNTAX_ERROR;
163
fprintf(stderr, "only one of '--ascii' and '--raw' can be given\n");
165
return SG_LIB_SYNTAX_ERROR;
167
if ((do_set || do_clear) && (raw || ascii)) {
168
fprintf(stderr, "'--set' cannot be used with either '--ascii' or "
171
return SG_LIB_SYNTAX_ERROR;
173
sg_fd = sg_cmds_open_device(device_name, 0 /* rw */, verbose);
175
fprintf(stderr, ME "open error: %s: %s\n", device_name,
176
safe_strerror(-sg_fd));
177
return SG_LIB_FILE_ERROR;
180
memset(rdi_buff, 0x0, sizeof(rdi_buff));
181
if (do_set || do_clear) {
183
res = fread(rdi_buff, 1, REPORT_DEV_ID_SANITY_LEN + 2, stdin);
185
fprintf(stderr, "no data read from stdin; to clear "
186
"identifier use '--clear' instead\n");
188
} else if (res > REPORT_DEV_ID_SANITY_LEN) {
189
fprintf(stderr, "SPC-3 limits identifier length to 512 "
194
res = sg_ll_set_dev_id(sg_fd, rdi_buff, di_len, 1, verbose);
195
} else /* do_clear */
196
res = sg_ll_set_dev_id(sg_fd, rdi_buff, 0, 1, verbose);
199
if (SG_LIB_CAT_NOT_READY == res)
200
fprintf(stderr, "Set Device Identifier command, device "
202
else if (SG_LIB_CAT_INVALID_OP == res)
203
fprintf(stderr, "Set Device Identifier command not "
205
else if (SG_LIB_CAT_UNIT_ATTENTION == res)
206
fprintf(stderr, "Set Device Identifier, unit attention\n");
207
else if (SG_LIB_CAT_ILLEGAL_REQ == res)
208
fprintf(stderr, "bad field in Set Device Identifier "
211
fprintf(stderr, "Set Device Identifier command failed\n");
213
fprintf(stderr, " try '-v' for more information\n");
216
} else { /* do report device identifier */
217
res = sg_ll_report_dev_id(sg_fd, rdi_buff, 4, 1, verbose);
219
di_len = (rdi_buff[0] << 24) + (rdi_buff[1] << 16) +
220
(rdi_buff[2] << 8) + rdi_buff[3];
222
printf("Reported device identifier length = %d\n", di_len);
224
fprintf(stderr, " This implies the device has an empty "
228
if (di_len > REPORT_DEV_ID_SANITY_LEN) {
229
fprintf(stderr, " That length (%d) seems too long for a "
230
"device identifier\n", di_len);
234
res = sg_ll_report_dev_id(sg_fd, ucp, di_len + 4, 1, verbose);
236
di_len = (ucp[0] << 24) + (ucp[1] << 16) + (ucp[2] << 8) +
240
n = fwrite(ucp + 4, 1, di_len, stdout);
242
printf("Device identifier:\n");
245
printf("%.*s\n", di_len, (const char *)ucp + 4);
247
dStrHex((const char *)ucp + 4, di_len, 0);
252
if (SG_LIB_CAT_NOT_READY == res)
253
fprintf(stderr, "Report Device Identifier command, "
254
"device not ready\n");
255
else if (SG_LIB_CAT_UNIT_ATTENTION == res)
256
fprintf(stderr, "Report Device Identifier, unit "
258
else if (SG_LIB_CAT_INVALID_OP == res)
259
fprintf(stderr, "Report Device Identifier command not "
261
else if (SG_LIB_CAT_ILLEGAL_REQ == res)
262
fprintf(stderr, "bad field in Report Device Identifier "
265
fprintf(stderr, "Report Device Identifier command "
268
fprintf(stderr, " try '-v' for more "
276
res = sg_cmds_close_device(sg_fd);
278
fprintf(stderr, "close error: %s\n", safe_strerror(-res));
280
return SG_LIB_FILE_ERROR;
282
return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;