aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_sysfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r--drivers/scsi/scsi_sysfs.c56
1 files changed, 40 insertions, 16 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index dff8fafb741c..8d2312239ae0 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -775,6 +775,29 @@ static struct bin_attribute dev_attr_vpd_##_page = { \
775sdev_vpd_pg_attr(pg83); 775sdev_vpd_pg_attr(pg83);
776sdev_vpd_pg_attr(pg80); 776sdev_vpd_pg_attr(pg80);
777 777
778static ssize_t show_inquiry(struct file *filep, struct kobject *kobj,
779 struct bin_attribute *bin_attr,
780 char *buf, loff_t off, size_t count)
781{
782 struct device *dev = container_of(kobj, struct device, kobj);
783 struct scsi_device *sdev = to_scsi_device(dev);
784
785 if (!sdev->inquiry)
786 return -EINVAL;
787
788 return memory_read_from_buffer(buf, count, &off, sdev->inquiry,
789 sdev->inquiry_len);
790}
791
792static struct bin_attribute dev_attr_inquiry = {
793 .attr = {
794 .name = "inquiry",
795 .mode = S_IRUGO,
796 },
797 .size = 0,
798 .read = show_inquiry,
799};
800
778static ssize_t 801static ssize_t
779show_iostat_counterbits(struct device *dev, struct device_attribute *attr, 802show_iostat_counterbits(struct device *dev, struct device_attribute *attr,
780 char *buf) 803 char *buf)
@@ -900,7 +923,7 @@ sdev_store_queue_ramp_up_period(struct device *dev,
900 return -EINVAL; 923 return -EINVAL;
901 924
902 sdev->queue_ramp_up_period = msecs_to_jiffies(period); 925 sdev->queue_ramp_up_period = msecs_to_jiffies(period);
903 return period; 926 return count;
904} 927}
905 928
906static DEVICE_ATTR(queue_ramp_up_period, S_IRUGO | S_IWUSR, 929static DEVICE_ATTR(queue_ramp_up_period, S_IRUGO | S_IWUSR,
@@ -959,6 +982,7 @@ static struct attribute *scsi_sdev_attrs[] = {
959static struct bin_attribute *scsi_sdev_bin_attrs[] = { 982static struct bin_attribute *scsi_sdev_bin_attrs[] = {
960 &dev_attr_vpd_pg83, 983 &dev_attr_vpd_pg83,
961 &dev_attr_vpd_pg80, 984 &dev_attr_vpd_pg80,
985 &dev_attr_inquiry,
962 NULL 986 NULL
963}; 987};
964static struct attribute_group scsi_sdev_attr_group = { 988static struct attribute_group scsi_sdev_attr_group = {
@@ -1086,9 +1110,7 @@ void __scsi_remove_device(struct scsi_device *sdev)
1086 device_unregister(&sdev->sdev_dev); 1110 device_unregister(&sdev->sdev_dev);
1087 transport_remove_device(dev); 1111 transport_remove_device(dev);
1088 scsi_dh_remove_device(sdev); 1112 scsi_dh_remove_device(sdev);
1089 device_del(dev); 1113 }
1090 } else
1091 put_device(&sdev->sdev_dev);
1092 1114
1093 /* 1115 /*
1094 * Stop accepting new requests and wait until all queuecommand() and 1116 * Stop accepting new requests and wait until all queuecommand() and
@@ -1099,6 +1121,16 @@ void __scsi_remove_device(struct scsi_device *sdev)
1099 blk_cleanup_queue(sdev->request_queue); 1121 blk_cleanup_queue(sdev->request_queue);
1100 cancel_work_sync(&sdev->requeue_work); 1122 cancel_work_sync(&sdev->requeue_work);
1101 1123
1124 /*
1125 * Remove the device after blk_cleanup_queue() has been called such
1126 * a possible bdi_register() call with the same name occurs after
1127 * blk_cleanup_queue() has called bdi_destroy().
1128 */
1129 if (sdev->is_visible)
1130 device_del(dev);
1131 else
1132 put_device(&sdev->sdev_dev);
1133
1102 if (sdev->host->hostt->slave_destroy) 1134 if (sdev->host->hostt->slave_destroy)
1103 sdev->host->hostt->slave_destroy(sdev); 1135 sdev->host->hostt->slave_destroy(sdev);
1104 transport_destroy_device(dev); 1136 transport_destroy_device(dev);
@@ -1160,31 +1192,23 @@ static void __scsi_remove_target(struct scsi_target *starget)
1160void scsi_remove_target(struct device *dev) 1192void scsi_remove_target(struct device *dev)
1161{ 1193{
1162 struct Scsi_Host *shost = dev_to_shost(dev->parent); 1194 struct Scsi_Host *shost = dev_to_shost(dev->parent);
1163 struct scsi_target *starget, *last = NULL; 1195 struct scsi_target *starget;
1164 unsigned long flags; 1196 unsigned long flags;
1165 1197
1166 /* remove targets being careful to lookup next entry before 1198restart:
1167 * deleting the last
1168 */
1169 spin_lock_irqsave(shost->host_lock, flags); 1199 spin_lock_irqsave(shost->host_lock, flags);
1170 list_for_each_entry(starget, &shost->__targets, siblings) { 1200 list_for_each_entry(starget, &shost->__targets, siblings) {
1171 if (starget->state == STARGET_DEL) 1201 if (starget->state == STARGET_DEL)
1172 continue; 1202 continue;
1173 if (starget->dev.parent == dev || &starget->dev == dev) { 1203 if (starget->dev.parent == dev || &starget->dev == dev) {
1174 /* assuming new targets arrive at the end */
1175 kref_get(&starget->reap_ref); 1204 kref_get(&starget->reap_ref);
1176 spin_unlock_irqrestore(shost->host_lock, flags); 1205 spin_unlock_irqrestore(shost->host_lock, flags);
1177 if (last)
1178 scsi_target_reap(last);
1179 last = starget;
1180 __scsi_remove_target(starget); 1206 __scsi_remove_target(starget);
1181 spin_lock_irqsave(shost->host_lock, flags); 1207 scsi_target_reap(starget);
1208 goto restart;
1182 } 1209 }
1183 } 1210 }
1184 spin_unlock_irqrestore(shost->host_lock, flags); 1211 spin_unlock_irqrestore(shost->host_lock, flags);
1185
1186 if (last)
1187 scsi_target_reap(last);
1188} 1212}
1189EXPORT_SYMBOL(scsi_remove_target); 1213EXPORT_SYMBOL(scsi_remove_target);
1190 1214