1 /* $Id: init.c 12.9 1999/09/11 17:05:14 Michiel Exp Michiel $ */
3 * Revision 12.9 1999/09/11 17:05:14 Michiel
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)
16 * Revision 12.5 1998/09/03 07:12:14 Michiel
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
26 * Revision 12.2 1996/03/07 10:05:24 Michiel
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
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
53 * Revision 11.10 1995/07/07 14:39:17 Michiel
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
62 * Revision 11.7 1995/05/20 12:12:12 Michiel
63 * Updated messages to reflect Ami-FileLock
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
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)
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
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>
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"
132 extern CONST UBYTE
*version
;
133 extern AROS_INTP(DiskChangeHandler
);
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
*);
143 static void DoPostponed (struct volumedata
*volume
, globaldata
*g
);
146 /**********************************************************************/
150 /**********************************************************************/
153 BOOL
Initialize(DSTR mountname
, struct FileSysStartupMsg
*fssm
,
154 struct DeviceNode
*devnode
, globaldata
*g
)
159 BOOL
Initialize(DSTR mountname
, struct FileSysStartupMsg
*fssm
,
160 struct DeviceNode
*devnode
, globaldata
*g
)
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
;
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
);
204 g
->bufferPool
= LibCreatePool (g
->dosenvec
->de_BufMemType
, 20*1024, 16*1024);
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);
229 ErrorMsg (AFS_ERROR_MEMORY_POOL
, NULL
, g
);
237 g
->directsize
= 16*1024>>i
;
239 #define DE(x) g->dosenvec->de_##x
241 if ((DE(HighCyl
)+1)*DE(BlocksPerTrack
)*DE(Surfaces
) >= (1UL << (32-BLOCKSHIFT
))) {
250 if (!(g
->geom
= AllocMemP (sizeof(struct DriveGeometry
), g
)))
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
) )
259 DB(Trace(4,"Init","result = %ld",(ULONG
)g
->trackdisk
));
261 /* mode now always big */
262 g
->harddiskmode
= TRUE
;
265 g
->dc
.size
= DATACACHELEN
;
266 g
->dc
.mask
= DATACACHEMASK
;
268 g
->dc
.ref
= AllocMemR (DATACACHELEN
* sizeof(struct reftable
), MEMF_CLEAR
, g
);
269 g
->dc
.data
= AllocMemR (DATACACHELEN
* BLOCKSIZE
, g
->dosenvec
->de_BufMemType
, g
);
273 /* check memory against mask */
274 if (((IPTR
)g
->dc
.data
) & ~g
->dosenvec
->de_Mask
)
275 ErrorMsg (AFS_WARNING_MEMORY_MASK
, NULL
, g
);
280 if (!OpenTimerDevice(&g
->timeport
, &g
->trequest
, UNIT_VBLANK
, g
) )
283 g
->removable
= TestRemovability(g
);
285 InstallDiskChangeHandler(g
);
287 AddToFSResource (g
->dosenvec
->de_DosType
, ((struct DosList
*)devnode
)->dol_misc
.dol_handler
.dol_SegList
, g
);
290 g
->sleepport
= CreateMsgPort();
293 DB(Trace(1,"Initialize","Removable = %ld", (ULONG
)g
->removable
));
299 /* added from HDVersion7.0B 11-4-94 */
300 static BOOL
TestRemovability(globaldata
*g
)
304 struct DriveGeometry
*geom
= g
->geom
;
305 struct IOExtTD
*request
= g
->request
;
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
;
317 result
= 1; /* trackdisk assumed to be removable */
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 */
326 result
= 0; /* disk is assumed to be NOT removable by default */
332 return 1; /* to accomodate SyQuest, Floptical etc */
336 /* added from HDVersion7.0B 11-4-94 */
337 static void InstallDiskChangeHandler(struct globaldata
*g
)
339 struct IOExtTD
*request
;
340 struct Interrupt
*di
;
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
= (VOID_FUNC
)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
);
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'
380 ** out port, request, trackdisk
382 static BOOL
OpenDiskDevice(struct FileSysStartupMsg
*startup
, struct MsgPort
**port
,
383 struct IOExtTD
**request
, BOOL
*trackdisk
, globaldata
*g
)
387 *port
= CreateMsgPort();
390 *request
= (struct IOExtTD
*)CreateIORequest(*port
, sizeof(struct IOExtTD
));
393 BCPLtoCString(name
, (UBYTE
*)BADDR(startup
->fssm_Device
));
394 *trackdisk
= (strcmp(name
, "trackdisk.device") == 0) || (strcmp(name
, "diskspare.device") == 0);
396 #if KS13WRAPPER_DEBUG
397 DebugPutStr("Opening device..\n");
402 if(OpenDevice(name
, startup
->fssm_Unit
, (struct IORequest
*)*request
,
403 startup
->fssm_Flags
) == 0)
410 static BOOL
OpenTimerDevice(struct MsgPort
**port
, struct timerequest
**request
,
411 ULONG unit
, globaldata
*g
)
413 *port
= CreateMsgPort();
416 *request
= (struct timerequest
*)
417 CreateIORequest(*port
, sizeof(struct timerequest
));
420 if(!OpenDevice(TIMERNAME
, unit
, (struct IORequest
*)*request
, 0))
429 ** function supplied by Nicola Salmoria
431 static BOOL
AddToFSResource(ULONG dostype
, BPTR seglist
, globaldata
*g
)
433 struct FileSysResource
*FileSysResBase
;
435 FileSysResBase
= (struct FileSysResource
*)OpenResource(FSRNAME
);
438 struct FileSysEntry
*fse
,*nfse
;
442 fse
= (struct FileSysEntry
*)FileSysResBase
->fsr_FileSysEntries
.lh_Head
;
443 while ((nfse
= (struct FileSysEntry
*)fse
->fse_Node
.ln_Succ
))
445 /* if filesystem already in resource, return */
446 if (fse
->fse_DosType
== dostype
)
448 DB(Trace(4,"ADDTORESOURCE","Already there\n"));
455 if (!nfse
&& (fse
= AllocMem(sizeof(struct FileSysEntry
), MEMF_PUBLIC
| MEMF_CLEAR
)))
457 fse
->fse_Node
.ln_Name
= (UBYTE
*)&version
[6];
458 fse
->fse_DosType
= dostype
;
459 fse
->fse_Version
= ((LONG
)VERNUM
) << 16 | REVNUM
;
460 fse
->fse_PatchFlags
= 0x180;
461 fse
->fse_SegList
= seglist
;
462 fse
->fse_GlobalVec
= (BPTR
)(SIPTR
)-1;
464 AddHead(&FileSysResBase
->fsr_FileSysEntries
,&fse
->fse_Node
);
474 /* Reconfigure the filesystem from a rootblock
475 ** GetDriveGeometry already called by GetCurrentRoot, which does
476 ** g->firstblock and g->lastblock.
477 ** rootblockextension must have been loaded
479 void InitModules (struct volumedata
*volume
, BOOL formatting
, globaldata
*g
)
481 rootblock_t
*rootblock
= volume
->rootblk
;
483 g
->rootblock
= rootblock
;
485 g
->harddiskmode
= rootblock
->options
& MODE_HARDDISK
;
486 g
->anodesplitmode
= rootblock
->options
& MODE_SPLITTED_ANODES
;
487 g
->dirextension
= rootblock
->options
& MODE_DIR_EXTENSION
;
489 g
->deldirenabled
= (rootblock
->options
& MODE_DELDIR
) &&
490 g
->dirextension
&& (volume
->rblkextension
->blk
.deldirsize
> 0);
492 g
->supermode
= rootblock
->options
& MODE_SUPERINDEX
;
493 g
->fnsize
= (volume
->rblkextension
) ? (volume
->rblkextension
->blk
.fnsize
) : 32;
494 if (!g
->fnsize
) g
->fnsize
= 32;
496 InitAnodes (volume
, formatting
, g
);
497 InitAllocation (volume
, g
);
501 DoPostponed (volume
, g
);
507 static void DoPostponed (struct volumedata
*volume
, globaldata
*g
)
509 struct crootblockextension
*rext
;
510 struct anodechain
*achain
;
511 struct postponed_op
*postponed
;
513 rext
= volume
->rblkextension
;
516 postponed
= &rext
->blk
.tobedone
;
518 switch (postponed
->operation_id
)
520 case PP_FREEBLOCKS_FREE
:
522 /* we assume we have enough memory at startup.. */
523 achain
= GetAnodeChain (postponed
->argument1
, g
);
524 FreeBlocksAC (achain
, postponed
->argument2
, freeanodes
, g
);
527 case PP_FREEBLOCKS_KEEP
:
529 /* we assume we have enough memory at startup.. */
530 achain
= GetAnodeChain (postponed
->argument1
, g
);
531 alloc_data
.clean_blocksfree
-= postponed
->argument3
;
532 alloc_data
.alloc_available
-= postponed
->argument3
;
533 FreeBlocksAC (achain
, postponed
->argument2
, keepanodes
, g
);
536 case PP_FREEANODECHAIN
:
538 FreeAnodesInChain (postponed
->argument1
, g
);
542 postponed
->operation_id
= 0;
543 postponed
->argument1
= 0;
544 postponed
->argument2
= 0;
545 postponed
->argument3
= 0;