Skip to content

Commit

Permalink
ide: improve handling of Power Management requests
Browse files Browse the repository at this point in the history
Make hwif->rq point to PM request during PM sequence and do not allow
any other types of requests to slip in (the old comment was never correct
as there should be no such requests generated during PM sequence).

Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Bartlomiej Zolnierkiewicz authored and David S. Miller committed Jun 24, 2009
1 parent ba9413b commit a1317f7
Showing 1 changed file with 22 additions and 32 deletions.
54 changes: 22 additions & 32 deletions drivers/ide/ide-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -476,10 +476,14 @@ void do_ide_request(struct request_queue *q)

if (!ide_lock_port(hwif)) {
ide_hwif_t *prev_port;

WARN_ON_ONCE(hwif->rq);
repeat:
prev_port = hwif->host->cur_port;

if (drive->dev_flags & IDE_DFLAG_BLOCKED)
rq = hwif->rq;
else
WARN_ON_ONCE(hwif->rq);

if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
time_after(drive->sleep, jiffies)) {
ide_unlock_port(hwif);
Expand All @@ -506,43 +510,29 @@ void do_ide_request(struct request_queue *q)
hwif->cur_dev = drive;
drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);

spin_unlock_irq(&hwif->lock);
spin_lock_irq(q->queue_lock);
/*
* we know that the queue isn't empty, but this can happen
* if the q->prep_rq_fn() decides to kill a request
*/
if (!rq)
if (rq == NULL) {
spin_unlock_irq(&hwif->lock);
spin_lock_irq(q->queue_lock);
/*
* we know that the queue isn't empty, but this can
* happen if ->prep_rq_fn() decides to kill a request
*/
rq = blk_fetch_request(drive->queue);
spin_unlock_irq(q->queue_lock);
spin_lock_irq(&hwif->lock);

spin_unlock_irq(q->queue_lock);
spin_lock_irq(&hwif->lock);

if (!rq) {
ide_unlock_port(hwif);
goto out;
if (rq == NULL) {
ide_unlock_port(hwif);
goto out;
}
}

/*
* Sanity: don't accept a request that isn't a PM request
* if we are currently power managed. This is very important as
* blk_stop_queue() doesn't prevent the blk_fetch_request()
* above to return us whatever is in the queue. Since we call
* ide_do_request() ourselves, we end up taking requests while
* the queue is blocked...
*
* We let requests forced at head of queue with ide-preempt
* though. I hope that doesn't happen too much, hopefully not
* unless the subdriver triggers such a thing in its own PM
* state machine.
* if we are currently power managed.
*/
if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
blk_pm_request(rq) == 0 &&
(rq->cmd_flags & REQ_PREEMPT) == 0) {
/* there should be no pending command at this point */
ide_unlock_port(hwif);
goto plug_device;
}
BUG_ON((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
blk_pm_request(rq) == 0);

hwif->rq = rq;

Expand Down

0 comments on commit a1317f7

Please sign in to comment.