340} 341 342/* 343 * Attempt to open the disk described by (dev) for use by (f). 344 * 345 * Note that the philosophy here is "give them exactly what 346 * they ask for". This is necessary because being too "smart" 347 * about what the user might want leads to complications. 348 * (eg. given no slice or partition value, with a disk that is 349 * sliced - are they after the first BSD slice, or the DOS 350 * slice before it?) 351 */ 352static int 353bd_open(struct open_file *f, ...) 354{ 355 struct disk_devdesc *dev, rdev; 356 int err, g_err; 357 va_list ap; 358 359 va_start(ap, f); 360 dev = va_arg(ap, struct disk_devdesc *); 361 va_end(ap); 362 363 if (dev->d_unit < 0 || dev->d_unit >= nbdinfo) 364 return (EIO); 365 BD(dev).bd_open++; 366 if (BD(dev).bd_bcache == NULL) 367 BD(dev).bd_bcache = bcache_allocate(); 368 err = disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize, 369 BD(dev).bd_sectorsize, (BD(dev).bd_flags & BD_FLOPPY) ? 370 DISK_F_NOCACHE: 0); 371 372#ifdef LOADER_GELI_SUPPORT 373 static char gelipw[GELI_PW_MAXLEN]; 374 char *passphrase; 375 376 if (err) 377 return (err); 378 379 /* if we already know there is no GELI, skip the rest */ 380 if (geli_status[dev->d_unit][dev->d_slice] != ISGELI_UNKNOWN) 381 return (err); 382 383 struct dsk dskp; 384 struct ptable *table = NULL; 385 struct ptable_entry part; 386 struct pentry *entry; 387 int geli_part = 0; 388 389 dskp.drive = bd_unit2bios(dev->d_unit); 390 dskp.type = dev->d_type; 391 dskp.unit = dev->d_unit; 392 dskp.slice = dev->d_slice; 393 dskp.part = dev->d_partition; 394 dskp.start = dev->d_offset; 395 396 memcpy(&rdev, dev, sizeof(rdev)); 397 /* to read the GPT table, we need to read the first sector */ 398 rdev.d_offset = 0; 399 /* We need the LBA of the end of the partition */ 400 table = ptable_open(&rdev, BD(dev).bd_sectors, 401 BD(dev).bd_sectorsize, ptblread); 402 if (table == NULL) { 403 DEBUG("Can't read partition table"); 404 /* soft failure, return the exit status of disk_open */ 405 return (err); 406 } 407 408 if (table->type == PTABLE_GPT) 409 dskp.part = 255; 410 411 STAILQ_FOREACH(entry, &table->entries, entry) { 412 dskp.slice = entry->part.index; 413 dskp.start = entry->part.start; 414 if (is_geli(&dskp) == 0) { 415 geli_status[dev->d_unit][dskp.slice] = ISGELI_YES; 416 return (0); 417 } 418 if (geli_taste(bios_read, &dskp, 419 entry->part.end - entry->part.start) == 0) { 420 if ((passphrase = getenv("kern.geom.eli.passphrase")) 421 != NULL) { 422 /* Use the cached passphrase */ 423 bcopy(passphrase, &gelipw, GELI_PW_MAXLEN); 424 } 425 if (geli_passphrase(&gelipw, dskp.unit, 'p', 426 (dskp.slice > 0 ? dskp.slice : dskp.part), 427 &dskp) == 0) { 428 setenv("kern.geom.eli.passphrase", &gelipw, 1); 429 bzero(gelipw, sizeof(gelipw)); 430 geli_status[dev->d_unit][dskp.slice] = ISGELI_YES; 431 geli_part++; 432 } 433 } else 434 geli_status[dev->d_unit][dskp.slice] = ISGELI_NO; 435 } 436 437 /* none of the partitions on this disk have GELI */ 438 if (geli_part == 0) { 439 /* found no GELI */ 440 geli_status[dev->d_unit][dev->d_slice] = ISGELI_NO; 441 } 442#endif /* LOADER_GELI_SUPPORT */ 443 444 return (err); 445} 446 447static int 448bd_close(struct open_file *f) 449{ 450 struct disk_devdesc *dev; 451 452 dev = (struct disk_devdesc *)f->f_devdata; 453 BD(dev).bd_open--; 454 if (BD(dev).bd_open == 0) { 455 bcache_free(BD(dev).bd_bcache); 456 BD(dev).bd_bcache = NULL; 457 } 458 return (disk_close(dev)); 459} 460 461static int 462bd_ioctl(struct open_file *f, u_long cmd, void *data) 463{ 464 struct disk_devdesc *dev; 465 466 dev = (struct disk_devdesc *)f->f_devdata; 467 switch (cmd) { 468 case DIOCGSECTORSIZE: 469 *(u_int *)data = BD(dev).bd_sectorsize; 470 break; 471 case DIOCGMEDIASIZE: 472 *(off_t *)data = BD(dev).bd_sectors * BD(dev).bd_sectorsize; 473 break; 474 default: 475 return (ENOTTY); 476 } 477 return (0); 478} 479 480static int 481bd_strategy(void *devdata, int rw, daddr_t dblk, size_t size, 482 char *buf, size_t *rsize) 483{ 484 struct bcache_devdata bcd; 485 struct disk_devdesc *dev; 486 487 dev = (struct disk_devdesc *)devdata; 488 bcd.dv_strategy = bd_realstrategy; 489 bcd.dv_devdata = devdata; 490 bcd.dv_cache = BD(dev).bd_bcache; 491 return (bcache_strategy(&bcd, rw, dblk + dev->d_offset, 492 size, buf, rsize)); 493} 494 495static int 496bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size, 497 char *buf, size_t *rsize) 498{ 499 struct disk_devdesc *dev = (struct disk_devdesc *)devdata; 500 int blks, remaining; 501#ifdef BD_SUPPORT_FRAGS /* XXX: sector size */ 502 char fragbuf[BIOSDISK_SECSIZE]; 503 size_t fragsize; 504 505 fragsize = size % BIOSDISK_SECSIZE; 506#else 507 if (size % BD(dev).bd_sectorsize) 508 panic("bd_strategy: %d bytes I/O not multiple of block size", size); 509#endif 510 511 DEBUG("open_disk %p", dev); 512 blks = size / BD(dev).bd_sectorsize; 513 if (rsize) 514 *rsize = 0; 515 516 /* 517 * Perform partial read to prevent read-ahead crossing 518 * the end of disk - or any 32 bit aliases of the end. 519 * Signed arithmetic is used to handle wrap-around cases 520 * like we do for TCP sequence numbers. 521 */ 522 remaining = (int)(BD(dev).bd_sectors - dblk); /* truncate */ 523 if (remaining > 0 && remaining < blks) { 524 blks = remaining; 525 size = blks * BD(dev).bd_sectorsize; 526 DEBUG("short read %d", blks); 527 } 528 529 switch(rw){ 530 case F_READ: 531 DEBUG("read %d from %lld to %p", blks, dblk, buf); 532 533 if (blks && bd_read(dev, dblk, blks, buf)) { 534 DEBUG("read error"); 535 return (EIO); 536 } 537#ifdef BD_SUPPORT_FRAGS /* XXX: sector size */ 538 DEBUG("bd_strategy: frag read %d from %d+%d to %p", 539 fragsize, dblk, blks, buf + (blks * BIOSDISK_SECSIZE)); 540 if (fragsize && bd_read(od, dblk + blks, 1, fragsize)) { 541 DEBUG("frag read error"); 542 return(EIO); 543 } 544 bcopy(fragbuf, buf + (blks * BIOSDISK_SECSIZE), fragsize); 545#endif 546 break; 547 case F_WRITE : 548 DEBUG("write %d from %d to %p", blks, dblk, buf); 549 550 if (blks && bd_write(dev, dblk, blks, buf)) { 551 DEBUG("write error"); 552 return (EIO); 553 } 554#ifdef BD_SUPPORT_FRAGS 555 if(fragsize) { 556 DEBUG("Attempted to write a frag"); 557 return (EIO); 558 } 559#endif 560 break; 561 default: 562 /* DO NOTHING */ 563 return (EROFS); 564 } 565 566 if (rsize) 567 *rsize = size; 568 return (0); 569} 570 571/* Max number of sectors to bounce-buffer if the request crosses a 64k boundary */ 572#define FLOPPY_BOUNCEBUF 18 573 574static int 575bd_edd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest, 576 int write) 577{ 578 static struct edd_packet packet; 579 580 packet.len = sizeof(struct edd_packet); 581 packet.count = blks; 582 packet.off = VTOPOFF(dest); 583 packet.seg = VTOPSEG(dest); 584 packet.lba = dblk; 585 v86.ctl = V86_FLAGS; 586 v86.addr = 0x13; 587 if (write) 588 /* Should we Write with verify ?? 0x4302 ? */ 589 v86.eax = 0x4300; 590 else 591 v86.eax = 0x4200; 592 v86.edx = BD(dev).bd_unit; 593 v86.ds = VTOPSEG(&packet); 594 v86.esi = VTOPOFF(&packet); 595 v86int(); 596 return (V86_CY(v86.efl)); 597} 598 599static int 600bd_chs_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest, 601 int write) 602{ 603 u_int x, bpc, cyl, hd, sec; 604 605 bpc = BD(dev).bd_sec * BD(dev).bd_hds; /* blocks per cylinder */ 606 x = dblk; 607 cyl = x / bpc; /* block # / blocks per cylinder */ 608 x %= bpc; /* block offset into cylinder */ 609 hd = x / BD(dev).bd_sec; /* offset / blocks per track */ 610 sec = x % BD(dev).bd_sec; /* offset into track */ 611 612 /* correct sector number for 1-based BIOS numbering */ 613 sec++; 614 615 if (cyl > 1023) 616 /* CHS doesn't support cylinders > 1023. */ 617 return (1); 618 619 v86.ctl = V86_FLAGS; 620 v86.addr = 0x13; 621 if (write) 622 v86.eax = 0x300 | blks; 623 else 624 v86.eax = 0x200 | blks; 625 v86.ecx = ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec; 626 v86.edx = (hd << 8) | BD(dev).bd_unit; 627 v86.es = VTOPSEG(dest); 628 v86.ebx = VTOPOFF(dest); 629 v86int(); 630 return (V86_CY(v86.efl)); 631} 632 633static int 634bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest, int write) 635{ 636 u_int x, sec, result, resid, retry, maxfer; 637 caddr_t p, xp, bbuf, breg; 638 639 /* Just in case some idiot actually tries to read/write -1 blocks... */ 640 if (blks < 0) 641 return (-1); 642 643 resid = blks; 644 p = dest; 645 646 /* Decide whether we have to bounce */ 647 if (VTOP(dest) >> 20 != 0 || (BD(dev).bd_unit < 0x80 && 648 (VTOP(dest) >> 16) != (VTOP(dest + 649 blks * BD(dev).bd_sectorsize) >> 16))) { 650 651 /* 652 * There is a 64k physical boundary somewhere in the 653 * destination buffer, or the destination buffer is above 654 * first 1MB of physical memory so we have to arrange a 655 * suitable bounce buffer. Allocate a buffer twice as large 656 * as we need to. Use the bottom half unless there is a break 657 * there, in which case we use the top half. 658 */ 659 x = min(FLOPPY_BOUNCEBUF, (unsigned)blks); 660 bbuf = alloca(x * 2 * BD(dev).bd_sectorsize); 661 if (((u_int32_t)VTOP(bbuf) & 0xffff0000) == 662 ((u_int32_t)VTOP(bbuf + x * BD(dev).bd_sectorsize) & 0xffff0000)) { 663 breg = bbuf; 664 } else { 665 breg = bbuf + x * BD(dev).bd_sectorsize; 666 } 667 maxfer = x; /* limit transfers to bounce region size */ 668 } else { 669 breg = bbuf = NULL; 670 maxfer = 0; 671 } 672 673 while (resid > 0) { 674 /* 675 * Play it safe and don't cross track boundaries. 676 * (XXX this is probably unnecessary) 677 */ 678 sec = dblk % BD(dev).bd_sec; /* offset into track */ 679 x = min(BD(dev).bd_sec - sec, resid); 680 if (maxfer > 0) 681 x = min(x, maxfer); /* fit bounce buffer */ 682 683 /* where do we transfer to? */ 684 xp = bbuf == NULL ? p : breg; 685 686 /* 687 * Put your Data In, Put your Data out, 688 * Put your Data In, and shake it all about 689 */ 690 if (write && bbuf != NULL) 691 bcopy(p, breg, x * BD(dev).bd_sectorsize); 692 693 /* 694 * Loop retrying the operation a couple of times. The BIOS 695 * may also retry. 696 */ 697 for (retry = 0; retry < 3; retry++) { 698 /* if retrying, reset the drive */ 699 if (retry > 0) { 700 v86.ctl = V86_FLAGS; 701 v86.addr = 0x13; 702 v86.eax = 0; 703 v86.edx = BD(dev).bd_unit; 704 v86int(); 705 } 706 707 if (BD(dev).bd_flags & BD_MODEEDD1) 708 result = bd_edd_io(dev, dblk, x, xp, write); 709 else 710 result = bd_chs_io(dev, dblk, x, xp, write); 711 if (result == 0) 712 break; 713 } 714 715 if (write) 716 DEBUG("Write %d sector(s) from %p (0x%x) to %lld %s", x, 717 p, VTOP(p), dblk, result ? "failed" : "ok"); 718 else 719 DEBUG("Read %d sector(s) from %lld to %p (0x%x) %s", x, 720 dblk, p, VTOP(p), result ? "failed" : "ok"); 721 if (result) { 722 return(-1); 723 } 724 if (!write && bbuf != NULL) 725 bcopy(breg, p, x * BD(dev).bd_sectorsize); 726 p += (x * BD(dev).bd_sectorsize); 727 dblk += x; 728 resid -= x; 729 } 730 731/* hexdump(dest, (blks * BD(dev).bd_sectorsize)); */ 732 return(0); 733} 734 735static int 736bd_read(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest) 737{ 738#ifdef LOADER_GELI_SUPPORT 739 struct dsk dskp; 740 off_t p_off, diff; 741 daddr_t alignlba; 742 int err, n, alignblks; 743 char *tmpbuf; 744 745 /* if we already know there is no GELI, skip the rest */ 746 if (geli_status[dev->d_unit][dev->d_slice] != ISGELI_YES) 747 return (bd_io(dev, dblk, blks, dest, 0)); 748 749 if (geli_status[dev->d_unit][dev->d_slice] == ISGELI_YES) { 750 /* 751 * Align reads to DEV_GELIBOOT_BSIZE bytes because partial 752 * sectors cannot be decrypted. Round the requested LBA down to 753 * nearest multiple of DEV_GELIBOOT_BSIZE bytes. 754 */ 755 alignlba = rounddown2(dblk * BD(dev).bd_sectorsize, 756 DEV_GELIBOOT_BSIZE) / BD(dev).bd_sectorsize; 757 /* 758 * Round number of blocks to read up to nearest multiple of 759 * DEV_GELIBOOT_BSIZE 760 */ 761 diff = (dblk - alignlba) * BD(dev).bd_sectorsize; 762 alignblks = roundup2(blks * BD(dev).bd_sectorsize + diff, 763 DEV_GELIBOOT_BSIZE) / BD(dev).bd_sectorsize; 764 765 /* 766 * If the read is rounded up to a larger size, use a temporary 767 * buffer here because the buffer provided by the caller may be 768 * too small. 769 */ 770 if (diff == 0) { 771 tmpbuf = dest; 772 } else { 773 tmpbuf = malloc(alignblks * BD(dev).bd_sectorsize); 774 if (tmpbuf == NULL) { 775 return (-1); 776 } 777 } 778 779 err = bd_io(dev, alignlba, alignblks, tmpbuf, 0); 780 if (err) 781 return (err); 782 783 dskp.drive = bd_unit2bios(dev->d_unit); 784 dskp.type = dev->d_type; 785 dskp.unit = dev->d_unit; 786 dskp.slice = dev->d_slice; 787 dskp.part = dev->d_partition; 788 dskp.start = dev->d_offset; 789 790 /* GELI needs the offset relative to the partition start */ 791 p_off = alignlba - dskp.start; 792 793 err = geli_read(&dskp, p_off * BD(dev).bd_sectorsize, tmpbuf, 794 alignblks * BD(dev).bd_sectorsize); 795 if (err) 796 return (err); 797 798 if (tmpbuf != dest) { 799 bcopy(tmpbuf + diff, dest, blks * BD(dev).bd_sectorsize); 800 free(tmpbuf); 801 } 802 return (0); 803 } 804#endif /* LOADER_GELI_SUPPORT */ 805 806 return (bd_io(dev, dblk, blks, dest, 0)); 807} 808 809static int 810bd_write(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest) 811{ 812 813 return (bd_io(dev, dblk, blks, dest, 1)); 814} 815 816/* 817 * Return the BIOS geometry of a given "fixed drive" in a format 818 * suitable for the legacy bootinfo structure. Since the kernel is 819 * expecting raw int 0x13/0x8 values for N_BIOS_GEOM drives, we 820 * prefer to get the information directly, rather than rely on being 821 * able to put it together from information already maintained for 822 * different purposes and for a probably different number of drives. 823 * 824 * For valid drives, the geometry is expected in the format (31..0) 825 * "000000cc cccccccc hhhhhhhh 00ssssss"; and invalid drives are 826 * indicated by returning the geometry of a "1.2M" PC-format floppy 827 * disk. And, incidentally, what is returned is not the geometry as 828 * such but the highest valid cylinder, head, and sector numbers. 829 */ 830u_int32_t 831bd_getbigeom(int bunit) 832{ 833 834 v86.ctl = V86_FLAGS; 835 v86.addr = 0x13; 836 v86.eax = 0x800; 837 v86.edx = 0x80 + bunit; 838 v86int(); 839 if (V86_CY(v86.efl)) 840 return 0x4f010f; 841 return ((v86.ecx & 0xc0) << 18) | ((v86.ecx & 0xff00) << 8) | 842 (v86.edx & 0xff00) | (v86.ecx & 0x3f); 843} 844 845/* 846 * Return a suitable dev_t value for (dev). 847 * 848 * In the case where it looks like (dev) is a SCSI disk, we allow the number of 849 * IDE disks to be specified in $num_ide_disks. There should be a Better Way. 850 */ 851int 852bd_getdev(struct i386_devdesc *d) 853{ 854 struct disk_devdesc *dev; 855 int biosdev; 856 int major; 857 int rootdev; 858 char *nip, *cp; 859 int i, unit; 860 861 dev = (struct disk_devdesc *)d; 862 biosdev = bd_unit2bios(dev->d_unit); 863 DEBUG("unit %d BIOS device %d", dev->d_unit, biosdev); 864 if (biosdev == -1) /* not a BIOS device */ 865 return(-1); 866 if (disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize, 867 BD(dev).bd_sectorsize,(BD(dev).bd_flags & BD_FLOPPY) ? 868 DISK_F_NOCACHE: 0) != 0) /* oops, not a viable device */ 869 return (-1); 870 else 871 disk_close(dev); 872 873 if (biosdev < 0x80) { 874 /* floppy (or emulated floppy) or ATAPI device */ 875 if (bdinfo[dev->d_unit].bd_type == DT_ATAPI) { 876 /* is an ATAPI disk */ 877 major = WFDMAJOR; 878 } else { 879 /* is a floppy disk */ 880 major = FDMAJOR; 881 } 882 } else { 883 /* assume an IDE disk */ 884 major = WDMAJOR; 885 } 886 /* default root disk unit number */ 887 unit = biosdev & 0x7f; 888 889 /* XXX a better kludge to set the root disk unit number */ 890 if ((nip = getenv("root_disk_unit")) != NULL) { 891 i = strtol(nip, &cp, 0); 892 /* check for parse error */ 893 if ((cp != nip) && (*cp == 0)) 894 unit = i; 895 } 896 897 rootdev = MAKEBOOTDEV(major, dev->d_slice + 1, unit, dev->d_partition); 898 DEBUG("dev is 0x%x\n", rootdev); 899 return(rootdev); 900} 901 902#ifdef LOADER_GELI_SUPPORT 903int 904bios_read(void *vdev __unused, struct dsk *priv, off_t off, char *buf, size_t bytes) 905{ 906 struct disk_devdesc dev; 907 908 dev.d_dev = &biosdisk; 909 dev.d_type = priv->type; 910 dev.d_unit = priv->unit; 911 dev.d_slice = priv->slice; 912 dev.d_partition = priv->part; 913 dev.d_offset = priv->start; 914 915 off = off / BD(&dev).bd_sectorsize; 916 /* GELI gives us the offset relative to the partition start */ 917 off += dev.d_offset; 918 bytes = bytes / BD(&dev).bd_sectorsize; 919 920 return (bd_io(&dev, off, bytes, buf, 0)); 921} 922#endif /* LOADER_GELI_SUPPORT */
| 349} 350 351/* 352 * Attempt to open the disk described by (dev) for use by (f). 353 * 354 * Note that the philosophy here is "give them exactly what 355 * they ask for". This is necessary because being too "smart" 356 * about what the user might want leads to complications. 357 * (eg. given no slice or partition value, with a disk that is 358 * sliced - are they after the first BSD slice, or the DOS 359 * slice before it?) 360 */ 361static int 362bd_open(struct open_file *f, ...) 363{ 364 struct disk_devdesc *dev, rdev; 365 int err, g_err; 366 va_list ap; 367 368 va_start(ap, f); 369 dev = va_arg(ap, struct disk_devdesc *); 370 va_end(ap); 371 372 if (dev->d_unit < 0 || dev->d_unit >= nbdinfo) 373 return (EIO); 374 BD(dev).bd_open++; 375 if (BD(dev).bd_bcache == NULL) 376 BD(dev).bd_bcache = bcache_allocate(); 377 err = disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize, 378 BD(dev).bd_sectorsize, (BD(dev).bd_flags & BD_FLOPPY) ? 379 DISK_F_NOCACHE: 0); 380 381#ifdef LOADER_GELI_SUPPORT 382 static char gelipw[GELI_PW_MAXLEN]; 383 char *passphrase; 384 385 if (err) 386 return (err); 387 388 /* if we already know there is no GELI, skip the rest */ 389 if (geli_status[dev->d_unit][dev->d_slice] != ISGELI_UNKNOWN) 390 return (err); 391 392 struct dsk dskp; 393 struct ptable *table = NULL; 394 struct ptable_entry part; 395 struct pentry *entry; 396 int geli_part = 0; 397 398 dskp.drive = bd_unit2bios(dev->d_unit); 399 dskp.type = dev->d_type; 400 dskp.unit = dev->d_unit; 401 dskp.slice = dev->d_slice; 402 dskp.part = dev->d_partition; 403 dskp.start = dev->d_offset; 404 405 memcpy(&rdev, dev, sizeof(rdev)); 406 /* to read the GPT table, we need to read the first sector */ 407 rdev.d_offset = 0; 408 /* We need the LBA of the end of the partition */ 409 table = ptable_open(&rdev, BD(dev).bd_sectors, 410 BD(dev).bd_sectorsize, ptblread); 411 if (table == NULL) { 412 DEBUG("Can't read partition table"); 413 /* soft failure, return the exit status of disk_open */ 414 return (err); 415 } 416 417 if (table->type == PTABLE_GPT) 418 dskp.part = 255; 419 420 STAILQ_FOREACH(entry, &table->entries, entry) { 421 dskp.slice = entry->part.index; 422 dskp.start = entry->part.start; 423 if (is_geli(&dskp) == 0) { 424 geli_status[dev->d_unit][dskp.slice] = ISGELI_YES; 425 return (0); 426 } 427 if (geli_taste(bios_read, &dskp, 428 entry->part.end - entry->part.start) == 0) { 429 if ((passphrase = getenv("kern.geom.eli.passphrase")) 430 != NULL) { 431 /* Use the cached passphrase */ 432 bcopy(passphrase, &gelipw, GELI_PW_MAXLEN); 433 } 434 if (geli_passphrase(&gelipw, dskp.unit, 'p', 435 (dskp.slice > 0 ? dskp.slice : dskp.part), 436 &dskp) == 0) { 437 setenv("kern.geom.eli.passphrase", &gelipw, 1); 438 bzero(gelipw, sizeof(gelipw)); 439 geli_status[dev->d_unit][dskp.slice] = ISGELI_YES; 440 geli_part++; 441 } 442 } else 443 geli_status[dev->d_unit][dskp.slice] = ISGELI_NO; 444 } 445 446 /* none of the partitions on this disk have GELI */ 447 if (geli_part == 0) { 448 /* found no GELI */ 449 geli_status[dev->d_unit][dev->d_slice] = ISGELI_NO; 450 } 451#endif /* LOADER_GELI_SUPPORT */ 452 453 return (err); 454} 455 456static int 457bd_close(struct open_file *f) 458{ 459 struct disk_devdesc *dev; 460 461 dev = (struct disk_devdesc *)f->f_devdata; 462 BD(dev).bd_open--; 463 if (BD(dev).bd_open == 0) { 464 bcache_free(BD(dev).bd_bcache); 465 BD(dev).bd_bcache = NULL; 466 } 467 return (disk_close(dev)); 468} 469 470static int 471bd_ioctl(struct open_file *f, u_long cmd, void *data) 472{ 473 struct disk_devdesc *dev; 474 475 dev = (struct disk_devdesc *)f->f_devdata; 476 switch (cmd) { 477 case DIOCGSECTORSIZE: 478 *(u_int *)data = BD(dev).bd_sectorsize; 479 break; 480 case DIOCGMEDIASIZE: 481 *(off_t *)data = BD(dev).bd_sectors * BD(dev).bd_sectorsize; 482 break; 483 default: 484 return (ENOTTY); 485 } 486 return (0); 487} 488 489static int 490bd_strategy(void *devdata, int rw, daddr_t dblk, size_t size, 491 char *buf, size_t *rsize) 492{ 493 struct bcache_devdata bcd; 494 struct disk_devdesc *dev; 495 496 dev = (struct disk_devdesc *)devdata; 497 bcd.dv_strategy = bd_realstrategy; 498 bcd.dv_devdata = devdata; 499 bcd.dv_cache = BD(dev).bd_bcache; 500 return (bcache_strategy(&bcd, rw, dblk + dev->d_offset, 501 size, buf, rsize)); 502} 503 504static int 505bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size, 506 char *buf, size_t *rsize) 507{ 508 struct disk_devdesc *dev = (struct disk_devdesc *)devdata; 509 int blks, remaining; 510#ifdef BD_SUPPORT_FRAGS /* XXX: sector size */ 511 char fragbuf[BIOSDISK_SECSIZE]; 512 size_t fragsize; 513 514 fragsize = size % BIOSDISK_SECSIZE; 515#else 516 if (size % BD(dev).bd_sectorsize) 517 panic("bd_strategy: %d bytes I/O not multiple of block size", size); 518#endif 519 520 DEBUG("open_disk %p", dev); 521 blks = size / BD(dev).bd_sectorsize; 522 if (rsize) 523 *rsize = 0; 524 525 /* 526 * Perform partial read to prevent read-ahead crossing 527 * the end of disk - or any 32 bit aliases of the end. 528 * Signed arithmetic is used to handle wrap-around cases 529 * like we do for TCP sequence numbers. 530 */ 531 remaining = (int)(BD(dev).bd_sectors - dblk); /* truncate */ 532 if (remaining > 0 && remaining < blks) { 533 blks = remaining; 534 size = blks * BD(dev).bd_sectorsize; 535 DEBUG("short read %d", blks); 536 } 537 538 switch(rw){ 539 case F_READ: 540 DEBUG("read %d from %lld to %p", blks, dblk, buf); 541 542 if (blks && bd_read(dev, dblk, blks, buf)) { 543 DEBUG("read error"); 544 return (EIO); 545 } 546#ifdef BD_SUPPORT_FRAGS /* XXX: sector size */ 547 DEBUG("bd_strategy: frag read %d from %d+%d to %p", 548 fragsize, dblk, blks, buf + (blks * BIOSDISK_SECSIZE)); 549 if (fragsize && bd_read(od, dblk + blks, 1, fragsize)) { 550 DEBUG("frag read error"); 551 return(EIO); 552 } 553 bcopy(fragbuf, buf + (blks * BIOSDISK_SECSIZE), fragsize); 554#endif 555 break; 556 case F_WRITE : 557 DEBUG("write %d from %d to %p", blks, dblk, buf); 558 559 if (blks && bd_write(dev, dblk, blks, buf)) { 560 DEBUG("write error"); 561 return (EIO); 562 } 563#ifdef BD_SUPPORT_FRAGS 564 if(fragsize) { 565 DEBUG("Attempted to write a frag"); 566 return (EIO); 567 } 568#endif 569 break; 570 default: 571 /* DO NOTHING */ 572 return (EROFS); 573 } 574 575 if (rsize) 576 *rsize = size; 577 return (0); 578} 579 580/* Max number of sectors to bounce-buffer if the request crosses a 64k boundary */ 581#define FLOPPY_BOUNCEBUF 18 582 583static int 584bd_edd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest, 585 int write) 586{ 587 static struct edd_packet packet; 588 589 packet.len = sizeof(struct edd_packet); 590 packet.count = blks; 591 packet.off = VTOPOFF(dest); 592 packet.seg = VTOPSEG(dest); 593 packet.lba = dblk; 594 v86.ctl = V86_FLAGS; 595 v86.addr = 0x13; 596 if (write) 597 /* Should we Write with verify ?? 0x4302 ? */ 598 v86.eax = 0x4300; 599 else 600 v86.eax = 0x4200; 601 v86.edx = BD(dev).bd_unit; 602 v86.ds = VTOPSEG(&packet); 603 v86.esi = VTOPOFF(&packet); 604 v86int(); 605 return (V86_CY(v86.efl)); 606} 607 608static int 609bd_chs_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest, 610 int write) 611{ 612 u_int x, bpc, cyl, hd, sec; 613 614 bpc = BD(dev).bd_sec * BD(dev).bd_hds; /* blocks per cylinder */ 615 x = dblk; 616 cyl = x / bpc; /* block # / blocks per cylinder */ 617 x %= bpc; /* block offset into cylinder */ 618 hd = x / BD(dev).bd_sec; /* offset / blocks per track */ 619 sec = x % BD(dev).bd_sec; /* offset into track */ 620 621 /* correct sector number for 1-based BIOS numbering */ 622 sec++; 623 624 if (cyl > 1023) 625 /* CHS doesn't support cylinders > 1023. */ 626 return (1); 627 628 v86.ctl = V86_FLAGS; 629 v86.addr = 0x13; 630 if (write) 631 v86.eax = 0x300 | blks; 632 else 633 v86.eax = 0x200 | blks; 634 v86.ecx = ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec; 635 v86.edx = (hd << 8) | BD(dev).bd_unit; 636 v86.es = VTOPSEG(dest); 637 v86.ebx = VTOPOFF(dest); 638 v86int(); 639 return (V86_CY(v86.efl)); 640} 641 642static int 643bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest, int write) 644{ 645 u_int x, sec, result, resid, retry, maxfer; 646 caddr_t p, xp, bbuf, breg; 647 648 /* Just in case some idiot actually tries to read/write -1 blocks... */ 649 if (blks < 0) 650 return (-1); 651 652 resid = blks; 653 p = dest; 654 655 /* Decide whether we have to bounce */ 656 if (VTOP(dest) >> 20 != 0 || (BD(dev).bd_unit < 0x80 && 657 (VTOP(dest) >> 16) != (VTOP(dest + 658 blks * BD(dev).bd_sectorsize) >> 16))) { 659 660 /* 661 * There is a 64k physical boundary somewhere in the 662 * destination buffer, or the destination buffer is above 663 * first 1MB of physical memory so we have to arrange a 664 * suitable bounce buffer. Allocate a buffer twice as large 665 * as we need to. Use the bottom half unless there is a break 666 * there, in which case we use the top half. 667 */ 668 x = min(FLOPPY_BOUNCEBUF, (unsigned)blks); 669 bbuf = alloca(x * 2 * BD(dev).bd_sectorsize); 670 if (((u_int32_t)VTOP(bbuf) & 0xffff0000) == 671 ((u_int32_t)VTOP(bbuf + x * BD(dev).bd_sectorsize) & 0xffff0000)) { 672 breg = bbuf; 673 } else { 674 breg = bbuf + x * BD(dev).bd_sectorsize; 675 } 676 maxfer = x; /* limit transfers to bounce region size */ 677 } else { 678 breg = bbuf = NULL; 679 maxfer = 0; 680 } 681 682 while (resid > 0) { 683 /* 684 * Play it safe and don't cross track boundaries. 685 * (XXX this is probably unnecessary) 686 */ 687 sec = dblk % BD(dev).bd_sec; /* offset into track */ 688 x = min(BD(dev).bd_sec - sec, resid); 689 if (maxfer > 0) 690 x = min(x, maxfer); /* fit bounce buffer */ 691 692 /* where do we transfer to? */ 693 xp = bbuf == NULL ? p : breg; 694 695 /* 696 * Put your Data In, Put your Data out, 697 * Put your Data In, and shake it all about 698 */ 699 if (write && bbuf != NULL) 700 bcopy(p, breg, x * BD(dev).bd_sectorsize); 701 702 /* 703 * Loop retrying the operation a couple of times. The BIOS 704 * may also retry. 705 */ 706 for (retry = 0; retry < 3; retry++) { 707 /* if retrying, reset the drive */ 708 if (retry > 0) { 709 v86.ctl = V86_FLAGS; 710 v86.addr = 0x13; 711 v86.eax = 0; 712 v86.edx = BD(dev).bd_unit; 713 v86int(); 714 } 715 716 if (BD(dev).bd_flags & BD_MODEEDD1) 717 result = bd_edd_io(dev, dblk, x, xp, write); 718 else 719 result = bd_chs_io(dev, dblk, x, xp, write); 720 if (result == 0) 721 break; 722 } 723 724 if (write) 725 DEBUG("Write %d sector(s) from %p (0x%x) to %lld %s", x, 726 p, VTOP(p), dblk, result ? "failed" : "ok"); 727 else 728 DEBUG("Read %d sector(s) from %lld to %p (0x%x) %s", x, 729 dblk, p, VTOP(p), result ? "failed" : "ok"); 730 if (result) { 731 return(-1); 732 } 733 if (!write && bbuf != NULL) 734 bcopy(breg, p, x * BD(dev).bd_sectorsize); 735 p += (x * BD(dev).bd_sectorsize); 736 dblk += x; 737 resid -= x; 738 } 739 740/* hexdump(dest, (blks * BD(dev).bd_sectorsize)); */ 741 return(0); 742} 743 744static int 745bd_read(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest) 746{ 747#ifdef LOADER_GELI_SUPPORT 748 struct dsk dskp; 749 off_t p_off, diff; 750 daddr_t alignlba; 751 int err, n, alignblks; 752 char *tmpbuf; 753 754 /* if we already know there is no GELI, skip the rest */ 755 if (geli_status[dev->d_unit][dev->d_slice] != ISGELI_YES) 756 return (bd_io(dev, dblk, blks, dest, 0)); 757 758 if (geli_status[dev->d_unit][dev->d_slice] == ISGELI_YES) { 759 /* 760 * Align reads to DEV_GELIBOOT_BSIZE bytes because partial 761 * sectors cannot be decrypted. Round the requested LBA down to 762 * nearest multiple of DEV_GELIBOOT_BSIZE bytes. 763 */ 764 alignlba = rounddown2(dblk * BD(dev).bd_sectorsize, 765 DEV_GELIBOOT_BSIZE) / BD(dev).bd_sectorsize; 766 /* 767 * Round number of blocks to read up to nearest multiple of 768 * DEV_GELIBOOT_BSIZE 769 */ 770 diff = (dblk - alignlba) * BD(dev).bd_sectorsize; 771 alignblks = roundup2(blks * BD(dev).bd_sectorsize + diff, 772 DEV_GELIBOOT_BSIZE) / BD(dev).bd_sectorsize; 773 774 /* 775 * If the read is rounded up to a larger size, use a temporary 776 * buffer here because the buffer provided by the caller may be 777 * too small. 778 */ 779 if (diff == 0) { 780 tmpbuf = dest; 781 } else { 782 tmpbuf = malloc(alignblks * BD(dev).bd_sectorsize); 783 if (tmpbuf == NULL) { 784 return (-1); 785 } 786 } 787 788 err = bd_io(dev, alignlba, alignblks, tmpbuf, 0); 789 if (err) 790 return (err); 791 792 dskp.drive = bd_unit2bios(dev->d_unit); 793 dskp.type = dev->d_type; 794 dskp.unit = dev->d_unit; 795 dskp.slice = dev->d_slice; 796 dskp.part = dev->d_partition; 797 dskp.start = dev->d_offset; 798 799 /* GELI needs the offset relative to the partition start */ 800 p_off = alignlba - dskp.start; 801 802 err = geli_read(&dskp, p_off * BD(dev).bd_sectorsize, tmpbuf, 803 alignblks * BD(dev).bd_sectorsize); 804 if (err) 805 return (err); 806 807 if (tmpbuf != dest) { 808 bcopy(tmpbuf + diff, dest, blks * BD(dev).bd_sectorsize); 809 free(tmpbuf); 810 } 811 return (0); 812 } 813#endif /* LOADER_GELI_SUPPORT */ 814 815 return (bd_io(dev, dblk, blks, dest, 0)); 816} 817 818static int 819bd_write(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest) 820{ 821 822 return (bd_io(dev, dblk, blks, dest, 1)); 823} 824 825/* 826 * Return the BIOS geometry of a given "fixed drive" in a format 827 * suitable for the legacy bootinfo structure. Since the kernel is 828 * expecting raw int 0x13/0x8 values for N_BIOS_GEOM drives, we 829 * prefer to get the information directly, rather than rely on being 830 * able to put it together from information already maintained for 831 * different purposes and for a probably different number of drives. 832 * 833 * For valid drives, the geometry is expected in the format (31..0) 834 * "000000cc cccccccc hhhhhhhh 00ssssss"; and invalid drives are 835 * indicated by returning the geometry of a "1.2M" PC-format floppy 836 * disk. And, incidentally, what is returned is not the geometry as 837 * such but the highest valid cylinder, head, and sector numbers. 838 */ 839u_int32_t 840bd_getbigeom(int bunit) 841{ 842 843 v86.ctl = V86_FLAGS; 844 v86.addr = 0x13; 845 v86.eax = 0x800; 846 v86.edx = 0x80 + bunit; 847 v86int(); 848 if (V86_CY(v86.efl)) 849 return 0x4f010f; 850 return ((v86.ecx & 0xc0) << 18) | ((v86.ecx & 0xff00) << 8) | 851 (v86.edx & 0xff00) | (v86.ecx & 0x3f); 852} 853 854/* 855 * Return a suitable dev_t value for (dev). 856 * 857 * In the case where it looks like (dev) is a SCSI disk, we allow the number of 858 * IDE disks to be specified in $num_ide_disks. There should be a Better Way. 859 */ 860int 861bd_getdev(struct i386_devdesc *d) 862{ 863 struct disk_devdesc *dev; 864 int biosdev; 865 int major; 866 int rootdev; 867 char *nip, *cp; 868 int i, unit; 869 870 dev = (struct disk_devdesc *)d; 871 biosdev = bd_unit2bios(dev->d_unit); 872 DEBUG("unit %d BIOS device %d", dev->d_unit, biosdev); 873 if (biosdev == -1) /* not a BIOS device */ 874 return(-1); 875 if (disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize, 876 BD(dev).bd_sectorsize,(BD(dev).bd_flags & BD_FLOPPY) ? 877 DISK_F_NOCACHE: 0) != 0) /* oops, not a viable device */ 878 return (-1); 879 else 880 disk_close(dev); 881 882 if (biosdev < 0x80) { 883 /* floppy (or emulated floppy) or ATAPI device */ 884 if (bdinfo[dev->d_unit].bd_type == DT_ATAPI) { 885 /* is an ATAPI disk */ 886 major = WFDMAJOR; 887 } else { 888 /* is a floppy disk */ 889 major = FDMAJOR; 890 } 891 } else { 892 /* assume an IDE disk */ 893 major = WDMAJOR; 894 } 895 /* default root disk unit number */ 896 unit = biosdev & 0x7f; 897 898 /* XXX a better kludge to set the root disk unit number */ 899 if ((nip = getenv("root_disk_unit")) != NULL) { 900 i = strtol(nip, &cp, 0); 901 /* check for parse error */ 902 if ((cp != nip) && (*cp == 0)) 903 unit = i; 904 } 905 906 rootdev = MAKEBOOTDEV(major, dev->d_slice + 1, unit, dev->d_partition); 907 DEBUG("dev is 0x%x\n", rootdev); 908 return(rootdev); 909} 910 911#ifdef LOADER_GELI_SUPPORT 912int 913bios_read(void *vdev __unused, struct dsk *priv, off_t off, char *buf, size_t bytes) 914{ 915 struct disk_devdesc dev; 916 917 dev.d_dev = &biosdisk; 918 dev.d_type = priv->type; 919 dev.d_unit = priv->unit; 920 dev.d_slice = priv->slice; 921 dev.d_partition = priv->part; 922 dev.d_offset = priv->start; 923 924 off = off / BD(&dev).bd_sectorsize; 925 /* GELI gives us the offset relative to the partition start */ 926 off += dev.d_offset; 927 bytes = bytes / BD(&dev).bd_sectorsize; 928 929 return (bd_io(&dev, off, bytes, buf, 0)); 930} 931#endif /* LOADER_GELI_SUPPORT */
|