diff options
Diffstat (limited to 'drivers/ide/ide-dma.c')
-rw-r--r-- | drivers/ide/ide-dma.c | 103 |
1 files changed, 63 insertions, 40 deletions
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 7ee44f86bc54..be99d463dcc7 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -100,10 +100,11 @@ static const struct drive_list_entry drive_blacklist [] = { | |||
100 | 100 | ||
101 | ide_startstop_t ide_dma_intr (ide_drive_t *drive) | 101 | ide_startstop_t ide_dma_intr (ide_drive_t *drive) |
102 | { | 102 | { |
103 | ide_hwif_t *hwif = drive->hwif; | ||
103 | u8 stat = 0, dma_stat = 0; | 104 | u8 stat = 0, dma_stat = 0; |
104 | 105 | ||
105 | dma_stat = drive->hwif->dma_ops->dma_end(drive); | 106 | dma_stat = hwif->dma_ops->dma_end(drive); |
106 | stat = ide_read_status(drive); | 107 | stat = hwif->tp_ops->read_status(hwif); |
107 | 108 | ||
108 | if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) { | 109 | if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) { |
109 | if (!dma_stat) { | 110 | if (!dma_stat) { |
@@ -334,7 +335,7 @@ static int config_drive_for_dma (ide_drive_t *drive) | |||
334 | static int dma_timer_expiry (ide_drive_t *drive) | 335 | static int dma_timer_expiry (ide_drive_t *drive) |
335 | { | 336 | { |
336 | ide_hwif_t *hwif = HWIF(drive); | 337 | ide_hwif_t *hwif = HWIF(drive); |
337 | u8 dma_stat = hwif->INB(hwif->dma_status); | 338 | u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); |
338 | 339 | ||
339 | printk(KERN_WARNING "%s: dma_timer_expiry: dma status == 0x%02x\n", | 340 | printk(KERN_WARNING "%s: dma_timer_expiry: dma status == 0x%02x\n", |
340 | drive->name, dma_stat); | 341 | drive->name, dma_stat); |
@@ -369,14 +370,18 @@ void ide_dma_host_set(ide_drive_t *drive, int on) | |||
369 | { | 370 | { |
370 | ide_hwif_t *hwif = HWIF(drive); | 371 | ide_hwif_t *hwif = HWIF(drive); |
371 | u8 unit = (drive->select.b.unit & 0x01); | 372 | u8 unit = (drive->select.b.unit & 0x01); |
372 | u8 dma_stat = hwif->INB(hwif->dma_status); | 373 | u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); |
373 | 374 | ||
374 | if (on) | 375 | if (on) |
375 | dma_stat |= (1 << (5 + unit)); | 376 | dma_stat |= (1 << (5 + unit)); |
376 | else | 377 | else |
377 | dma_stat &= ~(1 << (5 + unit)); | 378 | dma_stat &= ~(1 << (5 + unit)); |
378 | 379 | ||
379 | hwif->OUTB(dma_stat, hwif->dma_status); | 380 | if (hwif->host_flags & IDE_HFLAG_MMIO) |
381 | writeb(dma_stat, | ||
382 | (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); | ||
383 | else | ||
384 | outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS); | ||
380 | } | 385 | } |
381 | 386 | ||
382 | EXPORT_SYMBOL_GPL(ide_dma_host_set); | 387 | EXPORT_SYMBOL_GPL(ide_dma_host_set); |
@@ -449,6 +454,7 @@ int ide_dma_setup(ide_drive_t *drive) | |||
449 | ide_hwif_t *hwif = drive->hwif; | 454 | ide_hwif_t *hwif = drive->hwif; |
450 | struct request *rq = HWGROUP(drive)->rq; | 455 | struct request *rq = HWGROUP(drive)->rq; |
451 | unsigned int reading; | 456 | unsigned int reading; |
457 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | ||
452 | u8 dma_stat; | 458 | u8 dma_stat; |
453 | 459 | ||
454 | if (rq_data_dir(rq)) | 460 | if (rq_data_dir(rq)) |
@@ -470,13 +476,21 @@ int ide_dma_setup(ide_drive_t *drive) | |||
470 | outl(hwif->dmatable_dma, hwif->dma_base + ATA_DMA_TABLE_OFS); | 476 | outl(hwif->dmatable_dma, hwif->dma_base + ATA_DMA_TABLE_OFS); |
471 | 477 | ||
472 | /* specify r/w */ | 478 | /* specify r/w */ |
473 | hwif->OUTB(reading, hwif->dma_command); | 479 | if (mmio) |
480 | writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); | ||
481 | else | ||
482 | outb(reading, hwif->dma_base + ATA_DMA_CMD); | ||
474 | 483 | ||
475 | /* read dma_status for INTR & ERROR flags */ | 484 | /* read DMA status for INTR & ERROR flags */ |
476 | dma_stat = hwif->INB(hwif->dma_status); | 485 | dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); |
477 | 486 | ||
478 | /* clear INTR & ERROR flags */ | 487 | /* clear INTR & ERROR flags */ |
479 | hwif->OUTB(dma_stat|6, hwif->dma_status); | 488 | if (mmio) |
489 | writeb(dma_stat | 6, | ||
490 | (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); | ||
491 | else | ||
492 | outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); | ||
493 | |||
480 | drive->waiting_for_dma = 1; | 494 | drive->waiting_for_dma = 1; |
481 | return 0; | 495 | return 0; |
482 | } | 496 | } |
@@ -492,16 +506,24 @@ EXPORT_SYMBOL_GPL(ide_dma_exec_cmd); | |||
492 | 506 | ||
493 | void ide_dma_start(ide_drive_t *drive) | 507 | void ide_dma_start(ide_drive_t *drive) |
494 | { | 508 | { |
495 | ide_hwif_t *hwif = HWIF(drive); | 509 | ide_hwif_t *hwif = drive->hwif; |
496 | u8 dma_cmd = hwif->INB(hwif->dma_command); | 510 | u8 dma_cmd; |
497 | 511 | ||
498 | /* Note that this is done *after* the cmd has | 512 | /* Note that this is done *after* the cmd has |
499 | * been issued to the drive, as per the BM-IDE spec. | 513 | * been issued to the drive, as per the BM-IDE spec. |
500 | * The Promise Ultra33 doesn't work correctly when | 514 | * The Promise Ultra33 doesn't work correctly when |
501 | * we do this part before issuing the drive cmd. | 515 | * we do this part before issuing the drive cmd. |
502 | */ | 516 | */ |
503 | /* start DMA */ | 517 | if (hwif->host_flags & IDE_HFLAG_MMIO) { |
504 | hwif->OUTB(dma_cmd|1, hwif->dma_command); | 518 | dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); |
519 | /* start DMA */ | ||
520 | writeb(dma_cmd | 1, | ||
521 | (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); | ||
522 | } else { | ||
523 | dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); | ||
524 | outb(dma_cmd | 1, hwif->dma_base + ATA_DMA_CMD); | ||
525 | } | ||
526 | |||
505 | hwif->dma = 1; | 527 | hwif->dma = 1; |
506 | wmb(); | 528 | wmb(); |
507 | } | 529 | } |
@@ -511,18 +533,33 @@ EXPORT_SYMBOL_GPL(ide_dma_start); | |||
511 | /* returns 1 on error, 0 otherwise */ | 533 | /* returns 1 on error, 0 otherwise */ |
512 | int __ide_dma_end (ide_drive_t *drive) | 534 | int __ide_dma_end (ide_drive_t *drive) |
513 | { | 535 | { |
514 | ide_hwif_t *hwif = HWIF(drive); | 536 | ide_hwif_t *hwif = drive->hwif; |
537 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | ||
515 | u8 dma_stat = 0, dma_cmd = 0; | 538 | u8 dma_stat = 0, dma_cmd = 0; |
516 | 539 | ||
517 | drive->waiting_for_dma = 0; | 540 | drive->waiting_for_dma = 0; |
518 | /* get dma_command mode */ | 541 | |
519 | dma_cmd = hwif->INB(hwif->dma_command); | 542 | if (mmio) { |
520 | /* stop DMA */ | 543 | /* get DMA command mode */ |
521 | hwif->OUTB(dma_cmd&~1, hwif->dma_command); | 544 | dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); |
545 | /* stop DMA */ | ||
546 | writeb(dma_cmd & ~1, | ||
547 | (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); | ||
548 | } else { | ||
549 | dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); | ||
550 | outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD); | ||
551 | } | ||
552 | |||
522 | /* get DMA status */ | 553 | /* get DMA status */ |
523 | dma_stat = hwif->INB(hwif->dma_status); | 554 | dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); |
524 | /* clear the INTR & ERROR bits */ | 555 | |
525 | hwif->OUTB(dma_stat|6, hwif->dma_status); | 556 | if (mmio) |
557 | /* clear the INTR & ERROR bits */ | ||
558 | writeb(dma_stat | 6, | ||
559 | (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); | ||
560 | else | ||
561 | outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); | ||
562 | |||
526 | /* purge DMA mappings */ | 563 | /* purge DMA mappings */ |
527 | ide_destroy_dmatable(drive); | 564 | ide_destroy_dmatable(drive); |
528 | /* verify good DMA status */ | 565 | /* verify good DMA status */ |
@@ -537,7 +574,7 @@ EXPORT_SYMBOL(__ide_dma_end); | |||
537 | int ide_dma_test_irq(ide_drive_t *drive) | 574 | int ide_dma_test_irq(ide_drive_t *drive) |
538 | { | 575 | { |
539 | ide_hwif_t *hwif = HWIF(drive); | 576 | ide_hwif_t *hwif = HWIF(drive); |
540 | u8 dma_stat = hwif->INB(hwif->dma_status); | 577 | u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); |
541 | 578 | ||
542 | /* return 1 if INTR asserted */ | 579 | /* return 1 if INTR asserted */ |
543 | if ((dma_stat & 4) == 4) | 580 | if ((dma_stat & 4) == 4) |
@@ -719,9 +756,8 @@ static int ide_tune_dma(ide_drive_t *drive) | |||
719 | static int ide_dma_check(ide_drive_t *drive) | 756 | static int ide_dma_check(ide_drive_t *drive) |
720 | { | 757 | { |
721 | ide_hwif_t *hwif = drive->hwif; | 758 | ide_hwif_t *hwif = drive->hwif; |
722 | int vdma = (hwif->host_flags & IDE_HFLAG_VDMA)? 1 : 0; | ||
723 | 759 | ||
724 | if (!vdma && ide_tune_dma(drive)) | 760 | if (ide_tune_dma(drive)) |
725 | return 0; | 761 | return 0; |
726 | 762 | ||
727 | /* TODO: always do PIO fallback */ | 763 | /* TODO: always do PIO fallback */ |
@@ -730,7 +766,7 @@ static int ide_dma_check(ide_drive_t *drive) | |||
730 | 766 | ||
731 | ide_set_max_pio(drive); | 767 | ide_set_max_pio(drive); |
732 | 768 | ||
733 | return vdma ? 0 : -1; | 769 | return -1; |
734 | } | 770 | } |
735 | 771 | ||
736 | int ide_id_dma_bug(ide_drive_t *drive) | 772 | int ide_id_dma_bug(ide_drive_t *drive) |
@@ -842,7 +878,7 @@ int ide_allocate_dma_engine(ide_hwif_t *hwif) | |||
842 | } | 878 | } |
843 | EXPORT_SYMBOL_GPL(ide_allocate_dma_engine); | 879 | EXPORT_SYMBOL_GPL(ide_allocate_dma_engine); |
844 | 880 | ||
845 | static const struct ide_dma_ops sff_dma_ops = { | 881 | const struct ide_dma_ops sff_dma_ops = { |
846 | .dma_host_set = ide_dma_host_set, | 882 | .dma_host_set = ide_dma_host_set, |
847 | .dma_setup = ide_dma_setup, | 883 | .dma_setup = ide_dma_setup, |
848 | .dma_exec_cmd = ide_dma_exec_cmd, | 884 | .dma_exec_cmd = ide_dma_exec_cmd, |
@@ -852,18 +888,5 @@ static const struct ide_dma_ops sff_dma_ops = { | |||
852 | .dma_timeout = ide_dma_timeout, | 888 | .dma_timeout = ide_dma_timeout, |
853 | .dma_lost_irq = ide_dma_lost_irq, | 889 | .dma_lost_irq = ide_dma_lost_irq, |
854 | }; | 890 | }; |
855 | 891 | EXPORT_SYMBOL_GPL(sff_dma_ops); | |
856 | void ide_setup_dma(ide_hwif_t *hwif, unsigned long base) | ||
857 | { | ||
858 | hwif->dma_base = base; | ||
859 | |||
860 | if (!hwif->dma_command) | ||
861 | hwif->dma_command = hwif->dma_base + 0; | ||
862 | if (!hwif->dma_status) | ||
863 | hwif->dma_status = hwif->dma_base + 2; | ||
864 | |||
865 | hwif->dma_ops = &sff_dma_ops; | ||
866 | } | ||
867 | |||
868 | EXPORT_SYMBOL_GPL(ide_setup_dma); | ||
869 | #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */ | 892 | #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */ |