Minor fixes to comments.
[AROS.git] / rom / filesys / fat / main.c
blob50b586fcf14fe8fa5a3c91c7ebbd902e4c43de4e
1 /*
2 * fat.handler - FAT12/16/32 filesystem handler
4 * Copyright © 2006 Marek Szyprowski
5 * Copyright © 2007-2011 The AROS Development Team
7 * This program is free software; you can redistribute it and/or modify it
8 * under the same terms as AROS itself.
10 * $Id$
13 #include <aros/asmcall.h>
14 #include <aros/macros.h>
15 #include <exec/types.h>
16 #include <exec/execbase.h>
17 #include <exec/memory.h>
18 #include <dos/dos.h>
19 #include <dos/dosextens.h>
20 #include <dos/dostags.h>
21 #include <dos/filehandler.h>
22 #include <devices/trackdisk.h>
24 #include <proto/exec.h>
25 #include <proto/dos.h>
27 #include <string.h>
29 #include "fat_fs.h"
30 #include "fat_protos.h"
31 #include "charset.h"
33 #define DEBUG DEBUG_MISC
34 #include "debug.h"
36 struct DosLibrary *DOSBase;
37 struct Library *UtilityBase;
38 struct Library *IntuitionBase;
40 struct Globals global_data;
41 struct Globals *glob = &global_data;
43 const TEXT version_string[] = "$VER: fat.handler 41.52 (28.12.2011)";
45 LONG handler(struct ExecBase *SysBase) {
46 struct Message *msg;
47 struct DosPacket *startuppacket;
48 LONG error = ERROR_NO_FREE_STORE;
50 memset(glob, 0, sizeof(struct Globals));
51 NEWLIST(&glob->sblist);
52 glob->ourtask = FindTask(NULL);
53 glob->ourport = &((struct Process *)glob->ourtask)->pr_MsgPort;
54 WaitPort(glob->ourport);
56 msg = GetMsg(glob->ourport);
57 startuppacket = (struct DosPacket *) msg->mn_Node.ln_Name;
58 glob->devnode = BADDR(startuppacket->dp_Arg3);
60 D(bug("\nFATFS: opening libraries.\n"));
61 D(bug("\tFS task: %lx, port %lx\n", glob->ourtask, glob->ourport));
63 glob->notifyport = CreateMsgPort();
65 if ((DOSBase = (struct DosLibrary*)OpenLibrary("dos.library", 37))) {
66 if ((IntuitionBase = OpenLibrary("intuition.library", 37))) {
67 if ((UtilityBase = OpenLibrary("utility.library", 37))) {
68 glob->fssm = BADDR(startuppacket->dp_Arg2);
70 if ((glob->mempool = CreatePool(MEMF_PUBLIC, DEF_POOL_SIZE, DEF_POOL_THRESHOLD))) {
72 error = InitTimer();
73 if (!error) {
74 InitCharsetTables();
75 if ((error = InitDiskHandler(glob->fssm)) == 0) {
76 ULONG pktsig = 1 << glob->ourport->mp_SigBit;
77 ULONG diskchgsig = 1 << glob->diskchgsig_bit;
78 ULONG notifysig = 1 << glob->notifyport->mp_SigBit;
79 ULONG timersig = 1 << glob->timerport->mp_SigBit;
80 ULONG mask = pktsig | diskchgsig | notifysig | timersig;
81 ULONG sigs;
82 struct MsgPort *rp;
84 D(bug("\tInitiated device: %s\n", AROS_BSTR_ADDR(glob->devnode->dol_Name)));
86 glob->devnode->dol_Task = glob->ourport;
88 D(bug("[fat] returning startup packet\n"));
90 rp = startuppacket->dp_Port;
91 startuppacket->dp_Port = glob->ourport;
92 startuppacket->dp_Res1 = DOSTRUE;
93 startuppacket->dp_Res2 = 0;
94 PutMsg(rp, startuppacket->dp_Link);
96 D(bug("Handler init finished.\n"));
98 ProcessDiskChange(); /* insert disk */
100 while(!glob->quit) {
101 sigs = Wait(mask);
102 if (sigs & diskchgsig)
103 ProcessDiskChange();
104 if (sigs & pktsig)
105 ProcessPackets();
106 if (sigs & notifysig)
107 ProcessNotify();
108 if (sigs & timersig)
109 HandleTimer();
112 D(bug("\nHandler shutdown initiated\n"));
114 error = 0;
115 startuppacket = NULL;
117 CleanupDiskHandler();
119 CleanupTimer();
121 DeletePool(glob->mempool);
123 else
124 error = ERROR_NO_FREE_STORE;
126 CloseLibrary(UtilityBase);
128 CloseLibrary(IntuitionBase);
130 CloseLibrary((struct Library*)DOSBase);
133 DeleteMsgPort(glob->notifyport);
135 if (glob->death_packet != NULL)
136 ReplyPacket(glob->death_packet);
138 D(bug("The end.\n"));
140 if (startuppacket != NULL) {
141 D(bug("[fat] returning startup packet\n"));
143 startuppacket->dp_Res1 = DOSTRUE;
144 startuppacket->dp_Res2 = 0;
145 ReplyPacket(startuppacket);
148 return RETURN_OK;
151 static struct IntData {
152 struct Interrupt Interrupt;
153 struct ExecBase *SysBase;
154 struct Task *task;
155 ULONG signal;
156 } DiskChangeIntData;
158 static AROS_INTH1(DiskChangeIntHandler, struct IntData *, MyIntData)
160 AROS_INTFUNC_INIT
162 struct ExecBase *SysBase = MyIntData->SysBase;
164 Signal(MyIntData->task, MyIntData->signal);
165 return 0;
167 AROS_INTFUNC_EXIT
170 LONG InitDiskHandler (struct FileSysStartupMsg *fssm) {
171 LONG err;
172 ULONG diskchgintbit, flags;
173 IPTR unit;
174 UBYTE *device;
176 unit = fssm->fssm_Unit;
177 flags = fssm->fssm_Flags;
179 device = AROS_BSTR_ADDR(fssm->fssm_Device);
181 if ((diskchgintbit = AllocSignal(-1)) >= 0) {
182 glob->diskchgsig_bit = diskchgintbit;
184 if ((glob->diskport = CreateMsgPort())) {
186 if ((glob->diskioreq = CreateIORequest(glob->diskport, sizeof(struct IOExtTD)))) {
188 if (OpenDevice(device, unit, (struct IORequest *)glob->diskioreq, flags) == 0) {
189 D(bug("\tDevice successfully opened\n"));
190 Probe_64bit_support();
192 if ((glob->diskchgreq = AllocVec(sizeof(struct IOExtTD), MEMF_PUBLIC))) {
193 CopyMem(glob->diskioreq, glob->diskchgreq, sizeof(struct IOExtTD));
195 /* fill interrupt data */
196 DiskChangeIntData.SysBase = SysBase;
197 DiskChangeIntData.task = glob->ourtask;
198 DiskChangeIntData.signal = 1 << diskchgintbit;
200 DiskChangeIntData.Interrupt.is_Node.ln_Type = NT_INTERRUPT;
201 DiskChangeIntData.Interrupt.is_Node.ln_Pri = 0;
202 DiskChangeIntData.Interrupt.is_Node.ln_Name = "FATFS";
203 DiskChangeIntData.Interrupt.is_Data = &DiskChangeIntData;
204 DiskChangeIntData.Interrupt.is_Code = (VOID_FUNC)AROS_ASMSYMNAME(DiskChangeIntHandler);
206 /* fill io request data */
207 glob->diskchgreq->iotd_Req.io_Command = TD_ADDCHANGEINT;
208 glob->diskchgreq->iotd_Req.io_Data = &DiskChangeIntData.Interrupt;
209 glob->diskchgreq->iotd_Req.io_Length = sizeof(struct Interrupt);
210 glob->diskchgreq->iotd_Req.io_Flags = 0;
212 SendIO((struct IORequest*)glob->diskchgreq);
214 D(bug("\tDisk change interrupt handler installed\n"));
216 return 0;
218 else
219 err = ERROR_NO_FREE_STORE;
221 CloseDevice((struct IORequest *)glob->diskioreq);
223 else
224 err = ERROR_DEVICE_NOT_MOUNTED;
226 DeleteIORequest(glob->diskioreq);
227 glob->diskioreq = NULL;
229 else
230 err = ERROR_NO_FREE_STORE;
232 DeleteMsgPort(glob->diskport);
233 glob->diskport = NULL;
235 else
236 err = ERROR_NO_FREE_STORE;
238 FreeSignal(diskchgintbit);
240 glob->diskchgsig_bit = 0;
242 else
243 err = ERROR_NO_FREE_STORE;
245 return err;
248 void CleanupDiskHandler(void) {
249 D(bug("\tFreeing handler resources:\n"));
251 /* remove disk change interrupt */
252 glob->diskchgreq->iotd_Req.io_Command = TD_REMCHANGEINT;
253 glob->diskchgreq->iotd_Req.io_Data = &DiskChangeIntData.Interrupt;
254 glob->diskchgreq->iotd_Req.io_Length = sizeof(struct Interrupt);
255 glob->diskchgreq->iotd_Req.io_Flags = 0;
257 DoIO((struct IORequest*)glob->diskchgreq);
258 D(bug("\tDisk change interrupt handler removed\n"));
260 CloseDevice((struct IORequest *)glob->diskioreq);
261 DeleteIORequest(glob->diskioreq);
262 FreeVec(glob->diskchgreq);
263 DeleteMsgPort(glob->diskport);
264 D(bug("\tDevice closed\n"));
266 glob->diskioreq = NULL;
267 glob->diskchgreq = NULL;
268 glob->diskport = NULL;
270 FreeSignal(glob->diskchgsig_bit);
272 D(bug("\tDone.\n"));