]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/scsi/scsi_lib.c
Merge branch 'omap-clks3' into devel
[linux-2.6-omap-h63xx.git] / drivers / scsi / scsi_lib.c
index f2f51e0333eb3b8c8cd1b30fcffe22dd92a03284..b82ffd90632e256ca0ce5c7d478dae715f3e8318 100644 (file)
@@ -91,26 +91,19 @@ static void scsi_unprep_request(struct request *req)
        scsi_put_command(cmd);
 }
 
-/*
- * Function:    scsi_queue_insert()
- *
- * Purpose:     Insert a command in the midlevel queue.
- *
- * Arguments:   cmd    - command that we are adding to queue.
- *              reason - why we are inserting command to queue.
- *
- * Lock status: Assumed that lock is not held upon entry.
- *
- * Returns:     Nothing.
- *
- * Notes:       We do this for one of two cases.  Either the host is busy
- *              and it cannot accept any more commands for the time being,
- *              or the device returned QUEUE_FULL and can accept no more
- *              commands.
- * Notes:       This could be called either from an interrupt context or a
- *              normal process context.
+/**
+ * __scsi_queue_insert - private queue insertion
+ * @cmd: The SCSI command being requeued
+ * @reason:  The reason for the requeue
+ * @unbusy: Whether the queue should be unbusied
+ *
+ * This is a private queue insertion.  The public interface
+ * scsi_queue_insert() always assumes the queue should be unbusied
+ * because it's always called before the completion.  This function is
+ * for a requeue after completion, which should only occur in this
+ * file.
  */
-int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
+static int __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy)
 {
        struct Scsi_Host *host = cmd->device->host;
        struct scsi_device *device = cmd->device;
@@ -150,7 +143,8 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
         * Decrement the counters, since these commands are no longer
         * active on the host/device.
         */
-       scsi_device_unbusy(device);
+       if (unbusy)
+               scsi_device_unbusy(device);
 
        /*
         * Requeue this command.  It will go before all other commands
@@ -172,6 +166,29 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
        return 0;
 }
 
+/*
+ * Function:    scsi_queue_insert()
+ *
+ * Purpose:     Insert a command in the midlevel queue.
+ *
+ * Arguments:   cmd    - command that we are adding to queue.
+ *              reason - why we are inserting command to queue.
+ *
+ * Lock status: Assumed that lock is not held upon entry.
+ *
+ * Returns:     Nothing.
+ *
+ * Notes:       We do this for one of two cases.  Either the host is busy
+ *              and it cannot accept any more commands for the time being,
+ *              or the device returned QUEUE_FULL and can accept no more
+ *              commands.
+ * 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)
+{
+       return __scsi_queue_insert(cmd, reason, 1);
+}
 /**
  * scsi_execute - insert request and wait for the result
  * @sdev:      scsi device
@@ -684,6 +701,8 @@ void scsi_run_host_queues(struct Scsi_Host *shost)
                scsi_run_queue(sdev->request_queue);
 }
 
+static void __scsi_release_buffers(struct scsi_cmnd *, int);
+
 /*
  * Function:    scsi_end_request()
  *
@@ -732,6 +751,7 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error,
                                 * leftovers in the front of the
                                 * queue, and goose the queue again.
                                 */
+                               scsi_release_buffers(cmd);
                                scsi_requeue_command(q, cmd);
                                cmd = NULL;
                        }
@@ -743,6 +763,7 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error,
         * This will goose the queue request function at the end, so we don't
         * need to worry about launching another command.
         */
+       __scsi_release_buffers(cmd, 0);
        scsi_next_command(cmd);
        return NULL;
 }
@@ -798,6 +819,26 @@ static void scsi_free_sgtable(struct scsi_data_buffer *sdb)
        __sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS, scsi_sg_free);
 }
 
