2 Copyright � 2013, The AROS Development Team. All rights reserved.
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>
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>
24 #include "sdcard_base.h"
25 #include "sdcard_unit.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
;
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
;
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
);
76 block
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
77 count
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
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
;
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
;
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
;
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
;
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
);
132 block
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
133 count
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
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
;
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
;
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
;
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
;
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
);
185 block
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
186 count
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
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
;
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
;
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
;
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
;
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
;
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
);
249 block
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
250 count
>>= unit
->sdcu_Bus
->sdcb_SectorShift
;
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
;
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__
));
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
);
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
++;
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
;
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
;
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;
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;
373 if ((unit
->sdcu_Flags
& (AF_Card_WriteProtect
|AF_Card_Locked
)) != 0)
374 IOStdReq(io
)->io_Actual
= -1;
376 IOStdReq(io
)->io_Actual
= 0;
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__
));
395 AddHead(&unit
->sdcu_SoftList
, (struct Node
*)io
);
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__
));
407 Remove((struct Node
*)io
);
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;
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
;
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
[] = {
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
)
554 LIBBASETYPEPTR LIBBASE
= ((struct sdcard_Unit
*)io
->io_Unit
)->sdcu_Bus
->sdcb_DeviceBase
;
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
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
);
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
584 case TD_GETDRIVETYPE
:
585 IOStdReq(io
)->io_Actual
= DRIVE_NEWSTYLE
;
588 case TD_ADDCHANGEINT
:
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.
596 if (io
->io_Command
<= (HD_SCSICMD
+ 1))
598 if (map32
[io
->io_Command
])
599 map32
[io
->io_Command
](io
, LIBBASE
);
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
);
608 cmd_Invalid(io
, LIBBASE
);
610 else cmd_Invalid(io
, LIBBASE
);
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 */
624 /* For commands with numbers <= 31 check the mask */
627 if (IMMEDIATE_COMMANDS
& (1 << comm
))
630 else if (comm
== NSCMD_TD_SEEK64
) slow
= FALSE
;
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
)
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 */
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
;
665 /* Put the message to the bus */
666 PutMsg(unit
->sdcu_Bus
->sdcb_MsgPort
, (struct Message
*)io
);
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
;
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
);
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__
));
690 AROS_LH1(LONG
, AbortIO
,
691 AROS_LHA(struct IORequest
*, io
, A1
),
692 LIBBASETYPEPTR
, LIBBASE
, 6, sdcard
)
696 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit
*)io
->io_Unit
)->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
698 /* Cannot Abort IO */
704 AROS_LH1(ULONG
, GetRdskLba
,
705 AROS_LHA(struct IORequest
*, io
, A1
),
706 LIBBASETYPEPTR
, LIBBASE
, 7, sdcard
)
710 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit
*)io
->io_Unit
)->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
717 AROS_LH1(ULONG
, GetBlkSize
,
718 AROS_LHA(struct IORequest
*, io
, A1
),
719 LIBBASETYPEPTR
, LIBBASE
, 8, sdcard
)
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
;