enable large file support on Wii. used by tinysmb.
[libogc.git] / libogc / sdgecko_io.c
blob59d59152dbb0ad7371c7e54868dbedda41791bcc
1 #include <stdlib.h>
2 #include <string.h>
3 #include <time.h>
4 #include <unistd.h>
5 #include <ogcsys.h>
7 #include "asm.h"
8 #include "processor.h"
9 #include "exi.h"
10 #include "lwp.h"
11 #include "system.h"
12 #include "semaphore.h"
13 #include "card_cmn.h"
14 //#include "card_fat.h"
15 #include "card_io.h"
17 //#define _CARDIO_DEBUG
18 #ifdef _CARDIO_DEBUG
19 #include <stdio.h>
20 #endif
21 // SDHC support
22 // added by emu_kidid
23 #define SECTOR_ADDRESSING 0
24 #define BYTE_ADDRESSING 1
25 #define TYPE_SD 0
26 #define TYPE_SDHC 1
28 #define MMC_ERROR_PARAM 0x0040
29 #define MMC_ERROR_ADDRESS 0x0020
30 #define MMC_ERROR_ERASE_SEQ 0x0010
31 #define MMC_ERROR_CRC 0x0008
32 #define MMC_ERROR_ILL 0x0004
33 #define MMC_ERROR_ERASE_RES 0x0002
34 #define MMC_ERROR_IDLE 0x0001
36 #define CARDIO_OP_INITFAILED 0x8000
37 #define CARDIO_OP_TIMEDOUT 0x4000
38 #define CARDIO_OP_IOERR_IDLE 0x2000
39 #define CARDIO_OP_IOERR_PARAM 0x1000
40 #define CARDIO_OP_IOERR_WRITE 0x0200
41 #define CARDIO_OP_IOERR_ADDR 0x0100
42 #define CARDIO_OP_IOERR_CRC 0x0002
43 #define CARDIO_OP_IOERR_ILL 0x0001
44 #define CARDIO_OP_IOERR_FATAL (CARDIO_OP_IOERR_PARAM|CARDIO_OP_IOERR_WRITE|CARDIO_OP_IOERR_ADDR|CARDIO_OP_IOERR_CRC|CARDIO_OP_IOERR_ILL)
46 #define _SHIFTL(v, s, w) \
47 ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s)))
48 #define _SHIFTR(v, s, w) \
49 ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1)))
51 typedef s32 (*cardiocallback)(s32 drv_no);
53 u8 g_CID[MAX_DRIVE][16];
54 u8 g_CSD[MAX_DRIVE][16];
55 u8 g_CardStatus[MAX_DRIVE][64];
57 u8 g_mCode[MAX_MI_NUM] = { 0x03 };
59 u16 g_dCode[MAX_MI_NUM][MAX_DI_NUM] =
62 0x033f, /* SD 8Mb */
63 0x0383, /* SD 16Mb */
64 0x074b, /* SD 32Mb */
65 0x0edf, /* SD 64Mb */
66 0x0f03 /* SD 128Mb */
70 static u8 _ioWPFlag;
71 static u8 _ioClrFlag;
72 static u32 _ioCardFreq;
73 static u32 _ioRetryCnt;
74 static cardiocallback _ioRetryCB = NULL;
76 static lwpq_t _ioEXILock[MAX_DRIVE];
78 static u32 _ioPageSize[MAX_DRIVE];
79 static u32 _ioFlag[MAX_DRIVE];
80 static u32 _ioError[MAX_DRIVE];
81 static bool _ioCardInserted[MAX_DRIVE];
83 static u8 _ioResponse[MAX_DRIVE][128];
84 static u8 _ioCrc7Table[256];
85 static u16 _ioCrc16Table[256];
87 // SDHC support
88 static u32 _initType[MAX_DRIVE];
89 static u32 _ioAddressingType[MAX_DRIVE];
91 extern unsigned long gettick();
93 static __inline__ u32 __check_response(s32 drv_no,u8 res)
95 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
97 _ioError[drv_no] = 0;
98 if(_ioFlag[drv_no]==INITIALIZING && res&MMC_ERROR_IDLE) {
99 _ioError[drv_no] |= CARDIO_OP_IOERR_IDLE;
100 return CARDIO_ERROR_READY;
101 } else {
102 if(res&MMC_ERROR_PARAM) _ioError[drv_no] |= CARDIO_OP_IOERR_PARAM;
103 if(res&MMC_ERROR_ADDRESS) _ioError[drv_no] |= CARDIO_OP_IOERR_ADDR;
104 if(res&MMC_ERROR_CRC) _ioError[drv_no] |= CARDIO_OP_IOERR_CRC;
105 if(res&MMC_ERROR_ILL) _ioError[drv_no] |= CARDIO_OP_IOERR_ILL;
107 return ((_ioError[drv_no]&CARDIO_OP_IOERR_FATAL)?CARDIO_ERROR_INTERNAL:CARDIO_ERROR_READY);
110 static void __init_crc7()
112 s32 i,j;
113 u8 c,crc7;
115 crc7 = 0;
116 for(i=0;i<256;i++) {
117 c = i;
118 crc7 = 0;
119 for(j=0;j<8;j++) {
120 crc7 <<= 1;
121 if((crc7^c)&0x80) crc7 ^= 0x09;
122 c <<= 1;
124 crc7 &= 0x7f;
125 _ioCrc7Table[i] = crc7;
129 static u8 __make_crc7(void *buffer,u32 len)
131 s32 i;
132 u8 crc7;
133 u8 *ptr;
135 crc7 = 0;
136 ptr = buffer;
137 for(i=0;i<len;i++)
138 crc7 = _ioCrc7Table[(u8)((crc7<<1)^ptr[i])];
140 return ((crc7<<1)|1);
143 /* Old way, realtime
144 static u8 __make_crc7(void *buffer,u32 len)
146 u32 mask,cnt,bcnt;
147 u32 res,val;
148 u8 *ptr = (u8*)buffer;
150 cnt = 0;
151 res = 0;
152 while(cnt<len) {
153 bcnt = 0;
154 mask = 0x80;
155 while(bcnt<8) {
156 res <<= 1;
157 val = *ptr^((res>>bcnt)&0xff);
158 if(mask&val) {
159 res |= 0x01;
160 if(!(res&0x0008)) res |= 0x0008;
161 else res &= ~0x0008;
163 } else if(res&0x0008) res |= 0x0008;
164 else res &= ~0x0008;
166 mask >>= 1;
167 bcnt++;
169 ptr++;
170 cnt++;
172 return (res<<1)&0xff;
175 static void __init_crc16()
177 s32 i,j;
178 u16 crc16,c;
180 for(i=0;i<256;i++) {
181 crc16 = 0;
182 c = ((u16)i)<<8;
183 for(j=0;j<8;j++) {
184 if((crc16^c)&0x8000) crc16 = (crc16<<1)^0x1021;
185 else crc16 <<= 1;
187 c <<= 1;
190 _ioCrc16Table[i] = crc16;
194 static u16 __make_crc16(void *buffer,u32 len)
196 s32 i;
197 u8 *ptr;
198 u16 crc16;
200 crc16 = 0;
201 ptr = buffer;
202 for(i=0;i<len;i++)
203 crc16 = (crc16<<8)^_ioCrc16Table[((crc16>>8)^(u16)(ptr[i]))];
205 return crc16;
208 /* Old way, realtime
209 static u16 __make_crc16(void *buffer,u32 len)
211 u32 mask,cnt,bcnt;
212 u32 res,val,tmp;
213 u8 *ptr = (u8*)buffer;
215 cnt = 0;
216 res = 0;
217 while(cnt<len) {
218 bcnt = 0;
219 mask = 0x80;
220 val = *ptr;
221 while(bcnt<8) {
222 tmp = val^((res>>(bcnt+8))&0xff);
223 if(mask&tmp) {
224 res = (res<<1)|0x0001;
225 if(!(res&0x0020)) res |= 0x0020;
226 else res &= ~0x0020;
227 if(!(res&0x1000)) res |= 0x1000;
228 else res &= ~0x1000;
229 } else {
230 res = (res<<1)&~0x0001;
231 if(res&0x0020) res |= 0x0020;
232 else res &= ~0x0020;
233 if(res&0x1000) res |= 0x1000;
234 else res &= ~0x1000;
236 mask >>= 1;
237 bcnt++;
239 ptr++;
240 cnt++;
243 return (res&0xffff);
247 static u32 __card_checktimeout(s32 drv_no,u32 startT,u32 timeout)
249 u32 endT,diff;
250 u32 msec;
252 endT = gettick();
253 if(endT<startT) {
254 diff = (endT+(-1-startT))+1;
255 } else
256 diff = (endT-startT);
258 msec = (diff/TB_TIMER_CLOCK);
259 if(msec<=timeout) return 0;
261 _ioError[drv_no] |= CARDIO_OP_TIMEDOUT;
262 return 1;
265 static s32 __exi_unlock(s32 chn,s32 dev)
267 LWP_ThreadBroadcast(_ioEXILock[chn]);
268 return 1;
271 static void __exi_wait(s32 drv_no)
273 u32 ret;
275 do {
276 if((ret=EXI_Lock(drv_no,EXI_DEVICE_0,__exi_unlock))==1) break;
277 LWP_ThreadSleep(_ioEXILock[drv_no]);
278 } while(ret==0);
281 static s32 __card_exthandler(s32 chn,s32 dev)
283 _ioCardInserted[chn] = FALSE;
284 sdgecko_doUnmount(chn);
285 sdgecko_ejectedCB(chn);
286 EXI_Unlock(chn);
287 return 1;
290 static s32 __card_writecmd0(s32 drv_no)
292 u8 crc;
293 u32 cnt;
294 u8 dummy[128];
295 u8 cmd[5] = {0,0,0,0,0};
297 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
299 _ioClrFlag = 0xff;
300 cmd[0] = 0x40;
301 crc = __make_crc7(cmd,5);
303 if(_ioWPFlag) {
304 _ioClrFlag = 0x00;
305 for(cnt=0;cnt<5;cnt++) cmd[cnt] ^= -1;
308 for(cnt=0;cnt<128;cnt++) dummy[cnt] = _ioClrFlag;
310 __exi_wait(drv_no);
312 if(EXI_SelectSD(drv_no,EXI_DEVICE_0,_ioCardFreq)==0) {
313 EXI_Unlock(drv_no);
314 return CARDIO_ERROR_NOCARD;
318 cnt = 0;
319 while(cnt<20) {
320 if(EXI_ImmEx(drv_no,dummy,128,EXI_WRITE)==0) {
321 EXI_Deselect(drv_no);
322 EXI_Unlock(drv_no);
323 return CARDIO_ERROR_IOERROR;
325 cnt++;
327 EXI_Deselect(drv_no);
329 if(EXI_Select(drv_no,EXI_DEVICE_0,_ioCardFreq)==0) {
330 EXI_Unlock(drv_no);
331 return CARDIO_ERROR_NOCARD;
334 crc |= 0x01;
335 if(_ioWPFlag) crc ^= -1;
336 #ifdef _CARDIO_DEBUG
337 printf("sd command0: %02x %02x %02x %02x %02x %02x\n",cmd[0],cmd[1],cmd[2],cmd[3],cmd[4],crc);
338 #endif
339 if(EXI_ImmEx(drv_no,cmd,5,EXI_WRITE)==0) {
340 EXI_Deselect(drv_no);
341 EXI_Unlock(drv_no);
342 return CARDIO_ERROR_IOERROR;
345 if(EXI_ImmEx(drv_no,&crc,1,EXI_WRITE)==0) {
346 EXI_Deselect(drv_no);
347 EXI_Unlock(drv_no);
348 return CARDIO_ERROR_IOERROR;
351 EXI_Deselect(drv_no);
352 EXI_Unlock(drv_no);
353 return CARDIO_ERROR_READY;
356 static s32 __card_writecmd(s32 drv_no,void *buf,s32 len)
358 u8 crc,*ptr;
359 u8 dummy[32];
360 u32 cnt;
362 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
364 ptr = buf;
365 ptr[0] |= 0x40;
366 crc = __make_crc7(buf,len);
368 if(_ioWPFlag) {
369 for(cnt=0;cnt<len;cnt++) ptr[cnt] ^= -1;
372 __exi_wait(drv_no);
374 if(EXI_Select(drv_no,EXI_DEVICE_0,_ioCardFreq)==0) {
375 EXI_Unlock(drv_no);
376 return CARDIO_ERROR_NOCARD;
379 for(cnt=0;cnt<32;cnt++) dummy[cnt] = _ioClrFlag;
381 if(EXI_ImmEx(drv_no,dummy,10,EXI_WRITE)==0) {
382 EXI_Deselect(drv_no);
383 EXI_Unlock(drv_no);
384 return CARDIO_ERROR_IOERROR;
387 crc |= 0x01;
388 if(_ioWPFlag) crc ^= -1;
389 #ifdef _CARDIO_DEBUG
390 printf("sd command: %02x %02x %02x %02x %02x %02x\n",((u8*)buf)[0],((u8*)buf)[1],((u8*)buf)[2],((u8*)buf)[3],((u8*)buf)[4],crc);
391 #endif
392 if(EXI_ImmEx(drv_no,buf,len,EXI_WRITE)==0) {
393 EXI_Deselect(drv_no);
394 EXI_Unlock(drv_no);
395 return CARDIO_ERROR_IOERROR;
397 if(EXI_ImmEx(drv_no,&crc,1,EXI_WRITE)==0) {
398 EXI_Deselect(drv_no);
399 EXI_Unlock(drv_no);
400 return CARDIO_ERROR_IOERROR;
403 EXI_Deselect(drv_no);
404 EXI_Unlock(drv_no);
405 return CARDIO_ERROR_READY;
408 static s32 __card_readresponse(s32 drv_no,void *buf,s32 len)
410 u8 *ptr;
411 s32 startT,ret;
413 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
415 ret = CARDIO_ERROR_READY;
416 ptr = buf;
417 *ptr = _ioClrFlag;
419 __exi_wait(drv_no);
421 if(EXI_Select(drv_no,EXI_DEVICE_0,_ioCardFreq)==0) {
422 EXI_Unlock(drv_no);
423 return CARDIO_ERROR_NOCARD;
426 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
427 EXI_Deselect(drv_no);
428 EXI_Unlock(drv_no);
429 return CARDIO_ERROR_IOERROR;
431 #ifdef _CARDIO_DEBUG
432 printf("sd response: %02x\n",((u8*)buf)[0]);
433 #endif
435 startT = gettick();
436 while(*ptr&0x80) {
437 *ptr = _ioClrFlag;
438 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
439 EXI_Deselect(drv_no);
440 EXI_Unlock(drv_no);
441 return CARDIO_ERROR_IOERROR;
443 #ifdef _CARDIO_DEBUG
444 printf("sd response: %02x\n",((u8*)buf)[0]);
445 #endif
446 if(!(*ptr&0x80)) break;
447 if(__card_checktimeout(drv_no,startT,500)!=0) {
448 *ptr = _ioClrFlag;
449 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
450 EXI_Deselect(drv_no);
451 EXI_Unlock(drv_no);
452 return CARDIO_ERROR_IOERROR;
454 #ifdef _CARDIO_DEBUG
455 printf("sd response: %02x\n",((u8*)buf)[0]);
456 #endif
457 if(*ptr&0x80) ret = CARDIO_ERROR_IOTIMEOUT;
458 break;
461 if(len>1 && ret==CARDIO_ERROR_READY) {
462 *(++ptr) = _ioClrFlag;
463 if(EXI_ImmEx(drv_no,ptr,len-1,EXI_READWRITE)==0) ret = CARDIO_ERROR_IOERROR;
466 EXI_Deselect(drv_no);
467 EXI_Unlock(drv_no);
468 return ret;
471 static s32 __card_stopreadresponse(s32 drv_no,void *buf,s32 len)
473 u8 *ptr,tmp;
474 s32 startT,ret;
476 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
478 ptr = buf;
480 __exi_wait(drv_no);
482 if(EXI_Select(drv_no,EXI_DEVICE_0,_ioCardFreq)==0) {
483 EXI_Unlock(drv_no);
484 return CARDIO_ERROR_NOCARD;
487 ret = CARDIO_ERROR_READY;
488 *ptr = _ioClrFlag;
489 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
490 EXI_Deselect(drv_no);
491 EXI_Unlock(drv_no);
492 return CARDIO_ERROR_IOERROR;
494 #ifdef _CARDIO_DEBUG
495 kprintf("sd response(%d): %02x\n",__LINE__,((u8*)buf)[0]);
496 #endif
498 *ptr = _ioClrFlag;
499 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
500 EXI_Deselect(drv_no);
501 EXI_Unlock(drv_no);
502 return CARDIO_ERROR_IOERROR;
504 #ifdef _CARDIO_DEBUG
505 kprintf("sd response1: %02x\n",((u8*)buf)[0]);
506 #endif
508 startT = gettick();
509 while(*ptr&0x80) {
510 *ptr = _ioClrFlag;
511 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
512 EXI_Deselect(drv_no);
513 EXI_Unlock(drv_no);
514 return CARDIO_ERROR_IOERROR;
516 #ifdef _CARDIO_DEBUG
517 kprintf("sd response2: %02x\n",((u8*)buf)[0]);
518 #endif
519 if(!(*ptr&0x80)) break;
520 if(__card_checktimeout(drv_no,startT,1500)!=0) {
521 *ptr = _ioClrFlag;
522 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
523 EXI_Deselect(drv_no);
524 EXI_Unlock(drv_no);
525 return CARDIO_ERROR_IOERROR;
527 #ifdef _CARDIO_DEBUG
528 kprintf("sd response3: %02x\n",((u8*)buf)[0]);
529 #endif
530 if(*ptr&0x80) ret = CARDIO_ERROR_IOTIMEOUT;
531 break;
535 tmp = *ptr;
536 while(*ptr!=0xff) {
537 *ptr = _ioClrFlag;
538 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
539 EXI_Deselect(drv_no);
540 EXI_Unlock(drv_no);
541 return CARDIO_ERROR_IOERROR;
543 #ifdef _CARDIO_DEBUG
544 kprintf("sd response4: %02x\n",((u8*)buf)[0]);
545 #endif
546 if(*ptr==0xff) break;
547 if(__card_checktimeout(drv_no,startT,1500)!=0) {
548 *ptr = _ioClrFlag;
549 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
550 EXI_Deselect(drv_no);
551 EXI_Unlock(drv_no);
552 return CARDIO_ERROR_IOERROR;
554 #ifdef _CARDIO_DEBUG
555 kprintf("sd response5: %02x\n",((u8*)buf)[0]);
556 #endif
557 if(*ptr!=0xff) ret = CARDIO_ERROR_IOTIMEOUT;
558 break;
561 *ptr = tmp;
563 if(len>1 && ret==CARDIO_ERROR_READY) {
564 *(++ptr) = _ioClrFlag;
565 if(EXI_ImmEx(drv_no,ptr,len-1,EXI_READWRITE)==0) ret = CARDIO_ERROR_IOERROR;
568 EXI_Deselect(drv_no);
569 EXI_Unlock(drv_no);
570 return ret;
573 static s32 __card_datares(s32 drv_no,void *buf)
575 u8 *ptr;
576 s32 startT,ret;
578 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
580 ptr = buf;
582 __exi_wait(drv_no);
584 if(EXI_Select(drv_no,EXI_DEVICE_0,_ioCardFreq)==0) {
585 EXI_Unlock(drv_no);
586 return CARDIO_ERROR_NOCARD;
589 ret = CARDIO_ERROR_READY;
590 *ptr = _ioClrFlag;
591 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
592 EXI_Deselect(drv_no);
593 EXI_Unlock(drv_no);
594 return CARDIO_ERROR_IOERROR;
596 #ifdef _CARDIO_DEBUG
597 printf("sd response: %02x\n",((u8*)buf)[0]);
598 #endif
599 startT = gettick();
600 while(*ptr&0x10) {
601 *ptr = _ioClrFlag;
602 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
603 EXI_Deselect(drv_no);
604 EXI_Unlock(drv_no);
605 return CARDIO_ERROR_IOERROR;
607 #ifdef _CARDIO_DEBUG
608 printf("sd response: %02x\n",((u8*)buf)[0]);
609 #endif
610 if(!(*ptr&0x10)) break;
611 if(__card_checktimeout(drv_no,startT,1500)!=0) {
612 *ptr = _ioClrFlag;
613 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
614 EXI_Deselect(drv_no);
615 EXI_Unlock(drv_no);
616 return CARDIO_ERROR_IOERROR;
618 #ifdef _CARDIO_DEBUG
619 printf("sd response: %02x\n",((u8*)buf)[0]);
620 #endif
621 if(*ptr&0x10) ret = CARDIO_ERROR_IOTIMEOUT;
622 break;
626 *(++ptr) = _ioClrFlag;
627 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
628 EXI_Deselect(drv_no);
629 EXI_Unlock(drv_no);
630 return CARDIO_ERROR_IOERROR;
633 startT = gettick();
634 while(!*ptr) {
635 *ptr = _ioClrFlag;
636 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
637 EXI_Deselect(drv_no);
638 EXI_Unlock(drv_no);
639 return CARDIO_ERROR_IOERROR;
641 #ifdef _CARDIO_DEBUG
642 printf("sd response: %02x\n",((u8*)buf)[0]);
643 #endif
644 if(*ptr) break;
645 if(__card_checktimeout(drv_no,startT,1500)!=0) {
646 *ptr = _ioClrFlag;
647 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
648 EXI_Deselect(drv_no);
649 EXI_Unlock(drv_no);
650 return CARDIO_ERROR_IOERROR;
652 #ifdef _CARDIO_DEBUG
653 printf("sd response: %02x\n",((u8*)buf)[0]);
654 #endif
655 if(!*ptr) ret = CARDIO_ERROR_IOTIMEOUT;
656 break;
659 EXI_Deselect(drv_no);
660 EXI_Unlock(drv_no);
662 return ret;
665 static s32 __card_stopresponse(s32 drv_no)
667 s32 ret;
669 if((ret=__card_stopreadresponse(drv_no,_ioResponse[drv_no],1))!=0) return ret;
670 ret = __check_response(drv_no,_ioResponse[drv_no][0]);
672 return ret;
675 static s32 __card_dataresponse(s32 drv_no)
677 s32 ret;
678 u8 res;
680 if((ret=__card_datares(drv_no,_ioResponse[drv_no]))!=0) return ret;
681 res = _SHIFTR(_ioResponse[drv_no][0],1,3);
682 if(res==0x0005) ret = CARDIO_OP_IOERR_CRC;
683 else if(res==0x0006) ret = CARDIO_OP_IOERR_WRITE;
685 return ret;
688 static s32 __card_dataread(s32 drv_no,void *buf,u32 len)
690 u8 *ptr;
691 u32 cnt;
692 u8 res[2];
693 u16 crc,crc_org;
694 s32 startT,ret;
696 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
698 __exi_wait(drv_no);
700 if(EXI_Select(drv_no,EXI_DEVICE_0,_ioCardFreq)==0) {
701 EXI_Unlock(drv_no);
702 return CARDIO_ERROR_NOCARD;
705 ret = CARDIO_ERROR_READY;
706 ptr = buf;
707 for(cnt=0;cnt<len;cnt++) ptr[cnt] = _ioClrFlag;
708 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
709 EXI_Deselect(drv_no);
710 EXI_Unlock(drv_no);
711 return CARDIO_ERROR_IOERROR;
713 #ifdef _CARDIO_DEBUG
714 printf("sd response: %02x\n",((u8*)buf)[0]);
715 #endif
717 startT = gettick();
718 while(*ptr!=0xfe) {
719 *ptr = _ioClrFlag;
720 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
721 EXI_Deselect(drv_no);
722 EXI_Unlock(drv_no);
723 return CARDIO_ERROR_IOERROR;
725 #ifdef _CARDIO_DEBUG
726 printf("sd response: %02x\n",((u8*)buf)[0]);
727 #endif
728 if(*ptr==0xfe) break;
729 if(__card_checktimeout(drv_no,startT,1500)!=0) {
730 *ptr = _ioClrFlag;
731 if(EXI_ImmEx(drv_no,ptr,1,EXI_READWRITE)==0) {
732 EXI_Deselect(drv_no);
733 EXI_Unlock(drv_no);
734 return CARDIO_ERROR_IOERROR;
736 #ifdef _CARDIO_DEBUG
737 printf("sd response: %02x\n",((u8*)buf)[0]);
738 #endif
739 if(*ptr!=0xfe) ret = CARDIO_ERROR_IOTIMEOUT;
740 break;
744 *ptr = _ioClrFlag;
745 if(EXI_ImmEx(drv_no,ptr,len,EXI_READWRITE)==0) {
746 EXI_Deselect(drv_no);
747 EXI_Unlock(drv_no);
748 return CARDIO_ERROR_IOERROR;
751 /* sleep 1us*/
752 usleep(1);
754 res[0] = res[1] = _ioClrFlag;
755 if(EXI_ImmEx(drv_no,res,2,EXI_READWRITE)==0) {
756 EXI_Deselect(drv_no);
757 EXI_Unlock(drv_no);
758 return CARDIO_ERROR_IOERROR;
760 #ifdef _CARDIO_DEBUG
761 printf("sd response: %04x\n",*(u16*)res);
762 #endif
763 crc_org = ((res[0]<<8)&0xff00)|(res[1]&0xff);
765 EXI_Deselect(drv_no);
766 EXI_Unlock(drv_no);
768 crc = __make_crc16(buf,len);
769 if(crc!=crc_org) ret = CARDIO_OP_IOERR_CRC;
770 #ifdef _CARDIO_DEBUG
771 printf("crc ok: %04x : %04x\n",crc_org,crc);
772 #endif
773 return ret;
776 static s32 __card_multidatawrite(s32 drv_no,void *buf,u32 len)
778 u8 dummy[32];
779 u16 crc;
780 u32 cnt;
781 s32 ret;
783 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
785 for(cnt=0;cnt<32;cnt++) dummy[cnt] = _ioClrFlag;
786 crc = __make_crc16(buf,len);
788 __exi_wait(drv_no);
790 if(EXI_Select(drv_no,EXI_DEVICE_0,_ioCardFreq)==0) {
791 EXI_Unlock(drv_no);
792 return CARDIO_ERROR_NOCARD;
795 dummy[0] = 0xfc;
796 if(EXI_ImmEx(drv_no,dummy,1,EXI_WRITE)==0) {
797 EXI_Deselect(drv_no);
798 EXI_Unlock(drv_no);
799 return CARDIO_ERROR_IOERROR;
802 if(EXI_ImmEx(drv_no,buf,len,EXI_WRITE)==0) {
803 EXI_Deselect(drv_no);
804 EXI_Unlock(drv_no);
805 return CARDIO_ERROR_IOERROR;
808 /* sleep 1us*/
809 usleep(1);
811 ret = CARDIO_ERROR_READY;
812 if(EXI_ImmEx(drv_no,&crc,2,EXI_WRITE)==0) ret = CARDIO_ERROR_IOERROR;
814 EXI_Deselect(drv_no);
815 EXI_Unlock(drv_no);
817 return ret;
820 static s32 __card_multiwritestop(s32 drv_no)
822 s32 ret,cnt,startT;
823 u8 dummy[32];
825 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
827 for(cnt=0;cnt<32;cnt++) dummy[cnt] = _ioClrFlag;
829 __exi_wait(drv_no);
831 if(EXI_Select(drv_no,EXI_DEVICE_0,_ioCardFreq)==0) {
832 EXI_Unlock(drv_no);
833 return CARDIO_ERROR_NOCARD;
836 ret = CARDIO_ERROR_READY;
837 dummy[0] = 0xfd;
838 if(_ioWPFlag) dummy[0] = 0x02; //!0xfd
839 if(EXI_ImmEx(drv_no,dummy,1,EXI_WRITE)==0) {
840 EXI_Deselect(drv_no);
841 EXI_Unlock(drv_no);
842 return CARDIO_ERROR_IOERROR;
845 dummy[0] = _ioClrFlag;
846 if(EXI_ImmEx(drv_no,dummy,1,EXI_READWRITE)==0) {
847 EXI_Deselect(drv_no);
848 EXI_Unlock(drv_no);
849 return CARDIO_ERROR_IOERROR;
852 dummy[0] = _ioClrFlag;
853 if(EXI_ImmEx(drv_no,dummy,1,EXI_READWRITE)==0) {
854 EXI_Deselect(drv_no);
855 EXI_Unlock(drv_no);
856 return CARDIO_ERROR_IOERROR;
859 dummy[0] = _ioClrFlag;
860 if(EXI_ImmEx(drv_no,dummy,1,EXI_READWRITE)==0) {
861 EXI_Deselect(drv_no);
862 EXI_Unlock(drv_no);
863 return CARDIO_ERROR_IOERROR;
866 dummy[0] = _ioClrFlag;
867 if(EXI_ImmEx(drv_no,dummy,1,EXI_READWRITE)==0) {
868 EXI_Deselect(drv_no);
869 EXI_Unlock(drv_no);
870 return CARDIO_ERROR_IOERROR;
873 startT = gettick();
874 ret = CARDIO_ERROR_READY;
875 while(dummy[0]==0) {
876 dummy[0] = _ioClrFlag;
877 if(EXI_ImmEx(drv_no,dummy,1,EXI_READWRITE)==0) {
878 EXI_Deselect(drv_no);
879 EXI_Unlock(drv_no);
880 return CARDIO_ERROR_IOERROR;
882 if(dummy[0]) break;
883 if(__card_checktimeout(drv_no,startT,1500)!=0) {
884 dummy[0] = _ioClrFlag;
885 if(EXI_ImmEx(drv_no,dummy,1,EXI_READWRITE)==0) {
886 EXI_Deselect(drv_no);
887 EXI_Unlock(drv_no);
888 return CARDIO_ERROR_IOERROR;
890 if(!dummy[0]) ret = CARDIO_ERROR_IOTIMEOUT;
891 break;
895 EXI_Deselect(drv_no);
896 EXI_Unlock(drv_no);
897 return ret;
900 static s32 __card_response1(s32 drv_no)
902 s32 ret;
904 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
906 if((ret=__card_readresponse(drv_no,_ioResponse[drv_no],1))!=0) return ret;
907 return __check_response(drv_no,_ioResponse[drv_no][0]);
910 static s32 __card_response2(s32 drv_no)
912 u32 ret;
914 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
916 if((ret=__card_readresponse(drv_no,_ioResponse[drv_no],2))!=0) return ret;
917 if(!(_ioResponse[drv_no][0]&0x7c) && !(_ioResponse[drv_no][1]&0x9e)) return CARDIO_ERROR_READY;
918 return CARDIO_ERROR_FATALERROR;
921 static s32 __card_sendappcmd(s32 drv_no)
923 s32 ret;
924 u8 ccmd[5] = {0,0,0,0,0};
926 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
928 ccmd[0] = 0x37;
929 if((ret=__card_writecmd(drv_no,ccmd,5))!=0) {
930 #ifdef _CARDIO_DEBUG
931 printf("__card_sendappcmd(%d): sd write cmd failed.\n",ret);
932 #endif
933 return ret;
935 if((ret=__card_readresponse(drv_no,_ioResponse[drv_no],1))!=0) return ret;
936 ret = __check_response(drv_no,_ioResponse[drv_no][0]);
938 return ret;
941 static s32 __card_sendopcond(s32 drv_no)
943 u8 ccmd[5] = {0,0,0,0,0};
944 s32 ret;
945 s32 startT;
947 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
948 #ifdef _CARDIO_DEBUG
949 printf("__card_sendopcond(%d)\n",drv_no);
950 #endif
951 ret = 0;
952 startT = gettick();
953 do {
954 if(_initType[drv_no]==TYPE_SDHC) {
955 __card_sendappcmd(drv_no);
956 ccmd[0] = 0x29;
957 ccmd[1] = 0x40;
958 } else
959 ccmd[0] = 0x01;
961 if((ret=__card_writecmd(drv_no,ccmd,5))!=0) {
962 #ifdef _CARDIO_DEBUG
963 printf("__card_sendopcond(%d): sd write cmd failed.\n",ret);
964 #endif
965 return ret;
967 if((ret=__card_readresponse(drv_no,_ioResponse[drv_no],1))!=0) return ret;
968 if((ret=__check_response(drv_no,_ioResponse[drv_no][0]))!=0) return ret;
969 if(!(_ioError[drv_no]&CARDIO_OP_IOERR_IDLE)) return CARDIO_ERROR_READY;
971 ret = __card_checktimeout(drv_no,startT,1500);
972 } while(ret==0);
974 if(_initType[drv_no]==TYPE_SDHC) {
975 __card_sendappcmd(drv_no);
976 ccmd[0] = 0x29;
977 ccmd[1] = 0x40;
978 } else
979 ccmd[0] = 0x01;
981 if((ret=__card_writecmd(drv_no,ccmd,5))!=0) {
982 #ifdef _CARDIO_DEBUG
983 printf("__card_sendopcond(%d): sd write cmd failed.\n",ret);
984 #endif
985 return ret;
987 if((ret=__card_readresponse(drv_no,_ioResponse[drv_no],1))!=0) return ret;
988 if((ret=__check_response(drv_no,_ioResponse[drv_no][0]))!=0) return ret;
989 if(_ioError[drv_no]&CARDIO_OP_IOERR_IDLE) return CARDIO_ERROR_IOERROR;
991 return CARDIO_ERROR_READY;
994 static s32 __card_sendCMD8(s32 drv_no)
996 s32 ret;
997 u8 ccmd[5] = {0,0,0,0,0};
999 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
1001 ccmd[0] = 0x08;
1002 ccmd[3] = 0x01;
1003 ccmd[4] = 0xAA;
1004 if((ret=__card_writecmd(drv_no,ccmd,5))!=0){
1005 #ifdef _CARDIO_DEBUG
1006 printf("__card_sendCMD8(%d): sd write cmd failed.\n",ret);
1007 #endif
1008 return ret;
1010 if((ret=__card_readresponse(drv_no,_ioResponse[drv_no],5))!=0) return ret;
1011 ret = __check_response(drv_no,_ioResponse[drv_no][0]);
1013 return ret;
1016 static s32 __card_sendCMD58(s32 drv_no)
1018 s32 ret;
1019 u8 ccmd[5] = {0,0,0,0,0};
1021 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
1023 ccmd[0]= 0x3A;
1024 if((ret=__card_writecmd(drv_no,ccmd,5))!=0) {
1025 #ifdef _CARDIO_DEBUG
1026 printf("__card_sendCMD58(%d): sd write cmd failed.\n",ret);
1027 #endif
1028 return ret;
1030 if((ret=__card_readresponse(drv_no,_ioResponse[drv_no],5))!=0) return ret;
1031 ret = __check_response(drv_no,_ioResponse[drv_no][0]);
1033 return ret;
1036 static s32 __card_sendcmd(s32 drv_no,u8 cmd,u8 *arg)
1038 u8 ccmd[5] = {0,0,0,0,0};
1040 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
1042 ccmd[0] = cmd;
1043 if(arg) {
1044 ccmd[1] = arg[0];
1045 ccmd[2] = arg[1];
1046 ccmd[3] = arg[2];
1047 ccmd[4] = arg[3];
1049 return __card_writecmd(drv_no,ccmd,5);
1052 static s32 __card_setblocklen(s32 drv_no,u32 block_len)
1054 u8 cmd[5];
1055 s32 ret;
1057 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
1058 #ifdef _CARDIO_DEBUG
1059 printf("__card_setblocklen(%d,%d)\n",drv_no,block_len);
1060 #endif
1061 if(block_len>PAGE_SIZE512) block_len = PAGE_SIZE512;
1063 cmd[0] = 0x10;
1064 cmd[1] = (block_len>>24)&0xff;
1065 cmd[2] = (block_len>>16)&0xff;
1066 cmd[3] = (block_len>>8)&0xff;
1067 cmd[4] = block_len&0xff;
1068 if((ret=__card_writecmd(drv_no,cmd,5))!=0) {
1069 #ifdef _CARDIO_DEBUG
1070 printf("__card_setblocklen(%d): sd write cmd failed.\n",ret);
1071 #endif
1072 return ret;
1074 if((ret=__card_readresponse(drv_no,_ioResponse[drv_no],1))<0) return ret;
1075 ret = __check_response(drv_no,_ioResponse[drv_no][0]);
1077 return ret;
1080 static s32 __card_readcsd(s32 drv_no)
1082 u8 ccmd[5] = {0,0,0,0,0};
1083 s32 ret;
1085 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
1086 #ifdef _CARDIO_DEBUG
1087 printf("__card_readcsd(%d)\n",drv_no);
1088 #endif
1089 ret = 0;
1090 ccmd[0] = 0x09;
1091 if((ret=__card_writecmd(drv_no,ccmd,5))!=0) {
1092 #ifdef _CARDIO_DEBUG
1093 printf("__card_readcsd(%d): sd write cmd failed.\n",ret);
1094 #endif
1095 return ret;
1097 if((ret=__card_readresponse(drv_no,_ioResponse[drv_no],1))!=0) return ret;
1098 ret = __check_response(drv_no,_ioResponse[drv_no][0]);
1099 if(ret==0) {
1100 if((ret=__card_dataread(drv_no,g_CSD[drv_no],16))!=0) return ret;
1102 return ret;
1105 static s32 __card_readcid(s32 drv_no)
1107 u8 ccmd[5] = {0,0,0,0,0};
1108 s32 ret;
1110 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
1111 #ifdef _CARDIO_DEBUG
1112 printf("__card_readcid(%d)\n",drv_no);
1113 #endif
1114 ret = 0;
1115 ccmd[0] = 0x0A;
1116 if((ret=__card_writecmd(drv_no,ccmd,5))!=0) {
1117 #ifdef _CARDIO_DEBUG
1118 printf("__card_readcid(%d): sd write cmd failed.\n",ret);
1119 #endif
1120 return ret;
1122 if((ret=__card_readresponse(drv_no,_ioResponse[drv_no],1))!=0) return ret;
1123 ret = __check_response(drv_no,_ioResponse[drv_no][0]);
1124 if(ret==0) {
1125 if((ret=__card_dataread(drv_no,g_CID[drv_no],16))!=0) return ret;
1127 return ret;
1130 static s32 __card_sd_status(s32 drv_no)
1132 s32 ret;
1134 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
1135 #ifdef _CARDIO_DEBUG
1136 printf("__card_sd_status(%d)\n",drv_no);
1137 #endif
1138 if(_ioPageSize[drv_no]!=64) {
1139 _ioPageSize[drv_no] = 64;
1140 if((ret=__card_setblocklen(drv_no,_ioPageSize[drv_no]))!=0) return ret;
1142 if((ret=__card_sendappcmd(drv_no))!=0) return ret;
1143 if((ret=__card_sendcmd(drv_no,0x0d,NULL))!=0) return ret;
1144 if((ret=__card_response2(drv_no))!=0) return ret;
1145 ret = __card_dataread(drv_no,g_CardStatus[drv_no],64);
1147 return ret;
1150 static s32 __card_softreset(s32 drv_no)
1152 s32 ret;
1154 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
1155 #ifdef _CARDIO_DEBUG
1156 printf("__card_softreset(%d)\n",drv_no);
1157 #endif
1158 ret = 0;
1159 if((ret=__card_writecmd0(drv_no))!=0) {
1160 #ifdef _CARDIO_DEBUG
1161 printf("__card_softreset(%d): sd write cmd0 failed.\n",ret);
1162 #endif
1163 return ret;
1166 if((ret=__card_readresponse(drv_no,_ioResponse[drv_no],1))!=0) return ret;
1167 return __check_response(drv_no,_ioResponse[drv_no][0]);
1170 static bool __card_check(s32 drv_no)
1172 s32 ret;
1174 if(drv_no<0 || drv_no>=MAX_DRIVE) return FALSE;
1175 #ifdef _CARDIO_DEBUG
1176 printf("__card_check(%d)\n",drv_no);
1177 #endif
1178 while((ret=EXI_ProbeEx(drv_no))==0);
1179 if(ret!=1) return FALSE;
1181 if(!(EXI_GetState(drv_no)&EXI_FLAG_ATTACH)) {
1182 if(EXI_Attach(drv_no,__card_exthandler)==0) return FALSE;
1183 #ifdef _CARDIO_DEBUG
1184 printf("__card_check(%d, attached)\n",drv_no);
1185 #endif
1186 sdgecko_insertedCB(drv_no);
1188 return TRUE;
1191 static s32 __card_retrycb(s32 drv_no)
1193 #ifdef _CARDIO_DEBUG
1194 printf("__card_retrycb(%d)\n",drv_no);
1195 #endif
1196 _ioRetryCB = NULL;
1197 _ioRetryCnt++;
1198 return sdgecko_initIO(drv_no);
1201 static void __convert_sector(s32 drv_no,u32 sector_no,u8 *arg)
1203 if(_ioAddressingType[drv_no]==BYTE_ADDRESSING) {
1204 arg[0] = (sector_no>>15)&0xff;
1205 arg[1] = (sector_no>>7)&0xff;
1206 arg[2] = (sector_no<<1)&0xff;
1207 arg[3] = (sector_no<<9)&0xff;
1208 } else if(_ioAddressingType[drv_no]==SECTOR_ADDRESSING) {
1209 arg[0] = (sector_no>>24)&0xff;
1210 arg[1] = (sector_no>>16)&0xff;
1211 arg[2] = (sector_no>>8)&0xff;
1212 arg[3] = sector_no&0xff;
1216 void sdgecko_initIODefault()
1218 u32 i;
1219 #ifdef _CARDIO_DEBUG
1220 printf("card_initIODefault()\n");
1221 #endif
1222 __init_crc7();
1223 __init_crc16();
1224 for(i=0;i<MAX_DRIVE;++i) {
1225 _ioRetryCnt = 0;
1226 _ioError[i] = 0;
1227 _ioCardInserted[i] = FALSE;
1228 _ioFlag[i] = NOT_INITIALIZED;
1229 _ioAddressingType[i] = BYTE_ADDRESSING;
1230 _initType[i] = TYPE_SD;
1231 LWP_InitQueue(&_ioEXILock[i]);
1235 s32 sdgecko_initIO(s32 drv_no)
1237 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
1239 u32 id = 0;
1240 EXI_GetID(drv_no,EXI_DEVICE_0,&id);
1241 if ( id != -1 ) return CARDIO_ERROR_NOCARD;
1243 if(_ioRetryCnt>5) {
1244 _ioRetryCnt = 0;
1245 return CARDIO_ERROR_IOERROR;
1248 _ioCardInserted[drv_no] = __card_check(drv_no);
1250 if(_ioCardInserted[drv_no]==TRUE) {
1251 _ioWPFlag = 0;
1252 _ioCardFreq = EXI_SPEED16MHZ;
1253 _initType[drv_no] = TYPE_SD;
1254 _ioFlag[drv_no] = INITIALIZING;
1255 _ioAddressingType[drv_no] = BYTE_ADDRESSING;
1256 if(__card_softreset(drv_no)!=0) {
1257 _ioWPFlag = 1;
1258 if(__card_softreset(drv_no)!=0) goto exit;
1261 if(__card_sendCMD8(drv_no)!=0) goto exit;
1262 #ifdef _CARDIO_DEBUG
1263 printf("Response %02X,%02X,%02X,%02X,%02X\n",_ioResponse[drv_no][0],_ioResponse[drv_no][1],_ioResponse[drv_no][2],_ioResponse[drv_no][3],_ioResponse[drv_no][4]);
1264 #endif
1265 if((_ioResponse[drv_no][3]==1) && (_ioResponse[drv_no][4]==0xAA)) _initType[drv_no] = TYPE_SDHC;
1267 if(__card_sendopcond(drv_no)!=0) goto exit;
1268 if(__card_readcsd(drv_no)!=0) goto exit;
1269 if(__card_readcid(drv_no)!=0) goto exit;
1271 if(_initType[drv_no]==TYPE_SDHC) {
1272 if(__card_sendCMD58(drv_no)!=0) goto exit;
1273 #ifdef _CARDIO_DEBUG
1274 printf("Response %02X,%02X,%02X,%02X,%02X\n",_ioResponse[drv_no][0],_ioResponse[drv_no][1],_ioResponse[drv_no][2],_ioResponse[drv_no][3],_ioResponse[drv_no][4]);
1275 #endif
1276 if(_ioResponse[drv_no][1]&0x40) _ioAddressingType[drv_no] = SECTOR_ADDRESSING;
1279 _ioPageSize[drv_no] = 1<<WRITE_BL_LEN(drv_no);
1280 if(__card_setblocklen(drv_no,_ioPageSize[drv_no])!=0) goto exit;
1282 if(__card_sd_status(drv_no)!=0) goto exit;
1284 _ioRetryCnt = 0;
1285 _ioFlag[drv_no] = INITIALIZED;
1286 return CARDIO_ERROR_READY;
1287 exit:
1288 _ioRetryCB = __card_retrycb;
1289 return sdgecko_doUnmount(drv_no);
1291 return CARDIO_ERROR_NOCARD;
1294 s32 sdgecko_preIO(s32 drv_no)
1296 s32 ret;
1298 if(_ioFlag[drv_no]!=INITIALIZED) {
1299 ret = sdgecko_initIO(drv_no);
1300 if(ret!=CARDIO_ERROR_READY) {
1301 #ifdef _CARDIO_DEBUG
1302 printf("sdgecko_preIO(%d,ret = %d)\n",drv_no,ret);
1303 #endif
1304 return ret;
1307 return CARDIO_ERROR_READY;
1310 s32 sdgecko_readCID(s32 drv_no)
1312 s32 ret;
1314 if(drv_no<EXI_CHANNEL_0 || drv_no>=EXI_CHANNEL_2) return CARDIO_ERROR_NOCARD;
1315 #ifdef _CARDIO_DEBUG
1316 printf("sdgecko_readCID(%d)\n",drv_no);
1317 #endif
1318 ret = sdgecko_preIO(drv_no);
1319 if(ret!=0) return ret;
1321 return __card_readcid(drv_no);
1324 s32 sdgecko_readCSD(s32 drv_no)
1326 s32 ret;
1328 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
1329 #ifdef _CARDIO_DEBUG
1330 printf("sdgecko_readCSD(%d)\n",drv_no);
1331 #endif
1332 ret = sdgecko_preIO(drv_no);
1333 if(ret!=0) return ret;
1335 return __card_readcsd(drv_no);
1338 s32 sdgecko_readStatus(s32 drv_no)
1340 s32 ret;
1342 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
1343 #ifdef _CARDIO_DEBUG
1344 printf("sdgecko_readCSD(%d)\n",drv_no);
1345 #endif
1346 ret = sdgecko_preIO(drv_no);
1347 if(ret!=0) return ret;
1349 return __card_sd_status(drv_no);
1352 // Multiple sector read by emu_kidid
1353 s32 sdgecko_readSectors(s32 drv_no,u32 sector_no,u32 num_sectors,void *buf)
1355 u32 i;
1356 s32 ret;
1357 u8 arg[4];
1358 char *ptr = (char*)buf;
1360 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
1362 ret = sdgecko_preIO(drv_no);
1363 if(ret!=0) return ret;
1365 if(num_sectors<1) return CARDIO_ERROR_INTERNAL;
1367 #ifdef _CARDIO_DEBUG
1368 kprintf("sdgecko_readSectors(%d,%d,%d,%d)\n",drv_no,sector_no,num_sectors,_ioPageSize[drv_no]);
1369 #endif
1371 // Must be 512b, otherwise fail!
1372 if(PAGE_SIZE512!=_ioPageSize[drv_no]) {
1373 _ioPageSize[drv_no] = PAGE_SIZE512;
1374 if((ret=__card_setblocklen(drv_no,PAGE_SIZE512))!=0) return ret;
1377 // SDHC support fix
1378 __convert_sector(drv_no,sector_no,arg);
1380 if((ret=__card_sendcmd(drv_no,0x12,arg))!=0) return ret;
1381 if((ret=__card_response1(drv_no))!=0) return ret;
1383 for(i=0;i<num_sectors;i++) {
1384 if((ret=__card_dataread(drv_no,ptr,_ioPageSize[drv_no]))!=0) return ret;
1385 ptr += _ioPageSize[drv_no];
1388 if((ret=__card_sendcmd(drv_no,0x0C,NULL))!=0) return ret;
1389 return __card_stopresponse(drv_no);
1392 s32 sdgecko_writeSectors(s32 drv_no,u32 sector_no,u32 num_sectors,const void *buf)
1394 u32 i;
1395 s32 ret;
1396 u8 arg[4];
1397 char *ptr = (char*)buf;
1399 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
1401 ret = sdgecko_preIO(drv_no);
1402 if(ret!=0) return ret;
1404 if(num_sectors<1) return CARDIO_ERROR_INTERNAL;
1406 #ifdef _CARDIO_DEBUG
1407 printf("sdgecko_writeSectors(%d,%d,%d,%d)\n",drv_no,sector_no,num_sectors,_ioPageSize[drv_no]);
1408 #endif
1410 if(PAGE_SIZE512!=_ioPageSize[drv_no]) {
1411 _ioPageSize[drv_no] = PAGE_SIZE512;
1412 if((ret=__card_setblocklen(drv_no,_ioPageSize[drv_no]))!=0) return ret;
1415 // send SET_WRITE_BLK_ERASE_CNT cmd
1416 arg[0] = (num_sectors>>24)&0xff;
1417 arg[1] = (num_sectors>>16)&0xff;
1418 arg[2] = (num_sectors>>8)&0xff;
1419 arg[3] = num_sectors&0xff;
1420 if((ret=__card_sendappcmd(drv_no))!=0) return ret;
1421 if((ret=__card_sendcmd(drv_no,0x17,arg))!=0) return ret;
1422 if((ret=__card_response1(drv_no))!=0) return ret;
1424 // SDHC support fix
1425 __convert_sector(drv_no,sector_no,arg);
1427 if((ret=__card_sendcmd(drv_no,0x19,arg))!=0) return ret;
1428 if((ret=__card_response1(drv_no))!=0) return ret;
1430 for(i=0;i<num_sectors;i++) {
1431 if((ret=__card_multidatawrite(drv_no,ptr,_ioPageSize[drv_no]))!=0) return ret;
1432 if((ret=__card_dataresponse(drv_no))!=0) {
1433 if((ret=__card_sendcmd(drv_no,0x0C,arg))!=0) return ret;
1434 return __card_stopresponse(drv_no);
1436 ptr += _ioPageSize[drv_no];
1439 if((ret=__card_multiwritestop(drv_no))!=0) return ret;
1440 if((ret=__card_sendcmd(drv_no,0x0D,NULL))!=0) return ret;
1441 return __card_response2(drv_no);
1444 s32 sdgecko_doUnmount(s32 drv_no)
1446 s32 ret;
1448 if(drv_no<0 || drv_no>=MAX_DRIVE) return CARDIO_ERROR_NOCARD;
1450 if(__card_check(drv_no)==TRUE && _ioFlag[drv_no]!=NOT_INITIALIZED) {
1451 if((ret=__card_sendappcmd(drv_no))!=0) goto exit;
1452 if((ret=__card_sendcmd(drv_no,0x2a,NULL))!=0) goto exit;
1453 ret = __card_response1(drv_no);
1454 #ifdef _CARDIO_DEBUG
1455 printf("sdgecko_doUnmount(%d) disconnected 50KOhm pull-up(%d)\n",drv_no,ret);
1456 #endif
1458 _ioFlag[drv_no] = NOT_INITIALIZED;
1460 exit:
1461 if(_ioCardInserted[drv_no]==TRUE) {
1462 _ioCardInserted[drv_no] = FALSE;
1463 EXI_Detach(drv_no);
1465 if(_ioRetryCB)
1466 return _ioRetryCB(drv_no);
1468 return CARDIO_ERROR_READY;
1471 static void (*pfCallbackIN[MAX_DRIVE])(s32) = {NULL, NULL};
1472 static void (*pfCallbackOUT[MAX_DRIVE])(s32) = {NULL, NULL};
1474 void sdgecko_insertedCB(s32 drv_no)
1476 if(pfCallbackIN[drv_no])
1477 pfCallbackIN[drv_no](drv_no);
1480 void sdgecko_ejectedCB(s32 drv_no)
1482 if(pfCallbackOUT[drv_no])
1483 pfCallbackOUT[drv_no](drv_no);
1486 void sdgecko_setSpeed(u32 freq)
1488 _ioCardFreq = freq;
1491 u32 sdgecko_getPageSize(s32 drv_no)
1493 return _ioPageSize[drv_no];
1496 u32 sdgecko_setPageSize(s32 drv_no, int size)
1498 if(_ioPageSize[drv_no]!=size)
1499 _ioPageSize[drv_no] = size;
1501 return __card_setblocklen(drv_no, _ioPageSize[drv_no]);
1504 u32 sdgecko_getAddressingType(s32 drv_no)
1506 return _ioAddressingType[drv_no];