update copyright
[AROS.git] / rom / partition / partition_support.c
blob49e76c89071e12ce0a15f6431c047d0e99331ed4
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 */
7 #include <proto/exec.h>
8 #include <devices/newstyle.h>
9 #include <utility/tagitem.h>
11 #include "partition_intern.h"
12 #include "partition_support.h"
13 #include "debug.h"
15 const struct PTFunctionTable * const PartitionSupport[] =
17 &PartitionGPT, /* The order of these two is important, GPT must be checked before MBR */
18 &PartitionMBR,
19 &PartitionEBR,
20 &PartitionRDB,
21 NULL
24 /* Keep RDB last. RDB scans up to 16 blocks and in case of
25 * MBR->EBR->RDB having RDB first detects RDB as root and
26 * causes MBR and EBR offsets not be taken into account
29 /* get geometry */
30 LONG PartitionGetGeometry
32 struct Library *PartitionBase,
33 struct IOExtTD *ioreq,
34 struct DriveGeometry *dg
38 ioreq->iotd_Req.io_Command = TD_GETGEOMETRY;
39 ioreq->iotd_Req.io_Data = dg;
40 ioreq->iotd_Req.io_Length = sizeof(struct DriveGeometry);
41 return DoIO((struct IORequest *)ioreq);
44 /* query NSD commands */
45 void PartitionNsdCheck
47 struct Library *PartitionBase,
48 struct PartitionHandle *root
51 struct NSDeviceQueryResult nsdq;
52 struct IOExtTD *ioreq = root->bd->ioreq;
53 UWORD *cmdcheck;
55 if (
57 root->de.de_HighCyl*
58 root->de.de_Surfaces*
59 root->de.de_BlocksPerTrack*
60 ((root->de.de_SizeBlock<<2)/512)
61 )>8388608)
63 nsdq.SizeAvailable=0;
64 nsdq.DevQueryFormat=0;
65 ioreq->iotd_Req.io_Command=NSCMD_DEVICEQUERY;
66 ioreq->iotd_Req.io_Data=&nsdq;
67 ioreq->iotd_Req.io_Length=sizeof(struct NSDeviceQueryResult);
68 if (DoIO((struct IORequest *)ioreq)==0)
70 if (
71 (ioreq->iotd_Req.io_Actual<=sizeof(struct NSDeviceQueryResult)) &&
72 (ioreq->iotd_Req.io_Actual!=0) &&
73 (ioreq->iotd_Req.io_Actual==nsdq.SizeAvailable)
76 if (nsdq.DeviceType != NSDEVTYPE_TRACKDISK)
77 D(bug("partition: NSDcheck: WARNING no trackdisk type\n"));
78 for (cmdcheck=nsdq.SupportedCommands;*cmdcheck;cmdcheck++)
80 if (*cmdcheck == NSCMD_TD_READ64)
81 root->bd->cmdread = NSCMD_TD_READ64;
82 if (*cmdcheck == NSCMD_TD_WRITE64);
83 root->bd->cmdwrite = NSCMD_TD_WRITE64;
86 else
87 D(bug("partition: NSDcheck: WARNING wrong io_Actual using NSD\n"));
92 /* get real first block of partition ph */
93 ULONG getStartBlock(struct PartitionHandle *ph) {
94 ULONG start = 0;
96 while (ph)
98 start += ph->de.de_LowCyl*ph->de.de_BlocksPerTrack*ph->de.de_Surfaces;
99 ph = ph->root;
101 return start;
104 LONG deviceError(LONG err)
106 switch (err)
108 case 0:
109 return 0;
111 case TDERR_WriteProt:
112 return ERROR_DISK_WRITE_PROTECTED;
114 case TDERR_SeekError:
115 return ERROR_SEEK_ERROR;
117 default:
118 return ERROR_NOT_A_DOS_DISK;
123 * Initialize partition handle based on parent's data.
124 * Geometry will be inherited from parent and adjusted if needed
125 * for given start block and length in blocks to fit in.
127 void initPartitionHandle(struct PartitionHandle *root, struct PartitionHandle *ph, ULONG first_sector, ULONG count_sector)
129 ULONG cylsecs = root->de.de_BlocksPerTrack * root->de.de_Surfaces;
131 /* Attach parent */
132 ph->root = root;
133 ph->bd = root->bd;
135 /* initialize DosEnvec */
136 CopyMem(&root->de, &ph->de, sizeof(struct DosEnvec));
138 /* Check if partition starts and ends on a cylinder boundary */
139 if ((first_sector % cylsecs != 0) || (count_sector % cylsecs != 0))
141 /* Treat each track as a cylinder if possible */
142 ph->de.de_Surfaces = 1;
143 cylsecs = ph->de.de_BlocksPerTrack;
145 if ((first_sector % cylsecs != 0) || (count_sector % cylsecs != 0))
148 * We can't. We could find the highest common factor of
149 * first_sector and count_sector here, but currently we
150 * simply use one block per cylinder (flat LBA)
152 ph->de.de_BlocksPerTrack = 1;
153 cylsecs = 1;
157 /* initialize DriveGeometry */
158 ph->dg.dg_DeviceType = DG_DIRECT_ACCESS;
159 ph->dg.dg_SectorSize = ph->de.de_SizeBlock<<2;
160 ph->dg.dg_Heads = ph->de.de_Surfaces;
161 ph->dg.dg_TrackSectors = ph->de.de_BlocksPerTrack;
162 ph->dg.dg_Cylinders = count_sector / cylsecs;
163 ph->dg.dg_CylSectors = cylsecs;
164 ph->dg.dg_BufMemType = ph->de.de_BufMemType;
166 /* Set start/end cylinder in DosEnvec */
167 ph->de.de_LowCyl = first_sector / cylsecs;
168 ph->de.de_HighCyl = ph->de.de_LowCyl + ph->dg.dg_Cylinders - 1;
170 /* Fix up DosEnvec size if necessary */
171 if (ph->de.de_TableSize < DE_BUFMEMTYPE)
172 ph->de.de_TableSize = DE_BUFMEMTYPE;
175 /* Set DOSType and some defaults according to it */
176 void setDosType(struct DosEnvec *de, ULONG type)
178 de->de_TableSize = DE_DOSTYPE;
179 de->de_SectorPerBlock = 1;
180 de->de_DosType = type;
182 * These two are actually device-dependent. However there's no way
183 * to obtain them, so just fill in defaults.
185 de->de_MaxTransfer = 0x00200000;
186 de->de_Mask = 0x7ffffffe;
188 /* Some more filesystem-specific defaults */
189 switch (type)
191 case ID_DOS_DISK:
192 case ID_FFS_DISK:
193 case ID_INTER_FFS_DISK:
194 case ID_SFS_BE_DISK:
195 de->de_TableSize = DE_BOOTBLOCKS;
196 de->de_Reserved = 2;
197 de->de_BootBlocks = 2;