Init control word to zero, cdrom-handler reads this and will crash if it is non-zero...
[AROS.git] / rom / partition / partition_support.c
blobed67148f5de7a1034e5da0c0bc1900218d5192a9
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 &PartitionRDB,
18 &PartitionGPT, /* The order of these two is important, GPT must be checked before MBR */
19 &PartitionMBR,
20 &PartitionEBR,
21 NULL
24 /* get geometry */
25 LONG PartitionGetGeometry
27 struct Library *PartitionBase,
28 struct IOExtTD *ioreq,
29 struct DriveGeometry *dg
33 ioreq->iotd_Req.io_Command = TD_GETGEOMETRY;
34 ioreq->iotd_Req.io_Data = dg;
35 ioreq->iotd_Req.io_Length = sizeof(struct DriveGeometry);
36 return DoIO((struct IORequest *)ioreq);
39 /* query NSD commands */
40 void PartitionNsdCheck
42 struct Library *PartitionBase,
43 struct PartitionHandle *root
46 struct NSDeviceQueryResult nsdq;
47 struct IOExtTD *ioreq = root->bd->ioreq;
48 UWORD *cmdcheck;
50 if (
52 root->de.de_HighCyl*
53 root->de.de_Surfaces*
54 root->de.de_BlocksPerTrack*
55 ((root->de.de_SizeBlock<<2)/512)
56 )>8388608)
58 nsdq.SizeAvailable=0;
59 nsdq.DevQueryFormat=0;
60 ioreq->iotd_Req.io_Command=NSCMD_DEVICEQUERY;
61 ioreq->iotd_Req.io_Data=&nsdq;
62 ioreq->iotd_Req.io_Length=sizeof(struct NSDeviceQueryResult);
63 if (DoIO((struct IORequest *)ioreq)==0)
65 if (
66 (ioreq->iotd_Req.io_Actual<=sizeof(struct NSDeviceQueryResult)) &&
67 (ioreq->iotd_Req.io_Actual!=0) &&
68 (ioreq->iotd_Req.io_Actual==nsdq.SizeAvailable)
71 if (nsdq.DeviceType != NSDEVTYPE_TRACKDISK)
72 D(bug("partition: NSDcheck: WARNING no trackdisk type\n"));
73 for (cmdcheck=nsdq.SupportedCommands;*cmdcheck;cmdcheck++)
75 if (*cmdcheck == NSCMD_TD_READ64)
76 root->bd->cmdread = NSCMD_TD_READ64;
77 if (*cmdcheck == NSCMD_TD_WRITE64);
78 root->bd->cmdwrite = NSCMD_TD_WRITE64;
81 else
82 D(bug("partition: NSDcheck: WARNING wrong io_Actual using NSD\n"));
87 /* get real first block of partition ph */
88 ULONG getStartBlock(struct PartitionHandle *ph) {
89 ULONG start = 0;
91 while (ph)
93 start += ph->de.de_LowCyl*ph->de.de_BlocksPerTrack*ph->de.de_Surfaces;
94 ph = ph->root;
96 return start;
99 /* read a single block within partition ph */
100 LONG readBlock(struct Library *PartitionBase, struct PartitionHandle *ph, ULONG block, void *mem)
102 return readDataFromBlock(ph, block, ph->de.de_SizeBlock<<2, mem);
105 /* read 'size' bytes starting from 'block' within partition ph */
106 LONG readDataFromBlock(struct PartitionHandle *ph, UQUAD block, ULONG size, void *mem)
108 UQUAD offset = (getStartBlock(ph) + block) * (ph->de.de_SizeBlock<<2);
109 struct IOExtTD *ioreq = ph->bd->ioreq;
111 ioreq->iotd_Req.io_Command = ph->bd->cmdread;
112 ioreq->iotd_Req.io_Length = size;
113 ioreq->iotd_Req.io_Data = mem;
114 ioreq->iotd_Req.io_Offset = offset;
115 ioreq->iotd_Req.io_Actual = offset >> 32;
117 return DoIO((struct IORequest *)ioreq);
121 write a single block within partition ph
123 LONG PartitionWriteBlock(struct Library *PartitionBase, struct PartitionHandle *ph, ULONG block, void *mem)
125 return writeDataFromBlock(ph, block, ph->de.de_SizeBlock << 2, mem);
128 /* write 'size' bytes starting from 'block' within partition ph */
129 LONG writeDataFromBlock(struct PartitionHandle *ph, UQUAD block, ULONG size, void *mem)
131 UQUAD offset = (getStartBlock(ph) + block) * (ph->de.de_SizeBlock<<2);
132 struct IOExtTD *ioreq = ph->bd->ioreq;
134 ioreq->iotd_Req.io_Command = ph->bd->cmdwrite;
135 ioreq->iotd_Req.io_Length = size;
136 ioreq->iotd_Req.io_Data = mem;
137 ioreq->iotd_Req.io_Offset = offset;
138 ioreq->iotd_Req.io_Actual = offset>>32;
140 return DoIO((struct IORequest *)ioreq);
143 LONG deviceError(LONG err)
145 switch (err)
147 case 0:
148 return 0;
150 case TDERR_WriteProt:
151 return ERROR_DISK_WRITE_PROTECTED;
153 case TDERR_SeekError:
154 return ERROR_SEEK_ERROR;
156 default:
157 return ERROR_NOT_A_DOS_DISK;
162 * Initialize partition handle based on parent's data.
163 * Geometry will be inherited from parent and adjusted if needed
164 * for given start block and length in blocks to fit in.
166 void initPartitionHandle(struct PartitionHandle *root, struct PartitionHandle *ph, ULONG first_sector, ULONG count_sector)
168 ULONG cylsecs = root->de.de_BlocksPerTrack * root->de.de_Surfaces;
170 /* Attach parent */
171 ph->root = root;
172 ph->bd = root->bd;
174 /* initialize DosEnvec */
175 CopyMem(&root->de, &ph->de, sizeof(struct DosEnvec));
177 /* Check if partition starts and ends on a cylinder boundary */
178 if ((first_sector % cylsecs != 0) || (count_sector % cylsecs != 0))
180 /* Treat each track as a cylinder if possible */
181 ph->de.de_Surfaces = 1;
182 cylsecs = ph->de.de_BlocksPerTrack;
184 if ((first_sector % cylsecs != 0) || (count_sector % cylsecs != 0))
187 * We can't. We could find the highest common factor of
188 * first_sector and count_sector here, but currently we
189 * simply use one block per cylinder (flat LBA)
191 ph->de.de_BlocksPerTrack = 1;
192 cylsecs = 1;
196 /* initialize DriveGeometry */
197 ph->dg.dg_DeviceType = DG_DIRECT_ACCESS;
198 ph->dg.dg_SectorSize = ph->de.de_SizeBlock<<2;
199 ph->dg.dg_Heads = ph->de.de_Surfaces;
200 ph->dg.dg_TrackSectors = ph->de.de_BlocksPerTrack;
201 ph->dg.dg_Cylinders = count_sector / cylsecs;
202 ph->dg.dg_BufMemType = ph->de.de_BufMemType;
204 /* Set start/end cylinder in DosEnvec */
205 ph->de.de_LowCyl = first_sector / cylsecs;
206 ph->de.de_HighCyl = ph->de.de_LowCyl + ph->dg.dg_Cylinders - 1;
208 /* Fix up DosEnvec size if necessary */
209 if (ph->de.de_TableSize < DE_BUFMEMTYPE)
210 ph->de.de_TableSize = DE_BUFMEMTYPE;
213 /* Set DOSType and some defaults according to it */
214 void setDosType(struct DosEnvec *de, ULONG type)
216 de->de_TableSize = DE_DOSTYPE;
217 de->de_SectorPerBlock = 1;
218 de->de_DosType = type;
220 * These two are actually device-dependent. However there's no way
221 * to obtain them, so just fill in defaults.
223 de->de_MaxTransfer = 0x00200000;
224 de->de_Mask = 0x7ffffffe;
226 /* Some more filesystem-specific defaults */
227 switch (type)
229 case ID_DOS_DISK:
230 case ID_FFS_DISK:
231 case ID_INTER_FFS_DISK:
232 case ID_SFS_BE_DISK:
233 de->de_TableSize = DE_BOOTBLOCKS;
234 de->de_Reserved = 2;
235 de->de_BootBlocks = 2;