2 Copyright © 2004-2012, The AROS Development Team. All rights reserved
9 #include <aros/debug.h>
11 #include <exec/types.h>
12 #include <exec/exec.h>
13 #include <exec/resident.h>
14 #include <utility/utility.h>
17 #include <proto/exec.h>
22 Prepare PRD entries for sectors transfer. This function assumes that no one
23 else will even touch PRD. It should be however truth, as for given bus all
24 ATA accesses are protected with a semaphore.
26 LONG
dma_Setup(APTR addr
, ULONG len
, BOOL read
, struct PRDEntry
* array
)
28 ULONG tmp
= 0, rem
= 0;
29 ULONG flg
= read
? DMA_ReadFromRAM
: 0;
33 D(bug("[ATA ] dma_Setup(addr %p, len %d, PRDEntry @ %p for %s)\n", addr
, len
, array
, read
? "READ" : "WRITE"));
36 * in future you may have to put this in prd construction procedure
41 phy_mem
= (IPTR
)CachePreDMA(addr
, &tmp
, flg
);
43 D(bug("[ATA ] dma_Setup: Translating V:%p > P:%p (%ld bytes)\n", addr
, phy_mem
, tmp
));
45 * update all addresses for the next call
47 addr
= &((UBYTE
*)addr
)[tmp
];
52 * check if we're crossing the magic 64k boundary:
57 * politely say what sucks
59 if (phy_mem
> 0xffffffffull
)
61 bug("[ATA ] dma_Setup: ERROR: ATA DMA POINTERS BEYOND MAXIMUM ALLOWED ADDRESS!\n");
66 bug("[ATA ] dma_Setup: ERROR: ATA DMA PRD TABLE SIZE TOO LARGE\n");
71 * calculate remainder and see if it is larger of the current memory block.
72 * if smaller, adjust its size.
74 rem
= 0x10000 - (phy_mem
& 0xffff);
78 * update PRD with address and remainder
80 D(bug("[ATA ] dma_Setup: Inserting into PRD Table: %p / %ld @ %p\n", phy_mem
, rem
, array
));
81 array
->prde_Address
= AROS_LONG2LE(phy_mem
);
82 array
->prde_Length
= AROS_LONG2LE((rem
& 0xffff));
97 array
->prde_Length
|= AROS_LONG2LE(PRDE_EOT
);
99 D(bug("[ATA ] dma_Setup: PRD Table set - %ld items in total.\n", items
));
108 BOOL
dma_SetupPRD(struct ata_Unit
*unit
, APTR buffer
, ULONG sectors
, BOOL io
)
110 return dma_SetupPRDSize(unit
, buffer
, sectors
<< unit
->au_SectorShift
, io
);
113 BOOL
dma_SetupPRDSize(struct ata_Unit
*unit
, APTR buffer
, ULONG size
, BOOL read
)
119 D(bug("[ATA%02ld] dma_SetupPRDSize(buffer @ %p, %ld bytes, PRD @ %x for %s)\n", unit
->au_UnitNum
, buffer
, size
, unit
->au_Bus
->ab_PRD
, read
? "READ" : "WRITE"));
121 items
= dma_Setup(buffer
, size
, read
, unit
->au_Bus
->ab_PRD
);
126 length
= items
* sizeof(struct PRDEntry
);
128 prd_phys
= (IPTR
)CachePreDMA(unit
->au_Bus
->ab_PRD
, &length
, DMA_ReadFromRAM
);
130 ATA_OUTL(prd_phys
, dma_PRD
, unit
->au_DMAPort
);
133 ATA_OUT(DMA_WRITE
, dma_Command
, unit
->au_DMAPort
); /* inverse logic */
135 ATA_OUT(DMA_READ
, dma_Command
, unit
->au_DMAPort
);
139 VOID
dma_Cleanup(APTR addr
, ULONG len
, BOOL read
)
142 ULONG flg
= read
? DMA_ReadFromRAM
: 0;
144 D(bug("[ATA ] dma_Cleanup(%p, %d bytes)\n", addr
, len
));
149 CachePostDMA(addr
, &tmp
, flg
);
150 addr
= &((UBYTE
*)addr
)[tmp
];
156 VOID
dma_StartDMA(struct ata_Unit
*unit
)
158 D(bug("[ATA%02ld] dma_StartDMA()\n", unit
->au_UnitNum
));
159 ATA_OUT(ATA_IN(dma_Command
, unit
->au_DMAPort
) | DMA_START
, dma_Command
, unit
->au_DMAPort
);
162 VOID
dma_StopDMA(struct ata_Unit
*unit
)
164 D(bug("[ATA%02ld] dma_StopDMA()\n", unit
->au_UnitNum
));
165 ATA_OUT(ATA_IN(dma_Command
, unit
->au_DMAPort
) & ~DMA_START
, dma_Command
, unit
->au_DMAPort
);