]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/scsi.c
[SCSI] raid class: handle component-add errors
[linux-2.6-omap-h63xx.git] / drivers / scsi / scsi.c
index 94df671d776a33b21a442c93d8b6695be3b2e715..a21642e32c42769e6c396f85ecf0fb617c988e0a 100644 (file)
@@ -96,22 +96,26 @@ unsigned int scsi_logging_level;
 EXPORT_SYMBOL(scsi_logging_level);
 #endif
 
+/* 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",
+       "Direct-Access    ",
+       "Sequential-Access",
        "Printer          ",
        "Processor        ",
        "WORM             ",
-       "CD/DVD           ",
+       "CD-ROM           ",
        "Scanner          ",
-       "Optical memory   ",
-       "Media changer    ",
+       "Optical Device   ",
+       "Medium Changer   ",
        "Communications   ",
        "ASC IT8          ",
        "ASC IT8          ",
        "RAID             ",
        "Enclosure        ",
-       "Direct access RBC",
+       "Direct-Access-RBC",
        "Optical card     ",
        "Bridge controller",
        "Object storage   ",
@@ -124,7 +128,7 @@ const char * scsi_device_type(unsigned type)
                return "Well-known LUN   ";
        if (type == 0x1f)
                return "No Device        ";
-       if (type > ARRAY_SIZE(scsi_device_types))
+       if (type >= ARRAY_SIZE(scsi_device_types))
                return "Unknown          ";
        return scsi_device_types[type];
 }
@@ -851,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);
@@ -873,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);
@@ -1115,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;
 
@@ -1135,6 +1148,7 @@ cleanup_queue:
 
 static void __exit exit_scsi(void)
 {
+       scsi_netlink_exit();
        scsi_sysfs_unregister();
        scsi_exit_sysctl();
        scsi_exit_hosts();