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 if ((unit
->sdcu_Flags
& (AF_Card_WriteProtect
|AF_Card_Locked
)) != 0)
369 IOStdReq(io
)->io_Actual
= -1;
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__
));
388 AddHead(&unit
->sdcu_SoftList
, (struct Node
*)io
);
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__
));
400 Remove((struct Node
*)io
);
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;
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
;
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
[] = {
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
)
547 LIBBASETYPEPTR LIBBASE
= ((struct sdcard_Unit
*)io
->io_Unit
)->sdcu_Bus
->sdcb_DeviceBase
;
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
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
);
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
577 case TD_GETDRIVETYPE
:
578 IOStdReq(io
)->io_Actual
= DRIVE_NEWSTYLE
;
581 case TD_ADDCHANGEINT
:
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.
589 if (io
->io_Command
<= (HD_SCSICMD
+ 1))
591 if (map32
[io
->io_Command
])
592 map32
[io
->io_Command
](io
, LIBBASE
);
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
);
601 cmd_Invalid(io
, LIBBASE
);
603 else cmd_Invalid(io
, LIBBASE
);
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 */
620 if (IMMEDIATE_COMMANDS
& (1 << comm
))
623 else if (comm
== NSCMD_TD_SEEK64
) slow
= FALSE
;
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
)
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 */
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
;
658 /* Put the message to the bus */
659 PutMsg(unit
->sdcu_Bus
->sdcb_MsgPort
, (struct Message
*)io
);
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
;
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
);
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__
));
683 AROS_LH1(LONG
, AbortIO
,
684 AROS_LHA(struct IORequest
*, io
, A1
),
685 LIBBASETYPEPTR
, LIBBASE
, 6, sdcard
)
689 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit
*)io
->io_Unit
)->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
691 /* Cannot Abort IO */
697 AROS_LH1(ULONG
, GetRdskLba
,
698 AROS_LHA(struct IORequest
*, io
, A1
),
699 LIBBASETYPEPTR
, LIBBASE
, 7, sdcard
)
703 D(bug("[SDCard%02ld] %s()\n", ((struct sdcard_Unit
*)io
->io_Unit
)->sdcu_UnitNum
, __PRETTY_FUNCTION__
));
710 AROS_LH1(ULONG
, GetBlkSize
,
711 AROS_LHA(struct IORequest
*, io
, A1
),
712 LIBBASETYPEPTR
, LIBBASE
, 8, sdcard
)
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
;