| File: | src/sys/arch/amd64/stand/efiboot/bootia32/../diskprobe.c |
| Warning: | line 79, column 2 Value stored to 'n' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* $OpenBSD: diskprobe.c,v 1.2 2020/12/09 18:10:18 krw Exp $ */ |
| 2 | |
| 3 | /* |
| 4 | * Copyright (c) 1997 Tobias Weingartner |
| 5 | * All rights reserved. |
| 6 | * |
| 7 | * Redistribution and use in source and binary forms, with or without |
| 8 | * modification, are permitted provided that the following conditions |
| 9 | * are met: |
| 10 | * 1. Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. |
| 15 | * |
| 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
| 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
| 20 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 21 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 22 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 26 | * SUCH DAMAGE. |
| 27 | * |
| 28 | */ |
| 29 | |
| 30 | /* We want the disk type names from disklabel.h */ |
| 31 | #undef DKTYPENAMES |
| 32 | |
| 33 | #include <sys/param.h> |
| 34 | #include <sys/queue.h> |
| 35 | #include <sys/reboot.h> |
| 36 | #include <sys/disklabel.h> |
| 37 | #include <sys/hibernate.h> |
| 38 | |
| 39 | #include <lib/libz/zlib.h> |
| 40 | #include <machine/biosvar.h> |
| 41 | #include <stand/boot/bootarg.h> |
| 42 | |
| 43 | #include "disk.h" |
| 44 | #include "biosdev.h" |
| 45 | #include "libsa.h" |
| 46 | |
| 47 | #ifdef SOFTRAID1 |
| 48 | #include "softraid_amd64.h" |
| 49 | #endif |
| 50 | #include "efidev.h" |
| 51 | |
| 52 | #define MAX_CKSUMLEN(64 * 1024) / (1 << 9) MAXBSIZE(64 * 1024) / DEV_BSIZE(1 << 9) /* Max # of blks to cksum */ |
| 53 | |
| 54 | /* Local Prototypes */ |
| 55 | static int disksum(int); |
| 56 | |
| 57 | int bootdev_has_hibernate(void); /* export for loadfile() */ |
| 58 | |
| 59 | /* List of disk devices we found/probed */ |
| 60 | struct disklist_lh disklist; |
| 61 | |
| 62 | /* Pointer to boot device */ |
| 63 | struct diskinfo *bootdev_dip; |
| 64 | |
| 65 | extern int debug; |
| 66 | extern int bios_bootdev; |
| 67 | extern int bios_cddev; |
| 68 | |
| 69 | static void |
| 70 | efi_hardprobe(void) |
| 71 | { |
| 72 | int n; |
| 73 | struct diskinfo *dip, *dipt; |
| 74 | u_int bsdunit, type = 0; |
| 75 | u_int scsi= 0, ide = 0, atapi = 0; |
| 76 | extern struct disklist_lh |
| 77 | efi_disklist; |
| 78 | |
| 79 | n = 0; |
Value stored to 'n' is never read | |
| 80 | TAILQ_FOREACH_SAFE(dip, &efi_disklist, list, dipt)for ((dip) = ((&efi_disklist)->tqh_first); (dip) != (( void *)0) && ((dipt) = ((dip)->list.tqe_next), 1); (dip) = (dipt)) { |
| 81 | TAILQ_REMOVE(&efi_disklist, dip, list)do { if (((dip)->list.tqe_next) != ((void *)0)) (dip)-> list.tqe_next->list.tqe_prev = (dip)->list.tqe_prev; else (&efi_disklist)->tqh_last = (dip)->list.tqe_prev; * (dip)->list.tqe_prev = (dip)->list.tqe_next; ; ; } while (0); |
| 82 | n = scsi + ide; |
| 83 | |
| 84 | /* Try to find the label, to figure out device type */ |
| 85 | if ((efi_getdisklabel(dip->efi_info, &dip->disklabel))) { |
| 86 | type = 0; |
| 87 | printf(" hd%d*", n); |
| 88 | bsdunit = ide++; |
| 89 | } else { |
| 90 | /* Best guess */ |
| 91 | switch (dip->disklabel.d_type) { |
| 92 | case DTYPE_SCSI4: |
| 93 | type = 4; |
| 94 | bsdunit = scsi++; |
| 95 | dip->bios_info.flags |= BDI_GOODLABEL0x00000002; |
| 96 | break; |
| 97 | |
| 98 | case DTYPE_ESDI5: |
| 99 | case DTYPE_ST5066: |
| 100 | type = 0; |
| 101 | bsdunit = ide++; |
| 102 | dip->bios_info.flags |= BDI_GOODLABEL0x00000002; |
| 103 | break; |
| 104 | |
| 105 | case DTYPE_ATAPI13: |
| 106 | type = 6; |
| 107 | n = atapi; |
| 108 | bsdunit = atapi++; |
| 109 | dip->bios_info.flags |= BDI_GOODLABEL0x00000002 |
| 110 | | BDI_EL_TORITO0x00000008; |
| 111 | break; |
| 112 | |
| 113 | default: |
| 114 | dip->bios_info.flags |= BDI_BADLABEL0x00000004; |
| 115 | type = 0; /* XXX Suggest IDE */ |
| 116 | bsdunit = ide++; |
| 117 | } |
| 118 | printf(" %cd%d", (type == 6)? 'c' : 'h', n); |
| 119 | } |
| 120 | if (type != 6) |
| 121 | dip->bios_info.bios_number = 0x80 | n; |
| 122 | else |
| 123 | dip->bios_info.bios_number = 0xe0 | n; |
| 124 | |
| 125 | dip->bios_info.checksum = 0; /* just in case */ |
| 126 | /* Fill out best we can */ |
| 127 | dip->bsddev = dip->bios_info.bsd_dev = |
| 128 | MAKEBOOTDEV(type, 0, 0, bsdunit, RAW_PART)(((type) << 0) | ((0) << 24) | ((0) << 20) | ((bsdunit) << 16) | ((2) << 8) | 0xa0000000); |
| 129 | check_hibernate(dip); |
| 130 | |
| 131 | /* Add to queue of disks */ |
| 132 | TAILQ_INSERT_TAIL(&disklist, dip, list)do { (dip)->list.tqe_next = ((void *)0); (dip)->list.tqe_prev = (&disklist)->tqh_last; *(&disklist)->tqh_last = (dip); (&disklist)->tqh_last = &(dip)->list. tqe_next; } while (0); |
| 133 | n++; |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | /* Probe for all BIOS supported disks */ |
| 138 | u_int32_t bios_cksumlen; |
| 139 | void |
| 140 | diskprobe(void) |
| 141 | { |
| 142 | struct diskinfo *dip; |
| 143 | int i; |
| 144 | |
| 145 | /* These get passed to kernel */ |
| 146 | bios_diskinfo_t *bios_diskinfo; |
| 147 | |
| 148 | /* Init stuff */ |
| 149 | TAILQ_INIT(&disklist)do { (&disklist)->tqh_first = ((void *)0); (&disklist )->tqh_last = &(&disklist)->tqh_first; } while ( 0); |
| 150 | |
| 151 | efi_hardprobe(); |
| 152 | |
| 153 | #ifdef SOFTRAID1 |
| 154 | srprobe(); |
| 155 | #endif |
| 156 | |
| 157 | /* Checksumming of hard disks */ |
| 158 | for (i = 0; disksum(i++) && i < MAX_CKSUMLEN(64 * 1024) / (1 << 9); ) |
| 159 | ; |
| 160 | bios_cksumlen = i; |
| 161 | |
| 162 | /* Get space for passing bios_diskinfo stuff to kernel */ |
| 163 | for (i = 0, dip = TAILQ_FIRST(&disklist)((&disklist)->tqh_first); dip; |
| 164 | dip = TAILQ_NEXT(dip, list)((dip)->list.tqe_next)) |
| 165 | i++; |
| 166 | bios_diskinfo = alloc(++i * sizeof(bios_diskinfo_t)); |
| 167 | |
| 168 | /* Copy out the bios_diskinfo stuff */ |
| 169 | for (i = 0, dip = TAILQ_FIRST(&disklist)((&disklist)->tqh_first); dip; |
| 170 | dip = TAILQ_NEXT(dip, list)((dip)->list.tqe_next)) |
| 171 | bios_diskinfo[i++] = dip->bios_info; |
| 172 | |
| 173 | bios_diskinfo[i++].bios_number = -1; |
| 174 | /* Register for kernel use */ |
| 175 | addbootarg(BOOTARG_CKSUMLEN3, sizeof(u_int32_t), &bios_cksumlen); |
| 176 | addbootarg(BOOTARG_DISKINFO1, i * sizeof(bios_diskinfo_t), |
| 177 | bios_diskinfo); |
| 178 | } |
| 179 | |
| 180 | /* Find info on given BIOS disk */ |
| 181 | struct diskinfo * |
| 182 | dklookup(int dev) |
| 183 | { |
| 184 | struct diskinfo *dip; |
| 185 | |
| 186 | for (dip = TAILQ_FIRST(&disklist)((&disklist)->tqh_first); dip; dip = TAILQ_NEXT(dip, list)((dip)->list.tqe_next)) |
| 187 | if (dip->bios_info.bios_number == dev) |
| 188 | return dip; |
| 189 | |
| 190 | return NULL((void *)0); |
| 191 | } |
| 192 | |
| 193 | void |
| 194 | dump_diskinfo(void) |
| 195 | { |
| 196 | struct diskinfo *dip; |
| 197 | |
| 198 | printf("Disk\tBIOS#\tType\tCyls\tHeads\tSecs\tFlags\tChecksum\n"); |
| 199 | for (dip = TAILQ_FIRST(&disklist)((&disklist)->tqh_first); dip; dip = TAILQ_NEXT(dip, list)((dip)->list.tqe_next)) { |
| 200 | bios_diskinfo_t *bdi = &dip->bios_info; |
| 201 | int d = bdi->bios_number; |
| 202 | int u = d & 0x7f; |
| 203 | char c; |
| 204 | |
| 205 | if (bdi->flags & BDI_EL_TORITO0x00000008) { |
| 206 | c = 'c'; |
| 207 | u = 0; |
| 208 | } else { |
| 209 | c = (d & 0x80) ? 'h' : 'f'; |
| 210 | } |
| 211 | |
| 212 | printf("%cd%d\t0x%x\t%s\t%d\t%d\t%d\t0x%x\t0x%x\n", |
| 213 | c, u, d, |
| 214 | (bdi->flags & BDI_BADLABEL0x00000004)?"*none*":"label", |
| 215 | bdi->bios_cylinders, bdi->bios_heads, bdi->bios_sectors, |
| 216 | bdi->flags, bdi->checksum); |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | /* Find BIOS portion on given BIOS disk |
| 221 | * XXX - Use dklookup() instead. |
| 222 | */ |
| 223 | bios_diskinfo_t * |
| 224 | bios_dklookup(int dev) |
| 225 | { |
| 226 | struct diskinfo *dip; |
| 227 | |
| 228 | dip = dklookup(dev); |
| 229 | if (dip) |
| 230 | return &dip->bios_info; |
| 231 | |
| 232 | return NULL((void *)0); |
| 233 | } |
| 234 | |
| 235 | /* |
| 236 | * Checksum one more block on all harddrives |
| 237 | * |
| 238 | * Use the adler32() function from libz, |
| 239 | * as it is quick, small, and available. |
| 240 | */ |
| 241 | int |
| 242 | disksum(int blk) |
| 243 | { |
| 244 | struct diskinfo *dip, *dip2; |
| 245 | int st, reprobe = 0; |
| 246 | char buf[DEV_BSIZE(1 << 9)]; |
| 247 | |
| 248 | for (dip = TAILQ_FIRST(&disklist)((&disklist)->tqh_first); dip; dip = TAILQ_NEXT(dip, list)((dip)->list.tqe_next)) { |
| 249 | bios_diskinfo_t *bdi = &dip->bios_info; |
| 250 | |
| 251 | /* Skip this disk if it is not a HD or has had an I/O error */ |
| 252 | if (!(bdi->bios_number & 0x80) || bdi->flags & BDI_INVALID0x00000001) |
| 253 | continue; |
| 254 | |
| 255 | /* Adler32 checksum */ |
| 256 | st = dip->diskio(F_READ0x0001, dip, blk, 1, buf); |
| 257 | if (st) { |
| 258 | bdi->flags |= BDI_INVALID0x00000001; |
| 259 | continue; |
| 260 | } |
| 261 | bdi->checksum = adler32(bdi->checksum, buf, DEV_BSIZE(1 << 9)); |
| 262 | |
| 263 | for (dip2 = TAILQ_FIRST(&disklist)((&disklist)->tqh_first); dip2 != dip; |
| 264 | dip2 = TAILQ_NEXT(dip2, list)((dip2)->list.tqe_next)) { |
| 265 | bios_diskinfo_t *bd = &dip2->bios_info; |
| 266 | if ((bd->bios_number & 0x80) && |
| 267 | !(bd->flags & BDI_INVALID0x00000001) && |
| 268 | bdi->checksum == bd->checksum) |
| 269 | reprobe = 1; |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | return reprobe; |
| 274 | } |
| 275 | |
| 276 | int |
| 277 | bootdev_has_hibernate(void) |
| 278 | { |
| 279 | return ((bootdev_dip->bios_info.flags & BDI_HIBVALID0x00000010)? 1 : 0); |
| 280 | } |
| 281 | |
| 282 | void |
| 283 | check_hibernate(struct diskinfo *dip) |
| 284 | { |
| 285 | daddr_t sec; |
| 286 | int error; |
| 287 | union hibernate_info hib; |
| 288 | |
| 289 | /* read hibernate */ |
| 290 | if (dip->disklabel.d_partitions[1].p_fstype != FS_SWAP1 || |
| 291 | DL_GETPSIZE(&dip->disklabel.d_partitions[1])(((u_int64_t)(&dip->disklabel.d_partitions[1])->p_sizeh << 32) + (&dip->disklabel.d_partitions[1])-> p_size) == 0) |
| 292 | return; |
| 293 | |
| 294 | sec = DL_GETPOFFSET(&dip->disklabel.d_partitions[1])(((u_int64_t)(&dip->disklabel.d_partitions[1])->p_offseth << 32) + (&dip->disklabel.d_partitions[1])-> p_offset) + |
| 295 | DL_GETPSIZE(&dip->disklabel.d_partitions[1])(((u_int64_t)(&dip->disklabel.d_partitions[1])->p_sizeh << 32) + (&dip->disklabel.d_partitions[1])-> p_size) - |
| 296 | (sizeof(union hibernate_info) / DEV_BSIZE(1 << 9)); |
| 297 | |
| 298 | error = dip->strategy(dip, F_READ0x0001, sec, sizeof hib, &hib, NULL((void *)0)); |
| 299 | if (error == 0 && hib.magic == HIBERNATE_MAGIC0x0B5D0B5D) |
| 300 | dip->bios_info.flags |= BDI_HIBVALID0x00000010; /* Hibernate present */ |
| 301 | } |