revert between 56095 -> 55830 in arch
[AROS.git] / rom / devs / sdcard / sdcard_bus.c
blob4ecfd2eb50d90a86634e46b78464e45c4d068540
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|SDHCI_PS_DATA_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|SDHCI_PS_DATA_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) && (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT|SDHCI_PS_DATA_INHIBIT, 1000, 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) || (FNAME_SDCBUS(WaitCmd)(SDHCI_PS_CMD_INHIBIT|SDHCI_PS_DATA_INHIBIT, 1000, 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|SDHCI_PS_DATA_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|SDHCI_PS_DATA_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|SDHCI_PS_DATA_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|SDHCI_PS_DATA_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|SDHCI_PS_DATA_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|SDHCI_PS_DATA_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 #undef DFUNCS
547 #define DFUNCS(x) /*x*/
548 #undef DTRANS
549 #define DTRANS(x) /*x*/
550 #undef D
551 #define D(x) /*x*/
553 ULONG FNAME_SDCBUS(SendCmd)(struct TagItem *CmdTags, struct sdcard_Bus *bus)
555 UWORD sdCommand = (UWORD)GetTagData(SDCARD_TAG_CMD, 0, CmdTags);
556 ULONG sdArg = GetTagData(SDCARD_TAG_ARG, 0, CmdTags);
557 ULONG sdResponseType = GetTagData(SDCARD_TAG_RSPTYPE, MMC_RSP_NONE, CmdTags);
558 ULONG sdDataLen = 0, sdDataFlags;
560 UWORD sdcTransMode = 0, sdCommandFlags;
561 ULONG sdcInhibitMask = SDHCI_PS_CMD_INHIBIT;
562 ULONG timeout = 10;
563 ULONG retVal = 0;
565 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
567 if ((sdDataLen = GetTagData(SDCARD_TAG_DATALEN, 0, CmdTags)) > 0)
569 sdDataFlags = GetTagData(SDCARD_TAG_DATAFLAGS, 0, CmdTags);
572 bug("SendCmd(%d,%d)\n", sdCommand, sdDataLen);
574 /* Dont wait for DATA inihibit for stop commands */
575 if (sdCommand != MMC_CMD_STOP_TRANSMISSION)
576 sdcInhibitMask |= SDHCI_PS_DATA_INHIBIT;
578 while (bus->sdcb_IOReadLong(SDHCI_PRESENT_STATE, bus) & sdcInhibitMask) {
579 if (timeout == 0) {
580 bug("[SDBus%02u] %s: Controller failed to release inhibited bit(s).\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
581 bug("[SDBus%02u] %s: failed bit(s) = %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_IOReadLong(SDHCI_PRESENT_STATE, bus) & sdcInhibitMask);
583 bug("[SDBus%02u] %s: Reseting SDHCI CMD/DATA\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
585 FNAME_SDCBUS(SoftReset)(SDHCI_RESET_CMD, bus);
586 FNAME_SDCBUS(SoftReset)(SDHCI_RESET_DATA, bus);
588 return -1;
590 sdcard_Udelay(1000);
591 timeout--;
594 if (!(sdResponseType & MMC_RSP_PRESENT))
595 sdCommandFlags = SDHCI_CMD_RESP_NONE;
596 else if (sdResponseType & MMC_RSP_136)
597 sdCommandFlags = SDHCI_CMD_RESP_LONG;
598 else if (sdResponseType & MMC_RSP_BUSY)
599 sdCommandFlags = SDHCI_CMD_RESP_SHORT_BUSY;
600 else
601 sdCommandFlags = SDHCI_CMD_RESP_SHORT;
603 if (sdResponseType & MMC_RSP_CRC)
604 sdCommandFlags |= SDHCI_CMD_CRC;
605 if (sdResponseType & MMC_RSP_OPCODE)
606 sdCommandFlags |= SDHCI_CMD_INDEX;
607 if (sdDataLen > 0)
608 sdCommandFlags |= SDHCI_CMD_DATA;
610 if (sdDataLen > 0) {
611 sdcTransMode = SDHCI_TRANSMOD_BLK_CNT_EN;
612 DTRANS(bug("[SDBus%02u] %s: Configuring Data Transfer\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
614 if (bus->sdcb_LEDCtrl)
615 bus->sdcb_LEDCtrl(LED_ON);
617 bus->sdcb_IOWriteByte(SDHCI_TIMEOUT_CONTROL, SDHCI_TIMEOUT_MAX, bus);
619 bus->sdcb_IOWriteWord(SDHCI_BLOCK_SIZE, ((1 << 16) | ((sdDataLen > (1 << bus->sdcb_SectorShift)) ? (1 << bus->sdcb_SectorShift) : sdDataLen)), bus);
620 if ((sdDataLen >> bus->sdcb_SectorShift) > 1)
622 sdcTransMode |= SDHCI_TRANSMOD_MULTI;
623 bus->sdcb_IOWriteWord(SDHCI_BLOCK_COUNT, sdDataLen >> bus->sdcb_SectorShift, bus);
625 else
627 bus->sdcb_IOWriteWord(SDHCI_BLOCK_COUNT, 1, bus);
630 if (sdDataFlags == MMC_DATA_READ)
631 sdcTransMode |= SDHCI_TRANSMOD_READ;
633 if (!(bus->sdcb_Quirks & AF_Quirk_AtomicTMAndCMD))
635 bus->sdcb_IOWriteWord(SDHCI_TRANSFER_MODE, sdcTransMode, bus);
638 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)));
641 bus->sdcb_RespListener = CmdTags;
642 if (sdDataLen > 0)
643 bus->sdcb_DataListener = CmdTags;
645 SetSignal(0, 1L << bus->sdcb_CommandSig);
647 bus->sdcb_IOWriteLong(SDHCI_ARGUMENT, sdArg, bus);
648 if ((bus->sdcb_Quirks & AF_Quirk_AtomicTMAndCMD) && (sdcTransMode))
650 bus->sdcb_IOWriteLong(SDHCI_TRANSFER_MODE, (SDHCI_MAKE_CMD(sdCommand, sdCommandFlags) << 16) | sdcTransMode, bus);
652 else
654 bus->sdcb_IOWriteWord(SDHCI_COMMAND, SDHCI_MAKE_CMD(sdCommand, sdCommandFlags), bus);
657 //bug("Delay01Delay02\n");
659 D(bug("[SDBus%02u] %s: CMD %02d Sent\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdCommand));
661 return retVal;
664 #undef DFUNCS
665 #define DFUNCS(x) /* */
666 #undef DTRANS
667 #define DTRANS(x) /* */
668 #undef D
669 #define D(x) /* */
672 ULONG FNAME_SDCBUS(FinishCmd)(struct TagItem *CmdTags, struct sdcard_Bus *bus)
674 struct TagItem *Response = NULL;
676 D(UWORD sdCommand = (UWORD)GetTagData(SDCARD_TAG_CMD, 0, CmdTags));
677 ULONG sdResponseType = GetTagData(SDCARD_TAG_RSPTYPE, MMC_RSP_NONE, CmdTags);
678 ULONG retVal = 0;
680 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
682 if (sdResponseType != MMC_RSP_NONE)
684 if ((Response = FindTagItem(SDCARD_TAG_RSP, CmdTags)) != NULL)
686 D(bug("[SDBus%02u] %s: Reading CMD %02d Response ", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdCommand));
687 if (sdResponseType & MMC_RSP_136)
689 D(bug("[136bit]\n"));
690 if (Response->ti_Data)
692 ULONG i;
693 for (i = 0; i < 4; i ++)
695 ((ULONG *)Response->ti_Data)[i] = bus->sdcb_IOReadLong(SDHCI_RESPONSE + (3 - i) * 4, bus) << 8;
696 if (i != 3)
697 ((ULONG *)Response->ti_Data)[i] |= bus->sdcb_IOReadByte(SDHCI_RESPONSE + (3 - i) * 4 - 1, bus);
699 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]));
702 else
704 Response->ti_Data = bus->sdcb_IOReadLong(SDHCI_RESPONSE, bus);
705 D(bug("[= %08x]\n", Response->ti_Data));
710 return retVal;
713 ULONG FNAME_SDCBUS(FinishData)(struct TagItem *DataTags, struct sdcard_Bus *bus)
715 DTRANS(UWORD sdCommand = (UWORD)GetTagData(SDCARD_TAG_CMD, 0, DataTags));
716 ULONG sdcStateMask, sdCommandMask,
717 sdData, sdDataMode, sdDataLen, sdcReg = 0;
718 struct TagItem *sdDataLenTag = NULL;
719 ULONG timeout = 1000;
720 ULONG retVal = 0;
722 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
724 if ((sdData = GetTagData(SDCARD_TAG_DATA, 0, DataTags)) != 0)
726 if ((sdDataLenTag = FindTagItem(SDCARD_TAG_DATALEN, DataTags)) == NULL)
727 sdData = 0;
728 else
730 sdDataLen = sdDataLenTag->ti_Data;
731 if ((sdDataMode = GetTagData(SDCARD_TAG_DATAFLAGS, MMC_DATA_READ, DataTags)) == MMC_DATA_READ)
733 sdcStateMask = SDHCI_PS_DATA_AVAILABLE;
734 sdCommandMask = SDHCI_INT_DATA_AVAIL;
736 else
738 sdcStateMask = SDHCI_PS_SPACE_AVAILABLE;
739 sdCommandMask = SDHCI_INT_SPACE_AVAIL;
744 if (sdData)
746 DTRANS(bug("[SDBus%02u] %s: Transfering CMD %02d Data..\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, sdCommand));
747 do {
748 bus->sdcb_BusStatus = bus->sdcb_IOReadLong(SDHCI_INT_STATUS, bus);
749 if (bus->sdcb_BusStatus & SDHCI_INT_ERROR) {
750 bug("[SDBus%02u] %s: Error [status 0x%X]!\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_BusStatus);
751 retVal = -1;
752 break;
755 if ((bus->sdcb_BusStatus & sdCommandMask) && (bus->sdcb_IOReadLong(SDHCI_PRESENT_STATE, bus) & sdcStateMask)) {
756 ULONG currbyte, tranlen = (sdDataLen > (1 << bus->sdcb_SectorShift)) ? (1 << bus->sdcb_SectorShift) : sdDataLen;
758 DTRANS(bug("[SDBus%02u] %s: Attempting to %s %dbytes\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, ((sdDataMode == MMC_DATA_READ) ? "read" : "write"), tranlen));
759 for (currbyte = 0; currbyte < tranlen; currbyte++)
761 DTRANS(DUMP(
762 if ((currbyte % 16) == 0)
764 bug("[SDBus%02u] %s: ", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
767 if (sdDataMode == MMC_DATA_READ)
769 if ((currbyte % 4) == 0)
771 sdcReg = bus->sdcb_IOReadLong(SDHCI_BUFFER, bus);
773 *(UBYTE *)sdData = sdcReg & 0xFF;
775 else
776 sdcReg |= *(UBYTE *)sdData << (currbyte % 4);
778 sdData++;
779 sdDataLen--;
780 if (sdDataMode != MMC_DATA_READ)
782 if (((currbyte % 4) == 3) || (sdDataLen == 0))
784 bus->sdcb_IOWriteLong(SDHCI_BUFFER, *(ULONG *)(sdData - 3), bus);
787 else
788 sdcReg >>= 8;
789 DTRANS(DUMP(
790 if ((currbyte % 4) == 3)
792 bug(" %08x", *(ULONG *)(sdData - 3));
794 if ((currbyte % 16) == 15)
796 bug("\n");
800 DTRANS(DUMP(
801 if ((currbyte % 16) != 0)
803 bug("\n");
807 else if (!(bus->sdcb_BusStatus & SDHCI_INT_DATA_END))
809 sdcard_Udelay(1000);
811 if (timeout-- <= 0)
813 bug("[SDBus%02u] %s: Timeout!\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
814 retVal = -1;
815 break;
818 } while ((sdDataLen > 0) && (!(bus->sdcb_BusStatus & SDHCI_INT_DATA_END)));
820 if (bus->sdcb_LEDCtrl)
821 bus->sdcb_LEDCtrl(LED_OFF);
823 sdDataLenTag->ti_Data -= sdDataLen;
826 return retVal;
829 ULONG FNAME_SDCBUS(WaitCmd)(ULONG mask, ULONG timeout, struct sdcard_Bus *bus)
831 D(bug("[SDBus%02u] %s(), task %p %s\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, FindTask(NULL), FindTask(NULL)->tc_Node.ln_Name));
832 D(bug("Task=%p\n", bus->sdcb_Task));
833 if (bus->sdcb_Task == FindTask(NULL))
835 D(bug("Waiting for signal %d\n", bus->sdcb_CommandSig));
836 Wait(1L << bus->sdcb_CommandSig);
838 else
840 D(bug("\nNot a Bus task!\n\n"));
841 sdcard_Udelay(1000);
844 while (bus->sdcb_IOReadLong(SDHCI_PRESENT_STATE, bus) & mask) {
845 sdcard_Udelay(1000);
847 if ((bus->sdcb_BusStatus & SDHCI_INT_ERROR) == SDHCI_INT_ERROR)
848 break;
850 if (--timeout <= 0)
851 break;
854 if ((timeout <= 0) || (bus->sdcb_BusStatus & SDHCI_INT_ERROR))
856 return -1;
859 return 0;
863 ULONG FNAME_SDCBUS(Rsp136Unpack)(ULONG *buf, ULONG offset, const ULONG len)
865 const ULONG mask = ((len < 32) ? (1 << len) : 0) - 1;
866 const ULONG shift = (offset) & 0x1F;
867 ULONG retval;
869 retval = buf[3 - (offset >> 5)] >> shift;
870 if (len + shift > 32)
871 retval |= buf[3 - (offset >> 5) - 1] << ((32 - shift) % 32);
873 return (retval & mask);
876 /********** BUS IRQ HANDLER **************/
878 #undef DIRQ
879 #define DIRQ(x) x
881 void FNAME_SDCBUS(BusIRQ)(struct sdcard_Bus *bus, void *_unused)
883 BOOL error = FALSE;
885 DIRQ(bug("[SDBus%02u] %s(bus @ 0x%p)\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus));
887 if (!(bus))
889 DIRQ(bug("[SDBus%02u] %s: Bad Params!\n", __PRETTY_FUNCTION__));
890 return;
893 bus->sdcb_BusStatus = bus->sdcb_IOReadLong(SDHCI_INT_STATUS, bus);
895 if (!(bus->sdcb_BusStatus & SDHCI_INT_ERROR))
897 DIRQ(bug("[SDBus%02u] %s: Status = %08x\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_BusStatus));
899 if (bus->sdcb_BusStatus & (SDHCI_INT_CARD_INSERT|SDHCI_INT_CARD_REMOVE))
901 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, (bus->sdcb_BusStatus & (SDHCI_INT_CARD_INSERT|SDHCI_INT_CARD_REMOVE)), bus);
903 bus->sdcb_BusFlags &= ~AF_Bus_MediaPresent;
904 bus->sdcb_BusFlags |= AF_Bus_MediaChanged;
906 if (bus->sdcb_BusStatus & SDHCI_INT_CARD_INSERT)
907 bus->sdcb_BusFlags |= AF_Bus_MediaPresent;
909 bus->sdcb_BusStatus &= ~(SDHCI_INT_CARD_INSERT|SDHCI_INT_CARD_REMOVE);
911 if (bus->sdcb_Task)
912 Signal(bus->sdcb_Task, (1L << bus->sdcb_MediaSig));
914 if (bus->sdcb_BusStatus & SDHCI_INT_CMD_MASK)
916 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, (bus->sdcb_BusStatus & SDHCI_INT_CMD_MASK), bus);
918 if ((bus->sdcb_BusStatus & SDHCI_INT_RESPONSE) &&
919 (bus->sdcb_RespListener))
921 if (FNAME_SDCBUS(FinishCmd)(bus->sdcb_RespListener, bus) == -1)
922 error = TRUE;
923 bus->sdcb_RespListener = NULL;
925 if (bus->sdcb_Task && (bus->sdcb_BusStatus & SDHCI_INT_RESPONSE))
927 DIRQ(bug("Signalling task %p (%s) with signal %d\n", bus->sdcb_Task, bus->sdcb_Task->tc_Node.ln_Name, bus->sdcb_CommandSig));
928 Signal(bus->sdcb_Task, 1L << bus->sdcb_CommandSig);
931 bus->sdcb_BusStatus &= ~SDHCI_INT_CMD_MASK;
933 if (bus->sdcb_BusStatus & SDHCI_INT_DATA_MASK)
935 if ((bus->sdcb_BusStatus & (SDHCI_INT_DATA_AVAIL|SDHCI_INT_SPACE_AVAIL)) &&
936 (bus->sdcb_DataListener))
938 if (FNAME_SDCBUS(FinishData)(bus->sdcb_DataListener, bus) == -1)
939 error = TRUE;
940 bus->sdcb_DataListener = NULL;
941 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, (bus->sdcb_BusStatus & (SDHCI_INT_DATA_AVAIL|SDHCI_INT_SPACE_AVAIL)), bus);
942 bus->sdcb_BusStatus &= ~SDHCI_INT_DATA_MASK;
944 else
946 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, (bus->sdcb_BusStatus & SDHCI_INT_DATA_MASK), bus);
947 bus->sdcb_BusStatus &= ~SDHCI_INT_DATA_MASK;
951 else
953 bug("[SDBus%02u] %s: ERROR [Status = %08x]\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_BusStatus);
954 if (bus->sdcb_BusStatus & SDHCI_INT_ACMD12ERR)
956 bug("[SDBus%02u] %s: [acmd12err = %04x ]\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_IOReadWord(SDHCI_ACMD12_ERR, bus));
958 error = TRUE;
961 if (error)
963 if (bus->sdcb_BusStatus & bus->sdcb_IntrMask)
965 bug("[SDBus%02u] %s: Clearing Unhandled Interrupts [%08x]\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_BusStatus & bus->sdcb_IntrMask);
966 bus->sdcb_IOWriteLong(SDHCI_INT_STATUS, bus->sdcb_BusStatus & bus->sdcb_IntrMask, bus);
967 bus->sdcb_BusStatus &= ~bus->sdcb_IntrMask;
969 bug("[SDBus%02u] %s: Reseting SDHCI CMD/DATA\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__);
971 FNAME_SDCBUS(SoftReset)(SDHCI_RESET_CMD, bus);
972 FNAME_SDCBUS(SoftReset)(SDHCI_RESET_DATA, bus);
974 DIRQ(bug("[SDBus%02u] %s: Done.\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
977 #undef DIRQ
978 #define DIRQ(x) /* x */
979 /********** BUS MANAGEMENT TASK **************/
981 void FNAME_SDCBUS(BusTask)(struct sdcard_Bus *bus)
983 LIBBASETYPEPTR LIBBASE = bus->sdcb_DeviceBase;
984 struct IORequest *msg;
985 ULONG sig, tasksig;
987 DFUNCS(bug("[SDBus%02u] %s()\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
989 bus->sdcb_Timer = sdcard_OpenTimer(LIBBASE);
991 /* Get the signal used for sleeping */
992 bus->sdcb_Task = FindTask(0);
994 D(bug("[SDBus%02u] %s: Task @ 0x%p\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_Task));
996 bus->sdcb_TaskSig = AllocSignal(-1);
997 if ((bus->sdcb_MediaSig = AllocSignal(-1)) == -1)
999 D(bug("[SDBus%02u] %s: failed to allocate Media Change sigbit\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
1002 if ((bus->sdcb_CommandSig = AllocSignal(-1)) == -1)
1004 D(bug("[SDBus%02u] %s: failed to allocate Command Completed sigbit\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
1007 /* Failed to get it? Use SIGBREAKB_CTRL_E instead */
1008 if (bus->sdcb_TaskSig < 0)
1009 bus->sdcb_TaskSig = SIGBREAKB_CTRL_E;
1011 sig = ((1L << bus->sdcb_MsgPort->mp_SigBit)|(1L << bus->sdcb_TaskSig)|(1L << bus->sdcb_MediaSig));
1013 DINIT(bug("[SDBus%02u] %s: TaskSig: %d, MediaSig: %d\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_TaskSig, bus->sdcb_MediaSig));
1015 /* Install IRQ handler */
1016 if ((bus->sdcb_IRQHandle = KrnAddIRQHandler(bus->sdcb_BusIRQ, FNAME_SDCBUS(BusIRQ), bus, NULL)) != NULL)
1018 DINIT(bug("[SDBus%02u] %s: IRQHandle @ 0x%p for IRQ#%ld\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, bus->sdcb_IRQHandle, bus->sdcb_BusIRQ));
1020 DINIT(bug("[SDBus%02u] %s: Masking chipset Interrupts...\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
1022 bus->sdcb_IOWriteLong(SDHCI_INT_ENABLE, bus->sdcb_IntrMask, bus);
1023 bus->sdcb_IOWriteLong(SDHCI_SIGNAL_ENABLE, bus->sdcb_IntrMask, bus);
1026 for (;;)
1028 tasksig = Wait(sig);
1030 if ((tasksig & (1L << bus->sdcb_MediaSig)) && (bus->sdcb_BusFlags & AF_Bus_MediaChanged))
1032 D(bug("[SDBus%02u] %s: detected unit change\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__));
1033 D(bug("[SDBus%02u] %s: Card %s Detected!\n", bus->sdcb_BusNum, __PRETTY_FUNCTION__, (bus->sdcb_BusFlags & AF_Bus_MediaPresent) ? "Insert" : "Eject" ));
1034 if (bus->sdcb_BusFlags & AF_Bus_MediaPresent)
1036 FNAME_SDCBUS(RegisterUnit)(bus);
1038 else
1040 FNAME_SDCBUS(ReleaseUnit)(bus);
1044 /* Defer IORequest processing if the bus is active */
1045 if ((tasksig & (1L << bus->sdcb_MsgPort->mp_SigBit)) && (!(bus->sdcb_BusFlags & AF_Bus_Active)))
1047 /* process pending requests .. */
1048 bus->sdcb_BusFlags |= AF_Bus_Active;
1049 while ((msg = (struct IORequest *)GetMsg(bus->sdcb_MsgPort)))
1051 /* And do IO's */
1052 if (FNAME_SDC(HandleIO)(msg))
1054 ReplyMsg((struct Message *)msg);
1057 bus->sdcb_BusFlags &= ~AF_Bus_Active;