aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-lib.c')
-rw-r--r--drivers/ide/ide-lib.c78
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
355EXPORT_SYMBOL_GPL(ide_set_pio); 355EXPORT_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
381int 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
408int 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
426EXPORT_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
392int ide_set_xfer_rate(ide_drive_t *drive, u8 rate) 438int 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
416static void ide_dump_opcode(ide_drive_t *drive) 460static void ide_dump_opcode(ide_drive_t *drive)