From 87cf9f5aacf65d0bc186e5e525026cc760290379 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 25 May 2007 14:48:08 +0200 Subject: cciss device support --- extras/scsi_id/scsi_id.c | 116 +++++++++++++++++++++++++++++-------------- extras/scsi_id/scsi_id.h | 2 + extras/scsi_id/scsi_serial.c | 31 ++++++++++++ 3 files changed, 111 insertions(+), 38 deletions(-) (limited to 'extras/scsi_id') diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index c00145f30e..79a8d7e51b 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -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); diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index d7f675fa0b..0e2b297d28 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -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); diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index e1726bbd70..c84f41e043 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -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) { -- cgit v1.2.3-54-g00ecf