DOn't busy wait for SDHC command complete by reading the status register. Such behavi...
[AROS.git] / rom / devs / sdcard / sdcard_bus.c
blob26def8850e87e6102c5304a82859f875b109ba80
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 <hardware/mmc.h>
31 #include <hardware/sdhc.h>
33 #include <string.h>
35 #include "sdcard_base.h"
36 #include "sdcard_bus.h"
37 #include "sdcard_unit.h"
38 #include "timer.h"
40 #include LC_LIBDEFS_FILE
42 /* Generic "Bus Unit" Functions */
44 BOOL FNAME_SDCBUS(StartUnit)(struct sdcard_Unit *sdcUnit)
46 struct TagItem sdcStartTags[] =
48 {SDCARD_TAG_CMD, MMC_CMD_SELECT_CARD},
49 {SDCARD_TAG_ARG, sdcUnit->sdcu_CardRCA << 16},
50 {SDCARD_TAG_RSPTYPE, MMC_RSP_R1},
51 {SDCARD_TAG_RSP, 0},
52 {TAG_DONE, 0}
55 DFUNCS(bug("[SDCard%02ld] %s()\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
57 if (sdcUnit->sdcu_Flags & AF_Card_MMC)
59 FNAME_SDCUNIT(MMCChangeFrequency)(sdcUnit);
61 else
63 FNAME_SDCUNIT(SDSCChangeFrequency)(sdcUnit);
66 sdcard_Udelay(1000);
68 if ((FNAME_SDCBUS(SendCmd)(sdcStartTags, sdcUnit->sdcu_Bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, sdcUnit->sdcu_Bus) != -1))
70 if (FNAME_SDCUNIT(WaitStatus)(10000, sdcUnit) == -1)
72 D(bug("[SDCard%02ld] %s: Failed to Wait for Cards status\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
75 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));
76 D(bug("[SDCard%02ld] %s: Card is now operating in Transfer Mode\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
78 if (!(sdcUnit->sdcu_Flags & AF_Card_HighCapacity))
80 sdcStartTags[0].ti_Data = MMC_CMD_SET_BLOCKLEN;
81 sdcStartTags[1].ti_Data = 1 << sdcUnit->sdcu_Bus->sdcb_SectorShift;
82 sdcStartTags[2].ti_Data = MMC_RSP_R1;
83 sdcStartTags[3].ti_Data = 0;
84 if ((FNAME_SDCBUS(SendCmd)(sdcStartTags, sdcUnit->sdcu_Bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, sdcUnit->sdcu_Bus) != -1))
86 D(bug("[SDCard%02ld] %s: Blocklen set to %d\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__, sdcStartTags[1].ti_Data));
88 else
90 D(bug("[SDCard%02ld] %s: Failed to change Blocklen\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
94 if (sdcUnit->sdcu_Flags & AF_Card_MMC)
96 if (sdcUnit->sdcu_Flags & AF_Card_HighSpeed)
98 if (sdcUnit->sdcu_Flags & AB_Card_HighSpeed52)
99 FNAME_SDCBUS(SetClock)(52000000, sdcUnit->sdcu_Bus);
100 else
101 FNAME_SDCBUS(SetClock)(26000000, sdcUnit->sdcu_Bus);
103 else
104 FNAME_SDCBUS(SetClock)(20000000, sdcUnit->sdcu_Bus);
106 else
108 if (sdcUnit->sdcu_Flags & AF_Card_HighSpeed)
109 FNAME_SDCBUS(SetClock)(50000000, sdcUnit->sdcu_Bus);
110 else
111 FNAME_SDCBUS(SetClock)(25000000, sdcUnit->sdcu_Bus);
115 D(bug("[SDCard%02ld] %s: Done.\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
117 return TRUE;
120 ULONG FNAME_SDCUNIT(WaitStatus)(ULONG timeout, struct sdcard_Unit *sdcUnit)
122 struct TagItem sdcStatusTags[] =
124 {SDCARD_TAG_CMD, MMC_CMD_SEND_STATUS},
125 {SDCARD_TAG_ARG, sdcUnit->sdcu_CardRCA << 16},
126 {SDCARD_TAG_RSPTYPE, MMC_RSP_R1},
127 {SDCARD_TAG_RSP, 0},
128 {TAG_DONE, 0}
131 UBYTE retryreq = 5;
133 DFUNCS(bug("[SDCard%02ld] %s()\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__));
135 do {
136 if (FNAME_SDCBUS(SendCmd)(sdcStatusTags, sdcUnit->sdcu_Bus) != -1)
138 if ((sdcStatusTags[3].ti_Data & MMC_STATUS_RDY_FOR_DATA) &&
139 (sdcStatusTags[3].ti_Data & MMC_STATUS_STATE_MASK) != MMC_STATUS_STATE_PRG)
140 break;
141 else if (sdcStatusTags[3].ti_Data & MMC_STATUS_MASK) {
142 bug("[SDCard%02ld] %s: Status [Error = %08x]\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__, sdcStatusTags[3].ti_Data);
143 return -1;
145 } else if (--retryreq < 0)
146 return -1;
148 sdcard_Udelay(1000);
149 } while (--timeout > 0);
151 if (timeout <= 0) {
152 bug("[SDCard%02ld] %s: Timeout\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__);
153 return -1;
156 D(bug("[SDCard%02ld] %s: State = %08x\n", sdcUnit->sdcu_UnitNum, __PRETTY_FUNCTION__, sdcStatusTags[3].ti_Data & MMC_STATUS_STATE_MASK));
158 return 0;
161 /* Bus Functions */
163 BOOL FNAME_SDCBUS(RegisterUnit)(struct sdcard_Bus *bus)
165 unsigned int sdcCardPower, timeout = 1000;
166 LIBBASETYPEPTR LIBBASE = bus->sdcb_DeviceBase;
167 ULONG sdcRsp136[4] = {0, 0, 0, 0};
168 struct sdcard_Unit *sdcUnit = NULL;
169 struct DeviceNode *devnode;
170 struct TagItem sdcRegTags[] =
172 {SDCARD_TAG_CMD, 0},
173 {SDCARD_TAG_ARG, 0},
174 {SDCARD_TAG_RSPTYPE, 0},
175 {SDCARD_TAG_RSP, 0},
176 {TAG_DONE, 0}
178 BOOL sdcHighCap = FALSE;
179 IPTR pp[24];
181 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
183 D(bug("[SDBus%02u] %s: Putting card into Idle state ...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
184 sdcRegTags[0].ti_Data = MMC_CMD_GO_IDLE_STATE;
185 sdcRegTags[1].ti_Data = 0;
186 sdcRegTags[2].ti_Data = MMC_RSP_NONE;
187 if (FNAME_SDCBUS(SendCmd)(sdcRegTags, bus) == -1)
189 D(bug("[SDBus%02u] %s: Error: Card failed to go idle!\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
190 return FALSE;
193 sdcard_Udelay(2000);
195 sdcRegTags[0].ti_Data = SD_CMD_SEND_IF_COND;
196 sdcRegTags[1].ti_Data = ((bus->sdcb_Power & 0xFF8000) != 0) << 8 | 0xAA;
197 sdcRegTags[2].ti_Data = MMC_RSP_R7;
198 D(bug("[SDBus%02u] %s: Querying Interface conditions [%08x] ...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcRegTags[1].ti_Data));
200 if ((FNAME_SDCBUS(SendCmd)(sdcRegTags, bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, bus) != -1))
202 D(bug("[SDBus%02u] %s: Query Response = %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcRegTags[3].ti_Data));
203 D(bug("[SDBus%02u] %s: SD2.0 Compliant Card .. publishing high-capacity support\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
204 sdcHighCap = TRUE;
206 else
208 D(bug("[SDBus%02u] %s: SD1.0 Compliant Card\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
211 do {
212 D(bug("[SDBus%02u] %s: Preparing for Card App Command ...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
213 sdcRegTags[0].ti_Data = MMC_CMD_APP_CMD;
214 sdcRegTags[1].ti_Data = 0;
215 sdcRegTags[2].ti_Data = MMC_RSP_R1;
217 if ((FNAME_SDCBUS(SendCmd)(sdcRegTags, bus) == -1) || (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, bus) == -1))
219 D(bug("[SDBus%02u] %s: App Command Failed\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
220 return FALSE;
222 D(bug("[SDBus%02u] %s: App Command Response = %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcRegTags[3].ti_Data));
224 sdcRegTags[0].ti_Data = SD_CMD_APP_SEND_OP_COND;
225 sdcRegTags[1].ti_Data = (bus->sdcb_Power & 0xFF8000) | (sdcHighCap ? OCR_HCS : 0);
226 #warning "TODO: Publish support for OCR_S18R/OCR_XPC on capable Hosts"
227 sdcRegTags[2].ti_Data = MMC_RSP_R3;
229 D(bug("[SDBus%02u] %s: Querying Operating conditions [%08x] ...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcRegTags[1].ti_Data));
230 if ((FNAME_SDCBUS(SendCmd)(sdcRegTags, bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, bus) != -1))
232 D(bug("[SDBus%02u] %s: Query Response = %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcRegTags[3].ti_Data));
233 sdcard_Udelay(1000);
235 else
237 D(bug("[SDBus%02u] %s: Operating condition Query Failed\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
238 return FALSE;
240 } while ((!(sdcRegTags[3].ti_Data & OCR_BUSY)) && (--timeout > 0));
242 sdcHighCap = FALSE;
244 if (timeout > 0)
246 D(bug("[SDBus%02u] %s: Card OCR = %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, (sdcRegTags[3].ti_Data & 0xFFFF00)));
248 sdcCardPower = bus->sdcb_Power & (sdcRegTags[3].ti_Data & 0xFFFF00);
250 D(bug("[SDBus%02u] %s: Card is now operating in Identification Mode\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
252 if (sdcRegTags[3].ti_Data & OCR_HCS)
254 D(bug("[SDBus%02u] %s: High Capacity Card detected\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
255 sdcHighCap = TRUE;
258 if (sdcRegTags[3].ti_Data & OCR_S18R)
260 D(bug("[SDBus%02u] %s: Begin Voltage Switching..\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
263 FNAME_SDCBUS(SetPowerLevel)(sdcCardPower, TRUE, bus);
264 sdcard_Udelay(2000);
266 /* Put the "card" into identify mode*/
267 D(bug("[SDBus%02u] %s: Querying Card Identification Data ...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
268 sdcRegTags[0].ti_Data = MMC_CMD_ALL_SEND_CID;
269 sdcRegTags[1].ti_Data = 0;
270 sdcRegTags[2].ti_Data = MMC_RSP_R2;
271 sdcRegTags[3].ti_Data = (IPTR)sdcRsp136;
272 if ((FNAME_SDCBUS(SendCmd)(sdcRegTags, bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, bus) != -1))
274 if (sdcRegTags[3].ti_Data)
276 D(bug("[SDBus%02u] %s: # Card Identification Data (CID) Register\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
277 D(bug("[SDBus%02u] %s: # ======================================\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
278 D(bug("[SDBus%02u] %s: # Manuafacturer ID (MID) : %06x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 120, 8)));
279 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)));
280 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)));
281 D(bug("[SDBus%02u] %s: # Serial number (PSN) : %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 24, 32)));
282 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)));
283 D(bug("[SDBus%02u] %s: # CRC7 checksum (CRC7) : %x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 1, 7)));
284 D(bug("[SDBus%02u] %s: # Reserved : %x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 0, 1)));
287 D(bug("[SDBus%02u] %s: Querying Card Relative Address... \n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
288 sdcRegTags[0].ti_Data = SD_CMD_SEND_RELATIVE_ADDR;
289 sdcRegTags[1].ti_Data = 0;
290 sdcRegTags[2].ti_Data = MMC_RSP_R6;
291 sdcRegTags[3].ti_Data = 0;
292 if ((FNAME_SDCBUS(SendCmd)(sdcRegTags, bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, bus) != -1))
294 if ((sdcUnit = AllocVecPooled(LIBBASE->sdcard_MemPool, sizeof(struct sdcard_Unit))) != NULL)
296 sdcUnit->sdcu_Bus = bus;
297 if ((sdcUnit->sdcu_UnitNum = bus->sdcb_BusUnits->sdcbu_UnitCnt++) > bus->sdcb_BusUnits->sdcbu_UnitMax)
299 return FALSE;
301 (&bus->sdcb_BusUnits->sdcbu_Units)[sdcUnit->sdcu_UnitNum] = sdcUnit;
302 sdcUnit->sdcu_UnitNum += bus->sdcb_BusUnits->sdcbu_UnitBase;
303 sdcUnit->sdcu_CardRCA = (sdcRegTags[3].ti_Data >> 16) & 0xFFFF;
304 sdcUnit->sdcu_CardPower = sdcCardPower;
306 D(bug("[SDBus%02u] %s: Card RCA = %d\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcUnit->sdcu_CardRCA));
308 sdcRegTags[0].ti_Data = MMC_CMD_SEND_CSD;
309 sdcRegTags[1].ti_Data = sdcUnit->sdcu_CardRCA << 16;
310 sdcRegTags[2].ti_Data = MMC_RSP_R2;
311 sdcRegTags[3].ti_Data = (IPTR)sdcRsp136;
312 D(bug("[SDBus%02u] %s: Querying Card Specific Data [%08x] ...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcRegTags[1].ti_Data));
313 if ((FNAME_SDCBUS(SendCmd)(sdcRegTags, bus) != -1) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT, 1000, bus) != -1))
315 if (FNAME_SDCUNIT(WaitStatus)(10000, sdcUnit) == -1)
317 D(bug("[SDBus%02lu] %s: Failed to Wait for Cards status\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
320 if (sdcRegTags[3].ti_Data)
322 int __csdstruct = FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 126, 2);
323 D(bug("[SDBus%02u] %s: # Card Specific Data (CSD) Register\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
324 D(bug("[SDBus%02u] %s: # =================================\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
325 D(bug("[SDBus%02u] %s: # CSD_STRUCTURE : %x ", bus->sdcb_BusNum, __PRETTY_FUNCTION__, __csdstruct));
327 sdcUnit->sdcu_Read32 = FNAME_SDCIO(ReadSector32);
328 sdcUnit->sdcu_Write32 = FNAME_SDCIO(WriteSector32);
329 sdcUnit->sdcu_Bus->sdcb_BusFlags = AF_Bus_MediaPresent;
330 #if defined(SDHCI_READONLY)
331 sdcUnit->sdcu_Flags = AF_Card_WriteProtect;
332 #endif
333 if (sdcHighCap)
335 sdcUnit->sdcu_Flags |= AF_Card_HighCapacity;
336 sdcUnit->sdcu_Read64 = FNAME_SDCIO(ReadSector64);
337 sdcUnit->sdcu_Write64 = FNAME_SDCIO(WriteSector64);
340 switch (__csdstruct)
342 case 0:
344 D(bug("[SDSC Card]\n"));
345 pp[DE_SIZEBLOCK + 4] = 1 << FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 80, 4);
346 pp[DE_SECSPERBLOCK + 4] = pp[DE_SIZEBLOCK + 4] >> 9;
347 pp[DE_HIGHCYL + 4] = ((1 + FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 62, 12)) << (FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 47, 3) + 2));
348 break;
350 case 1:
352 D(bug("[SDHC/XC Card]\n"));
354 pp[DE_SECSPERBLOCK + 4] = 2;
355 pp[DE_SIZEBLOCK + 4] = 2 << (10 - 1);
356 pp[DE_HIGHCYL + 4] = ((1 + FNAME_SDCBUS(Rsp136Unpack)(sdcRsp136, 48, 22)) * (2 << (9 - 1)));
358 sdcUnit->sdcu_Flags |= AF_Card_MMC;
360 break;
362 default:
363 D(bug("[SDBus%02u] %s: Unsupported Card\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
364 return FALSE;
367 sdcUnit->sdcu_Cylinders = pp[DE_HIGHCYL + 4];
368 sdcUnit->sdcu_Heads = 1;
369 sdcUnit->sdcu_Sectors = pp[DE_SECSPERBLOCK + 4];
370 sdcUnit->sdcu_Capacity = sdcUnit->sdcu_Cylinders * sdcUnit->sdcu_Heads * sdcUnit->sdcu_Sectors;
372 sdcUnit->sdcu_Eject = FNAME_SDCIO(Eject);
374 D(bug("[SDBus%02u] %s: # READ_BL_LEN : %dbytes\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, pp[DE_SIZEBLOCK + 4] / sdcUnit->sdcu_Sectors));
375 D(bug("[SDBus%02u] %s: # C_SIZE : %d\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdcUnit->sdcu_Cylinders));
377 pp[0] = (IPTR)"MMC0";
378 pp[1] = (IPTR)MOD_NAME_STRING;
379 pp[2] = 0;
380 pp[DE_TABLESIZE + 4] = DE_BOOTBLOCKS;
381 pp[DE_NUMHEADS + 4] = sdcUnit->sdcu_Heads;
382 pp[DE_BLKSPERTRACK + 4] = 1;
383 pp[DE_RESERVEDBLKS + 4] = 2;
384 pp[DE_LOWCYL + 4] = 0;
385 pp[DE_NUMBUFFERS + 4] = 10;
386 pp[DE_BUFMEMTYPE + 4] = MEMF_PUBLIC | MEMF_31BIT;
387 pp[DE_MAXTRANSFER + 4] = 0x00200000;
388 pp[DE_MASK + 4] = 0x7FFFFFFE;
389 pp[DE_BOOTPRI + 4] = 0;
390 pp[DE_DOSTYPE + 4] = AROS_MAKE_ID('D','O','S','\001');
391 pp[DE_CONTROL + 4] = 0;
392 pp[DE_BOOTBLOCKS + 4] = 2;
394 devnode = MakeDosNode(pp);
396 if (devnode)
398 bug("[SDBus%02u] %b: [%ldMB Capacity]\n", bus->sdcb_BusNum, devnode->dn_Name, (ULONG)((sdcUnit->sdcu_Capacity >> 11) & 0xFFFFFFFFul));
399 D(bug("[SDBus%02u] %s: StartCyl:%d, EndCyl:%d ..\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__,
400 pp[DE_LOWCYL + 4], pp[DE_HIGHCYL + 4]));
401 D(bug("[SDBus%02u] %s: BlockSize:%d, SectorsPerBlock:%d ..\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__,
402 pp[DE_SIZEBLOCK + 4], sdcUnit->sdcu_Sectors));
404 AddBootNode(pp[DE_BOOTPRI + 4], ADNF_STARTPROC, devnode, NULL);
405 D(bug("[SDBus%02u] %s: Unit detection complete\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
407 return TRUE;
411 else
413 D(bug("[SDBus%02u] %s: Card failed to send CSD\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
416 else
418 D(bug("[SDBus%02u] %s: Failed to allocate Unit\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
421 else
423 D(bug("[SDBus%02u] %s: Card failed to send RCA\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
426 else
428 D(bug("[SDBus%02u] %s: Card failed to send CID\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
431 else
433 D(bug("[SDBus%02u] %s: Card failed to initialise\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
436 return FALSE;
439 void FNAME_SDCBUS(ReleaseUnit)(struct sdcard_Bus *bus)
441 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
444 void FNAME_SDCBUS(SoftReset)(UBYTE mask, struct sdcard_Bus *bus)
446 ULONG timeout = 100;
448 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
450 bus->sdcb_IOWriteByte(SDHCI_RESET, mask, bus);
451 while (bus->sdcb_IOReadByte(SDHCI_RESET, bus) & mask) {
452 if (timeout == 0) {
453 bug("[SDBus%02u] %s: Timeout\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
454 break;
456 sdcard_Udelay(1000);
457 timeout--;
461 void FNAME_SDCBUS(SetClock)(ULONG speed, struct sdcard_Bus *bus)
463 ULONG sdcClkDiv, timeout;
464 UWORD sdcClkCtrlCur, sdcClkCtrl;
466 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
468 sdcClkCtrlCur = bus->sdcb_IOReadWord(SDHCI_CLOCK_CONTROL, bus);
470 sdcClkDiv = FNAME_SDCBUS(GetClockDiv)(speed, bus);
472 sdcClkCtrl = (sdcClkDiv & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
473 sdcClkCtrl |= ((sdcClkDiv & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) << SDHCI_DIVIDER_HI_SHIFT;
475 if (sdcClkCtrl != (sdcClkCtrlCur & ~(SDHCI_CLOCK_INT_EN|SDHCI_CLOCK_INT_STABLE|SDHCI_CLOCK_CARD_EN)))
477 bus->sdcb_IOWriteWord(SDHCI_CLOCK_CONTROL, 0, bus);
479 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));
481 bus->sdcb_IOWriteWord(SDHCI_CLOCK_CONTROL, (sdcClkCtrl | SDHCI_CLOCK_INT_EN), bus);
483 timeout = 20;
484 while (!((sdcClkCtrl = bus->sdcb_IOReadWord(SDHCI_CLOCK_CONTROL, bus)) & SDHCI_CLOCK_INT_STABLE)) {
485 if (timeout == 0) {
486 bug("[SDBus%02u] %s: SDHCI Clock failed to stabilise\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
487 break;
489 sdcard_Udelay(1000);
490 timeout --;
493 else
494 if (sdcClkCtrlCur & SDHCI_CLOCK_CARD_EN)
495 return;
497 D(bug("[SDBus%02u] %s: Enabling clock...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
498 sdcClkCtrl |= SDHCI_CLOCK_CARD_EN;
499 bus->sdcb_IOWriteWord(SDHCI_CLOCK_CONTROL, sdcClkCtrl, bus);
502 void FNAME_SDCBUS(SetPowerLevel)(ULONG supportedlvls, BOOL lowest, struct sdcard_Bus *bus)
504 UBYTE sdcReg = 0, lvlCur;
506 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
508 if (lowest)
510 if (supportedlvls & MMC_VDD_165_195)
511 sdcReg = SDHCI_POWER_180;
512 else if (supportedlvls & (MMC_VDD_290_300|MMC_VDD_300_310))
513 sdcReg = SDHCI_POWER_300;
514 else if (supportedlvls & (MMC_VDD_320_330|MMC_VDD_330_340))
515 sdcReg = SDHCI_POWER_330;
517 else
519 if (supportedlvls & (MMC_VDD_320_330|MMC_VDD_330_340))
520 sdcReg = SDHCI_POWER_330;
521 else if (supportedlvls & (MMC_VDD_290_300|MMC_VDD_300_310))
522 sdcReg = SDHCI_POWER_300;
523 else if (supportedlvls & MMC_VDD_165_195)
524 sdcReg = SDHCI_POWER_180;
527 lvlCur = bus->sdcb_IOReadByte(SDHCI_POWER_CONTROL, bus);
528 if ((lvlCur & ~SDHCI_POWER_ON) != sdcReg)
530 D(bug("[SDBus%02u] %s: Changing Power Lvl [0x%x -> 0x%x]\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, lvlCur & ~SDHCI_POWER_ON, sdcReg));
531 bus->sdcb_IOWriteByte(SDHCI_POWER_CONTROL, sdcReg, bus);
532 sdcReg |= SDHCI_POWER_ON;
533 bus->sdcb_IOWriteByte(SDHCI_POWER_CONTROL, sdcReg, bus);
535 else
537 if (!(lvlCur & SDHCI_POWER_ON))
539 D(bug("[SDBus%02u] %s: Enabling Power Lvl [0x%x]\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, lvlCur));
540 lvlCur |= SDHCI_POWER_ON;
541 bus->sdcb_IOWriteByte(SDHCI_POWER_CONTROL, lvlCur, bus);
546 ULONG FNAME_SDCBUS(SendCmd)(struct TagItem *CmdTags, struct sdcard_Bus *bus)
548 UWORD sdCommand = (UWORD)GetTagData(SDCARD_TAG_CMD, 0, CmdTags);
549 ULONG sdArg = GetTagData(SDCARD_TAG_ARG, 0, CmdTags);
550 ULONG sdResponseType = GetTagData(SDCARD_TAG_RSPTYPE, MMC_RSP_NONE, CmdTags);
551 ULONG sdDataLen = 0, sdDataFlags;
553 UWORD sdcTransMode = 0, sdCommandFlags;
554 ULONG sdcInhibitMask = SDHCI_PS_CMD_INHIBIT;
555 ULONG timeout = 10;
556 ULONG retVal = 0;
558 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
560 SetSignal(0, 1L << bus->sdcb_CommandSig);
562 if ((sdDataLen = GetTagData(SDCARD_TAG_DATALEN, 0, CmdTags)) > 0)
564 sdDataFlags = GetTagData(SDCARD_TAG_DATAFLAGS, 0, CmdTags);
567 /* Dont wait for DATA inihibit for stop commands */
568 if (sdCommand != MMC_CMD_STOP_TRANSMISSION)
569 sdcInhibitMask |= SDHCI_PS_DATA_INHIBIT;
571 while (bus->sdcb_IOReadLong(SDHCI_PRESENT_STATE, bus) & sdcInhibitMask) {
572 if (timeout == 0) {
573 bug("[SDBus%02u] %s: Controller failed to release inhibited bit(s).\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
574 bug("[SDBus%02u] %s: failed bit(s) = %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_IOReadLong(SDHCI_PRESENT_STATE, bus) & sdcInhibitMask);
576 bug("[SDBus%02u] %s: Reseting SDHCI CMD/DATA\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
578 FNAME_SDCBUS(SoftReset)(SDHCI_RESET_CMD, bus);
579 FNAME_SDCBUS(SoftReset)(SDHCI_RESET_DATA, bus);
581 return -1;
583 sdcard_Udelay(1000);
584 timeout--;
587 if (!(sdResponseType & MMC_RSP_PRESENT))
588 sdCommandFlags = SDHCI_CMD_RESP_NONE;
589 else if (sdResponseType & MMC_RSP_136)
590 sdCommandFlags = SDHCI_CMD_RESP_LONG;
591 else if (sdResponseType & MMC_RSP_BUSY)
592 sdCommandFlags = SDHCI_CMD_RESP_SHORT_BUSY;
593 else
594 sdCommandFlags = SDHCI_CMD_RESP_SHORT;
596 if (sdResponseType & MMC_RSP_CRC)
597 sdCommandFlags |= SDHCI_CMD_CRC;
598 if (sdResponseType & MMC_RSP_OPCODE)
599 sdCommandFlags |= SDHCI_CMD_INDEX;
600 if (sdDataLen > 0)
601 sdCommandFlags |= SDHCI_CMD_DATA;
603 if (sdDataLen > 0) {
604 sdcTransMode = SDHCI_TRANSMOD_BLK_CNT_EN;
605 DTRANS(bug("[SDBus%02u] %s: Configuring Data Transfer\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
607 if (bus->sdcb_LEDCtrl)
608 bus->sdcb_LEDCtrl(LED_ON);
610 bus->sdcb_IOWriteByte(SDHCI_TIMEOUT_CONTROL, SDHCI_TIMEOUT_MAX, bus);
612 bus->sdcb_IOWriteWord(SDHCI_BLOCK_SIZE, ((1 << 16) | ((sdDataLen > (1 << bus->sdcb_SectorShift)) ? (1 << bus->sdcb_SectorShift) : sdDataLen)), bus);
613 if ((sdDataLen >> bus->sdcb_SectorShift) > 1)
615 sdcTransMode |= SDHCI_TRANSMOD_MULTI;
616 bus->sdcb_IOWriteWord(SDHCI_BLOCK_COUNT, sdDataLen >> bus->sdcb_SectorShift, bus);
618 else
620 bus->sdcb_IOWriteWord(SDHCI_BLOCK_COUNT, 1, bus);
623 if (sdDataFlags == MMC_DATA_READ)
624 sdcTransMode |= SDHCI_TRANSMOD_READ;
626 if (!(bus->sdcb_Quirks & AF_Quirk_AtomicTMAndCMD))
628 bus->sdcb_IOWriteWord(SDHCI_TRANSFER_MODE, sdcTransMode, bus);
631 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)));
634 bus->sdcb_RespListener = CmdTags;
635 if (sdDataLen > 0)
636 bus->sdcb_DataListener = CmdTags;
638 bus->sdcb_IOWriteLong(SDHCI_ARGUMENT, sdArg, bus);
639 if ((bus->sdcb_Quirks & AF_Quirk_AtomicTMAndCMD) && (sdcTransMode))
641 bus->sdcb_IOWriteLong(SDHCI_TRANSFER_MODE, (SDHCI_MAKE_CMD(sdCommand, sdCommandFlags) << 16) | sdcTransMode, bus);
643 else
645 bus->sdcb_IOWriteWord(SDHCI_COMMAND, SDHCI_MAKE_CMD(sdCommand, sdCommandFlags), bus);
648 D(bug("[SDBus%02u] %s: CMD %02d Sent\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdCommand));
650 return retVal;
653 ULONG FNAME_SDCBUS(FinishCmd)(struct TagItem *CmdTags, struct sdcard_Bus *bus)
655 struct TagItem *Response = NULL;
657 D(UWORD sdCommand = (UWORD)GetTagData(SDCARD_TAG_CMD, 0, CmdTags));
658 ULONG sdResponseType = GetTagData(SDCARD_TAG_RSPTYPE, MMC_RSP_NONE, CmdTags);
659 ULONG retVal = 0;
661 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
663 if (sdResponseType != MMC_RSP_NONE)
665 if ((Response = FindTagItem(SDCARD_TAG_RSP, CmdTags)) != NULL)
667 D(bug("[SDBus%02u] %s: Reading CMD %02d Response ", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdCommand));
668 if (sdResponseType & MMC_RSP_136)
670 D(bug("[136bit]\n"));
671 if (Response->ti_Data)
673 ULONG i;
674 for (i = 0; i < 4; i ++)
676 ((ULONG *)Response->ti_Data)[i] = bus->sdcb_IOReadLong(SDHCI_RESPONSE + (3 - i) * 4, bus) << 8;
677 if (i != 3)
678 ((ULONG *)Response->ti_Data)[i] |= bus->sdcb_IOReadByte(SDHCI_RESPONSE + (3 - i) * 4 - 1, bus);
680 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]));
683 else
685 Response->ti_Data = bus->sdcb_IOReadLong(SDHCI_RESPONSE, bus);
686 D(bug("[= %08x]\n", Response->ti_Data));
691 return retVal;
694 ULONG FNAME_SDCBUS(FinishData)(struct TagItem *DataTags, struct sdcard_Bus *bus)
696 DTRANS(UWORD sdCommand = (UWORD)GetTagData(SDCARD_TAG_CMD, 0, DataTags));
697 ULONG sdcStateMask, sdCommandMask,
698 sdData, sdDataMode, sdDataLen, sdcReg = 0;
699 struct TagItem *sdDataLenTag = NULL;
700 ULONG timeout = 1000;
701 ULONG retVal = 0;
703 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
705 if ((sdData = GetTagData(SDCARD_TAG_DATA, 0, DataTags)) != 0)
707 if ((sdDataLenTag = FindTagItem(SDCARD_TAG_DATALEN, DataTags)) == NULL)
708 sdData = 0;
709 else
711 sdDataLen = sdDataLenTag->ti_Data;
712 if ((sdDataMode = GetTagData(SDCARD_TAG_DATAFLAGS, MMC_DATA_READ, DataTags)) == MMC_DATA_READ)
714 sdcStateMask = SDHCI_PS_DATA_AVAILABLE;
715 sdCommandMask = SDHCI_INT_DATA_AVAIL;
717 else
719 sdcStateMask = SDHCI_PS_SPACE_AVAILABLE;
720 sdCommandMask = SDHCI_INT_SPACE_AVAIL;
725 if (sdData)
727 DTRANS(bug("[SDBus%02u] %s: Transfering CMD %02d Data..\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdCommand));
728 do {
729 bus->sdcb_BusStatus = bus->sdcb_IOReadLong(SDHCI_INT_STATUS, bus);
730 if (bus->sdcb_BusStatus & SDHCI_INT_ERROR) {
731 bug("[SDBus%02u] %s: Error [status 0x%X]!\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_BusStatus);
732 retVal = -1;
733 break;
736 if ((bus->sdcb_BusStatus & sdCommandMask) && (bus->sdcb_IOReadLong(SDHCI_PRESENT_STATE, bus) & sdcStateMask)) {
737 ULONG currbyte, tranlen = (sdDataLen > (1 << bus->sdcb_SectorShift)) ? (1 << bus->sdcb_SectorShift) : sdDataLen;
739 DTRANS(bug("[SDBus%02u] %s: Attempting to %s %dbytes\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, ((sdDataMode == MMC_DATA_READ) ? "read" : "write"), tranlen));
740 for (currbyte = 0; currbyte < tranlen; currbyte++)
742 DTRANS(DUMP(
743 if ((currbyte % 16) == 0)
745 bug("[SDBus%02u] %s: ", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
748 if (sdDataMode == MMC_DATA_READ)
750 if ((currbyte % 4) == 0)
752 sdcReg = bus->sdcb_IOReadLong(SDHCI_BUFFER, bus);
754 *(UBYTE *)sdData = sdcReg & 0xFF;
756 else
757 sdcReg |= *(UBYTE *)sdData << (currbyte % 4);
759 sdData++;
760 sdDataLen--;
761 if (sdDataMode != MMC_DATA_READ)
763 if (((currbyte % 4) == 3) || (sdDataLen == 0))
765 bus->sdcb_IOWriteLong(SDHCI_BUFFER, *(ULONG *)(sdData - 3), bus);
768 else
769 sdcReg >>= 8;
770 DTRANS(DUMP(
771 if ((currbyte % 4) == 3)
773 bug(" %08x", *(ULONG *)(sdData - 3));
775 if ((currbyte % 16) == 15)
777 bug("\n");
781 DTRANS(DUMP(
782 if ((currbyte % 16) != 0)
784 bug("\n");
788 else if (!(bus->sdcb_BusStatus & SDHCI_INT_DATA_END))
790 sdcard_Udelay(1000);
792 if (timeout-- <= 0)
794 bug("[SDBus%02u] %s: Timeout!\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
795 retVal = -1;
796 break;
799 } while ((sdDataLen > 0) && (!(bus->sdcb_BusStatus & SDHCI_INT_DATA_END)));
801 if (bus->sdcb_LEDCtrl)
802 bus->sdcb_LEDCtrl(LED_OFF);
804 sdDataLenTag->ti_Data -= sdDataLen;
807 return retVal;
810 ULONG FNAME_SDCBUS(WaitCmd)(ULONG mask, ULONG timeout, struct sdcard_Bus *bus)
812 D(bug("[SDBus%02u] %s(), task %p %s\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, FindTask(NULL), FindTask(NULL)->tc_Node.ln_Name));
813 D(bug("Task=%p\n", bus->sdcb_Task));
814 if (bus->sdcb_Task == FindTask(NULL))
816 D(bug("Waiting for signal %d\n", bus->sdcb_CommandSig));
817 Wait(1L << bus->sdcb_CommandSig);
819 else
821 D(bug("\nNot a Bus task!\n\n"));
822 sdcard_Udelay(10000);
825 while (bus->sdcb_IOReadLong(SDHCI_PRESENT_STATE, bus) & mask) {
826 sdcard_Udelay(1000);
828 if ((bus->sdcb_BusStatus & SDHCI_INT_ERROR) == SDHCI_INT_ERROR)
829 break;
831 if (--timeout <= 0)
832 break;
835 if ((timeout <= 0) || (bus->sdcb_BusStatus & SDHCI_INT_ERROR))
837 return -1;
840 return 0;
844 ULONG FNAME_SDCBUS(Rsp136Unpack)(ULONG *buf, ULONG offset, const ULONG len)
846 const ULONG mask = ((len < 32) ? (1 << len) : 0) - 1;
847 const ULONG shift = (offset) & 0x1F;
848 ULONG retval;
850 retval = buf[3 - (offset >> 5)] >> shift;
851 if (len + shift > 32)
852 retval |= buf[3 - (offset >> 5) - 1] << ((32 - shift) % 32);
854 return (retval & mask);
857 /********** BUS IRQ HANDLER **************/
859 void FNAME_SDCBUS(BusIRQ)(struct sdcard_Bus *bus, void *_unused)
861 BOOL error = FALSE;
863 DIRQ(bug("[SDBus%02u] %s(bus @ 0x%p)\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus));
865 if (!(bus))
867 DIRQ(bug("[SDBus%02u] %s: Bad Params!\n", __PRETTY_FUNCTION__));
868 return;
871 bus->sdcb_BusStatus = bus->sdcb_IOReadLong(SDHCI_INT_STATUS, bus);
873 if (!(bus->sdcb_BusStatus & SDHCI_INT_ERROR))
875 DIRQ(bug("[SDBus%02u] %s: Status = %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_BusStatus));
877 if (bus->sdcb_BusStatus & (SDHCI_INT_CARD_INSERT|SDHCI_INT_CARD_REMOVE))
879 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, (bus->sdcb_BusStatus & (SDHCI_INT_CARD_INSERT|SDHCI_INT_CARD_REMOVE)), bus);
881 bus->sdcb_BusFlags &= ~AF_Bus_MediaPresent;
882 bus->sdcb_BusFlags |= AF_Bus_MediaChanged;
884 if (bus->sdcb_BusStatus & SDHCI_INT_CARD_INSERT)
885 bus->sdcb_BusFlags |= AF_Bus_MediaPresent;
887 bus->sdcb_BusStatus &= ~(SDHCI_INT_CARD_INSERT|SDHCI_INT_CARD_REMOVE);
889 if (bus->sdcb_Task)
890 Signal(bus->sdcb_Task, (1L << bus->sdcb_MediaSig));
892 if (bus->sdcb_BusStatus & SDHCI_INT_CMD_MASK)
894 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, (bus->sdcb_BusStatus & SDHCI_INT_CMD_MASK), bus);
896 if ((bus->sdcb_BusStatus & SDHCI_INT_RESPONSE) &&
897 (bus->sdcb_RespListener))
899 if (FNAME_SDCBUS(FinishCmd)(bus->sdcb_RespListener, bus) == -1)
900 error = TRUE;
901 bus->sdcb_RespListener = NULL;
903 if (bus->sdcb_Task && (bus->sdcb_BusStatus & SDHCI_INT_RESPONSE))
905 DIRQ(bug("Signalling task %p (%s) with signal %d\n", bus->sdcb_Task, bus->sdcb_Task->tc_Node.ln_Name, bus->sdcb_CommandSig));
906 Signal(bus->sdcb_Task, 1L << bus->sdcb_CommandSig);
909 bus->sdcb_BusStatus &= ~SDHCI_INT_CMD_MASK;
911 if (bus->sdcb_BusStatus & SDHCI_INT_DATA_MASK)
913 if ((bus->sdcb_BusStatus & (SDHCI_INT_DATA_AVAIL|SDHCI_INT_SPACE_AVAIL)) &&
914 (bus->sdcb_DataListener))
916 if (FNAME_SDCBUS(FinishData)(bus->sdcb_DataListener, bus) == -1)
917 error = TRUE;
918 bus->sdcb_DataListener = NULL;
919 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, (bus->sdcb_BusStatus & (SDHCI_INT_DATA_AVAIL|SDHCI_INT_SPACE_AVAIL)), bus);
920 bus->sdcb_BusStatus &= ~SDHCI_INT_DATA_MASK;
922 else
924 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, (bus->sdcb_BusStatus & SDHCI_INT_DATA_MASK), bus);
925 bus->sdcb_BusStatus &= ~SDHCI_INT_DATA_MASK;
929 else
931 bug("[SDBus%02u] %s: ERROR [Status = %08x]\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_BusStatus);
932 if (bus->sdcb_BusStatus & SDHCI_INT_ACMD12ERR)
934 bug("[SDBus%02u] %s: [acmd12err = %04x ]\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_IOReadWord(SDHCI_ACMD12_ERR, bus));
936 error = TRUE;
939 if (error)
941 if (bus->sdcb_BusStatus & bus->sdcb_IntrMask)
943 bug("[SDBus%02u] %s: Clearing Unhandled Interrupts [%08x]\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_BusStatus & bus->sdcb_IntrMask);
944 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, bus->sdcb_BusStatus & bus->sdcb_IntrMask, bus);
945 bus->sdcb_BusStatus &= ~bus->sdcb_IntrMask;
947 bug("[SDBus%02u] %s: Reseting SDHCI CMD/DATA\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
949 FNAME_SDCBUS(SoftReset)(SDHCI_RESET_CMD, bus);
950 FNAME_SDCBUS(SoftReset)(SDHCI_RESET_DATA, bus);
952 DIRQ(bug("[SDBus%02u] %s: Done.\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
955 /********** BUS MANAGEMENT TASK **************/
957 void FNAME_SDCBUS(BusTask)(struct sdcard_Bus *bus)
959 LIBBASETYPEPTR LIBBASE = bus->sdcb_DeviceBase;
960 struct IORequest *msg;
961 ULONG sig, tasksig;
963 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
965 bus->sdcb_Timer = sdcard_OpenTimer(LIBBASE);
967 /* Get the signal used for sleeping */
968 bus->sdcb_Task = FindTask(0);
970 D(bug("[SDBus%02u] %s: Task @ 0x%p\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_Task));
972 bus->sdcb_TaskSig = AllocSignal(-1);
973 if ((bus->sdcb_MediaSig = AllocSignal(-1)) == -1)
975 D(bug("[SDBus%02u] %s: failed to allocate Media Change sigbit\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
978 if ((bus->sdcb_CommandSig = AllocSignal(-1)) == -1)
980 D(bug("[SDBus%02u] %s: failed to allocate Command Completed sigbit\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
983 /* Failed to get it? Use SIGBREAKB_CTRL_E instead */
984 if (bus->sdcb_TaskSig < 0)
985 bus->sdcb_TaskSig = SIGBREAKB_CTRL_E;
987 sig = ((1L << bus->sdcb_MsgPort->mp_SigBit)|(1L << bus->sdcb_TaskSig)|(1L << bus->sdcb_MediaSig));
989 DINIT(bug("[SDBus%02u] %s: TaskSig: %d, MediaSig: %d\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_TaskSig, bus->sdcb_MediaSig));
991 /* Install IRQ handler */
992 if ((bus->sdcb_IRQHandle = KrnAddIRQHandler(bus->sdcb_BusIRQ, FNAME_SDCBUS(BusIRQ), bus, NULL)) != NULL)
994 DINIT(bug("[SDBus%02u] %s: IRQHandle @ 0x%p for IRQ#%ld\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_IRQHandle, bus->sdcb_BusIRQ));
996 DINIT(bug("[SDBus%02u] %s: Masking chipset Interrupts...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
998 bus->sdcb_IOWriteLong(SDHCI_INT_ENABLE, bus->sdcb_IntrMask, bus);
999 bus->sdcb_IOWriteLong(SDHCI_SIGNAL_ENABLE, bus->sdcb_IntrMask, bus);
1002 for (;;)
1004 tasksig = Wait(sig);
1006 if ((tasksig & (1L << bus->sdcb_MediaSig)) && (bus->sdcb_BusFlags & AF_Bus_MediaChanged))
1008 D(bug("[SDBus%02u] %s: detected unit change\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
1009 D(bug("[SDBus%02u] %s: Card %s Detected!\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, (bus->sdcb_BusFlags & AF_Bus_MediaPresent) ? "Insert" : "Eject" ));
1010 if (bus->sdcb_BusFlags & AF_Bus_MediaPresent)
1012 FNAME_SDCBUS(RegisterUnit)(bus);
1014 else
1016 FNAME_SDCBUS(ReleaseUnit)(bus);
1020 /* Defer IORequest processing if the bus is active */
1021 if ((tasksig & (1L << bus->sdcb_MsgPort->mp_SigBit)) && (!(bus->sdcb_BusFlags & AF_Bus_Active)))
1023 /* process pending requests .. */
1024 bus->sdcb_BusFlags |= AF_Bus_Active;
1025 while ((msg = (struct IORequest *)GetMsg(bus->sdcb_MsgPort)))
1027 /* And do IO's */
1028 if (FNAME_SDC(HandleIO)(msg))
1030 ReplyMsg((struct Message *)msg);
1033 bus->sdcb_BusFlags &= ~AF_Bus_Active;