Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac
[deliverable/linux.git] / drivers / scsi / scsi_lib.c
index 4acf5c284c2e54e0de2b4bf5195b0ce6cb583d42..ffd77739ae3e2bc4bf793fe7b4bb0ed37c3ca8f4 100644 (file)
@@ -68,6 +68,23 @@ static struct scsi_host_sg_pool scsi_sg_pools[] = {
 
 struct kmem_cache *scsi_sdb_cache;
 
+#ifdef CONFIG_ACPI
+#include <acpi/acpi_bus.h>
+
+int scsi_register_acpi_bus_type(struct acpi_bus_type *bus)
+{
+        bus->bus = &scsi_bus_type;
+        return register_acpi_bus_type(bus);
+}
+EXPORT_SYMBOL_GPL(scsi_register_acpi_bus_type);
+
+void scsi_unregister_acpi_bus_type(struct acpi_bus_type *bus)
+{
+       unregister_acpi_bus_type(bus);
+}
+EXPORT_SYMBOL_GPL(scsi_unregister_acpi_bus_type);
+#endif
+
 /*
  * When to reinvoke queueing after a resource shortage. It's 3 msecs to
  * not change behaviour from the previous unplug mechanism, experimentation
@@ -109,7 +126,7 @@ static void scsi_unprep_request(struct request *req)
  * for a requeue after completion, which should only occur in this
  * file.
  */
-static int __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy)
+static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy)
 {
        struct Scsi_Host *host = cmd->device->host;
        struct scsi_device *device = cmd->device;
@@ -155,15 +172,14 @@ static int __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy)
 
        /*
         * Requeue this command.  It will go before all other commands
-        * that are already in the queue.
+        * that are already in the queue. Schedule requeue work under
+        * lock such that the kblockd_schedule_work() call happens
+        * before blk_cleanup_queue() finishes.
         */
        spin_lock_irqsave(q->queue_lock, flags);
        blk_requeue_request(q, cmd->request);
-       spin_unlock_irqrestore(q->queue_lock, flags);
-
        kblockd_schedule_work(q, &device->requeue_work);
-
-       return 0;
+       spin_unlock_irqrestore(q->queue_lock, flags);
 }
 
 /*
@@ -185,9 +201,9 @@ static int __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy)
  * Notes:       This could be called either from an interrupt context or a
  *              normal process context.
  */
-int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
+void scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
 {
-       return __scsi_queue_insert(cmd, reason, 1);
+       __scsi_queue_insert(cmd, reason, 1);
 }
 /**
  * scsi_execute - insert request and wait for the result
@@ -479,15 +495,26 @@ void scsi_requeue_run_queue(struct work_struct *work)
  */
 static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd)
 {
+       struct scsi_device *sdev = cmd->device;
        struct request *req = cmd->request;
        unsigned long flags;
 
+       /*
+        * We need to hold a reference on the device to avoid the queue being
+        * killed after the unlock and before scsi_run_queue is invoked which
+        * may happen because scsi_unprep_request() puts the command which
+        * releases its reference on the device.
+        */
+       get_device(&sdev->sdev_gendev);
+
        spin_lock_irqsave(q->queue_lock, flags);
        scsi_unprep_request(req);
        blk_requeue_request(q, req);
        spin_unlock_irqrestore(q->queue_lock, flags);
 
        scsi_run_queue(q);
+
+       put_device(&sdev->sdev_gendev);
 }
 
 void scsi_next_command(struct scsi_cmnd *cmd)
This page took 0.025495 seconds and 5 git commands to generate.