diff options
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r-- | drivers/ide/ide-io.c | 58 |
1 files changed, 25 insertions, 33 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index a381be814070..177db6d5b2f5 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -430,6 +430,26 @@ static inline void ide_unlock_host(struct ide_host *host) | |||
430 | } | 430 | } |
431 | } | 431 | } |
432 | 432 | ||
433 | static void __ide_requeue_and_plug(struct request_queue *q, struct request *rq) | ||
434 | { | ||
435 | if (rq) | ||
436 | blk_requeue_request(q, rq); | ||
437 | if (rq || blk_peek_request(q)) { | ||
438 | /* Use 3ms as that was the old plug delay */ | ||
439 | blk_delay_queue(q, 3); | ||
440 | } | ||
441 | } | ||
442 | |||
443 | void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq) | ||
444 | { | ||
445 | struct request_queue *q = drive->queue; | ||
446 | unsigned long flags; | ||
447 | |||
448 | spin_lock_irqsave(q->queue_lock, flags); | ||
449 | __ide_requeue_and_plug(q, rq); | ||
450 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
451 | } | ||
452 | |||
433 | /* | 453 | /* |
434 | * Issue a new request to a device. | 454 | * Issue a new request to a device. |
435 | */ | 455 | */ |
@@ -440,19 +460,7 @@ void do_ide_request(struct request_queue *q) | |||
440 | struct ide_host *host = hwif->host; | 460 | struct ide_host *host = hwif->host; |
441 | struct request *rq = NULL; | 461 | struct request *rq = NULL; |
442 | ide_startstop_t startstop; | 462 | ide_startstop_t startstop; |
443 | 463 | unsigned long queue_run_ms = 3; /* old plug delay */ | |
444 | /* | ||
445 | * drive is doing pre-flush, ordered write, post-flush sequence. even | ||
446 | * though that is 3 requests, it must be seen as a single transaction. | ||
447 | * we must not preempt this drive until that is complete | ||
448 | */ | ||
449 | if (blk_queue_flushing(q)) | ||
450 | /* | ||
451 | * small race where queue could get replugged during | ||
452 | * the 3-request flush cycle, just yank the plug since | ||
453 | * we want it to finish asap | ||
454 | */ | ||
455 | blk_remove_plug(q); | ||
456 | 464 | ||
457 | spin_unlock_irq(q->queue_lock); | 465 | spin_unlock_irq(q->queue_lock); |
458 | 466 | ||
@@ -472,6 +480,9 @@ repeat: | |||
472 | prev_port = hwif->host->cur_port; | 480 | prev_port = hwif->host->cur_port; |
473 | if (drive->dev_flags & IDE_DFLAG_SLEEPING && | 481 | if (drive->dev_flags & IDE_DFLAG_SLEEPING && |
474 | time_after(drive->sleep, jiffies)) { | 482 | time_after(drive->sleep, jiffies)) { |
483 | unsigned long left = jiffies - drive->sleep; | ||
484 | |||
485 | queue_run_ms = jiffies_to_msecs(left + 1); | ||
475 | ide_unlock_port(hwif); | 486 | ide_unlock_port(hwif); |
476 | goto plug_device; | 487 | goto plug_device; |
477 | } | 488 | } |
@@ -559,26 +570,7 @@ plug_device: | |||
559 | ide_unlock_host(host); | 570 | ide_unlock_host(host); |
560 | plug_device_2: | 571 | plug_device_2: |
561 | spin_lock_irq(q->queue_lock); | 572 | spin_lock_irq(q->queue_lock); |
562 | 573 | __ide_requeue_and_plug(q, rq); | |
563 | if (rq) | ||
564 | blk_requeue_request(q, rq); | ||
565 | if (!elv_queue_empty(q)) | ||
566 | blk_plug_device(q); | ||
567 | } | ||
568 | |||
569 | void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq) | ||
570 | { | ||
571 | struct request_queue *q = drive->queue; | ||
572 | unsigned long flags; | ||
573 | |||
574 | spin_lock_irqsave(q->queue_lock, flags); | ||
575 | |||
576 | if (rq) | ||
577 | blk_requeue_request(q, rq); | ||
578 | if (!elv_queue_empty(q)) | ||
579 | blk_plug_device(q); | ||
580 | |||
581 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
582 | } | 574 | } |
583 | 575 | ||
584 | static int drive_is_ready(ide_drive_t *drive) | 576 | static int drive_is_ready(ide_drive_t *drive) |