aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r--drivers/scsi/scsi_lib.c58
1 files changed, 8 insertions, 50 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index e40c8b66da40..ce9d73a292e2 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -254,55 +254,6 @@ void scsi_do_req(struct scsi_request *sreq, const void *cmnd,
254} 254}
255EXPORT_SYMBOL(scsi_do_req); 255EXPORT_SYMBOL(scsi_do_req);
256 256
257/* This is the end routine we get to if a command was never attached
258 * to the request. Simply complete the request without changing
259 * rq_status; this will cause a DRIVER_ERROR. */
260static void scsi_wait_req_end_io(struct request *req)
261{
262 BUG_ON(!req->waiting);
263
264 complete(req->waiting);
265}
266
267void scsi_wait_req(struct scsi_request *sreq, const void *cmnd, void *buffer,
268 unsigned bufflen, int timeout, int retries)
269{
270 DECLARE_COMPLETION(wait);
271 int write = (sreq->sr_data_direction == DMA_TO_DEVICE);
272 struct request *req;
273
274 req = blk_get_request(sreq->sr_device->request_queue, write,
275 __GFP_WAIT);
276 if (bufflen && blk_rq_map_kern(sreq->sr_device->request_queue, req,
277 buffer, bufflen, __GFP_WAIT)) {
278 sreq->sr_result = DRIVER_ERROR << 24;
279 blk_put_request(req);
280 return;
281 }
282
283 req->flags |= REQ_NOMERGE;
284 req->waiting = &wait;
285 req->end_io = scsi_wait_req_end_io;
286 req->cmd_len = COMMAND_SIZE(((u8 *)cmnd)[0]);
287 req->sense = sreq->sr_sense_buffer;
288 req->sense_len = 0;
289 memcpy(req->cmd, cmnd, req->cmd_len);
290 req->timeout = timeout;
291 req->flags |= REQ_BLOCK_PC;
292 req->rq_disk = NULL;
293 blk_insert_request(sreq->sr_device->request_queue, req,
294 sreq->sr_data_direction == DMA_TO_DEVICE, NULL);
295 wait_for_completion(&wait);
296 sreq->sr_request->waiting = NULL;
297 sreq->sr_result = req->errors;
298 if (req->errors)
299 sreq->sr_result |= (DRIVER_ERROR << 24);
300
301 blk_put_request(req);
302}
303
304EXPORT_SYMBOL(scsi_wait_req);
305
306/** 257/**
307 * scsi_execute - insert request and wait for the result 258 * scsi_execute - insert request and wait for the result
308 * @sdev: scsi device 259 * @sdev: scsi device
@@ -591,10 +542,17 @@ static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd)
591 542
592void scsi_next_command(struct scsi_cmnd *cmd) 543void scsi_next_command(struct scsi_cmnd *cmd)
593{ 544{
594 struct request_queue *q = cmd->device->request_queue; 545 struct scsi_device *sdev = cmd->device;
546 struct request_queue *q = sdev->request_queue;
547
548 /* need to hold a reference on the device before we let go of the cmd */
549 get_device(&sdev->sdev_gendev);
595 550
596 scsi_put_command(cmd); 551 scsi_put_command(cmd);
597 scsi_run_queue(q); 552 scsi_run_queue(q);
553
554 /* ok to remove device now */
555 put_device(&sdev->sdev_gendev);
598} 556}
599 557
600void scsi_run_host_queues(struct Scsi_Host *shost) 558void scsi_run_host_queues(struct Scsi_Host *shost)