diff options
Diffstat (limited to 'drivers/ide/ide-iops.c')
-rw-r--r-- | drivers/ide/ide-iops.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 91182ebed468..b762deb2dacb 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -1020,6 +1020,7 @@ static void ide_disk_pre_reset(ide_drive_t *drive) | |||
1020 | drive->special.b.recalibrate = legacy; | 1020 | drive->special.b.recalibrate = legacy; |
1021 | 1021 | ||
1022 | drive->mult_count = 0; | 1022 | drive->mult_count = 0; |
1023 | drive->dev_flags &= ~IDE_DFLAG_PARKED; | ||
1023 | 1024 | ||
1024 | if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 && | 1025 | if ((drive->dev_flags & IDE_DFLAG_KEEP_SETTINGS) == 0 && |
1025 | (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) | 1026 | (drive->dev_flags & IDE_DFLAG_USING_DMA) == 0) |
@@ -1079,12 +1080,13 @@ static void pre_reset(ide_drive_t *drive) | |||
1079 | 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) |
1080 | { | 1081 | { |
1081 | unsigned int unit; | 1082 | unsigned int unit; |
1082 | unsigned long flags; | 1083 | unsigned long flags, timeout; |
1083 | ide_hwif_t *hwif; | 1084 | ide_hwif_t *hwif; |
1084 | ide_hwgroup_t *hwgroup; | 1085 | ide_hwgroup_t *hwgroup; |
1085 | struct ide_io_ports *io_ports; | 1086 | struct ide_io_ports *io_ports; |
1086 | const struct ide_tp_ops *tp_ops; | 1087 | const struct ide_tp_ops *tp_ops; |
1087 | const struct ide_port_ops *port_ops; | 1088 | const struct ide_port_ops *port_ops; |
1089 | DEFINE_WAIT(wait); | ||
1088 | 1090 | ||
1089 | spin_lock_irqsave(&ide_lock, flags); | 1091 | spin_lock_irqsave(&ide_lock, flags); |
1090 | hwif = HWIF(drive); | 1092 | hwif = HWIF(drive); |
@@ -1111,6 +1113,31 @@ static ide_startstop_t do_reset1 (ide_drive_t *drive, int do_not_try_atapi) | |||
1111 | return ide_started; | 1113 | return ide_started; |
1112 | } | 1114 | } |
1113 | 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 | |||
1114 | /* | 1141 | /* |
1115 | * First, reset any device state data we were maintaining | 1142 | * First, reset any device state data we were maintaining |
1116 | * for any of the drives on this interface. | 1143 | * for any of the drives on this interface. |