diff options
Diffstat (limited to 'drivers/scsi/scsi_lib.c')
-rw-r--r-- | drivers/scsi/scsi_lib.c | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 6d5c7ff43f5..ec1803a4872 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -74,8 +74,6 @@ struct kmem_cache *scsi_sdb_cache; | |||
74 | */ | 74 | */ |
75 | #define SCSI_QUEUE_DELAY 3 | 75 | #define SCSI_QUEUE_DELAY 3 |
76 | 76 | ||
77 | static void scsi_run_queue(struct request_queue *q); | ||
78 | |||
79 | /* | 77 | /* |
80 | * Function: scsi_unprep_request() | 78 | * Function: scsi_unprep_request() |
81 | * | 79 | * |
@@ -161,7 +159,7 @@ static int __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy) | |||
161 | blk_requeue_request(q, cmd->request); | 159 | blk_requeue_request(q, cmd->request); |
162 | spin_unlock_irqrestore(q->queue_lock, flags); | 160 | spin_unlock_irqrestore(q->queue_lock, flags); |
163 | 161 | ||
164 | scsi_run_queue(q); | 162 | kblockd_schedule_work(q, &device->requeue_work); |
165 | 163 | ||
166 | return 0; | 164 | return 0; |
167 | } | 165 | } |
@@ -400,10 +398,15 @@ static inline int scsi_host_is_busy(struct Scsi_Host *shost) | |||
400 | static void scsi_run_queue(struct request_queue *q) | 398 | static void scsi_run_queue(struct request_queue *q) |
401 | { | 399 | { |
402 | struct scsi_device *sdev = q->queuedata; | 400 | struct scsi_device *sdev = q->queuedata; |
403 | struct Scsi_Host *shost = sdev->host; | 401 | struct Scsi_Host *shost; |
404 | LIST_HEAD(starved_list); | 402 | LIST_HEAD(starved_list); |
405 | unsigned long flags; | 403 | unsigned long flags; |
406 | 404 | ||
405 | /* if the device is dead, sdev will be NULL, so no queue to run */ | ||
406 | if (!sdev) | ||
407 | return; | ||
408 | |||
409 | shost = sdev->host; | ||
407 | if (scsi_target(sdev)->single_lun) | 410 | if (scsi_target(sdev)->single_lun) |
408 | scsi_single_lun_run(sdev); | 411 | scsi_single_lun_run(sdev); |
409 | 412 | ||
@@ -411,8 +414,6 @@ static void scsi_run_queue(struct request_queue *q) | |||
411 | list_splice_init(&shost->starved_list, &starved_list); | 414 | list_splice_init(&shost->starved_list, &starved_list); |
412 | 415 | ||
413 | while (!list_empty(&starved_list)) { | 416 | while (!list_empty(&starved_list)) { |
414 | int flagset; | ||
415 | |||
416 | /* | 417 | /* |
417 | * As long as shost is accepting commands and we have | 418 | * As long as shost is accepting commands and we have |
418 | * starved queues, call blk_run_queue. scsi_request_fn | 419 | * starved queues, call blk_run_queue. scsi_request_fn |
@@ -436,18 +437,9 @@ static void scsi_run_queue(struct request_queue *q) | |||
436 | } | 437 | } |
437 | 438 | ||
438 | spin_unlock(shost->host_lock); | 439 | spin_unlock(shost->host_lock); |
439 | |||
440 | spin_lock(sdev->request_queue->queue_lock); | 440 | spin_lock(sdev->request_queue->queue_lock); |
441 | flagset = test_bit(QUEUE_FLAG_REENTER, &q->queue_flags) && | 441 | __blk_run_queue(sdev->request_queue); |
442 | !test_bit(QUEUE_FLAG_REENTER, | ||
443 | &sdev->request_queue->queue_flags); | ||
444 | if (flagset) | ||
445 | queue_flag_set(QUEUE_FLAG_REENTER, sdev->request_queue); | ||
446 | __blk_run_queue(sdev->request_queue, false); | ||
447 | if (flagset) | ||
448 | queue_flag_clear(QUEUE_FLAG_REENTER, sdev->request_queue); | ||
449 | spin_unlock(sdev->request_queue->queue_lock); | 442 | spin_unlock(sdev->request_queue->queue_lock); |
450 | |||
451 | spin_lock(shost->host_lock); | 443 | spin_lock(shost->host_lock); |
452 | } | 444 | } |
453 | /* put any unprocessed entries back */ | 445 | /* put any unprocessed entries back */ |
@@ -457,6 +449,16 @@ static void scsi_run_queue(struct request_queue *q) | |||
457 | blk_run_queue(q); | 449 | blk_run_queue(q); |
458 | } | 450 | } |
459 | 451 | ||
452 | void scsi_requeue_run_queue(struct work_struct *work) | ||
453 | { | ||
454 | struct scsi_device *sdev; | ||
455 | struct request_queue *q; | ||
456 | |||
457 | sdev = container_of(work, struct scsi_device, requeue_work); | ||
458 | q = sdev->request_queue; | ||
459 | scsi_run_queue(q); | ||
460 | } | ||
461 | |||
460 | /* | 462 | /* |
461 | * Function: scsi_requeue_command() | 463 | * Function: scsi_requeue_command() |
462 | * | 464 | * |