diff options
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/pci/atiixp.c | 71 |
1 files changed, 18 insertions, 53 deletions
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index 5ae26564fb72..491871984aaa 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/ide/pci/atiixp.c Version 0.03 Aug 3 2007 | 2 | * linux/drivers/ide/pci/atiixp.c Version 0.05 Nov 9 2007 |
3 | * | 3 | * |
4 | * Copyright (C) 2003 ATI Inc. <hyu@ati.com> | 4 | * Copyright (C) 2003 ATI Inc. <hyu@ati.com> |
5 | * Copyright (C) 2004,2007 Bartlomiej Zolnierkiewicz | 5 | * Copyright (C) 2004,2007 Bartlomiej Zolnierkiewicz |
@@ -43,47 +43,8 @@ static atiixp_ide_timing mdma_timing[] = { | |||
43 | { 0x02, 0x00 }, | 43 | { 0x02, 0x00 }, |
44 | }; | 44 | }; |
45 | 45 | ||
46 | static int save_mdma_mode[4]; | ||
47 | |||
48 | static DEFINE_SPINLOCK(atiixp_lock); | 46 | static DEFINE_SPINLOCK(atiixp_lock); |
49 | 47 | ||
50 | static void atiixp_dma_host_on(ide_drive_t *drive) | ||
51 | { | ||
52 | struct pci_dev *dev = drive->hwif->pci_dev; | ||
53 | unsigned long flags; | ||
54 | u16 tmp16; | ||
55 | |||
56 | spin_lock_irqsave(&atiixp_lock, flags); | ||
57 | |||
58 | pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16); | ||
59 | if (save_mdma_mode[drive->dn]) | ||
60 | tmp16 &= ~(1 << drive->dn); | ||
61 | else | ||
62 | tmp16 |= (1 << drive->dn); | ||
63 | pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16); | ||
64 | |||
65 | spin_unlock_irqrestore(&atiixp_lock, flags); | ||
66 | |||
67 | ide_dma_host_on(drive); | ||
68 | } | ||
69 | |||
70 | static void atiixp_dma_host_off(ide_drive_t *drive) | ||
71 | { | ||
72 | struct pci_dev *dev = drive->hwif->pci_dev; | ||
73 | unsigned long flags; | ||
74 | u16 tmp16; | ||
75 | |||
76 | spin_lock_irqsave(&atiixp_lock, flags); | ||
77 | |||
78 | pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16); | ||
79 | tmp16 &= ~(1 << drive->dn); | ||
80 | pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16); | ||
81 | |||
82 | spin_unlock_irqrestore(&atiixp_lock, flags); | ||
83 | |||
84 | ide_dma_host_off(drive); | ||
85 | } | ||
86 | |||
87 | /** | 48 | /** |
88 | * atiixp_set_pio_mode - set host controller for PIO mode | 49 | * atiixp_set_pio_mode - set host controller for PIO mode |
89 | * @drive: drive | 50 | * @drive: drive |
@@ -132,26 +93,33 @@ static void atiixp_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
132 | int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; | 93 | int timing_shift = (drive->dn & 2) ? 16 : 0 + (drive->dn & 1) ? 0 : 8; |
133 | u32 tmp32; | 94 | u32 tmp32; |
134 | u16 tmp16; | 95 | u16 tmp16; |
96 | u16 udma_ctl = 0; | ||
135 | 97 | ||
136 | spin_lock_irqsave(&atiixp_lock, flags); | 98 | spin_lock_irqsave(&atiixp_lock, flags); |
137 | 99 | ||
138 | save_mdma_mode[drive->dn] = 0; | 100 | pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &udma_ctl); |
101 | |||
139 | if (speed >= XFER_UDMA_0) { | 102 | if (speed >= XFER_UDMA_0) { |
140 | pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &tmp16); | 103 | pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &tmp16); |
141 | tmp16 &= ~(0x07 << (drive->dn * 4)); | 104 | tmp16 &= ~(0x07 << (drive->dn * 4)); |
142 | tmp16 |= ((speed & 0x07) << (drive->dn * 4)); | 105 | tmp16 |= ((speed & 0x07) << (drive->dn * 4)); |
143 | pci_write_config_word(dev, ATIIXP_IDE_UDMA_MODE, tmp16); | 106 | pci_write_config_word(dev, ATIIXP_IDE_UDMA_MODE, tmp16); |
144 | } else { | 107 | |
145 | if ((speed >= XFER_MW_DMA_0) && (speed <= XFER_MW_DMA_2)) { | 108 | udma_ctl |= (1 << drive->dn); |
146 | save_mdma_mode[drive->dn] = speed; | 109 | } else if (speed >= XFER_MW_DMA_0) { |
147 | pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &tmp32); | 110 | u8 i = speed & 0x03; |
148 | tmp32 &= ~(0xff << timing_shift); | 111 | |
149 | tmp32 |= (mdma_timing[speed & 0x03].recover_width << timing_shift) | | 112 | pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &tmp32); |
150 | (mdma_timing[speed & 0x03].command_width << (timing_shift + 4)); | 113 | tmp32 &= ~(0xff << timing_shift); |
151 | pci_write_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, tmp32); | 114 | tmp32 |= (mdma_timing[i].recover_width << timing_shift) | |
152 | } | 115 | (mdma_timing[i].command_width << (timing_shift + 4)); |
116 | pci_write_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, tmp32); | ||
117 | |||
118 | udma_ctl &= ~(1 << drive->dn); | ||
153 | } | 119 | } |
154 | 120 | ||
121 | pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, udma_ctl); | ||
122 | |||
155 | spin_unlock_irqrestore(&atiixp_lock, flags); | 123 | spin_unlock_irqrestore(&atiixp_lock, flags); |
156 | } | 124 | } |
157 | 125 | ||
@@ -181,9 +149,6 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) | |||
181 | hwif->cbl = ATA_CBL_PATA80; | 149 | hwif->cbl = ATA_CBL_PATA80; |
182 | else | 150 | else |
183 | hwif->cbl = ATA_CBL_PATA40; | 151 | hwif->cbl = ATA_CBL_PATA40; |
184 | |||
185 | hwif->dma_host_on = &atiixp_dma_host_on; | ||
186 | hwif->dma_host_off = &atiixp_dma_host_off; | ||
187 | } | 152 | } |
188 | 153 | ||
189 | static const struct ide_port_info atiixp_pci_info[] __devinitdata = { | 154 | static const struct ide_port_info atiixp_pci_info[] __devinitdata = { |