chiark / gitweb /
cciss device support
authorHannes Reinecke <hare@suse.de>
Fri, 25 May 2007 12:48:08 +0000 (14:48 +0200)
committerKay Sievers <kay.sievers@vrfy.org>
Fri, 25 May 2007 12:48:08 +0000 (14:48 +0200)
etc/udev/rules.d/60-persistent-storage.rules
extras/path_id/path_id
extras/scsi_id/scsi_id.c
extras/scsi_id/scsi_id.h
extras/scsi_id/scsi_serial.c

index 04c7e7740d31ac42b0489d99011e6d469b3d1398..8de3e634109e7db5607eea596a2c1b0901e67b52 100644 (file)
@@ -36,8 +36,9 @@ KERNEL=="sd*[!0-9]|sr*|st*", ATTRS{ieee1394_id}=="?*", ENV{ID_SERIAL}="$attr{iee
 KERNEL=="sd*[!0-9]|sr*|st*", ENV{ID_SERIAL}=="", IMPORT{program}="usb_id -x"
 KERNEL=="sd*[!0-9]|sr*|st*", ENV{ID_SERIAL}=="", IMPORT{program}="scsi_id -g -x -s %p -d $tempnode"
 KERNEL=="sd*[!0-9]|sr*|st*", ENV{ID_SERIAL}=="", IMPORT{program}="scsi_id -g -x -a -s %p -d $tempnode"
-KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
-KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n"
+KERNEL=="cciss?c[0-9]d[0-9]", ENV{ID_SERIAL}=="", IMPORT{program}="scsi_id -n -g -x -s %p -d $tempnode"
+KERNEL=="sd*[!0-9]|sr*|cciss?c[0-9]d[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
+KERNEL=="sd*[0-9]|cciss*p[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n"
 
 # libata compat (links like hd*)
 KERNEL=="sd*[!0-9]|sr*", ENV{ID_VENDOR}=="ATA", PROGRAM="ata_id $tempnode", ENV{ID_ATA_COMPAT}="$result"
@@ -48,10 +49,10 @@ KERNEL=="mmcblk[0-9]", ATTR{name}=="?*", ATTR{serial}=="?*", ENV{ID_NAME}="$attr
 KERNEL=="mmcblk[0-9]p[0-9]", ATTR{name}=="?*", ATTR{serial}=="?*", ENV{ID_NAME}="$attr{name}", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/mmc-$env{ID_NAME}_$env{ID_SERIAL}-part%n"
 
 # by-path (shortest physical path)
-KERNEL=="*[!0-9]|sr*", IMPORT{program}="path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}"
+KERNEL=="*[!0-9]|sr*|cciss?c[0-9]d[0-9]", IMPORT{program}="path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}"
+KERNEL=="*[0-9]|cciss*p[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n"
 KERNEL=="st*", IMPORT{program}="path_id %p", SYMLINK+="tape/by-path/$env{ID_PATH}"
 KERNEL=="sr*|st*", GOTO="persistent_storage_end"
-KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n"
 
 # by-label/by-uuid (filesystem properties)
 KERNEL=="*[!0-9]", ATTR{removable}=="1", GOTO="persistent_storage_end"
