diff options
Diffstat (limited to 'drivers/ide/ide-iops.c')
-rw-r--r-- | drivers/ide/ide-iops.c | 133 |
1 files changed, 44 insertions, 89 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index cf0678b61161..aa738833bed5 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -473,57 +473,22 @@ int drive_is_ready (ide_drive_t *drive) | |||
473 | EXPORT_SYMBOL(drive_is_ready); | 473 | EXPORT_SYMBOL(drive_is_ready); |
474 | 474 | ||
475 | /* | 475 | /* |
476 | * Global for All, and taken from ide-pmac.c. Can be called | ||
477 | * with spinlock held & IRQs disabled, so don't schedule ! | ||
478 | */ | ||
479 | int wait_for_ready (ide_drive_t *drive, int timeout) | ||
480 | { | ||
481 | ide_hwif_t *hwif = HWIF(drive); | ||
482 | u8 stat = 0; | ||
483 | |||
484 | while(--timeout) { | ||
485 | stat = hwif->INB(IDE_STATUS_REG); | ||
486 | if (!(stat & BUSY_STAT)) { | ||
487 | if (drive->ready_stat == 0) | ||
488 | break; | ||
489 | else if ((stat & drive->ready_stat)||(stat & ERR_STAT)) | ||
490 | break; | ||
491 | } | ||
492 | mdelay(1); | ||
493 | } | ||
494 | if ((stat & ERR_STAT) || timeout <= 0) { | ||
495 | if (stat & ERR_STAT) { | ||
496 | printk(KERN_ERR "%s: wait_for_ready, " | ||
497 | "error status: %x\n", drive->name, stat); | ||
498 | } | ||
499 | return 1; | ||
500 | } | ||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | /* | ||
505 | * This routine busy-waits for the drive status to be not "busy". | 476 | * This routine busy-waits for the drive status to be not "busy". |
506 | * It then checks the status for all of the "good" bits and none | 477 | * It then checks the status for all of the "good" bits and none |
507 | * of the "bad" bits, and if all is okay it returns 0. All other | 478 | * of the "bad" bits, and if all is okay it returns 0. All other |
508 | * cases return 1 after invoking ide_error() -- caller should just return. | 479 | * cases return error -- caller may then invoke ide_error(). |
509 | * | 480 | * |
510 | * This routine should get fixed to not hog the cpu during extra long waits.. | 481 | * This routine should get fixed to not hog the cpu during extra long waits.. |
511 | * That could be done by busy-waiting for the first jiffy or two, and then | 482 | * That could be done by busy-waiting for the first jiffy or two, and then |
512 | * setting a timer to wake up at half second intervals thereafter, | 483 | * setting a timer to wake up at half second intervals thereafter, |
513 | * until timeout is achieved, before timing out. | 484 | * until timeout is achieved, before timing out. |
514 | */ | 485 | */ |
515 | int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout) | 486 | static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) |
516 | { | 487 | { |
517 | ide_hwif_t *hwif = HWIF(drive); | 488 | ide_hwif_t *hwif = drive->hwif; |
518 | u8 stat; | ||
519 | int i; | ||
520 | unsigned long flags; | 489 | unsigned long flags; |
521 | 490 | int i; | |
522 | /* bail early if we've exceeded max_failures */ | 491 | u8 stat; |
523 | if (drive->max_failures && (drive->failures > drive->max_failures)) { | ||
524 | *startstop = ide_stopped; | ||
525 | return 1; | ||
526 | } | ||
527 | 492 | ||
528 | udelay(1); /* spec allows drive 400ns to assert "BUSY" */ | 493 | udelay(1); /* spec allows drive 400ns to assert "BUSY" */ |
529 | if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { | 494 | if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { |
@@ -541,8 +506,8 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 b | |||
541 | break; | 506 | break; |
542 | 507 | ||
543 | local_irq_restore(flags); | 508 | local_irq_restore(flags); |
544 | *startstop = ide_error(drive, "status timeout", stat); | 509 | *rstat = stat; |
545 | return 1; | 510 | return -EBUSY; |
546 | } | 511 | } |
547 | } | 512 | } |
548 | local_irq_restore(flags); | 513 | local_irq_restore(flags); |
@@ -556,11 +521,39 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 b | |||
556 | */ | 521 | */ |
557 | for (i = 0; i < 10; i++) { | 522 | for (i = 0; i < 10; i++) { |
558 | udelay(1); | 523 | udelay(1); |
559 | if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), good, bad)) | 524 | if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), good, bad)) { |
525 | *rstat = stat; | ||
560 | return 0; | 526 | return 0; |
527 | } | ||
561 | } | 528 | } |
562 | *startstop = ide_error(drive, "status error", stat); | 529 | *rstat = stat; |
563 | return 1; | 530 | return -EFAULT; |
531 | } | ||
532 | |||
533 | /* | ||
534 | * In case of error returns error value after doing "*startstop = ide_error()". | ||
535 | * The caller should return the updated value of "startstop" in this case, | ||
536 | * "startstop" is unchanged when the function returns 0. | ||
537 | */ | ||
538 | int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout) | ||
539 | { | ||
540 | int err; | ||
541 | u8 stat; | ||
542 | |||
543 | /* bail early if we've exceeded max_failures */ | ||
544 | if (drive->max_failures && (drive->failures > drive->max_failures)) { | ||
545 | *startstop = ide_stopped; | ||
546 | return 1; | ||
547 | } | ||
548 | |||
549 | err = __ide_wait_stat(drive, good, bad, timeout, &stat); | ||
550 | |||
551 | if (err) { | ||
552 | char *s = (err == -EBUSY) ? "status timeout" : "status error"; | ||
553 | *startstop = ide_error(drive, s, stat); | ||
554 | } | ||
555 | |||
556 | return err; | ||
564 | } | 557 | } |
565 | 558 | ||
566 | EXPORT_SYMBOL(ide_wait_stat); | 559 | EXPORT_SYMBOL(ide_wait_stat); |
@@ -620,15 +613,10 @@ u8 eighty_ninty_three (ide_drive_t *drive) | |||
620 | 613 | ||
621 | /* | 614 | /* |
622 | * FIXME: | 615 | * FIXME: |
623 | * - change master/slave IDENTIFY order | ||
624 | * - force bit13 (80c cable present) check also for !ivb devices | 616 | * - force bit13 (80c cable present) check also for !ivb devices |
625 | * (unless the slave device is pre-ATA3) | 617 | * (unless the slave device is pre-ATA3) |
626 | */ | 618 | */ |
627 | #ifndef CONFIG_IDEDMA_IVB | ||
628 | if ((id->hw_config & 0x4000) || (ivb && (id->hw_config & 0x2000))) | 619 | if ((id->hw_config & 0x4000) || (ivb && (id->hw_config & 0x2000))) |
629 | #else | ||
630 | if (id->hw_config & 0x6000) | ||
631 | #endif | ||
632 | return 1; | 620 | return 1; |
633 | 621 | ||
634 | no_80w: | 622 | no_80w: |
@@ -778,15 +766,10 @@ int ide_driveid_update (ide_drive_t *drive) | |||
778 | #endif | 766 | #endif |
779 | } | 767 | } |
780 | 768 | ||
781 | /* | 769 | int ide_config_drive_speed(ide_drive_t *drive, u8 speed) |
782 | * Similar to ide_wait_stat(), except it never calls ide_error internally. | ||
783 | * | ||
784 | * const char *msg == consider adding for verbose errors. | ||
785 | */ | ||
786 | int ide_config_drive_speed (ide_drive_t *drive, u8 speed) | ||
787 | { | 770 | { |
788 | ide_hwif_t *hwif = HWIF(drive); | 771 | ide_hwif_t *hwif = drive->hwif; |
789 | int i, error = 1; | 772 | int error; |
790 | u8 stat; | 773 | u8 stat; |
791 | 774 | ||
792 | // while (HWGROUP(drive)->busy) | 775 | // while (HWGROUP(drive)->busy) |
@@ -826,35 +809,10 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) | |||
826 | hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); | 809 | hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); |
827 | if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) | 810 | if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) |
828 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); | 811 | hwif->OUTB(drive->ctl, IDE_CONTROL_REG); |
829 | udelay(1); | ||
830 | /* | ||
831 | * Wait for drive to become non-BUSY | ||
832 | */ | ||
833 | if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { | ||
834 | unsigned long flags, timeout; | ||
835 | local_irq_set(flags); | ||
836 | timeout = jiffies + WAIT_CMD; | ||
837 | while ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { | ||
838 | if (time_after(jiffies, timeout)) | ||
839 | break; | ||
840 | } | ||
841 | local_irq_restore(flags); | ||
842 | } | ||
843 | 812 | ||
844 | /* | 813 | error = __ide_wait_stat(drive, drive->ready_stat, |
845 | * Allow status to settle, then read it again. | 814 | BUSY_STAT|DRQ_STAT|ERR_STAT, |
846 | * A few rare drives vastly violate the 400ns spec here, | 815 | WAIT_CMD, &stat); |
847 | * so we'll wait up to 10usec for a "good" status | ||
848 | * rather than expensively fail things immediately. | ||
849 | * This fix courtesy of Matthew Faupel & Niccolo Rigacci. | ||
850 | */ | ||
851 | for (i = 0; i < 10; i++) { | ||
852 | udelay(1); | ||
853 | if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), drive->ready_stat, BUSY_STAT|DRQ_STAT|ERR_STAT)) { | ||
854 | error = 0; | ||
855 | break; | ||
856 | } | ||
857 | } | ||
858 | 816 | ||
859 | SELECT_MASK(drive, 0); | 817 | SELECT_MASK(drive, 0); |
860 | 818 | ||
@@ -899,9 +857,6 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) | |||
899 | return error; | 857 | return error; |
900 | } | 858 | } |
901 | 859 | ||
902 | EXPORT_SYMBOL(ide_config_drive_speed); | ||
903 | |||
904 | |||
905 | /* | 860 | /* |
906 | * This should get invoked any time we exit the driver to | 861 | * This should get invoked any time we exit the driver to |
907 | * wait for an interrupt response from a drive. handler() points | 862 | * wait for an interrupt response from a drive. handler() points |