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 ",
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];
}
*/
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);
*/
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);
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;
static void __exit exit_scsi(void)
{
+ scsi_netlink_exit();
scsi_sysfs_unregister();
scsi_exit_sysctl();
scsi_exit_hosts();