index a7d650bf423b62b46cfd188d3b31c9814d370c53..ee26dc1f8aa231d4cef773d8a20da12989d4ba74 100644 (file)
@@ -74,6 +74,17 @@ handle_pci () {
        DEV=${PWD}
        pci_id=${DEV##*/}
        host_dev_path=$DEV
+
+       # cciss devices don't have a separate sysfs node
+       for blk_link in block*; do
+           if [ -L "$blk_link" ]; then
+               case "$blk_link" in
+                   *cciss*)
+                       d=cciss-${blk_link#*cciss\!}
+                       ;;
+               esac
+           fi
+       done
        while [ ! -z "$host_dev_path" ] ; do
                case "$host_dev_path" in
                        */pci[0-9]*)
index c00145f30efe20b6a9863d14577d2e528a7101da..79a8d7e51bce5e1bc62d15355aa9eed2fca60540 100644 (file)
@@ -34,7 +34,7 @@
 #define TMP_DIR                "/dev"
 #define TMP_PREFIX     "tmp-scsi"
 
-static const char short_options[] = "abd:f:gip:s:uvVx";
+static const char short_options[] = "abd:f:ginp:s:uvVx";
 static const char dev_short_options[] = "bgp:";
 
 static int all_good;
@@ -48,6 +48,7 @@ static int use_stderr;
 static int debug;
 static int hotplug_mode;
 static int reformat_serial;
+static int ignore_sysfs;
 static int export;
 static char vendor_str[64];
 static char model_str[64];
@@ -459,6 +460,10 @@ static int set_options(int argc, char **argv, const char *short_opts,
                        }
                        break;
 
+               case 'n':
+                       ignore_sysfs = 1;
+                       break;
+
                case 's':
                        sys_specified = 1;
                        strncpy(target, optarg, MAX_PATH_LEN);
@@ -495,41 +500,12 @@ static int per_dev_options(struct sysfs_device *dev_scsi, int *good_bad, int *pa
        int retval;
        int newargc;
        char **newargv = NULL;
-       const char *vendor, *model, *type;
        int option;
 
        *good_bad = all_good;
        *page_code = default_page_code;
 
-       vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
-       if (!vendor) {
-               info("%s: cannot get vendor attribute", dev_scsi->devpath);
-               return -1;
-       }
-       set_str(vendor_str, vendor, sizeof(vendor_str)-1);
-
-       model = sysfs_attr_get_value(dev_scsi->devpath, "model");
-       if (!model) {
-               info("%s: cannot get model attribute\n", dev_scsi->devpath);
-               return -1;
-       }
-       set_str(model_str, model, sizeof(model_str)-1);
-
-       type = sysfs_attr_get_value(dev_scsi->devpath, "type");
-       if (!type) {
-               info("%s: cannot get type attribute", dev_scsi->devpath);
-               return -1;
-       }
-       set_type(type_str, type, sizeof(type_str));
-
-       type = sysfs_attr_get_value(dev_scsi->devpath, "rev");
-       if (!type) {
-               info("%s: cannot get type attribute\n", dev_scsi->devpath);
-               return -1;
-       }
-       set_str(revision_str, type, sizeof(revision_str)-1);
-
-       retval = get_file_options(vendor, model, &newargc, &newargv);
+       retval = get_file_options(vendor_str, model_str, &newargc, &newargv);
 
        optind = 1; /* reset this global extern */
        while (retval == 0) {
@@ -578,6 +554,58 @@ static int per_dev_options(struct sysfs_device *dev_scsi, int *good_bad, int *pa
        return retval;
 }
 
+static int set_sysfs_values(struct sysfs_device *dev_scsi)
+{
+       const char *vendor, *model, *type;
+
+       vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor");
+       if (!vendor) {
+               info("%s: cannot get vendor attribute", dev_scsi->devpath);
+               return -1;
+       }
+       set_str(vendor_str, vendor, sizeof(vendor_str)-1);
+
+       model = sysfs_attr_get_value(dev_scsi->devpath, "model");
+       if (!model) {
+               info("%s: cannot get model attribute\n", dev_scsi->devpath);
+               return -1;
+       }
+       set_str(model_str, model, sizeof(model_str)-1);
+
+       type = sysfs_attr_get_value(dev_scsi->devpath, "type");
+       if (!type) {
+               info("%s: cannot get type attribute", dev_scsi->devpath);
+               return -1;
+       }
+       set_type(type_str, type, sizeof(type_str));
+
+       type = sysfs_attr_get_value(dev_scsi->devpath, "rev");
+       if (!type) {
+               info("%s: cannot get type attribute\n", dev_scsi->devpath);
+               return -1;
+       }
+       set_str(revision_str, type, sizeof(revision_str)-1);
+
+       return 0;
+}
+
+static int set_inq_values(struct sysfs_device *dev_scsi, const char *path)
+{
+       int retval;
+       char vendor[8], model[16], type[4], rev[4];
+
+       retval = scsi_std_inquiry(dev_scsi, path, vendor, model, rev, type);
+       if (retval)
+           return retval;
+
+       set_str(vendor_str, vendor, 8);
+       set_str(model_str, model, 16);
+       set_type(type_str, type, sizeof(type_str) - 1);
+       set_str(revision_str, rev, sizeof(revision_str) -1);
+
+       return 0;
+}
+
 /*
  * format_serial: replace to whitespaces by underscores for calling
  * programs that use the serial for device naming (multipath, Suse
@@ -615,11 +643,12 @@ static int scsi_id(const char *devpath, char *maj_min_dev)
        int retval;
        int dev_type = 0;
        struct sysfs_device *dev;
-       struct sysfs_device *dev_scsi;
+       struct sysfs_device *dev_scsi = NULL;
        int good_dev;
        int page_code;
        char serial[MAX_SERIAL_LEN];
        char serial_short[MAX_SERIAL_LEN];
+       char bus_str[8];
 
        dbg("devpath %s\n", devpath);
 
@@ -634,11 +663,13 @@ static int scsi_id(const char *devpath, char *maj_min_dev)
        else
                dev_type = S_IFCHR;
 
-       /* get scsi parent device */
-       dev_scsi = sysfs_device_get_parent_with_subsystem(dev, "scsi");
-       if (dev_scsi == NULL) {
-               err("unable to access parent device of '%s'", devpath);
-               return 1;
+       if (!ignore_sysfs) {
+               /* get scsi parent device */
+               dev_scsi = sysfs_device_get_parent_with_subsystem(dev, "scsi");
+               if (dev_scsi == NULL) {
+                       err("unable to access parent device of '%s'", devpath);
+                       return 1;
+               }
        }
 
        /* mknod a temp dev to communicate with the device */
@@ -647,6 +678,15 @@ static int scsi_id(const char *devpath, char *maj_min_dev)
                return 1;
        }
 
+       if (!ignore_sysfs) {
+               set_sysfs_values(dev_scsi);
+               strcpy(bus_str,"scsi");
+       } else {
+               dev_scsi = dev;
+               set_inq_values(dev_scsi, maj_min_dev);
+               strcpy(bus_str,"cciss");
+       }
+
        /* get per device (vendor + model) options from the config file */
        retval = per_dev_options(dev_scsi, &good_dev, &page_code);
        dbg("per dev options: good %d; page code 0x%x", good_dev, page_code);
@@ -671,7 +711,7 @@ static int scsi_id(const char *devpath, char *maj_min_dev)
                        set_str(serial_str, serial_short, sizeof(serial_str));
                        printf("ID_SERIAL_SHORT=%s\n", serial_str);
                        printf("ID_TYPE=%s\n", type_str);
-                       printf("ID_BUS=scsi\n");
+                       printf("ID_BUS=%s\n", bus_str);
                } else {
                        if (reformat_serial)
                                format_serial(serial);
index d7f675fa0b4d7814b1726749e1318748747dd2c2..0e2b297d28838567fd50f444bd6183b73496a3f5 100644 (file)
@@ -30,6 +30,8 @@
  */
 #define MAX_BUFFER_LEN 256
 
+extern int scsi_std_inquiry(struct sysfs_device *dev_scsi, const char *devname,
+                           char *vendor, char *model, char *rev, char *type);
 extern int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname,
                            int page_code, char *serial, char *serial_short, int len);
 
index e1726bbd70add37d361315b7277d859a9f3f0a7b..c84f41e0437e9c0d84573b8adc5adcb3f02f7a35 100644 (file)
@@ -736,6 +736,37 @@ static int do_scsi_page80_inquiry(struct sysfs_device *dev_scsi, int fd,
        return 0;
 }
 
+int scsi_std_inquiry(struct sysfs_device *dev_scsi, const char *devname,
+                    char *vendor, char *model, char *rev, char *type)
+{
+       int retval;
+       int fd;
+       unsigned char buf[SCSI_INQ_BUFF_LEN];
+
+       dbg("opening %s\n", devname);
+       fd = open(devname, O_RDONLY | O_NONBLOCK);
+       if (fd < 0) {
+               info("%s: cannot open %s: %s",
+                   dev_scsi->kernel, devname, strerror(errno));
+               return 1;
+       }
+
+       memset(buf, 0, SCSI_INQ_BUFF_LEN);
+       retval = scsi_inquiry(dev_scsi, fd, 0, 0, buf, SCSI_INQ_BUFF_LEN);
+       if (retval < 0)
+               return retval;
+
+       memcpy(vendor, buf + 8, 8);
+       memcpy(model, buf + 16, 16);
+       memcpy(rev, buf + 32, 4);
+       sprintf(type,"%x", buf[0] & 0x1f);
+
+       if (close(fd) < 0)
+               info("%s: close failed: %s", dev_scsi->kernel, strerror(errno));
+
+       return 0;
+}
+
 int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname,
                     int page_code, char *serial, char *serial_short, int len)
 {