diff options
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ff5d56b3ee4d..98ee55ced592 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -852,7 +852,7 @@ static void scsi_end_bidi_request(struct scsi_cmnd *cmd) | |||
852 | void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | 852 | void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) |
853 | { | 853 | { |
854 | int result = cmd->result; | 854 | int result = cmd->result; |
855 | int this_count = scsi_bufflen(cmd); | 855 | int this_count; |
856 | struct request_queue *q = cmd->device->request_queue; | 856 | struct request_queue *q = cmd->device->request_queue; |
857 | struct request *req = cmd->request; | 857 | struct request *req = cmd->request; |
858 | int error = 0; | 858 | int error = 0; |
@@ -908,6 +908,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
908 | */ | 908 | */ |
909 | if (scsi_end_request(cmd, error, good_bytes, result == 0) == NULL) | 909 | if (scsi_end_request(cmd, error, good_bytes, result == 0) == NULL) |
910 | return; | 910 | return; |
911 | this_count = blk_rq_bytes(req); | ||
911 | 912 | ||
912 | /* good_bytes = 0, or (inclusive) there were leftovers and | 913 | /* good_bytes = 0, or (inclusive) there were leftovers and |
913 | * result = 0, so scsi_end_request couldn't retry. | 914 | * 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) | |||
1180 | 1181 | ||
1181 | cmd->transfersize = req->data_len; | 1182 | cmd->transfersize = req->data_len; |
1182 | cmd->allowed = req->retries; | 1183 | cmd->allowed = req->retries; |
1183 | cmd->timeout_per_command = req->timeout; | ||
1184 | return BLKPREP_OK; | 1184 | return BLKPREP_OK; |
1185 | } | 1185 | } |
1186 | EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd); | 1186 | EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd); |
@@ -1250,6 +1250,7 @@ int scsi_prep_state_check(struct scsi_device *sdev, struct request *req) | |||
1250 | break; | 1250 | break; |
1251 | case SDEV_QUIESCE: | 1251 | case SDEV_QUIESCE: |
1252 | case SDEV_BLOCK: | 1252 | case SDEV_BLOCK: |
1253 | case SDEV_CREATED_BLOCK: | ||
1253 | /* | 1254 | /* |
1254 | * If the devices is blocked we defer normal commands. | 1255 | * If the devices is blocked we defer normal commands. |
1255 | */ | 1256 | */ |
@@ -1415,17 +1416,26 @@ static void scsi_kill_request(struct request *req, struct request_queue *q) | |||
1415 | spin_unlock(shost->host_lock); | 1416 | spin_unlock(shost->host_lock); |
1416 | spin_lock(sdev->request_queue->queue_lock); | 1417 | spin_lock(sdev->request_queue->queue_lock); |
1417 | 1418 | ||
1418 | __scsi_done(cmd); | 1419 | blk_complete_request(req); |
1419 | } | 1420 | } |
1420 | 1421 | ||
1421 | static void scsi_softirq_done(struct request *rq) | 1422 | static void scsi_softirq_done(struct request *rq) |
1422 | { | 1423 | { |
1423 | struct scsi_cmnd *cmd = rq->completion_data; | 1424 | struct scsi_cmnd *cmd = rq->special; |
1424 | unsigned long wait_for = (cmd->allowed + 1) * cmd->timeout_per_command; | 1425 | unsigned long wait_for = (cmd->allowed + 1) * rq->timeout; |
1425 | int disposition; | 1426 | int disposition; |
1426 | 1427 | ||
1427 | INIT_LIST_HEAD(&cmd->eh_entry); | 1428 | INIT_LIST_HEAD(&cmd->eh_entry); |
1428 | 1429 | ||
1430 | /* | ||
1431 | * Set the serial numbers back to zero | ||
1432 | */ | ||
1433 | cmd->serial_number = 0; | ||
1434 | |||
1435 | atomic_inc(&cmd->device->iodone_cnt); | ||
1436 | if (cmd->result) | ||
1437 | atomic_inc(&cmd->device->ioerr_cnt); | ||
1438 | |||
1429 | disposition = scsi_decide_disposition(cmd); | 1439 | disposition = scsi_decide_disposition(cmd); |
1430 | if (disposition != SUCCESS && | 1440 | if (disposition != SUCCESS && |
1431 | time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) { | 1441 | time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) { |
@@ -1674,6 +1684,7 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) | |||
1674 | 1684 | ||
1675 | blk_queue_prep_rq(q, scsi_prep_fn); | 1685 | blk_queue_prep_rq(q, scsi_prep_fn); |
1676 | blk_queue_softirq_done(q, scsi_softirq_done); | 1686 | blk_queue_softirq_done(q, scsi_softirq_done); |
1687 | blk_queue_rq_timed_out(q, scsi_times_out); | ||
1677 | return q; | 1688 | return q; |
1678 | } | 1689 | } |
1679 | 1690 | ||
@@ -2063,10 +2074,13 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) | |||
2063 | 2074 | ||
2064 | switch (state) { | 2075 | switch (state) { |
2065 | case SDEV_CREATED: | 2076 | case SDEV_CREATED: |
2066 | /* There are no legal states that come back to | 2077 | switch (oldstate) { |
2067 | * created. This is the manually initialised start | 2078 | case SDEV_CREATED_BLOCK: |
2068 | * state */ | 2079 | break; |
2069 | goto illegal; | 2080 | default: |
2081 | goto illegal; | ||
2082 | } | ||
2083 | break; | ||
2070 | 2084 | ||
2071 | case SDEV_RUNNING: | 2085 | case SDEV_RUNNING: |
2072 | switch (oldstate) { | 2086 | switch (oldstate) { |
@@ -2104,8 +2118,17 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) | |||
2104 | 2118 | ||
2105 | case SDEV_BLOCK: | 2119 | case SDEV_BLOCK: |
2106 | switch (oldstate) { | 2120 | switch (oldstate) { |
2107 | case SDEV_CREATED: | ||
2108 | case SDEV_RUNNING: | 2121 | case SDEV_RUNNING: |
2122 | case SDEV_CREATED_BLOCK: | ||
2123 | break; | ||
2124 | default: | ||
2125 | goto illegal; | ||
2126 | } | ||
2127 | break; | ||
2128 | |||
2129 | case SDEV_CREATED_BLOCK: | ||
2130 | switch (oldstate) { | ||
2131 | case SDEV_CREATED: | ||
2109 | break; | 2132 | break; |
2110 | default: | 2133 | default: |
2111 | goto illegal; | 2134 | goto illegal; |
@@ -2393,8 +2416,12 @@ scsi_internal_device_block(struct scsi_device *sdev) | |||
2393 | int err = 0; | 2416 | int err = 0; |
2394 | 2417 | ||
2395 | err = scsi_device_set_state(sdev, SDEV_BLOCK); | 2418 | err = scsi_device_set_state(sdev, SDEV_BLOCK); |
2396 | if (err) | 2419 | if (err) { |
2397 | return err; | 2420 | err = scsi_device_set_state(sdev, SDEV_CREATED_BLOCK); |
2421 | |||
2422 | if (err) | ||
2423 | return err; | ||
2424 | } | ||
2398 | 2425 | ||
2399 | /* | 2426 | /* |
2400 | * The device has transitioned to SDEV_BLOCK. Stop the | 2427 | * The device has transitioned to SDEV_BLOCK. Stop the |
@@ -2437,8 +2464,12 @@ scsi_internal_device_unblock(struct scsi_device *sdev) | |||
2437 | * and goose the device queue if successful. | 2464 | * and goose the device queue if successful. |
2438 | */ | 2465 | */ |
2439 | err = scsi_device_set_state(sdev, SDEV_RUNNING); | 2466 | err = scsi_device_set_state(sdev, SDEV_RUNNING); |
2440 | if (err) | 2467 | if (err) { |
2441 | return err; | 2468 | err = scsi_device_set_state(sdev, SDEV_CREATED); |
2469 | |||
2470 | if (err) | ||
2471 | return err; | ||
2472 | } | ||
2442 | 2473 | ||
2443 | spin_lock_irqsave(q->queue_lock, flags); | 2474 | spin_lock_irqsave(q->queue_lock, flags); |
2444 | blk_start_queue(q); | 2475 | blk_start_queue(q); |