libsas: remove unused ata_task_resp fields
[pandora-kernel.git] / drivers / scsi / scsi_lib.c
index f85cfa6..823f0e9 100644 (file)
@@ -155,13 +155,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);
+       spin_unlock_irqrestore(q->queue_lock, flags);
 
        return 0;
 }
@@ -406,10 +407,6 @@ static void scsi_run_queue(struct request_queue *q)
        LIST_HEAD(starved_list);
        unsigned long flags;
 
-       /* if the device is dead, sdev will be NULL, so no queue to run */
-       if (!sdev)
-               return;
-
        shost = sdev->host;
        if (scsi_target(sdev)->single_lun)
                scsi_single_lun_run(sdev);
@@ -483,15 +480,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)
@@ -785,6 +793,14 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                        scsi_next_command(cmd);
                        return;
                }
+       } else if (blk_rq_bytes(req) == 0 && result && !sense_deferred) {
+               /*
+                * Certain non BLOCK_PC requests are commands that don't
+                * actually transfer anything (FLUSH), so cannot use
+                * good_bytes != blk_rq_bytes(req) as the signal for an error.
+                * This sets the error explicitly for the problem case.
+                */
+               error = __scsi_error_from_host_byte(cmd, result);
        }
 
        /* no bidi support for !REQ_TYPE_BLOCK_PC yet */
@@ -1190,9 +1206,11 @@ int scsi_prep_state_check(struct scsi_device *sdev, struct request *req)
                                    "rejecting I/O to dead device\n");
                        ret = BLKPREP_KILL;
                        break;
-               case SDEV_QUIESCE:
                case SDEV_BLOCK:
                case SDEV_CREATED_BLOCK:
+                       ret = BLKPREP_DEFER;
+                       break;
+               case SDEV_QUIESCE:
                        /*
                         * If the devices is blocked we defer normal commands.
                         */
@@ -1374,24 +1392,27 @@ static inline int scsi_host_queue_ready(struct request_queue *q,
  * may be changed after request stacking drivers call the function,
  * regardless of taking lock or not.
  *
- * When scsi can't dispatch I/Os anymore and needs to kill I/Os
- * (e.g. !sdev), scsi needs to return 'not busy'.
- * Otherwise, request stacking drivers may hold requests forever.
+ * When scsi can't dispatch I/Os anymore and needs to kill I/Os scsi
+ * needs to return 'not busy'. Otherwise, request stacking drivers
+ * may hold requests forever.
  */
 static int scsi_lld_busy(struct request_queue *q)
 {
        struct scsi_device *sdev = q->queuedata;
        struct Scsi_Host *shost;
-       struct scsi_target *starget;
 
-       if (!sdev)
+       if (blk_queue_dead(q))
                return 0;
 
        shost = sdev->host;
-       starget = scsi_target(sdev);
 
-       if (scsi_host_in_recovery(shost) || scsi_host_is_busy(shost) ||
-           scsi_target_is_busy(starget) || scsi_device_is_busy(sdev))
+       /*
+        * Ignore host/starget busy state.
+        * Since block layer does not have a concept of fairness across
+        * multiple queues, congestion of host/starget needs to be handled
+        * in SCSI layer.
+        */
+       if (scsi_host_in_recovery(shost) || scsi_device_is_busy(sdev))
                return 1;
 
        return 0;
@@ -1491,12 +1512,6 @@ static void scsi_request_fn(struct request_queue *q)
        struct scsi_cmnd *cmd;
        struct request *req;
 
-       if (!sdev) {
-               while ((req = blk_peek_request(q)) != NULL)
-                       scsi_kill_request(req, q);
-               return;
-       }
-
        if(!get_device(&sdev->sdev_gendev))
                /* We must be tearing the block queue down already */
                return;
@@ -1673,11 +1688,13 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
                q->limits.cluster = 0;
 
        /*
-        * set a reasonable default alignment on word boundaries: the
-        * host and device may alter it using
-        * blk_queue_update_dma_alignment() later.
+        * Set a reasonable default alignment:  The larger of 32-byte (dword),
+        * which is a common minimum for HBAs, and the minimum DMA alignment,
+        * which is set by the platform.
+        *
+        * Devices that require a bigger alignment can increase it later.
         */
-       blk_queue_dma_alignment(q, 0x03);
+       blk_queue_dma_alignment(q, max(4, dma_get_cache_alignment()) - 1);
 
        return q;
 }
@@ -1698,20 +1715,6 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
        return q;
 }
 
-void scsi_free_queue(struct request_queue *q)
-{
-       unsigned long flags;
-
-       WARN_ON(q->queuedata);
-
-       /* cause scsi_request_fn() to kill all non-finished requests */
-       spin_lock_irqsave(q->queue_lock, flags);
-       q->request_fn(q);
-       spin_unlock_irqrestore(q->queue_lock, flags);
-
-       blk_cleanup_queue(q);
-}
-
 /*
  * Function:    scsi_block_requests()
  *