2 * This hook is called after dos.library wakes up.
3 * Its job is to load all queued filesystems and add to the system.
6 #include <aros/asmcall.h>
7 #include <aros/debug.h>
8 #include <exec/resident.h>
9 #include <resources/filesysres.h>
10 #include <proto/alib.h>
11 #include <proto/dos.h>
12 #include <proto/exec.h>
13 #include <proto/partition.h>
15 #include "partition_support.h"
18 extern const UBYTE Partition_LibID
[];
19 extern int Partition_End
;
21 AROS_UFP3(static APTR
, FSLoader_Init
,
22 AROS_UFPA(void *, dummy1
, D0
),
23 AROS_UFPA(BPTR
, dummy2
, A0
),
24 AROS_UFPA(struct ExecBase
*, SysBase
, A6
));
27 * This ROMTag is placed in the file after the first one,
28 * provided by genmodule. rt_Skip of that ROMTag points to
29 * our one. This is specified in .conf * file (addromtag option).
30 * It needs to be in this way because disk-based library loader
31 * will find and initialize only the first ROMTag in the file.
32 * It must be the main library's ROMTag in order for disk-based library
35 const struct Resident FSLoader_resident
=
38 (struct Resident
*)&FSLoader_resident
,
43 -121, /* dos.library corresponds to -120 and is run manually. We can run next. */
45 &Partition_LibID
[6], /* This points to partition.library version string */
49 AROS_UFH3(static APTR
, FSLoader_Init
,
50 AROS_UFHA(void *, dummy1
, D0
),
51 AROS_UFHA(BPTR
, dummy2
, A0
),
52 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
56 struct BootFileSystem
*bfs
, *bfs2
;
57 struct PartitionBase_intern
*PartitionBase
= (struct PartitionBase_intern
*)OpenLibrary("partition.library", 2);
62 /* We should really have dos.library online now */
63 PartitionBase
->pb_DOSBase
= OpenLibrary("dos.library", 36);
64 D(bug("[FSLoader] DOSBase 0x%p\n", PartitionBase
->pb_DOSBase
));
66 if (PartitionBase
->pb_DOSBase
)
68 ForeachNodeSafe(&PartitionBase
->bootList
, bfs
, bfs2
)
71 * Unfortunately we have no way to process errors here.
72 * Well, let's hope that everything will be okay.
74 D(bug("[FSLoader] Loading %s...\n", bfs
->ln
.ln_Name
));
76 AddFS(&PartitionBase
->partbase
.lib
, bfs
->handle
);
77 bfs
->handle
->handler
->freeFileSystem(bfs
->handle
);
78 FreeMem(bfs
, sizeof(struct BootFileSystem
));
81 /* All nodes are already freed, reinitialize the list */
82 NewList(&PartitionBase
->bootList
);
85 CloseLibrary(&PartitionBase
->partbase
.lib
);
91 static struct FileSysEntry
*FindResidentFS(struct FileSysResource
*fsr
, ULONG dostype
, ULONG version
)
93 struct FileSysEntry
*fsrnode
;
95 ForeachNode(&fsr
->fsr_FileSysEntries
, fsrnode
)
97 if (fsrnode
->fse_DosType
== dostype
&& fsrnode
->fse_Version
>= version
)
104 ULONG
AddFS(struct Library
*PartitionBase
, struct FileSysHandle
*fs
)
106 struct DosLibrary
*DOSBase
= (struct DosLibrary
*)((struct PartitionBase_intern
*)PartitionBase
)->pb_DOSBase
;
107 struct FileSysResource
*fsr
;
108 struct FileSysEntry
*fsrnode
;
112 fsr
= OpenResource("FileSystem.resource");
114 return ERROR_INVALID_RESIDENT_LIBRARY
;
116 GetFileSystemAttrs(&fs
->ln
, FST_ID
, &dostype
, FST_VERSION
, &version
, TAG_DONE
);
119 * First we want to check if we already have this filesystem in the resource.
120 * Unfortunately the resource doesn't have any locking, so we have to use
121 * Forbid()/Permit() pair. In order not to hold it for a while, we repeat
122 * the check below after loading the handler (to eliminate race condition
123 * when someone loads newer version of the filesystem that we are loading
127 fsrnode
= FindResidentFS(fsr
, dostype
, version
);
131 return ERROR_OBJECT_EXISTS
;
133 fsrnode
= AllocVec(sizeof(struct FileSysEntry
), MEMF_PUBLIC
| MEMF_CLEAR
);
135 return ERROR_NO_FREE_STORE
;
137 GetFileSystemAttrs(&fs
->ln
, FST_FSENTRY
, fsrnode
, TAG_DONE
);
138 fsrnode
->fse_SegList
= LoadFileSystem(&fs
->ln
);
141 * FIXME: Name of the filesystem is currently not filled in.
142 * I left it this way just because this was originally done in m68k-specific hack.
143 * May be it should be added?
146 if (fsrnode
->fse_SegList
)
148 struct FileSysEntry
*dup
;
151 * Repeat checking, and insert the filesystem only if still not found.
152 * If found, unload our seglist and return error.
153 * This really sucks but nothing can be done with it. Even if we implement
154 * a global semaphore on the resource original m68k software won't know
159 dup
= FindResidentFS(fsr
, dostype
, version
);
162 * Entries in the list are not sorted by priority.
163 * Adding to head makes them sorted by version.
165 AddHead(&fsr
->fsr_FileSysEntries
, &fsrnode
->fse_Node
);
171 UnLoadSeg(fsrnode
->fse_SegList
);
174 return ERROR_OBJECT_EXISTS
;
180 /* InternalLoadSeg() will leave its error code in IoErr() */