includes: AROS_UFIxx -> AROS_INTxx change
[AROS.git] / rom / filesys / pfs3 / fs / init.c
blob654cfd87ab80c02b36fd78afdb55ff841917b94a
1 /* $Id: init.c 12.9 1999/09/11 17:05:14 Michiel Exp Michiel $ */
2 /* $Log: init.c $
3 * Revision 12.9 1999/09/11 17:05:14 Michiel
4 * bugfix version 18.4
6 * Revision 12.8 1999/05/14 11:31:34 Michiel
7 * Long filename support implemented; bugfixes
9 * Revision 12.7 1999/02/22 16:25:30 Michiel
10 * Changes for increasing deldir capacity
12 * Revision 12.6 1998/09/27 11:26:37 Michiel
13 * Memory allocation mask check removed (issue 00126)
14 * ErrorMsg param
16 * Revision 12.5 1998/09/03 07:12:14 Michiel
17 * versie 17.4
18 * bugfixes 118, 121, 123 and superindexblocks and td64 support
20 * Revision 12.4 1998/05/27 21:07:28 Mark
21 * Added second DMAMask failover to include MEMF_LOCAL
23 * Revision 12.3 1997/03/03 22:04:04 Michiel
24 * Release 16.21
26 * Revision 12.2 1996/03/07 10:05:24 Michiel
27 * format fix (wt)
29 * Revision 12.1 1995/11/15 15:50:20 Michiel
30 * Postponed operation handler 'DoPostponed' added
32 * Revision 11.17 1995/11/07 14:59:20 Michiel
33 * initialization of new datacache (version 16.2)
35 * Revision 11.16 1995/10/04 14:03:53 Michiel
36 * using new memorypool functions (from support.c 10.9)
38 * Revision 11.15 1995/09/01 11:19:39 Michiel
39 * ErrorMsg adaption (see disk.c and volume.c)
41 * Revision 11.14 1995/08/21 04:21:36 Michiel
42 * Initialise now creates the sleepport for MODE_SLEEP
44 * Revision 11.13 1995/07/17 12:22:34 Michiel
45 * AFS User adaptions
47 * Revision 11.12 1995/07/11 17:29:31 Michiel
48 * ErrorMsg () calls use messages.c variables now.
50 * Revision 11.11 1995/07/11 09:23:36 Michiel
51 * DELDIR stuff
53 * Revision 11.10 1995/07/07 14:39:17 Michiel
54 * AFSLITE stuff
56 * Revision 11.9 1995/06/16 10:01:02 Michiel
57 * added pool for buffer memory
59 * Revision 11.8 1995/06/15 18:56:09 Michiel
60 * pooled mem
62 * Revision 11.7 1995/05/20 12:12:12 Michiel
63 * Updated messages to reflect Ami-FileLock
64 * CUTDOWN version
65 * protection update
67 * Revision 11.6 1995/03/30 18:57:49 Michiel
68 * Initialization of notifyport added
69 * Myproc has come back (for diskchangeint)
71 * Revision 11.5 1995/02/28 18:34:03 Michiel
72 * MODE_HARDDISK, MDOE_SPLITTED_ANODES and MODE_DIR_EXTENSION added
74 * Revision 11.4 1995/02/15 16:43:39 Michiel
75 * Release version
76 * Using new headers (struct.h & blocks.h)
78 * Revision 11.3 1995/01/29 07:34:57 Michiel
79 * Datacache now is BufMemType
80 * Blockshift, directsize init added
82 * Revision 11.2 1995/01/15 05:25:29 Michiel
83 * now always sets removable to true to
84 * accommodate Syquest & Floptical
86 * Revision 11.1 1995/01/08 16:21:28 Michiel
87 * Compiled (new MODE_BIG version)
88 * added InitModules
90 * Revision 10.4 1994/11/15 17:52:30 Michiel
91 * *** empty log message ***
93 * Revision 10.3 1994/10/29 08:54:34 Michiel
94 * changed process references to msgport references
96 * Revision 10.2 1994/10/27 11:31:46 Michiel
97 * *** empty log message ***
99 * Revision 10.1 1994/10/24 11:04:22 Michiel
100 * first RCS revision
101 * */
103 #define __USE_SYSBASE
105 #include <exec/types.h>
106 #include <exec/memory.h>
107 #include <exec/devices.h>
108 #include <exec/interrupts.h>
109 #include <exec/execbase.h>
110 #include <exec/resident.h>
111 #include <devices/timer.h>
112 #include <dos/filehandler.h>
113 #include <resources/filesysres.h>
114 #include <clib/alib_protos.h>
116 #include <string.h>
117 #include "debug.h"
119 /* own includes */
120 #include "blocks.h"
121 #include "struct.h"
122 #include "versionhistory.doc"
123 #include "init_protos.h"
124 #include "volume_protos.h"
125 #include "anodes_protos.h"
126 #include "directory_protos.h"
127 #include "lru_protos.h"
128 #include "allocation_protos.h"
130 /* external globals
132 extern CONST UBYTE *version;
133 extern AROS_INTP(DiskChangeHandler);
135 /* prototypes
137 static BOOL OpenDiskDevice(struct FileSysStartupMsg * , struct MsgPort ** , struct IOExtTD **, BOOL *, globaldata *);
138 static BOOL OpenTimerDevice(struct MsgPort ** , struct timerequest ** , ULONG, globaldata * );
139 static BOOL TestRemovability(globaldata *);
140 static void InstallDiskChangeHandler(globaldata *);
141 static BOOL AddToFSResource(ULONG, BPTR, globaldata *);
142 #if VERSION23
143 static void DoPostponed (struct volumedata *volume, globaldata *g);
144 #endif
146 /**********************************************************************/
147 /* INITIALIZE */
148 /* INITIALIZE */
149 /* INITIALIZE */
150 /**********************************************************************/
152 #ifdef DEBUGMODE
153 BOOL Initialize(DSTR mountname, struct FileSysStartupMsg *fssm,
154 struct DeviceNode *devnode, globaldata *g)
156 return(TRUE);
158 #else
159 BOOL Initialize(DSTR mountname, struct FileSysStartupMsg *fssm,
160 struct DeviceNode *devnode, globaldata *g)
162 LONG i;
163 ULONG t;
165 ENTER("Initialize");
166 g->ErrorMsg = _NormalErrorMsg;
168 /* mountname can be something like "pfs:hello". I only need
169 ** the "pfs" part. <i> will be the mountnamelen.
170 ** sizeof(mountname) MUST be >0
173 for (i=1; i<*mountname+1 && mountname[i]!=':'; i++);
174 /* now mountname[i]==':' || i==*mountname+1 ==> i=sizeof(mnname) */
175 g->mountname = AllocMemR (i, 0, g);
176 g->mountname[0] = i-1;
177 CopyMem(mountname+1, g->mountname+1, i-1);
179 /* allocate messageport for notify */
180 g->notifyport = CreateMsgPort();
182 g->myproc = (struct Process *)FindTask(NULL);
183 g->msgport = devnode->dn_Task;
184 g->devnode = devnode;
185 g->startup = fssm;
186 g->dosenvec = (struct DosEnvec *)BADDR(fssm->fssm_Environ);
187 g->currentvolume = NULL;
190 * Assign memory functions; pooled or not depending
191 * on exec version (V16: always used LibPool functions
193 g->allocmemp = AllocPooledVec;
194 g->freememp = FreePooledVec;
195 g->allocbufmem = AllocPooledBuf;
196 g->freebufmem = FreePooledBuf;
198 if (!(g->mainPool = LibCreatePool (MEMF_CLEAR, 2*1024, 1*1024)))
200 ErrorMsg (AFS_ERROR_MEMORY_POOL, NULL, g);
201 return FALSE;
204 g->bufferPool = LibCreatePool (g->dosenvec->de_BufMemType, 20*1024, 16*1024);
205 if (g->bufferPool)
207 #if 0
208 Removed because of problems with Phase 5 boards
210 /* check if memory allocated is ok (First fail-over) */
211 if (((ULONG)LibAllocPooled(g->bufferPool, 8)) & ~g->dosenvec->de_Mask)
213 g->dosenvec->de_BufMemType |= MEMF_24BITDMA;
214 LibDeletePool (g->bufferPool);
215 g->bufferPool = LibCreatePool (g->dosenvec->de_BufMemType, 20*1024, 16*1024);
217 /* check if memory allocated is ok (Second fail-over) */
218 if (((ULONG)LibAllocPooled(g->bufferPool, 8)) & ~g->dosenvec->de_Mask)
220 g->dosenvec->de_BufMemType |= MEMF_LOCAL;
221 LibDeletePool (g->bufferPool);
222 g->bufferPool = LibCreatePool (g->dosenvec->de_BufMemType, 20*1024, 16*1024);
224 #endif
227 if (!g->bufferPool)
229 ErrorMsg (AFS_ERROR_MEMORY_POOL, NULL, g);
230 return FALSE;
233 t = BLOCKSIZE;
234 for (i=-1; t; i++)
235 t >>= 1;
236 g->blockshift = i;
237 g->directsize = 16*1024>>i;
239 #define DE(x) g->dosenvec->de_##x
240 g->td64mode = 0;
241 if ((DE(HighCyl)+1)*DE(BlocksPerTrack)*DE(Surfaces) >= (1UL << (32-BLOCKSHIFT))) {
242 #if TD64
243 g->td64mode = 1;
244 #elif SCSIDIRECT
245 /* kan ook */
246 #endif
248 #undef DE
250 if (!(g->geom = AllocMemP (sizeof(struct DriveGeometry), g)))
251 return FALSE;
253 NewList((struct List *)&g->volumes); /* %9.1 */
254 NewList((struct List *)&g->idlelist);
256 if (!OpenDiskDevice(fssm, &g->port, &g->request, &g->trackdisk, g) )
257 return FALSE;
259 DB(Trace(4,"Init","result = %ld",(ULONG)g->trackdisk));
261 /* mode now always big */
262 g->harddiskmode = TRUE;
264 /* data cache */
265 g->dc.size = DATACACHELEN;
266 g->dc.mask = DATACACHEMASK;
267 g->dc.roving = 0;
268 g->dc.ref = AllocMemR (DATACACHELEN * sizeof(struct reftable), MEMF_CLEAR, g);
269 g->dc.data = AllocMemR (DATACACHELEN * BLOCKSIZE, g->dosenvec->de_BufMemType, g);
270 if (!g->dc.data)
271 return FALSE;
273 /* check memory against mask */
274 if (((IPTR)g->dc.data) & ~g->dosenvec->de_Mask)
275 ErrorMsg (AFS_WARNING_MEMORY_MASK, NULL, g);
277 if (!InitLRU(g))
278 return FALSE;
280 if (!OpenTimerDevice(&g->timeport, &g->trequest, UNIT_VBLANK, g) )
281 return FALSE;
283 g->removable = TestRemovability(g);
284 if(g->removable)
285 InstallDiskChangeHandler(g);
287 AddToFSResource (g->dosenvec->de_DosType, ((struct DosList *)devnode)->dol_misc.dol_handler.dol_SegList, g);
289 #if EXTRAPACKETS
290 g->sleepport = CreateMsgPort();
291 #endif
293 DB(Trace(1,"Initialize","Removable = %ld", (ULONG)g->removable));
294 EXIT("initialize");
296 return TRUE;
299 /* added from HDVersion7.0B 11-4-94 */
300 static BOOL TestRemovability(globaldata *g)
302 #ifdef TRACKDISK
304 struct DriveGeometry *geom = g->geom;
305 struct IOExtTD *request = g->request;
306 BOOL result;
308 if(g->trackdisk)
310 request->iotd_Req.io_Data = g->geom;
311 request->iotd_Req.io_Command = TD_GETGEOMETRY;
312 request->iotd_Req.io_Length = sizeof(struct DriveGeometry);
314 if(DoIO((struct IORequest *)request) == NULL)
315 result = geom->dg_Flags & DGF_REMOVABLE;
316 else
317 result = 1; /* trackdisk assumed to be removable */
319 else
321 struct DosEnvec *env = g->dosenvec;
323 if( (env->de_Surfaces <= 2) && (env->de_LowCyl == 0) )
324 result = 1; /* to accomodate things like the diskspare.device */
325 else
326 result = 0; /* disk is assumed to be NOT removable by default */
329 return(result);
331 #else
332 return 1; /* to accomodate SyQuest, Floptical etc */
333 #endif
336 /* added from HDVersion7.0B 11-4-94 */
337 static void InstallDiskChangeHandler(struct globaldata *g)
339 struct IOExtTD *request;
340 struct Interrupt *di;
341 BYTE signal;
342 UBYTE *intname;
343 static const UBYTE *intext = "_interrupt";
345 intname = AllocMemR (g->mountname[0]+strlen(intext)+1, MEMF_PUBLIC, g);
346 CopyMem(g->mountname+1,intname,g->mountname[0]);
347 CopyMem((APTR)intext,intname+g->mountname[0],strlen(intext)+1);
348 DB(Trace(1,"Installdiskchangehandler","intname: %s\n",intname));
350 di = g->diskinterrupt = AllocMemR (sizeof(struct Interrupt), MEMF_PUBLIC|MEMF_CLEAR, g);
351 di->is_Node.ln_Type = NT_INTERRUPT;
352 di->is_Node.ln_Name = intname;
353 di->is_Data = (APTR)g;
354 di->is_Code = DiskChangeHandler;
356 signal = AllocSignal(-1);
357 g->diskchangesignal = 1 << signal;
359 /* make special request structure for inthandler */
360 request = g->handlrequest = (struct IOExtTD *)
361 AllocMemR (sizeof(struct IOExtTD), MEMF_PUBLIC, g);
362 CopyMem(g->request, request, sizeof(*request));
364 request->iotd_Req.io_Length = sizeof(struct Interrupt);
365 request->iotd_Req.io_Data = (APTR)di;
366 request->iotd_Req.io_Command = TD_ADDCHANGEINT;
367 SendIO((struct IORequest *)request);
370 #endif
372 /* OpenDiskDevice
374 ** Used by L2.InitUnit()
376 ** Opens the diskdevice specified by 'startup' and generates the corresponding
377 ** messageport and requeststructure which are returned in 'port' and 'request'
379 ** in startup
380 ** out port, request, trackdisk
382 static BOOL OpenDiskDevice(struct FileSysStartupMsg *startup, struct MsgPort **port,
383 struct IOExtTD **request, BOOL *trackdisk, globaldata *g)
385 UBYTE name[FNSIZE];
387 *port = CreateMsgPort();
388 if(*port)
390 *request = (struct IOExtTD *)CreateIORequest(*port, sizeof(struct IOExtTD));
391 if(*request)
393 BCPLtoCString(name, (UBYTE *)BADDR(startup->fssm_Device));
394 *trackdisk = (strcmp(name, "trackdisk.device") == 0) || (strcmp(name, "diskspare.device") == 0);
395 if(OpenDevice(name, startup->fssm_Unit, (struct IORequest *)*request,
396 startup->fssm_Flags) == 0)
397 return TRUE;
400 return FALSE;
403 static BOOL OpenTimerDevice(struct MsgPort **port, struct timerequest **request,
404 ULONG unit, globaldata *g)
406 *port = CreateMsgPort();
407 if(*port)
409 *request = (struct timerequest *)
410 CreateIORequest(*port, sizeof(struct timerequest));
411 if(*request)
413 if(!OpenDevice(TIMERNAME, unit, (struct IORequest *)*request, 0))
414 return(TRUE);
417 return(FALSE);
420 /* AddToFSResource
422 ** function supplied by Nicola Salmoria
424 static BOOL AddToFSResource(ULONG dostype, BPTR seglist, globaldata *g)
426 struct FileSysResource *FileSysResBase;
428 FileSysResBase = (struct FileSysResource *)OpenResource(FSRNAME);
429 if (FileSysResBase)
431 struct FileSysEntry *fse,*nfse;
433 Forbid();
435 fse = (struct FileSysEntry *)FileSysResBase->fsr_FileSysEntries.lh_Head;
436 while ((nfse = (struct FileSysEntry *)fse->fse_Node.ln_Succ))
438 /* if filesystem already in resource, return */
439 if (fse->fse_DosType == dostype)
441 DB(Trace(4,"ADDTORESOURCE","Already there\n"));
442 break;
445 fse = nfse;
448 if (!nfse && (fse = AllocMem(sizeof(struct FileSysEntry), MEMF_PUBLIC | MEMF_CLEAR)))
450 fse->fse_Node.ln_Name = (UBYTE *)&version[6];
451 fse->fse_DosType = dostype;
452 fse->fse_Version = ((LONG)VERNUM) << 16 | REVNUM;
453 fse->fse_PatchFlags = 0x180;
454 fse->fse_SegList = seglist;
455 fse->fse_GlobalVec = (BPTR)(SIPTR)-1;
457 AddHead(&FileSysResBase->fsr_FileSysEntries,&fse->fse_Node);
460 Permit();
463 return TRUE;
467 /* Reconfigure the filesystem from a rootblock
468 ** GetDriveGeometry already called by GetCurrentRoot, which does
469 ** g->firstblock and g->lastblock.
470 ** rootblockextension must have been loaded
472 void InitModules (struct volumedata *volume, BOOL formatting, globaldata *g)
474 rootblock_t *rootblock = volume->rootblk;
476 g->rootblock = rootblock;
477 g->uip = 0;
478 g->harddiskmode = rootblock->options & MODE_HARDDISK;
479 g->anodesplitmode = rootblock->options & MODE_SPLITTED_ANODES;
480 g->dirextension = rootblock->options & MODE_DIR_EXTENSION;
481 #if DELDIR
482 g->deldirenabled = (rootblock->options & MODE_DELDIR) &&
483 g->dirextension && (volume->rblkextension->blk.deldirsize > 0);
484 #endif
485 g->supermode = rootblock->options & MODE_SUPERINDEX;
486 g->fnsize = (volume->rblkextension) ? (volume->rblkextension->blk.fnsize) : 32;
487 if (!g->fnsize) g->fnsize = 32;
489 InitAnodes (volume, formatting, g);
490 InitAllocation (volume, g);
492 #if VERSION23
493 if (!formatting)
494 DoPostponed (volume, g);
495 #endif
499 #if VERSION23
500 static void DoPostponed (struct volumedata *volume, globaldata *g)
502 struct crootblockextension *rext;
503 struct anodechain *achain;
504 struct postponed_op *postponed;
506 rext = volume->rblkextension;
507 if (rext)
509 postponed = &rext->blk.tobedone;
511 switch (postponed->operation_id)
513 case PP_FREEBLOCKS_FREE:
515 /* we assume we have enough memory at startup.. */
516 achain = GetAnodeChain (postponed->argument1, g);
517 FreeBlocksAC (achain, postponed->argument2, freeanodes, g);
518 break;
520 case PP_FREEBLOCKS_KEEP:
522 /* we assume we have enough memory at startup.. */
523 achain = GetAnodeChain (postponed->argument1, g);
524 alloc_data.clean_blocksfree -= postponed->argument3;
525 alloc_data.alloc_available -= postponed->argument3;
526 FreeBlocksAC (achain, postponed->argument2, keepanodes, g);
527 break;
529 case PP_FREEANODECHAIN:
531 FreeAnodesInChain (postponed->argument1, g);
532 break;
535 postponed->operation_id = 0;
536 postponed->argument1 = 0;
537 postponed->argument2 = 0;
538 postponed->argument3 = 0;
541 #endif