This source file includes following definitions.
- floppyprobe
- hardprobe
- diskprobe
- cdprobe
- dklookup
- dump_diskinfo
- bios_dklookup
- disksum
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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 <stand/boot/bootarg.h>
38 #include <machine/biosvar.h>
39 #include <lib/libz/zlib.h>
40 #include "disk.h"
41 #include "biosdev.h"
42 #include "libsa.h"
43
44 #define MAX_CKSUMLEN MAXBSIZE / DEV_BSIZE
45
46
47 static int disksum(int);
48
49
50 struct disklist_lh disklist;
51
52
53 struct diskinfo *bootdev_dip;
54
55 extern int debug;
56 extern int bios_bootdev;
57 extern int bios_cddev;
58
59
60 static void
61 floppyprobe(void)
62 {
63 struct diskinfo *dip;
64 int i;
65
66
67 for (i = 0; i < 4; i++) {
68 dip = alloc(sizeof(struct diskinfo));
69 bzero(dip, sizeof(*dip));
70
71 if (bios_getdiskinfo(i, &dip->bios_info)) {
72 #ifdef BIOS_DEBUG
73 if (debug)
74 printf(" <!fd%u>", i);
75 #endif
76 free(dip, 0);
77 break;
78 }
79
80 printf(" fd%u", i);
81
82
83 dip->bios_info.bsd_dev = MAKEBOOTDEV(2, 0, 0, i, RAW_PART);
84
85
86
87
88
89
90
91 dip->bios_info.flags |= BDI_BADLABEL;
92
93
94 TAILQ_INSERT_TAIL(&disklist, dip, list);
95 }
96 }
97
98
99
100 static void
101 hardprobe(void)
102 {
103 struct diskinfo *dip;
104 int i;
105 u_int bsdunit, type;
106 u_int scsi = 0, ide = 0;
107 const char *dc = (const char *)((0x40 << 4) + 0x75);
108
109
110 for (i = 0x80; i < (0x80 + *dc); i++) {
111 dip = alloc(sizeof(struct diskinfo));
112 bzero(dip, sizeof(*dip));
113
114 if (bios_getdiskinfo(i, &dip->bios_info)) {
115 #ifdef BIOS_DEBUG
116 if (debug)
117 printf(" <!hd%u>", i&0x7f);
118 #endif
119 free(dip, 0);
120 break;
121 }
122
123 printf(" hd%u%s", i&0x7f, (dip->bios_info.bios_edd > 0?"+":""));
124
125
126 if ((bios_getdisklabel(&dip->bios_info, &dip->disklabel)) ) {
127 printf("*");
128 bsdunit = ide++;
129 type = 0;
130 } else {
131
132 switch (dip->disklabel.d_type) {
133 case DTYPE_SCSI:
134 type = 4;
135 bsdunit = scsi++;
136 dip->bios_info.flags |= BDI_GOODLABEL;
137 break;
138
139 case DTYPE_ESDI:
140 case DTYPE_ST506:
141 type = 0;
142 bsdunit = ide++;
143 dip->bios_info.flags |= BDI_GOODLABEL;
144 break;
145
146 default:
147 dip->bios_info.flags |= BDI_BADLABEL;
148 type = 0;
149 bsdunit = ide++;
150 }
151 }
152
153 dip->bios_info.checksum = 0;
154
155 dip->bios_info.bsd_dev =
156 MAKEBOOTDEV(type, 0, 0, bsdunit, RAW_PART);
157
158
159 TAILQ_INSERT_TAIL(&disklist, dip, list);
160 }
161 }
162
163
164
165 u_int32_t bios_cksumlen;
166 void
167 diskprobe(void)
168 {
169 struct diskinfo *dip;
170 int i;
171
172
173 bios_diskinfo_t *bios_diskinfo;
174
175
176 TAILQ_INIT(&disklist);
177
178
179 floppyprobe();
180 #ifdef BIOS_DEBUG
181 if (debug)
182 printf(";");
183 #endif
184 hardprobe();
185
186
187 for (i = 0; disksum(i++) && i < MAX_CKSUMLEN; )
188 ;
189 bios_cksumlen = i;
190
191
192 for (i = 0, dip = TAILQ_FIRST(&disklist); dip;
193 dip = TAILQ_NEXT(dip, list))
194 i++;
195 bios_diskinfo = alloc(++i * sizeof(bios_diskinfo_t));
196
197
198 for (i = 0, dip = TAILQ_FIRST(&disklist); dip;
199 dip = TAILQ_NEXT(dip, list))
200 bios_diskinfo[i++] = dip->bios_info;
201
202 bios_diskinfo[i++].bios_number = -1;
203
204 addbootarg(BOOTARG_CKSUMLEN, sizeof(u_int32_t), &bios_cksumlen);
205 addbootarg(BOOTARG_DISKINFO, i * sizeof(bios_diskinfo_t),
206 bios_diskinfo);
207 }
208
209
210 void
211 cdprobe(void)
212 {
213 struct diskinfo *dip;
214 int cddev = bios_cddev & 0xff;
215
216
217
218 if (bios_cddev == -1)
219 return;
220
221 dip = alloc(sizeof(struct diskinfo));
222 bzero(dip, sizeof(*dip));
223
224 #if 0
225 if (bios_getdiskinfo(cddev, &dip->bios_info)) {
226 printf(" <!cd0>");
227 free(dip, 0);
228 return;
229 }
230 #endif
231
232 printf(" cd0");
233
234 dip->bios_info.bios_number = cddev;
235 dip->bios_info.bios_edd = 1;
236 dip->bios_info.flags |= BDI_GOODLABEL | BDI_EL_TORITO;
237 dip->bios_info.checksum = 0;
238 dip->bios_info.bsd_dev =
239 MAKEBOOTDEV(0, 0, 0, 0xff, RAW_PART);
240
241
242 dip->disklabel.d_secsize = 2048;
243 dip->disklabel.d_ntracks = 1;
244 dip->disklabel.d_nsectors = 100;
245 dip->disklabel.d_ncylinders = 1;
246 dip->disklabel.d_secpercyl = dip->disklabel.d_ntracks *
247 dip->disklabel.d_nsectors;
248 if (dip->disklabel.d_secpercyl == 0) {
249 dip->disklabel.d_secpercyl = 100;
250
251 }
252
253 strncpy(dip->disklabel.d_typename, "ATAPI CD-ROM",
254 sizeof(dip->disklabel.d_typename));
255 dip->disklabel.d_type = DTYPE_ATAPI;
256
257 strncpy(dip->disklabel.d_packname, "fictitious",
258 sizeof(dip->disklabel.d_packname));
259 dip->disklabel.d_secperunit = 100;
260 dip->disklabel.d_rpm = 300;
261 dip->disklabel.d_interleave = 1;
262
263 dip->disklabel.d_bbsize = 2048;
264 dip->disklabel.d_sbsize = 2048;
265
266
267 dip->disklabel.d_partitions[0].p_offset = 0;
268 dip->disklabel.d_partitions[0].p_size = 100;
269 dip->disklabel.d_partitions[0].p_fstype = FS_UNUSED;
270
271
272 dip->disklabel.d_partitions[RAW_PART].p_offset = 0;
273 dip->disklabel.d_partitions[RAW_PART].p_size = 100;
274 dip->disklabel.d_partitions[RAW_PART].p_fstype = FS_UNUSED;
275
276 dip->disklabel.d_npartitions = RAW_PART + 1;
277
278 dip->disklabel.d_magic = DISKMAGIC;
279 dip->disklabel.d_magic2 = DISKMAGIC;
280 dip->disklabel.d_checksum = dkcksum(&dip->disklabel);
281
282
283 TAILQ_INSERT_TAIL(&disklist, dip, list);
284 }
285
286
287
288 struct diskinfo *
289 dklookup(int dev)
290 {
291 struct diskinfo *dip;
292
293 for (dip = TAILQ_FIRST(&disklist); dip; dip = TAILQ_NEXT(dip, list))
294 if (dip->bios_info.bios_number == dev)
295 return dip;
296
297 return NULL;
298 }
299
300 void
301 dump_diskinfo(void)
302 {
303 struct diskinfo *dip;
304
305 printf("Disk\tBIOS#\tType\tCyls\tHeads\tSecs\tFlags\tChecksum\n");
306 for (dip = TAILQ_FIRST(&disklist); dip; dip = TAILQ_NEXT(dip, list)) {
307 bios_diskinfo_t *bdi = &dip->bios_info;
308 int d = bdi->bios_number;
309 int u = d & 0x7f;
310 char c;
311
312 if (bdi->flags & BDI_EL_TORITO) {
313 c = 'c';
314 u = 0;
315 } else {
316 c = (d & 0x80) ? 'h' : 'f';
317 }
318
319 printf("%cd%d\t0x%x\t%s\t%d\t%d\t%d\t0x%x\t0x%x\n",
320 c, u, d,
321 (bdi->flags & BDI_BADLABEL)?"*none*":"label",
322 bdi->bios_cylinders, bdi->bios_heads, bdi->bios_sectors,
323 bdi->flags, bdi->checksum);
324 }
325 }
326
327
328
329
330 bios_diskinfo_t *
331 bios_dklookup(int dev)
332 {
333 struct diskinfo *dip;
334
335 dip = dklookup(dev);
336 if (dip)
337 return &dip->bios_info;
338
339 return NULL;
340 }
341
342
343
344
345
346
347
348 int
349 disksum(int blk)
350 {
351 struct diskinfo *dip, *dip2;
352 int st, reprobe = 0;
353 char *buf;
354
355 buf = alloca(DEV_BSIZE);
356 for (dip = TAILQ_FIRST(&disklist); dip; dip = TAILQ_NEXT(dip, list)) {
357 bios_diskinfo_t *bdi = &dip->bios_info;
358
359
360 if (!(bdi->bios_number & 0x80) || bdi->flags & BDI_INVALID)
361 continue;
362
363
364 st = biosd_io(F_READ, bdi, blk, 1, buf);
365 if (st) {
366 bdi->flags |= BDI_INVALID;
367 continue;
368 }
369 bdi->checksum = adler32(bdi->checksum, buf, DEV_BSIZE);
370
371 for (dip2 = TAILQ_FIRST(&disklist); dip2 != dip;
372 dip2 = TAILQ_NEXT(dip2, list)) {
373 bios_diskinfo_t *bd = &dip2->bios_info;
374 if ((bd->bios_number & 0x80) &&
375 !(bd->flags & BDI_INVALID) &&
376 bdi->checksum == bd->checksum)
377 reprobe = 1;
378 }
379 }
380
381 return reprobe;
382 }