w.i.p sdcard device driver for raspi. detects cards but isnt able to send commands...
[AROS.git] / arch / arm-raspi / devs / sdcard / sdcard_device.c
blobe30777f66ee3d6b30559eb5b02a3c941fa566e87
1 /*
2 Copyright © 2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 1
7 #include <aros/debug.h>
9 #include <exec/types.h>
10 #include <exec/exec.h>
11 #include <exec/resident.h>
12 #include <utility/utility.h>
13 #include <utility/tagitem.h>
14 #include <oop/oop.h>
15 #include "timer.h"
17 #include <dos/bptr.h>
19 #include <proto/exec.h>
20 #include <proto/oop.h>
22 #include "sdcard_intern.h"
23 #include LC_LIBDEFS_FILE
25 //---------------------------IO Commands---------------------------------------
27 /* Invalid comand does nothing, complains only. */
28 static void cmd_Invalid(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
30 D(bug("[SDCard%02ld] %s: %d\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__, io->io_Command));
31 io->io_Error = IOERR_NOCMD;
34 /* Don't need to reset the drive? */
35 static void cmd_Reset(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
37 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
38 IOStdReq(io)->io_Actual = 0;
41 /* CMD_READ implementation */
42 static void cmd_Read32(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
44 struct sdcard_Unit *unit = (struct sdcard_Unit *)IOStdReq(io)->io_Unit;
46 if (!(unit->sdcu_Flags & AF_MediaPresent))
48 D(bug("[SDCard%02ld] %s: Error: No Media present\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
49 io->io_Error = TDERR_DiskChanged;
50 return;
53 ULONG block = IOStdReq(io)->io_Offset;
54 ULONG count = IOStdReq(io)->io_Length;
56 D(bug("[SDCard%02ld] cmd_Read32(%08x, %08x)\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, block, count));
58 ULONG mask = (1 << unit->sdcu_Bus->sdcb_SectorShift) - 1;
61 During this IO call it should be sure that both offset and
62 length are already aligned properly to sector boundaries.
64 if ((block & mask) | (count & mask))
66 D(bug("[SDCard%02ld] cmd_Read32: offset or length not sector-aligned.\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum));
67 cmd_Invalid(io, LIBBASE);
69 else
71 block >>= unit->sdcu_Bus->sdcb_SectorShift;
72 count >>= unit->sdcu_Bus->sdcb_SectorShift;
73 ULONG cnt = 0;
75 if (((block + count) > unit->sdcu_Capacity))
77 bug("[SDCard%02ld] cmd_Read32: Requested block (%lx;%ld) outside disk range (%lx)\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, block, count, unit->sdcu_Capacity);
78 io->io_Error = IOERR_BADADDRESS;
79 return;
82 /* Call the Unit's access funtion */
83 io->io_Error = unit->sdcu_Read32(unit, block, count,
84 IOStdReq(io)->io_Data, &cnt);
86 IOStdReq(io)->io_Actual = cnt;
91 NSCMD_TD_READ64, TD_READ64 implementation. Basically the same, just packs
92 the 64 bit offset in both io_Offset (31:0) and io_Actual (63:32)
94 static void cmd_Read64(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
96 struct sdcard_Unit *unit = (struct sdcard_Unit *)IOStdReq(io)->io_Unit;
98 if (!(unit->sdcu_Flags & AF_MediaPresent))
100 D(bug("[SDCard%02ld] %s: Error: No Media present\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
101 io->io_Error = TDERR_DiskChanged;
102 return;
105 UQUAD block = IOStdReq(io)->io_Offset | (UQUAD)(IOStdReq(io)->io_Actual) << 32;
106 ULONG count = IOStdReq(io)->io_Length;
108 D(bug("[SDCard%02ld] cmd_Read64(%08x-%08x, %08x)\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, IOStdReq(io)->io_Actual, IOStdReq(io)->io_Offset, count));
110 ULONG mask = (1 << unit->sdcu_Bus->sdcb_SectorShift) - 1;
112 if ((block & (UQUAD)mask) | (count & mask) | (count == 0))
114 D(bug("[SDCard%02ld] cmd_Read64: offset or length not sector-aligned.\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum));
115 cmd_Invalid(io, LIBBASE);
117 else
119 block >>= unit->sdcu_Bus->sdcb_SectorShift;
120 count >>= unit->sdcu_Bus->sdcb_SectorShift;
121 ULONG cnt = 0;
124 If the sum of sector offset and the sector count doesn't overflow
125 the 28-bit LBA address, use 32-bit access for speed and simplicity.
126 Otherwise do the 48-bit LBA addressing.
128 if (((block + count) > unit->sdcu_Capacity))
130 bug("[SDCard%02ld] cmd_Read64: Requested block (%lx;%ld) outside disk range (%lx)\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, block, count, unit->sdcu_Capacity);
131 io->io_Error = IOERR_BADADDRESS;
132 return;
134 io->io_Error = unit->sdcu_Read32(unit, (ULONG)(block & 0x0fffffff), count, IOStdReq(io)->io_Data, &cnt);
136 IOStdReq(io)->io_Actual = cnt;
140 /* CMD_WRITE implementation */
141 static void cmd_Write32(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
143 struct sdcard_Unit *unit = (struct sdcard_Unit *)IOStdReq(io)->io_Unit;
145 if (!(unit->sdcu_Flags & AF_MediaPresent))
147 D(bug("[SDCard%02ld] %s: Error: No Media present\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
148 io->io_Error = TDERR_DiskChanged;
149 return;
152 ULONG block = IOStdReq(io)->io_Offset;
153 ULONG count = IOStdReq(io)->io_Length;
155 D(bug("[SDCard%02ld] cmd_Write32(%08x, %08x)\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, block, count));
157 ULONG mask = (1 << unit->sdcu_Bus->sdcb_SectorShift) - 1;
160 During this IO call it should be sure that both offset and
161 length are already aligned properly to sector boundaries.
163 if ((block & mask) | (count & mask))
165 D(bug("[SDCard%02ld] cmd_Write32: offset or length not sector-aligned.\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum));
166 cmd_Invalid(io, LIBBASE);
168 else
170 block >>= unit->sdcu_Bus->sdcb_SectorShift;
171 count >>= unit->sdcu_Bus->sdcb_SectorShift;
172 ULONG cnt = 0;
174 if (((block + count) > unit->sdcu_Capacity))
176 bug("[SDCard%02ld] cmd_Write32: Requested block (%lx;%ld) outside disk range (%lx)\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum,
177 block, count, unit->sdcu_Capacity);
178 io->io_Error = IOERR_BADADDRESS;
179 return;
182 /* Call the Unit's access funtion */
183 io->io_Error = unit->sdcu_Write32(unit, block, count,
184 IOStdReq(io)->io_Data, &cnt);
186 IOStdReq(io)->io_Actual = cnt;
191 NSCMD_TD_WRITE64, TD_WRITE64 implementation. Basically the same, just packs
192 the 64 bit offset in both io_Offset (31:0) and io_Actual (63:32)
194 static void cmd_Write64(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
196 struct sdcard_Unit *unit = (struct sdcard_Unit *)IOStdReq(io)->io_Unit;
198 if (!(unit->sdcu_Flags & AF_MediaPresent))
200 D(bug("[SDCard%02ld] %s: Error: No Media present\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
201 io->io_Error = TDERR_DiskChanged;
202 return;
205 UQUAD block = IOStdReq(io)->io_Offset | (UQUAD)(IOStdReq(io)->io_Actual) << 32;
206 ULONG count = IOStdReq(io)->io_Length;
208 D(bug("[SDCard%02ld] cmd_Write64(%08x-%08x, %08x)\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, IOStdReq(io)->io_Actual, IOStdReq(io)->io_Offset, count));
210 ULONG mask = (1 << unit->sdcu_Bus->sdcb_SectorShift) - 1;
212 if ((block & mask) | (count & mask) | (count==0))
214 D(bug("[SDCard%02ld] cmd_Write64: offset or length not sector-aligned.\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum));
215 cmd_Invalid(io, LIBBASE);
217 else
219 block >>= unit->sdcu_Bus->sdcb_SectorShift;
220 count >>= unit->sdcu_Bus->sdcb_SectorShift;
221 ULONG cnt = 0;
224 If the sum of sector offset and the sector count doesn't overflow
225 the 28-bit LBA address, use 32-bit access for speed and simplicity.
226 Otherwise do the 48-bit LBA addressing.
228 if (((block + count) > unit->sdcu_Capacity))
230 bug("[SDCard%02ld] cmd_Write64: Requested block (%lx:%08lx;%ld) outside disk "
231 "range (%lx:%08lx)\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum,
232 block>>32, block&0xfffffffful,
233 count, unit->sdcu_Capacity>>32,
234 unit->sdcu_Capacity & 0xfffffffful);
235 io->io_Error = IOERR_BADADDRESS;
236 return;
239 io->io_Error = unit->sdcu_Write64(unit, block, count,
240 IOStdReq(io)->io_Data, &cnt);
242 IOStdReq(io)->io_Actual = cnt;
247 /* use CMD_FLUSH to force all IO waiting commands to abort */
248 static void cmd_Flush(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
250 struct IORequest *msg;
251 D(bug("[SDCard%02ld] cmd_Flush()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum));
253 Forbid();
255 // while((msg = (struct IORequest *)GetMsg((struct MsgPort *)bus->sdb_MsgPort)))
256 // {
257 // msg->io_Error = IOERR_ABORTED;
258 // ReplyMsg((struct Message *)msg);
259 // }
261 Permit();
265 Internal command used to check whether the media in drive has been changed
266 since last call. If so, the handlers given by user are called.
268 static void cmd_TestChanged(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
270 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
271 struct IORequest *msg;
273 D(bug("[SDCard%02ld] cmd_TestChanged()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum));
275 if (unit->sdcu_Flags & AF_MediaChanged)
277 unit->sdcu_ChangeNum++;
279 Forbid();
281 /* old-fashioned RemoveInt call first */
282 if (unit->sdcu_RemoveInt)
283 Cause(unit->sdcu_RemoveInt);
285 /* And now the whole list of possible calls */
286 ForeachNode(&unit->sdcu_SoftList, msg)
288 Cause((struct Interrupt *)IOStdReq(msg)->io_Data);
291 unit->sdcu_Flags &= ~AF_MediaChanged;
293 Permit();
297 static void cmd_Update(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
299 /* Do nothing now. In near future there should be drive cache flush though */
300 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
303 static void cmd_Remove(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
305 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
307 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
309 if (unit->sdcu_RemoveInt)
310 io->io_Error = TDERR_DriveInUse;
311 else
312 unit->sdcu_RemoveInt = IOStdReq(io)->io_Data;
315 static void cmd_ChangeNum(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
317 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
319 IOStdReq(io)->io_Actual = ((struct sdcard_Unit *)io->io_Unit)->sdcu_ChangeNum;
322 static void cmd_ChangeState(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
324 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
326 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
328 if (unit->sdcu_Flags & AF_MediaPresent)
329 IOStdReq(io)->io_Actual = 0;
330 else
331 IOStdReq(io)->io_Actual = 1;
333 D(bug("[SDCard%02ld] cmd_ChangeState: Media %s\n", unit->sdcu_UnitNum, IOStdReq(io)->io_Actual ? "ABSENT" : "PRESENT"));
336 static void cmd_ProtStatus(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
338 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
340 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
342 if (unit->sdcu_DevType)
343 IOStdReq(io)->io_Actual = -1;
344 else
345 IOStdReq(io)->io_Actual = 0;
349 static void cmd_GetNumTracks(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
351 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
353 IOStdReq(io)->io_Actual = ((struct sdcard_Unit *)io->io_Unit)->sdcu_Cylinders;
356 static void cmd_AddChangeInt(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
358 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
360 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
362 Forbid();
363 AddHead(&unit->sdcu_SoftList, (struct Node *)io);
364 Permit();
366 io->io_Flags &= ~IOF_QUICK;
367 unit->sdcu_Unit.unit_flags &= ~UNITF_ACTIVE;
370 static void cmd_RemChangeInt(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
372 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
374 Forbid();
375 Remove((struct Node *)io);
376 Permit();
379 static void cmd_Eject(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
381 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
383 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
385 IOStdReq(io)->io_Error = unit->sdcu_Eject(unit);
386 cmd_TestChanged(io, LIBBASE);
389 static void cmd_GetGeometry(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
391 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
393 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
395 if (IOStdReq(io)->io_Length == sizeof(struct DriveGeometry))
397 struct DriveGeometry *dg = (struct DriveGeometry *)IOStdReq(io)->io_Data;
399 dg->dg_SectorSize = 1 << unit->sdcu_Bus->sdcb_SectorShift;
401 if ((unit->sdcu_Capacity >> 32) != 0)
402 dg->dg_TotalSectors = 0xffffffff;
403 else
404 dg->dg_TotalSectors = unit->sdcu_Capacity;
406 dg->dg_Cylinders = unit->sdcu_Cylinders;
407 dg->dg_CylSectors = unit->sdcu_Sectors * unit->sdcu_Heads;
408 dg->dg_Heads = unit->sdcu_Heads;
409 dg->dg_TrackSectors = unit->sdcu_Sectors;
410 dg->dg_BufMemType = MEMF_PUBLIC;
411 dg->dg_DeviceType = DG_DIRECT_ACCESS;
412 dg->dg_Flags = DGF_REMOVABLE;
413 dg->dg_Reserved = 0;
415 IOStdReq(io)->io_Actual = sizeof(struct DriveGeometry);
417 else io->io_Error = TDERR_NotSpecified;
420 static void cmd_DirectSCSI(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
422 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
424 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
426 IOStdReq(io)->io_Actual = sizeof(struct SCSICmd);
427 io->io_Error = IOERR_BADADDRESS;
430 //-----------------------------------------------------------------------------
433 command translation tables - used to call proper IO functions.
436 #define N_TD_READ64 0
437 #define N_TD_WRITE64 1
438 #define N_TD_SEEK64 2
439 #define N_TD_FORMAT64 3
441 typedef void (*mapfunc)(struct IORequest *, LIBBASETYPEPTR);
443 static mapfunc const map64[]= {
444 [N_TD_READ64] = cmd_Read64,
445 [N_TD_WRITE64] = cmd_Write64,
446 [N_TD_SEEK64] = cmd_Reset,
447 [N_TD_FORMAT64] = cmd_Write64
450 static mapfunc const map32[] = {
451 [CMD_INVALID] = cmd_Invalid,
452 [CMD_RESET] = cmd_Reset,
453 [CMD_READ] = cmd_Read32,
454 [CMD_WRITE] = cmd_Write32,
455 [CMD_UPDATE] = cmd_Update,
456 [CMD_CLEAR] = cmd_Reset,
457 [CMD_STOP] = cmd_Reset,
458 [CMD_START] = cmd_Reset,
459 [CMD_FLUSH] = cmd_Flush,
460 [TD_MOTOR] = cmd_Reset,
461 [TD_SEEK] = cmd_Reset,
462 [TD_FORMAT] = cmd_Write32,
463 [TD_REMOVE] = cmd_Remove,
464 [TD_CHANGENUM] = cmd_ChangeNum,
465 [TD_CHANGESTATE]= cmd_ChangeState,
466 [TD_PROTSTATUS] = cmd_ProtStatus,
467 [TD_RAWREAD] = cmd_Invalid,
468 [TD_RAWWRITE] = cmd_Invalid,
469 [TD_GETNUMTRACKS] = cmd_GetNumTracks,
470 [TD_ADDCHANGEINT] = cmd_AddChangeInt,
471 [TD_REMCHANGEINT] = cmd_RemChangeInt,
472 [TD_GETGEOMETRY]= cmd_GetGeometry,
473 [TD_EJECT] = cmd_Eject,
474 [TD_READ64] = cmd_Read64,
475 [TD_WRITE64] = cmd_Write64,
476 [TD_SEEK64] = cmd_Reset,
477 [TD_FORMAT64] = cmd_Write64,
478 [HD_SCSICMD] = cmd_DirectSCSI,
479 [HD_SCSICMD+1] = cmd_TestChanged,
482 static UWORD const NSDSupported[] = {
483 CMD_RESET,
484 CMD_READ,
485 CMD_WRITE,
486 CMD_UPDATE,
487 CMD_CLEAR,
488 CMD_STOP,
489 CMD_START,
490 CMD_FLUSH,
491 TD_MOTOR,
492 TD_SEEK,
493 TD_FORMAT,
494 TD_REMOVE,
495 TD_CHANGENUM,
496 TD_CHANGESTATE,
497 TD_PROTSTATUS,
498 TD_GETNUMTRACKS,
499 TD_ADDCHANGEINT,
500 TD_REMCHANGEINT,
501 TD_GETGEOMETRY,
502 TD_EJECT,
503 TD_READ64,
504 TD_WRITE64,
505 TD_SEEK64,
506 TD_FORMAT64,
507 HD_SCSICMD,
508 TD_GETDRIVETYPE,
509 NSCMD_DEVICEQUERY,
510 NSCMD_TD_READ64,
511 NSCMD_TD_WRITE64,
512 NSCMD_TD_SEEK64,
513 NSCMD_TD_FORMAT64,
518 Do proper IO actions depending on the request. It's called from the bus
519 tasks and from BeginIO in case of immediate commands.
521 BOOL FNAME_SDC(HandleIO)(struct IORequest *io)
523 BOOL retval = TRUE;
524 LIBBASETYPEPTR LIBBASE = ((struct sdcard_Unit*)io->io_Unit)->sdcu_Bus->sdcb_DeviceBase;
526 io->io_Error = 0;
528 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
530 /* Handle few commands directly here */
531 switch (io->io_Command)
534 New Style Devices query. Introduce self as trackdisk and provide list of
535 commands supported
537 case NSCMD_DEVICEQUERY:
539 struct NSDeviceQueryResult *nsdq = (struct NSDeviceQueryResult *)IOStdReq(io)->io_Data;
540 nsdq->DevQueryFormat = 0;
541 nsdq->SizeAvailable = sizeof(struct NSDeviceQueryResult);
542 nsdq->DeviceType = NSDEVTYPE_TRACKDISK;
543 nsdq->DeviceSubType = 0;
544 nsdq->SupportedCommands = (UWORD *)NSDSupported;
546 IOStdReq(io)->io_Actual = sizeof(struct NSDeviceQueryResult);
547 break;
550 New Style Devices report here the 'NSTY' - only if such value is
551 returned here, the NSCMD_DEVICEQUERY might be called. Otherwice it should
552 report error.
554 case TD_GETDRIVETYPE:
555 IOStdReq(io)->io_Actual = DRIVE_NEWSTYLE;
556 break;
558 case TD_ADDCHANGEINT:
559 retval = FALSE;
561 Call all other commands using the command pointer tables for 32- and
562 64-bit accesses. If requested function is defined call it, otherwise
563 make the function cmd_Invalid.
565 default:
566 if (io->io_Command <= (HD_SCSICMD + 1))
568 if (map32[io->io_Command])
569 map32[io->io_Command](io, LIBBASE);
570 else
571 cmd_Invalid(io, LIBBASE);
573 else if (io->io_Command >= NSCMD_TD_READ64 && io->io_Command <= NSCMD_TD_FORMAT64)
575 if (map64[io->io_Command - NSCMD_TD_READ64])
576 map64[io->io_Command - NSCMD_TD_READ64](io, LIBBASE);
577 else
578 cmd_Invalid(io, LIBBASE);
580 else cmd_Invalid(io, LIBBASE);
581 break;
583 return retval;
587 static const ULONG IMMEDIATE_COMMANDS = 0x803ff1e3; // 10000000001111111111000111100011
589 /* See whether the command can be done quick */
590 BOOL isSlow(ULONG comm)
592 BOOL slow = TRUE; /* Assume always slow command */
594 /* For commands with numbers <= 31 check the mask */
595 if (comm <= 31)
597 if (IMMEDIATE_COMMANDS & (1 << comm))
598 slow = FALSE;
600 else if (comm == NSCMD_TD_SEEK64) slow = FALSE;
602 return slow;
606 Try to do IO commands. All commands which require talking with mci devices
607 will be handled slow, that is they will be passed to bus task which will
608 execute them as soon as hardware will be free.
610 AROS_LH1(void, BeginIO,
611 AROS_LHA(struct IORequest *, io, A1),
612 LIBBASETYPEPTR, LIBBASE, 5, sdcard)
614 AROS_LIBFUNC_INIT
616 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
618 io->io_Message.mn_Node.ln_Type = NT_MESSAGE;
620 /* Disable interrupts for a while to modify message flags */
621 Disable();
623 D(bug("[SDCard%02ld] %s: Executing IO Command %lx\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__, io->io_Command));
626 If the command is not-immediate, or presence of disc is still unknown,
627 let the bus task do the job.
629 if (isSlow(io->io_Command))
631 unit->sdcu_Unit.unit_flags |= UNITF_ACTIVE | UNITF_INTASK;
632 io->io_Flags &= ~IOF_QUICK;
633 Enable();
635 /* Put the message to the bus */
636 PutMsg(unit->sdcu_Bus->sdcb_MsgPort, (struct Message *)io);
638 else
640 D(bug("[SDCard%02ld] %s: Fast command\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
642 /* Immediate command. Mark unit as active and do the command directly */
643 unit->sdcu_Unit.unit_flags |= UNITF_ACTIVE;
644 Enable();
645 if (FNAME_SDC(HandleIO)(io))
647 unit->sdcu_Unit.unit_flags &= ~UNITF_ACTIVE;
648 if (!(io->io_Flags & IOF_QUICK))
649 ReplyMsg((struct Message *)io);
651 else
652 unit->sdcu_Unit.unit_flags &= ~UNITF_ACTIVE;
655 D(bug("[SDCard%02ld] %s: Done\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
657 AROS_LIBFUNC_EXIT
660 AROS_LH1(LONG, AbortIO,
661 AROS_LHA(struct IORequest *, io, A1),
662 LIBBASETYPEPTR, LIBBASE, 6, sdcard)
664 AROS_LIBFUNC_INIT
666 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
668 /* Cannot Abort IO */
669 return 0;
671 AROS_LIBFUNC_EXIT
674 AROS_LH1(ULONG, GetRdskLba,
675 AROS_LHA(struct IORequest *, io, A1),
676 LIBBASETYPEPTR, LIBBASE, 7, sdcard)
678 AROS_LIBFUNC_INIT
680 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
682 return 0;
684 AROS_LIBFUNC_EXIT
687 AROS_LH1(ULONG, GetBlkSize,
688 AROS_LHA(struct IORequest *, io, A1),
689 LIBBASETYPEPTR, LIBBASE, 8, sdcard)
691 AROS_LIBFUNC_INIT
693 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
695 return Unit(io)->sdcu_Bus->sdcb_SectorShift;
697 AROS_LIBFUNC_EXIT