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. |
