diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-01-26 14:12:58 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-01-26 14:12:58 -0500 |
commit | 6ae8b1efcc83103f2e323c9486f56a8671ca1880 (patch) | |
tree | 6f8d8efffa0202450aedd2a23cb47889179f7582 /drivers/ide/pci | |
parent | 9b73e76f3cf63379dcf45fcd4f112f5812418d0a (diff) |
sl82c105: program DMA/PIO timings in ->dma_start/->ide_dma_end
* Program DMA timings in sl82c105_dma_start() (->dma_start method)
before starting DMA transfer.
* Add sl82c105_dma_end() (->ide_dma_end method) to switch back to
PIO timings when DMA transfer is complete.
* In sl82c105_set_pio_mode() program timings regardless of ->using_dma
setting and in sl82c105_set_dma_mode() only cache the new timings.
* Remove no longer needed sl82c105_{ide_dma_on,off_quietly}().
Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/pci')
-rw-r--r-- | drivers/ide/pci/sl82c105.c | 55 |
1 files changed, 15 insertions, 40 deletions
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 069f104fdcea..a85413467f93 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c | |||
@@ -13,6 +13,7 @@ | |||
13 | * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org | 13 | * -- Benjamin Herrenschmidt (01/11/03) benh@kernel.crashing.org |
14 | * | 14 | * |
15 | * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> | 15 | * Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com> |
16 | * Copyright (C) 2007 Bartlomiej Zolnierkiewicz | ||
16 | */ | 17 | */ |
17 | 18 | ||
18 | #include <linux/types.h> | 19 | #include <linux/types.h> |
@@ -90,14 +91,8 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
90 | drive->drive_data &= 0xffff0000; | 91 | drive->drive_data &= 0xffff0000; |
91 | drive->drive_data |= drv_ctrl; | 92 | drive->drive_data |= drv_ctrl; |
92 | 93 | ||
93 | if (!drive->using_dma) { | 94 | pci_write_config_word(dev, reg, drv_ctrl); |
94 | /* | 95 | pci_read_config_word (dev, reg, &drv_ctrl); |
95 | * If we are actually using MW DMA, then we can not | ||
96 | * reprogram the interface drive control register. | ||
97 | */ | ||
98 | pci_write_config_word(dev, reg, drv_ctrl); | ||
99 | pci_read_config_word (dev, reg, &drv_ctrl); | ||
100 | } | ||
101 | 96 | ||
102 | printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name, | 97 | printk(KERN_DEBUG "%s: selected %s (%dns) (%04X)\n", drive->name, |
103 | ide_xfer_verbose(pio + XFER_PIO_0), | 98 | ide_xfer_verbose(pio + XFER_PIO_0), |
@@ -123,17 +118,6 @@ static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
123 | */ | 118 | */ |
124 | drive->drive_data &= 0x0000ffff; | 119 | drive->drive_data &= 0x0000ffff; |
125 | drive->drive_data |= (unsigned long)drv_ctrl << 16; | 120 | drive->drive_data |= (unsigned long)drv_ctrl << 16; |
126 | |||
127 | /* | ||
128 | * If we are already using DMA, we just reprogram | ||
129 | * the drive control register. | ||
130 | */ | ||
131 | if (drive->using_dma) { | ||
132 | struct pci_dev *dev = HWIF(drive)->pci_dev; | ||
133 | int reg = 0x44 + drive->dn * 4; | ||
134 | |||
135 | pci_write_config_word(dev, reg, drv_ctrl); | ||
136 | } | ||
137 | } | 121 | } |
138 | 122 | ||
139 | /* | 123 | /* |
@@ -201,6 +185,11 @@ static void sl82c105_dma_start(ide_drive_t *drive) | |||
201 | { | 185 | { |
202 | ide_hwif_t *hwif = HWIF(drive); | 186 | ide_hwif_t *hwif = HWIF(drive); |
203 | struct pci_dev *dev = hwif->pci_dev; | 187 | struct pci_dev *dev = hwif->pci_dev; |
188 | int reg = 0x44 + drive->dn * 4; | ||
189 | |||
190 | DBG(("%s(drive:%s)\n", __FUNCTION__, drive->name)); | ||
191 | |||
192 | pci_write_config_word(dev, reg, drive->drive_data >> 16); | ||
204 | 193 | ||
205 | sl82c105_reset_host(dev); | 194 | sl82c105_reset_host(dev); |
206 | ide_dma_start(drive); | 195 | ide_dma_start(drive); |
@@ -214,32 +203,19 @@ static void sl82c105_dma_timeout(ide_drive_t *drive) | |||
214 | ide_dma_timeout(drive); | 203 | ide_dma_timeout(drive); |
215 | } | 204 | } |
216 | 205 | ||
217 | static int sl82c105_ide_dma_on(ide_drive_t *drive) | 206 | static int sl82c105_dma_end(ide_drive_t *drive) |
218 | { | ||
219 | struct pci_dev *dev = HWIF(drive)->pci_dev; | ||
220 | int rc, reg = 0x44 + drive->dn * 4; | ||
221 | |||
222 | DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); | ||
223 | |||
224 | rc = __ide_dma_on(drive); | ||
225 | if (rc == 0) { | ||
226 | pci_write_config_word(dev, reg, drive->drive_data >> 16); | ||
227 | |||
228 | printk(KERN_INFO "%s: DMA enabled\n", drive->name); | ||
229 | } | ||
230 | return rc; | ||
231 | } | ||
232 | |||
233 | static void sl82c105_dma_off_quietly(ide_drive_t *drive) | ||
234 | { | 207 | { |
235 | struct pci_dev *dev = HWIF(drive)->pci_dev; | 208 | struct pci_dev *dev = HWIF(drive)->pci_dev; |
236 | int reg = 0x44 + drive->dn * 4; | 209 | int reg = 0x44 + drive->dn * 4; |
210 | int ret; | ||
211 | |||
212 | DBG(("%s(drive:%s)\n", __FUNCTION__, drive->name)); | ||
237 | 213 | ||
238 | DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name)); | 214 | ret = __ide_dma_end(drive); |
239 | 215 | ||
240 | pci_write_config_word(dev, reg, drive->drive_data); | 216 | pci_write_config_word(dev, reg, drive->drive_data); |
241 | 217 | ||
242 | ide_dma_off_quietly(drive); | 218 | return ret; |
243 | } | 219 | } |
244 | 220 | ||
245 | /* | 221 | /* |
@@ -369,10 +345,9 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) | |||
369 | 345 | ||
370 | hwif->mwdma_mask = ATA_MWDMA2; | 346 | hwif->mwdma_mask = ATA_MWDMA2; |
371 | 347 | ||
372 | hwif->ide_dma_on = &sl82c105_ide_dma_on; | ||
373 | hwif->dma_off_quietly = &sl82c105_dma_off_quietly; | ||
374 | hwif->dma_lost_irq = &sl82c105_dma_lost_irq; | 348 | hwif->dma_lost_irq = &sl82c105_dma_lost_irq; |
375 | hwif->dma_start = &sl82c105_dma_start; | 349 | hwif->dma_start = &sl82c105_dma_start; |
350 | hwif->ide_dma_end = &sl82c105_dma_end; | ||
376 | hwif->dma_timeout = &sl82c105_dma_timeout; | 351 | hwif->dma_timeout = &sl82c105_dma_timeout; |
377 | 352 | ||
378 | if (hwif->mate) | 353 | if (hwif->mate) |