Commit e1eec525 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] IDE 107

 - Fix "temporal anomaly" in do_ide_request pointed out by Petr
   Vandrovec. Thanks Petr!
parent 2993fd69
...@@ -517,15 +517,16 @@ void ide_stall_queue(struct ata_device *drive, unsigned long timeout) ...@@ -517,15 +517,16 @@ void ide_stall_queue(struct ata_device *drive, unsigned long timeout)
* Issue a new request. * Issue a new request.
* Caller must have already done spin_lock_irqsave(channel->lock, ...) * Caller must have already done spin_lock_irqsave(channel->lock, ...)
*/ */
static void do_request(struct ata_channel *channel) void do_ide_request(request_queue_t *q)
{ {
struct ata_channel *channel = q->queuedata;
while (!test_and_set_bit(IDE_BUSY, channel->active)) {
struct ata_channel *ch; struct ata_channel *ch;
struct ata_device *drive = NULL; struct ata_device *drive = NULL;
unsigned int unit; unsigned int unit;
ide_startstop_t ret; ide_startstop_t ret;
local_irq_disable(); /* necessary paranoia */
/* /*
* Select the next device which will be serviced. This selects * Select the next device which will be serviced. This selects
* only between devices on the same channel, since everything * only between devices on the same channel, since everything
...@@ -753,22 +754,14 @@ static void do_request(struct ata_channel *channel) ...@@ -753,22 +754,14 @@ static void do_request(struct ata_channel *channel)
} while (ret != ATA_OP_CONTINUES); } while (ret != ATA_OP_CONTINUES);
/* make sure the BUSY bit is set */ /* make sure the BUSY bit is set */
/* FIXME: perhaps there is some place where we miss to set it? */ /* FIXME: perhaps there is some place where we miss to set it? */
// set_bit(IDE_BUSY, ch->active); // set_bit(IDE_BUSY, ch->active);
}
void do_ide_request(request_queue_t *q)
{
struct ata_channel *ch = q->queuedata;
while (!test_and_set_bit(IDE_BUSY, ch->active)) {
do_request(ch);
} }
} }
/* /*
* This is our timeout function for all drive operations. But note that it can * This is our timeout function for all drive operations. But note that it can
* also be invoked as a result of a "sleep" operation triggered by the * also be invoked as a result of a "sleep" operation triggered by the
* mod_timer() call in do_request. * mod_timer() call in do_ide_request.
* *
* FIXME: This should take a drive context instead of a channel. * FIXME: This should take a drive context instead of a channel.
* FIXME: This should not explicitly reenter the request handling engine. * FIXME: This should not explicitly reenter the request handling engine.
...@@ -893,7 +886,8 @@ void ide_timer_expiry(unsigned long data) ...@@ -893,7 +886,8 @@ void ide_timer_expiry(unsigned long data)
if (ret == ATA_OP_FINISHED) { if (ret == ATA_OP_FINISHED) {
/* Reenter the request handling engine. */ /* Reenter the request handling engine. */
do_request(ch); clear_bit(IDE_BUSY, ch->active);
do_ide_request(&drive->queue);
} }
} }
spin_unlock_irqrestore(ch->lock, flags); spin_unlock_irqrestore(ch->lock, flags);
...@@ -1050,9 +1044,10 @@ void ata_irq_request(int irq, void *data, struct pt_regs *regs) ...@@ -1050,9 +1044,10 @@ void ata_irq_request(int irq, void *data, struct pt_regs *regs)
* another interrupt. * another interrupt.
*/ */
if (!ch->handler) if (!ch->handler) {
do_request(ch); clear_bit(IDE_BUSY, ch->active);
else do_ide_request(&drive->queue);
} else
printk("%s: %s: huh? expected NULL handler on exit\n", printk("%s: %s: huh? expected NULL handler on exit\n",
drive->name, __FUNCTION__); drive->name, __FUNCTION__);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment