|
@@ -219,14 +219,13 @@ static int int13_guess_geometry_hdd ( struct san_device *sandev, void *scratch,
|
219
|
219
|
struct master_boot_record *mbr = scratch;
|
220
|
220
|
struct partition_table_entry *partition;
|
221
|
221
|
unsigned int i;
|
|
222
|
+ unsigned int start_cylinder;
|
|
223
|
+ unsigned int start_head;
|
|
224
|
+ unsigned int start_sector;
|
222
|
225
|
unsigned int end_head;
|
223
|
226
|
unsigned int end_sector;
|
224
|
227
|
int rc;
|
225
|
228
|
|
226
|
|
- /* Default guess is xx/255/63 */
|
227
|
|
- *heads = 255;
|
228
|
|
- *sectors = 63;
|
229
|
|
-
|
230
|
229
|
/* Read partition table */
|
231
|
230
|
if ( ( rc = sandev_rw ( sandev, 0, 1, virt_to_user ( mbr ),
|
232
|
231
|
block_read ) ) != 0 ) {
|
|
@@ -244,19 +243,54 @@ static int int13_guess_geometry_hdd ( struct san_device *sandev, void *scratch,
|
244
|
243
|
* heads and sectors_per_track if we find any used
|
245
|
244
|
* partitions.
|
246
|
245
|
*/
|
|
246
|
+ *heads = 0;
|
|
247
|
+ *sectors = 0;
|
247
|
248
|
for ( i = 0 ; i < 4 ; i++ ) {
|
|
249
|
+
|
|
250
|
+ /* Skip empty partitions */
|
248
|
251
|
partition = &mbr->partitions[i];
|
|
252
|
+ if ( ! partition->type )
|
|
253
|
+ continue;
|
|
254
|
+
|
|
255
|
+ /* If partition starts on cylinder 0 then we can
|
|
256
|
+ * unambiguously determine the number of sectors.
|
|
257
|
+ */
|
|
258
|
+ start_cylinder = PART_CYLINDER ( partition->chs_start );
|
|
259
|
+ start_head = PART_HEAD ( partition->chs_start );
|
|
260
|
+ start_sector = PART_SECTOR ( partition->chs_start );
|
|
261
|
+ if ( ( start_cylinder == 0 ) && ( start_head != 0 ) ) {
|
|
262
|
+ *sectors = ( ( partition->start + 1 - start_sector ) /
|
|
263
|
+ start_head );
|
|
264
|
+ DBGC ( sandev, "INT13 drive %02x guessing C/H/S "
|
|
265
|
+ "xx/xx/%d based on partition %d\n",
|
|
266
|
+ sandev->drive, *sectors, ( i + 1 ) );
|
|
267
|
+ }
|
|
268
|
+
|
|
269
|
+ /* If partition ends on a higher head or sector number
|
|
270
|
+ * than our current guess, then increase the guess.
|
|
271
|
+ */
|
249
|
272
|
end_head = PART_HEAD ( partition->chs_end );
|
250
|
273
|
end_sector = PART_SECTOR ( partition->chs_end );
|
251
|
|
- if ( ! ( partition->type && end_head && end_sector ) )
|
252
|
|
- continue;
|
253
|
|
- *heads = ( end_head + 1 );
|
254
|
|
- *sectors = end_sector;
|
255
|
|
- DBGC ( sandev, "INT13 drive %02x guessing C/H/S xx/%d/%d based "
|
256
|
|
- "on partition %d\n",
|
257
|
|
- sandev->drive, *heads, *sectors, ( i + 1 ) );
|
|
274
|
+ if ( ( end_head + 1 ) > *heads ) {
|
|
275
|
+ *heads = ( end_head + 1 );
|
|
276
|
+ DBGC ( sandev, "INT13 drive %02x guessing C/H/S "
|
|
277
|
+ "xx/%d/xx based on partition %d\n",
|
|
278
|
+ sandev->drive, *heads, ( i + 1 ) );
|
|
279
|
+ }
|
|
280
|
+ if ( end_sector > *sectors ) {
|
|
281
|
+ *sectors = end_sector;
|
|
282
|
+ DBGC ( sandev, "INT13 drive %02x guessing C/H/S "
|
|
283
|
+ "xx/xx/%d based on partition %d\n",
|
|
284
|
+ sandev->drive, *sectors, ( i + 1 ) );
|
|
285
|
+ }
|
258
|
286
|
}
|
259
|
287
|
|
|
288
|
+ /* Default guess is xx/255/63 */
|
|
289
|
+ if ( ! *heads )
|
|
290
|
+ *heads = 255;
|
|
291
|
+ if ( ! *sectors )
|
|
292
|
+ *sectors = 63;
|
|
293
|
+
|
260
|
294
|
return 0;
|
261
|
295
|
}
|
262
|
296
|
|