oops .. forgot to offset from objects bounds
[AROS.git] / rom / devs / sdcard / sdcard_bus.c
blobeff0dd831f412d9282b0843d07fc21b29a847820
1 /*
2 Copyright © 2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 0
7 #include <aros/debug.h>
9 #include <aros/bootloader.h>
10 #include <aros/symbolsets.h>
11 #include <exec/exec.h>
12 #include <exec/resident.h>
13 #include <exec/tasks.h>
14 #include <exec/memory.h>
15 #include <exec/nodes.h>
16 #include <utility/utility.h>
17 #include <libraries/expansion.h>
18 #include <libraries/configvars.h>
19 #include <dos/bptr.h>
20 #include <dos/dosextens.h>
21 #include <dos/filehandler.h>
23 #include <proto/exec.h>
24 #include <proto/timer.h>
25 #include <proto/bootloader.h>
26 #include <proto/expansion.h>
27 #include <proto/utility.h>
28 #include <proto/kernel.h>
30 #include <asm/bcm2835.h>
31 #include <hardware/mmc.h>
32 #include <hardware/sdhc.h>
34 #include <string.h>
36 #include "sdcard_base.h"
37 #include "sdcard_bus.h"
38 #include "sdcard_unit.h"
39 #include "timer.h"
41 #include LC_LIBDEFS_FILE
43 /* Generic "Bus Unit" Functions */
45 BOOL FNAME_SDCBUS(StartUnit)(struct sdcard_Unit *sdcUnit)
47 struct TagItem sdcStartTags[] =
49 {SDCARD_TAG_CMD, MMC_CMD_SELECT_CARD},
50 {SDCARD_TAG_ARG, sdcUnit->sdcu_CardRCA << 16},
51 {SDCARD_TAG_RSPTYPE, MMC_RSP_R1},
52 {SDCARD_TAG_RSP, 0},
53 {TAG_DONE, 0}
56 DFUNCS(bug("[SDCard%02ld] %s()\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
58 if (sdcUnit->sdcu_Flags & AF_Card_MMC)
60 FNAME_SDCUNIT(MMCChangeFrequency)(sdcUnit);
62 else
64 FNAME_SDCUNIT(SDSCChangeFrequency)(sdcUnit);
67 sdcard_Udelay(1000);
69 if ((FNAME_SDCBUS(SendCmd)(sdcStartTags, sdcUnit->sdcu_Bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, sdcUnit->sdcu_Bus) != -1))
71 if (FNAME_SDCUNIT(WaitStatus)(10000, sdcUnit) == -1)
73 D(bug("[SDCard%02ld] %s: Failed to Wait for Cards status\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
76 D(bug("[SDCard%02ld] %s: Selected card with RCA %d [select response %08x]\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__, sdcUnit->sdcu_CardRCA, sdcStartTags[3].ti_Data));
77 D(bug("[SDCard%02ld] %s: Card is now operating in Transfer Mode\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
79 if (!(sdcUnit->sdcu_Flags & AF_Card_HighCapacity))
81 sdcStartTags[0].ti_Data = MMC_CMD_SET_BLOCKLEN;
82 sdcStartTags[1].ti_Data = 1 << sdcUnit->sdcu_Bus->sdcb_SectorShift;
83 sdcStartTags[2].ti_Data = MMC_RSP_R1;
84 sdcStartTags[3].ti_Data = 0;
85 if ((FNAME_SDCBUS(SendCmd)(sdcStartTags, sdcUnit->sdcu_Bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, sdcUnit->sdcu_Bus) != -1))
87 D(bug("[SDCard%02ld] %s: Blocklen set to %d\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__, sdcStartTags[1].ti_Data));
89 else
91 D(bug("[SDCard%02ld] %s: Failed to change Blocklen\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
95 if (sdcUnit->sdcu_Flags & AF_Card_MMC)
97 if (sdcUnit->sdcu_Flags & AF_Card_HighSpeed)
99 if (sdcUnit->sdcu_Flags & AB_Card_HighSpeed52)
100 FNAME_SDCBUS(SetClock)(52000000, sdcUnit->sdcu_Bus);
101 else
102 FNAME_SDCBUS(SetClock)(26000000, sdcUnit->sdcu_Bus);
104 else
105 FNAME_SDCBUS(SetClock)(20000000, sdcUnit->sdcu_Bus);
107 else
109 if (sdcUnit->sdcu_Flags & AF_Card_HighSpeed)
110 FNAME_SDCBUS(SetClock)(50000000, sdcUnit->sdcu_Bus);
111 else
112 FNAME_SDCBUS(SetClock)(25000000, sdcUnit->sdcu_Bus);
116 D(bug("[SDCard%02ld] %s: Done.\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
118 return TRUE;
121 ULONG FNAME_SDCUNIT(WaitStatus)(ULONG timeout, struct sdcard_Unit *sdcUnit)
123 struct TagItem sdcStatusTags[] =
125 {SDCARD_TAG_CMD, MMC_CMD_SEND_STATUS},
126 {SDCARD_TAG_ARG, sdcUnit->sdcu_CardRCA << 16},
127 {SDCARD_TAG_RSPTYPE, MMC_RSP_R1},
128 {SDCARD_TAG_RSP, 0},
129 {TAG_DONE, 0}
132 UBYTE retryreq = 5;
134 DFUNCS(bug("[SDCard%02ld] %s()\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
136 do {
137 if (FNAME_SDCBUS(SendCmd)(sdcStatusTags, sdcUnit->sdcu_Bus) != -1)
139 if ((sdcStatusTags[3].ti_Data & MMC_STATUS_RDY_FOR_DATA) &&
140 (sdcStatusTags[3].ti_Data & MMC_STATUS_STATE_MASK) != MMC_STATUS_STATE_PRG)
141 break;
142 else if (sdcStatusTags[3].ti_Data & MMC_STATUS_MASK) {
143 bug("[SDCard%02ld] %s: Status [Error = %08x]\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__, sdcStatusTags[3].ti_Data);
144 return -1;
146 } else if (--retryreq < 0)
147 return -1;
149 sdcard_Udelay(1000);
150 } while (--timeout > 0);
152 if (timeout <= 0) {
153 bug("[SDCard%02ld] %s: Timeout\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__);
154 return -1;
157 D(bug("[SDCard%02ld] %s: State = %08x\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__, sdcStatusTags[3].ti_Data & MMC_STATUS_STATE_MASK));
159 return 0;
162 /* Bus Functions */
164 BOOL FNAME_SDCBUS(RegisterUnit)(struct sdcard_Bus *bus)
166 unsigned int sdcCardPower, timeout = 1000;
167 LIBBASETYPEPTR LIBBASE = bus->sdcb_DeviceBase;
168 ULONG sdcRsp136[4] = {0, 0, 0, 0};
169 struct sdcard_Unit *sdcUnit = NULL;
170 struct DeviceNode *devnode;
171 struct TagItem sdcRegTags[] =
173 {SDCARD_TAG_CMD, 0},
174 {SDCARD_TAG_ARG, 0},
175 {SDCARD_TAG_RSPTYPE, 0},
176 {SDCARD_TAG_RSP, 0},
177 {TAG_DONE, 0}
179 BOOL sdcHighCap = FALSE;
180 IPTR pp[24];
182 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
184 D(bug("[SDBus%02u] %s: Putting card into Idle state ...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
185 sdcRegTags[0].ti_Data = MMC_CMD_GO_IDLE_STATE;
186 sdcRegTags[1].ti_Data = 0;
187 sdcRegTags[2].ti_Data = MMC_RSP_NONE;
188 if (FNAME_SDCBUS(SendCmd)(sdcRegTags, bus) == -1)
190 D(bug("[SDBus%02u] %s: Error: Card failed to go idle!\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
191 return FALSE;
194 sdcard_Udelay(2000);
196 sdcRegTags[0].ti_Data = SD_CMD_SEND_IF_COND;
197 sdcRegTags[1].ti_Data = ((bus->sdcb_Power & 0xFF8000) != 0) << 8 | 0xAA;
198 sdcRegTags[2].ti_Data = MMC_RSP_R7;
199 D(bug("[SDBus%02u] %s: Querying Interface conditions [%08x] ...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcRegTags[1].ti_Data));
201 if ((FNAME_SDCBUS(SendCmd)(sdcRegTags, bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, bus) != -1))
203 D(bug("[SDBus%02u] %s: Query Response = %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcRegTags[3].ti_Data));
204 D(bug("[SDBus%02u] %s: SD2.0 Compliant Card .. publishing high-capacity support\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
205 sdcHighCap = TRUE;
207 else
209 D(bug("[SDBus%02u] %s: SD1.0 Compliant Card\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
212 do {
213 D(bug("[SDBus%02u] %s: Preparing for Card App Command ...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
214 sdcRegTags[0].ti_Data = MMC_CMD_APP_CMD;
215 sdcRegTags[1].ti_Data = 0;
216 sdcRegTags[2].ti_Data = MMC_RSP_R1;
218 if ((FNAME_SDCBUS(SendCmd)(sdcRegTags, bus) == -1) || (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, bus) == -1))
220 D(bug("[SDBus%02u] %s: App Command Failed\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
221 return FALSE;
223 D(bug("[SDBus%02u] %s: App Command Response = %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcRegTags[3].ti_Data));
225 sdcRegTags[0].ti_Data = SD_CMD_APP_SEND_OP_COND;
226 sdcRegTags[1].ti_Data = (bus->sdcb_Power & 0xFF8000) | (sdcHighCap ? OCR_HCS : 0);
227 #warning "TODO: Publish support for OCR_S18R/OCR_XPC on capable Hosts"
228 sdcRegTags[2].ti_Data = MMC_RSP_R3;
230 D(bug("[SDBus%02u] %s: Querying Operating conditions [%08x] ...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcRegTags[1].ti_Data));
231 if ((FNAME_SDCBUS(SendCmd)(sdcRegTags, bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, bus) != -1))
233 D(bug("[SDBus%02u] %s: Query Response = %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcRegTags[3].ti_Data));
234 sdcard_Udelay(1000);
236 else
238 D(bug("[SDBus%02u] %s: Operating condition Query Failed\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
239 return FALSE;
241 } while ((!(sdcRegTags[3].ti_Data & OCR_BUSY)) && (--timeout > 0));
243 sdcHighCap = FALSE;
245 if (timeout > 0)
247 D(bug("[SDBus%02u] %s: Card OCR = %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, (sdcRegTags[3].ti_Data & 0xFFFF00)));
249 sdcCardPower = bus->sdcb_Power & (sdcRegTags[3].ti_Data & 0xFFFF00);
251 D(bug("[SDBus%02u] %s: Card is now operating in Identification Mode\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
253 if (sdcRegTags[3].ti_Data & OCR_HCS)
255 D(bug("[SDBus%02u] %s: High Capacity Card detected\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
256 sdcHighCap = TRUE;
259 if (sdcRegTags[3].ti_Data & OCR_S18R)
261 D(bug("[SDBus%02u] %s: Begin Voltage Switching..\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
264 FNAME_SDCBUS(SetPowerLevel)(sdcCardPower, TRUE, bus);
265 sdcard_Udelay(2000);
267 /* Put the "card" into identify mode*/
268 D(bug("[SDBus%02u] %s: Querying Card Identification Data ...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
269 sdcRegTags[0].ti_Data = MMC_CMD_ALL_SEND_CID;
270 sdcRegTags[1].ti_Data = 0;
271 sdcRegTags[2].ti_Data = MMC_RSP_R2;
272 sdcRegTags[3].ti_Data = (IPTR)sdcRsp136;
273 if ((FNAME_SDCBUS(SendCmd)(sdcRegTags, bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, bus) != -1))
275 if (sdcRegTags[3].ti_Data)
277 D(bug("[SDBus%02u] %s: # Card Identification Data (CID) Register\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
278 D(bug("[SDBus%02u] %s: # ======================================\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
279 D(bug("[SDBus%02u] %s: # Manuafacturer ID (MID) : %06x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 120, 8)));
280 D(bug("[SDBus%02u] %s: # Product Name (PNM) : %c%c%c%c%c\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 96, 8), FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 88, 8), FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 80, 8), FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 72, 8), FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 64, 8)));
281 D(bug("[SDBus%02u] %s: # Product Revision (PRV) : %d.%d\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 60, 4), FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 56, 4)));
282 D(bug("[SDBus%02u] %s: # Serial number (PSN) : %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 24, 32)));
283 D(bug("[SDBus%02u] %s: # Manufacturing Date Code (MDT) : %d/%d\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 8, 4), FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 12, 8)));
284 D(bug("[SDBus%02u] %s: # CRC7 checksum (CRC7) : %x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 1, 7)));
285 D(bug("[SDBus%02u] %s: # Reserved : %x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 0, 1)));
288 D(bug("[SDBus%02u] %s: Querying Card Relative Address... \n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
289 sdcRegTags[0].ti_Data = SD_CMD_SEND_RELATIVE_ADDR;
290 sdcRegTags[1].ti_Data = 0;
291 sdcRegTags[2].ti_Data = MMC_RSP_R6;
292 sdcRegTags[3].ti_Data = 0;
293 if ((FNAME_SDCBUS(SendCmd)(sdcRegTags, bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, bus) != -1))
295 if ((sdcUnit = AllocVecPooled(LIBBASE->sdcard_MemPool, sizeof(struct sdcard_Unit))) != NULL)
297 sdcUnit->sdcu_Bus = bus;
298 if ((sdcUnit->sdcu_UnitNum = bus->sdcb_BusUnits->sdcbu_UnitCnt++) > bus->sdcb_BusUnits->sdcbu_UnitMax)
300 return FALSE;
302 (&bus->sdcb_BusUnits->sdcbu_Units)[sdcUnit->sdcu_UnitNum] = sdcUnit;
303 sdcUnit->sdcu_UnitNum += bus->sdcb_BusUnits->sdcbu_UnitBase;
304 sdcUnit->sdcu_CardRCA = (sdcRegTags[3].ti_Data >> 16) & 0xFFFF;
305 sdcUnit->sdcu_CardPower = sdcCardPower;
307 D(bug("[SDBus%02u] %s: Card RCA = %d\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcUnit->sdcu_CardRCA));
309 sdcRegTags[0].ti_Data = MMC_CMD_SEND_CSD;
310 sdcRegTags[1].ti_Data = sdcUnit->sdcu_CardRCA << 16;
311 sdcRegTags[2].ti_Data = MMC_RSP_R2;
312 sdcRegTags[3].ti_Data = (IPTR)sdcRsp136;
313 D(bug("[SDBus%02u] %s: Querying Card Specific Data [%08x] ...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcRegTags[1].ti_Data));
314 if ((FNAME_SDCBUS(SendCmd)(sdcRegTags, bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, bus) != -1))
316 if (FNAME_SDCUNIT(WaitStatus)(10000, sdcUnit) == -1)
318 D(bug("[SDBus%02lu] %s: Failed to Wait for Cards status\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
321 if (sdcRegTags[3].ti_Data)
323 int __csdstruct = FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 126, 2);
324 D(bug("[SDBus%02u] %s: # Card Specific Data (CSD) Register\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
325 D(bug("[SDBus%02u] %s: # =================================\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
326 D(bug("[SDBus%02u] %s: # CSD_STRUCTURE : %x ", bus->sdcb_BusNum, __PRETTY_FUNCTION__, __csdstruct));
328 sdcUnit->sdcu_Read32 = FNAME_SDCIO(ReadSector32);
329 sdcUnit->sdcu_Write32 = FNAME_SDCIO(WriteSector32);
330 sdcUnit->sdcu_Bus->sdcb_BusFlags = AF_Bus_MediaPresent;
331 #if defined(SDHCI_READONLY)
332 sdcUnit->sdcu_Flags = AF_Card_WriteProtect;
333 #endif
334 if (sdcHighCap)
336 sdcUnit->sdcu_Flags |= AF_Card_HighCapacity;
337 sdcUnit->sdcu_Read64 = FNAME_SDCIO(ReadSector64);
338 sdcUnit->sdcu_Write64 = FNAME_SDCIO(WriteSector64);
341 switch (__csdstruct)
343 case 0:
345 D(bug("[SDSC Card]\n"));
346 pp[DE_SIZEBLOCK + 4] = 1 << FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 80, 4);
347 pp[DE_SECSPERBLOCK + 4] = pp[DE_SIZEBLOCK + 4] >> 9;
348 pp[DE_HIGHCYL + 4] = ((1 + FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 62, 12)) << (FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 47, 3) + 2));
349 break;
351 case 1:
353 D(bug("[SDHC/XC Card]\n"));
355 pp[DE_SECSPERBLOCK + 4] = 2;
356 pp[DE_SIZEBLOCK + 4] = 2 << (10 - 1);
357 pp[DE_HIGHCYL + 4] = ((1 + FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 48, 22)) * (2 << (9 - 1)));
359 sdcUnit->sdcu_Flags |= AF_Card_MMC;
361 break;
363 default:
364 D(bug("[SDBus%02u] %s: Unsupported Card\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
365 return FALSE;
368 sdcUnit->sdcu_Cylinders = pp[DE_HIGHCYL + 4];
369 sdcUnit->sdcu_Heads = 1;
370 sdcUnit->sdcu_Sectors = pp[DE_SECSPERBLOCK + 4];
371 sdcUnit->sdcu_Capacity = sdcUnit->sdcu_Cylinders * sdcUnit->sdcu_Heads * sdcUnit->sdcu_Sectors;
373 sdcUnit->sdcu_Eject = FNAME_SDCIO(Eject);
375 D(bug("[SDBus%02u] %s: # READ_BL_LEN : %dbytes\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, pp[DE_SIZEBLOCK + 4] / sdcUnit->sdcu_Sectors));
376 D(bug("[SDBus%02u] %s: # C_SIZE : %d\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcUnit->sdcu_Cylinders));
378 pp[0] = (IPTR)"MMC0";
379 pp[1] = (IPTR)MOD_NAME_STRING;
380 pp[2] = 0;
381 pp[DE_TABLESIZE + 4] = DE_BOOTBLOCKS;
382 pp[DE_NUMHEADS + 4] = sdcUnit->sdcu_Heads;
383 pp[DE_BLKSPERTRACK + 4] = 1;
384 pp[DE_RESERVEDBLKS + 4] = 2;
385 pp[DE_LOWCYL + 4] = 0;
386 pp[DE_NUMBUFFERS + 4] = 10;
387 pp[DE_BUFMEMTYPE + 4] = MEMF_PUBLIC | MEMF_31BIT;
388 pp[DE_MAXTRANSFER + 4] = 0x00200000;
389 pp[DE_MASK + 4] = 0x7FFFFFFE;
390 pp[DE_BOOTPRI + 4] = 0;
391 pp[DE_DOSTYPE + 4] = AROS_MAKE_ID('D','O','S','\001');
392 pp[DE_CONTROL + 4] = 0;
393 pp[DE_BOOTBLOCKS + 4] = 2;
395 devnode = MakeDosNode(pp);
397 if (devnode)
399 bug("[SDBus%02u] %b: [%ldMB Capacity]\n", bus->sdcb_BusNum, devnode->dn_Name, (ULONG)((sdcUnit->sdcu_Capacity >> 11) & 0xFFFFFFFFul));
400 D(bug("[SDBus%02u] %s: StartCyl:%d, EndCyl:%d ..\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__,
401 pp[DE_LOWCYL + 4], pp[DE_HIGHCYL + 4]));
402 D(bug("[SDBus%02u] %s: BlockSize:%d, SectorsPerBlock:%d ..\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__,
403 pp[DE_SIZEBLOCK + 4], sdcUnit->sdcu_Sectors));
405 AddBootNode(pp[DE_BOOTPRI + 4], ADNF_STARTPROC, devnode, NULL);
406 D(bug("[SDBus%02u] %s: Unit detection complete\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
408 return TRUE;
412 else
414 D(bug("[SDBus%02u] %s: Card failed to send CSD\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
417 else
419 D(bug("[SDBus%02u] %s: Failed to allocate Unit\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
422 else
424 D(bug("[SDBus%02u] %s: Card failed to send RCA\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
427 else
429 D(bug("[SDBus%02u] %s: Card failed to send CID\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
432 else
434 D(bug("[SDBus%02u] %s: Card failed to initialise\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
437 return FALSE;
440 void FNAME_SDCBUS(ReleaseUnit)(struct sdcard_Bus *bus)
442 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
445 void FNAME_SDCBUS(SoftReset)(UBYTE mask, struct sdcard_Bus *bus)
447 ULONG timeout = 100;
449 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
451 bus->sdcb_IOWriteByte(SDHCI_RESET, mask, bus);
452 while (bus->sdcb_IOReadByte(SDHCI_RESET, bus) & mask) {
453 if (timeout == 0) {
454 bug("[SDBus%02u] %s: Timeout\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
455 break;
457 sdcard_Udelay(1000);
458 timeout--;
462 void FNAME_SDCBUS(SetClock)(ULONG speed, struct sdcard_Bus *bus)
464 ULONG sdcClkDiv, timeout;
465 UWORD sdcClkCtrlCur, sdcClkCtrl;
467 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
469 sdcClkCtrlCur = bus->sdcb_IOReadWord(SDHCI_CLOCK_CONTROL, bus);
471 sdcClkDiv = FNAME_SDCBUS(GetClockDiv)(speed, bus);
473 sdcClkCtrl = (sdcClkDiv & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
474 sdcClkCtrl |= ((sdcClkDiv & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) << SDHCI_DIVIDER_HI_SHIFT;
476 if (sdcClkCtrl != (sdcClkCtrlCur & ~(SDHCI_CLOCK_INT_EN|SDHCI_CLOCK_INT_STABLE|SDHCI_CLOCK_CARD_EN)))
478 bus->sdcb_IOWriteWord(SDHCI_CLOCK_CONTROL, 0, bus);
480 D(bug("[SDBus%02u] %s: Changing CLOCK_CONTROL [0x%04x -> 0x%04x] (div %d)\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcClkCtrlCur & ~(SDHCI_CLOCK_INT_EN|SDHCI_CLOCK_INT_STABLE|SDHCI_CLOCK_CARD_EN), sdcClkCtrl, sdcClkDiv));
482 bus->sdcb_IOWriteWord(SDHCI_CLOCK_CONTROL, (sdcClkCtrl | SDHCI_CLOCK_INT_EN), bus);
484 timeout = 20;
485 while (!((sdcClkCtrl = bus->sdcb_IOReadWord(SDHCI_CLOCK_CONTROL, bus)) & SDHCI_CLOCK_INT_STABLE)) {
486 if (timeout == 0) {
487 bug("[SDBus%02u] %s: SDHCI Clock failed to stabilise\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
488 break;
490 sdcard_Udelay(1000);
491 timeout --;
494 else
495 if (sdcClkCtrlCur & SDHCI_CLOCK_CARD_EN)
496 return;
498 D(bug("[SDBus%02u] %s: Enabling clock...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
499 sdcClkCtrl |= SDHCI_CLOCK_CARD_EN;
500 bus->sdcb_IOWriteWord(SDHCI_CLOCK_CONTROL, sdcClkCtrl, bus);
503 void FNAME_SDCBUS(SetPowerLevel)(ULONG supportedlvls, BOOL lowest, struct sdcard_Bus *bus)
505 UBYTE sdcReg = 0, lvlCur;
507 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
509 if (lowest)
511 if (supportedlvls & MMC_VDD_165_195)
512 sdcReg = SDHCI_POWER_180;
513 else if (supportedlvls & (MMC_VDD_290_300|MMC_VDD_300_310))
514 sdcReg = SDHCI_POWER_300;
515 else if (supportedlvls & (MMC_VDD_320_330|MMC_VDD_330_340))
516 sdcReg = SDHCI_POWER_330;
518 else
520 if (supportedlvls & (MMC_VDD_320_330|MMC_VDD_330_340))
521 sdcReg = SDHCI_POWER_330;
522 else if (supportedlvls & (MMC_VDD_290_300|MMC_VDD_300_310))
523 sdcReg = SDHCI_POWER_300;
524 else if (supportedlvls & MMC_VDD_165_195)
525 sdcReg = SDHCI_POWER_180;
528 lvlCur = bus->sdcb_IOReadByte(SDHCI_POWER_CONTROL, bus);
529 if ((lvlCur & ~SDHCI_POWER_ON) != sdcReg)
531 D(bug("[SDBus%02u] %s: Changing Power Lvl [0x%x -> 0x%x]\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, lvlCur & ~SDHCI_POWER_ON, sdcReg));
532 bus->sdcb_IOWriteByte(SDHCI_POWER_CONTROL, sdcReg, bus);
533 sdcReg |= SDHCI_POWER_ON;
534 bus->sdcb_IOWriteByte(SDHCI_POWER_CONTROL, sdcReg, bus);
536 else
538 if (!(lvlCur & SDHCI_POWER_ON))
540 D(bug("[SDBus%02u] %s: Enabling Power Lvl [0x%x]\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, lvlCur));
541 lvlCur |= SDHCI_POWER_ON;
542 bus->sdcb_IOWriteByte(SDHCI_POWER_CONTROL, lvlCur, bus);
547 ULONG FNAME_SDCBUS(SendCmd)(struct TagItem *CmdTags, struct sdcard_Bus *bus)
549 UWORD sdCommand = (UWORD)GetTagData(SDCARD_TAG_CMD, 0, CmdTags);
550 ULONG sdArg = GetTagData(SDCARD_TAG_ARG, 0, CmdTags);
551 ULONG sdResponseType = GetTagData(SDCARD_TAG_RSPTYPE, MMC_RSP_NONE, CmdTags);
552 ULONG sdDataLen = 0, sdDataFlags;
554 UWORD sdcTransMode = 0, sdCommandFlags;
555 ULONG sdcInhibitMask = SDHCI_PS_CMD_INHIBIT;
556 ULONG timeout = 10;
557 ULONG retVal = 0;
559 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
561 if ((sdDataLen = GetTagData(SDCARD_TAG_DATALEN, 0, CmdTags)) > 0)
563 sdDataFlags = GetTagData(SDCARD_TAG_DATAFLAGS, 0, CmdTags);
566 /* Dont wait for DATA inihibit for stop commands */
567 if (sdCommand != MMC_CMD_STOP_TRANSMISSION)
568 sdcInhibitMask |= SDHCI_PS_DATA_INHIBIT;
570 while (bus->sdcb_IOReadLong(SDHCI_PRESENT_STATE, bus) & sdcInhibitMask) {
571 if (timeout == 0) {
572 bug("[SDBus%02u] %s: Controller failed to release inhibited bit(s).\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
573 bug("[SDBus%02u] %s: failed bit(s) = %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_IOReadLong(SDHCI_PRESENT_STATE, bus) & sdcInhibitMask);
575 bug("[SDBus%02u] %s: Reseting SDHCI CMD/DATA\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
577 FNAME_SDCBUS(SoftReset)(SDHCI_RESET_CMD, bus);
578 FNAME_SDCBUS(SoftReset)(SDHCI_RESET_DATA, bus);
580 return -1;
582 sdcard_Udelay(1000);
583 timeout--;
586 if (!(sdResponseType & MMC_RSP_PRESENT))
587 sdCommandFlags = SDHCI_CMD_RESP_NONE;
588 else if (sdResponseType & MMC_RSP_136)
589 sdCommandFlags = SDHCI_CMD_RESP_LONG;
590 else if (sdResponseType & MMC_RSP_BUSY)
591 sdCommandFlags = SDHCI_CMD_RESP_SHORT_BUSY;
592 else
593 sdCommandFlags = SDHCI_CMD_RESP_SHORT;
595 if (sdResponseType & MMC_RSP_CRC)
596 sdCommandFlags |= SDHCI_CMD_CRC;
597 if (sdResponseType & MMC_RSP_OPCODE)
598 sdCommandFlags |= SDHCI_CMD_INDEX;
599 if (sdDataLen > 0)
600 sdCommandFlags |= SDHCI_CMD_DATA;
602 if (sdDataLen > 0) {
603 sdcTransMode = SDHCI_TRANSMOD_BLK_CNT_EN;
604 DTRANS(bug("[SDBus%02u] %s: Configuring Data Transfer\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
606 if (bus->sdcb_LEDCtrl)
607 bus->sdcb_LEDCtrl(LED_ON);
609 bus->sdcb_IOWriteByte(SDHCI_TIMEOUT_CONTROL, SDHCI_TIMEOUT_MAX, bus);
611 bus->sdcb_IOWriteWord(SDHCI_BLOCK_SIZE, ((1 << 16) | ((sdDataLen > (1 << bus->sdcb_SectorShift)) ? (1 << bus->sdcb_SectorShift) : sdDataLen)), bus);
612 if ((sdDataLen >> bus->sdcb_SectorShift) > 1)
614 sdcTransMode |= SDHCI_TRANSMOD_MULTI;
615 bus->sdcb_IOWriteWord(SDHCI_BLOCK_COUNT, sdDataLen >> bus->sdcb_SectorShift, bus);
617 else
619 bus->sdcb_IOWriteWord(SDHCI_BLOCK_COUNT, 1, bus);
622 if (sdDataFlags == MMC_DATA_READ)
623 sdcTransMode |= SDHCI_TRANSMOD_READ;
625 if (!(bus->sdcb_Quirks & AF_Quirk_AtomicTMAndCMD))
627 bus->sdcb_IOWriteWord(SDHCI_TRANSFER_MODE, sdcTransMode, bus);
630 DTRANS(bug("[SDBus%02u] %s: Mode %08x [%d x %dBytes]\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcTransMode, (((sdDataLen >> bus->sdcb_SectorShift) > 0) ? (sdDataLen >> bus->sdcb_SectorShift) : 1), ((sdDataLen > (1 << bus->sdcb_SectorShift)) ? (1 << bus->sdcb_SectorShift) : sdDataLen)));
633 bus->sdcb_RespListener = CmdTags;
634 if (sdDataLen > 0)
635 bus->sdcb_DataListener = CmdTags;
637 bus->sdcb_IOWriteLong(SDHCI_ARGUMENT, sdArg, bus);
638 if ((bus->sdcb_Quirks & AF_Quirk_AtomicTMAndCMD) && (sdcTransMode))
640 bus->sdcb_IOWriteLong(SDHCI_TRANSFER_MODE, (SDHCI_MAKE_CMD(sdCommand, sdCommandFlags) << 16) | sdcTransMode, bus);
642 else
644 bus->sdcb_IOWriteWord(SDHCI_COMMAND, SDHCI_MAKE_CMD(sdCommand, sdCommandFlags), bus);
647 D(bug("[SDBus%02u] %s: CMD %02d Sent\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdCommand));
649 return retVal;
652 ULONG FNAME_SDCBUS(FinishCmd)(struct TagItem *CmdTags, struct sdcard_Bus *bus)
654 struct TagItem *Response = NULL;
656 D(UWORD sdCommand = (UWORD)GetTagData(SDCARD_TAG_CMD, 0, CmdTags));
657 ULONG sdResponseType = GetTagData(SDCARD_TAG_RSPTYPE, MMC_RSP_NONE, CmdTags);
658 ULONG retVal = 0;
660 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
662 if (sdResponseType != MMC_RSP_NONE)
664 if ((Response = FindTagItem(SDCARD_TAG_RSP, CmdTags)) != NULL)
666 D(bug("[SDBus%02u] %s: Reading CMD %02d Response ", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdCommand));
667 if (sdResponseType & MMC_RSP_136)
669 D(bug("[136bit]\n"));
670 if (Response->ti_Data)
672 ULONG i;
673 for (i = 0; i < 4; i ++)
675 ((ULONG *)Response->ti_Data)[i] = bus->sdcb_IOReadLong(SDHCI_RESPONSE + (3 - i) * 4, bus) << 8;
676 if (i != 3)
677 ((ULONG *)Response->ti_Data)[i] |= bus->sdcb_IOReadByte(SDHCI_RESPONSE + (3 - i) * 4 - 1, bus);
679 D(bug("[SDBus%02u] %s: %08x%08x%08x%08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, ((ULONG *)Response->ti_Data)[0], ((ULONG *)Response->ti_Data)[1], ((ULONG *)Response->ti_Data)[2], ((ULONG *)Response->ti_Data)[3]));
682 else
684 Response->ti_Data = bus->sdcb_IOReadLong(SDHCI_RESPONSE, bus);
685 D(bug("[= %08x]\n", Response->ti_Data));
690 return retVal;
693 ULONG FNAME_SDCBUS(FinishData)(struct TagItem *DataTags, struct sdcard_Bus *bus)
695 DTRANS(UWORD sdCommand = (UWORD)GetTagData(SDCARD_TAG_CMD, 0, DataTags));
696 ULONG sdcStateMask, sdCommandMask,
697 sdData, sdDataMode, sdDataLen, sdcReg = 0;
698 struct TagItem *sdDataLenTag = NULL;
699 ULONG timeout = 1000;
700 ULONG retVal = 0;
702 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
704 if ((sdData = GetTagData(SDCARD_TAG_DATA, 0, DataTags)) != 0)
706 if ((sdDataLenTag = FindTagItem(SDCARD_TAG_DATALEN, DataTags)) == NULL)
707 sdData = 0;
708 else
710 sdDataLen = sdDataLenTag->ti_Data;
711 if ((sdDataMode = GetTagData(SDCARD_TAG_DATAFLAGS, MMC_DATA_READ, DataTags)) == MMC_DATA_READ)
713 sdcStateMask = SDHCI_PS_DATA_AVAILABLE;
714 sdCommandMask = SDHCI_INT_DATA_AVAIL;
716 else
718 sdcStateMask = SDHCI_PS_SPACE_AVAILABLE;
719 sdCommandMask = SDHCI_INT_SPACE_AVAIL;
724 if (sdData)
726 DTRANS(bug("[SDBus%02u] %s: Transfering CMD %02d Data..\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdCommand));
727 do {
728 bus->sdcb_BusStatus = bus->sdcb_IOReadLong(SDHCI_INT_STATUS, bus);
729 if (bus->sdcb_BusStatus & SDHCI_INT_ERROR) {
730 bug("[SDBus%02u] %s: Error [status 0x%X]!\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_BusStatus);
731 retVal = -1;
732 break;
735 if ((bus->sdcb_BusStatus & sdCommandMask) && (bus->sdcb_IOReadLong(SDHCI_PRESENT_STATE, bus) & sdcStateMask)) {
736 ULONG currbyte, tranlen = (sdDataLen > (1 << bus->sdcb_SectorShift)) ? (1 << bus->sdcb_SectorShift) : sdDataLen;
738 DTRANS(bug("[SDBus%02u] %s: Attempting to %s %dbytes\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, ((sdDataMode == MMC_DATA_READ) ? "read" : "write"), tranlen));
739 for (currbyte = 0; currbyte < tranlen; currbyte++)
741 DTRANS(DUMP(
742 if ((currbyte % 16) == 0)
744 bug("[SDBus%02u] %s: ", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
747 if (sdDataMode == MMC_DATA_READ)
749 if ((currbyte % 4) == 0)
751 sdcReg = bus->sdcb_IOReadLong(SDHCI_BUFFER, bus);
753 *(UBYTE *)sdData = sdcReg & 0xFF;
755 else
756 sdcReg |= *(UBYTE *)sdData << (currbyte % 4);
758 sdData++;
759 sdDataLen--;
760 if (sdDataMode != MMC_DATA_READ)
762 if (((currbyte % 4) == 3) || (sdDataLen == 0))
764 bus->sdcb_IOWriteLong(SDHCI_BUFFER, *(ULONG *)(sdData - 3), bus);
767 else
768 sdcReg >>= 8;
769 DTRANS(DUMP(
770 if ((currbyte % 4) == 3)
772 bug(" %08x", *(ULONG *)(sdData - 3));
774 if ((currbyte % 16) == 15)
776 bug("\n");
780 DTRANS(DUMP(
781 if ((currbyte % 16) != 0)
783 bug("\n");
787 else if (!(bus->sdcb_BusStatus & SDHCI_INT_DATA_END))
789 sdcard_Udelay(1000);
791 if (timeout-- <= 0)
793 bug("[SDBus%02u] %s: Timeout!\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
794 retVal = -1;
795 break;
798 } while ((sdDataLen > 0) && (!(bus->sdcb_BusStatus & SDHCI_INT_DATA_END)));
800 if (bus->sdcb_LEDCtrl)
801 bus->sdcb_LEDCtrl(LED_OFF);
803 sdDataLenTag->ti_Data -= sdDataLen;
806 return retVal;
809 ULONG FNAME_SDCBUS(WaitCmd)(ULONG mask, ULONG timeout, struct sdcard_Bus *bus)
811 bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
813 while (bus->sdcb_IOReadLong(SDHCI_PRESENT_STATE, bus) & mask) {
814 sdcard_Udelay(1000);
816 if ((bus->sdcb_BusStatus & SDHCI_INT_ERROR) == SDHCI_INT_ERROR)
817 break;
819 if (--timeout <= 0)
820 break;
823 if ((timeout <= 0) || (bus->sdcb_BusStatus & SDHCI_INT_ERROR))
825 return -1;
828 return 0;
832 ULONG FNAME_SDCBUS(Rsp136Unpack)(ULONG *buf, ULONG offset, const ULONG len)
834 const ULONG mask = ((len < 32) ? (1 << len) : 0) - 1;
835 const ULONG shift = (offset) & 0x1F;
836 ULONG retval;
838 retval = buf[3 - (offset >> 5)] >> shift;
839 if (len + shift > 32)
840 retval |= buf[3 - (offset >> 5) - 1] << ((32 - shift) % 32);
842 return (retval & mask);
845 /********** BUS IRQ HANDLER **************/
847 void FNAME_SDCBUS(BusIRQ)(struct sdcard_Bus *bus, void *_unused)
849 BOOL error = FALSE;
851 DIRQ(bug("[SDBus%02u] %s(bus @ 0x%p)\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus));
853 if (!(bus))
855 DIRQ(bug("[SDBus%02u] %s: Bad Params!\n", __PRETTY_FUNCTION__));
856 return;
859 bus->sdcb_BusStatus = bus->sdcb_IOReadLong(SDHCI_INT_STATUS, bus);
861 if (!(bus->sdcb_BusStatus & SDHCI_INT_ERROR))
863 DIRQ(bug("[SDBus%02u] %s: Status = %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_BusStatus));
865 if (bus->sdcb_BusStatus & (SDHCI_INT_CARD_INSERT|SDHCI_INT_CARD_REMOVE))
867 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, (bus->sdcb_BusStatus & (SDHCI_INT_CARD_INSERT|SDHCI_INT_CARD_REMOVE)), bus);
869 bus->sdcb_BusFlags &= ~AF_Bus_MediaPresent;
870 bus->sdcb_BusFlags |= AF_Bus_MediaChanged;
872 if (bus->sdcb_BusStatus & SDHCI_INT_CARD_INSERT)
873 bus->sdcb_BusFlags |= AF_Bus_MediaPresent;
875 bus->sdcb_BusStatus &= ~(SDHCI_INT_CARD_INSERT|SDHCI_INT_CARD_REMOVE);
877 if (bus->sdcb_Task)
878 Signal(bus->sdcb_Task, (1L << bus->sdcb_MediaSig));
880 if (bus->sdcb_BusStatus & SDHCI_INT_CMD_MASK)
882 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, (bus->sdcb_BusStatus & SDHCI_INT_CMD_MASK), bus);
884 if ((bus->sdcb_BusStatus & SDHCI_INT_RESPONSE) &&
885 (bus->sdcb_RespListener))
887 if (FNAME_SDCBUS(FinishCmd)(bus->sdcb_RespListener, bus) == -1)
888 error = TRUE;
889 bus->sdcb_RespListener = NULL;
891 bus->sdcb_BusStatus &= ~SDHCI_INT_CMD_MASK;
893 if (bus->sdcb_BusStatus & SDHCI_INT_DATA_MASK)
895 if ((bus->sdcb_BusStatus & (SDHCI_INT_DATA_AVAIL|SDHCI_INT_SPACE_AVAIL)) &&
896 (bus->sdcb_DataListener))
898 if (FNAME_SDCBUS(FinishData)(bus->sdcb_DataListener, bus) == -1)
899 error = TRUE;
900 bus->sdcb_DataListener = NULL;
901 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, (bus->sdcb_BusStatus & (SDHCI_INT_DATA_AVAIL|SDHCI_INT_SPACE_AVAIL)), bus);
902 bus->sdcb_BusStatus &= ~SDHCI_INT_DATA_MASK;
904 else
906 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, (bus->sdcb_BusStatus & SDHCI_INT_DATA_MASK), bus);
907 bus->sdcb_BusStatus &= ~SDHCI_INT_DATA_MASK;
911 else
913 bug("[SDBus%02u] %s: ERROR [Status = %08x]\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_BusStatus);
914 if (bus->sdcb_BusStatus & SDHCI_INT_ACMD12ERR)
916 bug("[SDBus%02u] %s: [acmd12err = %04x ]\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_IOReadWord(SDHCI_ACMD12_ERR, bus));
918 error = TRUE;
921 if (error)
923 if (bus->sdcb_BusStatus & bus->sdcb_IntrMask)
925 bug("[SDBus%02u] %s: Clearing Unhandled Interrupts [%08x]\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_BusStatus & bus->sdcb_IntrMask);
926 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, bus->sdcb_BusStatus & bus->sdcb_IntrMask, bus);
927 bus->sdcb_BusStatus &= ~bus->sdcb_IntrMask;
929 bug("[SDBus%02u] %s: Reseting SDHCI CMD/DATA\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
931 FNAME_SDCBUS(SoftReset)(SDHCI_RESET_CMD, bus);
932 FNAME_SDCBUS(SoftReset)(SDHCI_RESET_DATA, bus);
934 DIRQ(bug("[SDBus%02u] %s: Done.\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
937 /********** BUS MANAGEMENT TASK **************/
939 void FNAME_SDCBUS(BusTask)(struct sdcard_Bus *bus)
941 LIBBASETYPEPTR LIBBASE = bus->sdcb_DeviceBase;
942 struct IORequest *msg;
943 ULONG sig, tasksig;
945 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
947 bus->sdcb_Timer = sdcard_OpenTimer(LIBBASE);
949 /* Get the signal used for sleeping */
950 bus->sdcb_Task = FindTask(0);
952 D(bug("[SDBus%02u] %s: Task @ 0x%p\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_Task));
954 bus->sdcb_TaskSig = AllocSignal(-1);
955 if ((bus->sdcb_MediaSig = AllocSignal(-1)) == -1)
957 D(bug("[SDBus%02u] %s: failed to allocate Media Change sigbit\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
960 /* Failed to get it? Use SIGBREAKB_CTRL_E instead */
961 if (bus->sdcb_TaskSig < 0)
962 bus->sdcb_TaskSig = SIGBREAKB_CTRL_E;
964 sig = ((1L << bus->sdcb_MsgPort->mp_SigBit)|(1L << bus->sdcb_TaskSig)|(1L << bus->sdcb_MediaSig));
966 DINIT(bug("[SDBus%02u] %s: TaskSig: %d, MediaSig: %d\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_TaskSig, bus->sdcb_MediaSig));
968 /* Install IRQ handler */
969 if ((bus->sdcb_IRQHandle = KrnAddIRQHandler(bus->sdcb_BusIRQ, FNAME_SDCBUS(BusIRQ), bus, NULL)) != NULL)
971 DINIT(bug("[SDBus%02u] %s: IRQHandle @ 0x%p for IRQ#%ld\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_IRQHandle, bus->sdcb_BusIRQ));
973 DINIT(bug("[SDBus%02u] %s: Masking chipset Interrupts...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
975 bus->sdcb_IOWriteLong(SDHCI_INT_ENABLE, bus->sdcb_IntrMask, bus);
976 bus->sdcb_IOWriteLong(SDHCI_SIGNAL_ENABLE, bus->sdcb_IntrMask, bus);
979 for (;;)
981 tasksig = Wait(sig);
983 if ((tasksig & (1L << bus->sdcb_MediaSig)) && (bus->sdcb_BusFlags & AF_Bus_MediaChanged))
985 D(bug("[SDBus%02u] %s: detected unit change\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
986 D(bug("[SDBus%02u] %s: Card %s Detected!\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, (bus->sdcb_BusFlags & AF_Bus_MediaPresent) ? "Insert" : "Eject" ));
987 if (bus->sdcb_BusFlags & AF_Bus_MediaPresent)
989 FNAME_SDCBUS(RegisterUnit)(bus);
991 else
993 FNAME_SDCBUS(ReleaseUnit)(bus);
997 /* Defer IORequest processing if the bus is active */
998 if ((tasksig & (1L << bus->sdcb_MsgPort->mp_SigBit)) && (!(bus->sdcb_BusFlags & AF_Bus_Active)))
1000 /* process pending requests .. */
1001 bus->sdcb_BusFlags |= AF_Bus_Active;
1002 while ((msg = (struct IORequest *)GetMsg(bus->sdcb_MsgPort)))
1004 /* And do IO's */
1005 if (FNAME_SDC(HandleIO)(msg))
1007 ReplyMsg((struct Message *)msg);
1010 bus->sdcb_BusFlags &= ~AF_Bus_Active;