Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[linux-2.6-microblaze.git] / drivers / scsi / scsi_sysfs.c
index 6d7362e..677b5c5 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_pg80, vpd_pg80,
-                          lockdep_is_held(&sdev->inquiry_mutex));
-       rcu_swap_protected(sdev->vpd_pg83, vpd_pg83,
-                          lockdep_is_held(&sdev->inquiry_mutex));
+       vpd_pg0 = rcu_replace_pointer(sdev->vpd_pg0, vpd_pg0,
+                                      lockdep_is_held(&sdev->inquiry_mutex));
+       vpd_pg80 = rcu_replace_pointer(sdev->vpd_pg80, vpd_pg80,
+                                      lockdep_is_held(&sdev->inquiry_mutex));
+       vpd_pg83 = rcu_replace_pointer(sdev->vpd_pg83, vpd_pg83,
+                                      lockdep_is_held(&sdev->inquiry_mutex));
+       vpd_pg89 = rcu_replace_pointer(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);
 
@@ -868,6 +877,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,
@@ -1200,12 +1211,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;
 }
 
@@ -1248,8 +1265,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
 };
@@ -1309,7 +1328,8 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
        device_enable_async_suspend(&sdev->sdev_gendev);
        scsi_autopm_get_target(starget);
        pm_runtime_set_active(&sdev->sdev_gendev);
-       pm_runtime_forbid(&sdev->sdev_gendev);
+       if (!sdev->rpm_autosuspend)
+               pm_runtime_forbid(&sdev->sdev_gendev);
        pm_runtime_enable(&sdev->sdev_gendev);
        scsi_autopm_put_target(starget);