Deleted Added
full compact
biosdisk.c (63101) biosdisk.c (68358)
1/*-
2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/boot/pc98/libpc98/biosdisk.c 63101 2000-07-14 04:23:45Z nyan $
26 * $FreeBSD: head/sys/boot/pc98/libpc98/biosdisk.c 68358 2000-11-05 12:35:41Z nyan $
27 */
28
29/*
30 * BIOS disk device handling.
31 *
32 * Ideas and algorithms from:
33 *
34 * - NetBSD libi386/biosdisk.c

--- 67 unchanged lines hidden (view full) ---

102
103static int bd_getgeom(struct open_disk *od);
104static int bd_read(struct open_disk *od, daddr_t dblk, int blks,
105 caddr_t dest);
106
107static int bd_int13probe(struct bdinfo *bd);
108
109static void bd_printslice(struct open_disk *od, struct dos_partition *dp,
27 */
28
29/*
30 * BIOS disk device handling.
31 *
32 * Ideas and algorithms from:
33 *
34 * - NetBSD libi386/biosdisk.c

--- 67 unchanged lines hidden (view full) ---

102
103static int bd_getgeom(struct open_disk *od);
104static int bd_read(struct open_disk *od, daddr_t dblk, int blks,
105 caddr_t dest);
106
107static int bd_int13probe(struct bdinfo *bd);
108
109static void bd_printslice(struct open_disk *od, struct dos_partition *dp,
110 char *prefix);
111static void bd_printbsdslice(struct open_disk *od, int offset, char *prefix);
110 char *prefix, int verbose);
111static void bd_printbsdslice(struct open_disk *od, daddr_t offset,
112 char *prefix, int verbose);
112
113static int bd_init(void);
114static int bd_strategy(void *devdata, int flag, daddr_t dblk,
113
114static int bd_init(void);
115static int bd_strategy(void *devdata, int flag, daddr_t dblk,
115 size_t size, void *buf, size_t *rsize);
116 size_t size, char *buf, size_t *rsize);
116static int bd_realstrategy(void *devdata, int flag, daddr_t dblk,
117static int bd_realstrategy(void *devdata, int flag, daddr_t dblk,
117 size_t size, void *buf, size_t *rsize);
118 size_t size, char *buf, size_t *rsize);
118static int bd_open(struct open_file *f, ...);
119static int bd_close(struct open_file *f);
120static void bd_print(int verbose);
121
122struct devsw biosdisk = {
123 "disk",
124 DEVT_DISK,
125 bd_init,
126 bd_strategy,
127 bd_open,
128 bd_close,
129 noioctl,
119static int bd_open(struct open_file *f, ...);
120static int bd_close(struct open_file *f);
121static void bd_print(int verbose);
122
123struct devsw biosdisk = {
124 "disk",
125 DEVT_DISK,
126 bd_init,
127 bd_strategy,
128 bd_open,
129 bd_close,
130 noioctl,
130 bd_print
131 bd_print,
132 NULL
131};
132
133static int bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev);
134static void bd_closedisk(struct open_disk *od);
135static int bd_bestslice(struct open_disk *od);
136static void bd_checkextended(struct open_disk *od, int slicenum);
137
138/*

--- 66 unchanged lines hidden (view full) ---

205#else
206 int base, unit, nfd = 0;
207
208 /* sequence 0, 0x80 */
209 for (base = 0; base <= 0x80; base += 0x80) {
210 for (unit = base; (nbdinfo < MAXBDDEV); unit++) {
211 /* check the BIOS equipment list for number of fixed disks */
212 if((base == 0x80) &&
133};
134
135static int bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev);
136static void bd_closedisk(struct open_disk *od);
137static int bd_bestslice(struct open_disk *od);
138static void bd_checkextended(struct open_disk *od, int slicenum);
139
140/*

--- 66 unchanged lines hidden (view full) ---

207#else
208 int base, unit, nfd = 0;
209
210 /* sequence 0, 0x80 */
211 for (base = 0; base <= 0x80; base += 0x80) {
212 for (unit = base; (nbdinfo < MAXBDDEV); unit++) {
213 /* check the BIOS equipment list for number of fixed disks */
214 if((base == 0x80) &&
213 (nfd >= *(unsigned short *)PTOV(BIOS_NUMDRIVES)))
215 (nfd >= *(unsigned char *)PTOV(BIOS_NUMDRIVES)))
214 break;
215
216 bdinfo[nbdinfo].bd_unit = unit;
217 bdinfo[nbdinfo].bd_flags = (unit < 0x80) ? BD_FLOPPY : 0;
218
219 if (!bd_int13probe(&bdinfo[nbdinfo]))
220 break;
221

--- 34 unchanged lines hidden (view full) ---

256#else
257 v86.ctl = V86_FLAGS;
258 v86.addr = 0x13;
259 v86.eax = 0x800;
260 v86.edx = bd->bd_unit;
261 v86int();
262
263 if (!(v86.efl & 0x1) && /* carry clear */
216 break;
217
218 bdinfo[nbdinfo].bd_unit = unit;
219 bdinfo[nbdinfo].bd_flags = (unit < 0x80) ? BD_FLOPPY : 0;
220
221 if (!bd_int13probe(&bdinfo[nbdinfo]))
222 break;
223

--- 34 unchanged lines hidden (view full) ---

258#else
259 v86.ctl = V86_FLAGS;
260 v86.addr = 0x13;
261 v86.eax = 0x800;
262 v86.edx = bd->bd_unit;
263 v86int();
264
265 if (!(v86.efl & 0x1) && /* carry clear */
264 ((v86.edx & 0xff) > (bd->bd_unit & 0x7f))) { /* unit # OK */
266 ((v86.edx & 0xff) > ((unsigned)bd->bd_unit & 0x7f))) { /* unit # OK */
265 bd->bd_flags |= BD_MODEINT13;
266 bd->bd_type = v86.ebx & 0xff;
267
268 /* Determine if we can use EDD with this device. */
269 v86.eax = 0x4100;
270 v86.edx = bd->bd_unit;
271 v86.ebx = 0x55aa;
272 v86int();
273 if (!(v86.efl & 0x1) && /* carry clear */
274 ((v86.ebx & 0xffff) == 0xaa55) && /* signature */
275 (v86.ecx & 0x1)) { /* packets mode ok */
276 bd->bd_flags |= BD_MODEEDD1;
267 bd->bd_flags |= BD_MODEINT13;
268 bd->bd_type = v86.ebx & 0xff;
269
270 /* Determine if we can use EDD with this device. */
271 v86.eax = 0x4100;
272 v86.edx = bd->bd_unit;
273 v86.ebx = 0x55aa;
274 v86int();
275 if (!(v86.efl & 0x1) && /* carry clear */
276 ((v86.ebx & 0xffff) == 0xaa55) && /* signature */
277 (v86.ecx & 0x1)) { /* packets mode ok */
278 bd->bd_flags |= BD_MODEEDD1;
277 if(v86.eax & 0xff00 > 0x300)
279 if((v86.eax & 0xff00) > 0x300)
278 bd->bd_flags |= BD_MODEEDD3;
279 }
280 return(1);
281 }
282 return(0);
283#endif
284}
285

--- 24 unchanged lines hidden (view full) ---

310 dev.d_kind.biosdisk.partition = -1;
311
312 if (!bd_opendisk(&od, &dev)) {
313
314 /* Do we have a partition table? */
315 if (od->od_flags & BD_PARTTABOK) {
316 dptr = &od->od_slicetab[0];
317
280 bd->bd_flags |= BD_MODEEDD3;
281 }
282 return(1);
283 }
284 return(0);
285#endif
286}
287

--- 24 unchanged lines hidden (view full) ---

312 dev.d_kind.biosdisk.partition = -1;
313
314 if (!bd_opendisk(&od, &dev)) {
315
316 /* Do we have a partition table? */
317 if (od->od_flags & BD_PARTTABOK) {
318 dptr = &od->od_slicetab[0];
319
318 /* Check for a "truly dedicated" disk */
320 /* Check for a "dedicated" disk */
319#ifdef PC98
320 for (j = 0; j < od->od_nslices; j++) {
321 switch(dptr[j].dp_mid) {
322 case DOSMID_386BSD:
323 sprintf(line, " disk%ds%d", i, j + 1);
324 bd_printbsdslice(od,
325 dptr[j].dp_scyl * od->od_hds * od->od_sec +
326 dptr[j].dp_shd * od->od_sec + dptr[j].dp_ssect,
321#ifdef PC98
322 for (j = 0; j < od->od_nslices; j++) {
323 switch(dptr[j].dp_mid) {
324 case DOSMID_386BSD:
325 sprintf(line, " disk%ds%d", i, j + 1);
326 bd_printbsdslice(od,
327 dptr[j].dp_scyl * od->od_hds * od->od_sec +
328 dptr[j].dp_shd * od->od_sec + dptr[j].dp_ssect,
327 line);
329 line, verbose);
328 break;
329 default:
330 }
331 }
332#else
333 if ((dptr[3].dp_typ == DOSPTYP_386BSD) &&
334 (dptr[3].dp_start == 0) &&
335 (dptr[3].dp_size == 50000)) {
336 sprintf(line, " disk%d", i);
330 break;
331 default:
332 }
333 }
334#else
335 if ((dptr[3].dp_typ == DOSPTYP_386BSD) &&
336 (dptr[3].dp_start == 0) &&
337 (dptr[3].dp_size == 50000)) {
338 sprintf(line, " disk%d", i);
337 bd_printbsdslice(od, 0, line);
339 bd_printbsdslice(od, 0, line, verbose);
338 } else {
339 for (j = 0; j < od->od_nslices; j++) {
340 sprintf(line, " disk%ds%d", i, j + 1);
340 } else {
341 for (j = 0; j < od->od_nslices; j++) {
342 sprintf(line, " disk%ds%d", i, j + 1);
341 bd_printslice(od, &dptr[j], line);
343 bd_printslice(od, &dptr[j], line, verbose);
342 }
343 }
344#endif
345 }
346 bd_closedisk(od);
347 }
348 }
349}
350
344 }
345 }
346#endif
347 }
348 bd_closedisk(od);
349 }
350 }
351}
352
353#ifndef PC98
351/*
354/*
352 * Print information about slices on a disk
355 * Print information about slices on a disk. For the size calculations we
356 * assume a 512 byte sector.
353 */
357 */
354#ifndef PC98
355static void
358static void
356bd_printslice(struct open_disk *od, struct dos_partition *dp, char *prefix)
359bd_printslice(struct open_disk *od, struct dos_partition *dp, char *prefix,
360 int verbose)
357{
358 char line[80];
359
360 switch (dp->dp_typ) {
361 case DOSPTYP_386BSD:
361{
362 char line[80];
363
364 switch (dp->dp_typ) {
365 case DOSPTYP_386BSD:
362 bd_printbsdslice(od, dp->dp_start, prefix);
366 bd_printbsdslice(od, (daddr_t)dp->dp_start, prefix, verbose);
363 return;
364 case DOSPTYP_LINSWP:
367 return;
368 case DOSPTYP_LINSWP:
365 sprintf(line, "%s: Linux swap %.6dMB (%d - %d)\n", prefix,
366 dp->dp_size / 2048, /* 512-byte sector assumption */
367 dp->dp_start, dp->dp_start + dp->dp_size);
369 if (verbose)
370 sprintf(line, "%s: Linux swap %.6dMB (%d - %d)\n",
371 prefix, dp->dp_size / 2048,
372 dp->dp_start, dp->dp_start + dp->dp_size);
373 else
374 sprintf(line, "%s: Linux swap\n", prefix);
368 break;
369 case DOSPTYP_LINUX:
370 /*
371 * XXX
372 * read the superblock to confirm this is an ext2fs partition?
373 */
375 break;
376 case DOSPTYP_LINUX:
377 /*
378 * XXX
379 * read the superblock to confirm this is an ext2fs partition?
380 */
374 sprintf(line, "%s: ext2fs %.6dMB (%d - %d)\n", prefix,
375 dp->dp_size / 2048, /* 512-byte sector assumption */
376 dp->dp_start, dp->dp_start + dp->dp_size);
381 if (verbose)
382 sprintf(line, "%s: ext2fs %.6dMB (%d - %d)\n", prefix,
383 dp->dp_size / 2048, dp->dp_start,
384 dp->dp_start + dp->dp_size);
385 else
386 sprintf(line, "%s: ext2fs\n", prefix);
377 break;
378 case 0x00: /* unused partition */
379 case DOSPTYP_EXT:
380 return;
381 case 0x01:
387 break;
388 case 0x00: /* unused partition */
389 case DOSPTYP_EXT:
390 return;
391 case 0x01:
382 sprintf(line, "%s: FAT-12 %.6dMB (%d - %d)\n", prefix,
383 dp->dp_size / 2048, /* 512-byte sector assumption */
384 dp->dp_start, dp->dp_start + dp->dp_size);
392 if (verbose)
393 sprintf(line, "%s: FAT-12 %.6dMB (%d - %d)\n", prefix,
394 dp->dp_size / 2048, dp->dp_start,
395 dp->dp_start + dp->dp_size);
396 else
397 sprintf(line, "%s: FAT-12\n", prefix);
385 break;
386 case 0x04:
387 case 0x06:
388 case 0x0e:
398 break;
399 case 0x04:
400 case 0x06:
401 case 0x0e:
389 sprintf(line, "%s: FAT-16 %.6dMB (%d - %d)\n", prefix,
390 dp->dp_size / 2048, /* 512-byte sector assumption */
391 dp->dp_start, dp->dp_start + dp->dp_size);
402 if (verbose)
403 sprintf(line, "%s: FAT-16 %.6dMB (%d - %d)\n", prefix,
404 dp->dp_size / 2048, dp->dp_start,
405 dp->dp_start + dp->dp_size);
406 else
407 sprintf(line, "%s: FAT-16\n", prefix);
392 break;
393 case 0x0b:
394 case 0x0c:
408 break;
409 case 0x0b:
410 case 0x0c:
395 sprintf(line, "%s: FAT-32 %.6dMB (%d - %d)\n", prefix,
396 dp->dp_size / 2048, /* 512-byte sector assumption */
397 dp->dp_start, dp->dp_start + dp->dp_size);
411 if (verbose)
412 sprintf(line, "%s: FAT-32 %.6dMB (%d - %d)\n", prefix,
413 dp->dp_size / 2048, dp->dp_start,
414 dp->dp_start + dp->dp_size);
415 else
416 sprintf(line, "%s: FAT-32\n", prefix);
398 break;
399 default:
417 break;
418 default:
400 sprintf(line, "%s: Unknown fs: 0x%x %.6dMB (%d - %d)\n",
401 prefix, dp->dp_typ,
402 dp->dp_size / 2048, /* 512-byte sector assumption */
403 dp->dp_start, dp->dp_start + dp->dp_size);
419 if (verbose)
420 sprintf(line, "%s: Unknown fs: 0x%x %.6dMB (%d - %d)\n",
421 prefix, dp->dp_typ, dp->dp_size / 2048,
422 dp->dp_start, dp->dp_start + dp->dp_size);
423 else
424 sprintf(line, "%s: Unknown fs: 0x%x\n", prefix,
425 dp->dp_typ);
404 }
405 pager_output(line);
406}
407#endif
408
426 }
427 pager_output(line);
428}
429#endif
430
431/*
432 * Print out each valid partition in the disklabel of a FreeBSD slice.
433 * For size calculations, we assume a 512 byte sector size.
434 */
409static void
435static void
410bd_printbsdslice(struct open_disk *od, int offset, char *prefix)
436bd_printbsdslice(struct open_disk *od, daddr_t offset, char *prefix,
437 int verbose)
411{
412 char line[80];
438{
439 char line[80];
413 u_char buf[BIOSDISK_SECSIZE];
440 char buf[BIOSDISK_SECSIZE];
414 struct disklabel *lp;
415 int i;
416
417 /* read disklabel */
418 if (bd_read(od, offset + LABELSECTOR, 1, buf))
419 return;
420 lp =(struct disklabel *)(&buf[0]);
421 if (lp->d_magic != DISKMAGIC) {
422 sprintf(line, "%s: FFS bad disklabel\n", prefix);
423 pager_output(line);
424 return;
425 }
426
427 /* Print partitions */
428 for (i = 0; i < lp->d_npartitions; i++) {
441 struct disklabel *lp;
442 int i;
443
444 /* read disklabel */
445 if (bd_read(od, offset + LABELSECTOR, 1, buf))
446 return;
447 lp =(struct disklabel *)(&buf[0]);
448 if (lp->d_magic != DISKMAGIC) {
449 sprintf(line, "%s: FFS bad disklabel\n", prefix);
450 pager_output(line);
451 return;
452 }
453
454 /* Print partitions */
455 for (i = 0; i < lp->d_npartitions; i++) {
456 /*
457 * For each partition, make sure we know what type of fs it is. If
458 * not, then skip it. However, since floppies often have bogus
459 * fstypes, print the 'a' partition on a floppy even if it is marked
460 * unused.
461 */
429 if ((lp->d_partitions[i].p_fstype == FS_BSDFFS) ||
430 (lp->d_partitions[i].p_fstype == FS_SWAP) ||
431 (lp->d_partitions[i].p_fstype == FS_VINUM) ||
432 ((lp->d_partitions[i].p_fstype == FS_UNUSED) &&
462 if ((lp->d_partitions[i].p_fstype == FS_BSDFFS) ||
463 (lp->d_partitions[i].p_fstype == FS_SWAP) ||
464 (lp->d_partitions[i].p_fstype == FS_VINUM) ||
465 ((lp->d_partitions[i].p_fstype == FS_UNUSED) &&
433 (od->od_flags & BD_FLOPPY) && (i == 0))) { /* Floppies often have bogus fstype, print 'a' */
434 sprintf(line, " %s%c: %s %.6dMB (%d - %d)\n", prefix, 'a' + i,
466 (od->od_flags & BD_FLOPPY) && (i == 0))) {
467
468 /* Only print out statistics in verbose mode */
469 if (verbose)
470 sprintf(line, " %s%c: %s %.6dMB (%d - %d)\n", prefix, 'a' + i,
435 (lp->d_partitions[i].p_fstype == FS_SWAP) ? "swap" :
471 (lp->d_partitions[i].p_fstype == FS_SWAP) ? "swap" :
436 (lp->d_partitions[i].p_fstype == FS_VINUM) ? "vinum" : "FFS",
437 lp->d_partitions[i].p_size / 2048, /* 512-byte sector assumption */
438 lp->d_partitions[i].p_offset, lp->d_partitions[i].p_offset + lp->d_partitions[i].p_size);
472 (lp->d_partitions[i].p_fstype == FS_VINUM) ? "vinum" :
473 "FFS",
474 lp->d_partitions[i].p_size / 2048,
475 lp->d_partitions[i].p_offset,
476 lp->d_partitions[i].p_offset + lp->d_partitions[i].p_size);
477 else
478 sprintf(line, " %s%c: %s\n", prefix, 'a' + i,
479 (lp->d_partitions[i].p_fstype == FS_SWAP) ? "swap" :
480 (lp->d_partitions[i].p_fstype == FS_VINUM) ? "vinum" :
481 "FFS");
439 pager_output(line);
440 }
441 }
442}
443
444
445/*
446 * Attempt to open the disk described by (dev) for use by (f).

--- 30 unchanged lines hidden (view full) ---

477static int
478bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev)
479{
480 struct dos_partition *dptr;
481 struct disklabel *lp;
482 struct open_disk *od;
483 int sector, slice, i;
484 int error;
482 pager_output(line);
483 }
484 }
485}
486
487
488/*
489 * Attempt to open the disk described by (dev) for use by (f).

--- 30 unchanged lines hidden (view full) ---

520static int
521bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev)
522{
523 struct dos_partition *dptr;
524 struct disklabel *lp;
525 struct open_disk *od;
526 int sector, slice, i;
527 int error;
485 u_char buf[BUFSIZE];
528 char buf[BUFSIZE];
486
487 if (dev->d_kind.biosdisk.unit >= nbdinfo) {
488 DEBUG("attempt to open nonexistent disk");
489 return(ENXIO);
490 }
491
492 od = (struct open_disk *)malloc(sizeof(struct open_disk));
493 if (!od) {

--- 38 unchanged lines hidden (view full) ---

532 DEBUG("error reading MBR");
533 error = EIO;
534 goto out;
535 }
536
537 /*
538 * Check the slice table magic.
539 */
529
530 if (dev->d_kind.biosdisk.unit >= nbdinfo) {
531 DEBUG("attempt to open nonexistent disk");
532 return(ENXIO);
533 }
534
535 od = (struct open_disk *)malloc(sizeof(struct open_disk));
536 if (!od) {

--- 38 unchanged lines hidden (view full) ---

575 DEBUG("error reading MBR");
576 error = EIO;
577 goto out;
578 }
579
580 /*
581 * Check the slice table magic.
582 */
540 if ((buf[0x1fe] != 0x55) || (buf[0x1ff] != 0xaa)) {
583 if (((u_char)buf[0x1fe] != 0x55) || ((u_char)buf[0x1ff] != 0xaa)) {
541 /* If a slice number was explicitly supplied, this is an error */
542 if (dev->d_kind.biosdisk.slice > 0) {
543 DEBUG("no slice table/MBR (no magic)");
544 error = ENOENT;
545 goto out;
546 }
547 sector = 0;
548 goto unsliced; /* may be a floppy */

--- 121 unchanged lines hidden (view full) ---

670 if (dev->d_kind.biosdisk.partition >= lp->d_npartitions) {
671 DEBUG("partition '%c' exceeds partitions in table (a-'%c')",
672 'a' + dev->d_kind.biosdisk.partition, 'a' + lp->d_npartitions);
673 error = EPART;
674 goto out;
675
676 }
677
584 /* If a slice number was explicitly supplied, this is an error */
585 if (dev->d_kind.biosdisk.slice > 0) {
586 DEBUG("no slice table/MBR (no magic)");
587 error = ENOENT;
588 goto out;
589 }
590 sector = 0;
591 goto unsliced; /* may be a floppy */

--- 121 unchanged lines hidden (view full) ---

713 if (dev->d_kind.biosdisk.partition >= lp->d_npartitions) {
714 DEBUG("partition '%c' exceeds partitions in table (a-'%c')",
715 'a' + dev->d_kind.biosdisk.partition, 'a' + lp->d_npartitions);
716 error = EPART;
717 goto out;
718
719 }
720
678 /* Complain if the partition type is wrong */
721#ifdef DISK_DEBUG
722 /* Complain if the partition is unused unless this is a floppy. */
679 if ((lp->d_partitions[dev->d_kind.biosdisk.partition].p_fstype == FS_UNUSED) &&
723 if ((lp->d_partitions[dev->d_kind.biosdisk.partition].p_fstype == FS_UNUSED) &&
680 !(od->od_flags & BD_FLOPPY)) /* Floppies often have bogus fstype */
724 !(od->od_flags & BD_FLOPPY))
681 DEBUG("warning, partition marked as unused");
725 DEBUG("warning, partition marked as unused");
726#endif
682
683 od->od_boff = lp->d_partitions[dev->d_kind.biosdisk.partition].p_offset;
684 }
685
686 out:
687 if (error) {
688 free(od);
689 } else {
690 *odp = od; /* return the open disk */
691 }
692 return(error);
693}
694
695#ifndef PC98
696static void
697bd_checkextended(struct open_disk *od, int slicenum)
698{
727
728 od->od_boff = lp->d_partitions[dev->d_kind.biosdisk.partition].p_offset;
729 }
730
731 out:
732 if (error) {
733 free(od);
734 } else {
735 *odp = od; /* return the open disk */
736 }
737 return(error);
738}
739
740#ifndef PC98
741static void
742bd_checkextended(struct open_disk *od, int slicenum)
743{
699 u_char buf[BIOSDISK_SECSIZE];
744 char buf[BIOSDISK_SECSIZE];
700 struct dos_partition *dp;
701 u_int base;
702 int i, start, end;
703
704 dp = &od->od_slicetab[slicenum];
705 start = od->od_nslices;
706
707 if (dp->dp_size == 0)
708 goto done;
709 if (dp->dp_typ != DOSPTYP_EXT)
710 goto done;
745 struct dos_partition *dp;
746 u_int base;
747 int i, start, end;
748
749 dp = &od->od_slicetab[slicenum];
750 start = od->od_nslices;
751
752 if (dp->dp_size == 0)
753 goto done;
754 if (dp->dp_typ != DOSPTYP_EXT)
755 goto done;
711 if (bd_read(od, dp->dp_start, 1, buf))
756 if (bd_read(od, (daddr_t)dp->dp_start, 1, buf))
712 goto done;
757 goto done;
713 if ((buf[0x1fe] != 0x55) || (buf[0x1ff] != 0xaa)) {
758 if (((u_char)buf[0x1fe] != 0x55) || ((u_char)buf[0x1ff] != 0xaa)) {
714 DEBUG("no magic in extended table");
715 goto done;
716 }
717 base = dp->dp_start;
718 dp = (struct dos_partition *)(&buf[DOSPARTOFF]);
719 for (i = 0; i < NDOSPART; i++, dp++) {
720 if (dp->dp_size == 0)
721 continue;

--- 126 unchanged lines hidden (view full) ---

848 /* XXX is this required? (especially if disk already open...) */
849 if (od->od_flags & BD_FLOPPY)
850 delay(3000000);
851#endif
852 free(od);
853}
854
855static int
759 DEBUG("no magic in extended table");
760 goto done;
761 }
762 base = dp->dp_start;
763 dp = (struct dos_partition *)(&buf[DOSPARTOFF]);
764 for (i = 0; i < NDOSPART; i++, dp++) {
765 if (dp->dp_size == 0)
766 continue;

--- 126 unchanged lines hidden (view full) ---

893 /* XXX is this required? (especially if disk already open...) */
894 if (od->od_flags & BD_FLOPPY)
895 delay(3000000);
896#endif
897 free(od);
898}
899
900static int
856bd_strategy(void *devdata, int rw, daddr_t dblk, size_t size, void *buf, size_t *rsize)
901bd_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize)
857{
858 struct bcache_devdata bcd;
859 struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)devdata)->d_kind.biosdisk.data);
860
861 bcd.dv_strategy = bd_realstrategy;
862 bcd.dv_devdata = devdata;
863 return(bcache_strategy(&bcd, od->od_unit, rw, dblk+od->od_boff, size, buf, rsize));
864}
865
866static int
902{
903 struct bcache_devdata bcd;
904 struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)devdata)->d_kind.biosdisk.data);
905
906 bcd.dv_strategy = bd_realstrategy;
907 bcd.dv_devdata = devdata;
908 return(bcache_strategy(&bcd, od->od_unit, rw, dblk+od->od_boff, size, buf, rsize));
909}
910
911static int
867bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size, void *buf, size_t *rsize)
912bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize)
868{
869 struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)devdata)->d_kind.biosdisk.data);
870 int blks;
871#ifdef BD_SUPPORT_FRAGS
872 char fragbuf[BIOSDISK_SECSIZE];
873 size_t fragsize;
874
875 fragsize = size % BIOSDISK_SECSIZE;

