diff options
Diffstat (limited to 'drivers/ide/ide-dma.c')
-rw-r--r-- | drivers/ide/ide-dma.c | 105 |
1 files changed, 64 insertions, 41 deletions
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 56efed6742d4..08e7cd043bcc 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -348,15 +348,14 @@ EXPORT_SYMBOL_GPL(ide_destroy_dmatable); | |||
348 | static int config_drive_for_dma (ide_drive_t *drive) | 348 | static int config_drive_for_dma (ide_drive_t *drive) |
349 | { | 349 | { |
350 | struct hd_driveid *id = drive->id; | 350 | struct hd_driveid *id = drive->id; |
351 | ide_hwif_t *hwif = HWIF(drive); | ||
352 | 351 | ||
353 | if ((id->capability & 1) && hwif->autodma) { | 352 | if ((id->capability & 1) && drive->hwif->autodma) { |
354 | /* | 353 | /* |
355 | * Enable DMA on any drive that has | 354 | * Enable DMA on any drive that has |
356 | * UltraDMA (mode 0/1/2/3/4/5/6) enabled | 355 | * UltraDMA (mode 0/1/2/3/4/5/6) enabled |
357 | */ | 356 | */ |
358 | if ((id->field_valid & 4) && ((id->dma_ultra >> 8) & 0x7f)) | 357 | if ((id->field_valid & 4) && ((id->dma_ultra >> 8) & 0x7f)) |
359 | return hwif->ide_dma_on(drive); | 358 | return 0; |
360 | /* | 359 | /* |
361 | * Enable DMA on any drive that has mode2 DMA | 360 | * Enable DMA on any drive that has mode2 DMA |
362 | * (multi or single) enabled | 361 | * (multi or single) enabled |
@@ -364,14 +363,14 @@ static int config_drive_for_dma (ide_drive_t *drive) | |||
364 | if (id->field_valid & 2) /* regular DMA */ | 363 | if (id->field_valid & 2) /* regular DMA */ |
365 | if ((id->dma_mword & 0x404) == 0x404 || | 364 | if ((id->dma_mword & 0x404) == 0x404 || |
366 | (id->dma_1word & 0x404) == 0x404) | 365 | (id->dma_1word & 0x404) == 0x404) |
367 | return hwif->ide_dma_on(drive); | 366 | return 0; |
368 | 367 | ||
369 | /* Consult the list of known "good" drives */ | 368 | /* Consult the list of known "good" drives */ |
370 | if (__ide_dma_good_drive(drive)) | 369 | if (__ide_dma_good_drive(drive)) |
371 | return hwif->ide_dma_on(drive); | 370 | return 0; |
372 | } | 371 | } |
373 | // if (hwif->tuneproc != NULL) hwif->tuneproc(drive, 255); | 372 | |
374 | return hwif->ide_dma_off_quietly(drive); | 373 | return -1; |
375 | } | 374 | } |
376 | 375 | ||
377 | /** | 376 | /** |
@@ -415,72 +414,68 @@ static int dma_timer_expiry (ide_drive_t *drive) | |||
415 | } | 414 | } |
416 | 415 | ||
417 | /** | 416 | /** |
418 | * __ide_dma_host_off - Generic DMA kill | 417 | * ide_dma_host_off - Generic DMA kill |
419 | * @drive: drive to control | 418 | * @drive: drive to control |
420 | * | 419 | * |
421 | * Perform the generic IDE controller DMA off operation. This | 420 | * Perform the generic IDE controller DMA off operation. This |
422 | * works for most IDE bus mastering controllers | 421 | * works for most IDE bus mastering controllers |
423 | */ | 422 | */ |
424 | 423 | ||
425 | int __ide_dma_host_off (ide_drive_t *drive) | 424 | void ide_dma_host_off(ide_drive_t *drive) |
426 | { | 425 | { |
427 | ide_hwif_t *hwif = HWIF(drive); | 426 | ide_hwif_t *hwif = HWIF(drive); |
428 | u8 unit = (drive->select.b.unit & 0x01); | 427 | u8 unit = (drive->select.b.unit & 0x01); |
429 | u8 dma_stat = hwif->INB(hwif->dma_status); | 428 | u8 dma_stat = hwif->INB(hwif->dma_status); |
430 | 429 | ||
431 | hwif->OUTB((dma_stat & ~(1<<(5+unit))), hwif->dma_status); | 430 | hwif->OUTB((dma_stat & ~(1<<(5+unit))), hwif->dma_status); |
432 | return 0; | ||
433 | } | 431 | } |
434 | 432 | ||
435 | EXPORT_SYMBOL(__ide_dma_host_off); | 433 | EXPORT_SYMBOL(ide_dma_host_off); |
436 | 434 | ||
437 | /** | 435 | /** |
438 | * __ide_dma_host_off_quietly - Generic DMA kill | 436 | * ide_dma_off_quietly - Generic DMA kill |
439 | * @drive: drive to control | 437 | * @drive: drive to control |
440 | * | 438 | * |
441 | * Turn off the current DMA on this IDE controller. | 439 | * Turn off the current DMA on this IDE controller. |
442 | */ | 440 | */ |
443 | 441 | ||
444 | int __ide_dma_off_quietly (ide_drive_t *drive) | 442 | void ide_dma_off_quietly(ide_drive_t *drive) |
445 | { | 443 | { |
446 | drive->using_dma = 0; | 444 | drive->using_dma = 0; |
447 | ide_toggle_bounce(drive, 0); | 445 | ide_toggle_bounce(drive, 0); |
448 | 446 | ||
449 | if (HWIF(drive)->ide_dma_host_off(drive)) | 447 | drive->hwif->dma_host_off(drive); |
450 | return 1; | ||
451 | |||
452 | return 0; | ||
453 | } | 448 | } |
454 | 449 | ||
455 | EXPORT_SYMBOL(__ide_dma_off_quietly); | 450 | EXPORT_SYMBOL(ide_dma_off_quietly); |
456 | #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ | 451 | #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ |
457 | 452 | ||
458 | /** | 453 | /** |
459 | * __ide_dma_off - disable DMA on a device | 454 | * ide_dma_off - disable DMA on a device |
460 | * @drive: drive to disable DMA on | 455 | * @drive: drive to disable DMA on |
461 | * | 456 | * |
462 | * Disable IDE DMA for a device on this IDE controller. | 457 | * Disable IDE DMA for a device on this IDE controller. |
463 | * Inform the user that DMA has been disabled. | 458 | * Inform the user that DMA has been disabled. |
464 | */ | 459 | */ |
465 | 460 | ||
466 | int __ide_dma_off (ide_drive_t *drive) | 461 | void ide_dma_off(ide_drive_t *drive) |
467 | { | 462 | { |
468 | printk(KERN_INFO "%s: DMA disabled\n", drive->name); | 463 | printk(KERN_INFO "%s: DMA disabled\n", drive->name); |
469 | return HWIF(drive)->ide_dma_off_quietly(drive); | 464 | drive->hwif->dma_off_quietly(drive); |
470 | } | 465 | } |
471 | 466 | ||
472 | EXPORT_SYMBOL(__ide_dma_off); | 467 | EXPORT_SYMBOL(ide_dma_off); |
473 | 468 | ||
474 | #ifdef CONFIG_BLK_DEV_IDEDMA_PCI | 469 | #ifdef CONFIG_BLK_DEV_IDEDMA_PCI |
475 | /** | 470 | /** |
476 | * __ide_dma_host_on - Enable DMA on a host | 471 | * ide_dma_host_on - Enable DMA on a host |
477 | * @drive: drive to enable for DMA | 472 | * @drive: drive to enable for DMA |
478 | * | 473 | * |
479 | * Enable DMA on an IDE controller following generic bus mastering | 474 | * Enable DMA on an IDE controller following generic bus mastering |
480 | * IDE controller behaviour | 475 | * IDE controller behaviour |
481 | */ | 476 | */ |
482 | 477 | ||
483 | int __ide_dma_host_on (ide_drive_t *drive) | 478 | void ide_dma_host_on(ide_drive_t *drive) |
484 | { | 479 | { |
485 | if (drive->using_dma) { | 480 | if (drive->using_dma) { |
486 | ide_hwif_t *hwif = HWIF(drive); | 481 | ide_hwif_t *hwif = HWIF(drive); |
@@ -488,12 +483,10 @@ int __ide_dma_host_on (ide_drive_t *drive) | |||
488 | u8 dma_stat = hwif->INB(hwif->dma_status); | 483 | u8 dma_stat = hwif->INB(hwif->dma_status); |
489 | 484 | ||
490 | hwif->OUTB((dma_stat|(1<<(5+unit))), hwif->dma_status); | 485 | hwif->OUTB((dma_stat|(1<<(5+unit))), hwif->dma_status); |
491 | return 0; | ||
492 | } | 486 | } |
493 | return 1; | ||
494 | } | 487 | } |
495 | 488 | ||
496 | EXPORT_SYMBOL(__ide_dma_host_on); | 489 | EXPORT_SYMBOL(ide_dma_host_on); |
497 | 490 | ||
498 | /** | 491 | /** |
499 | * __ide_dma_on - Enable DMA on a device | 492 | * __ide_dma_on - Enable DMA on a device |
@@ -511,8 +504,7 @@ int __ide_dma_on (ide_drive_t *drive) | |||
511 | drive->using_dma = 1; | 504 | drive->using_dma = 1; |
512 | ide_toggle_bounce(drive, 1); | 505 | ide_toggle_bounce(drive, 1); |
513 | 506 | ||
514 | if (HWIF(drive)->ide_dma_host_on(drive)) | 507 | drive->hwif->dma_host_on(drive); |
515 | return 1; | ||
516 | 508 | ||
517 | return 0; | 509 | return 0; |
518 | } | 510 | } |
@@ -565,7 +557,10 @@ int ide_dma_setup(ide_drive_t *drive) | |||
565 | } | 557 | } |
566 | 558 | ||
567 | /* PRD table */ | 559 | /* PRD table */ |
568 | hwif->OUTL(hwif->dmatable_dma, hwif->dma_prdtable); | 560 | if (hwif->mmio) |
561 | writel(hwif->dmatable_dma, (void __iomem *)hwif->dma_prdtable); | ||
562 | else | ||
563 | outl(hwif->dmatable_dma, hwif->dma_prdtable); | ||
569 | 564 | ||
570 | /* specify r/w */ | 565 | /* specify r/w */ |
571 | hwif->OUTB(reading, hwif->dma_command); | 566 | hwif->OUTB(reading, hwif->dma_command); |
@@ -680,6 +675,9 @@ int ide_use_dma(ide_drive_t *drive) | |||
680 | struct hd_driveid *id = drive->id; | 675 | struct hd_driveid *id = drive->id; |
681 | ide_hwif_t *hwif = drive->hwif; | 676 | ide_hwif_t *hwif = drive->hwif; |
682 | 677 | ||
678 | if ((id->capability & 1) == 0 || drive->autodma == 0) | ||
679 | return 0; | ||
680 | |||
683 | /* consult the list of known "bad" drives */ | 681 | /* consult the list of known "bad" drives */ |
684 | if (__ide_dma_bad_drive(drive)) | 682 | if (__ide_dma_bad_drive(drive)) |
685 | return 0; | 683 | return 0; |
@@ -753,12 +751,37 @@ void ide_dma_verbose(ide_drive_t *drive) | |||
753 | return; | 751 | return; |
754 | bug_dma_off: | 752 | bug_dma_off: |
755 | printk(", BUG DMA OFF"); | 753 | printk(", BUG DMA OFF"); |
756 | hwif->ide_dma_off_quietly(drive); | 754 | hwif->dma_off_quietly(drive); |
757 | return; | 755 | return; |
758 | } | 756 | } |
759 | 757 | ||
760 | EXPORT_SYMBOL(ide_dma_verbose); | 758 | EXPORT_SYMBOL(ide_dma_verbose); |
761 | 759 | ||
760 | int ide_set_dma(ide_drive_t *drive) | ||
761 | { | ||
762 | ide_hwif_t *hwif = drive->hwif; | ||
763 | int rc; | ||
764 | |||
765 | rc = hwif->ide_dma_check(drive); | ||
766 | |||
767 | switch(rc) { | ||
768 | case -1: /* DMA needs to be disabled */ | ||
769 | hwif->dma_off_quietly(drive); | ||
770 | return 0; | ||
771 | case 0: /* DMA needs to be enabled */ | ||
772 | return hwif->ide_dma_on(drive); | ||
773 | case 1: /* DMA setting cannot be changed */ | ||
774 | break; | ||
775 | default: | ||
776 | BUG(); | ||
777 | break; | ||
778 | } | ||
779 | |||
780 | return rc; | ||
781 | } | ||
782 | |||
783 | EXPORT_SYMBOL_GPL(ide_set_dma); | ||
784 | |||
762 | #ifdef CONFIG_BLK_DEV_IDEDMA_PCI | 785 | #ifdef CONFIG_BLK_DEV_IDEDMA_PCI |
763 | int __ide_dma_lostirq (ide_drive_t *drive) | 786 | int __ide_dma_lostirq (ide_drive_t *drive) |
764 | { | 787 | { |
@@ -809,7 +832,7 @@ int ide_release_dma(ide_hwif_t *hwif) | |||
809 | { | 832 | { |
810 | ide_release_dma_engine(hwif); | 833 | ide_release_dma_engine(hwif); |
811 | 834 | ||
812 | if (hwif->mmio == 2) | 835 | if (hwif->mmio) |
813 | return 1; | 836 | return 1; |
814 | else | 837 | else |
815 | return ide_release_iomio_dma(hwif); | 838 | return ide_release_iomio_dma(hwif); |
@@ -878,9 +901,9 @@ static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int port | |||
878 | 901 | ||
879 | static int ide_dma_iobase(ide_hwif_t *hwif, unsigned long base, unsigned int ports) | 902 | static int ide_dma_iobase(ide_hwif_t *hwif, unsigned long base, unsigned int ports) |
880 | { | 903 | { |
881 | if (hwif->mmio == 2) | 904 | if (hwif->mmio) |
882 | return ide_mapped_mmio_dma(hwif, base,ports); | 905 | return ide_mapped_mmio_dma(hwif, base,ports); |
883 | BUG_ON(hwif->mmio == 1); | 906 | |
884 | return ide_iomio_dma(hwif, base, ports); | 907 | return ide_iomio_dma(hwif, base, ports); |
885 | } | 908 | } |
886 | 909 | ||
@@ -908,14 +931,14 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p | |||
908 | if (!(hwif->dma_prdtable)) | 931 | if (!(hwif->dma_prdtable)) |
909 | hwif->dma_prdtable = (hwif->dma_base + 4); | 932 | hwif->dma_prdtable = (hwif->dma_base + 4); |
910 | 933 | ||
911 | if (!hwif->ide_dma_off_quietly) | 934 | if (!hwif->dma_off_quietly) |
912 | hwif->ide_dma_off_quietly = &__ide_dma_off_quietly; | 935 | hwif->dma_off_quietly = &ide_dma_off_quietly; |
913 | if (!hwif->ide_dma_host_off) | 936 | if (!hwif->dma_host_off) |
914 | hwif->ide_dma_host_off = &__ide_dma_host_off; | 937 | hwif->dma_host_off = &ide_dma_host_off; |
915 | if (!hwif->ide_dma_on) | 938 | if (!hwif->ide_dma_on) |
916 | hwif->ide_dma_on = &__ide_dma_on; | 939 | hwif->ide_dma_on = &__ide_dma_on; |
917 | if (!hwif->ide_dma_host_on) | 940 | if (!hwif->dma_host_on) |
918 | hwif->ide_dma_host_on = &__ide_dma_host_on; | 941 | hwif->dma_host_on = &ide_dma_host_on; |
919 | if (!hwif->ide_dma_check) | 942 | if (!hwif->ide_dma_check) |
920 | hwif->ide_dma_check = &__ide_dma_check; | 943 | hwif->ide_dma_check = &__ide_dma_check; |
921 | if (!hwif->dma_setup) | 944 | if (!hwif->dma_setup) |