aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_sysfs.c
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2014-03-15 04:51:49 -0400
committerJames Bottomley <JBottomley@Parallels.com>2014-03-27 11:25:33 -0400
commitb3ae8780b42918111387240762f470d5c1e269d6 (patch)
treef3791a3002248327f6f72a9335a275b123e06dab /drivers/scsi/scsi_sysfs.c
parentbc8945df3c27e8edaa6a6de47cb20df7d12b80c8 (diff)
[SCSI] Add EVPD page 0x83 and 0x80 to sysfs
EVPD page 0x83 is used to uniquely identify the device. So instead of having each and every program issue a separate SG_IO call to retrieve this information it does make far more sense to display it in sysfs. Some older devices (most notably tapes) will only report reliable information in page 0x80 (Unit Serial Number). So export this in the sysfs attribute 'vpd_pg80'. [jejb: checkpatch fix] [hare: attach after transport configure] [fengguang.wu@intel.com: spotted problems with the original now fixed] Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r--drivers/scsi/scsi_sysfs.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 85098222a9e8..1392474c3499 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -412,6 +412,8 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
412 /* NULL queue means the device can't be used */ 412 /* NULL queue means the device can't be used */
413 sdev->request_queue = NULL; 413 sdev->request_queue = NULL;
414 414
415 kfree(sdev->vpd_pg83);
416 kfree(sdev->vpd_pg80);
415 kfree(sdev->inquiry); 417 kfree(sdev->inquiry);
416 kfree(sdev); 418 kfree(sdev);
417 419
@@ -751,8 +753,32 @@ store_queue_type_field(struct device *dev, struct device_attribute *attr,
751static DEVICE_ATTR(queue_type, S_IRUGO | S_IWUSR, show_queue_type_field, 753static DEVICE_ATTR(queue_type, S_IRUGO | S_IWUSR, show_queue_type_field,
752 store_queue_type_field); 754 store_queue_type_field);
753 755
756#define sdev_vpd_pg_attr(_page) \
757static ssize_t \
758show_vpd_##_page(struct file *filp, struct kobject *kobj, \
759 struct bin_attribute *bin_attr, \
760 char *buf, loff_t off, size_t count) \
761{ \
762 struct device *dev = container_of(kobj, struct device, kobj); \
763 struct scsi_device *sdev = to_scsi_device(dev); \
764 if (!sdev->vpd_##_page) \
765 return -EINVAL; \
766 return memory_read_from_buffer(buf, count, &off, \
767 sdev->vpd_##_page, \
768 sdev->vpd_##_page##_len); \
769} \
770static struct bin_attribute dev_attr_vpd_##_page = { \
771 .attr = {.name = __stringify(vpd_##_page), .mode = S_IRUGO }, \
772 .size = 0, \
773 .read = show_vpd_##_page, \
774};
775
776sdev_vpd_pg_attr(pg83);
777sdev_vpd_pg_attr(pg80);
778
754static ssize_t 779static ssize_t
755show_iostat_counterbits(struct device *dev, struct device_attribute *attr, char *buf) 780show_iostat_counterbits(struct device *dev, struct device_attribute *attr,
781 char *buf)
756{ 782{
757 return snprintf(buf, 20, "%d\n", (int)sizeof(atomic_t) * 8); 783 return snprintf(buf, 20, "%d\n", (int)sizeof(atomic_t) * 8);
758} 784}
@@ -936,8 +962,14 @@ static struct attribute *scsi_sdev_attrs[] = {
936 NULL 962 NULL
937}; 963};
938 964
965static struct bin_attribute *scsi_sdev_bin_attrs[] = {
966 &dev_attr_vpd_pg83,
967 &dev_attr_vpd_pg80,
968 NULL
969};
939static struct attribute_group scsi_sdev_attr_group = { 970static struct attribute_group scsi_sdev_attr_group = {
940 .attrs = scsi_sdev_attrs, 971 .attrs = scsi_sdev_attrs,
972 .bin_attrs = scsi_sdev_bin_attrs,
941 .is_visible = scsi_sdev_attr_is_visible, 973 .is_visible = scsi_sdev_attr_is_visible,
942}; 974};
943 975