4 * Code related to requesting and getting an id from a scsi device
6 * Copyright (C) IBM Corp. 2003
8 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as
10 * published by the Free Software Foundation; either version 2.1 of the
11 * License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24 #include <sys/types.h>
25 #include <sys/ioctl.h>
35 #include "../../udev.h"
38 #include "scsi_id_version.h"
41 * A priority based list of id, naa, and binary/ascii for the identifier
42 * descriptor in VPD page 0x83.
44 * Brute force search for a match starting with the first value in the
45 * following id_search_list. This is not a performance issue, since there
46 * is normally one or some small number of descriptors.
48 static const struct scsi_id_search_values id_search_list[] = {
49 { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG_EXTENDED, SCSI_ID_BINARY },
50 { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG_EXTENDED, SCSI_ID_ASCII },
51 { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG, SCSI_ID_BINARY },
52 { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG, SCSI_ID_ASCII },
54 * Devices already exist using NAA values that are now marked
55 * reserved. These should not conflict with other values, or it is
56 * a bug in the device. As long as we find the IEEE extended one
57 * first, we really don't care what other ones are used. Using
58 * don't care here means that a device that returns multiple
59 * non-IEEE descriptors in a random order will get different
62 { SCSI_ID_NAA, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY },
63 { SCSI_ID_NAA, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII },
64 { SCSI_ID_EUI_64, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY },
65 { SCSI_ID_EUI_64, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII },
66 { SCSI_ID_T10_VENDOR, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY },
67 { SCSI_ID_T10_VENDOR, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII },
68 { SCSI_ID_VENDOR_SPECIFIC, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY },
69 { SCSI_ID_VENDOR_SPECIFIC, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII },
72 static const char hex_str[]="0123456789abcdef";
75 * Values returned in the result/status, only the ones used by the code
79 #define DID_NO_CONNECT 0x01 /* Unable to connect before timeout */
80 #define DID_BUS_BUSY 0x02 /* Bus remain busy until timeout */
81 #define DID_TIME_OUT 0x03 /* Timed out for some other reason */
82 #define DRIVER_TIMEOUT 0x06
83 #define DRIVER_SENSE 0x08 /* Sense_buffer has been set */
85 /* The following "category" function returns one of the following */
86 #define SG_ERR_CAT_CLEAN 0 /* No errors or other information */
87 #define SG_ERR_CAT_MEDIA_CHANGED 1 /* interpreted from sense buffer */
88 #define SG_ERR_CAT_RESET 2 /* interpreted from sense buffer */
89 #define SG_ERR_CAT_TIMEOUT 3
90 #define SG_ERR_CAT_RECOVERED 4 /* Successful command after recovered err */
91 #define SG_ERR_CAT_NOTSUPPORTED 5 /* Illegal / unsupported command */
92 #define SG_ERR_CAT_SENSE 98 /* Something else in the sense buffer */
93 #define SG_ERR_CAT_OTHER 99 /* Some other error/warning */
95 static int sg_err_category_new(int scsi_status, int msg_status, int
96 host_status, int driver_status, const
97 unsigned char *sense_buffer, int sb_len)
102 * XXX change to return only two values - failed or OK.
108 if (!scsi_status && !msg_status && !host_status && !driver_status)
109 return SG_ERR_CAT_CLEAN;
111 if ((scsi_status == SCSI_CHECK_CONDITION) ||
112 (scsi_status == SCSI_COMMAND_TERMINATED) ||
113 ((driver_status & 0xf) == DRIVER_SENSE)) {
114 if (sense_buffer && (sb_len > 2)) {
118 if (sense_buffer[0] & 0x2) {
119 sense_key = sense_buffer[1] & 0xf;
120 asc = sense_buffer[2];
122 sense_key = sense_buffer[2] & 0xf;
123 asc = (sb_len > 12) ? sense_buffer[12] : 0;
126 if (sense_key == RECOVERED_ERROR)
127 return SG_ERR_CAT_RECOVERED;
128 else if (sense_key == UNIT_ATTENTION) {
130 return SG_ERR_CAT_MEDIA_CHANGED;
132 return SG_ERR_CAT_RESET;
133 } else if (sense_key == ILLEGAL_REQUEST) {
134 return SG_ERR_CAT_NOTSUPPORTED;
137 return SG_ERR_CAT_SENSE;
140 if ((host_status == DID_NO_CONNECT) ||
141 (host_status == DID_BUS_BUSY) ||
142 (host_status == DID_TIME_OUT))
143 return SG_ERR_CAT_TIMEOUT;
145 if (!driver_status) {
146 if (driver_status == DRIVER_TIMEOUT)
147 return SG_ERR_CAT_TIMEOUT;
149 return SG_ERR_CAT_OTHER;
152 static int sg_err_category3(struct sg_io_hdr *hp)
154 return sg_err_category_new(hp->status, hp->msg_status,
155 hp->host_status, hp->driver_status,
156 hp->sbp, hp->sb_len_wr);
159 static int scsi_dump_sense(struct sysfs_device *dev_scsi, struct sg_io_hdr *io)
161 unsigned char *sense_buffer;
167 int descriptor_format;
170 char out_buffer[256];
175 * Figure out and print the sense key, asc and ascq.
177 * If you want to suppress these for a particular drive model, add
178 * a black list entry in the scsi_id config file.
180 * XXX We probably need to: lookup the sense/asc/ascq in a retry
181 * table, and if found return 1 (after dumping the sense, asc, and
182 * ascq). So, if/when we get something like a power on/reset,
183 * we'll retry the command.
186 dbg("got check condition\n");
188 sb_len = io->sb_len_wr;
190 info("%s: sense buffer empty", dev_scsi->kernel_name);
194 sense_buffer = io->sbp;
195 sense_class = (sense_buffer[0] >> 4) & 0x07;
196 code = sense_buffer[0] & 0xf;
198 if (sense_class == 7) {
200 * extended sense data.
202 s = sense_buffer[7] + 8;
204 info("%s: sense buffer too small %d bytes, %d bytes too short",
205 dev_scsi->kernel_name, sb_len, s - sb_len);
208 if ((code == 0x0) || (code == 0x1)) {
209 descriptor_format = 0;
210 sense_key = sense_buffer[2] & 0xf;
215 info("%s: sense result too" " small %d bytes",
216 dev_scsi->kernel_name, s);
219 asc = sense_buffer[12];
220 ascq = sense_buffer[13];
221 } else if ((code == 0x2) || (code == 0x3)) {
222 descriptor_format = 1;
223 sense_key = sense_buffer[1] & 0xf;
224 asc = sense_buffer[2];
225 ascq = sense_buffer[3];
227 info("%s: invalid sense code 0x%x",
228 dev_scsi->kernel_name, code);
231 info("%s: sense key 0x%x ASC 0x%x ASCQ 0x%x",
232 dev_scsi->kernel_name, sense_key, asc, ascq);
235 info("%s: sense buffer too small %d bytes, %d bytes too short",
236 dev_scsi->kernel_name, sb_len, 4 - sb_len);
240 if (sense_buffer[0] < 15)
241 info("%s: old sense key: 0x%x", dev_scsi->kernel_name, sense_buffer[0] & 0x0f);
243 info("%s: sense = %2x %2x",
244 dev_scsi->kernel_name, sense_buffer[0], sense_buffer[2]);
245 info("%s: non-extended sense class %d code 0x%0x",
246 dev_scsi->kernel_name, sense_class, code);
251 for (i = 0, j = 0; (i < s) && (j < 254); i++) {
252 dbg("i %d, j %d\n", i, j);
253 out_buffer[j++] = hex_str[(sense_buffer[i] & 0xf0) >> 4];
254 out_buffer[j++] = hex_str[sense_buffer[i] & 0x0f];
255 out_buffer[j++] = ' ';
257 out_buffer[j] = '\0';
258 info("%s: sense dump:", dev_scsi->kernel_name);
259 info("%s: %s", dev_scsi->kernel_name, out_buffer);
265 static int scsi_dump(struct sysfs_device *dev_scsi, struct sg_io_hdr *io)
267 if (!io->status && !io->host_status && !io->msg_status &&
268 !io->driver_status) {
270 * Impossible, should not be called.
272 info("%s: called with no error", __FUNCTION__);
276 info("%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x",
277 dev_scsi->kernel_name, io->driver_status, io->host_status, io->msg_status, io->status);
278 if (io->status == SCSI_CHECK_CONDITION)
279 return scsi_dump_sense(dev_scsi, io);
284 static int scsi_inquiry(struct sysfs_device *dev_scsi, int fd,
285 unsigned char evpd, unsigned char page,
286 unsigned char *buf, unsigned int buflen)
288 unsigned char inq_cmd[INQUIRY_CMDLEN] =
289 { INQUIRY_CMD, evpd, page, 0, buflen, 0 };
290 unsigned char sense[SENSE_BUFF_LEN];
291 struct sg_io_hdr io_hdr;
293 int retry = 3; /* rather random */
295 if (buflen > SCSI_INQ_BUFF_LEN) {
296 info("buflen %d too long", buflen);
301 dbg("%s evpd %d, page 0x%x\n", dev_scsi->kernel_name, evpd, page);
303 memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
304 io_hdr.interface_id = 'S';
305 io_hdr.cmd_len = sizeof(inq_cmd);
306 io_hdr.mx_sb_len = sizeof(sense);
307 io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
308 io_hdr.dxfer_len = buflen;
310 io_hdr.cmdp = inq_cmd;
312 io_hdr.timeout = DEF_TIMEOUT;
314 if (ioctl(fd, SG_IO, &io_hdr) < 0) {
315 info("%s: ioctl failed: %s", dev_scsi->kernel_name, strerror(errno));
320 retval = sg_err_category3(&io_hdr);
323 case SG_ERR_CAT_NOTSUPPORTED:
326 case SG_ERR_CAT_CLEAN:
327 case SG_ERR_CAT_RECOVERED:
332 retval = scsi_dump(dev_scsi, &io_hdr);
337 } else if (retval > 0) {
339 dbg("%s: Retrying ...\n", dev_scsi->kernel_name);
347 info("%s: Unable to get INQUIRY vpd %d page 0x%x.",
348 dev_scsi->kernel_name, evpd, page);
353 /* Get list of supported EVPD pages */
354 static int do_scsi_page0_inquiry(struct sysfs_device *dev_scsi, int fd,
355 unsigned char *buffer, unsigned int len)
360 memset(buffer, 0, len);
361 retval = scsi_inquiry(dev_scsi, fd, 1, 0x0, buffer, len);
365 if (buffer[1] != 0) {
366 info("%s: page 0 not available.", dev_scsi->kernel_name);
369 if (buffer[3] > len) {
370 info("%s: page 0 buffer too long %d", dev_scsi->kernel_name, buffer[3]);
375 * Following check is based on code once included in the 2.5.x
378 * Some ill behaved devices return the standard inquiry here
379 * rather than the evpd data, snoop the data to verify.
381 if (buffer[3] > MODEL_LENGTH) {
383 * If the vendor id appears in the page assume the page is
386 vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
388 info("%s: cannot get model attribute", dev_scsi->kernel_name);
391 if (!strncmp((char *)&buffer[VENDOR_LENGTH], vendor, VENDOR_LENGTH)) {
392 info("%s: invalid page0 data", dev_scsi->kernel_name);
400 * The caller checks that serial is long enough to include the vendor +
403 static int prepend_vendor_model(struct sysfs_device *dev_scsi, char *serial)
408 attr = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
410 info("%s: cannot get vendor attribute", dev_scsi->kernel_name);
413 strncpy(serial, attr, VENDOR_LENGTH);
414 ind = strlen(serial) - 1;
416 attr = sysfs_attr_get_value(dev_scsi->devpath, "model");
418 info("%s: cannot get model attribute", dev_scsi->kernel_name);
421 strncat(serial, attr, MODEL_LENGTH);
422 ind = strlen(serial) - 1;
426 * This is not a complete check, since we are using strncat/cpy
427 * above, ind will never be too large.
429 if (ind != (VENDOR_LENGTH + MODEL_LENGTH)) {
430 info("%s: expected length %d, got length %d",
431 dev_scsi->kernel_name, (VENDOR_LENGTH + MODEL_LENGTH), ind);
438 * check_fill_0x83_id - check the page 0x83 id, if OK allocate and fill
441 static int check_fill_0x83_id(struct sysfs_device *dev_scsi,
442 unsigned char *page_83,
443 const struct scsi_id_search_values
444 *id_search, char *serial, int max_len)
449 * ASSOCIATION must be with the device (value 0)
451 if ((page_83[1] & 0x30) != 0)
454 if ((page_83[1] & 0x0f) != id_search->id_type)
458 * Possibly check NAA sub-type.
460 if ((id_search->naa_type != SCSI_ID_NAA_DONT_CARE) &&
461 (id_search->naa_type != (page_83[4] & 0xf0) >> 4))
465 * Check for matching code set - ASCII or BINARY.
467 if ((page_83[0] & 0x0f) != id_search->code_set)
471 * page_83[3]: identifier length
474 if ((page_83[0] & 0x0f) != SCSI_ID_ASCII)
476 * If not ASCII, use two bytes for each binary value.
481 * Add one byte for the NUL termination, and one for the id_type.
484 if (id_search->id_type == SCSI_ID_VENDOR_SPECIFIC)
485 len += VENDOR_LENGTH + MODEL_LENGTH;
488 info("%s: length %d too short - need %d",
489 dev_scsi->kernel_name, max_len, len);
493 serial[0] = hex_str[id_search->id_type];
496 * For SCSI_ID_VENDOR_SPECIFIC prepend the vendor and model before
497 * the id since it is not unique across all vendors and models,
498 * this differs from SCSI_ID_T10_VENDOR, where the vendor is
499 * included in the identifier.
501 if (id_search->id_type == SCSI_ID_VENDOR_SPECIFIC)
502 if (prepend_vendor_model(dev_scsi, &serial[1]) < 0) {
503 dbg("prepend failed\n");
507 i = 4; /* offset to the start of the identifier */
509 if ((page_83[0] & 0x0f) == SCSI_ID_ASCII) {
513 while (i < (4 + page_83[3]))
514 serial[j++] = page_83[i++];
517 * Binary descriptor, convert to ASCII, using two bytes of
518 * ASCII for each byte in the page_83.
520 while (i < (4 + page_83[3])) {
521 serial[j++] = hex_str[(page_83[i] & 0xf0) >> 4];
522 serial[j++] = hex_str[page_83[i] & 0x0f];
529 /* Extract the raw binary from VPD 0x83 pre-SPC devices */
530 static int check_fill_0x83_prespc3(struct sysfs_device *dev_scsi,
531 unsigned char *page_83,
532 const struct scsi_id_search_values
533 *id_search, char *serial, int max_len)
537 serial[0] = hex_str[id_search->id_type];
538 /* serial has been memset to zero before */
539 j = strlen(serial); /* j = 1; */
541 for (i = 0; i < page_83[3]; ++i) {
542 serial[j++] = hex_str[(page_83[4+i] & 0xf0) >> 4];
543 serial[j++] = hex_str[ page_83[4+i] & 0x0f];
545 dbg("using pre-spc3-83 for %s.\n", dev_scsi->kernel_name);
550 /* Get device identification VPD page */
551 static int do_scsi_page83_inquiry(struct sysfs_device *dev_scsi, int fd,
552 char *serial, int len)
555 unsigned int id_ind, j;
556 unsigned char page_83[SCSI_INQ_BUFF_LEN];
558 memset(page_83, 0, SCSI_INQ_BUFF_LEN);
559 retval = scsi_inquiry(dev_scsi, fd, 1, PAGE_83, page_83,
564 if (page_83[1] != PAGE_83) {
565 info("%s: Invalid page 0x83", dev_scsi->kernel_name);
570 * XXX Some devices (IBM 3542) return all spaces for an identifier if
571 * the LUN is not actually configured. This leads to identifers of
576 * Model 4, 5, and (some) model 6 EMC Symmetrix devices return
577 * a page 83 reply according to SCSI-2 format instead of SPC-2/3.
579 * The SCSI-2 page 83 format returns an IEEE WWN in binary
580 * encoded hexi-decimal in the 16 bytes following the initial
581 * 4-byte page 83 reply header.
583 * Both the SPC-2 and SPC-3 formats return an IEEE WWN as part
584 * of an Identification descriptor. The 3rd byte of the first
585 * Identification descriptor is a reserved (BSZ) byte field.
587 * Reference the 7th byte of the page 83 reply to determine
588 * whether the reply is compliant with SCSI-2 or SPC-2/3
589 * specifications. A zero value in the 7th byte indicates
590 * an SPC-2/3 conformant reply, (i.e., the reserved field of the
591 * first Identification descriptor). This byte will be non-zero
592 * for a SCSI-2 conformant page 83 reply from these EMC
593 * Symmetrix models since the 7th byte of the reply corresponds
594 * to the 4th and 5th nibbles of the 6-byte OUI for EMC, that is,
599 return check_fill_0x83_prespc3(dev_scsi, page_83,
600 id_search_list, serial, len);
603 * Search for a match in the prioritized id_search_list.
606 id_ind < sizeof(id_search_list)/sizeof(id_search_list[0]);
609 * Examine each descriptor returned. There is normally only
610 * one or a small number of descriptors.
612 for (j = 4; j <= (unsigned int)page_83[3] + 3; j += page_83[j + 3] + 4) {
613 retval = check_fill_0x83_id(dev_scsi, &page_83[j],
614 &id_search_list[id_ind],
616 dbg("%s id desc %d/%d/%d\n", dev_scsi->kernel_name,
617 id_search_list[id_ind].id_type,
618 id_search_list[id_ind].naa_type,
619 id_search_list[id_ind].code_set);
623 } else if (retval < 0) {
635 * Get device identification VPD page for older SCSI-2 device which is not
636 * compliant with either SPC-2 or SPC-3 format.
638 * Return the hard coded error code value 2 if the page 83 reply is not
639 * conformant to the SCSI-2 format.
641 static int do_scsi_page83_prespc3_inquiry(struct sysfs_device *dev_scsi, int fd,
642 char *serial, int len)
646 unsigned char page_83[SCSI_INQ_BUFF_LEN];
648 memset(page_83, 0, SCSI_INQ_BUFF_LEN);
649 retval = scsi_inquiry(dev_scsi, fd, 1, PAGE_83, page_83, SCSI_INQ_BUFF_LEN);
653 if (page_83[1] != PAGE_83) {
654 info("%s: Invalid page 0x83", dev_scsi->kernel_name);
658 * Model 4, 5, and (some) model 6 EMC Symmetrix devices return
659 * a page 83 reply according to SCSI-2 format instead of SPC-2/3.
661 * The SCSI-2 page 83 format returns an IEEE WWN in binary
662 * encoded hexi-decimal in the 16 bytes following the initial
663 * 4-byte page 83 reply header.
665 * Both the SPC-2 and SPC-3 formats return an IEEE WWN as part
666 * of an Identification descriptor. The 3rd byte of the first
667 * Identification descriptor is a reserved (BSZ) byte field.
669 * Reference the 7th byte of the page 83 reply to determine
670 * whether the reply is compliant with SCSI-2 or SPC-2/3
671 * specifications. A zero value in the 7th byte indicates
672 * an SPC-2/3 conformant reply, (i.e., the reserved field of the
673 * first Identification descriptor). This byte will be non-zero
674 * for a SCSI-2 conformant page 83 reply from these EMC
675 * Symmetrix models since the 7th byte of the reply corresponds
676 * to the 4th and 5th nibbles of the 6-byte OUI for EMC, that is,
682 serial[0] = hex_str[id_search_list[0].id_type];
684 * The first four bytes contain data, not a descriptor.
689 * Binary descriptor, convert to ASCII,
690 * using two bytes of ASCII for each byte
693 while (i < (page_83[3]+4)) {
694 serial[j++] = hex_str[(page_83[i] & 0xf0) >> 4];
695 serial[j++] = hex_str[page_83[i] & 0x0f];
698 dbg("using pre-spc3-83 for %s.\n", dev_scsi->kernel_name);
702 /* Get unit serial number VPD page */
703 static int do_scsi_page80_inquiry(struct sysfs_device *dev_scsi, int fd,
704 char *serial, int max_len)
710 unsigned char buf[SCSI_INQ_BUFF_LEN];
712 memset(buf, 0, SCSI_INQ_BUFF_LEN);
713 retval = scsi_inquiry(dev_scsi, fd, 1, PAGE_80, buf, SCSI_INQ_BUFF_LEN);
717 if (buf[1] != PAGE_80) {
718 info("%s: Invalid page 0x80", dev_scsi->kernel_name);
722 len = 1 + VENDOR_LENGTH + MODEL_LENGTH + buf[3];
724 info("%s: length %d too short - need %d",
725 dev_scsi->kernel_name, max_len, len);
729 * Prepend 'S' to avoid unlikely collision with page 0x83 vendor
730 * specific type where we prepend '0' + vendor + model.
733 ser_ind = prepend_vendor_model(dev_scsi, &serial[1]);
737 for (i = 4; i < len + 4; i++, ser_ind++)
738 serial[ser_ind] = buf[i];
742 int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname,
743 int page_code, char *serial, int len)
745 unsigned char page0[SCSI_INQ_BUFF_LEN];
750 memset(serial, 0, len);
751 dbg("opening %s\n", devname);
752 fd = open(devname, O_RDONLY | O_NONBLOCK);
754 info("%s: cannot open %s: %s",
755 dev_scsi->kernel_name, devname, strerror(errno));
759 if (page_code == PAGE_80) {
760 if (do_scsi_page80_inquiry(dev_scsi, fd, serial, len)) {
767 } else if (page_code == PAGE_83) {
768 if (do_scsi_page83_inquiry(dev_scsi, fd, serial, len)) {
775 } else if (page_code == PAGE_83_PRE_SPC3) {
776 retval = do_scsi_page83_prespc3_inquiry(dev_scsi, fd, serial, len);
779 * Fallback to servicing a SPC-2/3 compliant page 83
780 * inquiry if the page 83 reply format does not
781 * conform to pre-SPC3 expectations.
784 if (do_scsi_page83_inquiry(dev_scsi, fd, serial, len)) {
800 } else if (page_code != 0x00) {
801 info("%s: unsupported page code 0x%d", dev_scsi->kernel_name, page_code);
806 * Get page 0, the page of the pages. By default, try from best to
807 * worst of supported pages: 0x83 then 0x80.
809 if (do_scsi_page0_inquiry(dev_scsi, fd, page0, SCSI_INQ_BUFF_LEN)) {
811 * Don't try anything else. Black list if a specific page
812 * should be used for this vendor+model, or maybe have an
813 * optional fall-back to page 0x80 or page 0x83.
819 dbg("%s: Checking page0\n", dev_scsi->kernel_name);
821 for (ind = 4; ind <= page0[3] + 3; ind++)
822 if (page0[ind] == PAGE_83)
823 if (!do_scsi_page83_inquiry(dev_scsi, fd, serial,
832 for (ind = 4; ind <= page0[3] + 3; ind++)
833 if (page0[ind] == PAGE_80)
834 if (!do_scsi_page80_inquiry(dev_scsi, fd, serial,
845 info("%s: close failed: %s", dev_scsi->kernel_name, strerror(errno));