Enforce libdir. On OpenSUSE the libs where stored in "lib64". They weren't
[AROS.git] / rom / devs / sdcard / sdcard_device.c
blob4be2518df61875893ddec697a797a687e4b98d0b
1 /*
2 Copyright © 2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 0
7 #include <aros/debug.h>
9 #include <proto/exec.h>
10 #include <proto/oop.h>
12 #include <exec/types.h>
13 #include <exec/exec.h>
14 #include <exec/resident.h>
15 #include <exec/io.h>
16 #include <dos/bptr.h>
17 #include <devices/trackdisk.h>
18 #include <devices/scsidisk.h>
19 #include <devices/newstyle.h>
20 #include <utility/utility.h>
21 #include <utility/tagitem.h>
22 #include <oop/oop.h>
24 #include "sdcard_base.h"
25 #include "sdcard_unit.h"
26 #include "timer.h"
28 #include LC_LIBDEFS_FILE
30 //---------------------------IO Commands---------------------------------------
32 /* Invalid comand does nothing, complains only. */
33 static void cmd_Invalid(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
35 D(bug("[SDCard%02ld] %s: %d\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__, io->io_Command));
36 io->io_Error = IOERR_NOCMD;
39 /* Don't need to reset the drive? */
40 static void cmd_Reset(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
42 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
43 IOStdReq(io)->io_Actual = 0;
46 /* CMD_READ implementation */
47 static void cmd_Read32(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
49 struct sdcard_Unit *unit = (struct sdcard_Unit *)IOStdReq(io)->io_Unit;
50 ULONG block = IOStdReq(io)->io_Offset;
51 ULONG count = IOStdReq(io)->io_Length;
52 ULONG mask;
54 D(bug("[SDCard%02ld] %s(%08x, %08x)\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__, block, count));
56 if (!(unit->sdcu_Bus->sdcb_BusFlags & AF_Bus_MediaPresent))
58 bug("[SDCard%02ld] %s: Error: No Media present\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__);
59 io->io_Error = TDERR_DiskChanged;
60 return;
63 mask = (1 << unit->sdcu_Bus->sdcb_SectorShift) - 1;
66 During this IO call it should be sure that both offset and
67 length are already aligned properly to sector boundaries.
69 if ((block & mask) | (count & mask))
71 bug("[SDCard%02ld] %s: offset or length not sector-aligned.\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__);
72 cmd_Invalid(io, LIBBASE);
74 else
76 block >>= unit->sdcu_Bus->sdcb_SectorShift;
77 count >>= unit->sdcu_Bus->sdcb_SectorShift;
78 ULONG cnt = 0;
80 if ((block + count) > (ULONG)(unit->sdcu_Capacity & 0xFFFFFFFFul))
82 bug("[SDCard%02ld] %s: Requested block (%lx;%ld) outside disk range (%lx)\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__, block, count, (ULONG)(unit->sdcu_Capacity & 0xFFFFFFFFul));
83 io->io_Error = IOERR_BADADDRESS;
84 return;
87 /* Call the Unit's access funtion */
88 io->io_Error = unit->sdcu_Read32(unit, block, count,
89 IOStdReq(io)->io_Data, &cnt);
91 IOStdReq(io)->io_Actual = cnt;
96 NSCMD_TD_READ64, TD_READ64 implementation. Basically the same, just packs
97 the 64 bit offset in both io_Offset (31:0) and io_Actual (63:32)
99 static void cmd_Read64(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
101 struct sdcard_Unit *unit = (struct sdcard_Unit *)IOStdReq(io)->io_Unit;
102 UQUAD block = IOStdReq(io)->io_Offset | (UQUAD)(IOStdReq(io)->io_Actual) << 32;
103 ULONG count = IOStdReq(io)->io_Length;
104 ULONG mask;
106 D(bug("[SDCard%02ld] %s(%08x%08x, %08x)\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__, IOStdReq(io)->io_Actual, IOStdReq(io)->io_Offset, count));
108 if (!(unit->sdcu_Flags & AF_Card_HighCapacity))
110 /* 64bit commands are only used with high capacity devices .. */
111 D(bug("[SDCard%02ld] %s: 64bit IO called on 32bit unit\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
112 io->io_Error = IOERR_NOCMD;
113 return;
116 if (!(unit->sdcu_Bus->sdcb_BusFlags & AF_Bus_MediaPresent))
118 bug("[SDCard%02ld] %s: Error: No Media present\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__);
119 io->io_Error = TDERR_DiskChanged;
120 return;
123 mask = (1 << unit->sdcu_Bus->sdcb_SectorShift) - 1;
125 if ((block & (UQUAD)mask) | (count & mask) | (count == 0))
127 D(bug("[SDCard%02ld] %s: offset or length not sector-aligned.\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
128 cmd_Invalid(io, LIBBASE);
130 else
132 block >>= unit->sdcu_Bus->sdcb_SectorShift;
133 count >>= unit->sdcu_Bus->sdcb_SectorShift;
134 ULONG cnt = 0;
136 if (((block + count) > unit->sdcu_Capacity))
138 bug("[SDCard%02ld] %s: Requested block (%lx;%ld) outside disk range (%lx)\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__, block, count, unit->sdcu_Capacity);
139 io->io_Error = IOERR_BADADDRESS;
140 return;
142 io->io_Error = unit->sdcu_Read64(unit, block, count, IOStdReq(io)->io_Data, &cnt);
144 IOStdReq(io)->io_Actual = cnt;
148 /* CMD_WRITE implementation */
149 static void cmd_Write32(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
151 struct sdcard_Unit *unit = (struct sdcard_Unit *)IOStdReq(io)->io_Unit;
152 ULONG block = IOStdReq(io)->io_Offset;
153 ULONG count = IOStdReq(io)->io_Length;
154 ULONG mask;
156 D(bug("[SDCard%02ld] %s(%08x, %08x)\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__, block, count));
158 if (!(unit->sdcu_Bus->sdcb_BusFlags & AF_Bus_MediaPresent))
160 bug("[SDCard%02ld] %s: Error: No Media present\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__);
161 io->io_Error = TDERR_DiskChanged;
162 return;
165 if (unit->sdcu_Flags & (AF_Card_WriteProtect|AF_Card_Locked))
167 bug("[SDCard%02ld] %s: Error: Card is Locked/Write Protected\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__);
168 io->io_Error = IOERR_ABORTED;
169 return;
172 mask = (1 << unit->sdcu_Bus->sdcb_SectorShift) - 1;
175 During this IO call it should be sure that both offset and
176 length are already aligned properly to sector boundaries.
178 if ((block & mask) | (count & mask))
180 D(bug("[SDCard%02ld] %s: offset or length not sector-aligned.\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
181 cmd_Invalid(io, LIBBASE);
183 else
185 block >>= unit->sdcu_Bus->sdcb_SectorShift;
186 count >>= unit->sdcu_Bus->sdcb_SectorShift;
187 ULONG cnt = 0;
189 if (((block + count) > unit->sdcu_Capacity))
191 bug("[SDCard%02ld] %s: Requested block (%lx;%ld) outside disk range (%lx)\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__,
192 block, count, unit->sdcu_Capacity);
193 io->io_Error = IOERR_BADADDRESS;
194 return;
197 /* Call the Unit's access funtion */
198 io->io_Error = unit->sdcu_Write32(unit, block, count,
199 IOStdReq(io)->io_Data, &cnt);
201 IOStdReq(io)->io_Actual = cnt;
206 NSCMD_TD_WRITE64, TD_WRITE64 implementation. Basically the same, just packs
207 the 64 bit offset in both io_Offset (31:0) and io_Actual (63:32)
209 static void cmd_Write64(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
211 struct sdcard_Unit *unit = (struct sdcard_Unit *)IOStdReq(io)->io_Unit;
212 UQUAD block = IOStdReq(io)->io_Offset | (UQUAD)(IOStdReq(io)->io_Actual) << 32;
213 ULONG count = IOStdReq(io)->io_Length;
214 ULONG mask;
216 D(bug("[SDCard%02ld] %s(%08x-%08x, %08x)\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__, IOStdReq(io)->io_Actual, IOStdReq(io)->io_Offset, count));
218 if (!(unit->sdcu_Flags & AF_Card_HighCapacity))
220 /* 64bit commands are only used with high capacity devices .. */
221 D(bug("[SDCard%02ld] %s: 64bit IO called on 32bit unit\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
222 io->io_Error = IOERR_NOCMD;
223 return;
226 if (!(unit->sdcu_Bus->sdcb_BusFlags & AF_Bus_MediaPresent))
228 bug("[SDCard%02ld] %s: Error: No Media present\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__);
229 io->io_Error = TDERR_DiskChanged;
230 return;
233 if (unit->sdcu_Flags & (AF_Card_WriteProtect|AF_Card_Locked))
235 bug("[SDCard%02ld] %s: Error: Card is Locked/Write Protected\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__);
236 io->io_Error = IOERR_ABORTED;
237 return;
240 mask = (1 << unit->sdcu_Bus->sdcb_SectorShift) - 1;
242 if ((block & mask) | (count & mask) | (count==0))
244 D(bug("[SDCard%02ld] %s: offset or length not sector-aligned.\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
245 cmd_Invalid(io, LIBBASE);
247 else
249 block >>= unit->sdcu_Bus->sdcb_SectorShift;
250 count >>= unit->sdcu_Bus->sdcb_SectorShift;
251 ULONG cnt = 0;
253 if (((block + count) > unit->sdcu_Capacity))
255 bug("[SDCard%02ld] %s: Requested block (%lx:%08lx;%ld) outside disk "
256 "range (%lx:%08lx)\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__,
257 block>>32, block&0xfffffffful,
258 count, unit->sdcu_Capacity>>32,
259 unit->sdcu_Capacity & 0xfffffffful);
260 io->io_Error = IOERR_BADADDRESS;
261 return;
264 io->io_Error = unit->sdcu_Write64(unit, block, count,
265 IOStdReq(io)->io_Data, &cnt);
267 IOStdReq(io)->io_Actual = cnt;
272 /* use CMD_FLUSH to force all IO waiting commands to abort */
273 static void cmd_Flush(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
275 struct IORequest *msg;
276 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
278 Forbid();
280 while((msg = (struct IORequest *)GetMsg((struct MsgPort *)((struct sdcard_Unit *)io->io_Unit)->sdcu_Bus->sdcb_MsgPort)))
282 msg->io_Error = IOERR_ABORTED;
283 ReplyMsg((struct Message *)msg);
286 Permit();
290 Internal command used to check whether the media in drive has been changed
291 since last call. If so, the handlers given by user are called.
293 static void cmd_TestChanged(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
295 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
296 struct IORequest *msg;
298 D(bug("[SDCard%02ld] %s()\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
300 if (unit->sdcu_Bus->sdcb_BusFlags & AF_Bus_MediaChanged)
302 unit->sdcu_ChangeNum++;
304 Forbid();
306 /* old-fashioned RemoveInt call first */
307 if (unit->sdcu_RemoveInt)
308 Cause(unit->sdcu_RemoveInt);
310 /* And now the whole list of possible calls */
311 ForeachNode(&unit->sdcu_SoftList, msg)
313 Cause((struct Interrupt *)IOStdReq(msg)->io_Data);
316 unit->sdcu_Bus->sdcb_BusFlags &= ~AF_Bus_MediaChanged;
318 Permit();
322 static void cmd_Update(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
324 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
326 /* Do nothing now. In near future there should be drive cache flush though */
329 static void cmd_Remove(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
331 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
333 D(bug("[SDCard%02ld] %s()\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
335 if (unit->sdcu_RemoveInt)
336 io->io_Error = TDERR_DriveInUse;
337 else
338 unit->sdcu_RemoveInt = IOStdReq(io)->io_Data;
341 static void cmd_ChangeNum(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
343 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
345 IOStdReq(io)->io_Actual = ((struct sdcard_Unit *)io->io_Unit)->sdcu_ChangeNum;
348 static void cmd_ChangeState(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
350 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
352 D(bug("[SDCard%02ld] %s()\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
354 if (unit->sdcu_Bus->sdcb_BusFlags & AF_Bus_MediaPresent)
355 IOStdReq(io)->io_Actual = 0;
356 else
357 IOStdReq(io)->io_Actual = 1;
359 D(bug("[SDCard%02ld] %s: Media %s\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__, IOStdReq(io)->io_Actual ? "ABSENT" : "PRESENT"));
362 static void cmd_ProtStatus(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
364 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
366 D(bug("[SDCard%02ld] %s()\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
368 if ((unit->sdcu_Flags & (AF_Card_WriteProtect|AF_Card_Locked)) != 0)
369 IOStdReq(io)->io_Actual = -1;
370 else
371 IOStdReq(io)->io_Actual = 0;
374 static void cmd_GetNumTracks(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
376 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
378 IOStdReq(io)->io_Actual = ((struct sdcard_Unit *)io->io_Unit)->sdcu_Cylinders;
381 static void cmd_AddChangeInt(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
383 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
385 D(bug("[SDCard%02ld] %s()\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
387 Forbid();
388 AddHead(&unit->sdcu_SoftList, (struct Node *)io);
389 Permit();
391 io->io_Flags &= ~IOF_QUICK;
392 unit->sdcu_Unit.unit_flags &= ~UNITF_ACTIVE;
395 static void cmd_RemChangeInt(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
397 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
399 Forbid();
400 Remove((struct Node *)io);
401 Permit();
404 static void cmd_Eject(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
406 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
408 D(bug("[SDCard%02ld] %s()\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
410 IOStdReq(io)->io_Error = unit->sdcu_Eject(unit);
411 cmd_TestChanged(io, LIBBASE);
414 static void cmd_GetGeometry(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
416 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
418 D(bug("[SDCard%02ld] %s()\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
420 if (IOStdReq(io)->io_Length == sizeof(struct DriveGeometry))
422 struct DriveGeometry *dg = (struct DriveGeometry *)IOStdReq(io)->io_Data;
424 dg->dg_SectorSize = 1 << unit->sdcu_Bus->sdcb_SectorShift;
426 if ((ULONG)((unit->sdcu_Capacity >> 32) & 0xFFFFFFFFul) != 0)
427 dg->dg_TotalSectors = 0xFFFFFFFF;
428 else
429 dg->dg_TotalSectors = (ULONG)(unit->sdcu_Capacity & 0xFFFFFFFFul);
431 dg->dg_Cylinders = unit->sdcu_Cylinders;
432 dg->dg_CylSectors = unit->sdcu_Sectors * unit->sdcu_Heads;
433 dg->dg_Heads = unit->sdcu_Heads;
434 dg->dg_TrackSectors = unit->sdcu_Sectors;
435 dg->dg_BufMemType = MEMF_PUBLIC;
436 dg->dg_DeviceType = DG_DIRECT_ACCESS;
437 dg->dg_Flags = DGF_REMOVABLE;
438 dg->dg_Reserved = 0;
440 IOStdReq(io)->io_Actual = sizeof(struct DriveGeometry);
442 else io->io_Error = TDERR_NotSpecified;
445 static void cmd_DirectSCSI(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
447 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
449 IOStdReq(io)->io_Actual = sizeof(struct SCSICmd);
450 io->io_Error = IOERR_BADADDRESS;
453 //-----------------------------------------------------------------------------
456 command translation tables - used to call proper IO functions.
459 #define N_TD_READ64 0
460 #define N_TD_WRITE64 1
461 #define N_TD_SEEK64 2
462 #define N_TD_FORMAT64 3
464 typedef void (*mapfunc)(struct IORequest *, LIBBASETYPEPTR);
466 static mapfunc const map64[]= {
467 [N_TD_READ64] = cmd_Read64,
468 [N_TD_WRITE64] = cmd_Write64,
469 [N_TD_SEEK64] = cmd_Reset,
470 [N_TD_FORMAT64] = cmd_Write64
473 static mapfunc const map32[] = {
474 [CMD_INVALID] = cmd_Invalid,
475 [CMD_RESET] = cmd_Reset,
476 [CMD_READ] = cmd_Read32,
477 [CMD_WRITE] = cmd_Write32,
478 [CMD_UPDATE] = cmd_Update,
479 [CMD_CLEAR] = cmd_Reset,
480 [CMD_STOP] = cmd_Reset,
481 [CMD_START] = cmd_Reset,
482 [CMD_FLUSH] = cmd_Flush,
483 [TD_MOTOR] = cmd_Reset,
484 [TD_SEEK] = cmd_Reset,
485 [TD_FORMAT] = cmd_Write32,
486 [TD_REMOVE] = cmd_Remove,
487 [TD_CHANGENUM] = cmd_ChangeNum,
488 [TD_CHANGESTATE]= cmd_ChangeState,
489 [TD_PROTSTATUS] = cmd_ProtStatus,
490 [TD_RAWREAD] = cmd_Invalid,
491 [TD_RAWWRITE] = cmd_Invalid,
492 [TD_GETNUMTRACKS] = cmd_GetNumTracks,
493 [TD_ADDCHANGEINT] = cmd_AddChangeInt,
494 [TD_REMCHANGEINT] = cmd_RemChangeInt,
495 [TD_GETGEOMETRY]= cmd_GetGeometry,
496 [TD_EJECT] = cmd_Eject,
497 [TD_READ64] = cmd_Read64,
498 [TD_WRITE64] = cmd_Write64,
499 [TD_SEEK64] = cmd_Reset,
500 [TD_FORMAT64] = cmd_Write64,
501 [HD_SCSICMD] = cmd_DirectSCSI,
502 [HD_SCSICMD+1] = cmd_TestChanged,
505 static UWORD const NSDSupported[] = {
506 TD_READ64,
507 TD_WRITE64,
508 TD_SEEK64,
509 TD_FORMAT64,
510 NSCMD_TD_READ64,
511 NSCMD_TD_WRITE64,
512 NSCMD_TD_SEEK64,
513 NSCMD_TD_FORMAT64,
514 CMD_RESET,
515 CMD_READ,
516 CMD_WRITE,
517 CMD_UPDATE,
518 CMD_CLEAR,
519 CMD_STOP,
520 CMD_START,
521 CMD_FLUSH,
522 TD_MOTOR,
523 TD_SEEK,
524 TD_FORMAT,
525 TD_REMOVE,
526 TD_CHANGENUM,
527 TD_CHANGESTATE,
528 TD_PROTSTATUS,
529 TD_GETNUMTRACKS,
530 TD_ADDCHANGEINT,
531 TD_REMCHANGEINT,
532 TD_GETGEOMETRY,
533 TD_EJECT,
534 HD_SCSICMD,
535 TD_GETDRIVETYPE,
536 NSCMD_DEVICEQUERY,
541 Do proper IO actions depending on the request. It's called from the bus
542 tasks and from BeginIO in case of immediate commands.
544 BOOL FNAME_SDC(HandleIO)(struct IORequest *io)
546 BOOL retval = TRUE;
547 LIBBASETYPEPTR LIBBASE = ((struct sdcard_Unit*)io->io_Unit)->sdcu_Bus->sdcb_DeviceBase;
549 io->io_Error = 0;
551 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
553 /* Handle few commands directly here */
554 switch (io->io_Command)
557 New Style Devices query. Introduce self as trackdisk and provide list of
558 commands supported
560 case NSCMD_DEVICEQUERY:
562 struct NSDeviceQueryResult *nsdq = (struct NSDeviceQueryResult *)IOStdReq(io)->io_Data;
563 nsdq->DevQueryFormat = 0;
564 nsdq->SizeAvailable = sizeof(struct NSDeviceQueryResult);
565 nsdq->DeviceType = NSDEVTYPE_TRACKDISK;
566 nsdq->DeviceSubType = 0;
567 nsdq->SupportedCommands = (((struct sdcard_Unit*)io->io_Unit)->sdcu_Flags & AF_Card_HighCapacity) ? (UWORD *)NSDSupported : (UWORD *)&NSDSupported[8];
569 IOStdReq(io)->io_Actual = sizeof(struct NSDeviceQueryResult);
570 break;
573 New Style Devices report here the 'NSTY' - only if such value is
574 returned here, the NSCMD_DEVICEQUERY might be called. Otherwice it should
575 report error.
577 case TD_GETDRIVETYPE:
578 IOStdReq(io)->io_Actual = DRIVE_NEWSTYLE;
579 break;
581 case TD_ADDCHANGEINT:
582 retval = FALSE;
584 Call all other commands using the command pointer tables for 32- and
585 64-bit accesses. If requested function is defined call it, otherwise
586 make the function cmd_Invalid.
588 default:
589 if (io->io_Command <= (HD_SCSICMD + 1))
591 if (map32[io->io_Command])
592 map32[io->io_Command](io, LIBBASE);
593 else
594 cmd_Invalid(io, LIBBASE);
596 else if (io->io_Command >= NSCMD_TD_READ64 && io->io_Command <= NSCMD_TD_FORMAT64)
598 if (map64[io->io_Command - NSCMD_TD_READ64])
599 map64[io->io_Command - NSCMD_TD_READ64](io, LIBBASE);
600 else
601 cmd_Invalid(io, LIBBASE);
603 else cmd_Invalid(io, LIBBASE);
604 break;
606 return retval;
610 static const ULONG IMMEDIATE_COMMANDS = 0x803ff1e3; // 10000000001111111111000111100011
612 /* See whether the command can be done quick */
613 BOOL isSlow(ULONG comm)
615 BOOL slow = TRUE; /* Assume always slow command */
617 /* For commands with numbers <= 31 check the mask */
618 if (comm <= 31)
620 if (IMMEDIATE_COMMANDS & (1 << comm))
621 slow = FALSE;
623 else if (comm == NSCMD_TD_SEEK64) slow = FALSE;
625 return slow;
629 Try to do IO commands. All commands which require talking with mci devices
630 will be handled slow, that is they will be passed to bus task which will
631 execute them as soon as hardware will be free.
633 AROS_LH1(void, BeginIO,
634 AROS_LHA(struct IORequest *, io, A1),
635 LIBBASETYPEPTR, LIBBASE, 5, sdcard)
637 AROS_LIBFUNC_INIT
639 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
641 io->io_Message.mn_Node.ln_Type = NT_MESSAGE;
643 /* Disable interrupts for a while to modify message flags */
644 Disable();
646 D(bug("[SDCard%02ld] %s: Executing IO Command %lx\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__, io->io_Command));
649 If the command is not-immediate, or presence of disc is still unknown,
650 let the bus task do the job.
652 if (isSlow(io->io_Command))
654 unit->sdcu_Unit.unit_flags |= UNITF_ACTIVE | UNITF_INTASK;
655 io->io_Flags &= ~IOF_QUICK;
656 Enable();
658 /* Put the message to the bus */
659 PutMsg(unit->sdcu_Bus->sdcb_MsgPort, (struct Message *)io);
661 else
663 D(bug("[SDCard%02ld] %s: Fast command\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
665 /* Immediate command. Mark unit as active and do the command directly */
666 unit->sdcu_Unit.unit_flags |= UNITF_ACTIVE;
667 Enable();
668 if (FNAME_SDC(HandleIO)(io))
670 unit->sdcu_Unit.unit_flags &= ~UNITF_ACTIVE;
671 if (!(io->io_Flags & IOF_QUICK))
672 ReplyMsg((struct Message *)io);
674 else
675 unit->sdcu_Unit.unit_flags &= ~UNITF_ACTIVE;
678 D(bug("[SDCard%02ld] %s: Done\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
680 AROS_LIBFUNC_EXIT
683 AROS_LH1(LONG, AbortIO,
684 AROS_LHA(struct IORequest *, io, A1),
685 LIBBASETYPEPTR, LIBBASE, 6, sdcard)
687 AROS_LIBFUNC_INIT
689 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
691 /* Cannot Abort IO */
692 return 0;
694 AROS_LIBFUNC_EXIT
697 AROS_LH1(ULONG, GetRdskLba,
698 AROS_LHA(struct IORequest *, io, A1),
699 LIBBASETYPEPTR, LIBBASE, 7, sdcard)
701 AROS_LIBFUNC_INIT
703 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
705 return 0;
707 AROS_LIBFUNC_EXIT
710 AROS_LH1(ULONG, GetBlkSize,
711 AROS_LHA(struct IORequest *, io, A1),
712 LIBBASETYPEPTR, LIBBASE, 8, sdcard)
714 AROS_LIBFUNC_INIT
716 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
718 return Unit(io)->sdcu_Bus->sdcb_SectorShift;
720 AROS_LIBFUNC_EXIT