Don't use RTF_AUTOINIT

When using autoinit the mounter would mount the devices before the device is added to execs Device list

Before DOS is started (like rom boot) this is not a problem because the device will be added to the list before DOS is started

After DOS is started though it becomes a problem, dos will try to OpenDevice() the device before it is even on the Device List
This commit is contained in:
Matt Harlum 2025-06-27 10:31:38 +00:00
parent aa9bc3ce2f
commit d4bd1050ff
5 changed files with 55 additions and 34 deletions

BIN
examples/spisd/bootrom/spisd.rom Executable file

Binary file not shown.

View File

@ -55,7 +55,7 @@ static volatile ULONG card_change_num;
static struct Interrupt *remove_int;
static struct IOStdReq *change_int;
void mount(__reg("a6") struct ExecBase *SysBase, __reg("a1") struct ConfigDev *cd, __reg("a0") struct Library *device);
void mount(__reg("a6") struct ExecBase *SysBase, __reg("a1") struct ConfigDev *cd, __reg("a0") char *deviceName);
static uint32_t device_get_geometry(struct IOStdReq *ior)
{
@ -175,7 +175,9 @@ static void init_iomp(struct Task *self) {
static void task_run()
{
struct Task *self = FindTask(0);
struct Task *parent = (struct Task *)self->tc_UserData;
volatile struct Task *parent = (struct Task *)self->tc_UserData;
Forbid();
if ((AllocSignal(SIGB_CARD_CHANGE)) == -1) Alert(0xBADBEEF);
if ((AllocSignal(SIGB_OP_REQUEST)) == -1) Alert(0xBADBEEF);
@ -187,7 +189,9 @@ static void task_run()
if (card_present && sd_open() == 0)
card_opened = TRUE;
Signal(parent,SIGF_SINGLE);
Permit();
Signal((struct Task *)parent,SIGF_SINGLE);
while (1)
{
@ -342,6 +346,8 @@ static struct Library *init_device(__reg("a6") struct ExecBase *sys_base, __reg(
SysBase = *(struct ExecBase **)4;
saved_seg_list = seg_list;
card_opened = FALSE;
dev->lib_Node.ln_Type = NT_DEVICE;
dev->lib_Node.ln_Name = device_name;
dev->lib_Flags = LIBF_SUMUSED | LIBF_CHANGED;
@ -370,8 +376,6 @@ static struct Library *init_device(__reg("a6") struct ExecBase *sys_base, __reg(
Permit();
Wait(SIGF_SINGLE); // Wait for task to be ready
mount(SysBase,NULL,dev);
return dev;
fail3:
@ -446,10 +450,24 @@ static ULONG device_vectors[] =
-1,
};
ULONG auto_init_tables[] =
{
sizeof(struct Library),
(ULONG)device_vectors,
0,
(ULONG)init_device,
};
/**
* init
*
* Make the Device, add it and then call mounter
*
* Since Mounter uses OpenDevice() we cannot use RTF_AUTOINIT
*/
struct Library *init(__reg("a0") BPTR seglist) {
struct ExecBase *SysBase = *(struct ExecBase **)4UL;
struct Library *mydev = MakeLibrary((ULONG *)&device_vectors,
NULL,
(APTR)init_device,
sizeof(struct Library),
seglist);
if (mydev) {
AddDevice((struct Device *)mydev);
mount(SysBase,NULL,mydev->lib_Node.ln_Name);
}
return mydev;
}

View File

@ -20,9 +20,8 @@
; Frame pointer vars
MB_CD EQU -4 ; ConfigDev
MB_DEVICE EQU MB_CD-4 ; Device pointer
MB_DEVNAME EQU MB_DEVICE-4
MB_IOREQ EQU MB_DEVNAME-IOSTD_SIZE ; IORequest structure (48 bytes)
MB_DEVICE EQU MB_CD-4 ; Device Name
MB_IOREQ EQU MB_DEVICE-IOSTD_SIZE ; IORequest structure (48 bytes)
MB_MP EQU MB_IOREQ-MP_SIZE ; MsgPort structure (34 bytes)
MB_BLOCKSHIFT EQU MB_MP-2
MB_BLOCKSIZE EQU MB_BLOCKSHIFT-4 ; Blocksize
@ -60,7 +59,7 @@ MB_SIZE EQU -(MB_FSRES) ; Total frame size
; The function handles both Kickstart 1.3 and 2.x+ mounting protocols.
;
; INPUTS:
; A0.L - Device base
; A0.L - Device name (null-terminated string, e.g., "scsi.device")
; A1.L - ConfigDev structure pointer (from expansion board, NULL to create fake)
; A6.L - Pointer to exec.library base
;
@ -70,11 +69,21 @@ MB_SIZE EQU -(MB_FSRES) ; Total frame size
; REGISTER USAGE DURING EXECUTION:
; D2.L - Current unit number being processed
; D3.L - Return code accumulator
; A2.L - Device base pointer
; A2.L - Device name string pointer
; A3.L - ConfigDev structure pointer
; A4.L - ExpansionBase pointer (when expansion.library is open)
; A5.L - Frame pointer for local variable access
; A6.L - SysBase (exec.library base)
;
; STACK FRAME LAYOUT:
; MB_CD(-4): ConfigDev pointer
; MB_DEVICE(-8): Device name pointer
; MB_IOREQ(-56): IOStdReq structure for device I/O
; MB_MP(-90): MsgPort structure for async I/O
; MB_BLOCKSHIFT(-92): Block size shift value for address calculations
; MB_BLOCKSIZE(-96): Device block size in bytes
; MB_FSHB(-100): First filesystem header block pointer
; MB_FSRES(-104): FileSystem.resource pointer
;******************************************************************************
_mount: movem.l d2-d7/a2-a6,-(sp)
move.l a0,a2
@ -89,14 +98,13 @@ _mount: movem.l d2-d7/a2-a6,-(sp)
.zero clr.l -(a0)
dbra d0,.zero
move.l a2,MB_DEVICE(a5) ; Save Device pointer
move.l LN_NAME(a2),MB_DEVNAME(a5)
move.l a2,MB_DEVICE(a5) ; Save Device name
; Initialize MsgPort
lea.l MB_MP(a5),a0
bsr.w InitMP
tst.b d0
bmi.w .end
bmi.s .end
; Init IOReq
lea.l MB_IOREQ(a5),a0
@ -114,25 +122,19 @@ _mount: movem.l d2-d7/a2-a6,-(sp)
move.l a3,d0 ; Was a configDev provided?
beq .noconfigdev
move.l a3,MB_CD(a5)
bra.s .start
bra .start
.noconfigdev: bsr FakeConfigDev ; No configDev, create a fake one
move.l a1,MB_CD(a5)
.start: moveq #-1,d2 ; Start scanning units
.unitloop: add.l #1,d2 ; Start at unit 0
; Open the device
move.l a2,a0 ; Device name
move.l d2,d0 ; Unit
lea.l MB_IOREQ(a5),a1 ; IOStdReq
move.l MB_DEVICE(a5),IO_DEVICE(a1) ; Populate IO_DEVICE (required when calling open directly)
clr.l d1 ; Flags
exg a2,a6 ; Device <==> SysBase
jsr LIB_OPEN(a6) ; Call the devices Open() vector directly
exg a2,a6 ; SysBase <==> Device
lea.l MB_IOREQ(a5),a0
move.b IO_ERROR(a0),d0 ; Check IO Error
jsr _LVOOpenDevice(a6)
tst.b d0
beq.s .OpenOK
cmp.b #TDERR_BadUnitNum,d0 ; No unit here but there are others
@ -564,7 +566,7 @@ ProcessPart: movem.l a2-a3/d2-d5,-(sp)
move.b (a1)+,d0 ; Convert to C str
move.b #0,0(a1,d0.w) ; Null Terminate
move.l a1,(a0) ; Set drive name in param packet
move.l MB_DEVNAME(a5),4(a0) ; Set Device name
move.l MB_DEVICE(a5),4(a0) ; Set Device name
move.l d5,8(a0) ; Set the unit number
move.l #0,12(a0) ; Set flags
@ -995,7 +997,7 @@ LoadFS: movem.l d2/a2/a4,-(sp)
moveq #11,d1 ; Copy relevant fields
.copy: move.l (a0)+,(a4)+
dbf d1,.copy
move.l MB_DEVNAME(a5),LN_NAME(a1)
move.l MB_DEVICE(a5),LN_NAME(a1)
move.l d2,fse_SegList(a1) ; Patch in the new seglist
lea.l fsr_FileSysEntries(a2),a0
jsr _LVOAddHead(a6) ; Add it to the head of FileSysEntries

View File

@ -1,10 +1,11 @@
#include <exec/types.h>
#include <exec/resident.h>
#include <exec/nodes.h>
#include <dos/dos.h>
#include "version.h"
extern ULONG auto_init_tables[];
extern struct Library *init(__reg("a1") BPTR seg_list);
LONG noexec(void) {
return -1;
@ -16,11 +17,11 @@ const struct Resident romtag =
.rt_MatchWord = RTC_MATCHWORD,
.rt_MatchTag = (void *)&romtag,
.rt_EndSkip = &romtag + 1,
.rt_Flags = RTF_AUTOINIT,
.rt_Flags = RTF_COLDSTART,
.rt_Version = VERSION,
.rt_Type = NT_DEVICE,
.rt_Pri = 10,
.rt_Name = device_name,
.rt_IdString = id_string,
.rt_Init = auto_init_tables
.rt_Init = (APTR)init,
};

BIN
examples/spisd/spisd.device Executable file

Binary file not shown.