diff options
Diffstat (limited to 'arch/i386/boot/edd.c')
| -rw-r--r-- | arch/i386/boot/edd.c | 54 |
1 files changed, 12 insertions, 42 deletions
diff --git a/arch/i386/boot/edd.c b/arch/i386/boot/edd.c index 658834d9f92a..82b5c846a194 100644 --- a/arch/i386/boot/edd.c +++ b/arch/i386/boot/edd.c | |||
| @@ -19,40 +19,12 @@ | |||
| 19 | 19 | ||
| 20 | #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) | 20 | #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) |
| 21 | 21 | ||
| 22 | struct edd_dapa { | ||
| 23 | u8 pkt_size; | ||
| 24 | u8 rsvd; | ||
| 25 | u16 sector_cnt; | ||
| 26 | u16 buf_off, buf_seg; | ||
| 27 | u64 lba; | ||
| 28 | u64 buf_lin_addr; | ||
| 29 | }; | ||
| 30 | |||
| 31 | /* | 22 | /* |
| 32 | * Read the MBR (first sector) from a specific device. | 23 | * Read the MBR (first sector) from a specific device. |
| 33 | */ | 24 | */ |
| 34 | static int read_mbr(u8 devno, void *buf) | 25 | static int read_mbr(u8 devno, void *buf) |
| 35 | { | 26 | { |
| 36 | struct edd_dapa dapa; | 27 | u16 ax, bx, cx, dx; |
| 37 | u16 ax, bx, cx, dx, si; | ||
| 38 | |||
| 39 | memset(&dapa, 0, sizeof dapa); | ||
| 40 | dapa.pkt_size = sizeof(dapa); | ||
| 41 | dapa.sector_cnt = 1; | ||
| 42 | dapa.buf_off = (size_t)buf; | ||
| 43 | dapa.buf_seg = ds(); | ||
| 44 | /* dapa.lba = 0; */ | ||
| 45 | |||
| 46 | ax = 0x4200; /* Extended Read */ | ||
| 47 | si = (size_t)&dapa; | ||
| 48 | dx = devno; | ||
| 49 | asm("pushfl; stc; int $0x13; setc %%al; popfl" | ||
| 50 | : "+a" (ax), "+S" (si), "+d" (dx) | ||
| 51 | : "m" (dapa) | ||
| 52 | : "ebx", "ecx", "edi", "memory"); | ||
| 53 | |||
| 54 | if (!(u8)ax) | ||
| 55 | return 0; /* OK */ | ||
| 56 | 28 | ||
| 57 | ax = 0x0201; /* Legacy Read, one sector */ | 29 | ax = 0x0201; /* Legacy Read, one sector */ |
| 58 | cx = 0x0001; /* Sector 0-0-1 */ | 30 | cx = 0x0001; /* Sector 0-0-1 */ |
| @@ -65,11 +37,10 @@ static int read_mbr(u8 devno, void *buf) | |||
| 65 | return -(u8)ax; /* 0 or -1 */ | 37 | return -(u8)ax; /* 0 or -1 */ |
| 66 | } | 38 | } |
| 67 | 39 | ||
| 68 | static u32 read_mbr_sig(u8 devno, struct edd_info *ei) | 40 | static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig) |
| 69 | { | 41 | { |
| 70 | int sector_size; | 42 | int sector_size; |
| 71 | char *mbrbuf_ptr, *mbrbuf_end; | 43 | char *mbrbuf_ptr, *mbrbuf_end; |
| 72 | u32 mbrsig; | ||
| 73 | u32 buf_base, mbr_base; | 44 | u32 buf_base, mbr_base; |
| 74 | extern char _end[]; | 45 | extern char _end[]; |
| 75 | 46 | ||
| @@ -85,15 +56,15 @@ static u32 read_mbr_sig(u8 devno, struct edd_info *ei) | |||
| 85 | 56 | ||
| 86 | /* Make sure we actually have space on the heap... */ | 57 | /* Make sure we actually have space on the heap... */ |
| 87 | if (!(boot_params.hdr.loadflags & CAN_USE_HEAP)) | 58 | if (!(boot_params.hdr.loadflags & CAN_USE_HEAP)) |
| 88 | return 0; | 59 | return -1; |
| 89 | if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr) | 60 | if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr) |
| 90 | return 0; | 61 | return -1; |
| 91 | 62 | ||
| 92 | if (read_mbr(devno, mbrbuf_ptr)) | 63 | if (read_mbr(devno, mbrbuf_ptr)) |
| 93 | return 0; | 64 | return -1; |
| 94 | 65 | ||
| 95 | mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET]; | 66 | *mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET]; |
| 96 | return mbrsig; | 67 | return 0; |
| 97 | } | 68 | } |
| 98 | 69 | ||
| 99 | static int get_edd_info(u8 devno, struct edd_info *ei) | 70 | static int get_edd_info(u8 devno, struct edd_info *ei) |
| @@ -160,6 +131,7 @@ void query_edd(void) | |||
| 160 | int do_edd = 1; | 131 | int do_edd = 1; |
| 161 | int devno; | 132 | int devno; |
| 162 | struct edd_info ei, *edp; | 133 | struct edd_info ei, *edp; |
| 134 | u32 *mbrptr; | ||
| 163 | 135 | ||
| 164 | if (cmdline_find_option("edd", eddarg, sizeof eddarg) > 0) { | 136 | if (cmdline_find_option("edd", eddarg, sizeof eddarg) > 0) { |
| 165 | if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip")) | 137 | if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip")) |
| @@ -168,7 +140,8 @@ void query_edd(void) | |||
| 168 | do_edd = 0; | 140 | do_edd = 0; |
| 169 | } | 141 | } |
| 170 | 142 | ||
| 171 | edp = (struct edd_info *)boot_params.eddbuf; | 143 | edp = boot_params.eddbuf; |
| 144 | mbrptr = boot_params.edd_mbr_sig_buffer; | ||
| 172 | 145 | ||
| 173 | if (!do_edd) | 146 | if (!do_edd) |
| 174 | return; | 147 | return; |
| @@ -186,11 +159,8 @@ void query_edd(void) | |||
| 186 | boot_params.eddbuf_entries++; | 159 | boot_params.eddbuf_entries++; |
| 187 | } | 160 | } |
| 188 | 161 | ||
| 189 | if (do_mbr) { | 162 | if (do_mbr && !read_mbr_sig(devno, &ei, mbrptr++)) |
| 190 | u32 mbr_sig; | 163 | boot_params.edd_mbr_sig_buf_entries = devno-0x80+1; |
| 191 | mbr_sig = read_mbr_sig(devno, &ei); | ||
| 192 | boot_params.edd_mbr_sig_buffer[devno-0x80] = mbr_sig; | ||
| 193 | } | ||
| 194 | } | 164 | } |
| 195 | } | 165 | } |
| 196 | 166 | ||
