chiark / gitweb /
Add virtio-blk support to path_id
[elogind.git] / extras / scsi_id / scsi_serial.c
index 5b18b225a5eb6e7e4e9bd0eb15e0a600e011abc1..dd5e1fdbf8f1cee7c6df2d9604f44c7d2b449c27 100644 (file)
@@ -1,16 +1,20 @@
 /*
- * scsi_serial.c
+ * Copyright (C) IBM Corp. 2003
  *
- * Code related to requesting and getting an id from a scsi device
+ * Author: Patrick Mansfield<patmans@us.ibm.com>
  *
- * 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<patmans@us.ibm.com>
+ * 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 <http://www.gnu.org/licenses/>.
  */
 
 #include <sys/types.h>
@@ -482,7 +486,8 @@ static int check_fill_0x83_id(struct udev *udev,
                              unsigned char *page_83,
                              const struct scsi_id_search_values
                              *id_search, char *serial, char *serial_short, int max_len,
-                              char *wwn)
+                              char *wwn,
+                             char *wwn_vendor_extension)
 {
        int i, j, s, len;
 
@@ -569,6 +574,9 @@ static int check_fill_0x83_id(struct udev *udev,
 
         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;
 }
@@ -601,7 +609,8 @@ 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 *unit_serial_number, char *wwn,
+                                 char *wwn_vendor_extension)
 {
        int retval;
        unsigned int id_ind, j;
@@ -671,7 +680,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,
+                                                   wwn_vendor_extension);
                        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,
@@ -856,21 +866,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)
@@ -885,7 +895,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)) {
+               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)) {
                        retval = 1;
                        goto completed;
                } else  {
@@ -901,7 +911,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)) {
+                               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)) {
                                        retval = 1;
                                        goto completed;
                                } else  {
@@ -941,7 +951,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->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension)) {
                                /*
                                 * Success
                                 */