Lines 29-35
__FBSDID("$FreeBSD$");
Link Here
|
29 |
/* |
29 |
/* |
30 |
* BIOS disk device handling. |
30 |
* BIOS disk device handling. |
31 |
* |
31 |
* |
32 |
* Ideas and algorithms from: |
32 |
* Ideas and algorithms from: |
33 |
* |
33 |
* |
34 |
* - NetBSD libi386/biosdisk.c |
34 |
* - NetBSD libi386/biosdisk.c |
Lines 42-47
__FBSDID("$FreeBSD$");
Link Here
|
42 |
#include <sys/disklabel.h> |
42 |
#include <sys/disklabel.h> |
43 |
#include <sys/diskpc98.h> |
43 |
#include <sys/diskpc98.h> |
44 |
#include <machine/bootinfo.h> |
44 |
#include <machine/bootinfo.h> |
|
|
45 |
#include <machine/psl.h> |
45 |
#include <stdarg.h> |
46 |
#include <stdarg.h> |
Lines 122-133
static int bd_close(struct open_file *f);
Link Here
|
122 |
static void bd_print(int verbose); |
123 |
static void bd_print(int verbose); |
123 |
struct devsw biosdisk = { |
124 |
struct devsw biosdisk = { |
124 |
"disk", |
125 |
"disk", |
125 |
DEVT_DISK, |
126 |
DEVT_DISK, |
126 |
bd_init, |
127 |
bd_init, |
127 |
bd_strategy, |
128 |
bd_strategy, |
128 |
bd_open, |
129 |
bd_open, |
129 |
bd_close, |
130 |
bd_close, |
130 |
noioctl, |
131 |
noioctl, |
131 |
bd_print, |
132 |
bd_print, |
132 |
NULL |
133 |
NULL |
Lines 146-152
int
Link Here
|
146 |
bd_bios2unit(int biosdev) |
147 |
bd_bios2unit(int biosdev) |
147 |
{ |
148 |
{ |
148 |
int i; |
149 |
int i; |
149 |
|
150 |
|
150 |
DEBUG("looking for bios device 0x%x", biosdev); |
151 |
DEBUG("looking for bios device 0x%x", biosdev); |
151 |
for (i = 0; i < nbdinfo; i++) { |
152 |
for (i = 0; i < nbdinfo; i++) { |
152 |
DEBUG("bd unit %d is BIOS device 0x%x", i, bdinfo[i].bd_unit); |
153 |
DEBUG("bd unit %d is BIOS device 0x%x", i, bdinfo[i].bd_unit); |
Lines 164-174
bd_unit2bios(int unit)
Link Here
|
164 |
return(-1); |
165 |
return(-1); |
165 |
} |
166 |
} |
166 |
/* |
167 |
/* |
167 |
* Quiz the BIOS for disk devices, save a little info about them. |
168 |
* Quiz the BIOS for disk devices, save a little info about them. |
168 |
*/ |
169 |
*/ |
169 |
static int |
170 |
static int |
170 |
bd_init(void) |
171 |
bd_init(void) |
171 |
{ |
172 |
{ |
172 |
int base, unit; |
173 |
int base, unit; |
173 |
int da_drive=0, n=-0x10; |
174 |
int da_drive=0, n=-0x10; |
Lines 200-206
bd_init(void)
Link Here
|
200 |
bdinfo[nbdinfo].bd_da_unit = da_drive++; |
201 |
bdinfo[nbdinfo].bd_da_unit = da_drive++; |
201 |
} |
202 |
} |
202 |
/* XXX we need "disk aliases" to make this simpler */ |
203 |
/* XXX we need "disk aliases" to make this simpler */ |
203 |
printf("BIOS drive %c: is disk%d\n", |
204 |
printf("BIOS drive %c: is disk%d\n", |
204 |
'A' + nbdinfo, nbdinfo); |
205 |
'A' + nbdinfo, nbdinfo); |
205 |
nbdinfo++; |
206 |
nbdinfo++; |
206 |
} |
207 |
} |
Lines 250-256
bd_print(int verbose)
Link Here
|
250 |
struct i386_devdesc dev; |
251 |
struct i386_devdesc dev; |
251 |
struct open_disk *od; |
252 |
struct open_disk *od; |
252 |
struct pc98_partition *dptr; |
253 |
struct pc98_partition *dptr; |
253 |
|
254 |
|
254 |
for (i = 0; i < nbdinfo; i++) { |
255 |
for (i = 0; i < nbdinfo; i++) { |
255 |
sprintf(line, " disk%d: BIOS drive %c:\n", i, 'A' + i); |
256 |
sprintf(line, " disk%d: BIOS drive %c:\n", i, 'A' + i); |
256 |
pager_output(line); |
257 |
pager_output(line); |
Lines 259-265
bd_print(int verbose)
Link Here
|
259 |
dev.d_unit = i; |
260 |
dev.d_unit = i; |
260 |
dev.d_kind.biosdisk.slice = -1; |
261 |
dev.d_kind.biosdisk.slice = -1; |
261 |
dev.d_kind.biosdisk.partition = -1; |
262 |
dev.d_kind.biosdisk.partition = -1; |
262 |
|
263 |
|
263 |
if (!bd_opendisk(&od, &dev)) { |
264 |
if (!bd_opendisk(&od, &dev)) { |
264 |
/* Do we have a partition table? */ |
265 |
/* Do we have a partition table? */ |
Lines 368-374
bd_printbsdslice(struct open_disk *od, daddr_t offset, char *prefix,
Link Here
|
368 |
pager_output(line); |
369 |
pager_output(line); |
369 |
return; |
370 |
return; |
370 |
} |
371 |
} |
371 |
|
372 |
|
372 |
/* Print partitions */ |
373 |
/* Print partitions */ |
373 |
for (i = 0; i < lp->d_npartitions; i++) { |
374 |
for (i = 0; i < lp->d_npartitions; i++) { |
374 |
/* |
375 |
/* |
Lines 380-392
bd_printbsdslice(struct open_disk *od, daddr_t offset, char *prefix,
Link Here
|
380 |
if ((lp->d_partitions[i].p_fstype == FS_BSDFFS) || |
381 |
if ((lp->d_partitions[i].p_fstype == FS_BSDFFS) || |
381 |
(lp->d_partitions[i].p_fstype == FS_SWAP) || |
382 |
(lp->d_partitions[i].p_fstype == FS_SWAP) || |
382 |
(lp->d_partitions[i].p_fstype == FS_VINUM) || |
383 |
(lp->d_partitions[i].p_fstype == FS_VINUM) || |
383 |
((lp->d_partitions[i].p_fstype == FS_UNUSED) && |
384 |
((lp->d_partitions[i].p_fstype == FS_UNUSED) && |
384 |
(od->od_flags & BD_FLOPPY) && (i == 0))) { |
385 |
(od->od_flags & BD_FLOPPY) && (i == 0))) { |
385 |
/* Only print out statistics in verbose mode */ |
386 |
/* Only print out statistics in verbose mode */ |
386 |
if (verbose) |
387 |
if (verbose) |
387 |
sprintf(line, " %s%c: %s %s (%d - %d)\n", prefix, 'a' + i, |
388 |
sprintf(line, " %s%c: %s %s (%d - %d)\n", prefix, 'a' + i, |
388 |
(lp->d_partitions[i].p_fstype == FS_SWAP) ? "swap " : |
389 |
(lp->d_partitions[i].p_fstype == FS_SWAP) ? "swap " : |
389 |
(lp->d_partitions[i].p_fstype == FS_VINUM) ? "vinum" : |
390 |
(lp->d_partitions[i].p_fstype == FS_VINUM) ? "vinum" : |
390 |
"FFS ", |
391 |
"FFS ", |
391 |
display_size(lp->d_partitions[i].p_size), |
392 |
display_size(lp->d_partitions[i].p_size), |
Lines 394-400
bd_printbsdslice(struct open_disk *od, daddr_t offset, char *prefix,
Link Here
|
394 |
lp->d_partitions[i].p_offset + lp->d_partitions[i].p_size); |
395 |
lp->d_partitions[i].p_offset + lp->d_partitions[i].p_size); |
395 |
else |
396 |
else |
396 |
sprintf(line, " %s%c: %s\n", prefix, 'a' + i, |
397 |
sprintf(line, " %s%c: %s\n", prefix, 'a' + i, |
397 |
(lp->d_partitions[i].p_fstype == FS_SWAP) ? "swap" : |
398 |
(lp->d_partitions[i].p_fstype == FS_SWAP) ? "swap" : |
398 |
(lp->d_partitions[i].p_fstype == FS_VINUM) ? "vinum" : |
399 |
(lp->d_partitions[i].p_fstype == FS_VINUM) ? "vinum" : |
399 |
"FFS"); |
400 |
"FFS"); |
400 |
pager_output(line); |
401 |
pager_output(line); |
Lines 413-419
bd_printbsdslice(struct open_disk *od, daddr_t offset, char *prefix,
Link Here
|
413 |
* sliced - are they after the first BSD slice, or the DOS |
414 |
* sliced - are they after the first BSD slice, or the DOS |
414 |
* slice before it?) |
415 |
* slice before it?) |
415 |
*/ |
416 |
*/ |
416 |
static int |
417 |
static int |
417 |
bd_open(struct open_file *f, ...) |
418 |
bd_open(struct open_file *f, ...) |
418 |
{ |
419 |
{ |
419 |
va_list ap; |
420 |
va_list ap; |
Lines 426-432
bd_open(struct open_file *f, ...)
Link Here
|
426 |
va_end(ap); |
427 |
va_end(ap); |
427 |
if ((error = bd_opendisk(&od, dev))) |
428 |
if ((error = bd_opendisk(&od, dev))) |
428 |
return(error); |
429 |
return(error); |
429 |
|
430 |
|
430 |
/* |
431 |
/* |
431 |
* Save our context |
432 |
* Save our context |
432 |
*/ |
433 |
*/ |
Lines 445-451
bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev)
Link Here
|
445 |
DEBUG("attempt to open nonexistent disk"); |
446 |
DEBUG("attempt to open nonexistent disk"); |
446 |
return(ENXIO); |
447 |
return(ENXIO); |
447 |
} |
448 |
} |
448 |
|
449 |
|
449 |
od = (struct open_disk *)malloc(sizeof(struct open_disk)); |
450 |
od = (struct open_disk *)malloc(sizeof(struct open_disk)); |
450 |
if (!od) { |
451 |
if (!od) { |
451 |
DEBUG("no memory"); |
452 |
DEBUG("no memory"); |
Lines 459-465
bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev)
Link Here
|
459 |
od->od_boff = 0; |
460 |
od->od_boff = 0; |
460 |
error = 0; |
461 |
error = 0; |
461 |
DEBUG("open '%s', unit 0x%x slice %d partition %d", |
462 |
DEBUG("open '%s', unit 0x%x slice %d partition %d", |
462 |
i386_fmtdev(dev), dev->d_unit, |
463 |
i386_fmtdev(dev), dev->d_unit, |
463 |
dev->d_kind.biosdisk.slice, dev->d_kind.biosdisk.partition); |
464 |
dev->d_kind.biosdisk.slice, dev->d_kind.biosdisk.partition); |
464 |
/* Get geometry for this open (removable device may have changed) */ |
465 |
/* Get geometry for this open (removable device may have changed) */ |
Lines 471-477
bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev)
Link Here
|
471 |
/* Determine disk layout. */ |
472 |
/* Determine disk layout. */ |
472 |
error = bd_open_pc98(od, dev); |
473 |
error = bd_open_pc98(od, dev); |
473 |
|
474 |
|
474 |
out: |
475 |
out: |
475 |
if (error) { |
476 |
if (error) { |
476 |
free(od); |
477 |
free(od); |
Lines 508-514
bd_open_pc98(struct open_disk *od, struct i386_devdesc *dev)
Link Here
|
508 |
return (EIO); |
509 |
return (EIO); |
509 |
} |
510 |
} |
510 |
/* |
511 |
/* |
511 |
* Check the slice table magic. |
512 |
* Check the slice table magic. |
512 |
*/ |
513 |
*/ |
513 |
if (((u_char)buf[0x1fe] != 0x55) || ((u_char)buf[0x1ff] != 0xaa)) { |
514 |
if (((u_char)buf[0x1fe] != 0x55) || ((u_char)buf[0x1ff] != 0xaa)) { |
Lines 582-588
bd_open_pc98(struct open_disk *od, struct i386_devdesc *dev)
Link Here
|
582 |
dev->d_kind.biosdisk.partition = 0; |
583 |
dev->d_kind.biosdisk.partition = 0; |
583 |
unsliced: |
584 |
unsliced: |
584 |
/* |
585 |
/* |
585 |
* Now we have the slice offset, look for the partition in the disklabel if we have |
586 |
* Now we have the slice offset, look for the partition in the disklabel if we have |
586 |
* a partition to start with. |
587 |
* a partition to start with. |
587 |
* |
588 |
* |
Lines 592-598
bd_open_pc98(struct open_disk *od, struct i386_devdesc *dev)
Link Here
|
592 |
od->od_boff = sector; /* no partition, must be after the slice */ |
593 |
od->od_boff = sector; /* no partition, must be after the slice */ |
593 |
DEBUG("opening raw slice"); |
594 |
DEBUG("opening raw slice"); |
594 |
} else { |
595 |
} else { |
595 |
|
596 |
|
596 |
if (bd_read(od, sector + LABELSECTOR, 1, buf)) { |
597 |
if (bd_read(od, sector + LABELSECTOR, 1, buf)) { |
597 |
DEBUG("error reading disklabel"); |
598 |
DEBUG("error reading disklabel"); |
598 |
return (EIO); |
599 |
return (EIO); |
Lines 618-625
bd_open_pc98(struct open_disk *od, struct i386_devdesc *dev)
Link Here
|
618 |
!(od->od_flags & BD_FLOPPY)) |
619 |
!(od->od_flags & BD_FLOPPY)) |
619 |
DEBUG("warning, partition marked as unused"); |
620 |
DEBUG("warning, partition marked as unused"); |
620 |
#endif |
621 |
#endif |
621 |
|
622 |
|
622 |
od->od_boff = |
623 |
od->od_boff = |
623 |
lp->d_partitions[dev->d_kind.biosdisk.partition].p_offset - |
624 |
lp->d_partitions[dev->d_kind.biosdisk.partition].p_offset - |
624 |
lp->d_partitions[RAW_PART].p_offset + |
625 |
lp->d_partitions[RAW_PART].p_offset + |
625 |
sector; |
626 |
sector; |
Lines 655-661
bd_bestslice(struct open_disk *od)
Link Here
|
655 |
struct pc98_partition *dp; |
656 |
struct pc98_partition *dp; |
656 |
int pref, preflevel; |
657 |
int pref, preflevel; |
657 |
int i, prefslice; |
658 |
int i, prefslice; |
658 |
|
659 |
|
659 |
prefslice = 0; |
660 |
prefslice = 0; |
660 |
preflevel = PREF_NONE; |
661 |
preflevel = PREF_NONE; |
Lines 692-699
bd_bestslice(struct open_disk *od)
Link Here
|
692 |
} |
693 |
} |
693 |
return (prefslice); |
694 |
return (prefslice); |
694 |
} |
695 |
} |
695 |
|
696 |
|
696 |
static int |
697 |
static int |
697 |
bd_close(struct open_file *f) |
698 |
bd_close(struct open_file *f) |
698 |
{ |
699 |
{ |
699 |
struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)(f->f_devdata))->d_kind.biosdisk.data); |
700 |
struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)(f->f_devdata))->d_kind.biosdisk.data); |
Lines 714-720
bd_closedisk(struct open_disk *od)
Link Here
|
714 |
free(od); |
715 |
free(od); |
715 |
} |
716 |
} |
716 |
static int |
717 |
static int |
717 |
bd_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize) |
718 |
bd_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize) |
718 |
{ |
719 |
{ |
719 |
struct bcache_devdata bcd; |
720 |
struct bcache_devdata bcd; |
Lines 725-731
bd_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t
Link Here
|
725 |
return(bcache_strategy(&bcd, od->od_unit, rw, dblk+od->od_boff, size, buf, rsize)); |
726 |
return(bcache_strategy(&bcd, od->od_unit, rw, dblk+od->od_boff, size, buf, rsize)); |
726 |
} |
727 |
} |
727 |
static int |
728 |
static int |
728 |
bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize) |
729 |
bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize) |
729 |
{ |
730 |
{ |
730 |
struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)devdata)->d_kind.biosdisk.data); |
731 |
struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)devdata)->d_kind.biosdisk.data); |
Lines 824-830
bd_chs_io(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest, int write)
Link Here
|
824 |
v86.es = VTOPSEG(dest); |
825 |
v86.es = VTOPSEG(dest); |
825 |
v86.ebp = VTOPOFF(dest); |
826 |
v86.ebp = VTOPOFF(dest); |
826 |
v86int(); |
827 |
v86int(); |
827 |
return (v86.efl & 0x1); |
828 |
return (v86.efl & PSL_C); |
828 |
} |
829 |
} |
829 |
static int |
830 |
static int |
Lines 832-838
bd_io(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest, int write)
Link Here
|
832 |
{ |
833 |
{ |
833 |
u_int x, sec, result, resid, retry, maxfer; |
834 |
u_int x, sec, result, resid, retry, maxfer; |
834 |
caddr_t p, xp, bbuf, breg; |
835 |
caddr_t p, xp, bbuf, breg; |
835 |
|
836 |
|
836 |
/* Just in case some idiot actually tries to read/write -1 blocks... */ |
837 |
/* Just in case some idiot actually tries to read/write -1 blocks... */ |
837 |
if (blks < 0) |
838 |
if (blks < 0) |
838 |
return (-1); |
839 |
return (-1); |
Lines 844-850
bd_io(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest, int write)
Link Here
|
844 |
if (VTOP(dest) >> 20 != 0 || |
845 |
if (VTOP(dest) >> 20 != 0 || |
845 |
((VTOP(dest) >> 16) != (VTOP(dest + blks * BIOSDISK_SECSIZE) >> 16))) { |
846 |
((VTOP(dest) >> 16) != (VTOP(dest + blks * BIOSDISK_SECSIZE) >> 16))) { |
846 |
/* |
847 |
/* |
847 |
* There is a 64k physical boundary somewhere in the |
848 |
* There is a 64k physical boundary somewhere in the |
848 |
* destination buffer, or the destination buffer is above |
849 |
* destination buffer, or the destination buffer is above |
849 |
* first 1MB of physical memory so we have to arrange a |
850 |
* first 1MB of physical memory so we have to arrange a |
Lines 865-871
bd_io(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest, int write)
Link Here
|
865 |
breg = bbuf = NULL; |
866 |
breg = bbuf = NULL; |
866 |
maxfer = 0; |
867 |
maxfer = 0; |
867 |
} |
868 |
} |
868 |
|
869 |
|
869 |
while (resid > 0) { |
870 |
while (resid > 0) { |
870 |
/* |
871 |
/* |
871 |
* Play it safe and don't cross track boundaries. |
872 |
* Play it safe and don't cross track boundaries. |
Lines 881-887
bd_io(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest, int write)
Link Here
|
881 |
/* |
882 |
/* |
882 |
* Put your Data In, Put your Data out, |
883 |
* Put your Data In, Put your Data out, |
883 |
* Put your Data In, and shake it all about |
884 |
* Put your Data In, and shake it all about |
884 |
*/ |
885 |
*/ |
885 |
if (write && bbuf != NULL) |
886 |
if (write && bbuf != NULL) |
886 |
bcopy(p, breg, x * BIOSDISK_SECSIZE); |
887 |
bcopy(p, breg, x * BIOSDISK_SECSIZE); |
Lines 955-965
bd_getgeom(struct open_disk *od)
Link Here
|
955 |
v86.addr = 0x1b; |
956 |
v86.addr = 0x1b; |
956 |
v86.eax = 0x8400 | od->od_unit; |
957 |
v86.eax = 0x8400 | od->od_unit; |
957 |
v86int(); |
958 |
v86int(); |
958 |
|
959 |
|
959 |
od->od_cyl = v86.ecx; |
960 |
od->od_cyl = v86.ecx; |
960 |
od->od_hds = (v86.edx >> 8) & 0xff; |
961 |
od->od_hds = (v86.edx >> 8) & 0xff; |
961 |
od->od_sec = v86.edx & 0xff; |
962 |
od->od_sec = v86.edx & 0xff; |
962 |
if (v86.efl & 0x1) |
963 |
if (v86.efl & PSL_C) |
963 |
return(1); |
964 |
return(1); |
964 |
} |
965 |
} |
Lines 1010-1016
bd_getbigeom(int bunit)
Link Here
|
1010 |
v86.addr = 0x1b; |
1011 |
v86.addr = 0x1b; |
1011 |
v86.eax = 0x8400 | unit; |
1012 |
v86.eax = 0x8400 | unit; |
1012 |
v86int(); |
1013 |
v86int(); |
1013 |
if (v86.efl & 0x1) |
1014 |
if (v86.efl & PSL_C) |
1014 |
return 0x4F020F; /* 1200KB FD C:80 H:2 S:15 */ |
1015 |
return 0x4F020F; /* 1200KB FD C:80 H:2 S:15 */ |
1015 |
return ((v86.ecx & 0xffff) << 16) | (v86.edx & 0xffff); |
1016 |
return ((v86.ecx & 0xffff) << 16) | (v86.edx & 0xffff); |
1016 |
} |
1017 |
} |
1017 |
- |
|
|