--- 32 unchanged lines hidden (view full) ---

908}
909
910/* Max number of sectors to bounce-buffer if the request crosses a 64k boundary */
911#define FLOPPY_BOUNCEBUF 18
912
913static int
914bd_read(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest)
915{
913{
914 struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)devdata)->d_kind.biosdisk.data);
915 int blks;
916#ifdef BD_SUPPORT_FRAGS
917 char fragbuf[BIOSDISK_SECSIZE];
918 size_t fragsize;
919
920 fragsize = size % BIOSDISK_SECSIZE;

--- 32 unchanged lines hidden (view full) ---

953}
954
955/* Max number of sectors to bounce-buffer if the request crosses a 64k boundary */
956#define FLOPPY_BOUNCEBUF 18
957
958static int
959bd_read(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest)
960{
916 int x, bpc, cyl, hd, sec, result, resid, cnt, retry, maxfer;
961 u_int x, bpc, cyl, hd, sec, result, resid, retry, maxfer;
917 caddr_t p, xp, bbuf, breg;
918
962 caddr_t p, xp, bbuf, breg;
963
964 /* Just in case some idiot actually tries to read -1 blocks... */
965 if (blks < 0)
966 return (-1);
967
919 bpc = (od->od_sec * od->od_hds); /* blocks per cylinder */
920 resid = blks;
921 p = dest;
922
923 /* Decide whether we have to bounce */
924#ifdef PC98
925 if (
926#else
927 if ((od->od_unit < 0x80) &&
928#endif
929 ((VTOP(dest) >> 16) != (VTOP(dest + blks * BIOSDISK_SECSIZE) >> 16))) {
930
931 /*
932 * There is a 64k physical boundary somewhere in the destination buffer, so we have
933 * to arrange a suitable bounce buffer. Allocate a buffer twice as large as we
934 * need to. Use the bottom half unless there is a break there, in which case we
935 * use the top half.
936 */
937#ifdef PC98
968 bpc = (od->od_sec * od->od_hds); /* blocks per cylinder */
969 resid = blks;
970 p = dest;
971
972 /* Decide whether we have to bounce */
973#ifdef PC98
974 if (
975#else
976 if ((od->od_unit < 0x80) &&
977#endif
978 ((VTOP(dest) >> 16) != (VTOP(dest + blks * BIOSDISK_SECSIZE) >> 16))) {
979
980 /*
981 * There is a 64k physical boundary somewhere in the destination buffer, so we have
982 * to arrange a suitable bounce buffer. Allocate a buffer twice as large as we
983 * need to. Use the bottom half unless there is a break there, in which case we
984 * use the top half.
985 */
986#ifdef PC98
938 x = min(od->od_sec, blks);
987 x = min(od->od_sec, (unsigned)blks);
939#else
988#else
940 x = min(FLOPPY_BOUNCEBUF, blks);
989 x = min(FLOPPY_BOUNCEBUF, (unsigned)blks);
941#endif
942 bbuf = malloc(x * 2 * BIOSDISK_SECSIZE);
943 if (((u_int32_t)VTOP(bbuf) & 0xffff0000) == ((u_int32_t)VTOP(dest + x * BIOSDISK_SECSIZE) & 0xffff0000)) {
944 breg = bbuf;
945 } else {
946 breg = bbuf + x * BIOSDISK_SECSIZE;
947 }
948 maxfer = x; /* limit transfers to bounce region size */
949 } else {
990#endif
991 bbuf = malloc(x * 2 * BIOSDISK_SECSIZE);
992 if (((u_int32_t)VTOP(bbuf) & 0xffff0000) == ((u_int32_t)VTOP(dest + x * BIOSDISK_SECSIZE) & 0xffff0000)) {
993 breg = bbuf;
994 } else {
995 breg = bbuf + x * BIOSDISK_SECSIZE;
996 }
997 maxfer = x; /* limit transfers to bounce region size */
998 } else {
950 bbuf = NULL;
999 breg = bbuf = NULL;
951 maxfer = 0;
952 }
953
954 while (resid > 0) {
955 x = dblk;
956 cyl = x / bpc; /* block # / blocks per cylinder */
957 x %= bpc; /* block offset into cylinder */
958 hd = x / od->od_sec; /* offset / blocks per track */

--- 151 unchanged lines hidden (view full) ---

1110#else
1111 v86.ctl = V86_FLAGS;
1112 v86.addr = 0x13;
1113 v86.eax = 0x800;
1114 v86.edx = od->od_unit;
1115 v86int();
1116
1117 if ((v86.efl & 0x1) || /* carry set */
1000 maxfer = 0;
1001 }
1002
1003 while (resid > 0) {
1004 x = dblk;
1005 cyl = x / bpc; /* block # / blocks per cylinder */
1006 x %= bpc; /* block offset into cylinder */
1007 hd = x / od->od_sec; /* offset / blocks per track */

--- 151 unchanged lines hidden (view full) ---

1159#else
1160 v86.ctl = V86_FLAGS;
1161 v86.addr = 0x13;
1162 v86.eax = 0x800;
1163 v86.edx = od->od_unit;
1164 v86int();
1165
1166 if ((v86.efl & 0x1) || /* carry set */
1118 ((v86.edx & 0xff) <= (od->od_unit & 0x7f))) /* unit # bad */
1167 ((v86.edx & 0xff) <= (unsigned)(od->od_unit & 0x7f))) /* unit # bad */
1119 return(1);
1120
1121 /* convert max cyl # -> # of cylinders */
1122 od->od_cyl = ((v86.ecx & 0xc0) << 2) + ((v86.ecx & 0xff00) >> 8) + 1;
1123 /* convert max head # -> # of heads */
1124 od->od_hds = ((v86.edx & 0xff00) >> 8) + 1;
1125 od->od_sec = v86.ecx & 0x3f;
1126#endif

--- 104 unchanged lines hidden (view full) ---

1231 if ((cp != nip) && (*cp == 0))
1232 unitofs = i;
1233 }
1234 } else {
1235 /* assume an IDE disk */
1236 major = WDMAJOR;
1237 }
1238 }
1168 return(1);
1169
1170 /* convert max cyl # -> # of cylinders */
1171 od->od_cyl = ((v86.ecx & 0xc0) << 2) + ((v86.ecx & 0xff00) >> 8) + 1;
1172 /* convert max head # -> # of heads */
1173 od->od_hds = ((v86.edx & 0xff00) >> 8) + 1;
1174 od->od_sec = v86.ecx & 0x3f;
1175#endif

--- 104 unchanged lines hidden (view full) ---

1280 if ((cp != nip) && (*cp == 0))
1281 unitofs = i;
1282 }
1283 } else {
1284 /* assume an IDE disk */
1285 major = WDMAJOR;
1286 }
1287 }
1288 /* default root disk unit number */
1289#ifdef PC98
1290 if ((biosdev & 0xf0) == 0xa0)
1291 unit = bdinfo[dev->d_kind.biosdisk.unit].bd_da_unit;
1292 else
1293 unit = biosdev & 0xf;
1294#else
1295 unit = (biosdev & 0x7f) - unitofs;
1296#endif
1297
1239 /* XXX a better kludge to set the root disk unit number */
1240 if ((nip = getenv("root_disk_unit")) != NULL) {
1241 i = strtol(nip, &cp, 0);
1242 /* check for parse error */
1243 if ((cp != nip) && (*cp == 0))
1244 unit = i;
1298 /* XXX a better kludge to set the root disk unit number */
1299 if ((nip = getenv("root_disk_unit")) != NULL) {
1300 i = strtol(nip, &cp, 0);
1301 /* check for parse error */
1302 if ((cp != nip) && (*cp == 0))
1303 unit = i;
1245 } else {
1246#ifdef PC98
1247 if ((biosdev & 0xf0) == 0xa0)
1248 unit = bdinfo[dev->d_kind.biosdisk.unit].bd_da_unit;
1249 else
1250 unit = biosdev & 0xf;
1251#else
1252 unit = (biosdev & 0x7f) - unitofs; /* allow for #wd compenstation in da case */
1253#endif
1254 }
1255
1256 rootdev = MAKEBOOTDEV(major,
1257 (dev->d_kind.biosdisk.slice + 1) >> 4, /* XXX slices may be wrong here */
1258 (dev->d_kind.biosdisk.slice + 1) & 0xf,
1259 unit,
1260 dev->d_kind.biosdisk.partition);
1261 DEBUG("dev is 0x%x\n", rootdev);
1262 return(rootdev);
1263}
1304 }
1305
1306 rootdev = MAKEBOOTDEV(major,
1307 (dev->d_kind.biosdisk.slice + 1) >> 4, /* XXX slices may be wrong here */
1308 (dev->d_kind.biosdisk.slice + 1) & 0xf,
1309 unit,
1310 dev->d_kind.biosdisk.partition);
1311 DEBUG("dev is 0x%x\n", rootdev);
1312 return(rootdev);
1313}
1264
1265/*
1266 * Fix (dev) so that it refers to the 'real' disk/slice/partition that it implies.
1267 */
1268int
1269bd_fixupdev(struct i386_devdesc *dev)
1270{
1271 struct open_disk *od;
1272
1273 /*
1274 * Open the disk. This will fix up the slice and partition fields.
1275 */
1276 if (bd_opendisk(&od, dev) != 0)
1277 return(ENOENT);
1278
1279 bd_closedisk(od);
1280}