diff options
author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2007-02-07 12:18:13 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2007-02-07 12:18:13 -0500 |
commit | 4bf63de27e9fd9c0926ba3bb773de076b324a955 (patch) | |
tree | 69f2ab89ad78a5aa40b911d8bc79ca74ef8e4871 /drivers | |
parent | 26ccb802ee3f9a1f1fd5bc6abf38f124bfbd9cb2 (diff) |
hpt366: clean up DMA timeout handling for HPT370
Clean up DMA timeout handling for HPT370:
- hpt370_lostirq_timeout() cleared the DMA status which made __ide_dma_end()
called afterwards return the incorrect result, and the DMA engine was reset
both before and after stopping DMA while the HighPoint drivers only do it
after (which seems logical) -- fix this and also rename the function;
- get rid of the needless mutual recursion in hpt370_ide_dma_end() and
hpt370_ide_dma_timeout();
- get rid of hpt370_lostirq_timeout() since hwif->ide_dma_end() called from
the driver's interrupt handler later does all its work.
Signed-off-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ide/pci/hpt366.c | 62 |
1 files changed, 25 insertions, 37 deletions
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 7317defd8210..9ad1531b6034 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/ide/pci/hpt366.c Version 0.51 Jun 04, 2006 | 2 | * linux/drivers/ide/pci/hpt366.c Version 0.52 Jun 07, 2006 |
3 | * | 3 | * |
4 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> | 4 | * Copyright (C) 1999-2003 Andre Hedrick <andre@linux-ide.org> |
5 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. | 5 | * Portions Copyright (C) 2001 Sun Microsystems, Inc. |
@@ -90,6 +90,7 @@ | |||
90 | * there; make HPT36x speedproc handler look the same way as the HPT37x one | 90 | * there; make HPT36x speedproc handler look the same way as the HPT37x one |
91 | * - fix the tuneproc handler to always set the PIO mode requested, not the | 91 | * - fix the tuneproc handler to always set the PIO mode requested, not the |
92 | * best possible one | 92 | * best possible one |
93 | * - clean up DMA timeout handling for HPT370 | ||
93 | * <source@mvista.com> | 94 | * <source@mvista.com> |
94 | */ | 95 | */ |
95 | 96 | ||
@@ -680,7 +681,7 @@ static int hpt366_ide_dma_lostirq(ide_drive_t *drive) | |||
680 | return __ide_dma_lostirq(drive); | 681 | return __ide_dma_lostirq(drive); |
681 | } | 682 | } |
682 | 683 | ||
683 | static void hpt370_clear_engine (ide_drive_t *drive) | 684 | static void hpt370_clear_engine(ide_drive_t *drive) |
684 | { | 685 | { |
685 | ide_hwif_t *hwif = HWIF(drive); | 686 | ide_hwif_t *hwif = HWIF(drive); |
686 | 687 | ||
@@ -688,6 +689,22 @@ static void hpt370_clear_engine (ide_drive_t *drive) | |||
688 | udelay(10); | 689 | udelay(10); |
689 | } | 690 | } |
690 | 691 | ||
692 | static void hpt370_irq_timeout(ide_drive_t *drive) | ||
693 | { | ||
694 | ide_hwif_t *hwif = HWIF(drive); | ||
695 | u16 bfifo = 0; | ||
696 | u8 dma_cmd; | ||
697 | |||
698 | pci_read_config_word(hwif->pci_dev, hwif->select_data + 2, &bfifo); | ||
699 | printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo & 0x1ff); | ||
700 | |||
701 | /* get DMA command mode */ | ||
702 | dma_cmd = hwif->INB(hwif->dma_command); | ||
703 | /* stop DMA */ | ||
704 | hwif->OUTB(dma_cmd & ~0x1, hwif->dma_command); | ||
705 | hpt370_clear_engine(drive); | ||
706 | } | ||
707 | |||
691 | static void hpt370_ide_dma_start(ide_drive_t *drive) | 708 | static void hpt370_ide_dma_start(ide_drive_t *drive) |
692 | { | 709 | { |
693 | #ifdef HPT_RESET_STATE_ENGINE | 710 | #ifdef HPT_RESET_STATE_ENGINE |
@@ -696,55 +713,27 @@ static void hpt370_ide_dma_start(ide_drive_t *drive) | |||
696 | ide_dma_start(drive); | 713 | ide_dma_start(drive); |
697 | } | 714 | } |
698 | 715 | ||
699 | static int hpt370_ide_dma_end (ide_drive_t *drive) | 716 | static int hpt370_ide_dma_end(ide_drive_t *drive) |
700 | { | 717 | { |
701 | ide_hwif_t *hwif = HWIF(drive); | 718 | ide_hwif_t *hwif = HWIF(drive); |
702 | u8 dma_stat = hwif->INB(hwif->dma_status); | 719 | u8 dma_stat = hwif->INB(hwif->dma_status); |
703 | 720 | ||
704 | if (dma_stat & 0x01) { | 721 | if (dma_stat & 0x01) { |
705 | /* wait a little */ | 722 | /* wait a little */ |
706 | udelay(20); | 723 | udelay(20); |
707 | dma_stat = hwif->INB(hwif->dma_status); | 724 | dma_stat = hwif->INB(hwif->dma_status); |
725 | if (dma_stat & 0x01) | ||
726 | hpt370_irq_timeout(drive); | ||
708 | } | 727 | } |
709 | if ((dma_stat & 0x01) != 0) | ||
710 | /* fallthrough */ | ||
711 | (void) HWIF(drive)->ide_dma_timeout(drive); | ||
712 | |||
713 | return __ide_dma_end(drive); | 728 | return __ide_dma_end(drive); |
714 | } | 729 | } |
715 | 730 | ||
716 | static void hpt370_lostirq_timeout (ide_drive_t *drive) | 731 | static int hpt370_ide_dma_timeout(ide_drive_t *drive) |
717 | { | 732 | { |
718 | ide_hwif_t *hwif = HWIF(drive); | 733 | hpt370_irq_timeout(drive); |
719 | u8 bfifo = 0; | ||
720 | u8 dma_stat = 0, dma_cmd = 0; | ||
721 | |||
722 | pci_read_config_byte(HWIF(drive)->pci_dev, hwif->select_data + 2, &bfifo); | ||
723 | printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo); | ||
724 | hpt370_clear_engine(drive); | ||
725 | /* get dma command mode */ | ||
726 | dma_cmd = hwif->INB(hwif->dma_command); | ||
727 | /* stop dma */ | ||
728 | hwif->OUTB(dma_cmd & ~0x1, hwif->dma_command); | ||
729 | dma_stat = hwif->INB(hwif->dma_status); | ||
730 | /* clear errors */ | ||
731 | hwif->OUTB(dma_stat | 0x6, hwif->dma_status); | ||
732 | } | ||
733 | |||
734 | static int hpt370_ide_dma_timeout (ide_drive_t *drive) | ||
735 | { | ||
736 | hpt370_lostirq_timeout(drive); | ||
737 | hpt370_clear_engine(drive); | ||
738 | return __ide_dma_timeout(drive); | 734 | return __ide_dma_timeout(drive); |
739 | } | 735 | } |
740 | 736 | ||
741 | static int hpt370_ide_dma_lostirq (ide_drive_t *drive) | ||
742 | { | ||
743 | hpt370_lostirq_timeout(drive); | ||
744 | hpt370_clear_engine(drive); | ||
745 | return __ide_dma_lostirq(drive); | ||
746 | } | ||
747 | |||
748 | /* returns 1 if DMA IRQ issued, 0 otherwise */ | 737 | /* returns 1 if DMA IRQ issued, 0 otherwise */ |
749 | static int hpt374_ide_dma_test_irq(ide_drive_t *drive) | 738 | static int hpt374_ide_dma_test_irq(ide_drive_t *drive) |
750 | { | 739 | { |
@@ -1226,7 +1215,6 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) | |||
1226 | hwif->dma_start = &hpt370_ide_dma_start; | 1215 | hwif->dma_start = &hpt370_ide_dma_start; |
1227 | hwif->ide_dma_end = &hpt370_ide_dma_end; | 1216 | hwif->ide_dma_end = &hpt370_ide_dma_end; |
1228 | hwif->ide_dma_timeout = &hpt370_ide_dma_timeout; | 1217 | hwif->ide_dma_timeout = &hpt370_ide_dma_timeout; |
1229 | hwif->ide_dma_lostirq = &hpt370_ide_dma_lostirq; | ||
1230 | } else | 1218 | } else |
1231 | hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq; | 1219 | hwif->ide_dma_lostirq = &hpt366_ide_dma_lostirq; |
1232 | 1220 | ||