2 Copyright © 2004-2006, The AROS Development Team. All rights reserved
11 * ---------- ------------------ -------------------------------------------------------------------
12 * 2008-01-25 T. Wiszkowski Rebuilt, rearranged and partially fixed 60% of the code here
13 * Enabled implementation to scan for other PCI IDE controllers
14 * Implemented ATAPI Packet Support for both read and write
15 * Corrected ATAPI DMA handling
16 * Fixed major IDE enumeration bugs severely handicapping transfers with more than one controller
17 * Compacted source and implemented major ATA support procedure
18 * Improved DMA and Interrupt management
19 * Removed obsolete code
23 #include <aros/debug.h>
25 #include <exec/types.h>
26 #include <exec/exec.h>
27 #include <exec/resident.h>
28 #include <utility/utility.h>
31 #include <proto/exec.h>
36 Prepare PRD entries for sectors transfer. This function assumes, that noone
37 else will even touch PRD. It should be however truth, as for given bus all
38 ATA accesses are protected with a semaphore.
40 VOID
dma_SetupPRD(struct ata_Unit
*unit
, APTR buffer
, ULONG sectors
, BOOL io
)
42 dma_SetupPRDSize(unit
, buffer
, sectors
<< unit
->au_SectorShift
, io
);
45 VOID
dma_SetupPRDSize(struct ata_Unit
*unit
, APTR buffer
, ULONG size
, BOOL io
)
47 struct PRDEntry
*prd
= unit
->au_Bus
->ab_PRD
;
48 IPTR ptr
= (IPTR
)buffer
;
51 D(bug("[DMA] Setup PRD for %d bytes at %x\n",
55 The first PRD address is the buffer pointer self, doesn't have to be
56 aligned to 64K boundary
58 prd
[0].prde_Address
= ptr
;
61 All other PRD addresses are the next 64K pages, until the page address
62 is bigger as the highest address used
64 for (i
=1; i
< PRD_MAX
; i
++)
66 prd
[i
].prde_Address
= (prd
[i
-1].prde_Address
& 0xffff0000) + 0x00010000;
67 prd
[i
].prde_Length
= 0;
68 if (prd
[i
].prde_Address
> ptr
+ size
)
72 if (size
<= prd
[1].prde_Address
- prd
[0].prde_Address
)
74 prd
[0].prde_Length
= size
;
79 prd
[0].prde_Length
= prd
[1].prde_Address
- prd
[0].prde_Address
;
80 size
-= prd
[0].prde_Length
;
83 prd
[0].prde_Length
&= 0x0000ffff;
89 prd
[i
].prde_Length
= 0; /* 64KB in one PRD */
96 prd
[i
].prde_Length
= size
;
100 prd
[i
-1].prde_Length
|= 0x80000000;
102 outl((ULONG
)prd
, unit
->au_DMAPort
+ dma_PRD
);
103 outb(inb(unit
->au_DMAPort
+ dma_Status
) | DMAF_Error
| DMAF_Interrupt
, unit
->au_DMAPort
+ dma_Status
);
106 If io set to TRUE, then sectors are read, when set to FALSE, they are written
109 outb(DMA_WRITE
, unit
->au_DMAPort
+ dma_Command
);
111 outb(DMA_READ
, unit
->au_DMAPort
+ dma_Command
);
114 VOID
dma_StartDMA(struct ata_Unit
*unit
)
116 inb(unit
->au_DMAPort
+ dma_Command
);
117 inb(unit
->au_DMAPort
+ dma_Status
);
118 outb(inb(unit
->au_DMAPort
+ dma_Command
) | DMA_START
, unit
->au_DMAPort
+ dma_Command
);
119 inb(unit
->au_DMAPort
+ dma_Command
);
120 inb(unit
->au_DMAPort
+ dma_Status
);
123 VOID
dma_StopDMA(struct ata_Unit
*unit
)
125 inb(unit
->au_DMAPort
+ dma_Command
);
126 inb(unit
->au_DMAPort
+ dma_Status
);
127 outb(inb(unit
->au_DMAPort
) & ~DMA_START
, unit
->au_DMAPort
+ dma_Command
);
128 inb(unit
->au_DMAPort
+ dma_Command
);
129 inb(unit
->au_DMAPort
+ dma_Status
);
130 outb(inb(unit
->au_DMAPort
+ dma_Status
) | DMAF_Error
| DMAF_Interrupt
, unit
->au_DMAPort
+ dma_Status
);