added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / workbench / devs / afs / volumes.c
blobfefce08b4d8788fc33b20b7810315091de2f4bd0
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /*
7 * -date------ -name------------------- -description-----------------------------
8 * 26-dec-2007 [Tomasz Wiszkowski] added disk validation
9 * 04-jan-2008 [Tomasz Wiszkowski] corrected tabulation
10 * 05-jan-2008 [Tomasz Wiszkowski] removed requester prompting for validation
11 * to allow volume validation during boot-up
14 #ifndef DEBUG
15 #define DEBUG 0
16 #endif
18 #include "os.h"
19 #include "bitmap.h"
20 #include "checksums.h"
21 #include "error.h"
22 #include "afsblocks.h"
23 #include "baseredef.h"
24 #include "validator.h"
27 BOOL mediumPresent(struct IOHandle *ioh) {
28 return (ioh->ioflags & IOHF_DISK_IN)==IOHF_DISK_IN;
31 /*******************************************
32 Name : newMedium
33 Descr.: build infos for a new medium
34 Input : volume -
35 Output: 0 for success; error code otherwise
36 ********************************************/
37 LONG newMedium(struct AFSBase *afsbase, struct Volume *volume) {
38 struct BlockCache *blockbuffer;
39 UWORD i;
40 LONG error;
42 /* Check validity of root block first, since boot block may be left over
43 from an overwritten partition of a different size */
44 blockbuffer=getBlock(afsbase, volume,volume->rootblock);
45 if (blockbuffer == NULL)
46 return ERROR_UNKNOWN;
47 if (calcChkSum(volume->SizeBlock, blockbuffer->buffer) != 0 ||
48 OS_BE2LONG(blockbuffer->buffer[BLK_SECONDARY_TYPE(volume)]) != ST_ROOT)
49 return ERROR_NOT_A_DOS_DISK;
51 blockbuffer=getBlock(afsbase, volume,0);
52 if (blockbuffer == NULL)
53 return ERROR_UNKNOWN;
54 volume->dostype=OS_BE2LONG(blockbuffer->buffer[0]) & 0xFFFFFF00;
55 if (volume->dostype != 0x444F5300)
57 blockbuffer=getBlock(afsbase, volume, 1);
58 volume->dostype=OS_BE2LONG(blockbuffer->buffer[0]) & 0xFFFFFF00;
60 volume->dosflags = OS_BE2LONG(blockbuffer->buffer[0]) & 0xFF;
61 if (volume->dostype != 0x444F5300)
62 return ERROR_NOT_A_DOS_DISK;
63 blockbuffer=getBlock(afsbase, volume,volume->rootblock);
64 if (blockbuffer == NULL)
65 return ERROR_UNKNOWN;
66 for (i=0;i<=24;i++)
68 volume->bitmapblockpointers[i]=OS_BE2LONG
70 blockbuffer->buffer[BLK_BITMAP_POINTERS_START(volume)+i]
73 volume->bitmapextensionblock=OS_BE2LONG
75 blockbuffer->buffer[BLK_BITMAP_EXTENSION(volume)]
77 if (!blockbuffer->buffer[BLK_BITMAP_VALID_FLAG(volume)])
79 /* since our disk is invalid at this point, *
80 * we want to spawn a new process that will *
81 * perform disk validation while we move on */
83 volume->usedblockscount=0;
84 volume->state = ID_VALIDATING;
86 launchValidator(afsbase, volume);
90 * it's safe to assume that the block is still there
92 blockbuffer=getBlock(afsbase, volume,volume->rootblock);
94 if (blockbuffer->buffer[BLK_BITMAP_VALID_FLAG(volume)])
96 blockbuffer->flags |= BCF_USED; // won't be cleared until volume is ejected
97 volume->usedblockscount=countUsedBlocks(afsbase, volume);
98 volume->state = (volume->dosflags & 0xFC) ? ID_WRITE_PROTECTED : ID_VALIDATED;
100 error = osMediumInit(afsbase, volume, blockbuffer);
101 if (error != 0)
102 return error;
103 /* for free block searching */
104 volume->lastaccess=volume->rootblock;
105 return 0;
108 /*******************************************
109 Name : initVolume
110 Descr.: maybe a better name would be mountVolume
111 allocate resources for a new mounted device
112 Input : device - device pointer
113 blockdevice - name of blockdevice
114 unit - unit number of blockdevice
115 devicedef - medium geometry data
116 error - return error code
117 Output: 0 on error (error set dos dos error);
118 pointer to struct Volume on success
119 ********************************************/
120 struct Volume *initVolume
122 struct AFSBase *afsbase,
123 struct Device *device,
124 STRPTR blockdevice,
125 ULONG unit,
126 struct DosEnvec *devicedef,
127 ULONG *error
130 struct Volume *volume;
132 volume = AllocMem(sizeof(struct Volume),MEMF_PUBLIC | MEMF_CLEAR);
133 if (volume != NULL)
135 volume->device = device;
136 volume->ioh.blockdevice = blockdevice;
137 volume->ioh.unit = unit;
138 volume->ioh.flags = 0;
139 volume->SizeBlock=devicedef->de_SizeBlock;
140 if (devicedef->de_TableSize>=20)
141 volume->bootblocks=devicedef->de_BootBlocks;
142 else
143 volume->bootblocks=devicedef->de_Reserved;
144 volume->blockcache=initCache(afsbase, volume, devicedef->de_NumBuffers);
145 if (volume->blockcache != NULL)
147 if (openBlockDevice(afsbase, &volume->ioh)!= NULL)
149 volume->countblocks =
152 devicedef->de_HighCyl-devicedef->de_LowCyl+1
153 )*devicedef->de_Surfaces*devicedef->de_BlocksPerTrack
155 volume->rootblock =(volume->countblocks-1+devicedef->de_Reserved)/2;
156 volume->startblock=
157 devicedef->de_LowCyl*
158 devicedef->de_Surfaces*
159 devicedef->de_BlocksPerTrack;
160 volume->lastblock=
162 (devicedef->de_HighCyl+1)
163 *devicedef->de_Surfaces
164 *devicedef->de_BlocksPerTrack
165 )-1;
166 check64BitSupport(afsbase, volume);
167 volume->ah.volume=volume;
168 if (mediumPresent(&volume->ioh))
170 *error = newMedium(afsbase, volume);
172 else
173 *error = 0;
174 if ((*error == 0) || (*error == ERROR_NOT_A_DOS_DISK))
176 D(bug("[afs] initVolume: BootBlocks=%d\n",volume->bootblocks));
177 D(bug("[afs] initVolume: RootBlock=%ld\n",volume->rootblock));
178 volume->ah.header_block = volume->rootblock;
179 return volume;
182 else
184 *error=ERROR_NO_FREE_STORE;
186 freeCache(afsbase, volume->blockcache);
188 else
190 *error=ERROR_NO_FREE_STORE;
192 FreeMem(volume,sizeof(struct Volume));
194 else
195 *error=ERROR_NO_FREE_STORE;
196 return NULL;
199 /*******************************************
200 Name : uninitVolume
201 Descr.: maybe a better name would be unmountVolume
202 free resources allocated by initVolume
203 Input : volume - volume to unmount
204 Output: -
205 ********************************************/
206 void uninitVolume(struct AFSBase *afsbase, struct Volume *volume) {
208 osMediumFree(afsbase, volume, TRUE);
209 if (volume->blockcache != NULL)
210 freeCache(afsbase, volume->blockcache);
211 closeBlockDevice(afsbase, &volume->ioh);
212 FreeMem(volume,sizeof(struct Volume));
215 /* vim: set noet ts=3 ai fdm=marker fmr={,} :*/