cciss device support
This commit is contained in:
committed by
Kay Sievers
parent
335b8aace3
commit
87cf9f5aac
@@ -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"
|
||||
|
||||
@@ -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]*)
|
||||
|
||||
+78
-38
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user