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))
47     {
48         D(bug("[SDCard%02ld] %s: Error: No Media present\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
49         io->io_Error = TDERR_DiskChanged;
50         return;
51     }
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;
60     /*
61         During this IO call it should be sure that both offset and
62         length are already aligned properly to sector boundaries.
63     */
64     if ((block & mask) | (count & mask))
65     {
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);
68     }
69     else
70     {
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))
76         {
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;
80         }
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;
87     }
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))
99     {
100         D(bug("[SDCard%02ld] %s: Error: No Media present\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
101         io->io_Error = TDERR_DiskChanged;
102         return;
103     }
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))
113     {
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);
116     }
117     else
118     {
119         block >>= unit->sdcu_Bus->sdcb_SectorShift;
120         count >>= unit->sdcu_Bus->sdcb_SectorShift;
121         ULONG cnt = 0;
123         /*
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.
127         */
128         if (((block + count) > unit->sdcu_Capacity))
129         {
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;
133         }
134         io->io_Error = unit->sdcu_Read32(unit, (ULONG)(block & 0x0fffffff), count, IOStdReq(io)->io_Data, &cnt);
136         IOStdReq(io)->io_Actual = cnt;
137     }
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))
146     {
147         D(bug("[SDCard%02ld] %s: Error: No Media present\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
148         io->io_Error = TDERR_DiskChanged;
149         return;
150     }
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;
159     /*
160         During this IO call it should be sure that both offset and
161         length are already aligned properly to sector boundaries.
162     */
163     if ((block & mask) | (count & mask))
164     {
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);
167     }
168     else
169     {
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))
175         {
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;
180         }
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;
187     }
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))
199     {
200         D(bug("[SDCard%02ld] %s: Error: No Media present\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
201         io->io_Error = TDERR_DiskChanged;
202         return;
203     }
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))
213     {
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);
216     }
217     else
218     {
219         block >>= unit->sdcu_Bus->sdcb_SectorShift;
220         count >>= unit->sdcu_Bus->sdcb_SectorShift;
221         ULONG cnt = 0;
223         /*
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.
227         */
228         if (((block + count) > unit->sdcu_Capacity))
229         {
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;
237         }
239         io->io_Error = unit->sdcu_Write64(unit, block, count,
240             IOStdReq(io)->io_Data, &cnt);
242         IOStdReq(io)->io_Actual = cnt;
243    }
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)
276     {
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)
287         {
288             Cause((struct Interrupt *)IOStdReq(msg)->io_Data);
289         }
291         unit->sdcu_Flags &= ~AF_MediaChanged;
293         Permit();
294     }
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))
396     {
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);
416     }
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,
514     0
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)
532     {
533         /*
534             New Style Devices query. Introduce self as trackdisk and provide list of
535             commands supported
536         */
537         case NSCMD_DEVICEQUERY:
538             {
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;
545             }
546             IOStdReq(io)->io_Actual = sizeof(struct NSDeviceQueryResult);
547             break;
549         /*
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.
553         */
554         case TD_GETDRIVETYPE:
555             IOStdReq(io)->io_Actual = DRIVE_NEWSTYLE;
556             break;
558         case TD_ADDCHANGEINT:
559             retval = FALSE;
560         /*
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.
564         */
565         default:
566             if (io->io_Command <= (HD_SCSICMD + 1))
567             {
568                 if (map32[io->io_Command])
569                     map32[io->io_Command](io, LIBBASE);
570                 else
571                     cmd_Invalid(io, LIBBASE);
572             }
573             else if (io->io_Command >= NSCMD_TD_READ64 && io->io_Command <= NSCMD_TD_FORMAT64)
574             {
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);
579             }
580             else cmd_Invalid(io, LIBBASE);
581             break;
582     }
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)
596     {
597         if (IMMEDIATE_COMMANDS & (1 << comm))
598             slow = FALSE;
599     }
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));
625     /*
626         If the command is not-immediate, or presence of disc is still unknown,
627         let the bus task do the job.
628     */
629     if (isSlow(io->io_Command))
630     {
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);
637     }
638     else
639     {
640         D(bug("[SDCard%02ld] %s: Fast command\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
641     
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))
646         {
647             unit->sdcu_Unit.unit_flags &= ~UNITF_ACTIVE;
648             if (!(io->io_Flags & IOF_QUICK))
649                 ReplyMsg((struct Message *)io);
650         }
651         else
652             unit->sdcu_Unit.unit_flags &= ~UNITF_ACTIVE;
653     }
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