diff options
Diffstat (limited to 'drivers/ide/ide-iops.c')
-rw-r--r-- | drivers/ide/ide-iops.c | 95 |
1 files changed, 64 insertions, 31 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 0a2fd3b37ac4..b762deb2dacb 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -181,7 +181,7 @@ void ide_tf_load(ide_drive_t *drive, ide_task_t *task) | |||
181 | tf_outb(tf->lbah, io_ports->lbah_addr); | 181 | tf_outb(tf->lbah, io_ports->lbah_addr); |
182 | 182 | ||
183 | if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) | 183 | if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) |
184 | tf_outb((tf->device & HIHI) | drive->select.all, | 184 | tf_outb((tf->device & HIHI) | drive->select, |
185 | io_ports->device_addr); | 185 | io_ports->device_addr); |
186 | } | 186 | } |
187 | EXPORT_SYMBOL_GPL(ide_tf_load); | 187 | EXPORT_SYMBOL_GPL(ide_tf_load); |
@@ -647,7 +647,7 @@ u8 eighty_ninty_three (ide_drive_t *drive) | |||
647 | return 1; | 647 | return 1; |
648 | 648 | ||
649 | no_80w: | 649 | no_80w: |
650 | if (drive->udma33_warned == 1) | 650 | if (drive->dev_flags & IDE_DFLAG_UDMA33_WARNED) |
651 | return 0; | 651 | return 0; |
652 | 652 | ||
653 | printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, " | 653 | printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, " |
@@ -655,7 +655,7 @@ no_80w: | |||
655 | drive->name, | 655 | drive->name, |
656 | hwif->cbl == ATA_CBL_PATA80 ? "drive" : "host"); | 656 | hwif->cbl == ATA_CBL_PATA80 ? "drive" : "host"); |
657 | 657 | ||
658 | drive->udma33_warned = 1; | 658 | drive->dev_flags |= IDE_DFLAG_UDMA33_WARNED; |
659 | 659 | ||
660 | return 0; | 660 | return 0; |
661 | } | 661 | } |
@@ -711,7 +711,7 @@ int ide_driveid_update(ide_drive_t *drive) | |||
711 | 711 | ||
712 | kfree(id); | 712 | kfree(id); |
713 | 713 | ||
714 | if (drive->using_dma && ide_id_dma_bug(drive)) | 714 | if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && ide_id_dma_bug(drive)) |
715 | ide_dma_off(drive); | 715 | ide_dma_off(drive); |
716 | 716 | ||
717 | return 1; | 717 | return 1; |
@@ -790,7 +790,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed) | |||
790 | 790 | ||
791 | skip: | 791 | skip: |
792 | #ifdef CONFIG_BLK_DEV_IDEDMA | 792 | #ifdef CONFIG_BLK_DEV_IDEDMA |
793 | if (speed >= XFER_SW_DMA_0 && drive->using_dma) | 793 | if (speed >= XFER_SW_DMA_0 && (drive->dev_flags & IDE_DFLAG_USING_DMA)) |
794 | hwif->dma_ops->dma_host_set(drive, 1); | 794 | hwif->dma_ops->dma_host_set(drive, 1); |
795 | else if (hwif->dma_ops) /* check if host supports DMA */ | 795 | else if (hwif->dma_ops) /* check if host supports DMA */ |
796 | ide_dma_off_quietly(drive); | 796 | ide_dma_off_quietly(drive); |
@@ -940,6 +940,25 @@ static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) | |||
940 | return ide_stopped; | 940 | return ide_stopped; |
941 | } | 941 | } |
942 | 942 | ||
943 | static void ide_reset_report_error(ide_hwif_t *hwif, u8 err) | ||
944 | { | ||
945 | static const char *err_master_vals[] = | ||
946 | { NULL, "passed", "formatter device error", | ||
947 | "sector buffer error", "ECC circuitry error", | ||
948 | "controlling MPU error" }; | ||
949 | |||
950 | u8 err_master = err & 0x7f; | ||
951 | |||
952 | printk(KERN_ERR "%s: reset: master: ", hwif->name); | ||
953 | if (err_master && err_master < 6) | ||
954 | printk(KERN_CONT "%s", err_master_vals[err_master]); | ||
955 | else | ||
956 | printk(KERN_CONT "error (0x%02x?)", err); | ||
957 | if (err & 0x80) | ||
958 | printk(KERN_CONT "; slave: failed"); | ||
959 | printk(KERN_CONT "\n"); | ||
960 | } | ||
961 | |||
943 | /* | 962 | /* |
944 | * reset_pollfunc() gets invoked to poll the interface for completion every 50ms | 963 | * reset_pollfunc() gets invoked to poll the interface for completion every 50ms |
945 | * during an ide reset operation. If the drives have not yet responded, | 964 | * during an ide reset operation. If the drives have not yet responded, |
@@ -975,31 +994,14 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
975 | drive->failures++; | 994 | drive->failures++; |
976 | err = -EIO; | 995 | err = -EIO; |
977 | } else { | 996 | } else { |
978 | printk("%s: reset: ", hwif->name); | ||
979 | tmp = ide_read_error(drive); | 997 | tmp = ide_read_error(drive); |
980 | 998 | ||
981 | if (tmp == 1) { | 999 | if (tmp == 1) { |
982 | printk("success\n"); | 1000 | printk(KERN_INFO "%s: reset: success\n", hwif->name); |
983 | drive->failures = 0; | 1001 | drive->failures = 0; |
984 | } else { | 1002 | } else { |
1003 | ide_reset_report_error(hwif, tmp); | ||
985 | drive->failures++; | 1004 | drive->failures++; |
986 | printk("master: "); | ||
987 | switch (tmp & 0x7f) { | ||
988 | case 1: printk("passed"); | ||
989 | break; | ||
990 | case 2: printk("formatter device error"); | ||
991 | break; | ||
992 | case 3: printk("sector buffer error"); | ||
993 | break; | ||
994 | case 4: printk("ECC circuitry error"); | ||
995 | break; | ||
996 | case 5: printk("controlling MPU error"); | ||
997 | break; | ||
998 | default:printk("error (0x%02x?)", tmp); | ||
999 | } | ||
1000 | if (tmp & 0x80) | ||
1001 | printk("; slave: failed"); | ||
1002 | printk("\n"); | ||
1003 | err = -EIO; | 1005 | err = -EIO; |
1004 | } | 1006 | } |
1005 | } | 1007 | } |
@@ -1016,9 +1018,14 @@ static void ide_disk_pre_reset(ide_drive_t *drive) | |||
1016 | drive->special.all = 0; | 1018 | drive->special.all = 0; |
1017 | drive->special.b.set_geometry = legacy; | 1019 | drive->special.b.set_geometry = legacy; |
1018 | drive->special.b.recalibrate = legacy; | 1020 | drive->special.b.recalibrate = legacy; |
1021 | |||
1019 | drive->mult_count = 0; | 1022 | drive->mult_count = 0; |
1020 | if (!drive->keep_settings && !drive->using_dma) | 1023 | drive->dev_flags &= ~IDE_DFLAG_PARKED; |
1024 | |||
1025 | if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 && | ||
1026 | (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) | ||
1021 | drive->mult_req = 0; | 1027 | drive->mult_req = 0; |
1028 | |||
1022 | if (drive->mult_req != drive->mult_count) | 1029 | if (drive->mult_req != drive->mult_count) |
1023 | drive->special.b.set_multmode = 1; | 1030 | drive->special.b.set_multmode = 1; |
1024 | } | 1031 | } |
@@ -1030,18 +1037,18 @@ static void pre_reset(ide_drive_t *drive) | |||
1030 | if (drive->media == ide_disk) | 1037 | if (drive->media == ide_disk) |
1031 | ide_disk_pre_reset(drive); | 1038 | ide_disk_pre_reset(drive); |
1032 | else | 1039 | else |
1033 | drive->post_reset = 1; | 1040 | drive->dev_flags |= IDE_DFLAG_POST_RESET; |
1034 | 1041 | ||
1035 | if (drive->using_dma) { | 1042 | if (drive->dev_flags & IDE_DFLAG_USING_DMA) { |
1036 | if (drive->crc_count) | 1043 | if (drive->crc_count) |
1037 | ide_check_dma_crc(drive); | 1044 | ide_check_dma_crc(drive); |
1038 | else | 1045 | else |
1039 | ide_dma_off(drive); | 1046 | ide_dma_off(drive); |
1040 | } | 1047 | } |
1041 | 1048 | ||
1042 | if (!drive->keep_settings) { | 1049 | if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0) { |
1043 | if (!drive->using_dma) { | 1050 | if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) { |
1044 | drive->unmask = 0; | 1051 | drive->dev_flags &= ~IDE_DFLAG_UNMASK; |
1045 | drive->io_32bit = 0; | 1052 | drive->io_32bit = 0; |
1046 | } | 1053 | } |
1047 | return; | 1054 | return; |
@@ -1073,12 +1080,13 @@ static void pre_reset(ide_drive_t *drive) | |||
1073 | static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | 1080 | static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) |
1074 | { | 1081 | { |
1075 | unsigned int unit; | 1082 | unsigned int unit; |
1076 | unsigned long flags; | 1083 | unsigned long flags, timeout; |
1077 | ide_hwif_t *hwif; | 1084 | ide_hwif_t *hwif; |
1078 | ide_hwgroup_t *hwgroup; | 1085 | ide_hwgroup_t *hwgroup; |
1079 | struct ide_io_ports *io_ports; | 1086 | struct ide_io_ports *io_ports; |
1080 | const struct ide_tp_ops *tp_ops; | 1087 | const struct ide_tp_ops *tp_ops; |
1081 | const struct ide_port_ops *port_ops; | 1088 | const struct ide_port_ops *port_ops; |
1089 | DEFINE_WAIT(wait); | ||
1082 | 1090 | ||
1083 | spin_lock_irqsave(&ide_lock, flags); | 1091 | spin_lock_irqsave(&ide_lock, flags); |
1084 | hwif = HWIF(drive); | 1092 | hwif = HWIF(drive); |
@@ -1105,6 +1113,31 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1105 | return ide_started; | 1113 | return ide_started; |
1106 | } | 1114 | } |
1107 | 1115 | ||
1116 | /* We must not disturb devices in the IDE_DFLAG_PARKED state. */ | ||
1117 | do { | ||
1118 | unsigned long now; | ||
1119 | |||
1120 | prepare_to_wait(&ide_park_wq, &wait, TASK_UNINTERRUPTIBLE); | ||
1121 | timeout = jiffies; | ||
1122 | for (unit = 0; unit < MAX_DRIVES; unit++) { | ||
1123 | ide_drive_t *tdrive = &hwif->drives[unit]; | ||
1124 | |||
1125 | if (tdrive->dev_flags & IDE_DFLAG_PRESENT && | ||
1126 | tdrive->dev_flags & IDE_DFLAG_PARKED && | ||
1127 | time_after(tdrive->sleep, timeout)) | ||
1128 | timeout = tdrive->sleep; | ||
1129 | } | ||
1130 | |||
1131 | now = jiffies; | ||
1132 | if (time_before_eq(timeout, now)) | ||
1133 | break; | ||
1134 | |||
1135 | spin_unlock_irqrestore(&ide_lock, flags); | ||
1136 | timeout = schedule_timeout_uninterruptible(timeout - now); | ||
1137 | spin_lock_irqsave(&ide_lock, flags); | ||
1138 | } while (timeout); | ||
1139 | finish_wait(&ide_park_wq, &wait); | ||
1140 | |||
1108 | /* | 1141 | /* |
1109 | * First, reset any device state data we were maintaining | 1142 | * First, reset any device state data we were maintaining |
1110 | * for any of the drives on this interface. | 1143 | * for any of the drives on this interface. |