use new platform macros to access scheduling/per-cpu flags. fix execsmp wait()
[AROS.git] / workbench / tools / HDToolBox / partitions.c
blob8e703edaa19d0791689bd6fa6d2e519605cbdcf0
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <proto/exec.h>
7 #include <proto/gadtools.h>
8 #include <proto/intuition.h>
9 #include <proto/partition.h>
10 #include <proto/alib.h>
12 #include <devices/trackdisk.h>
13 #include <exec/memory.h>
14 #include <utility/tagitem.h>
16 #include <stdio.h>
17 #include <strings.h>
19 #include "partitions.h"
20 #include "hdtoolbox_support.h"
21 #include "platform.h"
22 #include "prefs.h"
24 #define DEBUG 0
26 #include "debug.h"
28 void setPartitionName(struct HDTBPartition *pnode)
30 D(bug("[HDToolBox] setPartitionName()\n"));
32 if (pnode->pos != -1)
33 sprintf(pnode->listnode.ln.ln_Name, "Partition %d", (int)pnode->pos);
34 else
36 sprintf
38 pnode->listnode.ln.ln_Name,
39 "%ld-%ld",
40 pnode->de.de_LowCyl,
41 pnode->de.de_HighCyl
46 struct HDTBPartition *newPartition(struct ListNode *parent, struct HDTBPartition *partition)
48 struct HDTBPartition *pn;
50 D(bug("[HDToolBox] newPartition()\n"));
52 pn = AllocMem(sizeof(struct HDTBPartition), MEMF_PUBLIC | MEMF_CLEAR);
53 if (pn)
55 pn->listnode.ln.ln_Name = AllocVec(100, MEMF_PUBLIC | MEMF_CLEAR);
56 if (pn->listnode.ln.ln_Name)
58 if (InitListNode(&pn->listnode, parent))
60 pn->listnode.ln.ln_Type = LNT_Partition;
61 pn->root = partition;
62 D(bug("[HDToolBox] newPartition successful - new partition at %p\n", pn));
63 return pn;
65 FreeVec(pn->listnode.ln.ln_Name);
67 FreeMem(pn, sizeof(struct HDTBPartition));
69 D(bug("[HDToolBox] newPartition failed\n"));
70 return NULL;
73 void findPartitions(struct ListNode *parent, struct HDTBPartition *partition)
75 struct PartitionHandle *ph;
76 struct HDTBPartition *pn;
77 LONG flag;
79 D(bug("[HDToolBox] findPartitions()\n"));
81 for
83 ph = (struct PartitionHandle *)partition->ph->table->list.lh_Head;
84 ph->ln.ln_Succ;
85 ph = (struct PartitionHandle *)ph->ln.ln_Succ
88 pn = newPartition(parent, partition);
89 D(bug("[HDToolBox] - found new partition at %p, created node at %p\n", ph, pn));
90 if (pn != NULL)
92 pn->ph = ph;
93 GetPartitionAttrsA
95 pn->ph,
96 PT_GEOMETRY, &pn->dg,
97 PT_DOSENVEC, &pn->de,
98 TAG_DONE
102 * check if we can read partition type
104 if (getAttrInfo(pn->root->table->pattrlist, PTA_TYPE) & PLAM_READ)
106 GetPartitionAttrsA(pn->ph, PT_TYPE, &pn->type, TAG_DONE);
107 D(bug("[HDToolBox] - ID valid (%ld)\n", pn->type));
109 else
111 pn->type.id[0] = 0;
112 pn->type.id_len = 0;
113 D(bug("[HDToolBox] - ID invalid\n"));
117 * read partition location
119 if (getAttrInfo(pn->root->table->pattrlist, PTA_POSITION) & PLAM_READ)
121 GetPartitionAttrsA(pn->ph, PT_POSITION, &pn->pos, TAG_DONE);
122 D(bug("[HDToolBox] - Position valid (%ld)\n", pn->pos));
124 else
126 pn->pos = -1L;
127 D(bug("[HDToolBox] - Position invalid\n"));
131 * read partition name
133 if (getAttrInfo(pn->root->table->pattrlist, PTA_NAME) & PLAM_READ)
135 GetPartitionAttrsA(pn->ph, PT_NAME, pn->listnode.ln.ln_Name, TAG_DONE);
136 D(bug("[HDToolBox] - Name valid (%s)\n", pn->listnode.ln.ln_Name));
138 else
140 setPartitionName(pn);
141 D(bug("[HDToolBox] - Name generated (%s)\n", pn->listnode.ln.ln_Name));
145 * check bootable flag
147 if (getAttrInfo(pn->root->table->pattrlist, PTA_BOOTABLE) & PLAM_READ)
149 GetPartitionAttrsA(pn->ph, PT_BOOTABLE, &flag, TAG_DONE);
150 if (flag)
151 pn->flags |= PNF_BOOTABLE;
152 D(bug("[HDToolBox] - Bootable flag %s\n", flag ? "enabled" : "disabled"));
156 * automount flag
158 if (getAttrInfo(pn->root->table->pattrlist, PTA_AUTOMOUNT) & PLAM_READ)
160 GetPartitionAttrsA(pn->ph, PT_AUTOMOUNT, &flag, TAG_DONE);
161 if (flag)
162 pn->flags |= PNF_AUTOMOUNT;
163 D(bug("[HDToolBox] - Automount flag %s\n", flag ? "enabled" : "disabled"));
167 * check if partition is active (MBR-specific)
169 if (getAttrInfo(pn->root->table->pattrlist, PTA_ACTIVE) & PLAM_READ)
171 GetPartitionAttrsA(pn->ph, PT_ACTIVE, &flag, TAG_DONE);
172 if (flag)
173 pn->flags |= PNF_ACTIVE;
174 D(bug("[HDToolBox] - Active flag %s\n", flag ? "enabled" : "disabled"));
177 if (pn->root->table->max_partitions)
179 pn->listnode.ln.ln_Pri=pn->root->table->max_partitions-1-pn->pos;
180 Enqueue(&parent->list, &pn->listnode.ln);
182 else
183 AddTail(&parent->list, &pn->listnode.ln);
184 if (findPartitionTable(pn))
186 findPartitions(&pn->listnode, pn);
187 pn->listnode.flags |= LNF_Listable;
191 D(bug("[HDToolBox] findPartitions() successful\n"));
194 void freePartitionNode(struct HDTBPartition *node)
196 D(bug("[HDToolBox] freePartitionNode(%p)\n", node));
198 if (node->table)
200 D(bug("[HDToolBox] Freeing sub-table %p\n", node->table));
201 freePartitionList(&node->listnode.list);
202 freePartitionTable(node);
204 UninitListNode(&node->listnode);
205 FreeVec(node->listnode.ln.ln_Name);
206 FreeMem(node, sizeof(struct HDTBPartition));
209 void freePartitionList(struct List *list)
211 struct HDTBPartition *node;
212 struct HDTBPartition *next;
214 D(bug("[HDToolBox] freePartitionList(%p)\n", list));
216 node = (struct HDTBPartition *)list->lh_Head;
217 while (node->listnode.ln.ln_Succ)
219 next = (struct HDTBPartition *)node->listnode.ln.ln_Succ;
220 if (node->listnode.ln.ln_Type != LNT_Parent)
222 Remove(&node->listnode.ln);
223 freePartitionNode(node);
225 node = next;
229 BOOL validValue(struct HDTBPartition *table, struct HDTBPartition *current, ULONG value)
231 struct HDTBPartition *pn;
232 ULONG spc;
234 D(bug("[HDToolBox] validValue()\n"));
236 if (value<table->table->reserved)
238 D(bug("[HDToolBox] - value (%ld) < table->reserved (%ld) -> bad\n", value, table->table->reserved));
239 return FALSE;
241 spc = table->dg.dg_Heads*table->dg.dg_TrackSectors;
242 if (value>=(table->dg.dg_Cylinders*spc))
244 D(bug("[HDToolBox] - value (%ld) >= table->dg.dg_Cylinders*spc (%ld) -> bad\n", value, table->dg.dg_Cylinders*spc));
245 return FALSE;
248 for (
249 pn = (struct HDTBPartition *)table->listnode.list.lh_Head;
250 pn->listnode.ln.ln_Succ;
251 pn = (struct HDTBPartition *)pn->listnode.ln.ln_Succ)
253 D(bug("[HDToolBox] - List %p / Partition %p / Next %p / Current %p\n", &table->listnode, pn, pn->listnode.ln.ln_Succ, current));
254 D(bug("[HDToolBox] - Partition Type: %lx\n", pn->type));
256 /* don't analyze PARENT, don't analyze ROOT */
257 if (pn->listnode.ln.ln_Type != LNT_Partition)
258 continue;
260 /* don't check currently processed partition */
261 if (current != pn)
263 spc = pn->de.de_Surfaces*pn->de.de_BlocksPerTrack;
264 if (
265 (value >= (pn->de.de_LowCyl*spc)) &&
266 (value < (((pn->de.de_HighCyl+1)*spc)-1))
269 D(bug("[HDToolBox] - value (%ld) within bounds <%ld; %ld) -> bad\n", value, pn->de.de_LowCyl * spc, (pn->de.de_HighCyl+1)*spc-1));
270 return FALSE;
275 D(bug("[HDToolBox] - value (%ld) good\n", value));
276 return TRUE;
279 struct HDTBPartition *addPartition(struct HDTBPartition *table, struct DosEnvec *de)
281 struct HDTBPartition *partition;
282 struct HDTBPartition *pn;
283 struct TableTypeNode *ttn;
284 ULONG leadin = 0, blocks_per_cyl;
286 D(bug("[HDToolBox] addPartition()\n"));
288 partition = newPartition(&table->listnode, table);
289 if (partition)
291 if (table->table->max_partitions)
293 /* find first free position */
294 ULONG count = 0;
295 pn = (struct HDTBPartition *)table->listnode.list.lh_Head;
296 while (pn->listnode.ln.ln_Succ)
298 if (pn->listnode.ln.ln_Type != LNT_Parent)
300 if (count!=pn->pos)
302 partition->pos = count;
303 break;
305 count++;
307 pn = (struct HDTBPartition *)pn->listnode.ln.ln_Succ;
309 if (pn->listnode.ln.ln_Succ == NULL)
310 partition->pos = count;
311 partition->listnode.ln.ln_Pri = table->table->max_partitions-1-partition->pos;
312 Enqueue(&table->listnode.list, &partition->listnode.ln);
314 else
315 AddTail(&table->listnode.list, &partition->listnode.ln);
317 de->de_TableSize = DE_DOSTYPE;
318 de->de_MaxTransfer = 0xFFFFFF;
319 de->de_Mask = 0xFFFFFFFE;
320 de->de_Reserved = 2;
321 de->de_BufMemType = MEMF_PUBLIC;
323 CopyMem(de, &partition->de, sizeof(struct DosEnvec));
324 ttn = findTableTypeNode(table->table->type);
325 CopyMem(&ttn->defaulttype, &partition->type, sizeof(struct PartitionType));
326 if (getAttrInfo(table->table->pattrlist, PTA_NAME) & PLAM_WRITE)
327 strcpy(partition->listnode.ln.ln_Name, "DH0");
328 else
329 setPartitionName(partition);
331 GetPartitionTableAttrsTags(table->ph, PTT_MAXLEADIN, &leadin, TAG_DONE);
333 blocks_per_cyl = de->de_Surfaces * de->de_BlocksPerTrack;
334 de->de_LowCyl += (leadin + blocks_per_cyl - 1) / blocks_per_cyl;
335 D(bug("[HDToolBox] addPartition() Prepared Envec:\n"));
336 D(bug("[HDToolBox] - LeadIn : %ld\n", leadin));
337 D(bug("[HDToolBox] - SizeBlock : %ld\n", de->de_SizeBlock));
338 D(bug("[HDToolBox] - SecOrg : %ld\n", de->de_SecOrg));
339 D(bug("[HDToolBox] - Surfaces : %ld\n", de->de_Surfaces));
340 D(bug("[HDToolBox] - SectorsPerBlock : %ld\n", de->de_SectorPerBlock));
341 D(bug("[HDToolBox] - Reserved : %ld\n", de->de_Reserved));
342 D(bug("[HDToolBox] - LowCyl : %ld\n", de->de_LowCyl));
343 D(bug("[HDToolBox] - HighCyl : %ld\n", de->de_HighCyl));
344 D(bug("[HDToolBox] - BlocksPerTrack : %ld\n", de->de_BlocksPerTrack));
345 D(bug("[HDToolBox] - BootBlocks : %ld\n", de->de_BootBlocks));
347 partition->ph = AddPartitionTags(table->ph,
348 PT_DOSENVEC, de,
349 PT_TYPE , &partition->type,
350 PT_NAME , partition->listnode.ln.ln_Name,
351 PT_POSITION, partition->pos,
352 TAG_DONE);
353 if (partition->ph)
355 /* We did not set GEOMETRY so partitionlib did it. Update geometry and DOS type in local DOSEnvec */
356 GetPartitionAttrsTags(partition->ph, PT_GEOMETRY, &partition->dg,
357 PT_DOSENVEC, &partition->de,
358 TAG_DONE);
360 de = &partition->de;
361 D(bug("[HDToolBox] addPartition() Real Envec:\n"));
362 D(bug("[HDToolBox] - SizeBlock : %ld\n", de->de_SizeBlock));
363 D(bug("[HDToolBox] - SecOrg : %ld\n", de->de_SecOrg));
364 D(bug("[HDToolBox] - Surfaces : %ld\n", de->de_Surfaces));
365 D(bug("[HDToolBox] - SectorsPerBlock : %ld\n", de->de_SectorPerBlock));
366 D(bug("[HDToolBox] - Reserved : %ld\n", de->de_Reserved));
367 D(bug("[HDToolBox] - LowCyl : %ld\n", de->de_LowCyl));
368 D(bug("[HDToolBox] - HighCyl : %ld\n", de->de_HighCyl));
369 D(bug("[HDToolBox] - BlocksPerTrack : %ld\n", de->de_BlocksPerTrack));
370 D(bug("[HDToolBox] - BootBlocks : %ld\n", de->de_BootBlocks));
371 D(bug("[HDToolBox] addPartition() successful\n"));
372 return partition;
375 D(bug("[HDToolBox] addPartition() failed to add partition\n"));
376 freePartitionNode(partition);
378 D(bug("[HDToolBox] addPartition() failed\n"));
379 return NULL;