1 /*- 2 * Copyright (c) 1998 Robert Nordier 3 * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms are freely 7 * permitted provided that the above copyright notice and this 8 * paragraph and the following disclaimer are duplicated in all 9 * such forms. 10 * 11 * This software is provided "AS IS" and without any express or 12 * implied warranties, including, without limitation, the implied 13 * warranties of merchantability and fitness for a particular 14 * purpose. 15 */ 16 17 #include <sys/cdefs.h> 18 __FBSDID("$FreeBSD$"); 19 20 #include <sys/param.h> 21 22 #include <btxv86.h> 23 24 #include "stand.h" 25 #include "rbx.h" 26 #include "drv.h" 27 #include "edd.h" 28 29 static struct edd_params params; 30 31 uint64_t 32 drvsize(struct dsk *dskp) 33 { 34 35 params.len = sizeof(struct edd_params); 36 v86.ctl = V86_FLAGS; 37 v86.addr = 0x13; 38 v86.eax = 0x4800; 39 v86.edx = dskp->drive; 40 v86.ds = VTOPSEG(¶ms); 41 v86.esi = VTOPOFF(¶ms); 42 v86int(); 43 if (V86_CY(v86.efl)) { 44 printf("error %u\n", v86.eax >> 8 & 0xff); 45 return (0); 46 } 47 return (params.sectors); 48 } 49 50 static struct edd_packet packet; 51 52 int 53 drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk) 54 { 55 static unsigned c = 0x2d5c7c2f; 56 57 if (!OPT_CHECK(RBX_QUIET)) 58 printf("%c\b", c = c << 8 | c >> 24); 59 packet.len = sizeof(struct edd_packet); 60 packet.count = nblk; 61 packet.off = VTOPOFF(buf); 62 packet.seg = VTOPSEG(buf); 63 packet.lba = lba; 64 v86.ctl = V86_FLAGS; 65 v86.addr = 0x13; 66 v86.eax = 0x4200; 67 v86.edx = dskp->drive; 68 v86.ds = VTOPSEG(&packet); 69 v86.esi = VTOPOFF(&packet); 70 v86int(); 71 if (V86_CY(v86.efl)) { 72 printf("%s: error %u lba %llu\n", 73 BOOTPROG, v86.eax >> 8 & 0xff, lba); 74 return (-1); 75 } 76 return (0); 77 } 78 79 #if defined(GPT) || defined(ZFS) 80 int 81 drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk) 82 { 83 84 packet.len = sizeof(struct edd_packet); 85 packet.count = nblk; 86 packet.off = VTOPOFF(buf); 87 packet.seg = VTOPSEG(buf); 88 packet.lba = lba; 89 v86.ctl = V86_FLAGS; 90 v86.addr = 0x13; 91 v86.eax = 0x4300; 92 v86.edx = dskp->drive; 93 v86.ds = VTOPSEG(&packet); 94 v86.esi = VTOPOFF(&packet); 95 v86int(); 96 if (V86_CY(v86.efl)) { 97 printf("error %u lba %llu\n", v86.eax >> 8 & 0xff, lba); 98 return (-1); 99 } 100 return (0); 101 } 102 #endif /* GPT || ZFS */ 103