+static void __scsi_release_buffers(struct scsi_cmnd *cmd, int do_bidi_check)
+{
+
+       if (cmd->sdb.table.nents)
+               scsi_free_sgtable(&cmd->sdb);
+
+       memset(&cmd->sdb, 0, sizeof(cmd->sdb));
+
+       if (do_bidi_check && scsi_bidi_cmnd(cmd)) {
+               struct scsi_data_buffer *bidi_sdb =
+                       cmd->request->next_rq->special;
+               scsi_free_sgtable(bidi_sdb);
+               kmem_cache_free(scsi_sdb_cache, bidi_sdb);
+               cmd->request->next_rq->special = NULL;
+       }
+
+       if (scsi_prot_sg_count(cmd))
+               scsi_free_sgtable(cmd->prot_sdb);
+}
+
 /*
  * Function:    scsi_release_buffers()
  *
@@ -817,21 +858,7 @@ static void scsi_free_sgtable(struct scsi_data_buffer *sdb)
  */
 void scsi_release_buffers(struct scsi_cmnd *cmd)
 {
-       if (cmd->sdb.table.nents)
-               scsi_free_sgtable(&cmd->sdb);
-
-       memset(&cmd->sdb, 0, sizeof(cmd->sdb));
-
-       if (scsi_bidi_cmnd(cmd)) {
-               struct scsi_data_buffer *bidi_sdb =
-                       cmd->request->next_rq->special;
-               scsi_free_sgtable(bidi_sdb);
-               kmem_cache_free(scsi_sdb_cache, bidi_sdb);
-               cmd->request->next_rq->special = NULL;
-       }
-
-       if (scsi_prot_sg_count(cmd))
-               scsi_free_sgtable(cmd->prot_sdb);
+       __scsi_release_buffers(cmd, 1);
 }
 EXPORT_SYMBOL(scsi_release_buffers);
 
@@ -945,7 +972,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
        }
 
        BUG_ON(blk_bidi_rq(req)); /* bidi not support for !blk_pc_request yet */
-       scsi_release_buffers(cmd);
 
        /*
         * Next deal with any sectors which we were able to correctly
@@ -963,6 +989,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                return;
        this_count = blk_rq_bytes(req);
 
+       error = -EIO;
+
        if (host_byte(result) == DID_RESET) {
                /* Third party bus reset or reset for error recovery
                 * reasons.  Just retry the command and see what
@@ -1004,15 +1032,19 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                                /* This will issue a new 6-byte command. */
                                cmd->device->use_10_for_rw = 0;
                                action = ACTION_REPREP;
+                       } else if (sshdr.asc == 0x10) /* DIX */ {
+                               description = "Host Data Integrity Failure";
+                               action = ACTION_FAIL;
+                               error = -EILSEQ;
                        } else
                                action = ACTION_FAIL;
                        break;
                case ABORTED_COMMAND:
+                       action = ACTION_FAIL;
                        if (sshdr.asc == 0x10) { /* DIF */
-                               action = ACTION_FAIL;
-                               description = "Data Integrity Failure";
-                       } else
-                               action = ACTION_RETRY;
+                               description = "Target Data Integrity Failure";
+                               error = -EILSEQ;
+                       }
                        break;
                case NOT_READY:
                        /* If the device is in the process of becoming
@@ -1029,6 +1061,10 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                                case 0x09: /* self test in progress */
                                        action = ACTION_DELAYED_RETRY;
                                        break;
+                               default:
+                                       description = "Device not ready";
+                                       action = ACTION_FAIL;
+                                       break;
                                }
                        } else {
                                description = "Device not ready";
@@ -1052,9 +1088,10 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
        switch (action) {
        case ACTION_FAIL:
                /* Give up and fail the remainder of the request */
+               scsi_release_buffers(cmd);
                if (!(req->cmd_flags & REQ_QUIET)) {
                        if (description)
-                               scmd_printk(KERN_INFO, cmd, "%s",
+                               scmd_printk(KERN_INFO, cmd, "%s\n",
                                            description);
                        scsi_print_result(cmd);
                        if (driver_byte(result) & DRIVER_SENSE)
@@ -1067,15 +1104,16 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
                /* Unprep the request and put it back at the head of the queue.
                 * A new command will be prepared and issued.
                 */
+               scsi_release_buffers(cmd);
                scsi_requeue_command(q, cmd);
                break;
        case ACTION_RETRY:
                /* Retry the same command immediately */
-               scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY);
+               __scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY, 0);
                break;
        case ACTION_DELAYED_RETRY:
                /* Retry the same command after a delay */
-               scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);
+               __scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY, 0);
                break;
        }
 }