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 |
