Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / libs / partition / partition_support.c
blobe288084f1d21f6e31185f3a5c54314d25c70fd50
1 /*
2 Copyright � 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 */
8 #include <proto/exec.h>
9 #include <devices/newstyle.h>
10 #include <utility/tagitem.h>
12 #include "partition_intern.h"
13 #include "partition_support.h"
15 #ifndef DEBUG
16 #define DEBUG 1
17 #endif
18 #include "debug.h"
20 extern struct PTFunctionTable PartitionEBR;
21 extern struct PTFunctionTable PartitionMBR;
22 extern struct PTFunctionTable PartitionRDB;
24 struct PTFunctionTable *PartitionSupport[] =
25 {&PartitionRDB, &PartitionMBR, &PartitionEBR, 0};
27 /* get geometry */
28 LONG PartitionGetGeometry
30 struct Library *PartitionBase,
31 struct IOExtTD *ioreq,
32 struct DriveGeometry *dg
36 ioreq->iotd_Req.io_Command = TD_GETGEOMETRY;
37 ioreq->iotd_Req.io_Data = dg;
38 ioreq->iotd_Req.io_Length = sizeof(struct DriveGeometry);
39 return DoIO((struct IORequest *)ioreq);
42 /* query NSD commands */
43 void PartitionNsdCheck
45 struct Library *PartitionBase,
46 struct PartitionHandle *root
49 struct NSDeviceQueryResult nsdq;
50 struct IOExtTD *ioreq = root->bd->ioreq;
51 UWORD *cmdcheck;
53 if (
55 root->de.de_HighCyl*
56 root->de.de_Surfaces*
57 root->de.de_BlocksPerTrack*
58 ((root->de.de_SizeBlock<<2)/512)
59 )>8388608)
61 nsdq.SizeAvailable=0;
62 nsdq.DevQueryFormat=0;
63 ioreq->iotd_Req.io_Command=NSCMD_DEVICEQUERY;
64 ioreq->iotd_Req.io_Data=&nsdq;
65 ioreq->iotd_Req.io_Length=sizeof(struct NSDeviceQueryResult);
66 if (DoIO((struct IORequest *)ioreq)==0)
68 if (
69 (ioreq->iotd_Req.io_Actual<=sizeof(struct NSDeviceQueryResult)) &&
70 (ioreq->iotd_Req.io_Actual!=0) &&
71 (ioreq->iotd_Req.io_Actual==nsdq.SizeAvailable)
74 if (nsdq.DeviceType != NSDEVTYPE_TRACKDISK)
75 D(bug("partition: NSDcheck: WARNING no trackdisk type\n"));
76 for (cmdcheck=nsdq.SupportedCommands;*cmdcheck;cmdcheck++)
78 if (*cmdcheck == NSCMD_TD_READ64)
79 root->bd->cmdread = NSCMD_TD_READ64;
80 if (*cmdcheck == NSCMD_TD_WRITE64);
81 root->bd->cmdwrite = NSCMD_TD_WRITE64;
84 else
85 D(bug("partition: NSDcheck: WARNING wrong io_Actual using NSD\n"));
90 /* get real first block of partition ph */
91 ULONG getStartBlock(struct PartitionHandle *ph) {
92 ULONG start = 0;
94 while (ph)
96 start += ph->de.de_LowCyl*ph->de.de_BlocksPerTrack*ph->de.de_Surfaces;
97 ph = ph->root;
99 return start;
104 read a block
105 block is within partition ph
107 LONG readBlock
109 struct Library *PartitionBase,
110 struct PartitionHandle *ph,
111 ULONG block,
112 void *mem
115 struct IOExtTD *ioreq;
116 #ifdef __AMIGAOS__
117 ULONG lo, hi;
118 #else
119 UQUAD offset;
120 #endif
122 ioreq = ph->bd->ioreq;
123 ioreq->iotd_Req.io_Command=ph->bd->cmdread;
124 ioreq->iotd_Req.io_Length=ph->de.de_SizeBlock<<2;
125 ioreq->iotd_Req.io_Data=mem;
126 #ifdef __AMIGAOS__
127 lo = getStartBlock(ph)+block;
128 hi = lo>>16; /* high 16 bits into "hi" */
129 lo &= 0xFFFF; /* low 16 bits stay in "lo" */
130 lo *= (ph->de.de_SizeBlock<<2); /* multiply lo part */
131 hi *= (ph->de.de_SizeBlock<<2); /* multiply hi part */
132 ioreq->iotd_Req.io_Offset = lo+(hi<<16); /* compose first low 32 bit */
133 ioreq->iotd_Req.io_Actual = hi>>16; /* high 32 bits (at least until bit 48 */
134 #else
135 offset=(UQUAD)(getStartBlock(ph)+block)*(ph->de.de_SizeBlock<<2);
136 ioreq->iotd_Req.io_Offset=0xFFFFFFFF & offset;
137 ioreq->iotd_Req.io_Actual=offset>>32;
138 #endif
139 return DoIO((struct IORequest *)&ioreq->iotd_Req);
143 write a block
144 block is within partition ph
146 LONG PartitionWriteBlock
148 struct Library *PartitionBase,
149 struct PartitionHandle *ph,
150 ULONG block,
151 void *mem
154 struct IOExtTD *ioreq;
155 #ifdef __AMIGAOS__
156 ULONG lo, hi;
157 #else
158 UQUAD offset;
159 #endif
161 ioreq = ph->bd->ioreq;
162 ioreq->iotd_Req.io_Command=ph->bd->cmdwrite;
163 ioreq->iotd_Req.io_Length=ph->de.de_SizeBlock<<2;
164 ioreq->iotd_Req.io_Data=mem;
165 #ifdef __AMIGAOS__
166 lo = getStartBlock(ph)+block;
167 hi = lo>>16; /* high 16 bits into "hi" */
168 lo &= 0xFFFF; /* low 16 bits stay in "lo" */
169 lo *= (ph->de.de_SizeBlock<<2); /* multiply lo part */
170 hi *= (ph->de.de_SizeBlock<<2); /* multiply hi part */
171 ioreq->iotd_Req.io_Offset = lo+(hi<<16); /* compose first low 32 bit */
172 ioreq->iotd_Req.io_Actual = hi>>16; /* high 32 bits (at least until bit 48 */
173 #else
174 offset=(UQUAD)(getStartBlock(ph)+block)*(ph->de.de_SizeBlock<<2);
175 ioreq->iotd_Req.io_Offset=0xFFFFFFFF & offset;
176 ioreq->iotd_Req.io_Actual=offset>>32;
177 #endif
178 return DoIO((struct IORequest *)&ioreq->iotd_Req);
181 struct TagItem *findTagItem(ULONG tag, struct TagItem *taglist) {
183 while (taglist[0].ti_Tag != TAG_DONE)
185 if (taglist[0].ti_Tag == tag)
186 return &taglist[0];
187 taglist++;
189 return 0;
192 void fillMem(BYTE *mem, LONG size, BYTE fillbyte) {
194 while (size--)
195 mem[size]=fillbyte;