Made comments and debug output more consistent.
[AROS.git] / rom / filesys / fat / main.c
blobc60b14884126f53afee86c3fa89008e66b651f9a
1 /*
2 * fat-handler - FAT12/16/32 filesystem handler
4 * Copyright © 2006 Marek Szyprowski
5 * Copyright © 2007-2015 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>
26 #include <string.h>
28 #include "fat_fs.h"
29 #include "fat_protos.h"
31 #define DEBUG DEBUG_MISC
32 #include "debug.h"
34 #undef SysBase
35 #undef UtilityBase
37 static void InitCharsetTables(struct Globals *glob)
39 int i;
41 for (i = 0; i < 65536; i++)
43 if (i < 256)
45 glob->from_unicode[i] = i;
46 glob->to_unicode[i] = i;
48 else
49 glob->from_unicode[i] = '_';
53 static struct Globals *fat_init(struct Process *proc, struct DosPacket *dp,
54 struct ExecBase *SysBase)
56 struct Globals *glob;
58 glob = AllocVec(sizeof(struct Globals), MEMF_ANY | MEMF_CLEAR);
59 if (glob)
61 glob->gl_SysBase = SysBase;
62 if ((glob->gl_DOSBase =
63 (struct DosLibrary *)OpenLibrary("dos.library", 0)))
65 if ((glob->gl_UtilityBase = OpenLibrary("utility.library", 0)))
67 NEWLIST(&glob->sblist);
68 glob->ourtask = &proc->pr_Task;
69 glob->ourport = &proc->pr_MsgPort;
71 glob->devnode = BADDR(dp->dp_Arg3);
73 D(bug("\nFATFS: opening libraries.\n"));
74 D(bug("\tFS task: %lx, port %lx\n", glob->ourtask,
75 glob->ourport));
77 glob->notifyport = CreateMsgPort();
79 glob->fssm = BADDR(dp->dp_Arg2);
81 if ((glob->mempool = CreatePool(MEMF_PUBLIC, DEF_POOL_SIZE,
82 DEF_POOL_THRESHOLD)))
84 LONG error = InitTimer(glob);
85 if (!error)
87 InitCharsetTables(glob);
88 if ((error = InitDiskHandler(glob)) == 0)
90 return glob;
93 CleanupTimer(glob);
95 DeletePool(glob->mempool);
98 CloseLibrary(glob->gl_UtilityBase);
101 CloseLibrary((struct Library *)glob->gl_DOSBase);
104 FreeVec(glob);
107 return NULL;
110 static void fat_exit(struct Globals *glob)
112 struct ExecBase *SysBase = glob->gl_SysBase;
113 CleanupDiskHandler(glob);
114 CleanupTimer(glob);
115 DeletePool(glob->mempool);
117 DeleteMsgPort(glob->notifyport);
119 CloseLibrary(glob->gl_UtilityBase);
120 CloseLibrary((struct Library *)glob->gl_DOSBase);
122 FreeVec(glob);
125 LONG handler(struct ExecBase *SysBase)
127 struct Globals *glob;
128 struct Process *proc;
129 struct MsgPort *mp;
130 struct DosPacket *dp;
132 D(bug("%s: start\n", __func__));
134 proc = (struct Process *)FindTask(NULL);
135 mp = &proc->pr_MsgPort;
136 WaitPort(mp);
137 dp = (struct DosPacket *)GetMsg(mp)->mn_Node.ln_Name;
139 D(bug("%s: mp=%p, path='%b'\n", __func__, mp, dp->dp_Arg1));
141 glob = fat_init(proc, dp, SysBase);
143 if (!glob)
145 D(bug("%s: %b - error %d\n", __func__, dp->dp_Arg1, RETURN_FAIL));
146 dp->dp_Res1 = DOSFALSE;
147 dp->dp_Res2 = ERROR_NO_FREE_STORE;
148 ReplyPacket(dp, SysBase);
149 return RETURN_FAIL;
151 else
153 ULONG pktsig = 1 << glob->ourport->mp_SigBit;
154 ULONG diskchgsig = 1 << glob->diskchgsig_bit;
155 ULONG notifysig = 1 << glob->notifyport->mp_SigBit;
156 ULONG timersig = 1 << glob->timerport->mp_SigBit;
157 ULONG mask = pktsig | diskchgsig | notifysig | timersig;
158 ULONG sigs;
160 D(bug("\tInitiated device: %s\n",
161 AROS_BSTR_ADDR(glob->devnode->dol_Name)));
163 glob->devnode->dol_Task = glob->ourport;
165 D(bug("[fat] returning startup packet\n"));
167 dp->dp_Res1 = DOSTRUE;
168 dp->dp_Res2 = 0;
169 ReplyPacket(dp, SysBase);
171 D(bug("Handler init finished.\n"));
173 /* Insert disk */
174 ProcessDiskChange(glob);
176 while (!glob->quit)
178 sigs = Wait(mask);
179 if (sigs & diskchgsig)
180 ProcessDiskChange(glob);
181 if (sigs & pktsig)
182 ProcessPackets(glob);
183 if (sigs & notifysig)
184 ProcessNotify(glob);
185 if (sigs & timersig)
186 HandleTimer(glob);
189 D(bug("\nHandler shutdown initiated\n"));
191 dp = NULL;
193 if (glob->death_packet != NULL)
194 ReplyPacket(glob->death_packet, SysBase);
196 fat_exit(glob);
198 D(bug("The end.\n"));
200 return RETURN_OK;
203 static AROS_INTH1(DiskChangeIntHandler, struct IntData *, MyIntData)
205 AROS_INTFUNC_INIT
207 struct ExecBase *SysBase = MyIntData->SysBase;
209 Signal(MyIntData->task, MyIntData->signal);
210 return 0;
212 AROS_INTFUNC_EXIT
215 LONG InitDiskHandler(struct Globals *glob)
217 struct FileSysStartupMsg *fssm = glob->fssm;
218 LONG err;
219 ULONG diskchgintbit, flags;
220 IPTR unit;
221 UBYTE *device;
223 unit = fssm->fssm_Unit;
224 flags = fssm->fssm_Flags;
226 device = AROS_BSTR_ADDR(fssm->fssm_Device);
228 if ((diskchgintbit = AllocSignal(-1)) >= 0)
230 glob->diskchgsig_bit = diskchgintbit;
232 if ((glob->diskport = CreateMsgPort()))
235 if ((glob->diskioreq = CreateIORequest(glob->diskport,
236 sizeof(struct IOExtTD))))
238 if (OpenDevice(device, unit,
239 (struct IORequest *)glob->diskioreq, flags) == 0)
241 D(bug("\tDevice successfully opened\n"));
242 Probe_64bit_support(glob);
244 if ((glob->diskchgreq =
245 AllocVec(sizeof(struct IOExtTD), MEMF_PUBLIC)))
247 CopyMem(glob->diskioreq, glob->diskchgreq,
248 sizeof(struct IOExtTD));
250 /* Fill interrupt data */
251 glob->DiskChangeIntData.SysBase = SysBase;
252 glob->DiskChangeIntData.task = glob->ourtask;
253 glob->DiskChangeIntData.signal = 1 << diskchgintbit;
255 glob->DiskChangeIntData.Interrupt.is_Node.ln_Type =
256 NT_INTERRUPT;
257 glob->DiskChangeIntData.Interrupt.is_Node.ln_Pri =
259 glob->DiskChangeIntData.Interrupt.is_Node.ln_Name =
260 "FATFS";
261 glob->DiskChangeIntData.Interrupt.is_Data =
262 &glob->DiskChangeIntData;
263 glob->DiskChangeIntData.Interrupt.is_Code =
264 (VOID_FUNC)
265 AROS_ASMSYMNAME(DiskChangeIntHandler);
267 /* Fill I/O request data */
268 glob->diskchgreq->iotd_Req.io_Command =
269 TD_ADDCHANGEINT;
270 glob->diskchgreq->iotd_Req.io_Data =
271 &glob->DiskChangeIntData.Interrupt;
272 glob->diskchgreq->iotd_Req.io_Length =
273 sizeof(struct Interrupt);
274 glob->diskchgreq->iotd_Req.io_Flags = 0;
276 SendIO((struct IORequest *)glob->diskchgreq);
278 D(bug("\tDisk change interrupt handler installed\n"));
280 return 0;
282 else
283 err = ERROR_NO_FREE_STORE;
285 CloseDevice((struct IORequest *)glob->diskioreq);
287 else
288 err = ERROR_DEVICE_NOT_MOUNTED;
290 DeleteIORequest(glob->diskioreq);
291 glob->diskioreq = NULL;
293 else
294 err = ERROR_NO_FREE_STORE;
296 DeleteMsgPort(glob->diskport);
297 glob->diskport = NULL;
299 else
300 err = ERROR_NO_FREE_STORE;
302 FreeSignal(diskchgintbit);
304 glob->diskchgsig_bit = 0;
306 else
307 err = ERROR_NO_FREE_STORE;
309 return err;
312 void CleanupDiskHandler(struct Globals *glob)
314 D(bug("\tFreeing handler resources:\n"));
316 /* Remove disk change interrupt */
317 glob->diskchgreq->iotd_Req.io_Command = TD_REMCHANGEINT;
318 glob->diskchgreq->iotd_Req.io_Data = &glob->DiskChangeIntData.Interrupt;
319 glob->diskchgreq->iotd_Req.io_Length = sizeof(struct Interrupt);
320 glob->diskchgreq->iotd_Req.io_Flags = 0;
322 DoIO((struct IORequest *)glob->diskchgreq);
323 D(bug("\tDisk change interrupt handler removed\n"));
325 CloseDevice((struct IORequest *)glob->diskioreq);
326 DeleteIORequest(glob->diskioreq);
327 FreeVec(glob->diskchgreq);
328 DeleteMsgPort(glob->diskport);
329 D(bug("\tDevice closed\n"));
331 glob->diskioreq = NULL;
332 glob->diskchgreq = NULL;
333 glob->diskport = NULL;
335 FreeSignal(glob->diskchgsig_bit);
337 D(bug("\tDone.\n"));