aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/pci/scc_pata.c54
1 files changed, 50 insertions, 4 deletions
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index a17f73ec577a..144938188325 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -260,6 +260,20 @@ static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
260 out_be32((void __iomem *)udenvt_port, reg); 260 out_be32((void __iomem *)udenvt_port, reg);
261} 261}
262 262
263static void scc_dma_host_set(ide_drive_t *drive, int on)
264{
265 ide_hwif_t *hwif = drive->hwif;
266 u8 unit = (drive->select.b.unit & 0x01);
267 u8 dma_stat = scc_ide_inb(hwif->dma_status);
268
269 if (on)
270 dma_stat |= (1 << (5 + unit));
271 else
272 dma_stat &= ~(1 << (5 + unit));
273
274 scc_ide_outb(dma_stat, hwif->dma_status);
275}
276
263/** 277/**
264 * scc_ide_dma_setup - begin a DMA phase 278 * scc_ide_dma_setup - begin a DMA phase
265 * @drive: target device 279 * @drive: target device
@@ -304,13 +318,45 @@ static int scc_dma_setup(ide_drive_t *drive)
304 return 0; 318 return 0;
305} 319}
306 320
321static void scc_dma_start(ide_drive_t *drive)
322{
323 ide_hwif_t *hwif = drive->hwif;
324 u8 dma_cmd = scc_ide_inb(hwif->dma_command);
325
326 /* start DMA */
327 scc_ide_outb(dma_cmd | 1, hwif->dma_command);
328 hwif->dma = 1;
329 wmb();
330}
331
332static int __scc_dma_end(ide_drive_t *drive)
333{
334 ide_hwif_t *hwif = drive->hwif;
335 u8 dma_stat, dma_cmd;
336
337 drive->waiting_for_dma = 0;
338 /* get DMA command mode */
339 dma_cmd = scc_ide_inb(hwif->dma_command);
340 /* stop DMA */
341 scc_ide_outb(dma_cmd & ~1, hwif->dma_command);
342 /* get DMA status */
343 dma_stat = scc_ide_inb(hwif->dma_status);
344 /* clear the INTR & ERROR bits */
345 scc_ide_outb(dma_stat | 6, hwif->dma_status);
346 /* purge DMA mappings */
347 ide_destroy_dmatable(drive);
348 /* verify good DMA status */
349 hwif->dma = 0;
350 wmb();
351 return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
352}
307 353
308/** 354/**
309 * scc_dma_end - Stop DMA 355 * scc_dma_end - Stop DMA
310 * @drive: IDE drive 356 * @drive: IDE drive
311 * 357 *
312 * Check and clear INT Status register. 358 * Check and clear INT Status register.
313 * Then call __ide_dma_end(). 359 * Then call __scc_dma_end().
314 */ 360 */
315 361
316static int scc_dma_end(ide_drive_t *drive) 362static int scc_dma_end(ide_drive_t *drive)
@@ -414,7 +460,7 @@ static int scc_dma_end(ide_drive_t *drive)
414 break; 460 break;
415 } 461 }
416 462
417 dma_stat = __ide_dma_end(drive); 463 dma_stat = __scc_dma_end(drive);
418 if (data_loss) 464 if (data_loss)
419 dma_stat |= 2; /* emulate DMA error (to retry command) */ 465 dma_stat |= 2; /* emulate DMA error (to retry command) */
420 return dma_stat; 466 return dma_stat;
@@ -811,10 +857,10 @@ static const struct ide_port_ops scc_port_ops = {
811}; 857};
812 858
813static const struct ide_dma_ops scc_dma_ops = { 859static const struct ide_dma_ops scc_dma_ops = {
814 .dma_host_set = ide_dma_host_set, 860 .dma_host_set = scc_dma_host_set,
815 .dma_setup = scc_dma_setup, 861 .dma_setup = scc_dma_setup,
816 .dma_exec_cmd = ide_dma_exec_cmd, 862 .dma_exec_cmd = ide_dma_exec_cmd,
817 .dma_start = ide_dma_start, 863 .dma_start = scc_dma_start,
818 .dma_end = scc_dma_end, 864 .dma_end = scc_dma_end,
819 .dma_test_irq = scc_dma_test_irq, 865 .dma_test_irq = scc_dma_test_irq,
820 .dma_lost_irq = ide_dma_lost_irq, 866 .dma_lost_irq = ide_dma_lost_irq,