diff options
Diffstat (limited to 'drivers/ide/ide-lib.c')
-rw-r--r-- | drivers/ide/ide-lib.c | 72 |
1 files changed, 42 insertions, 30 deletions
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 074bb32a4a40..92a6c7bcf527 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c | |||
@@ -249,12 +249,34 @@ static int ide_scan_pio_blacklist (char *model) | |||
249 | return -1; | 249 | return -1; |
250 | } | 250 | } |
251 | 251 | ||
252 | unsigned int ide_pio_cycle_time(ide_drive_t *drive, u8 pio) | ||
253 | { | ||
254 | struct hd_driveid *id = drive->id; | ||
255 | int cycle_time = 0; | ||
256 | |||
257 | if (id->field_valid & 2) { | ||
258 | if (id->capability & 8) | ||
259 | cycle_time = id->eide_pio_iordy; | ||
260 | else | ||
261 | cycle_time = id->eide_pio; | ||
262 | } | ||
263 | |||
264 | /* conservative "downgrade" for all pre-ATA2 drives */ | ||
265 | if (pio < 3) { | ||
266 | if (cycle_time && cycle_time < ide_pio_timings[pio].cycle_time) | ||
267 | cycle_time = 0; /* use standard timing */ | ||
268 | } | ||
269 | |||
270 | return cycle_time ? cycle_time : ide_pio_timings[pio].cycle_time; | ||
271 | } | ||
272 | |||
273 | EXPORT_SYMBOL_GPL(ide_pio_cycle_time); | ||
274 | |||
252 | /** | 275 | /** |
253 | * ide_get_best_pio_mode - get PIO mode from drive | 276 | * ide_get_best_pio_mode - get PIO mode from drive |
254 | * @drive: drive to consider | 277 | * @drive: drive to consider |
255 | * @mode_wanted: preferred mode | 278 | * @mode_wanted: preferred mode |
256 | * @max_mode: highest allowed mode | 279 | * @max_mode: highest allowed mode |
257 | * @d: PIO data | ||
258 | * | 280 | * |
259 | * This routine returns the recommended PIO settings for a given drive, | 281 | * This routine returns the recommended PIO settings for a given drive, |
260 | * based on the drive->id information and the ide_pio_blacklist[]. | 282 | * based on the drive->id information and the ide_pio_blacklist[]. |
@@ -263,22 +285,18 @@ static int ide_scan_pio_blacklist (char *model) | |||
263 | * This is used by most chipset support modules when "auto-tuning". | 285 | * This is used by most chipset support modules when "auto-tuning". |
264 | */ | 286 | */ |
265 | 287 | ||
266 | u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_pio_data_t *d) | 288 | u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode) |
267 | { | 289 | { |
268 | int pio_mode; | 290 | int pio_mode; |
269 | int cycle_time = 0; | ||
270 | int use_iordy = 0; | ||
271 | struct hd_driveid* id = drive->id; | 291 | struct hd_driveid* id = drive->id; |
272 | int overridden = 0; | 292 | int overridden = 0; |
273 | 293 | ||
274 | if (mode_wanted != 255) { | 294 | if (mode_wanted != 255) |
275 | pio_mode = mode_wanted; | 295 | return min_t(u8, mode_wanted, max_mode); |
276 | use_iordy = (pio_mode > 2); | 296 | |
277 | } else if (!drive->id) { | 297 | if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_BLACKLIST) == 0 && |
278 | pio_mode = 0; | 298 | (pio_mode = ide_scan_pio_blacklist(id->model)) != -1) { |
279 | } else if ((pio_mode = ide_scan_pio_blacklist(id->model)) != -1) { | 299 | printk(KERN_INFO "%s: is on PIO blacklist\n", drive->name); |
280 | overridden = 1; | ||
281 | use_iordy = (pio_mode > 2); | ||
282 | } else { | 300 | } else { |
283 | pio_mode = id->tPIO; | 301 | pio_mode = id->tPIO; |
284 | if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */ | 302 | if (pio_mode > 2) { /* 2 is maximum allowed tPIO value */ |
@@ -286,9 +304,7 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_p | |||
286 | overridden = 1; | 304 | overridden = 1; |
287 | } | 305 | } |
288 | if (id->field_valid & 2) { /* drive implements ATA2? */ | 306 | if (id->field_valid & 2) { /* drive implements ATA2? */ |
289 | if (id->capability & 8) { /* drive supports use_iordy? */ | 307 | if (id->capability & 8) { /* IORDY supported? */ |
290 | use_iordy = 1; | ||
291 | cycle_time = id->eide_pio_iordy; | ||
292 | if (id->eide_pio_modes & 7) { | 308 | if (id->eide_pio_modes & 7) { |
293 | overridden = 0; | 309 | overridden = 0; |
294 | if (id->eide_pio_modes & 4) | 310 | if (id->eide_pio_modes & 4) |
@@ -298,31 +314,27 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_p | |||
298 | else | 314 | else |
299 | pio_mode = 3; | 315 | pio_mode = 3; |
300 | } | 316 | } |
301 | } else { | ||
302 | cycle_time = id->eide_pio; | ||
303 | } | 317 | } |
304 | } | 318 | } |
305 | 319 | ||
320 | if (overridden) | ||
321 | printk(KERN_INFO "%s: tPIO > 2, assuming tPIO = 2\n", | ||
322 | drive->name); | ||
323 | |||
306 | /* | 324 | /* |
307 | * Conservative "downgrade" for all pre-ATA2 drives | 325 | * Conservative "downgrade" for all pre-ATA2 drives |
308 | */ | 326 | */ |
309 | if (pio_mode && pio_mode < 4) { | 327 | if ((drive->hwif->host_flags & IDE_HFLAG_PIO_NO_DOWNGRADE) == 0 && |
328 | pio_mode && pio_mode < 4) { | ||
310 | pio_mode--; | 329 | pio_mode--; |
311 | overridden = 1; | 330 | printk(KERN_INFO "%s: applying conservative " |
312 | if (cycle_time && cycle_time < ide_pio_timings[pio_mode].cycle_time) | 331 | "PIO \"downgrade\"\n", drive->name); |
313 | cycle_time = 0; /* use standard timing */ | ||
314 | } | 332 | } |
315 | } | 333 | } |
316 | if (pio_mode > max_mode) { | 334 | |
335 | if (pio_mode > max_mode) | ||
317 | pio_mode = max_mode; | 336 | pio_mode = max_mode; |
318 | cycle_time = 0; | 337 | |
319 | } | ||
320 | if (d) { | ||
321 | d->pio_mode = pio_mode; | ||
322 | d->cycle_time = cycle_time ? cycle_time : ide_pio_timings[pio_mode].cycle_time; | ||
323 | d->use_iordy = use_iordy; | ||
324 | d->overridden = overridden; | ||
325 | } | ||
326 | return pio_mode; | 338 | return pio_mode; |
327 | } | 339 | } |
328 | 340 | ||