2 Copyright © 2013, The AROS Development Team. All rights reserved.
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>
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>
36 #include "sdcard_base.h"
37 #include "sdcard_bus.h"
38 #include "sdcard_unit.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
},
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
);
64 FNAME_SDCUNIT(SDSCChangeFrequency
)(sdcUnit
);
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
));
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
);
102 FNAME_SDCBUS(SetClock
)(26000000, sdcUnit
->sdcu_Bus
);
105 FNAME_SDCBUS(SetClock
)(20000000, sdcUnit
->sdcu_Bus
);
109 if (sdcUnit
->sdcu_Flags
& AF_Card_HighSpeed
)
110 FNAME_SDCBUS(SetClock
)(50000000, sdcUnit
->sdcu_Bus
);
112 FNAME_SDCBUS(SetClock
)(25000000, sdcUnit
->sdcu_Bus
);
116 D(bug("[SDCard%02ld] %s: Done.\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
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
},
134 DFUNCS(bug("[SDCard%02ld] %s()\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
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
)
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
);
146 } else if (--retryreq
< 0)
150 } while (--timeout
> 0);
153 bug("[SDCard%02ld] %s: Timeout\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
);
157 D(bug("[SDCard%02ld] %s: State = %08x\n", sdcUnit
->sdcu_UnitNum
, __PRETTY_FUNCTION__
, sdcStatusTags
[3].ti_Data
& MMC_STATUS_STATE_MASK
));
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
[] =
175 {SDCARD_TAG_RSPTYPE
, 0},
179 BOOL sdcHighCap
= FALSE
;
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__
));
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__
));
209 D(bug("[SDBus%02u] %s: SD1.0 Compliant Card\n", bus
->sdcb_BusNum
, __PRETTY_FUNCTION__
));
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__
));
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
));
238 D(bug("[SDBus%02u] %s: Operating condition Query Failed\n", bus
->sdcb_BusNum
, __PRETTY_FUNCTION__
));
241 } while ((!(sdcRegTags
[3].ti_Data
& OCR_BUSY
)) && (--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__
));
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
);
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
)
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
;
336 sdcUnit
->sdcu_Flags
|= AF_Card_HighCapacity
;
337 sdcUnit
->sdcu_Read64
= FNAME_SDCIO(ReadSector64
);
338 sdcUnit
->sdcu_Write64
= FNAME_SDCIO(WriteSector64
);
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));
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
;
364 D(bug("[SDBus%02u] %s: Unsupported Card\n", bus
->sdcb_BusNum
, __PRETTY_FUNCTION__
));
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
;
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
);
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__
));
414 D(bug("[SDBus%02u] %s: Card failed to send CSD\n", bus
->sdcb_BusNum
, __PRETTY_FUNCTION__
));
419 D(bug("[SDBus%02u] %s: Failed to allocate Unit\n", bus
->sdcb_BusNum
, __PRETTY_FUNCTION__
));
424 D(bug("[SDBus%02u] %s: Card failed to send RCA\n", bus
->sdcb_BusNum
, __PRETTY_FUNCTION__
));
429 D(bug("[SDBus%02u] %s: Card failed to send CID\n", bus
->sdcb_BusNum
, __PRETTY_FUNCTION__
));
434 D(bug("[SDBus%02u] %s: Card failed to initialise\n", bus
->sdcb_BusNum
, __PRETTY_FUNCTION__
));
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
)
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
) {
454 bug("[SDBus%02u] %s: Timeout\n", bus
->sdcb_BusNum
, __PRETTY_FUNCTION__
);
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
);
485 while (!((sdcClkCtrl
= bus
->sdcb_IOReadWord(SDHCI_CLOCK_CONTROL
, bus
)) & SDHCI_CLOCK_INT_STABLE
)) {
487 bug("[SDBus%02u] %s: SDHCI Clock failed to stabilise\n", bus
->sdcb_BusNum
, __PRETTY_FUNCTION__
);
495 if (sdcClkCtrlCur
& SDHCI_CLOCK_CARD_EN
)
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__
));
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
;
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
);
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
;
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
) {
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
);
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
;
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
;
600 sdCommandFlags
|= SDHCI_CMD_DATA
;
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
);
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
;
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
);
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
));
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
);
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
)
673 for (i
= 0; i
< 4; i
++)
675 ((ULONG
*)Response
->ti_Data
)[i
] = bus
->sdcb_IOReadLong(SDHCI_RESPONSE
+ (3 - i
) * 4, bus
) << 8;
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]));
684 Response
->ti_Data
= bus
->sdcb_IOReadLong(SDHCI_RESPONSE
, bus
);
685 D(bug("[= %08x]\n", Response
->ti_Data
));
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;
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
)
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
;
718 sdcStateMask
= SDHCI_PS_SPACE_AVAILABLE
;
719 sdCommandMask
= SDHCI_INT_SPACE_AVAIL
;
726 DTRANS(bug("[SDBus%02u] %s: Transfering CMD %02d Data..\n", bus
->sdcb_BusNum
, __PRETTY_FUNCTION__
, sdCommand
));
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
);
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
++)
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;
756 sdcReg
|= *(UBYTE
*)sdData
<< (currbyte
% 4);
760 if (sdDataMode
!= MMC_DATA_READ
)
762 if (((currbyte
% 4) == 3) || (sdDataLen
== 0))
764 bus
->sdcb_IOWriteLong(SDHCI_BUFFER
, *(ULONG
*)(sdData
- 3), bus
);
770 if ((currbyte
% 4) == 3)
772 bug(" %08x", *(ULONG
*)(sdData
- 3));
774 if ((currbyte
% 16) == 15)
781 if ((currbyte
% 16) != 0)
787 else if (!(bus
->sdcb_BusStatus
& SDHCI_INT_DATA_END
))
793 bug("[SDBus%02u] %s: Timeout!\n", bus
->sdcb_BusNum
, __PRETTY_FUNCTION__
);
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
;
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
) {
816 if ((bus
->sdcb_BusStatus
& SDHCI_INT_ERROR
) == SDHCI_INT_ERROR
)
823 if ((timeout
<= 0) || (bus
->sdcb_BusStatus
& SDHCI_INT_ERROR
))
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;
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
)
851 DIRQ(bug("[SDBus%02u] %s(bus @ 0x%p)\n", bus
->sdcb_BusNum
, __PRETTY_FUNCTION__
, bus
));
855 DIRQ(bug("[SDBus%02u] %s: Bad Params!\n", __PRETTY_FUNCTION__
));
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
);
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)
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)
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
;
906 bus
->sdcb_IOWriteLong(SDHCI_INT_STATUS
, (bus
->sdcb_BusStatus
& SDHCI_INT_DATA_MASK
), bus
);
907 bus
->sdcb_BusStatus
&= ~SDHCI_INT_DATA_MASK
;
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
));
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
;
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
);
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
);
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
)))
1005 if (FNAME_SDC(HandleIO
)(msg
))
1007 ReplyMsg((struct Message
*)msg
);
1010 bus
->sdcb_BusFlags
&= ~AF_Bus_Active
;