ChangeSet 1.1474.81.35, 2004/01/16 17:18:20-08:00, mdharm-usb@one-eyed-alien.net [PATCH] USB Storage: add sysfs info attribute This patch adds a sysfs attribute to the usb-storage SCSI devices. This attribute (read-only) is basically a clone of the information available in /proc/scsi/scsi -- since that interface is going away, adding a new sysfs attribute seemed like a good idea. drivers/usb/storage/scsiglue.c | 58 +++++++++++++++++++++++++++++++++++++---- 1 files changed, 53 insertions(+), 5 deletions(-) diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c --- a/drivers/usb/storage/scsiglue.c Tue Jan 20 17:34:12 2004 +++ b/drivers/usb/storage/scsiglue.c Tue Jan 20 17:34:12 2004 @@ -237,13 +237,14 @@ #undef SPRINTF #define SPRINTF(args...) \ do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0) +#define DO_FLAG(a) \ + do { if (us->flags & US_FL_##a) pos += sprintf(pos, " " #a); } while(0) static int proc_info (struct Scsi_Host *hostptr, char *buffer, char **start, off_t offset, int length, int inout) { struct us_data *us; char *pos = buffer; - unsigned long f; /* if someone is sending us data, just throw it away */ if (inout) @@ -266,17 +267,14 @@ /* show the device flags */ if (pos < buffer + length) { pos += sprintf(pos, " Quirks:"); - f = us->flags; -#define DO_FLAG(a) if (f & US_FL_##a) pos += sprintf(pos, " " #a) DO_FLAG(SINGLE_LUN); DO_FLAG(SCM_MULT_TARG); DO_FLAG(FIX_INQUIRY); DO_FLAG(FIX_CAPACITY); -#undef DO_FLAG *(pos++) = '\n'; - } + } /* * Calculate start of next buffer, and return value. @@ -291,6 +289,53 @@ return (length); } +/*********************************************************************** + * Sysfs interface + ***********************************************************************/ + +/* Output routine for the sysfs info file */ +static ssize_t show_info(struct device *dev, char *buffer) +{ + char *pos = buffer; + const int length = PAGE_SIZE; + + struct scsi_device *sdev = to_scsi_device(dev); + struct us_data *us = (struct us_data*)sdev->host->hostdata[0]; + + /* print the controller name */ + SPRINTF(" Host scsi%d: usb-storage\n", sdev->host->host_no); + + /* print product, vendor, and serial number strings */ + SPRINTF(" Vendor: %s\n", us->vendor); + SPRINTF(" Product: %s\n", us->product); + SPRINTF("Serial Number: %s\n", us->serial); + + /* show the protocol and transport */ + SPRINTF(" Protocol: %s\n", us->protocol_name); + SPRINTF(" Transport: %s\n", us->transport_name); + + /* show the device flags */ + if (pos < buffer + length) { + pos += sprintf(pos, " Quirks:"); + + DO_FLAG(SINGLE_LUN); + DO_FLAG(SCM_MULT_TARG); + DO_FLAG(FIX_INQUIRY); + DO_FLAG(FIX_CAPACITY); + + *(pos++) = '\n'; + } + + return (pos - buffer); +} + +static DEVICE_ATTR(info, S_IRUGO, show_info, NULL); + +static struct device_attribute *sysfs_device_attr_list[] = { + &dev_attr_info, + NULL, + }; + /* * this defines our host template, with which we'll allocate hosts */ @@ -333,6 +378,9 @@ /* emulated HBA */ .emulated = TRUE, + + /* sysfs device attributes */ + .sdev_attrs = sysfs_device_attr_list, /* modify scsi_device bits on probe */ .flags = (BLIST_MS_SKIP_PAGE_08 | BLIST_MS_SKIP_PAGE_3F |