X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=extras%2Fscsi_id%2Fscsi_serial.c;h=516a6f16c5c791cd0b6dc00c3ee914af5ac55831;hb=0c0b3f97cad4c34140dda3aa85a9bc74badb4b16;hp=0c9d9c3095e9723627c0f38740771329d6fcf976;hpb=7f4954d04026f28b0ebe65a514f06fefad8efaca;p=elogind.git diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index 0c9d9c309..516a6f16c 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -1,17 +1,20 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * scsi_serial.c +/* + * Copyright (C) IBM Corp. 2003 * - * Code related to requesting and getting an id from a scsi device + * Author: Patrick Mansfield * - * Copyright (C) IBM Corp. 2003 + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. * - * Author: - * Patrick Mansfield + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation version 2 of the License. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ #include @@ -45,6 +48,7 @@ * is normally one or some small number of descriptors. */ static const struct scsi_id_search_values id_search_list[] = { + { SCSI_ID_TGTGROUP, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY }, { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG_EXTENDED, SCSI_ID_BINARY }, { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG_EXTENDED, SCSI_ID_ASCII }, { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG, SCSI_ID_BINARY }, @@ -482,17 +486,22 @@ static int check_fill_0x83_id(struct udev *udev, struct scsi_id_device *dev_scsi, unsigned char *page_83, const struct scsi_id_search_values - *id_search, char *serial, char *serial_short, int max_len, - char *wwn, - char *wwn_vendor_extension) + *id_search, char *serial, char *serial_short, + int max_len, char *wwn, + char *wwn_vendor_extension, char *tgpt_group) { int i, j, s, len; /* * ASSOCIATION must be with the device (value 0) + * or with the target port for SCSI_ID_TGTPORT */ - if ((page_83[1] & 0x30) != 0) + if ((page_83[1] & 0x30) == 0x10) { + if (id_search->id_type != SCSI_ID_TGTGROUP) + return 1; + } else if ((page_83[1] & 0x30) != 0) { return 1; + } if ((page_83[1] & 0x0f) != id_search->id_type) return 1; @@ -533,6 +542,14 @@ static int check_fill_0x83_id(struct udev *udev, return 1; } + if (id_search->id_type == SCSI_ID_TGTGROUP && tgpt_group != NULL) { + unsigned int group; + + group = ((unsigned int)page_83[6] << 8) | page_83[7]; + sprintf(tgpt_group,"%x", group); + return 1; + } + serial[0] = hex_str[id_search->id_type]; /* @@ -569,12 +586,13 @@ static int check_fill_0x83_id(struct udev *udev, strcpy(serial_short, &serial[s]); - if (id_search->id_type == SCSI_ID_NAA && wwn != NULL) { - strncpy(wwn, &serial[s], 16); + if (id_search->id_type == SCSI_ID_NAA && wwn != NULL) { + strncpy(wwn, &serial[s], 16); if (wwn_vendor_extension != NULL) { strncpy(wwn_vendor_extension, &serial[s + 16], 16); } - } + } + return 0; } @@ -606,14 +624,14 @@ static int check_fill_0x83_prespc3(struct udev *udev, static int do_scsi_page83_inquiry(struct udev *udev, struct scsi_id_device *dev_scsi, int fd, char *serial, char *serial_short, int len, - char *unit_serial_number, char *wwn, - char *wwn_vendor_extension) + char *unit_serial_number, char *wwn, + char *wwn_vendor_extension, char *tgpt_group) { int retval; unsigned int id_ind, j; unsigned char page_83[SCSI_INQ_BUFF_LEN]; - /* also pick up the page 80 serial number */ + /* also pick up the page 80 serial number */ do_scsi_page80_inquiry(udev, dev_scsi, fd, NULL, unit_serial_number, MAX_SERIAL_LEN); memset(page_83, 0, SCSI_INQ_BUFF_LEN); @@ -677,8 +695,8 @@ static int do_scsi_page83_inquiry(struct udev *udev, dev_scsi, &page_83[j], &id_search_list[id_ind], serial, serial_short, len, - wwn, - wwn_vendor_extension); + wwn, wwn_vendor_extension, + tgpt_group); dbg(udev, "%s id desc %d/%d/%d\n", dev_scsi->kernel, id_search_list[id_ind].id_type, id_search_list[id_ind].naa_type, @@ -863,21 +881,21 @@ int scsi_get_serial(struct udev *udev, { unsigned char page0[SCSI_INQ_BUFF_LEN]; int fd = -1; - int cnt = 10; + int cnt; int ind; int retval; memset(dev_scsi->serial, 0, len); dbg(udev, "opening %s\n", devname); - while (--cnt) { - const struct timespec duration = { 0, 500 * 1000 * 1000 }; + srand((unsigned int)getpid()); + for (cnt = 20; cnt > 0; cnt--) { + struct timespec duration; fd = open(devname, O_RDONLY | O_NONBLOCK); - if (fd >= 0) - break; - info(udev, "%s: cannot open %s: %s\n", dev_scsi->kernel, devname, strerror(errno)); - if (errno != EBUSY) + if (fd >= 0 || errno != EBUSY) break; + duration.tv_sec = 0; + duration.tv_nsec = (200 * 1000 * 1000) + (rand() % 100 * 1000 * 1000); nanosleep(&duration, NULL); } if (fd < 0) @@ -892,7 +910,7 @@ int scsi_get_serial(struct udev *udev, goto completed; } } else if (page_code == PAGE_83) { - if (do_scsi_page83_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension)) { + if (do_scsi_page83_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) { retval = 1; goto completed; } else { @@ -908,7 +926,7 @@ int scsi_get_serial(struct udev *udev, * conform to pre-SPC3 expectations. */ if (retval == 2) { - if (do_scsi_page83_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension)) { + if (do_scsi_page83_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) { retval = 1; goto completed; } else { @@ -948,7 +966,7 @@ int scsi_get_serial(struct udev *udev, for (ind = 4; ind <= page0[3] + 3; ind++) if (page0[ind] == PAGE_83) if (!do_scsi_page83_inquiry(udev, dev_scsi, fd, - dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension)) { + dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) { /* * Success */