scsi: core: Add sysfs attributes for VPD pages 0h and 89h
authorRyan Attard <ryanattard@ryanattard.info>
Thu, 26 Sep 2019 16:22:17 +0000 (11:22 -0500)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 1 Oct 2019 03:24:36 +0000 (23:24 -0400)
Add sysfs attributes for the ATA information page and Supported VPD Pages
page.

Link: https://lore.kernel.org/r/20190926162216.56591-1-ryanattard@ryanattard.info
Signed-off-by: Ryan Attard <ryanattard@ryanattard.info>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/scsi.c
drivers/scsi/scsi_sysfs.c
include/scsi/scsi_device.h

index 1f5b5c8..4f76841 100644 (file)
@@ -465,10 +465,14 @@ void scsi_attach_vpd(struct scsi_device *sdev)
                return;
 
        for (i = 4; i < vpd_buf->len; i++) {
+               if (vpd_buf->data[i] == 0x0)
+                       scsi_update_vpd_page(sdev, 0x0, &sdev->vpd_pg0);
                if (vpd_buf->data[i] == 0x80)
                        scsi_update_vpd_page(sdev, 0x80, &sdev->vpd_pg80);
                if (vpd_buf->data[i] == 0x83)
                        scsi_update_vpd_page(sdev, 0x83, &sdev->vpd_pg83);
+               if (vpd_buf->data[i] == 0x89)
+                       scsi_update_vpd_page(sdev, 0x89, &sdev->vpd_pg89);
        }
        kfree(vpd_buf);
 }
index cebb933..2c76d7a 100644 (file)
@@ -437,6 +437,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
        struct device *parent;
        struct list_head *this, *tmp;
        struct scsi_vpd *vpd_pg80 = NULL, *vpd_pg83 = NULL;
+       struct scsi_vpd *vpd_pg0 = NULL, *vpd_pg89 = NULL;
        unsigned long flags;
 
        sdev = container_of(work, struct scsi_device, ew.work);
@@ -466,16 +467,24 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
        sdev->request_queue = NULL;
 
        mutex_lock(&sdev->inquiry_mutex);
+       rcu_swap_protected(sdev->vpd_pg0, vpd_pg0,
+                          lockdep_is_held(&sdev->inquiry_mutex));
        rcu_swap_protected(sdev->vpd_pg80, vpd_pg80,
                           lockdep_is_held(&sdev->inquiry_mutex));
        rcu_swap_protected(sdev->vpd_pg83, vpd_pg83,
                           lockdep_is_held(&sdev->inquiry_mutex));
+       rcu_swap_protected(sdev->vpd_pg89, vpd_pg89,
+                          lockdep_is_held(&sdev->inquiry_mutex));
        mutex_unlock(&sdev->inquiry_mutex);
 
+       if (vpd_pg0)
+               kfree_rcu(vpd_pg0, rcu);
        if (vpd_pg83)
                kfree_rcu(vpd_pg83, rcu);
        if (vpd_pg80)
                kfree_rcu(vpd_pg80, rcu);
+       if (vpd_pg89)
+               kfree_rcu(vpd_pg89, rcu);
        kfree(sdev->inquiry);
        kfree(sdev);
 
@@ -859,6 +868,8 @@ static struct bin_attribute dev_attr_vpd_##_page = {                \
 
 sdev_vpd_pg_attr(pg83);
 sdev_vpd_pg_attr(pg80);
+sdev_vpd_pg_attr(pg89);
+sdev_vpd_pg_attr(pg0);
 
 static ssize_t show_inquiry(struct file *filep, struct kobject *kobj,
                            struct bin_attribute *bin_attr,
@@ -1191,12 +1202,18 @@ static umode_t scsi_sdev_bin_attr_is_visible(struct kobject *kobj,
        struct scsi_device *sdev = to_scsi_device(dev);
 
 
+       if (attr == &dev_attr_vpd_pg0 && !sdev->vpd_pg0)
+               return 0;
+
        if (attr == &dev_attr_vpd_pg80 && !sdev->vpd_pg80)
                return 0;
 
        if (attr == &dev_attr_vpd_pg83 && !sdev->vpd_pg83)
                return 0;
 
+       if (attr == &dev_attr_vpd_pg89 && !sdev->vpd_pg89)
+               return 0;
+
        return S_IRUGO;
 }
 
@@ -1239,8 +1256,10 @@ static struct attribute *scsi_sdev_attrs[] = {
 };
 
 static struct bin_attribute *scsi_sdev_bin_attrs[] = {
+       &dev_attr_vpd_pg0,
        &dev_attr_vpd_pg83,
        &dev_attr_vpd_pg80,
+       &dev_attr_vpd_pg89,
        &dev_attr_inquiry,
        NULL
 };
index 039e289..3ed836d 100644 (file)
@@ -140,8 +140,10 @@ struct scsi_device {
        const char * rev;               /* ... "nullnullnullnull" before scan */
 
 #define SCSI_VPD_PG_LEN                255
+       struct scsi_vpd __rcu *vpd_pg0;
        struct scsi_vpd __rcu *vpd_pg83;
        struct scsi_vpd __rcu *vpd_pg80;
+       struct scsi_vpd __rcu *vpd_pg89;
        unsigned char current_tag;      /* current tag */
        struct scsi_target      *sdev_target;   /* used only for single_lun */