ide: add ide_busy_sleep() helper

Add ide_busy_sleep() helper and use it in do_probe(),
enable_nest() and probe_hwif().

As a nice side-effect this fixes a minor bug in do_probe()
(the code was reading status register without any delay).
Acked-by: default avatarSergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent ce71ed9b
...@@ -382,6 +382,20 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd) ...@@ -382,6 +382,20 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd)
return retval; return retval;
} }
static int ide_busy_sleep(ide_hwif_t *hwif)
{
unsigned long timeout = jiffies + WAIT_WORSTCASE;
u8 stat;
do {
msleep(50);
stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
if ((stat & BUSY_STAT) == 0)
return 0;
} while (time_before(jiffies, timeout));
return 1;
}
/** /**
* do_probe - probe an IDE device * do_probe - probe an IDE device
...@@ -450,7 +464,6 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ...@@ -450,7 +464,6 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
if ((rc == 1 && cmd == WIN_PIDENTIFY) && if ((rc == 1 && cmd == WIN_PIDENTIFY) &&
((drive->autotune == IDE_TUNE_DEFAULT) || ((drive->autotune == IDE_TUNE_DEFAULT) ||
(drive->autotune == IDE_TUNE_AUTO))) { (drive->autotune == IDE_TUNE_AUTO))) {
unsigned long timeout;
printk("%s: no response (status = 0x%02x), " printk("%s: no response (status = 0x%02x), "
"resetting drive\n", drive->name, "resetting drive\n", drive->name,
hwif->INB(IDE_STATUS_REG)); hwif->INB(IDE_STATUS_REG));
...@@ -458,10 +471,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ...@@ -458,10 +471,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
hwif->OUTB(drive->select.all, IDE_SELECT_REG); hwif->OUTB(drive->select.all, IDE_SELECT_REG);
msleep(50); msleep(50);
hwif->OUTB(WIN_SRST, IDE_COMMAND_REG); hwif->OUTB(WIN_SRST, IDE_COMMAND_REG);
timeout = jiffies; (void)ide_busy_sleep(hwif);
while (((hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) &&
time_before(jiffies, timeout + WAIT_WORSTCASE))
msleep(50);
rc = try_to_identify(drive, cmd); rc = try_to_identify(drive, cmd);
} }
if (rc == 1) if (rc == 1)
...@@ -489,20 +499,16 @@ static int do_probe (ide_drive_t *drive, u8 cmd) ...@@ -489,20 +499,16 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
static void enable_nest (ide_drive_t *drive) static void enable_nest (ide_drive_t *drive)
{ {
ide_hwif_t *hwif = HWIF(drive); ide_hwif_t *hwif = HWIF(drive);
unsigned long timeout;
printk("%s: enabling %s -- ", hwif->name, drive->id->model); printk("%s: enabling %s -- ", hwif->name, drive->id->model);
SELECT_DRIVE(drive); SELECT_DRIVE(drive);
msleep(50); msleep(50);
hwif->OUTB(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG); hwif->OUTB(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG);
timeout = jiffies + WAIT_WORSTCASE;
do { if (ide_busy_sleep(hwif)) {
if (time_after(jiffies, timeout)) { printk(KERN_CONT "failed (timeout)\n");
printk("failed (timeout)\n");
return; return;
} }
msleep(50);
} while ((hwif->INB(IDE_STATUS_REG)) & BUSY_STAT);
msleep(50); msleep(50);
...@@ -783,18 +789,11 @@ static void probe_hwif(ide_hwif_t *hwif) ...@@ -783,18 +789,11 @@ static void probe_hwif(ide_hwif_t *hwif)
} }
} }
if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) { if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) {
unsigned long timeout = jiffies + WAIT_WORSTCASE;
u8 stat;
printk(KERN_WARNING "%s: reset\n", hwif->name); printk(KERN_WARNING "%s: reset\n", hwif->name);
hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]); hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
udelay(10); udelay(10);
hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
do { (void)ide_busy_sleep(hwif);
msleep(50);
stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
} while ((stat & BUSY_STAT) && time_after(timeout, jiffies));
} }
local_irq_restore(flags); local_irq_restore(flags);
/* /*
......
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