summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r--drivers/scsi/scsi.c61
1 files changed, 41 insertions, 20 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 2ab7df0dcfe..7a054f9d1ee 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -96,7 +96,11 @@ unsigned int scsi_logging_level;
EXPORT_SYMBOL(scsi_logging_level);
#endif
-const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = {
+/* NB: These are exposed through /proc/scsi/scsi and form part of the ABI.
+ * You may not alter any existing entry (although adding new ones is
+ * encouraged once assigned by ANSI/INCITS T10
+ */
+static const char *const scsi_device_types[] = {
"Direct-Access ",
"Sequential-Access",
"Printer ",
@@ -107,13 +111,29 @@ const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = {
"Optical Device ",
"Medium Changer ",
"Communications ",
- "Unknown ",
- "Unknown ",
+ "ASC IT8 ",
+ "ASC IT8 ",
"RAID ",
"Enclosure ",
"Direct-Access-RBC",
+ "Optical card ",
+ "Bridge controller",
+ "Object storage ",
+ "Automation/Drive ",
};
-EXPORT_SYMBOL(scsi_device_types);
+
+const char * scsi_device_type(unsigned type)
+{
+ if (type == 0x1e)
+ return "Well-known LUN ";
+ if (type == 0x1f)
+ return "No Device ";
+ if (type > ARRAY_SIZE(scsi_device_types))
+ return "Unknown ";
+ return scsi_device_types[type];
+}
+
+EXPORT_SYMBOL(scsi_device_type);
struct scsi_host_cmd_pool {
kmem_cache_t *slab;
@@ -346,7 +366,7 @@ void scsi_log_send(struct scsi_cmnd *cmd)
if (level > 3) {
printk(KERN_INFO "buffer = 0x%p, bufflen = %d,"
" done = 0x%p, queuecommand 0x%p\n",
- cmd->buffer, cmd->bufflen,
+ cmd->request_buffer, cmd->request_bufflen,
cmd->done,
sdev->host->hostt->queuecommand);
@@ -661,11 +681,6 @@ void __scsi_done(struct scsi_cmnd *cmd)
*/
int scsi_retry_command(struct scsi_cmnd *cmd)
{
- /*
- * Restore the SCSI command state.
- */
- scsi_setup_cmd_retry(cmd);
-
/*
* Zero the sense information from the last time we tried
* this command.
@@ -711,10 +726,6 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
"Notifying upper driver of completion "
"(result %x)\n", cmd->result));
- /*
- * We can get here with use_sg=0, causing a panic in the upper level
- */
- cmd->use_sg = cmd->old_use_sg;
cmd->done(cmd);
}
EXPORT_SYMBOL(scsi_finish_command);
@@ -844,14 +855,14 @@ EXPORT_SYMBOL(scsi_track_queue_full);
*/
int scsi_device_get(struct scsi_device *sdev)
{
- if (sdev->sdev_state == SDEV_DEL || sdev->sdev_state == SDEV_CANCEL)
+ if (sdev->sdev_state == SDEV_DEL)
return -ENXIO;
if (!get_device(&sdev->sdev_gendev))
return -ENXIO;
- if (!try_module_get(sdev->host->hostt->module)) {
- put_device(&sdev->sdev_gendev);
- return -ENXIO;
- }
+ /* We can fail this if we're doing SCSI operations
+ * from module exit (like cache flush) */
+ try_module_get(sdev->host->hostt->module);
+
return 0;
}
EXPORT_SYMBOL(scsi_device_get);
@@ -866,7 +877,14 @@ EXPORT_SYMBOL(scsi_device_get);
*/
void scsi_device_put(struct scsi_device *sdev)
{
- module_put(sdev->host->hostt->module);
+ struct module *module = sdev->host->hostt->module;
+
+#ifdef CONFIG_MODULE_UNLOAD
+ /* The module refcount will be zero if scsi_device_get()
+ * was called from a module removal routine */
+ if (module && module_refcount(module) != 0)
+ module_put(module);
+#endif
put_device(&sdev->sdev_gendev);
}
EXPORT_SYMBOL(scsi_device_put);
@@ -1108,6 +1126,8 @@ static int __init init_scsi(void)
for_each_possible_cpu(i)
INIT_LIST_HEAD(&per_cpu(scsi_done_q, i));
+ scsi_netlink_init();
+
printk(KERN_NOTICE "SCSI subsystem initialized\n");
return 0;
@@ -1128,6 +1148,7 @@ cleanup_queue:
static void __exit exit_scsi(void)
{
+ scsi_netlink_exit();
scsi_sysfs_unregister();
scsi_exit_sysctl();
scsi_exit_hosts();