diff options
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r-- | drivers/scsi/scsi.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 2ab7df0dcfe8..7a054f9d1ee3 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -96,7 +96,11 @@ unsigned int scsi_logging_level; | |||
96 | EXPORT_SYMBOL(scsi_logging_level); | 96 | EXPORT_SYMBOL(scsi_logging_level); |
97 | #endif | 97 | #endif |
98 | 98 | ||
99 | const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = { | 99 | /* NB: These are exposed through /proc/scsi/scsi and form part of the ABI. |
100 | * You may not alter any existing entry (although adding new ones is | ||
101 | * encouraged once assigned by ANSI/INCITS T10 | ||
102 | */ | ||
103 | static const char *const scsi_device_types[] = { | ||
100 | "Direct-Access ", | 104 | "Direct-Access ", |
101 | "Sequential-Access", | 105 | "Sequential-Access", |
102 | "Printer ", | 106 | "Printer ", |
@@ -107,13 +111,29 @@ const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = { | |||
107 | "Optical Device ", | 111 | "Optical Device ", |
108 | "Medium Changer ", | 112 | "Medium Changer ", |
109 | "Communications ", | 113 | "Communications ", |
110 | "Unknown ", | 114 | "ASC IT8 ", |
111 | "Unknown ", | 115 | "ASC IT8 ", |
112 | "RAID ", | 116 | "RAID ", |
113 | "Enclosure ", | 117 | "Enclosure ", |
114 | "Direct-Access-RBC", | 118 | "Direct-Access-RBC", |
119 | "Optical card ", | ||
120 | "Bridge controller", | ||
121 | "Object storage ", | ||
122 | "Automation/Drive ", | ||
115 | }; | 123 | }; |
116 | EXPORT_SYMBOL(scsi_device_types); | 124 | |
125 | const char * scsi_device_type(unsigned type) | ||
126 | { | ||
127 | if (type == 0x1e) | ||
128 | return "Well-known LUN "; | ||
129 | if (type == 0x1f) | ||
130 | return "No Device "; | ||
131 | if (type > ARRAY_SIZE(scsi_device_types)) | ||
132 | return "Unknown "; | ||
133 | return scsi_device_types[type]; | ||
134 | } | ||
135 | |||
136 | EXPORT_SYMBOL(scsi_device_type); | ||
117 | 137 | ||
118 | struct scsi_host_cmd_pool { | 138 | struct scsi_host_cmd_pool { |
119 | kmem_cache_t *slab; | 139 | kmem_cache_t *slab; |
@@ -346,7 +366,7 @@ void scsi_log_send(struct scsi_cmnd *cmd) | |||
346 | if (level > 3) { | 366 | if (level > 3) { |
347 | printk(KERN_INFO "buffer = 0x%p, bufflen = %d," | 367 | printk(KERN_INFO "buffer = 0x%p, bufflen = %d," |
348 | " done = 0x%p, queuecommand 0x%p\n", | 368 | " done = 0x%p, queuecommand 0x%p\n", |
349 | cmd->buffer, cmd->bufflen, | 369 | cmd->request_buffer, cmd->request_bufflen, |
350 | cmd->done, | 370 | cmd->done, |
351 | sdev->host->hostt->queuecommand); | 371 | sdev->host->hostt->queuecommand); |
352 | 372 | ||
@@ -661,11 +681,6 @@ void __scsi_done(struct scsi_cmnd *cmd) | |||
661 | */ | 681 | */ |
662 | int scsi_retry_command(struct scsi_cmnd *cmd) | 682 | int scsi_retry_command(struct scsi_cmnd *cmd) |
663 | { | 683 | { |
664 | /* | ||
665 | * Restore the SCSI command state. | ||
666 | */ | ||
667 | scsi_setup_cmd_retry(cmd); | ||
668 | |||
669 | /* | 684 | /* |
670 | * Zero the sense information from the last time we tried | 685 | * Zero the sense information from the last time we tried |
671 | * this command. | 686 | * this command. |
@@ -711,10 +726,6 @@ void scsi_finish_command(struct scsi_cmnd *cmd) | |||
711 | "Notifying upper driver of completion " | 726 | "Notifying upper driver of completion " |
712 | "(result %x)\n", cmd->result)); | 727 | "(result %x)\n", cmd->result)); |
713 | 728 | ||
714 | /* | ||
715 | * We can get here with use_sg=0, causing a panic in the upper level | ||
716 | */ | ||
717 | cmd->use_sg = cmd->old_use_sg; | ||
718 | cmd->done(cmd); | 729 | cmd->done(cmd); |
719 | } | 730 | } |
720 | EXPORT_SYMBOL(scsi_finish_command); | 731 | EXPORT_SYMBOL(scsi_finish_command); |
@@ -844,14 +855,14 @@ EXPORT_SYMBOL(scsi_track_queue_full); | |||
844 | */ | 855 | */ |
845 | int scsi_device_get(struct scsi_device *sdev) | 856 | int scsi_device_get(struct scsi_device *sdev) |
846 | { | 857 | { |
847 | if (sdev->sdev_state == SDEV_DEL || sdev->sdev_state == SDEV_CANCEL) | 858 | if (sdev->sdev_state == SDEV_DEL) |
848 | return -ENXIO; | 859 | return -ENXIO; |
849 | if (!get_device(&sdev->sdev_gendev)) | 860 | if (!get_device(&sdev->sdev_gendev)) |
850 | return -ENXIO; | 861 | return -ENXIO; |
851 | if (!try_module_get(sdev->host->hostt->module)) { | 862 | /* We can fail this if we're doing SCSI operations |
852 | put_device(&sdev->sdev_gendev); | 863 | * from module exit (like cache flush) */ |
853 | return -ENXIO; | 864 | try_module_get(sdev->host->hostt->module); |
854 | } | 865 | |
855 | return 0; | 866 | return 0; |
856 | } | 867 | } |
857 | EXPORT_SYMBOL(scsi_device_get); | 868 | EXPORT_SYMBOL(scsi_device_get); |
@@ -866,7 +877,14 @@ EXPORT_SYMBOL(scsi_device_get); | |||
866 | */ | 877 | */ |
867 | void scsi_device_put(struct scsi_device *sdev) | 878 | void scsi_device_put(struct scsi_device *sdev) |
868 | { | 879 | { |
869 | module_put(sdev->host->hostt->module); | 880 | struct module *module = sdev->host->hostt->module; |
881 | |||
882 | #ifdef CONFIG_MODULE_UNLOAD | ||
883 | /* The module refcount will be zero if scsi_device_get() | ||
884 | * was called from a module removal routine */ | ||
885 | if (module && module_refcount(module) != 0) | ||
886 | module_put(module); | ||
887 | #endif | ||
870 | put_device(&sdev->sdev_gendev); | 888 | put_device(&sdev->sdev_gendev); |
871 | } | 889 | } |
872 | EXPORT_SYMBOL(scsi_device_put); | 890 | EXPORT_SYMBOL(scsi_device_put); |
@@ -1108,6 +1126,8 @@ static int __init init_scsi(void) | |||
1108 | for_each_possible_cpu(i) | 1126 | for_each_possible_cpu(i) |
1109 | INIT_LIST_HEAD(&per_cpu(scsi_done_q, i)); | 1127 | INIT_LIST_HEAD(&per_cpu(scsi_done_q, i)); |
1110 | 1128 | ||
1129 | scsi_netlink_init(); | ||
1130 | |||
1111 | printk(KERN_NOTICE "SCSI subsystem initialized\n"); | 1131 | printk(KERN_NOTICE "SCSI subsystem initialized\n"); |
1112 | return 0; | 1132 | return 0; |
1113 | 1133 | ||
@@ -1128,6 +1148,7 @@ cleanup_queue: | |||
1128 | 1148 | ||
1129 | static void __exit exit_scsi(void) | 1149 | static void __exit exit_scsi(void) |
1130 | { | 1150 | { |
1151 | scsi_netlink_exit(); | ||
1131 | scsi_sysfs_unregister(); | 1152 | scsi_sysfs_unregister(); |
1132 | scsi_exit_sysctl(); | 1153 | scsi_exit_sysctl(); |
1133 | scsi_exit_hosts(); | 1154 | scsi_exit_hosts(); |