2 Copyright © 1995-2008, The AROS Development Team. All rights reserved.
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>
19 #include "partitions.h"
20 #include "hdtoolbox_support.h"
28 void setPartitionName(struct HDTBPartition
*pnode
)
30 D(bug("[HDToolBox] setPartitionName()\n"));
33 sprintf(pnode
->listnode
.ln
.ln_Name
, "Partition %ld", pnode
->pos
);
38 pnode
->listnode
.ln
.ln_Name
,
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
);
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
;
62 D(bug("[HDToolBox] newPartition successful - new partition at %p\n", pn
));
65 FreeVec(pn
->listnode
.ln
.ln_Name
);
67 FreeMem(pn
, sizeof(struct HDTBPartition
));
69 D(bug("[HDToolBox] newPartition failed\n"));
73 void findPartitions(struct ListNode
*parent
, struct HDTBPartition
*partition
)
75 struct PartitionHandle
*ph
;
76 struct HDTBPartition
*pn
;
79 D(bug("[HDToolBox] findPartitions()\n"));
83 ph
= (struct PartitionHandle
*)partition
->ph
->table
->list
.lh_Head
;
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
));
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
));
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
));
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
));
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
);
151 pn
->flags
|= PNF_BOOTABLE
;
152 D(bug("[HDToolBox] - Bootable flag %s\n", flag
? "enabled" : "disabled"));
158 if (getAttrInfo(pn
->root
->table
->pattrlist
, PTA_AUTOMOUNT
) & PLAM_READ
)
160 GetPartitionAttrsA(pn
->ph
, PT_AUTOMOUNT
, &flag
, TAG_DONE
);
162 pn
->flags
|= PNF_AUTOMOUNT
;
163 D(bug("[HDToolBox] - Automount flag %s\n", flag
? "enabled" : "disabled"));
167 * check if partition is active
168 * (what's the difference between this and automount?)
170 if (getAttrInfo(pn
->root
->table
->pattrlist
, PTA_ACTIVE
) & PLAM_READ
)
172 GetPartitionAttrsA(pn
->ph
, PT_ACTIVE
, &flag
, TAG_DONE
);
174 pn
->flags
|= PNF_ACTIVE
;
175 D(bug("[HDToolBox] - Active flag %s\n", flag
? "enabled" : "disabled"));
178 if (pn
->root
->table
->max_partitions
)
180 pn
->listnode
.ln
.ln_Pri
=pn
->root
->table
->max_partitions
-1-pn
->pos
;
181 Enqueue(&parent
->list
, &pn
->listnode
.ln
);
184 AddTail(&parent
->list
, &pn
->listnode
.ln
);
185 if (findPartitionTable(pn
))
187 findPartitions(&pn
->listnode
, pn
);
188 pn
->listnode
.flags
|= LNF_Listable
;
192 D(bug("[HDToolBox] findPartitions() successful\n"));
195 void freePartitionNode(struct HDTBPartition
*node
)
197 D(bug("[HDToolBox] freePartitionNode()\n"));
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()\n"));
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
);
229 BOOL
validValue(struct HDTBPartition
*table
, struct HDTBPartition
*current
, ULONG value
)
231 struct HDTBPartition
*pn
;
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
));
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
));
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
)
260 /* don't check currently processed partition */
263 spc
= pn
->de
.de_Surfaces
*pn
->de
.de_BlocksPerTrack
;
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));
275 D(bug("[HDToolBox] - value (%ld) good\n", value
));
279 struct PartitionHandle
*AddPartitionA(struct PartitionHandle
*root
, IPTR tag
, ...)
281 // D(bug("[HDToolBox] AddPartitionA()\n"));
282 #warning "TODO: Check varargs usage is correct"
284 AROS_SLOWSTACKMETHODS_PRE(tag
)
285 retval
= (IPTR
)AddPartition(root
, (struct TagItem
*)AROS_SLOWSTACKMETHODS_ARG(tag
));
286 AROS_SLOWSTACKMETHODS_POST
288 //return retval; return is already done by AROS_SLOWSTACKMETHODS_POST
290 return AddPartition(root
, (struct TagItem
*)&tag
);
294 struct HDTBPartition
*addPartition(struct HDTBPartition
*table
, struct DosEnvec
*de
)
296 struct HDTBPartition
*partition
;
297 struct HDTBPartition
*pn
;
298 struct TableTypeNode
*ttn
;
299 ULONG leadin
= 0, blocks_per_cyl
;
301 D(bug("[HDToolBox] addPartition()\n"));
303 partition
= newPartition(&table
->listnode
, table
);
306 if (table
->table
->max_partitions
)
308 /* find first free position */
310 pn
= (struct HDTBPartition
*)table
->listnode
.list
.lh_Head
;
311 while (pn
->listnode
.ln
.ln_Succ
)
313 if (pn
->listnode
.ln
.ln_Type
!= LNT_Parent
)
317 partition
->pos
= count
;
322 pn
= (struct HDTBPartition
*)pn
->listnode
.ln
.ln_Succ
;
324 if (pn
->listnode
.ln
.ln_Succ
== NULL
)
325 partition
->pos
= count
;
326 partition
->listnode
.ln
.ln_Pri
= table
->table
->max_partitions
-1-partition
->pos
;
327 Enqueue(&table
->listnode
.list
, &partition
->listnode
.ln
);
330 AddTail(&table
->listnode
.list
, &partition
->listnode
.ln
);
332 de
->de_TableSize
= DE_DOSTYPE
;
333 de
->de_MaxTransfer
= 0xFFFFFF;
334 de
->de_Mask
= 0xFFFFFFFE;
336 de
->de_BufMemType
= MEMF_ANY
;
337 CopyMem(de
, &partition
->de
, sizeof(struct DosEnvec
));
338 ttn
= findTableTypeNode(table
->table
->type
);
339 CopyMem(&ttn
->defaulttype
, &partition
->type
, sizeof(struct PartitionType
));
340 if (getAttrInfo(table
->table
->pattrlist
, PTA_NAME
) & PLAM_WRITE
)
341 strcpy(partition
->listnode
.ln
.ln_Name
, "DH0");
343 setPartitionName(partition
);
344 GetPartitionTableAttrsA
347 PTT_MAXLEADIN
, &leadin
,
350 blocks_per_cyl
= de
->de_Surfaces
* de
->de_BlocksPerTrack
;
351 de
->de_LowCyl
+= (leadin
+ blocks_per_cyl
- 1) / blocks_per_cyl
;
352 D(bug("[HDToolBox] addPartition() Prepared Envec:\n"));
353 D(bug("[HDToolBox] - LeadIn : %ld\n", leadin
));
354 D(bug("[HDToolBox] - SizeBlock : %ld\n", de
->de_SizeBlock
));
355 D(bug("[HDToolBox] - SecOrg : %ld\n", de
->de_SecOrg
));
356 D(bug("[HDToolBox] - Surfaces : %ld\n", de
->de_Surfaces
));
357 D(bug("[HDToolBox] - SectorsPerBlock : %ld\n", de
->de_SectorPerBlock
));
358 D(bug("[HDToolBox] - Reserved : %ld\n", de
->de_Reserved
));
359 D(bug("[HDToolBox] - LowCyl : %ld\n", de
->de_LowCyl
));
360 D(bug("[HDToolBox] - HighCyl : %ld\n", de
->de_HighCyl
));
361 D(bug("[HDToolBox] - BlocksPerTrack : %ld\n", de
->de_BlocksPerTrack
));
362 D(bug("[HDToolBox] - BootBlocks : %ld\n", de
->de_BootBlocks
));
364 partition
->ph
= AddPartitionA
368 PT_TYPE
, &partition
->type
,
369 PT_NAME
, partition
->listnode
.ln
.ln_Name
,
370 PT_POSITION
, partition
->pos
,
375 /* we did not set GEOMETRY so partitionlib did it */
379 PT_GEOMETRY
, &partition
->dg
,
382 /* Update DOS type in local DOSEnvec */
383 GetPartitionAttrsA(partition
->ph
, PT_DOSENVEC
, &partition
->de
, TAG_DONE
);
385 D(bug("[HDToolBox] addPartition() Real Envec:\n"));
386 D(bug("[HDToolBox] - SizeBlock : %ld\n", de
->de_SizeBlock
));
387 D(bug("[HDToolBox] - SecOrg : %ld\n", de
->de_SecOrg
));
388 D(bug("[HDToolBox] - Surfaces : %ld\n", de
->de_Surfaces
));
389 D(bug("[HDToolBox] - SectorsPerBlock : %ld\n", de
->de_SectorPerBlock
));
390 D(bug("[HDToolBox] - Reserved : %ld\n", de
->de_Reserved
));
391 D(bug("[HDToolBox] - LowCyl : %ld\n", de
->de_LowCyl
));
392 D(bug("[HDToolBox] - HighCyl : %ld\n", de
->de_HighCyl
));
393 D(bug("[HDToolBox] - BlocksPerTrack : %ld\n", de
->de_BlocksPerTrack
));
394 D(bug("[HDToolBox] - BootBlocks : %ld\n", de
->de_BootBlocks
));
395 D(bug("[HDToolBox] addPartition() successful\n"));
399 D(bug("[HDToolBox] addPartition() failed to add partition\n"));
400 freePartitionNode(partition
);
402 D(bug("[HDToolBox] addPartition() failed\n"));