diff options
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index d18da21c9c57..9f996499fa9d 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -92,10 +92,12 @@ int scsi_insert_special_req(struct scsi_request *sreq, int at_head) | |||
92 | */ | 92 | */ |
93 | sreq->sr_request->flags &= ~REQ_DONTPREP; | 93 | sreq->sr_request->flags &= ~REQ_DONTPREP; |
94 | blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request, | 94 | blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request, |
95 | at_head, sreq, 0); | 95 | at_head, sreq); |
96 | return 0; | 96 | return 0; |
97 | } | 97 | } |
98 | 98 | ||
99 | static void scsi_run_queue(struct request_queue *q); | ||
100 | |||
99 | /* | 101 | /* |
100 | * Function: scsi_queue_insert() | 102 | * Function: scsi_queue_insert() |
101 | * | 103 | * |
@@ -119,18 +121,14 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason) | |||
119 | { | 121 | { |
120 | struct Scsi_Host *host = cmd->device->host; | 122 | struct Scsi_Host *host = cmd->device->host; |
121 | struct scsi_device *device = cmd->device; | 123 | struct scsi_device *device = cmd->device; |
124 | struct request_queue *q = device->request_queue; | ||
125 | unsigned long flags; | ||
122 | 126 | ||
123 | SCSI_LOG_MLQUEUE(1, | 127 | SCSI_LOG_MLQUEUE(1, |
124 | printk("Inserting command %p into mlqueue\n", cmd)); | 128 | printk("Inserting command %p into mlqueue\n", cmd)); |
125 | 129 | ||
126 | /* | 130 | /* |
127 | * We are inserting the command into the ml queue. First, we | 131 | * Set the appropriate busy bit for the device/host. |
128 | * cancel the timer, so it doesn't time out. | ||
129 | */ | ||
130 | scsi_delete_timer(cmd); | ||
131 | |||
132 | /* | ||
133 | * Next, set the appropriate busy bit for the device/host. | ||
134 | * | 132 | * |
135 | * If the host/device isn't busy, assume that something actually | 133 | * If the host/device isn't busy, assume that something actually |
136 | * completed, and that we should be able to queue a command now. | 134 | * completed, and that we should be able to queue a command now. |
@@ -160,17 +158,22 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason) | |||
160 | scsi_device_unbusy(device); | 158 | scsi_device_unbusy(device); |
161 | 159 | ||
162 | /* | 160 | /* |
163 | * Insert this command at the head of the queue for it's device. | 161 | * Requeue this command. It will go before all other commands |
164 | * It will go before all other commands that are already in the queue. | 162 | * that are already in the queue. |
165 | * | 163 | * |
166 | * NOTE: there is magic here about the way the queue is plugged if | 164 | * NOTE: there is magic here about the way the queue is plugged if |
167 | * we have no outstanding commands. | 165 | * we have no outstanding commands. |
168 | * | 166 | * |
169 | * Although this *doesn't* plug the queue, it does call the request | 167 | * Although we *don't* plug the queue, we call the request |
170 | * function. The SCSI request function detects the blocked condition | 168 | * function. The SCSI request function detects the blocked condition |
171 | * and plugs the queue appropriately. | 169 | * and plugs the queue appropriately. |
172 | */ | 170 | */ |
173 | blk_insert_request(device->request_queue, cmd->request, 1, cmd, 1); | 171 | spin_lock_irqsave(q->queue_lock, flags); |
172 | blk_requeue_request(q, cmd->request); | ||
173 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
174 | |||
175 | scsi_run_queue(q); | ||
176 | |||
174 | return 0; | 177 | return 0; |
175 | } | 178 | } |
176 | 179 | ||
@@ -485,8 +488,13 @@ static void scsi_run_queue(struct request_queue *q) | |||
485 | */ | 488 | */ |
486 | static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd) | 489 | static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd) |
487 | { | 490 | { |
491 | unsigned long flags; | ||
492 | |||
488 | cmd->request->flags &= ~REQ_DONTPREP; | 493 | cmd->request->flags &= ~REQ_DONTPREP; |
489 | blk_insert_request(q, cmd->request, 1, cmd, 1); | 494 | |
495 | spin_lock_irqsave(q->queue_lock, flags); | ||
496 | blk_requeue_request(q, cmd->request); | ||
497 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
490 | 498 | ||
491 | scsi_run_queue(q); | 499 | scsi_run_queue(q); |
492 | } | 500 | } |
@@ -941,10 +949,8 @@ static int scsi_init_io(struct scsi_cmnd *cmd) | |||
941 | * if sg table allocation fails, requeue request later. | 949 | * if sg table allocation fails, requeue request later. |
942 | */ | 950 | */ |
943 | sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC); | 951 | sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC); |
944 | if (unlikely(!sgpnt)) { | 952 | if (unlikely(!sgpnt)) |
945 | req->flags |= REQ_SPECIAL; | ||
946 | return BLKPREP_DEFER; | 953 | return BLKPREP_DEFER; |
947 | } | ||
948 | 954 | ||
949 | cmd->request_buffer = (char *) sgpnt; | 955 | cmd->request_buffer = (char *) sgpnt; |
950 | cmd->request_bufflen = req->nr_sectors << 9; | 956 | cmd->request_bufflen = req->nr_sectors << 9; |