2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
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"
15 const struct PTFunctionTable
* const PartitionSupport
[] =
17 &PartitionGPT
, /* The order of these two is important, GPT must be checked before MBR */
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
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
;
59 root
->de
.de_BlocksPerTrack
*
60 ((root
->de
.de_SizeBlock
<<2)/512)
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)
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
;
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
) {
98 start
+= ph
->de
.de_LowCyl
*ph
->de
.de_BlocksPerTrack
*ph
->de
.de_Surfaces
;
104 LONG
deviceError(LONG err
)
111 case TDERR_WriteProt
:
112 return ERROR_DISK_WRITE_PROTECTED
;
114 case TDERR_SeekError
:
115 return ERROR_SEEK_ERROR
;
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
;
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;
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 */
193 case ID_INTER_FFS_DISK
:
195 de
->de_TableSize
= DE_BOOTBLOCKS
;
197 de
->de_BootBlocks
= 2;