diff options
Diffstat (limited to 'drivers/ide/ide-lib.c')
-rw-r--r-- | drivers/ide/ide-lib.c | 78 |
1 files changed, 61 insertions, 17 deletions
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index d97390c0543b..0e2562f0f74e 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c | |||
@@ -349,7 +349,7 @@ void ide_set_pio(ide_drive_t *drive, u8 req_pio) | |||
349 | drive->name, host_pio, req_pio, | 349 | drive->name, host_pio, req_pio, |
350 | req_pio == 255 ? "(auto-tune)" : "", pio); | 350 | req_pio == 255 ? "(auto-tune)" : "", pio); |
351 | 351 | ||
352 | hwif->set_pio_mode(drive, pio); | 352 | (void)ide_set_pio_mode(drive, XFER_PIO_0 + pio); |
353 | } | 353 | } |
354 | 354 | ||
355 | EXPORT_SYMBOL_GPL(ide_set_pio); | 355 | EXPORT_SYMBOL_GPL(ide_set_pio); |
@@ -378,39 +378,83 @@ void ide_toggle_bounce(ide_drive_t *drive, int on) | |||
378 | blk_queue_bounce_limit(drive->queue, addr); | 378 | blk_queue_bounce_limit(drive->queue, addr); |
379 | } | 379 | } |
380 | 380 | ||
381 | int ide_set_pio_mode(ide_drive_t *drive, const u8 mode) | ||
382 | { | ||
383 | ide_hwif_t *hwif = drive->hwif; | ||
384 | |||
385 | if (hwif->set_pio_mode == NULL) | ||
386 | return -1; | ||
387 | |||
388 | /* | ||
389 | * TODO: temporary hack for some legacy host drivers that didn't | ||
390 | * set transfer mode on the device in ->set_pio_mode method... | ||
391 | */ | ||
392 | if (hwif->set_dma_mode == NULL) { | ||
393 | hwif->set_pio_mode(drive, mode - XFER_PIO_0); | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) { | ||
398 | if (ide_config_drive_speed(drive, mode)) | ||
399 | return -1; | ||
400 | hwif->set_pio_mode(drive, mode - XFER_PIO_0); | ||
401 | return 0; | ||
402 | } else { | ||
403 | hwif->set_pio_mode(drive, mode - XFER_PIO_0); | ||
404 | return ide_config_drive_speed(drive, mode); | ||
405 | } | ||
406 | } | ||
407 | |||
408 | int ide_set_dma_mode(ide_drive_t *drive, const u8 mode) | ||
409 | { | ||
410 | ide_hwif_t *hwif = drive->hwif; | ||
411 | |||
412 | if (hwif->set_dma_mode == NULL) | ||
413 | return -1; | ||
414 | |||
415 | if (hwif->host_flags & IDE_HFLAG_POST_SET_MODE) { | ||
416 | if (ide_config_drive_speed(drive, mode)) | ||
417 | return -1; | ||
418 | hwif->set_dma_mode(drive, mode); | ||
419 | return 0; | ||
420 | } else { | ||
421 | hwif->set_dma_mode(drive, mode); | ||
422 | return ide_config_drive_speed(drive, mode); | ||
423 | } | ||
424 | } | ||
425 | |||
426 | EXPORT_SYMBOL_GPL(ide_set_dma_mode); | ||
427 | |||
381 | /** | 428 | /** |
382 | * ide_set_xfer_rate - set transfer rate | 429 | * ide_set_xfer_rate - set transfer rate |
383 | * @drive: drive to set | 430 | * @drive: drive to set |
384 | * @speed: speed to attempt to set | 431 | * @rate: speed to attempt to set |
385 | * | 432 | * |
386 | * General helper for setting the speed of an IDE device. This | 433 | * General helper for setting the speed of an IDE device. This |
387 | * function knows about user enforced limits from the configuration | 434 | * function knows about user enforced limits from the configuration |
388 | * which speedproc() does not. High level drivers should never | 435 | * which ->set_pio_mode/->set_dma_mode does not. |
389 | * invoke speedproc() directly. | ||
390 | */ | 436 | */ |
391 | 437 | ||
392 | int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) | 438 | int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) |
393 | { | 439 | { |
394 | ide_hwif_t *hwif = drive->hwif; | 440 | ide_hwif_t *hwif = drive->hwif; |
395 | 441 | ||
396 | if (hwif->speedproc == NULL) | 442 | if (hwif->set_dma_mode == NULL) |
397 | return -1; | 443 | return -1; |
398 | 444 | ||
399 | rate = ide_rate_filter(drive, rate); | 445 | rate = ide_rate_filter(drive, rate); |
400 | 446 | ||
401 | if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5) { | 447 | if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5) |
402 | if (hwif->set_pio_mode) | 448 | return ide_set_pio_mode(drive, rate); |
403 | hwif->set_pio_mode(drive, rate - XFER_PIO_0); | ||
404 | 449 | ||
405 | /* | 450 | /* |
406 | * FIXME: this is incorrect to return zero here but | 451 | * TODO: transfer modes 0x00-0x07 passed from the user-space are |
407 | * since all users of ide_set_xfer_rate() ignore | 452 | * currently handled here which needs fixing (please note that such |
408 | * the return value it is not a problem currently | 453 | * case could happen iff the transfer mode has already been set on |
409 | */ | 454 | * the device by ide-proc.c::set_xfer_rate()). |
410 | return 0; | 455 | */ |
411 | } | ||
412 | 456 | ||
413 | return hwif->speedproc(drive, rate); | 457 | return ide_set_dma_mode(drive, rate); |
414 | } | 458 | } |
415 | 459 | ||
416 | static void ide_dump_opcode(ide_drive_t *drive) | 460 | static void ide_dump_opcode(ide_drive_t *drive) |