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 | } |