revert between 56095 -> 55830 in arch
[AROS.git] / rom / devs / sdcard / sdcard_device.c
blobeba282d53e35d2479c80d44b006e855abd167fc4
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__, (ULONG)block, count, (ULONG)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 /* Write unsupported yet, return write protect state *always* */
369 IOStdReq(io)->io_Actual = -1;
371 #if 0
373 if ((unit->sdcu_Flags & (AF_Card_WriteProtect|AF_Card_Locked)) != 0)
374 IOStdReq(io)->io_Actual = -1;
375 else
376 IOStdReq(io)->io_Actual = 0;
378 #endif
381 static void cmd_GetNumTracks(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
383 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
385 IOStdReq(io)->io_Actual = ((struct sdcard_Unit *)io->io_Unit)->sdcu_Cylinders;
388 static void cmd_AddChangeInt(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
390 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
392 D(bug("[SDCard%02ld] %s()\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
394 Forbid();
395 AddHead(&unit->sdcu_SoftList, (struct Node *)io);
396 Permit();
398 io->io_Flags &= ~IOF_QUICK;
399 unit->sdcu_Unit.unit_flags &= ~UNITF_ACTIVE;
402 static void cmd_RemChangeInt(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
404 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
406 Forbid();
407 Remove((struct Node *)io);
408 Permit();
411 static void cmd_Eject(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
413 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
415 D(bug("[SDCard%02ld] %s()\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
417 IOStdReq(io)->io_Error = unit->sdcu_Eject(unit);
418 cmd_TestChanged(io, LIBBASE);
421 static void cmd_GetGeometry(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
423 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
425 D(bug("[SDCard%02ld] %s()\n", unit->sdcu_UnitNum, __PRETTY_FUNCTION__));
427 if (IOStdReq(io)->io_Length == sizeof(struct DriveGeometry))
429 struct DriveGeometry *dg = (struct DriveGeometry *)IOStdReq(io)->io_Data;
431 dg->dg_SectorSize = 1 << unit->sdcu_Bus->sdcb_SectorShift;
433 if ((ULONG)((unit->sdcu_Capacity >> 32) & 0xFFFFFFFFul) != 0)
434 dg->dg_TotalSectors = 0xFFFFFFFF;
435 else
436 dg->dg_TotalSectors = (ULONG)(unit->sdcu_Capacity & 0xFFFFFFFFul);
438 dg->dg_Cylinders = unit->sdcu_Cylinders;
439 dg->dg_CylSectors = unit->sdcu_Sectors * unit->sdcu_Heads;
440 dg->dg_Heads = unit->sdcu_Heads;
441 dg->dg_TrackSectors = unit->sdcu_Sectors;
442 dg->dg_BufMemType = MEMF_PUBLIC;
443 dg->dg_DeviceType = DG_DIRECT_ACCESS;
444 dg->dg_Flags = DGF_REMOVABLE;
445 dg->dg_Reserved = 0;
447 IOStdReq(io)->io_Actual = sizeof(struct DriveGeometry);
449 else io->io_Error = TDERR_NotSpecified;
452 static void cmd_DirectSCSI(struct IORequest *io, LIBBASETYPEPTR LIBBASE)
454 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
456 IOStdReq(io)->io_Actual = sizeof(struct SCSICmd);
457 io->io_Error = IOERR_BADADDRESS;
460 //-----------------------------------------------------------------------------
463 command translation tables - used to call proper IO functions.
466 #define N_TD_READ64 0
467 #define N_TD_WRITE64 1
468 #define N_TD_SEEK64 2
469 #define N_TD_FORMAT64 3
471 typedef void (*mapfunc)(struct IORequest *, LIBBASETYPEPTR);
473 static mapfunc const map64[]= {
474 [N_TD_READ64] = cmd_Read64,
475 [N_TD_WRITE64] = cmd_Write64,
476 [N_TD_SEEK64] = cmd_Reset,
477 [N_TD_FORMAT64] = cmd_Write64
480 static mapfunc const map32[] = {
481 [CMD_INVALID] = cmd_Invalid,
482 [CMD_RESET] = cmd_Reset,
483 [CMD_READ] = cmd_Read32,
484 [CMD_WRITE] = cmd_Write32,
485 [CMD_UPDATE] = cmd_Update,
486 [CMD_CLEAR] = cmd_Reset,
487 [CMD_STOP] = cmd_Reset,
488 [CMD_START] = cmd_Reset,
489 [CMD_FLUSH] = cmd_Flush,
490 [TD_MOTOR] = cmd_Reset,
491 [TD_SEEK] = cmd_Reset,
492 [TD_FORMAT] = cmd_Write32,
493 [TD_REMOVE] = cmd_Remove,
494 [TD_CHANGENUM] = cmd_ChangeNum,
495 [TD_CHANGESTATE]= cmd_ChangeState,
496 [TD_PROTSTATUS] = cmd_ProtStatus,
497 [TD_RAWREAD] = cmd_Invalid,
498 [TD_RAWWRITE] = cmd_Invalid,
499 [TD_GETNUMTRACKS] = cmd_GetNumTracks,
500 [TD_ADDCHANGEINT] = cmd_AddChangeInt,
501 [TD_REMCHANGEINT] = cmd_RemChangeInt,
502 [TD_GETGEOMETRY]= cmd_GetGeometry,
503 [TD_EJECT] = cmd_Eject,
504 [TD_READ64] = cmd_Read64,
505 [TD_WRITE64] = cmd_Write64,
506 [TD_SEEK64] = cmd_Reset,
507 [TD_FORMAT64] = cmd_Write64,
508 [HD_SCSICMD] = cmd_DirectSCSI,
509 [HD_SCSICMD+1] = cmd_TestChanged,
512 static UWORD const NSDSupported[] = {
513 TD_READ64,
514 TD_WRITE64,
515 TD_SEEK64,
516 TD_FORMAT64,
517 NSCMD_TD_READ64,
518 NSCMD_TD_WRITE64,
519 NSCMD_TD_SEEK64,
520 NSCMD_TD_FORMAT64,
521 CMD_RESET,
522 CMD_READ,
523 CMD_WRITE,
524 CMD_UPDATE,
525 CMD_CLEAR,
526 CMD_STOP,
527 CMD_START,
528 CMD_FLUSH,
529 TD_MOTOR,
530 TD_SEEK,
531 TD_FORMAT,
532 TD_REMOVE,
533 TD_CHANGENUM,
534 TD_CHANGESTATE,
535 TD_PROTSTATUS,
536 TD_GETNUMTRACKS,
537 TD_ADDCHANGEINT,
538 TD_REMCHANGEINT,
539 TD_GETGEOMETRY,
540 TD_EJECT,
541 HD_SCSICMD,
542 TD_GETDRIVETYPE,
543 NSCMD_DEVICEQUERY,
548 Do proper IO actions depending on the request. It's called from the bus
549 tasks and from BeginIO in case of immediate commands.
551 BOOL FNAME_SDC(HandleIO)(struct IORequest *io)
553 BOOL retval = TRUE;
554 LIBBASETYPEPTR LIBBASE = ((struct sdcard_Unit*)io->io_Unit)->sdcu_Bus->sdcb_DeviceBase;
556 io->io_Error = 0;
558 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
560 /* Handle few commands directly here */
561 switch (io->io_Command)
564 New Style Devices query. Introduce self as trackdisk and provide list of
565 commands supported
567 case NSCMD_DEVICEQUERY:
569 struct NSDeviceQueryResult *nsdq = (struct NSDeviceQueryResult *)IOStdReq(io)->io_Data;
570 nsdq->DevQueryFormat = 0;
571 nsdq->SizeAvailable = sizeof(struct NSDeviceQueryResult);
572 nsdq->DeviceType = NSDEVTYPE_TRACKDISK;
573 nsdq->DeviceSubType = 0;
574 nsdq->SupportedCommands = (((struct sdcard_Unit*)io->io_Unit)->sdcu_Flags & AF_Card_HighCapacity) ? (UWORD *)NSDSupported : (UWORD *)&NSDSupported[8];
576 IOStdReq(io)->io_Actual = sizeof(struct NSDeviceQueryResult);
577 break;
580 New Style Devices report here the 'NSTY' - only if such value is
581 returned here, the NSCMD_DEVICEQUERY might be called. Otherwice it should
582 report error.
584 case TD_GETDRIVETYPE:
585 IOStdReq(io)->io_Actual = DRIVE_NEWSTYLE;
586 break;
588 case TD_ADDCHANGEINT:
589 retval = FALSE;
591 Call all other commands using the command pointer tables for 32- and
592 64-bit accesses. If requested function is defined call it, otherwise
593 make the function cmd_Invalid.
595 default:
596 if (io->io_Command <= (HD_SCSICMD + 1))
598 if (map32[io->io_Command])
599 map32[io->io_Command](io, LIBBASE);
600 else
601 cmd_Invalid(io, LIBBASE);
603 else if (io->io_Command >= NSCMD_TD_READ64 && io->io_Command <= NSCMD_TD_FORMAT64)
605 if (map64[io->io_Command - NSCMD_TD_READ64])
606 map64[io->io_Command - NSCMD_TD_READ64](io, LIBBASE);
607 else
608 cmd_Invalid(io, LIBBASE);
610 else cmd_Invalid(io, LIBBASE);
611 break;
613 return retval;
617 //static const ULONG IMMEDIATE_COMMANDS = 0x803ff1e3; // 10000000001111111111000111100011
619 /* See whether the command can be done quick */
620 BOOL isSlow(ULONG comm)
622 BOOL slow = TRUE; /* Assume always slow command */
623 #if 0
624 /* For commands with numbers <= 31 check the mask */
625 if (comm <= 31)
627 if (IMMEDIATE_COMMANDS & (1 << comm))
628 slow = FALSE;
630 else if (comm == NSCMD_TD_SEEK64) slow = FALSE;
631 #endif
632 return slow;
636 Try to do IO commands. All commands which require talking with mci devices
637 will be handled slow, that is they will be passed to bus task which will
638 execute them as soon as hardware will be free.
640 AROS_LH1(void, BeginIO,
641 AROS_LHA(struct IORequest *, io, A1),
642 LIBBASETYPEPTR, LIBBASE, 5, sdcard)
644 AROS_LIBFUNC_INIT
646 struct sdcard_Unit *unit = (struct sdcard_Unit *)io->io_Unit;
648 io->io_Message.mn_Node.ln_Type = NT_MESSAGE;
650 /* Disable interrupts for a while to modify message flags */
651 Disable();
653 D(bug("[SDCard%02ld] %s: Executing IO Command %lx\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__, io->io_Command));
656 If the command is not-immediate, or presence of disc is still unknown,
657 let the bus task do the job.
659 if (isSlow(io->io_Command))
661 unit->sdcu_Unit.unit_flags |= UNITF_ACTIVE | UNITF_INTASK;
662 io->io_Flags &= ~IOF_QUICK;
663 Enable();
665 /* Put the message to the bus */
666 PutMsg(unit->sdcu_Bus->sdcb_MsgPort, (struct Message *)io);
668 else
670 D(bug("[SDCard%02ld] %s: Fast command\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
672 /* Immediate command. Mark unit as active and do the command directly */
673 unit->sdcu_Unit.unit_flags |= UNITF_ACTIVE;
674 Enable();
675 if (FNAME_SDC(HandleIO)(io))
677 unit->sdcu_Unit.unit_flags &= ~UNITF_ACTIVE;
678 if (!(io->io_Flags & IOF_QUICK))
679 ReplyMsg((struct Message *)io);
681 else
682 unit->sdcu_Unit.unit_flags &= ~UNITF_ACTIVE;
685 D(bug("[SDCard%02ld] %s: Done\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
687 AROS_LIBFUNC_EXIT
690 AROS_LH1(LONG, AbortIO,
691 AROS_LHA(struct IORequest *, io, A1),
692 LIBBASETYPEPTR, LIBBASE, 6, sdcard)
694 AROS_LIBFUNC_INIT
696 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
698 /* Cannot Abort IO */
699 return 0;
701 AROS_LIBFUNC_EXIT
704 AROS_LH1(ULONG, GetRdskLba,
705 AROS_LHA(struct IORequest *, io, A1),
706 LIBBASETYPEPTR, LIBBASE, 7, sdcard)
708 AROS_LIBFUNC_INIT
710 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
712 return 0;
714 AROS_LIBFUNC_EXIT
717 AROS_LH1(ULONG, GetBlkSize,
718 AROS_LHA(struct IORequest *, io, A1),
719 LIBBASETYPEPTR, LIBBASE, 8, sdcard)
721 AROS_LIBFUNC_INIT
723 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit*)io->io_Unit)->sdcu_UnitNum, __PRETTY_FUNCTION__));
725 return Unit(io)->sdcu_Bus->sdcb_SectorShift;
727 AROS_LIBFUNC_EXIT