diff options
Diffstat (limited to 'drivers/ide/ide-iops.c')
-rw-r--r-- | drivers/ide/ide-iops.c | 154 |
1 files changed, 44 insertions, 110 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 16b1f6e12781..c32e759df208 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -163,8 +163,6 @@ void SELECT_DRIVE (ide_drive_t *drive) | |||
163 | HWIF(drive)->OUTB(drive->select.all, IDE_SELECT_REG); | 163 | HWIF(drive)->OUTB(drive->select.all, IDE_SELECT_REG); |
164 | } | 164 | } |
165 | 165 | ||
166 | EXPORT_SYMBOL(SELECT_DRIVE); | ||
167 | |||
168 | void SELECT_MASK (ide_drive_t *drive, int mask) | 166 | void SELECT_MASK (ide_drive_t *drive, int mask) |
169 | { | 167 | { |
170 | if (HWIF(drive)->maskproc) | 168 | if (HWIF(drive)->maskproc) |
@@ -432,10 +430,10 @@ int drive_is_ready (ide_drive_t *drive) | |||
432 | * about possible isa-pnp and pci-pnp issues yet. | 430 | * about possible isa-pnp and pci-pnp issues yet. |
433 | */ | 431 | */ |
434 | if (IDE_CONTROL_REG) | 432 | if (IDE_CONTROL_REG) |
435 | stat = hwif->INB(IDE_ALTSTATUS_REG); | 433 | stat = ide_read_altstatus(drive); |
436 | else | 434 | else |
437 | /* Note: this may clear a pending IRQ!! */ | 435 | /* Note: this may clear a pending IRQ!! */ |
438 | stat = hwif->INB(IDE_STATUS_REG); | 436 | stat = ide_read_status(drive); |
439 | 437 | ||
440 | if (stat & BUSY_STAT) | 438 | if (stat & BUSY_STAT) |
441 | /* drive busy: definitely not interrupting */ | 439 | /* drive busy: definitely not interrupting */ |
@@ -460,23 +458,24 @@ EXPORT_SYMBOL(drive_is_ready); | |||
460 | */ | 458 | */ |
461 | static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) | 459 | static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) |
462 | { | 460 | { |
463 | ide_hwif_t *hwif = drive->hwif; | ||
464 | unsigned long flags; | 461 | unsigned long flags; |
465 | int i; | 462 | int i; |
466 | u8 stat; | 463 | u8 stat; |
467 | 464 | ||
468 | udelay(1); /* spec allows drive 400ns to assert "BUSY" */ | 465 | udelay(1); /* spec allows drive 400ns to assert "BUSY" */ |
469 | if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { | 466 | stat = ide_read_status(drive); |
467 | |||
468 | if (stat & BUSY_STAT) { | ||
470 | local_irq_set(flags); | 469 | local_irq_set(flags); |
471 | timeout += jiffies; | 470 | timeout += jiffies; |
472 | while ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { | 471 | while ((stat = ide_read_status(drive)) & BUSY_STAT) { |
473 | if (time_after(jiffies, timeout)) { | 472 | if (time_after(jiffies, timeout)) { |
474 | /* | 473 | /* |
475 | * One last read after the timeout in case | 474 | * One last read after the timeout in case |
476 | * heavy interrupt load made us not make any | 475 | * heavy interrupt load made us not make any |
477 | * progress during the timeout.. | 476 | * progress during the timeout.. |
478 | */ | 477 | */ |
479 | stat = hwif->INB(IDE_STATUS_REG); | 478 | stat = ide_read_status(drive); |
480 | if (!(stat & BUSY_STAT)) | 479 | if (!(stat & BUSY_STAT)) |
481 | break; | 480 | break; |
482 | 481 | ||
@@ -496,7 +495,9 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti | |||
496 | */ | 495 | */ |
497 | for (i = 0; i < 10; i++) { | 496 | for (i = 0; i < 10; i++) { |
498 | udelay(1); | 497 | udelay(1); |
499 | if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), good, bad)) { | 498 | stat = ide_read_status(drive); |
499 | |||
500 | if (OK_STAT(stat, good, bad)) { | ||
500 | *rstat = stat; | 501 | *rstat = stat; |
501 | return 0; | 502 | return 0; |
502 | } | 503 | } |
@@ -614,71 +615,12 @@ no_80w: | |||
614 | return 0; | 615 | return 0; |
615 | } | 616 | } |
616 | 617 | ||
617 | int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) | ||
618 | { | ||
619 | if (args->tf.command == WIN_SETFEATURES && | ||
620 | args->tf.nsect > XFER_UDMA_2 && | ||
621 | args->tf.feature == SETFEATURES_XFER) { | ||
622 | if (eighty_ninty_three(drive) == 0) { | ||
623 | printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot " | ||
624 | "be set\n", drive->name); | ||
625 | return 1; | ||
626 | } | ||
627 | } | ||
628 | |||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | /* | ||
633 | * Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER. | ||
634 | * 1 : Safe to update drive->id DMA registers. | ||
635 | * 0 : OOPs not allowed. | ||
636 | */ | ||
637 | int set_transfer (ide_drive_t *drive, ide_task_t *args) | ||
638 | { | ||
639 | if (args->tf.command == WIN_SETFEATURES && | ||
640 | args->tf.nsect >= XFER_SW_DMA_0 && | ||
641 | args->tf.feature == SETFEATURES_XFER && | ||
642 | (drive->id->dma_ultra || | ||
643 | drive->id->dma_mword || | ||
644 | drive->id->dma_1word)) | ||
645 | return 1; | ||
646 | |||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | #ifdef CONFIG_BLK_DEV_IDEDMA | ||
651 | static u8 ide_auto_reduce_xfer (ide_drive_t *drive) | ||
652 | { | ||
653 | if (!drive->crc_count) | ||
654 | return drive->current_speed; | ||
655 | drive->crc_count = 0; | ||
656 | |||
657 | switch(drive->current_speed) { | ||
658 | case XFER_UDMA_7: return XFER_UDMA_6; | ||
659 | case XFER_UDMA_6: return XFER_UDMA_5; | ||
660 | case XFER_UDMA_5: return XFER_UDMA_4; | ||
661 | case XFER_UDMA_4: return XFER_UDMA_3; | ||
662 | case XFER_UDMA_3: return XFER_UDMA_2; | ||
663 | case XFER_UDMA_2: return XFER_UDMA_1; | ||
664 | case XFER_UDMA_1: return XFER_UDMA_0; | ||
665 | /* | ||
666 | * OOPS we do not goto non Ultra DMA modes | ||
667 | * without iCRC's available we force | ||
668 | * the system to PIO and make the user | ||
669 | * invoke the ATA-1 ATA-2 DMA modes. | ||
670 | */ | ||
671 | case XFER_UDMA_0: | ||
672 | default: return XFER_PIO_4; | ||
673 | } | ||
674 | } | ||
675 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | ||
676 | |||
677 | int ide_driveid_update(ide_drive_t *drive) | 618 | int ide_driveid_update(ide_drive_t *drive) |
678 | { | 619 | { |
679 | ide_hwif_t *hwif = drive->hwif; | 620 | ide_hwif_t *hwif = drive->hwif; |
680 | struct hd_driveid *id; | 621 | struct hd_driveid *id; |
681 | unsigned long timeout, flags; | 622 | unsigned long timeout, flags; |
623 | u8 stat; | ||
682 | 624 | ||
683 | /* | 625 | /* |
684 | * Re-read drive->id for possible DMA mode | 626 | * Re-read drive->id for possible DMA mode |
@@ -695,10 +637,15 @@ int ide_driveid_update(ide_drive_t *drive) | |||
695 | SELECT_MASK(drive, 0); | 637 | SELECT_MASK(drive, 0); |
696 | return 0; /* drive timed-out */ | 638 | return 0; /* drive timed-out */ |
697 | } | 639 | } |
640 | |||
698 | msleep(50); /* give drive a breather */ | 641 | msleep(50); /* give drive a breather */ |
699 | } while (hwif->INB(IDE_ALTSTATUS_REG) & BUSY_STAT); | 642 | stat = ide_read_altstatus(drive); |
643 | } while (stat & BUSY_STAT); | ||
644 | |||
700 | msleep(50); /* wait for IRQ and DRQ_STAT */ | 645 | msleep(50); /* wait for IRQ and DRQ_STAT */ |
701 | if (!OK_STAT(hwif->INB(IDE_STATUS_REG),DRQ_STAT,BAD_R_STAT)) { | 646 | stat = ide_read_status(drive); |
647 | |||
648 | if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) { | ||
702 | SELECT_MASK(drive, 0); | 649 | SELECT_MASK(drive, 0); |
703 | printk("%s: CHECK for good STATUS\n", drive->name); | 650 | printk("%s: CHECK for good STATUS\n", drive->name); |
704 | return 0; | 651 | return 0; |
@@ -711,7 +658,7 @@ int ide_driveid_update(ide_drive_t *drive) | |||
711 | return 0; | 658 | return 0; |
712 | } | 659 | } |
713 | ata_input_data(drive, id, SECTOR_WORDS); | 660 | ata_input_data(drive, id, SECTOR_WORDS); |
714 | (void) hwif->INB(IDE_STATUS_REG); /* clear drive IRQ */ | 661 | (void)ide_read_status(drive); /* clear drive IRQ */ |
715 | local_irq_enable(); | 662 | local_irq_enable(); |
716 | local_irq_restore(flags); | 663 | local_irq_restore(flags); |
717 | ide_fix_driveid(id); | 664 | ide_fix_driveid(id); |
@@ -882,22 +829,17 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler, | |||
882 | unsigned long flags; | 829 | unsigned long flags; |
883 | ide_hwgroup_t *hwgroup = HWGROUP(drive); | 830 | ide_hwgroup_t *hwgroup = HWGROUP(drive); |
884 | ide_hwif_t *hwif = HWIF(drive); | 831 | ide_hwif_t *hwif = HWIF(drive); |
885 | 832 | ||
886 | spin_lock_irqsave(&ide_lock, flags); | 833 | spin_lock_irqsave(&ide_lock, flags); |
887 | |||
888 | BUG_ON(hwgroup->handler); | 834 | BUG_ON(hwgroup->handler); |
889 | hwgroup->handler = handler; | 835 | __ide_set_handler(drive, handler, timeout, expiry); |
890 | hwgroup->expiry = expiry; | ||
891 | hwgroup->timer.expires = jiffies + timeout; | ||
892 | hwgroup->req_gen_timer = hwgroup->req_gen; | ||
893 | add_timer(&hwgroup->timer); | ||
894 | hwif->OUTBSYNC(drive, cmd, IDE_COMMAND_REG); | 836 | hwif->OUTBSYNC(drive, cmd, IDE_COMMAND_REG); |
895 | /* Drive takes 400nS to respond, we must avoid the IRQ being | 837 | /* |
896 | serviced before that. | 838 | * Drive takes 400nS to respond, we must avoid the IRQ being |
897 | 839 | * serviced before that. | |
898 | FIXME: we could skip this delay with care on non shared | 840 | * |
899 | devices | 841 | * FIXME: we could skip this delay with care on non shared devices |
900 | */ | 842 | */ |
901 | ndelay(400); | 843 | ndelay(400); |
902 | spin_unlock_irqrestore(&ide_lock, flags); | 844 | spin_unlock_irqrestore(&ide_lock, flags); |
903 | } | 845 | } |
@@ -917,17 +859,16 @@ static ide_startstop_t do_reset1 (ide_drive_t *, int); | |||
917 | static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) | 859 | static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) |
918 | { | 860 | { |
919 | ide_hwgroup_t *hwgroup = HWGROUP(drive); | 861 | ide_hwgroup_t *hwgroup = HWGROUP(drive); |
920 | ide_hwif_t *hwif = HWIF(drive); | ||
921 | u8 stat; | 862 | u8 stat; |
922 | 863 | ||
923 | SELECT_DRIVE(drive); | 864 | SELECT_DRIVE(drive); |
924 | udelay (10); | 865 | udelay (10); |
866 | stat = ide_read_status(drive); | ||
925 | 867 | ||
926 | if (OK_STAT(stat = hwif->INB(IDE_STATUS_REG), 0, BUSY_STAT)) { | 868 | if (OK_STAT(stat, 0, BUSY_STAT)) |
927 | printk("%s: ATAPI reset complete\n", drive->name); | 869 | printk("%s: ATAPI reset complete\n", drive->name); |
928 | } else { | 870 | else { |
929 | if (time_before(jiffies, hwgroup->poll_timeout)) { | 871 | if (time_before(jiffies, hwgroup->poll_timeout)) { |
930 | BUG_ON(HWGROUP(drive)->handler != NULL); | ||
931 | ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); | 872 | ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); |
932 | /* continue polling */ | 873 | /* continue polling */ |
933 | return ide_started; | 874 | return ide_started; |
@@ -965,9 +906,10 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
965 | } | 906 | } |
966 | } | 907 | } |
967 | 908 | ||
968 | if (!OK_STAT(tmp = hwif->INB(IDE_STATUS_REG), 0, BUSY_STAT)) { | 909 | tmp = ide_read_status(drive); |
910 | |||
911 | if (!OK_STAT(tmp, 0, BUSY_STAT)) { | ||
969 | if (time_before(jiffies, hwgroup->poll_timeout)) { | 912 | if (time_before(jiffies, hwgroup->poll_timeout)) { |
970 | BUG_ON(HWGROUP(drive)->handler != NULL); | ||
971 | ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); | 913 | ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); |
972 | /* continue polling */ | 914 | /* continue polling */ |
973 | return ide_started; | 915 | return ide_started; |
@@ -976,7 +918,9 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
976 | drive->failures++; | 918 | drive->failures++; |
977 | } else { | 919 | } else { |
978 | printk("%s: reset: ", hwif->name); | 920 | printk("%s: reset: ", hwif->name); |
979 | if ((tmp = hwif->INB(IDE_ERROR_REG)) == 1) { | 921 | tmp = ide_read_error(drive); |
922 | |||
923 | if (tmp == 1) { | ||
980 | printk("success\n"); | 924 | printk("success\n"); |
981 | drive->failures = 0; | 925 | drive->failures = 0; |
982 | } else { | 926 | } else { |
@@ -1005,19 +949,6 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
1005 | return ide_stopped; | 949 | return ide_stopped; |
1006 | } | 950 | } |
1007 | 951 | ||
1008 | static void check_dma_crc(ide_drive_t *drive) | ||
1009 | { | ||
1010 | #ifdef CONFIG_BLK_DEV_IDEDMA | ||
1011 | if (drive->crc_count) { | ||
1012 | ide_dma_off_quietly(drive); | ||
1013 | ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive)); | ||
1014 | if (drive->current_speed >= XFER_SW_DMA_0) | ||
1015 | ide_dma_on(drive); | ||
1016 | } else | ||
1017 | ide_dma_off(drive); | ||
1018 | #endif | ||
1019 | } | ||
1020 | |||
1021 | static void ide_disk_pre_reset(ide_drive_t *drive) | 952 | static void ide_disk_pre_reset(ide_drive_t *drive) |
1022 | { | 953 | { |
1023 | int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1; | 954 | int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1; |
@@ -1039,17 +970,20 @@ static void pre_reset(ide_drive_t *drive) | |||
1039 | else | 970 | else |
1040 | drive->post_reset = 1; | 971 | drive->post_reset = 1; |
1041 | 972 | ||
973 | if (drive->using_dma) { | ||
974 | if (drive->crc_count) | ||
975 | ide_check_dma_crc(drive); | ||
976 | else | ||
977 | ide_dma_off(drive); | ||
978 | } | ||
979 | |||
1042 | if (!drive->keep_settings) { | 980 | if (!drive->keep_settings) { |
1043 | if (drive->using_dma) { | 981 | if (!drive->using_dma) { |
1044 | check_dma_crc(drive); | ||
1045 | } else { | ||
1046 | drive->unmask = 0; | 982 | drive->unmask = 0; |
1047 | drive->io_32bit = 0; | 983 | drive->io_32bit = 0; |
1048 | } | 984 | } |
1049 | return; | 985 | return; |
1050 | } | 986 | } |
1051 | if (drive->using_dma) | ||
1052 | check_dma_crc(drive); | ||
1053 | 987 | ||
1054 | if (HWIF(drive)->pre_reset != NULL) | 988 | if (HWIF(drive)->pre_reset != NULL) |
1055 | HWIF(drive)->pre_reset(drive); | 989 | HWIF(drive)->pre_reset(drive); |