2 Copyright © 2013, The AROS Development Team. All rights reserved.
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>
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
;
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
);
71 block
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
72 count
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
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
;
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
;
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
);
119 block
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
120 count
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
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
;
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
;
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
);
170 block
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
171 count
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
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
;
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
;
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
);
219 block
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
220 count
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
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
;
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
));
255 // while((msg = (struct IORequest *)GetMsg((struct MsgPort *)bus->sdb_MsgPort)))
257 // msg->io_Error = IOERR_ABORTED;
258 // ReplyMsg((struct Message *)msg);
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
++;
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
;
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
;
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;
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;
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__
));
363 AddHead(&unit
->sdcu_SoftList
, (struct Node
*)io
);
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__
));
375 Remove((struct Node
*)io
);
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;
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
;
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
[] = {
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
)
524 LIBBASETYPEPTR LIBBASE
= ((struct sdcard_Unit
*)io
->io_Unit
)->sdcu_Bus
->sdcb_DeviceBase
;
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
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
);
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
554 case TD_GETDRIVETYPE
:
555 IOStdReq(io
)->io_Actual
= DRIVE_NEWSTYLE
;
558 case TD_ADDCHANGEINT
:
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.
566 if (io
->io_Command
<= (HD_SCSICMD
+ 1))
568 if (map32
[io
->io_Command
])
569 map32
[io
->io_Command
](io
, LIBBASE
);
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
);
578 cmd_Invalid(io
, LIBBASE
);
580 else cmd_Invalid(io
, LIBBASE
);
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 */
597 if (IMMEDIATE_COMMANDS
& (1 << comm
))
600 else if (comm
== NSCMD_TD_SEEK64
) slow
= FALSE
;
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
)
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 */
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
;
635 /* Put the message to the bus */
636 PutMsg(unit
->sdcu_Bus
->sdcb_MsgPort
, (struct Message
*)io
);
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
;
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
);
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__
));
660 AROS_LH1(LONG
, AbortIO
,
661 AROS_LHA(struct IORequest
*, io
, A1
),
662 LIBBASETYPEPTR
, LIBBASE
, 6, sdcard
)
666 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit
*)io
->io_Unit
)->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
668 /* Cannot Abort IO */
674 AROS_LH1(ULONG
, GetRdskLba
,
675 AROS_LHA(struct IORequest
*, io
, A1
),
676 LIBBASETYPEPTR
, LIBBASE
, 7, sdcard
)
680 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit
*)io
->io_Unit
)->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
687 AROS_LH1(ULONG
, GetBlkSize
,
688 AROS_LHA(struct IORequest
*, io
, A1
),
689 LIBBASETYPEPTR
, LIBBASE
, 8, sdcard
)
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
;