aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-dma-sff.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-dma-sff.c')
-rw-r--r--drivers/ide/ide-dma-sff.c52
1 files changed, 23 insertions, 29 deletions
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c
index 1f2a5f56f81c..f6d2d44d8a9a 100644
--- a/drivers/ide/ide-dma-sff.c
+++ b/drivers/ide/ide-dma-sff.c
@@ -176,15 +176,10 @@ int ide_dma_setup(ide_drive_t *drive)
176{ 176{
177 ide_hwif_t *hwif = drive->hwif; 177 ide_hwif_t *hwif = drive->hwif;
178 struct request *rq = hwif->hwgroup->rq; 178 struct request *rq = hwif->hwgroup->rq;
179 unsigned int reading; 179 unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR;
180 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; 180 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
181 u8 dma_stat; 181 u8 dma_stat;
182 182
183 if (rq_data_dir(rq))
184 reading = 0;
185 else
186 reading = 1 << 3;
187
188 /* fall back to pio! */ 183 /* fall back to pio! */
189 if (!ide_build_dmatable(drive, rq)) { 184 if (!ide_build_dmatable(drive, rq)) {
190 ide_map_sg(drive, rq); 185 ide_map_sg(drive, rq);
@@ -209,10 +204,11 @@ int ide_dma_setup(ide_drive_t *drive)
209 204
210 /* clear INTR & ERROR flags */ 205 /* clear INTR & ERROR flags */
211 if (mmio) 206 if (mmio)
212 writeb(dma_stat | 6, 207 writeb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR,
213 (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); 208 (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
214 else 209 else
215 outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); 210 outb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR,
211 hwif->dma_base + ATA_DMA_STATUS);
216 212
217 drive->waiting_for_dma = 1; 213 drive->waiting_for_dma = 1;
218 return 0; 214 return 0;
@@ -246,14 +242,13 @@ static int dma_timer_expiry(ide_drive_t *drive)
246 242
247 hwif->hwgroup->expiry = NULL; /* one free ride for now */ 243 hwif->hwgroup->expiry = NULL; /* one free ride for now */
248 244
249 /* 1 dmaing, 2 error, 4 intr */ 245 if (dma_stat & ATA_DMA_ERR) /* ERROR */
250 if (dma_stat & 2) /* ERROR */
251 return -1; 246 return -1;
252 247
253 if (dma_stat & 1) /* DMAing */ 248 if (dma_stat & ATA_DMA_ACTIVE) /* DMAing */
254 return WAIT_CMD; 249 return WAIT_CMD;
255 250
256 if (dma_stat & 4) /* Got an Interrupt */ 251 if (dma_stat & ATA_DMA_INTR) /* Got an Interrupt */
257 return WAIT_CMD; 252 return WAIT_CMD;
258 253
259 return 0; /* Status is unknown -- reset the bus */ 254 return 0; /* Status is unknown -- reset the bus */
@@ -279,12 +274,11 @@ void ide_dma_start(ide_drive_t *drive)
279 */ 274 */
280 if (hwif->host_flags & IDE_HFLAG_MMIO) { 275 if (hwif->host_flags & IDE_HFLAG_MMIO) {
281 dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); 276 dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
282 /* start DMA */ 277 writeb(dma_cmd | ATA_DMA_START,
283 writeb(dma_cmd | 1,
284 (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); 278 (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
285 } else { 279 } else {
286 dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); 280 dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
287 outb(dma_cmd | 1, hwif->dma_base + ATA_DMA_CMD); 281 outb(dma_cmd | ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD);
288 } 282 }
289 283
290 wmb(); 284 wmb();
@@ -296,19 +290,18 @@ int ide_dma_end(ide_drive_t *drive)
296{ 290{
297 ide_hwif_t *hwif = drive->hwif; 291 ide_hwif_t *hwif = drive->hwif;
298 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; 292 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
299 u8 dma_stat = 0, dma_cmd = 0; 293 u8 dma_stat = 0, dma_cmd = 0, mask;
300 294
301 drive->waiting_for_dma = 0; 295 drive->waiting_for_dma = 0;
302 296
297 /* stop DMA */
303 if (mmio) { 298 if (mmio) {
304 /* get DMA command mode */
305 dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); 299 dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
306 /* stop DMA */ 300 writeb(dma_cmd & ~ATA_DMA_START,
307 writeb(dma_cmd & ~1,
308 (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); 301 (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
309 } else { 302 } else {
310 dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); 303 dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
311 outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD); 304 outb(dma_cmd & ~ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD);
312 } 305 }
313 306
314 /* get DMA status */ 307 /* get DMA status */
@@ -316,16 +309,21 @@ int ide_dma_end(ide_drive_t *drive)
316 309
317 if (mmio) 310 if (mmio)
318 /* clear the INTR & ERROR bits */ 311 /* clear the INTR & ERROR bits */
319 writeb(dma_stat | 6, 312 writeb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR,
320 (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); 313 (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
321 else 314 else
322 outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); 315 outb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR,
316 hwif->dma_base + ATA_DMA_STATUS);
323 317
324 /* purge DMA mappings */ 318 /* purge DMA mappings */
325 ide_destroy_dmatable(drive); 319 ide_destroy_dmatable(drive);
326 /* verify good DMA status */
327 wmb(); 320 wmb();
328 return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; 321
322 /* verify good DMA status */
323 mask = ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR;
324 if ((dma_stat & mask) != ATA_DMA_INTR)
325 return 0x10 | dma_stat;
326 return 0;
329} 327}
330EXPORT_SYMBOL_GPL(ide_dma_end); 328EXPORT_SYMBOL_GPL(ide_dma_end);
331 329
@@ -335,11 +333,7 @@ int ide_dma_test_irq(ide_drive_t *drive)
335 ide_hwif_t *hwif = drive->hwif; 333 ide_hwif_t *hwif = drive->hwif;
336 u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); 334 u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif);
337 335
338 /* return 1 if INTR asserted */ 336 return (dma_stat & ATA_DMA_INTR) ? 1 : 0;
339 if ((dma_stat & 4) == 4)
340 return 1;
341
342 return 0;
343} 337}
344EXPORT_SYMBOL_GPL(ide_dma_test_irq); 338EXPORT_SYMBOL_GPL(ide_dma_test_irq);
345 339