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.c36
1 files changed, 20 insertions, 16 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index c3f67373a4f8..e0bd3f790fca 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -251,6 +251,7 @@ shost_rd_attr(host_busy, "%hu\n");
251shost_rd_attr(cmd_per_lun, "%hd\n"); 251shost_rd_attr(cmd_per_lun, "%hd\n");
252shost_rd_attr(can_queue, "%hd\n"); 252shost_rd_attr(can_queue, "%hd\n");
253shost_rd_attr(sg_tablesize, "%hu\n"); 253shost_rd_attr(sg_tablesize, "%hu\n");
254shost_rd_attr(sg_prot_tablesize, "%hu\n");
254shost_rd_attr(unchecked_isa_dma, "%d\n"); 255shost_rd_attr(unchecked_isa_dma, "%d\n");
255shost_rd_attr(prot_capabilities, "%u\n"); 256shost_rd_attr(prot_capabilities, "%u\n");
256shost_rd_attr(prot_guard_type, "%hd\n"); 257shost_rd_attr(prot_guard_type, "%hd\n");
@@ -262,6 +263,7 @@ static struct attribute *scsi_sysfs_shost_attrs[] = {
262 &dev_attr_cmd_per_lun.attr, 263 &dev_attr_cmd_per_lun.attr,
263 &dev_attr_can_queue.attr, 264 &dev_attr_can_queue.attr,
264 &dev_attr_sg_tablesize.attr, 265 &dev_attr_sg_tablesize.attr,
266 &dev_attr_sg_prot_tablesize.attr,
265 &dev_attr_unchecked_isa_dma.attr, 267 &dev_attr_unchecked_isa_dma.attr,
266 &dev_attr_proc_name.attr, 268 &dev_attr_proc_name.attr,
267 &dev_attr_scan.attr, 269 &dev_attr_scan.attr,
@@ -320,14 +322,9 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
320 kfree(evt); 322 kfree(evt);
321 } 323 }
322 324
323 if (sdev->request_queue) { 325 blk_put_queue(sdev->request_queue);
324 sdev->request_queue->queuedata = NULL; 326 /* NULL queue means the device can't be used */
325 /* user context needed to free queue */ 327 sdev->request_queue = NULL;
326 scsi_free_queue(sdev->request_queue);
327 /* temporary expedient, try to catch use of queue lock
328 * after free of sdev */
329 sdev->request_queue = NULL;
330 }
331 328
332 scsi_target_reap(scsi_target(sdev)); 329 scsi_target_reap(scsi_target(sdev));
333 330
@@ -381,7 +378,7 @@ struct bus_type scsi_bus_type = {
381 .name = "scsi", 378 .name = "scsi",
382 .match = scsi_bus_match, 379 .match = scsi_bus_match,
383 .uevent = scsi_bus_uevent, 380 .uevent = scsi_bus_uevent,
384#ifdef CONFIG_PM_OPS 381#ifdef CONFIG_PM
385 .pm = &scsi_bus_pm_ops, 382 .pm = &scsi_bus_pm_ops,
386#endif 383#endif
387}; 384};
@@ -862,13 +859,15 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
862 859
863 error = device_add(&sdev->sdev_gendev); 860 error = device_add(&sdev->sdev_gendev);
864 if (error) { 861 if (error) {
865 printk(KERN_INFO "error 1\n"); 862 sdev_printk(KERN_INFO, sdev,
863 "failed to add device: %d\n", error);
866 return error; 864 return error;
867 } 865 }
868 device_enable_async_suspend(&sdev->sdev_dev); 866 device_enable_async_suspend(&sdev->sdev_dev);
869 error = device_add(&sdev->sdev_dev); 867 error = device_add(&sdev->sdev_dev);
870 if (error) { 868 if (error) {
871 printk(KERN_INFO "error 2\n"); 869 sdev_printk(KERN_INFO, sdev,
870 "failed to add class device: %d\n", error);
872 device_del(&sdev->sdev_gendev); 871 device_del(&sdev->sdev_gendev);
873 return error; 872 return error;
874 } 873 }
@@ -933,6 +932,12 @@ void __scsi_remove_device(struct scsi_device *sdev)
933 if (sdev->host->hostt->slave_destroy) 932 if (sdev->host->hostt->slave_destroy)
934 sdev->host->hostt->slave_destroy(sdev); 933 sdev->host->hostt->slave_destroy(sdev);
935 transport_destroy_device(dev); 934 transport_destroy_device(dev);
935
936 /* cause the request function to reject all I/O requests */
937 sdev->request_queue->queuedata = NULL;
938
939 /* Freeing the queue signals to block that we're done */
940 scsi_free_queue(sdev->request_queue);
936 put_device(dev); 941 put_device(dev);
937} 942}
938 943
@@ -962,10 +967,11 @@ static void __scsi_remove_target(struct scsi_target *starget)
962 list_for_each_entry(sdev, &shost->__devices, siblings) { 967 list_for_each_entry(sdev, &shost->__devices, siblings) {
963 if (sdev->channel != starget->channel || 968 if (sdev->channel != starget->channel ||
964 sdev->id != starget->id || 969 sdev->id != starget->id ||
965 sdev->sdev_state == SDEV_DEL) 970 scsi_device_get(sdev))
966 continue; 971 continue;
967 spin_unlock_irqrestore(shost->host_lock, flags); 972 spin_unlock_irqrestore(shost->host_lock, flags);
968 scsi_remove_device(sdev); 973 scsi_remove_device(sdev);
974 scsi_device_put(sdev);
969 spin_lock_irqsave(shost->host_lock, flags); 975 spin_lock_irqsave(shost->host_lock, flags);
970 goto restart; 976 goto restart;
971 } 977 }
@@ -990,16 +996,14 @@ static int __remove_child (struct device * dev, void * data)
990 */ 996 */
991void scsi_remove_target(struct device *dev) 997void scsi_remove_target(struct device *dev)
992{ 998{
993 struct device *rdev;
994
995 if (scsi_is_target_device(dev)) { 999 if (scsi_is_target_device(dev)) {
996 __scsi_remove_target(to_scsi_target(dev)); 1000 __scsi_remove_target(to_scsi_target(dev));
997 return; 1001 return;
998 } 1002 }
999 1003
1000 rdev = get_device(dev); 1004 get_device(dev);
1001 device_for_each_child(dev, NULL, __remove_child); 1005 device_for_each_child(dev, NULL, __remove_child);
1002 put_device(rdev); 1006 put_device(dev);
1003} 1007}
1004EXPORT_SYMBOL(scsi_remove_target); 1008EXPORT_SYMBOL(scsi_remove_target);
1005 1009