aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-10-13 11:47:49 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2007-10-13 11:47:49 -0400
commit74af21cf4d0ab67df53608753a443dc7904ec12e (patch)
tree0e5cbfdc12dbd00fcde2ccf08c7df59e3424ff11 /drivers
parentfd553ce86893e0a54ec0d07d1f1d241f2fb2aef3 (diff)
ide: add __ide_wait_stat() helper
* Split off checking of the status register from ide_wait_stat() to __ide_wait_stat() helper. * Use the new helper in ide_config_drive_speed(). The only change in the functionality is that the function now fails if after 20 sec (WAIT_CMD) device is still busy (BUSY_STAT bit is set) while previously instead of failing the function continued with checking for the correct device status (which would give the device additional 10 usec to clear BUSY_STAT bit). * Remove stale comment for ide_config_drive_speed(). * Remove duplicate comment for ide_wait_stat() from <linux/ide.h>. Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ide/ide-iops.c96
1 files changed, 44 insertions, 52 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index cf0678b61161..fb524cf175d5 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -505,25 +505,19 @@ int wait_for_ready (ide_drive_t *drive, int timeout)
505 * This routine busy-waits for the drive status to be not "busy". 505 * 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 506 * 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 507 * 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. 508 * cases return error -- caller may then invoke ide_error().
509 * 509 *
510 * This routine should get fixed to not hog the cpu during extra long waits.. 510 * 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 511 * 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, 512 * setting a timer to wake up at half second intervals thereafter,
513 * until timeout is achieved, before timing out. 513 * until timeout is achieved, before timing out.
514 */ 514 */
515int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout) 515static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat)
516{ 516{
517 ide_hwif_t *hwif = HWIF(drive); 517 ide_hwif_t *hwif = drive->hwif;
518 u8 stat;
519 int i;
520 unsigned long flags; 518 unsigned long flags;
521 519 int i;
522 /* bail early if we've exceeded max_failures */ 520 u8 stat;
523 if (drive->max_failures && (drive->failures > drive->max_failures)) {
524 *startstop = ide_stopped;
525 return 1;
526 }
527 521
528 udelay(1); /* spec allows drive 400ns to assert "BUSY" */ 522 udelay(1); /* spec allows drive 400ns to assert "BUSY" */
529 if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { 523 if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) {
@@ -541,8 +535,8 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 b
541 break; 535 break;
542 536
543 local_irq_restore(flags); 537 local_irq_restore(flags);
544 *startstop = ide_error(drive, "status timeout", stat); 538 *rstat = stat;
545 return 1; 539 return -EBUSY;
546 } 540 }
547 } 541 }
548 local_irq_restore(flags); 542 local_irq_restore(flags);
@@ -556,11 +550,39 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 b
556 */ 550 */
557 for (i = 0; i < 10; i++) { 551 for (i = 0; i < 10; i++) {
558 udelay(1); 552 udelay(1);
559 if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), good, bad)) 553 if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), good, bad)) {
554 *rstat = stat;
560 return 0; 555 return 0;
556 }
561 } 557 }
562 *startstop = ide_error(drive, "status error", stat); 558 *rstat = stat;
563 return 1; 559 return -EFAULT;
560}
561
562/*
563 * In case of error returns error value after doing "*startstop = ide_error()".
564 * The caller should return the updated value of "startstop" in this case,
565 * "startstop" is unchanged when the function returns 0.
566 */
567int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout)
568{
569 int err;
570 u8 stat;
571
572 /* bail early if we've exceeded max_failures */
573 if (drive->max_failures && (drive->failures > drive->max_failures)) {
574 *startstop = ide_stopped;
575 return 1;
576 }
577
578 err = __ide_wait_stat(drive, good, bad, timeout, &stat);
579
580 if (err) {
581 char *s = (err == -EBUSY) ? "status timeout" : "status error";
582 *startstop = ide_error(drive, s, stat);
583 }
584
585 return err;
564} 586}
565 587
566EXPORT_SYMBOL(ide_wait_stat); 588EXPORT_SYMBOL(ide_wait_stat);
@@ -778,15 +800,10 @@ int ide_driveid_update (ide_drive_t *drive)
778#endif 800#endif
779} 801}
780 802
781/* 803int 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 */
786int ide_config_drive_speed (ide_drive_t *drive, u8 speed)
787{ 804{
788 ide_hwif_t *hwif = HWIF(drive); 805 ide_hwif_t *hwif = drive->hwif;
789 int i, error = 1; 806 int error;
790 u8 stat; 807 u8 stat;
791 808
792// while (HWGROUP(drive)->busy) 809// while (HWGROUP(drive)->busy)
@@ -826,35 +843,10 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed)
826 hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); 843 hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG);
827 if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) 844 if ((IDE_CONTROL_REG) && (drive->quirk_list == 2))
828 hwif->OUTB(drive->ctl, IDE_CONTROL_REG); 845 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 846
844 /* 847 error = __ide_wait_stat(drive, drive->ready_stat,
845 * Allow status to settle, then read it again. 848 BUSY_STAT|DRQ_STAT|ERR_STAT,
846 * A few rare drives vastly violate the 400ns spec here, 849 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 850
859 SELECT_MASK(drive, 0); 851 SELECT_MASK(drive, 0);
860 852