diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-01-26 14:13:09 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-01-26 14:13:09 -0500 |
commit | 3a5015cc9d7051ce8e706ef48276d8484aac0c4b (patch) | |
tree | 44c983552fb651a887a0276fdd8cc309376f2bfd /drivers/ide/ide-probe.c | |
parent | ce71ed9ba8b558d54c213d372a6cf8b302fa1fa4 (diff) |
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: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r-- | drivers/ide/ide-probe.c | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 9d9f1c6d602a..edf650b20c67 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -382,6 +382,20 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd) | |||
382 | return retval; | 382 | return retval; |
383 | } | 383 | } |
384 | 384 | ||
385 | static int ide_busy_sleep(ide_hwif_t *hwif) | ||
386 | { | ||
387 | unsigned long timeout = jiffies + WAIT_WORSTCASE; | ||
388 | u8 stat; | ||
389 | |||
390 | do { | ||
391 | msleep(50); | ||
392 | stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]); | ||
393 | if ((stat & BUSY_STAT) == 0) | ||
394 | return 0; | ||
395 | } while (time_before(jiffies, timeout)); | ||
396 | |||
397 | return 1; | ||
398 | } | ||
385 | 399 | ||
386 | /** | 400 | /** |
387 | * do_probe - probe an IDE device | 401 | * do_probe - probe an IDE device |
@@ -450,7 +464,6 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
450 | if ((rc == 1 && cmd == WIN_PIDENTIFY) && | 464 | if ((rc == 1 && cmd == WIN_PIDENTIFY) && |
451 | ((drive->autotune == IDE_TUNE_DEFAULT) || | 465 | ((drive->autotune == IDE_TUNE_DEFAULT) || |
452 | (drive->autotune == IDE_TUNE_AUTO))) { | 466 | (drive->autotune == IDE_TUNE_AUTO))) { |
453 | unsigned long timeout; | ||
454 | printk("%s: no response (status = 0x%02x), " | 467 | printk("%s: no response (status = 0x%02x), " |
455 | "resetting drive\n", drive->name, | 468 | "resetting drive\n", drive->name, |
456 | hwif->INB(IDE_STATUS_REG)); | 469 | hwif->INB(IDE_STATUS_REG)); |
@@ -458,10 +471,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
458 | hwif->OUTB(drive->select.all, IDE_SELECT_REG); | 471 | hwif->OUTB(drive->select.all, IDE_SELECT_REG); |
459 | msleep(50); | 472 | msleep(50); |
460 | hwif->OUTB(WIN_SRST, IDE_COMMAND_REG); | 473 | hwif->OUTB(WIN_SRST, IDE_COMMAND_REG); |
461 | timeout = jiffies; | 474 | (void)ide_busy_sleep(hwif); |
462 | while (((hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && | ||
463 | time_before(jiffies, timeout + WAIT_WORSTCASE)) | ||
464 | msleep(50); | ||
465 | rc = try_to_identify(drive, cmd); | 475 | rc = try_to_identify(drive, cmd); |
466 | } | 476 | } |
467 | if (rc == 1) | 477 | if (rc == 1) |
@@ -489,20 +499,16 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
489 | static void enable_nest (ide_drive_t *drive) | 499 | static void enable_nest (ide_drive_t *drive) |
490 | { | 500 | { |
491 | ide_hwif_t *hwif = HWIF(drive); | 501 | ide_hwif_t *hwif = HWIF(drive); |
492 | unsigned long timeout; | ||
493 | 502 | ||
494 | printk("%s: enabling %s -- ", hwif->name, drive->id->model); | 503 | printk("%s: enabling %s -- ", hwif->name, drive->id->model); |
495 | SELECT_DRIVE(drive); | 504 | SELECT_DRIVE(drive); |
496 | msleep(50); | 505 | msleep(50); |
497 | hwif->OUTB(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG); | 506 | hwif->OUTB(EXABYTE_ENABLE_NEST, IDE_COMMAND_REG); |
498 | timeout = jiffies + WAIT_WORSTCASE; | 507 | |
499 | do { | 508 | if (ide_busy_sleep(hwif)) { |
500 | if (time_after(jiffies, timeout)) { | 509 | printk(KERN_CONT "failed (timeout)\n"); |
501 | printk("failed (timeout)\n"); | 510 | return; |
502 | return; | 511 | } |
503 | } | ||
504 | msleep(50); | ||
505 | } while ((hwif->INB(IDE_STATUS_REG)) & BUSY_STAT); | ||
506 | 512 | ||
507 | msleep(50); | 513 | msleep(50); |
508 | 514 | ||
@@ -783,18 +789,11 @@ static void probe_hwif(ide_hwif_t *hwif) | |||
783 | } | 789 | } |
784 | } | 790 | } |
785 | if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) { | 791 | if (hwif->io_ports[IDE_CONTROL_OFFSET] && hwif->reset) { |
786 | unsigned long timeout = jiffies + WAIT_WORSTCASE; | ||
787 | u8 stat; | ||
788 | |||
789 | printk(KERN_WARNING "%s: reset\n", hwif->name); | 792 | printk(KERN_WARNING "%s: reset\n", hwif->name); |
790 | hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]); | 793 | hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]); |
791 | udelay(10); | 794 | udelay(10); |
792 | hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); | 795 | hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); |
793 | do { | 796 | (void)ide_busy_sleep(hwif); |
794 | msleep(50); | ||
795 | stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]); | ||
796 | } while ((stat & BUSY_STAT) && time_after(timeout, jiffies)); | ||
797 | |||
798 | } | 797 | } |
799 | local_irq_restore(flags); | 798 | local_irq_restore(flags); |
800 | /* | 799 | /* |