ide: drop dsc_handle argument from ide_pc_intr()
[cascardo/linux.git] / drivers / scsi / scsi_lib.c
index ff5d56b..98ee55c 100644 (file)
@@ -852,7 +852,7 @@ static void scsi_end_bidi_request(struct scsi_cmnd *cmd)
 void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 {
        int result = cmd->result;
-       int this_count = scsi_bufflen(cmd);
+       int this_count;
        struct request_queue *q = cmd->device->request_queue;
        struct request *req = cmd->request;
        int error = 0;
@@ -908,6 +908,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
         */
        if (scsi_end_request(cmd, error, good_bytes, result == 0) == NULL)
                return;
+       this_count = blk_rq_bytes(req);
 
        /* good_bytes = 0, or (inclusive) there were leftovers and
         * result = 0, so scsi_end_request couldn't retry.
@@ -1180,7 +1181,6 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)
        
        cmd->transfersize = req->data_len;
        cmd->allowed = req->retries;
-       cmd->timeout_per_command = req->timeout;
        return BLKPREP_OK;
 }
 EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd);
@@ -1250,6 +1250,7 @@ int scsi_prep_state_check(struct scsi_device *sdev, struct request *req)
                        break;
                case SDEV_QUIESCE:
                case SDEV_BLOCK:
+               case SDEV_CREATED_BLOCK:
                        /*
                         * If the devices is blocked we defer normal commands.
                         */
@@ -1415,17 +1416,26 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
        spin_unlock(shost->host_lock);
        spin_lock(sdev->request_queue->queue_lock);
 
-       __scsi_done(cmd);
+       blk_complete_request(req);
 }
 
 static void scsi_softirq_done(struct request *rq)
 {
-       struct scsi_cmnd *cmd = rq->completion_data;
-       unsigned long wait_for = (cmd->allowed + 1) * cmd->timeout_per_command;
+       struct scsi_cmnd *cmd = rq->special;
+       unsigned long wait_for = (cmd->allowed + 1) * rq->timeout;
        int disposition;
 
        INIT_LIST_HEAD(&cmd->eh_entry);
 
+       /*
+        * Set the serial numbers back to zero
+        */
+       cmd->serial_number = 0;
+
+       atomic_inc(&cmd->device->iodone_cnt);
+       if (cmd->result)
+               atomic_inc(&cmd->device->ioerr_cnt);
+
        disposition = scsi_decide_disposition(cmd);
        if (disposition != SUCCESS &&
            time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) {
@@ -1674,6 +1684,7 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev)
 
        blk_queue_prep_rq(q, scsi_prep_fn);
        blk_queue_softirq_done(q, scsi_softirq_done);
+       blk_queue_rq_timed_out(q, scsi_times_out);
        return q;
 }
 
@@ -2063,10 +2074,13 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
 
        switch (state) {
        case SDEV_CREATED:
-               /* There are no legal states that come back to
-                * created.  This is the manually initialised start
-                * state */
-               goto illegal;
+               switch (oldstate) {
+               case SDEV_CREATED_BLOCK:
+                       break;
+               default:
+                       goto illegal;
+               }
+               break;
                        
        case SDEV_RUNNING:
                switch (oldstate) {
@@ -2104,8 +2118,17 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state)
 
        case SDEV_BLOCK:
                switch (oldstate) {
-               case SDEV_CREATED:
                case SDEV_RUNNING:
+               case SDEV_CREATED_BLOCK:
+                       break;
+               default:
+                       goto illegal;
+               }
+               break;
+
+       case SDEV_CREATED_BLOCK:
+               switch (oldstate) {
+               case SDEV_CREATED:
                        break;
                default:
                        goto illegal;
@@ -2393,8 +2416,12 @@ scsi_internal_device_block(struct scsi_device *sdev)
        int err = 0;
 
        err = scsi_device_set_state(sdev, SDEV_BLOCK);
-       if (err)
-               return err;
+       if (err) {
+               err = scsi_device_set_state(sdev, SDEV_CREATED_BLOCK);
+
+               if (err)
+                       return err;
+       }
 
        /* 
         * The device has transitioned to SDEV_BLOCK.  Stop the
@@ -2437,8 +2464,12 @@ scsi_internal_device_unblock(struct scsi_device *sdev)
         * and goose the device queue if successful.  
         */
        err = scsi_device_set_state(sdev, SDEV_RUNNING);
-       if (err)
-               return err;
+       if (err) {
+               err = scsi_device_set_state(sdev, SDEV_CREATED);
+
+               if (err)
+                       return err;
+       }
 
        spin_lock_irqsave(q->queue_lock, flags);
        blk_start_queue(q);