biosdisk.c (146010) | biosdisk.c (146011) |
---|---|
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 --- 11 unchanged lines hidden (view full) --- 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 27#include <sys/cdefs.h> | 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 --- 11 unchanged lines hidden (view full) --- 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 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/boot/pc98/libpc98/biosdisk.c 146010 2005-05-08 13:30:14Z nyan $"); | 28__FBSDID("$FreeBSD: head/sys/boot/pc98/libpc98/biosdisk.c 146011 2005-05-08 14:17:28Z nyan $"); |
29 30/* 31 * BIOS disk device handling. 32 * 33 * Ideas and algorithms from: 34 * 35 * - NetBSD libi386/biosdisk.c 36 * - FreeBSD biosboot/disk.c --- 39 unchanged lines hidden (view full) --- 76 int od_flags; 77#define BD_MODEINT13 0x0000 78#define BD_MODEEDD1 0x0001 79#define BD_MODEEDD3 0x0002 80#define BD_MODEMASK 0x0003 81#define BD_FLOPPY 0x0004 82#define BD_LABELOK 0x0008 83#define BD_PARTTABOK 0x0010 | 29 30/* 31 * BIOS disk device handling. 32 * 33 * Ideas and algorithms from: 34 * 35 * - NetBSD libi386/biosdisk.c 36 * - FreeBSD biosboot/disk.c --- 39 unchanged lines hidden (view full) --- 76 int od_flags; 77#define BD_MODEINT13 0x0000 78#define BD_MODEEDD1 0x0001 79#define BD_MODEEDD3 0x0002 80#define BD_MODEMASK 0x0003 81#define BD_FLOPPY 0x0004 82#define BD_LABELOK 0x0008 83#define BD_PARTTABOK 0x0010 |
84#ifdef PC98 | |
85#define BD_OPTICAL 0x0020 | 84#define BD_OPTICAL 0x0020 |
86#endif | |
87 struct disklabel od_disklabel; 88 int od_nslices; /* slice count */ 89 struct pc98_partition od_slicetab[NDOSPART]; 90}; 91 92/* 93 * List of BIOS devices, translation from disk unit number to 94 * BIOS unit number. 95 */ 96static struct bdinfo 97{ 98 int bd_unit; /* BIOS unit number */ 99 int bd_flags; 100 int bd_type; /* BIOS 'drive type' (floppy only) */ | 85 struct disklabel od_disklabel; 86 int od_nslices; /* slice count */ 87 struct pc98_partition od_slicetab[NDOSPART]; 88}; 89 90/* 91 * List of BIOS devices, translation from disk unit number to 92 * BIOS unit number. 93 */ 94static struct bdinfo 95{ 96 int bd_unit; /* BIOS unit number */ 97 int bd_flags; 98 int bd_type; /* BIOS 'drive type' (floppy only) */ |
101#ifdef PC98 | |
102 int bd_da_unit; /* kernel unit number for da */ | 99 int bd_da_unit; /* kernel unit number for da */ |
103#endif | |
104} bdinfo [MAXBDDEV]; 105static int nbdinfo = 0; 106 107static int bd_getgeom(struct open_disk *od); 108static int bd_read(struct open_disk *od, daddr_t dblk, int blks, 109 caddr_t dest); 110static int bd_write(struct open_disk *od, daddr_t dblk, int blks, 111 caddr_t dest); --- 57 unchanged lines hidden (view full) --- 169} 170 171/* 172 * Quiz the BIOS for disk devices, save a little info about them. 173 */ 174static int 175bd_init(void) 176{ | 100} bdinfo [MAXBDDEV]; 101static int nbdinfo = 0; 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); 106static int bd_write(struct open_disk *od, daddr_t dblk, int blks, 107 caddr_t dest); --- 57 unchanged lines hidden (view full) --- 165} 166 167/* 168 * Quiz the BIOS for disk devices, save a little info about them. 169 */ 170static int 171bd_init(void) 172{ |
177#ifdef PC98 | |
178 int base, unit; 179 int da_drive=0, n=-0x10; 180 181 /* sequence 0x90, 0x80, 0xa0 */ 182 for (base = 0x90; base <= 0xa0; base += n, n += 0x30) { 183 for (unit = base; (nbdinfo < MAXBDDEV) || ((unit & 0x0f) < 4); unit++) { 184 bdinfo[nbdinfo].bd_unit = unit; 185 bdinfo[nbdinfo].bd_flags = (unit & 0xf0) == 0x90 ? BD_FLOPPY : 0; --- 19 unchanged lines hidden (view full) --- 205 bdinfo[nbdinfo].bd_da_unit = da_drive++; 206 } 207 /* XXX we need "disk aliases" to make this simpler */ 208 printf("BIOS drive %c: is disk%d\n", 209 'A' + nbdinfo, nbdinfo); 210 nbdinfo++; 211 } 212 } | 173 int base, unit; 174 int da_drive=0, n=-0x10; 175 176 /* sequence 0x90, 0x80, 0xa0 */ 177 for (base = 0x90; base <= 0xa0; base += n, n += 0x30) { 178 for (unit = base; (nbdinfo < MAXBDDEV) || ((unit & 0x0f) < 4); unit++) { 179 bdinfo[nbdinfo].bd_unit = unit; 180 bdinfo[nbdinfo].bd_flags = (unit & 0xf0) == 0x90 ? BD_FLOPPY : 0; --- 19 unchanged lines hidden (view full) --- 200 bdinfo[nbdinfo].bd_da_unit = da_drive++; 201 } 202 /* XXX we need "disk aliases" to make this simpler */ 203 printf("BIOS drive %c: is disk%d\n", 204 'A' + nbdinfo, nbdinfo); 205 nbdinfo++; 206 } 207 } |
213#else 214 int base, unit, nfd = 0; 215 216 /* sequence 0, 0x80 */ 217 for (base = 0; base <= 0x80; base += 0x80) { 218 for (unit = base; (nbdinfo < MAXBDDEV); unit++) { 219 /* check the BIOS equipment list for number of fixed disks */ 220 if((base == 0x80) && 221 (nfd >= *(unsigned char *)PTOV(BIOS_NUMDRIVES))) 222 break; 223 224 bdinfo[nbdinfo].bd_unit = unit; 225 bdinfo[nbdinfo].bd_flags = (unit < 0x80) ? BD_FLOPPY : 0; 226 227 if (!bd_int13probe(&bdinfo[nbdinfo])) 228 break; 229 230 /* XXX we need "disk aliases" to make this simpler */ 231 printf("BIOS drive %c: is disk%d\n", 232 (unit < 0x80) ? ('A' + unit) : ('C' + unit - 0x80), nbdinfo); 233 nbdinfo++; 234 if (base == 0x80) 235 nfd++; 236 } 237 } 238#endif | |
239 return(0); 240} 241 242/* 243 * Try to detect a device supported by the legacy int13 BIOS 244 */ 245static int 246bd_int13probe(struct bdinfo *bd) 247{ | 208 return(0); 209} 210 211/* 212 * Try to detect a device supported by the legacy int13 BIOS 213 */ 214static int 215bd_int13probe(struct bdinfo *bd) 216{ |
248#ifdef PC98 | |
249 int addr; 250 251 if (bd->bd_flags & BD_FLOPPY) { 252 addr = 0xa155c; 253 } else { 254 if ((bd->bd_unit & 0xf0) == 0x80) 255 addr = 0xa155d; 256 else --- 7 unchanged lines hidden (view full) --- 264 int media = ((unsigned *)PTOV(0xA1460))[bd->bd_unit & 0x0F] & 0x1F; 265 266 if (media == 7) { /* MO */ 267 bd->bd_flags |= BD_MODEINT13 | BD_OPTICAL; 268 return(1); 269 } 270 } 271 return(0); | 217 int addr; 218 219 if (bd->bd_flags & BD_FLOPPY) { 220 addr = 0xa155c; 221 } else { 222 if ((bd->bd_unit & 0xf0) == 0x80) 223 addr = 0xa155d; 224 else --- 7 unchanged lines hidden (view full) --- 232 int media = ((unsigned *)PTOV(0xA1460))[bd->bd_unit & 0x0F] & 0x1F; 233 234 if (media == 7) { /* MO */ 235 bd->bd_flags |= BD_MODEINT13 | BD_OPTICAL; 236 return(1); 237 } 238 } 239 return(0); |
272#else 273 v86.ctl = V86_FLAGS; 274 v86.addr = 0x13; 275 v86.eax = 0x800; 276 v86.edx = bd->bd_unit; 277 v86int(); 278 279 if (!(v86.efl & 0x1) && /* carry clear */ 280 ((v86.edx & 0xff) > ((unsigned)bd->bd_unit & 0x7f))) { /* unit # OK */ 281 bd->bd_flags |= BD_MODEINT13; 282 bd->bd_type = v86.ebx & 0xff; 283 284 /* Determine if we can use EDD with this device. */ 285 v86.eax = 0x4100; 286 v86.edx = bd->bd_unit; 287 v86.ebx = 0x55aa; 288 v86int(); 289 if (!(v86.efl & 0x1) && /* carry clear */ 290 ((v86.ebx & 0xffff) == 0xaa55) && /* signature */ 291 (v86.ecx & 0x1)) { /* packets mode ok */ 292 bd->bd_flags |= BD_MODEEDD1; 293 if((v86.eax & 0xff00) > 0x300) 294 bd->bd_flags |= BD_MODEEDD3; 295 } 296 return(1); 297 } 298 return(0); 299#endif | |
300} 301 302/* 303 * Print information about disks 304 */ 305static void 306bd_print(int verbose) 307{ 308 int i, j; 309 char line[80]; 310 struct i386_devdesc dev; 311 struct open_disk *od; 312 struct pc98_partition *dptr; 313 314 for (i = 0; i < nbdinfo; i++) { | 240} 241 242/* 243 * Print information about disks 244 */ 245static void 246bd_print(int verbose) 247{ 248 int i, j; 249 char line[80]; 250 struct i386_devdesc dev; 251 struct open_disk *od; 252 struct pc98_partition *dptr; 253 254 for (i = 0; i < nbdinfo; i++) { |
315#ifdef PC98 | |
316 sprintf(line, " disk%d: BIOS drive %c:\n", i, 'A' + i); | 255 sprintf(line, " disk%d: BIOS drive %c:\n", i, 'A' + i); |
317#else 318 sprintf(line, " disk%d: BIOS drive %c:\n", i, 319 (bdinfo[i].bd_unit < 0x80) ? ('A' + bdinfo[i].bd_unit) : ('C' + bdinfo[i].bd_unit - 0x80)); 320#endif | |
321 pager_output(line); 322 323 /* try to open the whole disk */ 324 dev.d_kind.biosdisk.unit = i; 325 dev.d_kind.biosdisk.slice = -1; 326 dev.d_kind.biosdisk.partition = -1; 327 328 if (!bd_opendisk(&od, &dev)) { 329 330 /* Do we have a partition table? */ 331 if (od->od_flags & BD_PARTTABOK) { 332 dptr = &od->od_slicetab[0]; 333 334 /* Check for a "dedicated" disk */ | 256 pager_output(line); 257 258 /* try to open the whole disk */ 259 dev.d_kind.biosdisk.unit = i; 260 dev.d_kind.biosdisk.slice = -1; 261 dev.d_kind.biosdisk.partition = -1; 262 263 if (!bd_opendisk(&od, &dev)) { 264 265 /* Do we have a partition table? */ 266 if (od->od_flags & BD_PARTTABOK) { 267 dptr = &od->od_slicetab[0]; 268 269 /* Check for a "dedicated" disk */ |
335#ifdef PC98 | |
336 for (j = 0; j < od->od_nslices; j++) { 337 switch(dptr[j].dp_mid) { 338 case DOSMID_386BSD: 339 sprintf(line, " disk%ds%d", i, j + 1); 340 bd_printbsdslice(od, 341 dptr[j].dp_scyl * od->od_hds * od->od_sec + 342 dptr[j].dp_shd * od->od_sec + dptr[j].dp_ssect, 343 line, verbose); 344 break; 345 default: 346 break; 347 } 348 } | 270 for (j = 0; j < od->od_nslices; j++) { 271 switch(dptr[j].dp_mid) { 272 case DOSMID_386BSD: 273 sprintf(line, " disk%ds%d", i, j + 1); 274 bd_printbsdslice(od, 275 dptr[j].dp_scyl * od->od_hds * od->od_sec + 276 dptr[j].dp_shd * od->od_sec + dptr[j].dp_ssect, 277 line, verbose); 278 break; 279 default: 280 break; 281 } 282 } |
349#else 350 if ((dptr[3].dp_typ == DOSPTYP_386BSD) && 351 (dptr[3].dp_start == 0) && 352 (dptr[3].dp_size == 50000)) { 353 sprintf(line, " disk%d", i); 354 bd_printbsdslice(od, 0, line, verbose); 355 } else { 356 for (j = 0; j < od->od_nslices; j++) { 357 sprintf(line, " disk%ds%d", i, j + 1); 358 bd_printslice(od, &dptr[j], line, verbose); 359 } 360 } 361#endif | |
362 } 363 bd_closedisk(od); 364 } 365 } 366} 367 | 283 } 284 bd_closedisk(od); 285 } 286 } 287} 288 |
368#ifndef PC98 | |
369/* | 289/* |
370 * Print information about slices on a disk. For the size calculations we 371 * assume a 512 byte sector. 372 */ 373static void 374bd_printslice(struct open_disk *od, struct dos_partition *dp, char *prefix, 375 int verbose) 376{ 377 char line[80]; 378 379 switch (dp->dp_typ) { 380 case DOSPTYP_386BSD: 381 bd_printbsdslice(od, (daddr_t)dp->dp_start, prefix, verbose); 382 return; 383 case DOSPTYP_LINSWP: 384 if (verbose) 385 sprintf(line, "%s: Linux swap %.6dMB (%d - %d)\n", 386 prefix, dp->dp_size / 2048, 387 dp->dp_start, dp->dp_start + dp->dp_size); 388 else 389 sprintf(line, "%s: Linux swap\n", prefix); 390 break; 391 case DOSPTYP_LINUX: 392 /* 393 * XXX 394 * read the superblock to confirm this is an ext2fs partition? 395 */ 396 if (verbose) 397 sprintf(line, "%s: ext2fs %.6dMB (%d - %d)\n", prefix, 398 dp->dp_size / 2048, dp->dp_start, 399 dp->dp_start + dp->dp_size); 400 else 401 sprintf(line, "%s: ext2fs\n", prefix); 402 break; 403 case 0x00: /* unused partition */ 404 case DOSPTYP_EXT: 405 return; 406 case 0x01: 407 if (verbose) 408 sprintf(line, "%s: FAT-12 %.6dMB (%d - %d)\n", prefix, 409 dp->dp_size / 2048, dp->dp_start, 410 dp->dp_start + dp->dp_size); 411 else 412 sprintf(line, "%s: FAT-12\n", prefix); 413 break; 414 case 0x04: 415 case 0x06: 416 case 0x0e: 417 if (verbose) 418 sprintf(line, "%s: FAT-16 %.6dMB (%d - %d)\n", prefix, 419 dp->dp_size / 2048, dp->dp_start, 420 dp->dp_start + dp->dp_size); 421 else 422 sprintf(line, "%s: FAT-16\n", prefix); 423 break; 424 case 0x0b: 425 case 0x0c: 426 if (verbose) 427 sprintf(line, "%s: FAT-32 %.6dMB (%d - %d)\n", prefix, 428 dp->dp_size / 2048, dp->dp_start, 429 dp->dp_start + dp->dp_size); 430 else 431 sprintf(line, "%s: FAT-32\n", prefix); 432 break; 433 default: 434 if (verbose) 435 sprintf(line, "%s: Unknown fs: 0x%x %.6dMB (%d - %d)\n", 436 prefix, dp->dp_typ, dp->dp_size / 2048, 437 dp->dp_start, dp->dp_start + dp->dp_size); 438 else 439 sprintf(line, "%s: Unknown fs: 0x%x\n", prefix, 440 dp->dp_typ); 441 } 442 pager_output(line); 443} 444#endif 445 446/* | |
447 * Print out each valid partition in the disklabel of a FreeBSD slice. 448 * For size calculations, we assume a 512 byte sector size. 449 */ 450static void 451bd_printbsdslice(struct open_disk *od, daddr_t offset, char *prefix, 452 int verbose) 453{ 454 char line[80]; --- 120 unchanged lines hidden (view full) --- 575 * Following calculations attempt to determine the correct value 576 * for d->od_boff by looking for the slice and partition specified, 577 * or searching for reasonable defaults. 578 */ 579 580 /* 581 * Find the slice in the DOS slice table. 582 */ | 290 * Print out each valid partition in the disklabel of a FreeBSD slice. 291 * For size calculations, we assume a 512 byte sector size. 292 */ 293static void 294bd_printbsdslice(struct open_disk *od, daddr_t offset, char *prefix, 295 int verbose) 296{ 297 char line[80]; --- 120 unchanged lines hidden (view full) --- 418 * Following calculations attempt to determine the correct value 419 * for d->od_boff by looking for the slice and partition specified, 420 * or searching for reasonable defaults. 421 */ 422 423 /* 424 * Find the slice in the DOS slice table. 425 */ |
583#ifdef PC98 | |
584 if (od->od_flags & BD_FLOPPY) { 585 sector = 0; 586 goto unsliced; 587 } | 426 if (od->od_flags & BD_FLOPPY) { 427 sector = 0; 428 goto unsliced; 429 } |
588#endif | |
589 if (bd_read(od, 0, 1, buf)) { 590 DEBUG("error reading MBR"); 591 error = EIO; 592 goto out; 593 } 594 595 /* 596 * Check the slice table magic. 597 */ 598 if (((u_char)buf[0x1fe] != 0x55) || ((u_char)buf[0x1ff] != 0xaa)) { 599 /* If a slice number was explicitly supplied, this is an error */ 600 if (dev->d_kind.biosdisk.slice > 0) { 601 DEBUG("no slice table/MBR (no magic)"); 602 error = ENOENT; 603 goto out; 604 } 605 sector = 0; 606 goto unsliced; /* may be a floppy */ 607 } | 430 if (bd_read(od, 0, 1, buf)) { 431 DEBUG("error reading MBR"); 432 error = EIO; 433 goto out; 434 } 435 436 /* 437 * Check the slice table magic. 438 */ 439 if (((u_char)buf[0x1fe] != 0x55) || ((u_char)buf[0x1ff] != 0xaa)) { 440 /* If a slice number was explicitly supplied, this is an error */ 441 if (dev->d_kind.biosdisk.slice > 0) { 442 DEBUG("no slice table/MBR (no magic)"); 443 error = ENOENT; 444 goto out; 445 } 446 sector = 0; 447 goto unsliced; /* may be a floppy */ 448 } |
608#ifdef PC98 | |
609 if (bd_read(od, 1, 1, buf)) { 610 DEBUG("error reading MBR"); 611 error = EIO; 612 goto out; 613 } | 449 if (bd_read(od, 1, 1, buf)) { 450 DEBUG("error reading MBR"); 451 error = EIO; 452 goto out; 453 } |
614#endif | |
615 616 /* 617 * copy the partition table, then pick up any extended partitions. 618 */ 619 bcopy(buf + DOSPARTOFF, &od->od_slicetab, 620 sizeof(struct pc98_partition) * NDOSPART); | 454 455 /* 456 * copy the partition table, then pick up any extended partitions. 457 */ 458 bcopy(buf + DOSPARTOFF, &od->od_slicetab, 459 sizeof(struct pc98_partition) * NDOSPART); |
621#ifdef PC98 | |
622 od->od_nslices = NDOSPART; /* extended slices start here */ | 460 od->od_nslices = NDOSPART; /* extended slices start here */ |
623#else 624 od->od_nslices = 4; /* extended slices start here */ 625 for (i = 0; i < NDOSPART; i++) 626 bd_checkextended(od, i); 627#endif | |
628 od->od_flags |= BD_PARTTABOK; 629 dptr = &od->od_slicetab[0]; 630 631 /* Is this a request for the whole disk? */ 632 if (dev->d_kind.biosdisk.slice == -1) { 633 sector = 0; 634 goto unsliced; 635 } --- 5 unchanged lines hidden (view full) --- 641 slice = dev->d_kind.biosdisk.slice - 1; 642 if (slice >= od->od_nslices) { 643 DEBUG("slice %d not found", slice); 644 error = ENOENT; 645 goto out; 646 } 647 } 648 | 461 od->od_flags |= BD_PARTTABOK; 462 dptr = &od->od_slicetab[0]; 463 464 /* Is this a request for the whole disk? */ 465 if (dev->d_kind.biosdisk.slice == -1) { 466 sector = 0; 467 goto unsliced; 468 } --- 5 unchanged lines hidden (view full) --- 474 slice = dev->d_kind.biosdisk.slice - 1; 475 if (slice >= od->od_nslices) { 476 DEBUG("slice %d not found", slice); 477 error = ENOENT; 478 goto out; 479 } 480 } 481 |
649#ifndef PC98 650 /* 651 * Check for the historically bogus MBR found on true dedicated disks 652 */ 653 if ((dptr[3].dp_typ == DOSPTYP_386BSD) && 654 (dptr[3].dp_start == 0) && 655 (dptr[3].dp_size == 50000)) { 656 sector = 0; 657 goto unsliced; 658 } 659#endif 660 | |
661 /* Try to auto-detect the best slice; this should always give a slice number */ 662 if (dev->d_kind.biosdisk.slice == 0) { 663 slice = bd_bestslice(od); 664 if (slice == -1) { 665 error = ENOENT; 666 goto out; 667 } 668 dev->d_kind.biosdisk.slice = slice; 669 } 670 671 dptr = &od->od_slicetab[0]; 672 /* 673 * Accept the supplied slice number unequivocally (we may be looking 674 * at a DOS partition). 675 */ 676 dptr += (dev->d_kind.biosdisk.slice - 1); /* we number 1-4, offsets are 0-3 */ | 482 /* Try to auto-detect the best slice; this should always give a slice number */ 483 if (dev->d_kind.biosdisk.slice == 0) { 484 slice = bd_bestslice(od); 485 if (slice == -1) { 486 error = ENOENT; 487 goto out; 488 } 489 dev->d_kind.biosdisk.slice = slice; 490 } 491 492 dptr = &od->od_slicetab[0]; 493 /* 494 * Accept the supplied slice number unequivocally (we may be looking 495 * at a DOS partition). 496 */ 497 dptr += (dev->d_kind.biosdisk.slice - 1); /* we number 1-4, offsets are 0-3 */ |
677#ifdef PC98 | |
678 sector = dptr->dp_scyl * od->od_hds * od->od_sec + 679 dptr->dp_shd * od->od_sec + dptr->dp_ssect; 680 { 681 int end = dptr->dp_ecyl * od->od_hds * od->od_sec + 682 dptr->dp_ehd * od->od_sec + dptr->dp_esect; 683 DEBUG("slice entry %d at %d, %d sectors", 684 dev->d_kind.biosdisk.slice - 1, sector, end-sector); 685 } | 498 sector = dptr->dp_scyl * od->od_hds * od->od_sec + 499 dptr->dp_shd * od->od_sec + dptr->dp_ssect; 500 { 501 int end = dptr->dp_ecyl * od->od_hds * od->od_sec + 502 dptr->dp_ehd * od->od_sec + dptr->dp_esect; 503 DEBUG("slice entry %d at %d, %d sectors", 504 dev->d_kind.biosdisk.slice - 1, sector, end-sector); 505 } |
686#else 687 sector = dptr->dp_start; 688 DEBUG("slice entry %d at %d, %d sectors", dev->d_kind.biosdisk.slice - 1, sector, dptr->dp_size); 689#endif | |
690 691 /* 692 * If we are looking at a BSD slice, and the partition is < 0, assume the 'a' partition 693 */ | 506 507 /* 508 * If we are looking at a BSD slice, and the partition is < 0, assume the 'a' partition 509 */ |
694#ifdef PC98 | |
695 if ((dptr->dp_mid == DOSMID_386BSD) && (dev->d_kind.biosdisk.partition < 0)) | 510 if ((dptr->dp_mid == DOSMID_386BSD) && (dev->d_kind.biosdisk.partition < 0)) |
696#else 697 if ((dptr->dp_typ == DOSPTYP_386BSD) && (dev->d_kind.biosdisk.partition < 0)) 698#endif | |
699 dev->d_kind.biosdisk.partition = 0; 700 701 unsliced: 702 /* 703 * Now we have the slice offset, look for the partition in the disklabel if we have 704 * a partition to start with. 705 * 706 * XXX we might want to check the label checksum. --- 43 unchanged lines hidden (view full) --- 750 if (error) { 751 free(od); 752 } else { 753 *odp = od; /* return the open disk */ 754 } 755 return(error); 756} 757 | 511 dev->d_kind.biosdisk.partition = 0; 512 513 unsliced: 514 /* 515 * Now we have the slice offset, look for the partition in the disklabel if we have 516 * a partition to start with. 517 * 518 * XXX we might want to check the label checksum. --- 43 unchanged lines hidden (view full) --- 562 if (error) { 563 free(od); 564 } else { 565 *odp = od; /* return the open disk */ 566 } 567 return(error); 568} 569 |
758#ifndef PC98 759static void 760bd_checkextended(struct open_disk *od, int slicenum) 761{ 762 char buf[BIOSDISK_SECSIZE]; 763 struct dos_partition *dp; 764 u_int base; 765 int i, start, end; 766 767 dp = &od->od_slicetab[slicenum]; 768 start = od->od_nslices; 769 770 if (dp->dp_size == 0) 771 goto done; 772 if (dp->dp_typ != DOSPTYP_EXT) 773 goto done; 774 if (bd_read(od, (daddr_t)dp->dp_start, 1, buf)) 775 goto done; 776 if (((u_char)buf[0x1fe] != 0x55) || ((u_char)buf[0x1ff] != 0xaa)) { 777 DEBUG("no magic in extended table"); 778 goto done; 779 } 780 base = dp->dp_start; 781 dp = (struct dos_partition *)(&buf[DOSPARTOFF]); 782 for (i = 0; i < NDOSPART; i++, dp++) { 783 if (dp->dp_size == 0) 784 continue; 785 if (od->od_nslices == NDOSPART) 786 goto done; 787 dp->dp_start += base; 788 bcopy(dp, &od->od_slicetab[od->od_nslices], sizeof(*dp)); 789 od->od_nslices++; 790 } 791 end = od->od_nslices; 792 793 /* 794 * now, recursively check the slices we just added 795 */ 796 for (i = start; i < end; i++) 797 bd_checkextended(od, i); 798done: 799 return; 800} 801#endif 802 | |
803/* 804 * Search for a slice with the following preferences: 805 * 806 * 1: Active FreeBSD slice 807 * 2: Non-active FreeBSD slice 808 * 3: Active Linux slice 809 * 4: non-active Linux slice 810 * 5: Active FAT/FAT32 slice --- 18 unchanged lines hidden (view full) --- 829 int pref, preflevel; 830 int i, prefslice; 831 832 prefslice = 0; 833 preflevel = PREF_NONE; 834 835 dp = &od->od_slicetab[0]; 836 for (i = 0; i < od->od_nslices; i++, dp++) { | 570/* 571 * Search for a slice with the following preferences: 572 * 573 * 1: Active FreeBSD slice 574 * 2: Non-active FreeBSD slice 575 * 3: Active Linux slice 576 * 4: non-active Linux slice 577 * 5: Active FAT/FAT32 slice --- 18 unchanged lines hidden (view full) --- 596 int pref, preflevel; 597 int i, prefslice; 598 599 prefslice = 0; 600 preflevel = PREF_NONE; 601 602 dp = &od->od_slicetab[0]; 603 for (i = 0; i < od->od_nslices; i++, dp++) { |
837 838#ifdef PC98 | |
839 switch(dp->dp_mid & 0x7f) { 840 case DOSMID_386BSD & 0x7f: /* FreeBSD */ 841 if ((dp->dp_mid & 0x80) && 842 (preflevel > PREF_FBSD_ACT)) { 843 pref = i; 844 preflevel = PREF_FBSD_ACT; 845 } else if (preflevel > PREF_FBSD) { 846 pref = i; --- 12 unchanged lines hidden (view full) --- 859 pref = i; 860 preflevel = PREF_DOS_ACT; 861 } else if (preflevel > PREF_DOS) { 862 pref = i; 863 preflevel = PREF_DOS; 864 } 865 break; 866 } | 604 switch(dp->dp_mid & 0x7f) { 605 case DOSMID_386BSD & 0x7f: /* FreeBSD */ 606 if ((dp->dp_mid & 0x80) && 607 (preflevel > PREF_FBSD_ACT)) { 608 pref = i; 609 preflevel = PREF_FBSD_ACT; 610 } else if (preflevel > PREF_FBSD) { 611 pref = i; --- 12 unchanged lines hidden (view full) --- 624 pref = i; 625 preflevel = PREF_DOS_ACT; 626 } else if (preflevel > PREF_DOS) { 627 pref = i; 628 preflevel = PREF_DOS; 629 } 630 break; 631 } |
867#else 868 switch (dp->dp_typ) { 869 case DOSPTYP_386BSD: /* FreeBSD */ 870 pref = dp->dp_flag & 0x80 ? PREF_FBSD_ACT : PREF_FBSD; 871 break; 872 873 case DOSPTYP_LINUX: 874 pref = dp->dp_flag & 0x80 ? PREF_LINUX_ACT : PREF_LINUX; 875 break; 876 877 case 0x01: /* DOS/Windows */ 878 case 0x04: 879 case 0x06: 880 case 0x0b: 881 case 0x0c: 882 case 0x0e: 883 pref = dp->dp_flag & 0x80 ? PREF_DOS_ACT : PREF_DOS; 884 break; 885 886 default: 887 pref = PREF_NONE; 888 } 889 if (pref < preflevel) { 890 preflevel = pref; 891 prefslice = i + 1; 892 } 893#endif | |
894 } 895 return (prefslice); 896} 897 898static int 899bd_close(struct open_file *f) 900{ 901 struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)(f->f_devdata))->d_kind.biosdisk.data); --- 109 unchanged lines hidden (view full) --- 1011 if (blks < 0) 1012 return (-1); 1013 1014 bpc = (od->od_sec * od->od_hds); /* blocks per cylinder */ 1015 resid = blks; 1016 p = dest; 1017 1018 /* Decide whether we have to bounce */ | 632 } 633 return (prefslice); 634} 635 636static int 637bd_close(struct open_file *f) 638{ 639 struct open_disk *od = (struct open_disk *)(((struct i386_devdesc *)(f->f_devdata))->d_kind.biosdisk.data); --- 109 unchanged lines hidden (view full) --- 749 if (blks < 0) 750 return (-1); 751 752 bpc = (od->od_sec * od->od_hds); /* blocks per cylinder */ 753 resid = blks; 754 p = dest; 755 756 /* Decide whether we have to bounce */ |
1019#ifdef PC98 1020 if ( 1021#else 1022 if ((od->od_unit < 0x80) && 1023#endif 1024 ((VTOP(dest) >> 16) != (VTOP(dest + blks * BIOSDISK_SECSIZE) >> 16))) { | 757 if (((VTOP(dest) >> 16) != (VTOP(dest + blks * BIOSDISK_SECSIZE) >> 16))) { |
1025 1026 /* 1027 * There is a 64k physical boundary somewhere in the destination buffer, so we have 1028 * to arrange a suitable bounce buffer. Allocate a buffer twice as large as we 1029 * need to. Use the bottom half unless there is a break there, in which case we 1030 * use the top half. 1031 */ | 758 759 /* 760 * There is a 64k physical boundary somewhere in the destination buffer, so we have 761 * to arrange a suitable bounce buffer. Allocate a buffer twice as large as we 762 * need to. Use the bottom half unless there is a break there, in which case we 763 * use the top half. 764 */ |
1032#ifdef PC98 | |
1033 x = min(od->od_sec, (unsigned)blks); | 765 x = min(od->od_sec, (unsigned)blks); |
1034#else 1035 x = min(FLOPPY_BOUNCEBUF, (unsigned)blks); 1036#endif | |
1037 bbuf = malloc(x * 2 * BIOSDISK_SECSIZE); 1038 if (((u_int32_t)VTOP(bbuf) & 0xffff0000) == ((u_int32_t)VTOP(bbuf + x * BIOSDISK_SECSIZE) & 0xffff0000)) { 1039 breg = bbuf; 1040 } else { 1041 breg = bbuf + x * BIOSDISK_SECSIZE; 1042 } 1043 maxfer = x; /* limit transfers to bounce region size */ 1044 } else { --- 12 unchanged lines hidden (view full) --- 1057 x = min(od->od_sec - sec, resid); 1058 if (maxfer > 0) 1059 x = min(x, maxfer); /* fit bounce buffer */ 1060 1061 /* where do we transfer to? */ 1062 xp = bbuf == NULL ? p : breg; 1063 1064 /* correct sector number for 1-based BIOS numbering */ | 766 bbuf = malloc(x * 2 * BIOSDISK_SECSIZE); 767 if (((u_int32_t)VTOP(bbuf) & 0xffff0000) == ((u_int32_t)VTOP(bbuf + x * BIOSDISK_SECSIZE) & 0xffff0000)) { 768 breg = bbuf; 769 } else { 770 breg = bbuf + x * BIOSDISK_SECSIZE; 771 } 772 maxfer = x; /* limit transfers to bounce region size */ 773 } else { --- 12 unchanged lines hidden (view full) --- 786 x = min(od->od_sec - sec, resid); 787 if (maxfer > 0) 788 x = min(x, maxfer); /* fit bounce buffer */ 789 790 /* where do we transfer to? */ 791 xp = bbuf == NULL ? p : breg; 792 793 /* correct sector number for 1-based BIOS numbering */ |
1065#ifdef PC98 | |
1066 if ((od->od_unit & 0xf0) == 0x30 || (od->od_unit & 0xf0) == 0x90) 1067 sec++; | 794 if ((od->od_unit & 0xf0) == 0x30 || (od->od_unit & 0xf0) == 0x90) 795 sec++; |
1068#else 1069 sec++; 1070#endif | |
1071 1072 /* Loop retrying the operation a couple of times. The BIOS may also retry. */ 1073 for (retry = 0; retry < 3; retry++) { 1074 /* if retrying, reset the drive */ 1075 if (retry > 0) { | 796 797 /* Loop retrying the operation a couple of times. The BIOS may also retry. */ 798 for (retry = 0; retry < 3; retry++) { 799 /* if retrying, reset the drive */ 800 if (retry > 0) { |
1076#ifdef PC98 | |
1077 v86.ctl = V86_FLAGS; 1078 v86.addr = 0x1b; 1079 v86.eax = 0x0300 | od->od_unit; | 801 v86.ctl = V86_FLAGS; 802 v86.addr = 0x1b; 803 v86.eax = 0x0300 | od->od_unit; |
1080#else 1081 v86.ctl = V86_FLAGS; 1082 v86.addr = 0x13; 1083 v86.eax = 0; 1084 v86.edx = od->od_unit; 1085#endif | |
1086 v86int(); 1087 } 1088 | 804 v86int(); 805 } 806 |
1089#ifdef PC98 | |
1090 v86.ctl = V86_FLAGS; 1091 v86.addr = 0x1b; 1092 if (od->od_flags & BD_FLOPPY) { 1093 v86.eax = 0xd600 | od->od_unit; 1094 v86.ecx = 0x0200 | (cyl & 0xff); 1095 } 1096 else { 1097 v86.eax = 0x0600 | od->od_unit; --- 8 unchanged lines hidden (view full) --- 1106 } 1107 v86.ebx = x * BIOSDISK_SECSIZE; 1108 v86.es = VTOPSEG(xp); 1109 v86.ebp = VTOPOFF(xp); 1110 v86int(); 1111 result = (v86.efl & 0x1); 1112 if (result == 0) 1113 break; | 807 v86.ctl = V86_FLAGS; 808 v86.addr = 0x1b; 809 if (od->od_flags & BD_FLOPPY) { 810 v86.eax = 0xd600 | od->od_unit; 811 v86.ecx = 0x0200 | (cyl & 0xff); 812 } 813 else { 814 v86.eax = 0x0600 | od->od_unit; --- 8 unchanged lines hidden (view full) --- 823 } 824 v86.ebx = x * BIOSDISK_SECSIZE; 825 v86.es = VTOPSEG(xp); 826 v86.ebp = VTOPOFF(xp); 827 v86int(); 828 result = (v86.efl & 0x1); 829 if (result == 0) 830 break; |
1114#else 1115 if(cyl > 1023) { 1116 /* use EDD if the disk supports it, otherwise, return error */ 1117 if(od->od_flags & BD_MODEEDD1) { 1118 static unsigned short packet[8]; 1119 1120 packet[0] = 0x10; 1121 packet[1] = x; 1122 packet[2] = VTOPOFF(xp); 1123 packet[3] = VTOPSEG(xp); 1124 packet[4] = dblk & 0xffff; 1125 packet[5] = dblk >> 16; 1126 packet[6] = 0; 1127 packet[7] = 0; 1128 v86.ctl = V86_FLAGS; 1129 v86.addr = 0x13; 1130 v86.eax = 0x4200; 1131 v86.edx = od->od_unit; 1132 v86.ds = VTOPSEG(packet); 1133 v86.esi = VTOPOFF(packet); 1134 v86int(); 1135 result = (v86.efl & 0x1); 1136 if(result == 0) 1137 break; 1138 } else { 1139 result = 1; 1140 break; 1141 } 1142 } else { 1143 /* Use normal CHS addressing */ 1144 v86.ctl = V86_FLAGS; 1145 v86.addr = 0x13; 1146 v86.eax = 0x200 | x; 1147 v86.ecx = ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec; 1148 v86.edx = (hd << 8) | od->od_unit; 1149 v86.es = VTOPSEG(xp); 1150 v86.ebx = VTOPOFF(xp); 1151 v86int(); 1152 result = (v86.efl & 0x1); 1153 if (result == 0) 1154 break; 1155 } 1156#endif | |
1157 } 1158 | 831 } 832 |
1159#ifdef PC98 | |
1160 DEBUG("%d sectors from %d/%d/%d to %p (0x%x) %s", x, cyl, hd, od->od_flags & BD_FLOPPY ? sec - 1 : sec, p, VTOP(p), result ? "failed" : "ok"); 1161 /* BUG here, cannot use v86 in printf because putchar uses it too */ 1162 DEBUG("ax = 0x%04x cx = 0x%04x dx = 0x%04x status 0x%x", 1163 od->od_flags & BD_FLOPPY ? 0xd600 | od->od_unit : 0x0600 | od->od_unit, 1164 od->od_flags & BD_FLOPPY ? 0x0200 | cyl : cyl, (hd << 8) | sec, 1165 (v86.eax >> 8) & 0xff); | 833 DEBUG("%d sectors from %d/%d/%d to %p (0x%x) %s", x, cyl, hd, od->od_flags & BD_FLOPPY ? sec - 1 : sec, p, VTOP(p), result ? "failed" : "ok"); 834 /* BUG here, cannot use v86 in printf because putchar uses it too */ 835 DEBUG("ax = 0x%04x cx = 0x%04x dx = 0x%04x status 0x%x", 836 od->od_flags & BD_FLOPPY ? 0xd600 | od->od_unit : 0x0600 | od->od_unit, 837 od->od_flags & BD_FLOPPY ? 0x0200 | cyl : cyl, (hd << 8) | sec, 838 (v86.eax >> 8) & 0xff); |
1166#else 1167 DEBUG("%d sectors from %d/%d/%d to %p (0x%x) %s", x, cyl, hd, sec - 1, p, VTOP(p), result ? "failed" : "ok"); 1168 /* BUG here, cannot use v86 in printf because putchar uses it too */ 1169 DEBUG("ax = 0x%04x cx = 0x%04x dx = 0x%04x status 0x%x", 1170 0x200 | x, ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec, (hd << 8) | od->od_unit, (v86.eax >> 8) & 0xff); 1171#endif | |
1172 if (result) { 1173 if (bbuf != NULL) 1174 free(bbuf); 1175 return(-1); 1176 } 1177 if (bbuf != NULL) 1178 bcopy(breg, p, x * BIOSDISK_SECSIZE); 1179 p += (x * BIOSDISK_SECSIZE); --- 18 unchanged lines hidden (view full) --- 1198 if (blks < 0) 1199 return (-1); 1200 1201 bpc = (od->od_sec * od->od_hds); /* blocks per cylinder */ 1202 resid = blks; 1203 p = dest; 1204 1205 /* Decide whether we have to bounce */ | 839 if (result) { 840 if (bbuf != NULL) 841 free(bbuf); 842 return(-1); 843 } 844 if (bbuf != NULL) 845 bcopy(breg, p, x * BIOSDISK_SECSIZE); 846 p += (x * BIOSDISK_SECSIZE); --- 18 unchanged lines hidden (view full) --- 865 if (blks < 0) 866 return (-1); 867 868 bpc = (od->od_sec * od->od_hds); /* blocks per cylinder */ 869 resid = blks; 870 p = dest; 871 872 /* Decide whether we have to bounce */ |
1206#ifdef PC98 1207 if ( 1208#else 1209 if ((od->od_unit < 0x80) && 1210#endif 1211 ((VTOP(dest) >> 16) != (VTOP(dest + blks * BIOSDISK_SECSIZE) >> 16))) { | 873 if (((VTOP(dest) >> 16) != (VTOP(dest + blks * BIOSDISK_SECSIZE) >> 16))) { |
1212 1213 /* 1214 * There is a 64k physical boundary somewhere in the destination buffer, so we have 1215 * to arrange a suitable bounce buffer. Allocate a buffer twice as large as we 1216 * need to. Use the bottom half unless there is a break there, in which case we 1217 * use the top half. 1218 */ 1219 | 874 875 /* 876 * There is a 64k physical boundary somewhere in the destination buffer, so we have 877 * to arrange a suitable bounce buffer. Allocate a buffer twice as large as we 878 * need to. Use the bottom half unless there is a break there, in which case we 879 * use the top half. 880 */ 881 |
1220#ifdef PC98 | |
1221 x = min(od->od_sec, (unsigned)blks); | 882 x = min(od->od_sec, (unsigned)blks); |
1222#else 1223 x = min(FLOPPY_BOUNCEBUF, (unsigned)blks); 1224#endif | |
1225 bbuf = malloc(x * 2 * BIOSDISK_SECSIZE); 1226 if (((u_int32_t)VTOP(bbuf) & 0xffff0000) == ((u_int32_t)VTOP(bbuf + x * BIOSDISK_SECSIZE) & 0xffff0000)) { 1227 breg = bbuf; 1228 } else { 1229 breg = bbuf + x * BIOSDISK_SECSIZE; 1230 } 1231 maxfer = x; /* limit transfers to bounce region size */ 1232 } else { --- 12 unchanged lines hidden (view full) --- 1245 x = min(od->od_sec - sec, resid); 1246 if (maxfer > 0) 1247 x = min(x, maxfer); /* fit bounce buffer */ 1248 1249 /* where do we transfer to? */ 1250 xp = bbuf == NULL ? p : breg; 1251 1252 /* correct sector number for 1-based BIOS numbering */ | 883 bbuf = malloc(x * 2 * BIOSDISK_SECSIZE); 884 if (((u_int32_t)VTOP(bbuf) & 0xffff0000) == ((u_int32_t)VTOP(bbuf + x * BIOSDISK_SECSIZE) & 0xffff0000)) { 885 breg = bbuf; 886 } else { 887 breg = bbuf + x * BIOSDISK_SECSIZE; 888 } 889 maxfer = x; /* limit transfers to bounce region size */ 890 } else { --- 12 unchanged lines hidden (view full) --- 903 x = min(od->od_sec - sec, resid); 904 if (maxfer > 0) 905 x = min(x, maxfer); /* fit bounce buffer */ 906 907 /* where do we transfer to? */ 908 xp = bbuf == NULL ? p : breg; 909 910 /* correct sector number for 1-based BIOS numbering */ |
1253#ifdef PC98 | |
1254 if ((od->od_unit & 0xf0) == 0x30 || (od->od_unit & 0xf0) == 0x90) 1255 sec++; | 911 if ((od->od_unit & 0xf0) == 0x30 || (od->od_unit & 0xf0) == 0x90) 912 sec++; |
1256#else 1257 sec++; 1258#endif | |
1259 | 913 |
1260 | |
1261 /* Put your Data In, Put your Data out, 1262 Put your Data In, and shake it all about 1263 */ 1264 if (bbuf != NULL) 1265 bcopy(p, breg, x * BIOSDISK_SECSIZE); 1266 p += (x * BIOSDISK_SECSIZE); 1267 dblk += x; 1268 resid -= x; 1269 1270 /* Loop retrying the operation a couple of times. The BIOS may also retry. */ 1271 for (retry = 0; retry < 3; retry++) { 1272 /* if retrying, reset the drive */ 1273 if (retry > 0) { | 914 /* Put your Data In, Put your Data out, 915 Put your Data In, and shake it all about 916 */ 917 if (bbuf != NULL) 918 bcopy(p, breg, x * BIOSDISK_SECSIZE); 919 p += (x * BIOSDISK_SECSIZE); 920 dblk += x; 921 resid -= x; 922 923 /* Loop retrying the operation a couple of times. The BIOS may also retry. */ 924 for (retry = 0; retry < 3; retry++) { 925 /* if retrying, reset the drive */ 926 if (retry > 0) { |
1274#ifdef PC98 | |
1275 v86.ctl = V86_FLAGS; 1276 v86.addr = 0x1b; 1277 v86.eax = 0x0300 | od->od_unit; | 927 v86.ctl = V86_FLAGS; 928 v86.addr = 0x1b; 929 v86.eax = 0x0300 | od->od_unit; |
1278#else 1279 v86.ctl = V86_FLAGS; 1280 v86.addr = 0x13; 1281 v86.eax = 0; 1282 v86.edx = od->od_unit; 1283#endif | |
1284 v86int(); 1285 } 1286 | 930 v86int(); 931 } 932 |
1287#ifdef PC98 | |
1288 v86.ctl = V86_FLAGS; 1289 v86.addr = 0x1b; 1290 if (od->od_flags & BD_FLOPPY) { 1291 v86.eax = 0xd500 | od->od_unit; 1292 v86.ecx = 0x0200 | (cyl & 0xff); 1293 } else { 1294 v86.eax = 0x0500 | od->od_unit; 1295 v86.ecx = cyl; 1296 } 1297 v86.edx = (hd << 8) | sec; 1298 v86.ebx = x * BIOSDISK_SECSIZE; 1299 v86.es = VTOPSEG(xp); 1300 v86.ebp = VTOPOFF(xp); 1301 v86int(); 1302 result = (v86.efl & 0x1); 1303 if (result == 0) 1304 break; | 933 v86.ctl = V86_FLAGS; 934 v86.addr = 0x1b; 935 if (od->od_flags & BD_FLOPPY) { 936 v86.eax = 0xd500 | od->od_unit; 937 v86.ecx = 0x0200 | (cyl & 0xff); 938 } else { 939 v86.eax = 0x0500 | od->od_unit; 940 v86.ecx = cyl; 941 } 942 v86.edx = (hd << 8) | sec; 943 v86.ebx = x * BIOSDISK_SECSIZE; 944 v86.es = VTOPSEG(xp); 945 v86.ebp = VTOPOFF(xp); 946 v86int(); 947 result = (v86.efl & 0x1); 948 if (result == 0) 949 break; |
1305#else 1306 if(cyl > 1023) { 1307 /* use EDD if the disk supports it, otherwise, return error */ 1308 if(od->od_flags & BD_MODEEDD1) { 1309 static unsigned short packet[8]; 1310 1311 packet[0] = 0x10; 1312 packet[1] = x; 1313 packet[2] = VTOPOFF(xp); 1314 packet[3] = VTOPSEG(xp); 1315 packet[4] = dblk & 0xffff; 1316 packet[5] = dblk >> 16; 1317 packet[6] = 0; 1318 packet[7] = 0; 1319 v86.ctl = V86_FLAGS; 1320 v86.addr = 0x13; 1321 /* Should we Write with verify ?? 0x4302 ? */ 1322 v86.eax = 0x4300; 1323 v86.edx = od->od_unit; 1324 v86.ds = VTOPSEG(packet); 1325 v86.esi = VTOPOFF(packet); 1326 v86int(); 1327 result = (v86.efl & 0x1); 1328 if(result == 0) 1329 break; 1330 } else { 1331 result = 1; 1332 break; 1333 } 1334 } else { 1335 /* Use normal CHS addressing */ 1336 v86.ctl = V86_FLAGS; 1337 v86.addr = 0x13; 1338 v86.eax = 0x300 | x; 1339 v86.ecx = ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec; 1340 v86.edx = (hd << 8) | od->od_unit; 1341 v86.es = VTOPSEG(xp); 1342 v86.ebx = VTOPOFF(xp); 1343 v86int(); 1344 result = (v86.efl & 0x1); 1345 if (result == 0) 1346 break; 1347 } 1348#endif | |
1349 } 1350 | 950 } 951 |
1351#ifdef PC98 | |
1352 DEBUG("%d sectors from %d/%d/%d to %p (0x%x) %s", x, cyl, hd, 1353 od->od_flags & BD_FLOPPY ? sec - 1 : sec, p, VTOP(p), 1354 result ? "failed" : "ok"); 1355 /* BUG here, cannot use v86 in printf because putchar uses it too */ 1356 DEBUG("ax = 0x%04x cx = 0x%04x dx = 0x%04x status 0x%x", 1357 od->od_flags & BD_FLOPPY ? 0xd600 | od->od_unit : 0x0600 | od->od_unit, 1358 od->od_flags & BD_FLOPPY ? 0x0200 | cyl : cyl, (hd << 8) | sec, 1359 (v86.eax >> 8) & 0xff); | 952 DEBUG("%d sectors from %d/%d/%d to %p (0x%x) %s", x, cyl, hd, 953 od->od_flags & BD_FLOPPY ? sec - 1 : sec, p, VTOP(p), 954 result ? "failed" : "ok"); 955 /* BUG here, cannot use v86 in printf because putchar uses it too */ 956 DEBUG("ax = 0x%04x cx = 0x%04x dx = 0x%04x status 0x%x", 957 od->od_flags & BD_FLOPPY ? 0xd600 | od->od_unit : 0x0600 | od->od_unit, 958 od->od_flags & BD_FLOPPY ? 0x0200 | cyl : cyl, (hd << 8) | sec, 959 (v86.eax >> 8) & 0xff); |
1360#else 1361 DEBUG("%d sectors from %d/%d/%d to %p (0x%x) %s", x, cyl, hd, sec - 1, p, VTOP(p), result ? "failed" : "ok"); 1362 /* BUG here, cannot use v86 in printf because putchar uses it too */ 1363 DEBUG("ax = 0x%04x cx = 0x%04x dx = 0x%04x status 0x%x", 1364 0x200 | x, ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec, (hd << 8) | od->od_unit, (v86.eax >> 8) & 0xff); 1365#endif | 960 |
1366 if (result) { 1367 if (bbuf != NULL) 1368 free(bbuf); 1369 return(-1); 1370 } 1371 } 1372 1373/* hexdump(dest, (blks * BIOSDISK_SECSIZE)); */ 1374 if (bbuf != NULL) 1375 free(bbuf); 1376 return(0); 1377} 1378static int 1379bd_getgeom(struct open_disk *od) 1380{ 1381 | 961 if (result) { 962 if (bbuf != NULL) 963 free(bbuf); 964 return(-1); 965 } 966 } 967 968/* hexdump(dest, (blks * BIOSDISK_SECSIZE)); */ 969 if (bbuf != NULL) 970 free(bbuf); 971 return(0); 972} 973static int 974bd_getgeom(struct open_disk *od) 975{ 976 |
1382#ifdef PC98 | |
1383 if (od->od_flags & BD_FLOPPY) { 1384 od->od_cyl = 79; 1385 od->od_hds = 2; 1386 od->od_sec = (od->od_unit & 0xf0) == 0x30 ? 18 : 15; 1387 } else if (od->od_flags & BD_OPTICAL) { 1388 od->od_cyl = 0xFFFE; 1389 od->od_hds = 8; 1390 od->od_sec = 32; --- 4 unchanged lines hidden (view full) --- 1395 v86int(); 1396 1397 od->od_cyl = v86.ecx; 1398 od->od_hds = (v86.edx >> 8) & 0xff; 1399 od->od_sec = v86.edx & 0xff; 1400 if (v86.efl & 0x1) 1401 return(1); 1402 } | 977 if (od->od_flags & BD_FLOPPY) { 978 od->od_cyl = 79; 979 od->od_hds = 2; 980 od->od_sec = (od->od_unit & 0xf0) == 0x30 ? 18 : 15; 981 } else if (od->od_flags & BD_OPTICAL) { 982 od->od_cyl = 0xFFFE; 983 od->od_hds = 8; 984 od->od_sec = 32; --- 4 unchanged lines hidden (view full) --- 989 v86int(); 990 991 od->od_cyl = v86.ecx; 992 od->od_hds = (v86.edx >> 8) & 0xff; 993 od->od_sec = v86.edx & 0xff; 994 if (v86.efl & 0x1) 995 return(1); 996 } |
1403#else 1404 v86.ctl = V86_FLAGS; 1405 v86.addr = 0x13; 1406 v86.eax = 0x800; 1407 v86.edx = od->od_unit; 1408 v86int(); | |
1409 | 997 |
1410 if ((v86.efl & 0x1) || /* carry set */ 1411 ((v86.edx & 0xff) <= (unsigned)(od->od_unit & 0x7f))) /* unit # bad */ 1412 return(1); 1413 1414 /* convert max cyl # -> # of cylinders */ 1415 od->od_cyl = ((v86.ecx & 0xc0) << 2) + ((v86.ecx & 0xff00) >> 8) + 1; 1416 /* convert max head # -> # of heads */ 1417 od->od_hds = ((v86.edx & 0xff00) >> 8) + 1; 1418 od->od_sec = v86.ecx & 0x3f; 1419#endif 1420 | |
1421 DEBUG("unit 0x%x geometry %d/%d/%d", od->od_unit, od->od_cyl, od->od_hds, od->od_sec); 1422 return(0); 1423} 1424 1425/* 1426 * Return the BIOS geometry of a given "fixed drive" in a format 1427 * suitable for the legacy bootinfo structure. Since the kernel is 1428 * expecting raw int 0x13/0x8 values for N_BIOS_GEOM drives, we --- 5 unchanged lines hidden (view full) --- 1434 * "000000cc cccccccc hhhhhhhh 00ssssss"; and invalid drives are 1435 * indicated by returning the geometry of a "1.2M" PC-format floppy 1436 * disk. And, incidentally, what is returned is not the geometry as 1437 * such but the highest valid cylinder, head, and sector numbers. 1438 */ 1439u_int32_t 1440bd_getbigeom(int bunit) 1441{ | 998 DEBUG("unit 0x%x geometry %d/%d/%d", od->od_unit, od->od_cyl, od->od_hds, od->od_sec); 999 return(0); 1000} 1001 1002/* 1003 * Return the BIOS geometry of a given "fixed drive" in a format 1004 * suitable for the legacy bootinfo structure. Since the kernel is 1005 * expecting raw int 0x13/0x8 values for N_BIOS_GEOM drives, we --- 5 unchanged lines hidden (view full) --- 1011 * "000000cc cccccccc hhhhhhhh 00ssssss"; and invalid drives are 1012 * indicated by returning the geometry of a "1.2M" PC-format floppy 1013 * disk. And, incidentally, what is returned is not the geometry as 1014 * such but the highest valid cylinder, head, and sector numbers. 1015 */ 1016u_int32_t 1017bd_getbigeom(int bunit) 1018{ |
1442 1443#ifdef PC98 | |
1444 int hds = 0; 1445 int unit = 0x80; /* IDE HDD */ 1446 u_int addr = 0xA155d; 1447 1448 while (unit < 0xa7) { 1449 if (*(u_char *)PTOV(addr) & (1 << (unit & 0x0f))) 1450 if (hds++ == bunit) 1451 break; --- 13 unchanged lines hidden (view full) --- 1465 return 0x4F020F; /* 1200KB FD C:80 H:2 S:15 */ 1466 v86.ctl = V86_FLAGS; 1467 v86.addr = 0x1b; 1468 v86.eax = 0x8400 | unit; 1469 v86int(); 1470 if (v86.efl & 0x1) 1471 return 0x4F020F; /* 1200KB FD C:80 H:2 S:15 */ 1472 return ((v86.ecx & 0xffff) << 16) | (v86.edx & 0xffff); | 1019 int hds = 0; 1020 int unit = 0x80; /* IDE HDD */ 1021 u_int addr = 0xA155d; 1022 1023 while (unit < 0xa7) { 1024 if (*(u_char *)PTOV(addr) & (1 << (unit & 0x0f))) 1025 if (hds++ == bunit) 1026 break; --- 13 unchanged lines hidden (view full) --- 1040 return 0x4F020F; /* 1200KB FD C:80 H:2 S:15 */ 1041 v86.ctl = V86_FLAGS; 1042 v86.addr = 0x1b; 1043 v86.eax = 0x8400 | unit; 1044 v86int(); 1045 if (v86.efl & 0x1) 1046 return 0x4F020F; /* 1200KB FD C:80 H:2 S:15 */ 1047 return ((v86.ecx & 0xffff) << 16) | (v86.edx & 0xffff); |
1473#else 1474 v86.ctl = V86_FLAGS; 1475 v86.addr = 0x13; 1476 v86.eax = 0x800; 1477 v86.edx = 0x80 + bunit; 1478 v86int(); 1479 if (v86.efl & 0x1) 1480 return 0x4f010f; 1481 return ((v86.ecx & 0xc0) << 18) | ((v86.ecx & 0xff00) << 8) | 1482 (v86.edx & 0xff00) | (v86.ecx & 0x3f); 1483#endif | |
1484} 1485 1486/* 1487 * Return a suitable dev_t value for (dev). 1488 * 1489 * In the case where it looks like (dev) is a SCSI disk, we allow the number of 1490 * IDE disks to be specified in $num_ide_disks. There should be a Better Way. 1491 */ --- 9 unchanged lines hidden (view full) --- 1501 1502 biosdev = bd_unit2bios(dev->d_kind.biosdisk.unit); 1503 DEBUG("unit %d BIOS device %d", dev->d_kind.biosdisk.unit, biosdev); 1504 if (biosdev == -1) /* not a BIOS device */ 1505 return(-1); 1506 if (bd_opendisk(&od, dev) != 0) /* oops, not a viable device */ 1507 return(-1); 1508 | 1048} 1049 1050/* 1051 * Return a suitable dev_t value for (dev). 1052 * 1053 * In the case where it looks like (dev) is a SCSI disk, we allow the number of 1054 * IDE disks to be specified in $num_ide_disks. There should be a Better Way. 1055 */ --- 9 unchanged lines hidden (view full) --- 1065 1066 biosdev = bd_unit2bios(dev->d_kind.biosdisk.unit); 1067 DEBUG("unit %d BIOS device %d", dev->d_kind.biosdisk.unit, biosdev); 1068 if (biosdev == -1) /* not a BIOS device */ 1069 return(-1); 1070 if (bd_opendisk(&od, dev) != 0) /* oops, not a viable device */ 1071 return(-1); 1072 |
1509#ifdef PC98 | |
1510 if ((biosdev & 0xf0) == 0x90 || (biosdev & 0xf0) == 0x30) { | 1073 if ((biosdev & 0xf0) == 0x90 || (biosdev & 0xf0) == 0x30) { |
1511#else 1512 if (biosdev < 0x80) { 1513#endif | |
1514 /* floppy (or emulated floppy) or ATAPI device */ 1515 if (bdinfo[dev->d_kind.biosdisk.unit].bd_type == DT_ATAPI) { 1516 /* is an ATAPI disk */ 1517 major = WFDMAJOR; 1518 } else { 1519 /* is a floppy disk */ 1520 major = FDMAJOR; 1521 } --- 10 unchanged lines hidden (view full) --- 1532 unitofs = i; 1533 } 1534 } else { 1535 /* assume an IDE disk */ 1536 major = WDMAJOR; 1537 } 1538 } 1539 /* default root disk unit number */ | 1074 /* floppy (or emulated floppy) or ATAPI device */ 1075 if (bdinfo[dev->d_kind.biosdisk.unit].bd_type == DT_ATAPI) { 1076 /* is an ATAPI disk */ 1077 major = WFDMAJOR; 1078 } else { 1079 /* is a floppy disk */ 1080 major = FDMAJOR; 1081 } --- 10 unchanged lines hidden (view full) --- 1092 unitofs = i; 1093 } 1094 } else { 1095 /* assume an IDE disk */ 1096 major = WDMAJOR; 1097 } 1098 } 1099 /* default root disk unit number */ |
1540#ifdef PC98 | |
1541 if ((biosdev & 0xf0) == 0xa0) 1542 unit = bdinfo[dev->d_kind.biosdisk.unit].bd_da_unit; 1543 else 1544 unit = biosdev & 0xf; | 1100 if ((biosdev & 0xf0) == 0xa0) 1101 unit = bdinfo[dev->d_kind.biosdisk.unit].bd_da_unit; 1102 else 1103 unit = biosdev & 0xf; |
1545#else 1546 unit = (biosdev & 0x7f) - unitofs; 1547#endif | |
1548 1549 /* XXX a better kludge to set the root disk unit number */ 1550 if ((nip = getenv("root_disk_unit")) != NULL) { 1551 i = strtol(nip, &cp, 0); 1552 /* check for parse error */ 1553 if ((cp != nip) && (*cp == 0)) 1554 unit = i; 1555 } 1556 1557 rootdev = MAKEBOOTDEV(major, 1558 (dev->d_kind.biosdisk.slice + 1) >> 4, /* XXX slices may be wrong here */ 1559 (dev->d_kind.biosdisk.slice + 1) & 0xf, 1560 unit, 1561 dev->d_kind.biosdisk.partition); 1562 DEBUG("dev is 0x%x\n", rootdev); 1563 return(rootdev); 1564} | 1104 1105 /* XXX a better kludge to set the root disk unit number */ 1106 if ((nip = getenv("root_disk_unit")) != NULL) { 1107 i = strtol(nip, &cp, 0); 1108 /* check for parse error */ 1109 if ((cp != nip) && (*cp == 0)) 1110 unit = i; 1111 } 1112 1113 rootdev = MAKEBOOTDEV(major, 1114 (dev->d_kind.biosdisk.slice + 1) >> 4, /* XXX slices may be wrong here */ 1115 (dev->d_kind.biosdisk.slice + 1) & 0xf, 1116 unit, 1117 dev->d_kind.biosdisk.partition); 1118 DEBUG("dev is 0x%x\n", rootdev); 1119 return(rootdev); 1120} |