]> git.ipfire.org Git - ipfire-2.x.git/blob - src/hwinfo/src/hd/int.c
Signierten GPG-Schluessel importiert.
[ipfire-2.x.git] / src / hwinfo / src / hd / int.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 typedef unsigned long kernel_ulong_t;
6 #include <linux/types.h>
7 #ifdef __UCLIBC__
8 #include <linux/pci.h>
9 #else
10 #include <sys/pci.h>
11 #endif
12 #include <sys/types.h>
13 #include <sys/stat.h>
14
15 #include "hd.h"
16 #include "hd_int.h"
17 #include "int.h"
18
19 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
20 * internal things
21 *
22 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
23 */
24
25 static void int_hotplug(hd_data_t *hd_data);
26 static void int_cdrom(hd_data_t *hd_data);
27 #if defined(__i386__) || defined (__x86_64__)
28 static int set_bios_id(hd_data_t *hd_data, hd_t *hd_ref, int bios_id);
29 static int bios_ctrl_order(hd_data_t *hd_data, unsigned *sctrl, int sctrl_len);
30 static void int_bios(hd_data_t *hd_data);
31 #endif
32 static void int_media_check(hd_data_t *hd_data);
33 static int contains_word(char *str, char *str2);
34 static int is_zip(hd_t *hd);
35 static void int_floppy(hd_data_t *hd_data);
36 static void int_fix_usb_scsi(hd_data_t *hd_data);
37 static void int_mouse(hd_data_t *hd_data);
38 static void new_id(hd_data_t *hd_data, hd_t *hd);
39 static void int_modem(hd_data_t *hd_data);
40 static void int_wlan(hd_data_t *hd_data);
41 static void int_udev(hd_data_t *hd_data);
42 static void int_devicenames(hd_data_t *hd_data);
43 #if defined(__i386__) || defined (__x86_64__)
44 static void int_softraid(hd_data_t *hd_data);
45 #endif
46 #if defined(__i386__) || defined (__x86_64__)
47 static void int_system(hd_data_t *hd_data);
48 static void int_legacy_geo(hd_data_t *hd_data);
49 #endif
50
51 void hd_scan_int(hd_data_t *hd_data)
52 {
53 hd_t *hd;
54
55 if(!hd_probe_feature(hd_data, pr_int)) return;
56
57 hd_data->module = mod_int;
58
59 /* some clean-up */
60 remove_hd_entries(hd_data);
61
62 PROGRESS(2, 0, "cdrom");
63 int_cdrom(hd_data);
64
65 PROGRESS(3, 0, "media");
66 int_media_check(hd_data);
67
68 PROGRESS(4, 0, "floppy");
69 int_floppy(hd_data);
70
71 #if defined(__i386__) || defined (__x86_64__)
72 PROGRESS(5, 0, "bios");
73 int_bios(hd_data);
74 #endif
75
76 PROGRESS(6, 0, "mouse");
77 int_mouse(hd_data);
78
79 #if defined(__i386__) || defined (__x86_64__)
80 PROGRESS(15, 0, "system info");
81 int_system(hd_data);
82 #endif
83
84 PROGRESS(7, 0, "hdb");
85 hd_data->flags.keep_kmods = 1;
86 for(hd = hd_data->hd; hd; hd = hd->next) {
87 hddb_add_info(hd_data, hd);
88 }
89 hd_data->flags.keep_kmods = 0;
90
91 PROGRESS(8, 0, "usbscsi");
92 int_fix_usb_scsi(hd_data);
93
94 PROGRESS(9, 0, "hotplug");
95 int_hotplug(hd_data);
96
97 PROGRESS(10, 0, "modem");
98 int_modem(hd_data);
99
100 PROGRESS(11, 0, "wlan");
101 int_wlan(hd_data);
102
103 PROGRESS(12, 0, "udev");
104 int_udev(hd_data);
105
106 PROGRESS(13, 0, "device names");
107 int_devicenames(hd_data);
108
109 #if defined(__i386__) || defined (__x86_64__)
110 PROGRESS(14, 0, "soft raid");
111 int_softraid(hd_data);
112
113 PROGRESS(15, 0, "geo");
114 int_legacy_geo(hd_data);
115 #endif
116
117 }
118
119 /*
120 * Identify hotpluggable devices.
121 */
122 void int_hotplug(hd_data_t *hd_data)
123 {
124 hd_t *hd;
125
126 for(hd = hd_data->hd; hd; hd = hd->next) {
127 if(hd->bus.id == bus_usb || hd->usb_guid) {
128 hd->hotplug = hp_usb;
129 }
130 }
131 }
132
133 /*
134 * Add more info to CDROM entries.
135 */
136 void int_cdrom(hd_data_t *hd_data)
137 {
138 hd_t *hd;
139
140 for(hd = hd_data->hd; hd; hd = hd->next) {
141 if(
142 hd->base_class.id == bc_storage_device &&
143 hd->sub_class.id == sc_sdev_cdrom &&
144 !hd->prog_if.id
145 ) {
146 if(hd->device.name && strstr(hd->device.name, "DVD")) {
147 hd->prog_if.id = 3;
148 }
149 }
150 }
151 }
152
153 #if defined(__i386__) || defined (__x86_64__)
154
155 int set_bios_id(hd_data_t *hd_data, hd_t *hd_ref, int bios_id)
156 {
157 int found = 0;
158 hd_t *hd;
159
160 if(!hd_ref || !hd_ref->unix_dev_name) return 0;
161
162 for(hd = hd_data->hd; hd; hd = hd->next) {
163 if(
164 hd->base_class.id == bc_storage_device &&
165 hd->sub_class.id == sc_sdev_disk &&
166 hd->unix_dev_name &&
167 !strcmp(hd->unix_dev_name, hd_ref->unix_dev_name)
168 ) {
169 str_printf(&hd->rom_id, 0, "0x%02x", bios_id);
170 found = 1;
171 }
172 }
173
174 return found;
175 }
176
177
178 int bios_ctrl_order(hd_data_t *hd_data, unsigned *sctrl, int sctrl_len)
179 {
180 hd_t *hd;
181 bios_info_t *bt;
182 int i, j, k, sctrl2_len = 0;
183 unsigned pci_slot, pci_func;
184 unsigned *sctrl2 = NULL, *sctrl3 = NULL;
185 int order_info = 0;
186
187 for(bt = NULL, hd = hd_data->hd; hd; hd = hd->next) {
188 if(
189 hd->base_class.id == bc_internal &&
190 hd->sub_class.id == sc_int_bios &&
191 hd->detail &&
192 hd->detail->type == hd_detail_bios &&
193 (bt = hd->detail->bios.data)
194 ) {
195 break;
196 }
197 }
198
199 if(!bt || !bt->bios32.ok || !bt->bios32.compaq) return 0;
200
201 sctrl2 = new_mem((sizeof bt->bios32.cpq_ctrl / sizeof *bt->bios32.cpq_ctrl) * sizeof *sctrl2);
202
203 for(i = 0; (unsigned) i < sizeof bt->bios32.cpq_ctrl / sizeof *bt->bios32.cpq_ctrl; i++) {
204 if(
205 bt->bios32.cpq_ctrl[i].id &&
206 !(bt->bios32.cpq_ctrl[i].misc & 0x40) /* bios support ??????? */
207 ) {
208 pci_slot = PCI_SLOT(bt->bios32.cpq_ctrl[i].devfn) + (bt->bios32.cpq_ctrl[i].bus << 8);
209 pci_func = PCI_FUNC(bt->bios32.cpq_ctrl[i].devfn);
210 for(hd = hd_data->hd; hd; hd = hd->next) {
211 if(hd->bus.id == bus_pci && hd->slot == pci_slot && hd->func == pci_func) {
212 sctrl2[sctrl2_len++] = hd->idx;
213 break;
214 }
215 }
216 }
217 }
218
219 if(sctrl2_len) order_info = 1;
220
221 for(i = 0; i < sctrl2_len; i++) {
222 ADD2LOG(" bios ord %d: %d\n", i, sctrl2[i]);
223 }
224
225 /* sort list */
226
227 sctrl3 = new_mem(sctrl_len * sizeof *sctrl3);
228
229 k = 0 ;
230 for(i = 0; i < sctrl2_len; i++) {
231 for(j = 0; j < sctrl_len; j++) {
232 if(sctrl[j] == sctrl2[i]) {
233 sctrl3[k++] = sctrl[j];
234 sctrl[j] = 0;
235 break;
236 }
237 }
238 }
239
240 for(i = 0; i < sctrl_len; i++) {
241 if(sctrl[i] && k < sctrl_len) sctrl3[k++] = sctrl[i];
242 }
243
244 memcpy(sctrl, sctrl3, sctrl_len * sizeof *sctrl);
245
246 free_mem(sctrl2);
247 free_mem(sctrl3);
248
249 return order_info;
250 }
251
252
253 void int_bios(hd_data_t *hd_data)
254 {
255 hd_t *hd, *hd_boot;
256 unsigned *sctrl, *sctrl2;
257 int sctrl_len, i, j;
258 int bios_id, list_sorted;
259
260 /* don't do anything if there is useful edd info */
261 if(hd_data->flags.edd_used) return;
262
263 for(i = 0, hd = hd_data->hd; hd; hd = hd->next) {
264 if(
265 hd->base_class.id == bc_storage_device &&
266 hd->sub_class.id == sc_sdev_disk
267 ) {
268 i++;
269 }
270 }
271
272 if(!i) return;
273
274 sctrl = new_mem(i * sizeof *sctrl);
275
276 /* sctrl: list of storage controllers with disks */
277
278 for(sctrl_len = 0, hd = hd_data->hd; hd; hd = hd->next) {
279 if(
280 hd->base_class.id == bc_storage_device &&
281 hd->sub_class.id == sc_sdev_disk
282 ) {
283 for(i = 0; i < sctrl_len; i++) {
284 if(sctrl[i] == hd->attached_to) break;
285 }
286 if(i == sctrl_len) sctrl[sctrl_len++] = hd->attached_to;
287 }
288 }
289
290 /* sort list, if possible */
291
292 list_sorted = bios_ctrl_order(hd_data, sctrl, sctrl_len);
293
294 hd_boot = hd_get_device_by_idx(hd_data, hd_boot_disk(hd_data, &i));
295
296 /* if we know the boot device, make this controller the first */
297
298 if(hd_boot && hd_boot->attached_to && i == 1) {
299 for(i = 0; i < sctrl_len; i++) {
300 if(sctrl[i] == hd_boot->attached_to) break;
301 }
302 if(i < sctrl_len) {
303 sctrl2 = new_mem(sctrl_len * sizeof *sctrl2);
304 *sctrl2 = hd_boot->attached_to;
305 for(i = 0, j = 1; i < sctrl_len; i++) {
306 if(sctrl[i] != hd_boot->attached_to) sctrl2[j++] = sctrl[i];
307 }
308 free_mem(sctrl);
309 sctrl = sctrl2;
310 }
311 }
312 else {
313 hd_boot = NULL;
314 }
315
316 if(hd_boot) ADD2LOG(" bios boot dev: %d\n", hd_boot->idx);
317 for(i = 0; i < sctrl_len; i++) {
318 ADD2LOG(" bios ctrl %d: %d\n", i, sctrl[i]);
319 }
320
321 /* remove existing entries */
322
323 for(hd = hd_data->hd; hd; hd = hd->next) {
324 if(
325 hd->base_class.id == bc_storage_device &&
326 hd->sub_class.id == sc_sdev_disk
327 ) {
328 hd->rom_id = free_mem(hd->rom_id);
329 }
330 }
331
332 if(!list_sorted && !hd_boot && sctrl_len > 1) {
333 /* we have no info at all */
334 sctrl_len = 0;
335 }
336 else if(!list_sorted && hd_boot && sctrl_len > 2) {
337 /* we know which controller has the boot device */
338 sctrl_len = 1;
339 }
340
341 bios_id = 0x80;
342
343 /* rely on it */
344
345 if(hd_boot) {
346 bios_id += set_bios_id(hd_data, hd_boot, bios_id);
347 }
348
349 /* assign all the others */
350
351 for(i = 0; i < sctrl_len; i++) {
352 for(hd = hd_data->hd; hd; hd = hd->next) {
353 if(
354 hd->base_class.id == bc_storage_device &&
355 hd->sub_class.id == sc_sdev_disk &&
356 hd->attached_to == sctrl[i] &&
357 !hd->rom_id
358 ) {
359 bios_id += set_bios_id(hd_data, hd, bios_id);
360 }
361 }
362 }
363
364 free_mem(sctrl);
365 }
366
367
368 #if 0
369 void int_bios(hd_data_t *hd_data)
370 {
371 hd_t *hd, *hd_boot;
372 int i, start, bios = 0x80;
373 int ide_1st;
374 char ide_name[] = "/dev/hda";
375 char scsi_name[] = "/dev/sda";
376 char *s;
377
378 hd_boot = hd_get_device_by_idx(hd_data, hd_boot_disk(hd_data, &i));
379
380 if(hd_boot) {
381 free_mem(hd_boot->rom_id);
382 hd_boot->rom_id = new_str("0x80");
383 }
384
385 if(!hd_boot || i != 1) return;
386
387 if(strstr(hd_boot->unix_dev_name, "/dev/sd") == hd_boot->unix_dev_name) {
388 ide_1st = 0;
389 start = hd_boot->unix_dev_name[sizeof "/dev/sd" - 1] - 'a';
390 }
391 else if(strstr(hd_boot->unix_dev_name, "/dev/hd") == hd_boot->unix_dev_name) {
392 ide_1st = 1;
393 start = hd_boot->unix_dev_name[sizeof "/dev/hd" - 1] - 'a';
394 }
395 else {
396 return;
397 }
398
399 if(start < 0) return;
400
401 for(hd = hd_data->hd; hd; hd = hd->next) {
402 if(
403 hd->base_class.id == bc_storage_device &&
404 hd->sub_class.id == sc_sdev_disk
405 ) {
406 hd->rom_id = free_mem(hd->rom_id);
407 }
408 }
409
410 s = ide_1st ? ide_name : scsi_name;
411
412 for(i = start; i < 26; i++) {
413 s[strlen(s) - 1] = 'a' + i;
414 bios += set_bios_id(hd_data, s, bios);
415 }
416
417 for(i = 0; i < start; i++) {
418 s[strlen(s) - 1] = 'a' + i;
419 bios += set_bios_id(hd_data, s, bios);
420 }
421
422 s = ide_1st ? scsi_name : ide_name;
423
424 for(i = 0; i < 26; i++) {
425 s[strlen(s) - 1] = 'a' + i;
426 bios += set_bios_id(hd_data, s, bios);
427 }
428 }
429 #endif /* 0 */
430 #endif /* defined(__i386__) || defined (__x86_64__) */
431
432 /*
433 * Try to read block 0 for block devices.
434 */
435 void int_media_check(hd_data_t *hd_data)
436 {
437 hd_t *hd;
438 int i, j = 0;
439
440 for(hd = hd_data->hd; hd; hd = hd->next) {
441 if(!hd_report_this(hd_data, hd)) continue;
442 if(
443 hd->base_class.id == bc_storage_device &&
444 (
445 /* hd->sub_class.id == sc_sdev_cdrom || */ /* cf. cdrom.c */
446 hd->sub_class.id == sc_sdev_disk ||
447 hd->sub_class.id == sc_sdev_floppy
448 ) &&
449 hd->unix_dev_name &&
450 !hd->block0 &&
451 !hd->is.notready &&
452 hd->status.available != status_no
453 ) {
454 i = 5;
455 PROGRESS(4, ++j, hd->unix_dev_name);
456 hd->block0 = read_block0(hd_data, hd->unix_dev_name, &i);
457 hd->is.notready = hd->block0 ? 0 : 1;
458 }
459 }
460 }
461
462
463 /*
464 * Check if str has str2 in it.
465 */
466 int contains_word(char *str, char *str2)
467 {
468 int i, len, len2, found = 0;
469 char *s;
470
471 if(!str2 || !*str2 || !str || !*str) return 0;
472
473 str = new_str(str);
474
475 len = strlen(str);
476 len2 = strlen(str2);
477
478 for(i = 0; i < len; i++) {
479 if(str[i] >= 'a' && str[i] <= 'z') str[i] -= 'a' - 'A';
480 }
481
482 for(s = str; (s = strstr(s, str2)); s++) {
483 if(
484 (s == str || s[-1] < 'A' || s[-1] > 'Z') &&
485 (s[len2] < 'A' || s[len2] > 'Z')
486 ) {
487 found = 1;
488 break;
489 }
490 }
491
492 free_mem(str);
493
494 return found;
495 }
496
497
498 /*
499 * Check for zip drive.
500 */
501 int is_zip(hd_t *hd)
502 {
503 if(
504 hd->base_class.id == bc_storage_device &&
505 (
506 hd->sub_class.id == sc_sdev_disk ||
507 hd->sub_class.id == sc_sdev_floppy
508 )
509 ) {
510 if(
511 (
512 contains_word(hd->vendor.name, "IOMEGA") ||
513 contains_word(hd->sub_vendor.name, "IOMEGA") ||
514 contains_word(hd->device.name, "IOMEGA") ||
515 contains_word(hd->sub_device.name, "IOMEGA")
516 ) && (
517 contains_word(hd->device.name, "ZIP") ||
518 contains_word(hd->sub_device.name, "ZIP")
519 )
520 ) {
521 return 1;
522 }
523 }
524
525 return 0;
526 }
527
528
529 /*
530 * Turn some drives into floppies.
531 */
532 void int_floppy(hd_data_t *hd_data)
533 {
534 hd_t *hd;
535 hd_res_t *res;
536
537 for(hd = hd_data->hd; hd; hd = hd->next) {
538 if(is_zip(hd)) hd->is.zip = 1;
539 if(
540 hd->base_class.id == bc_storage_device &&
541 hd->sub_class.id == sc_sdev_disk
542 ) {
543 if(hd->is.zip) {
544 hd->sub_class.id = sc_sdev_floppy;
545 new_id(hd_data, hd);
546 }
547 else {
548 /* make everything a floppy that is 1440k */
549 for(res = hd->res; res; res = res->next) {
550 if(
551 res->any.type == res_size &&
552 res->size.unit == size_unit_sectors &&
553 res->size.val1 == 2880 &&
554 res->size.val2 == 512
555 ) {
556 hd->sub_class.id = sc_sdev_floppy;
557 new_id(hd_data, hd);
558 break;
559 }
560 }
561 }
562 }
563 }
564 }
565
566
567 #define COPY_ENTRY(a) if(hd_scsi->a) { free_mem(hd_usb->a); hd_usb->a = new_str(hd_scsi->a); }
568 /*
569 * Remove usb entries that are handled by usb-storage.
570 */
571 void int_fix_usb_scsi(hd_data_t *hd_data)
572 {
573 hd_t *hd_scsi, *hd_usb;
574
575 for(hd_usb = hd_data->hd; hd_usb; hd_usb= hd_usb->next) {
576 if(
577 hd_usb->bus.id == bus_usb &&
578 hd_usb->sysfs_id &&
579 search_str_list(hd_usb->drivers, "usb-storage")
580 ) {
581 for(hd_scsi = hd_data->hd; hd_scsi; hd_scsi = hd_scsi->next) {
582 if(
583 hd_scsi->bus.id == bus_scsi &&
584 hd_scsi->sysfs_device_link &&
585 search_str_list(hd_scsi->drivers, "usb-storage")
586 ) {
587 if(!strncmp(hd_scsi->sysfs_device_link, hd_usb->sysfs_id, strlen(hd_usb->sysfs_id))) {
588 hd_set_hw_class(hd_scsi, hw_usb);
589
590 free_mem(hd_scsi->unique_id);
591 hd_scsi->unique_id = hd_usb->unique_id;
592 hd_usb->unique_id = NULL;
593
594 add_res_entry(&hd_scsi->res, hd_usb->res);
595 hd_usb->res = NULL;
596
597 new_id(hd_data, hd_scsi);
598
599 hd_usb->tag.remove = 1;
600 }
601 }
602 }
603 }
604
605 }
606
607
608
609 #if 0
610 for(hd_scsi = hd_data->hd; hd_scsi; hd_scsi = hd_scsi->next) {
611 if(
612 hd_scsi->bus.id == bus_scsi &&
613 hd_scsi->usb_guid &&
614 search_str_list(hd_scsi->drivers, "usb-storage")
615 ) {
616 for(hd_usb = hd_data->hd; hd_usb ; hd_usb = hd_usb->next) {
617 if(
618 hd_usb->bus.id == bus_usb &&
619 hd_usb->usb_guid &&
620 !hd_usb->tag.remove &&
621 !strcmp(hd_usb->usb_guid, hd_scsi->usb_guid) &&
622 hd_usb->detail &&
623 hd_usb->detail->type == hd_detail_usb &&
624 (usb = hd_usb->detail->usb.data) &&
625 usb->driver &&
626 !strcmp(usb->driver, "usb-storage")
627 ) {
628 hd_scsi->tag.remove = 1;
629
630 /* join usb & scsi info */
631 hd_usb->bus.id = hd_scsi->bus.id;
632 COPY_ENTRY(bus.name);
633 hd_usb->base_class.id = hd_scsi->base_class.id;
634 COPY_ENTRY(base_class.name);
635 hd_usb->sub_class.id = hd_scsi->sub_class.id;
636 COPY_ENTRY(sub_class.name);
637 hd_usb->prog_if.id = hd_scsi->prog_if.id;
638 COPY_ENTRY(prog_if.name);
639 COPY_ENTRY(unix_dev_name);
640 COPY_ENTRY(model);
641 // ###### FIXME?: COPY_ENTRY(driver)
642
643 hd_usb->vendor.id = hd_scsi->vendor.id;
644 COPY_ENTRY(vendor.name);
645 hd_usb->device.id = hd_scsi->device.id;
646 COPY_ENTRY(device.name);
647 hd_usb->sub_vendor.name = free_mem(hd_usb->sub_vendor.name);
648 COPY_ENTRY(sub_vendor.name);
649 hd_usb->sub_device.name = free_mem(hd_usb->sub_device.name);
650 COPY_ENTRY(sub_device.name);
651 COPY_ENTRY(revision.name);
652 COPY_ENTRY(serial);
653
654 hd_usb->is.notready = hd_scsi->is.notready;
655 if(hd_usb->block0) free_mem(hd_usb->block0);
656 hd_usb->block0 = hd_scsi->block0;
657 hd_scsi->block0 = NULL;
658 add_res_entry(&hd_usb->res, hd_scsi->res);
659 hd_scsi->res = NULL;
660
661 new_id(hd_data, hd_usb);
662 }
663 }
664 }
665 }
666 #endif
667
668
669
670 remove_tagged_hd_entries(hd_data);
671 }
672 #undef COPY_ENTRY
673
674
675 /*
676 * Improve mouse info.
677 */
678 void int_mouse(hd_data_t *hd_data)
679 {
680 hd_t *hd;
681 bios_info_t *bt = NULL;
682
683 for(hd = hd_data->hd; hd; hd = hd->next) {
684 if(
685 hd->detail &&
686 hd->detail->type == hd_detail_bios &&
687 (bt = hd->detail->bios.data) &&
688 bt->mouse.type
689 ) break;
690 }
691
692 if(!bt) return;
693
694 for(hd = hd_data->hd; hd; hd = hd->next) {
695 if(
696 hd->base_class.id == bc_mouse &&
697 hd->sub_class.id == sc_mou_ps2 &&
698 hd->bus.id == bt->mouse.bus &&
699 hd->vendor.id == MAKE_ID(TAG_SPECIAL, 0x0200) &&
700 hd->device.id == MAKE_ID(TAG_SPECIAL, 0x0002)
701 ) {
702 hd->vendor.name = free_mem(hd->vendor.name);
703 hd->device.name = free_mem(hd->device.name);
704 hd->vendor.id = hd->device.id = 0;
705 #if 0
706 hd->vendor.id = bt->mouse.compat_vend;
707 hd->device.id = bt->mouse.compat_dev;
708 #else
709 hd->vendor.name = new_str(bt->mouse.vendor);
710 hd->device.name = new_str(bt->mouse.type);
711 hd->compat_vendor.id = bt->mouse.compat_vend;
712 hd->compat_device.id = bt->mouse.compat_dev;
713 #endif
714 new_id(hd_data, hd);
715 }
716 }
717 }
718
719
720 void new_id(hd_data_t *hd_data, hd_t *hd)
721 {
722 #if 0
723 hd->unique_id = free_mem(hd->unique_id);
724 hd->unique_id1 = free_mem(hd->unique_id1);
725 hd->old_unique_id = free_mem(hd->old_unique_id);
726 hd_add_id(hd_data, hd);
727 #endif
728 }
729
730
731 /*
732 * Assign device names to (win-)modems.
733 */
734 void int_modem(hd_data_t *hd_data)
735 {
736 hd_t *hd;
737 char *s;
738 hd_dev_num_t dev_num = { type: 'c', range: 1 };
739 unsigned cnt4 = 0;
740
741 for(hd = hd_data->hd; hd; hd = hd->next) {
742 if(
743 hd->base_class.id == bc_modem
744 ) {
745 s = NULL;
746 switch(hd->sub_class.id) {
747 case sc_mod_win1:
748 s = new_str("/dev/ham");
749 dev_num.major = 240;
750 dev_num.minor = 1;
751 break;
752 case sc_mod_win2:
753 s = new_str("/dev/536ep0");
754 dev_num.major = 240;
755 dev_num.minor = 1;
756 break;
757 case sc_mod_win3:
758 s = new_str("/dev/ttyLT0");
759 dev_num.major = 62;
760 dev_num.minor = 64;
761 break;
762 case sc_mod_win4:
763 if(cnt4 < 4) {
764 str_printf(&s, 0, "/dev/ttySL%u", cnt4);
765 dev_num.major = 212;
766 dev_num.minor = cnt4++;
767 }
768 break;
769 }
770 if(s) {
771 free_mem(hd->unix_dev_name);
772 hd->unix_dev_name = s;
773 s = NULL;
774 hd->unix_dev_num = dev_num;
775 }
776 }
777 }
778 }
779
780
781 /*
782 * Look for WLAN cards by checking module info.
783 */
784 void int_wlan(hd_data_t *hd_data)
785 {
786 hd_t *hd;
787 driver_info_t *di;
788 str_list_t *sl;
789 unsigned u, found;
790 static char *wlan_mods[] = {
791 "acx_pci",
792 "airo",
793 "airo_cs",
794 "aironet4500_card",
795 "aironet4500_cs",
796 "airport",
797 "adm8211",
798 "arlan",
799 "at76c503",
800 "at76c503-i3861",
801 "at76c503-i3863",
802 "at76c503-rfmd",
803 "at76c503-rfmd-acc",
804 "at76c505-rfmd",
805 "at76c505-rfmd2958",
806 "ath_hal",
807 "ath_pci",
808 "atmel",
809 "atmel_cs",
810 "atmel_pci",
811 "hermes",
812 "hostap",
813 "hostap_pci",
814 "hostap_plx",
815 "ipw2100",
816 "ipw2200",
817 "netwave_cs",
818 "orinoco_cs",
819 "orinoco_pci",
820 "orinoco_plx",
821 "p80211",
822 "prism2_cs",
823 "prism2_pci",
824 "prism2_plx",
825 "prism2_usb",
826 "prism54",
827 "ray_cs",
828 "rt2400",
829 "rt2500",
830 "usbdfu",
831 "wavelan",
832 "wavelan_cs",
833 "wl3501_cs"
834 };
835
836 for(hd = hd_data->hd; hd; hd = hd->next) {
837 for(found = 0, di = hd->driver_info; di && !found; di = di->next) {
838 if(di->any.type == di_module) {
839 for(sl = di->module.names; sl && !found; sl = sl->next) {
840 for(u = 0; u < sizeof wlan_mods / sizeof *wlan_mods; u++) {
841 if(!strcmp(sl->str, wlan_mods[u])) {
842 found = 1;
843 break;
844 }
845 }
846 }
847 }
848 }
849 if(found) {
850 hd->is.wlan = 1;
851 hd->base_class.id = bc_network;
852 hd->sub_class.id = 0x82; /* wlan */
853 hddb_add_info(hd_data, hd);
854 }
855 }
856 }
857
858
859 /*
860 * Add udev info.
861 */
862 void int_udev(hd_data_t *hd_data)
863 {
864 hd_udevinfo_t *ui;
865 hd_t *hd;
866 char *s = NULL;
867 str_list_t *sl;
868
869 if(!hd_data->udevinfo) read_udevinfo(hd_data);
870
871 if(!hd_data->udevinfo) return;
872
873 for(hd = hd_data->hd; hd; hd = hd->next) {
874 if(!hd->sysfs_id) continue;
875
876 for(ui = hd_data->udevinfo; ui; ui = ui->next) {
877 if(ui->name && !strcmp(ui->sysfs, hd->sysfs_id)) {
878 hd->unix_dev_names = free_str_list(hd->unix_dev_names);
879 hd->unix_dev_name = free_mem(hd->unix_dev_name);
880 str_printf(&s, 0, "%s%s", ui->type == 'n' ? "" : "/dev/", ui->name);
881 add_str_list(&hd->unix_dev_names, s);
882 for(sl = ui->links; sl; sl = sl->next) {
883 str_printf(&s, 0, "%s%s", ui->type == 'n' ? "" : "/dev/", sl->str);
884 add_str_list(&hd->unix_dev_names, s);
885 }
886 s = free_mem(s);
887
888 sl = hd->unix_dev_names;
889
890 if(hd_data->flags.udev) {
891 /* use first link as canonical device name */
892 if(ui->links) sl = sl->next;
893 }
894
895 hd->unix_dev_name = new_str(sl->str);
896
897 break;
898 }
899 }
900 }
901 }
902
903
904 /*
905 * If hd->unix_dev_name is not in hd->unix_dev_names, add it.
906 */
907 void int_devicenames(hd_data_t *hd_data)
908 {
909 hd_t *hd;
910
911 for(hd = hd_data->hd; hd; hd = hd->next) {
912 if(
913 hd->unix_dev_name &&
914 !search_str_list(hd->unix_dev_names, hd->unix_dev_name)
915 ) {
916 add_str_list(&hd->unix_dev_names, hd->unix_dev_name);
917 }
918 }
919 }
920
921
922 #if defined(__i386__) || defined (__x86_64__)
923 /*
924 * Tag ide soft raid disks.
925 */
926 void int_softraid(hd_data_t *hd_data)
927 {
928 hd_t *hd;
929 str_list_t *raid, *sl, *raid_sysfs = NULL, *sl1;
930 size_t len;
931 char *s;
932
933 if(hd_data->flags.fast) return;
934
935 for(hd = hd_data->hd; hd; hd = hd->next) {
936 if(
937 hd->base_class.id == bc_storage_device &&
938 hd->status.available != status_no
939 ) break;
940 }
941
942 /* no disks -> no check necessary */
943 if(!hd) return;
944
945 raid = read_file("| /sbin/dmraid -rc 2>/dev/null", 0, 0);
946
947 for(sl = raid; sl; sl = sl->next) {
948 s = *sl->str ? strchr(sl->str + 1, '/') : NULL;
949 if(s) {
950 sl1 = add_str_list(&raid_sysfs, NULL);
951 str_printf(&sl1->str, 0, "/block%s", s);
952 len = strlen(sl1->str);
953 if(len) sl1->str[len - 1] = 0;
954 }
955 }
956
957 free_str_list(raid);
958
959 ADD2LOG("----- soft raid devices -----\n");
960 for(sl = raid_sysfs; sl; sl = sl->next) {
961 ADD2LOG(" %s\n", sl->str);
962 }
963 ADD2LOG("----- soft raid devices end -----\n");
964
965 for(hd = hd_data->hd; hd; hd = hd->next) {
966 if(search_str_list(raid_sysfs, hd->sysfs_id)) {
967 hd->is.softraiddisk = 1;
968 }
969 }
970
971 free_str_list(raid_sysfs);
972
973 }
974
975
976 /*
977 *
978 */
979 void int_system(hd_data_t *hd_data)
980 {
981 hd_t *hd_sys;
982 hd_smbios_t *sm;
983 struct {
984 unsigned notebook:1;
985 unsigned acpi_mods:1; /* *** evil hack *** */
986 enum { v_none = 0, v_ibm = 1, v_toshiba, v_sony } vendor;
987 } is = { };
988 char *s;
989
990 for(hd_sys = hd_data->hd; hd_sys; hd_sys = hd_sys->next) {
991 if(
992 hd_sys->base_class.id == bc_internal &&
993 hd_sys->sub_class.id == sc_int_sys
994 ) break;
995 }
996
997 if(!hd_sys) return;
998
999 if(
1000 hd_sys->vendor.name &&
1001 !strncasecmp(hd_sys->vendor.name, "sony", sizeof "sony" - 1)
1002 ) {
1003 is.vendor = v_sony;
1004 }
1005
1006 if(
1007 hd_sys->device.name &&
1008 !strncmp(hd_sys->device.name, "PCG-", sizeof "PCG-" - 1)
1009 ) {
1010 is.notebook = 1;
1011 }
1012
1013 for(sm = hd_data->smbios; sm; sm = sm->next) {
1014 if(
1015 sm->any.type == sm_sysinfo &&
1016 sm->sysinfo.manuf &&
1017 sm->sysinfo.product &&
1018 !strcasecmp(sm->sysinfo.manuf, "Hewlett-Packard") &&
1019 !strcasecmp(sm->sysinfo.product, "HP Compaq nc6220")
1020 ) {
1021 is.acpi_mods = 1;
1022 }
1023
1024 if(
1025 sm->any.type == sm_sysinfo &&
1026 sm->sysinfo.manuf &&
1027 !strcasecmp(sm->sysinfo.manuf, "ibm")
1028 ) {
1029 is.vendor = v_ibm;
1030 }
1031
1032 if(
1033 sm->any.type == sm_sysinfo &&
1034 sm->sysinfo.manuf &&
1035 !strcasecmp(sm->sysinfo.manuf, "toshiba")
1036 ) {
1037 is.vendor = v_toshiba;
1038
1039 if(!hd_sys->device.name && !hd_sys->device.id && sm->sysinfo.product) {
1040 hd_sys->device.name = new_str(sm->sysinfo.product);
1041 }
1042 if(!hd_sys->vendor.name && !hd_sys->vendor.id) {
1043 hd_sys->vendor.name = new_str("Toshiba");
1044 }
1045 }
1046
1047 if(
1048 sm->any.type == sm_sysinfo &&
1049 sm->sysinfo.manuf &&
1050 !strncasecmp(sm->sysinfo.manuf, "sony", sizeof "sony" - 1)
1051 ) {
1052 is.vendor = v_sony;
1053
1054 if(!hd_sys->device.name && !hd_sys->device.id && sm->sysinfo.product) {
1055 hd_sys->device.name = new_str(sm->sysinfo.product);
1056 if(
1057 (s = strchr(hd_sys->device.name, '(')) &&
1058 hd_sys->device.name[strlen(hd_sys->device.name) - 1] == ')'
1059 ) {
1060 *s = 0;
1061 }
1062 }
1063 if(!hd_sys->vendor.name && !hd_sys->vendor.id) {
1064 hd_sys->vendor.name = new_str("Sony");
1065 }
1066 }
1067
1068 if(
1069 sm->any.type == sm_chassis &&
1070 (
1071 (sm->chassis.ch_type.id >= 8 && sm->chassis.ch_type.id <= 11) ||
1072 sm->chassis.ch_type.id == 14
1073 )
1074 ) {
1075 is.notebook = 1;
1076 }
1077 }
1078
1079 ADD2LOG(
1080 " system type:%s%s\n",
1081 is.vendor == v_ibm ? " ibm" :
1082 is.vendor == v_toshiba ? " toshiba" :
1083 is.vendor == v_sony ? " sony" :
1084 "",
1085 is.notebook ? " notebook" : ""
1086 );
1087
1088 if(is.notebook && is.vendor) {
1089 hd_sys->compat_vendor.id = MAKE_ID(TAG_SPECIAL, 0xf001);
1090 hd_sys->compat_device.id = MAKE_ID(TAG_SPECIAL, is.vendor);
1091 }
1092 else if(is.acpi_mods) {
1093 hd_sys->compat_vendor.id = MAKE_ID(TAG_SPECIAL, 0xf001);
1094 hd_sys->compat_device.id = MAKE_ID(TAG_SPECIAL, 4);
1095 }
1096 }
1097
1098
1099 void int_legacy_geo(hd_data_t *hd_data)
1100 {
1101 hd_t *hd;
1102 hd_res_t *res;
1103 int id;
1104 char *s;
1105 edd_info_t *ei;
1106
1107 if(!hd_data->edd) return;
1108
1109 for(hd = hd_data->hd; hd; hd = hd->next) {
1110 if(
1111 hd->base_class.id == bc_storage_device &&
1112 hd->sub_class.id == sc_sdev_disk &&
1113 hd->rom_id
1114 ) {
1115 id = strtol(hd->rom_id, &s, 0) - 0x80;
1116 if(*s || id < 0 || id >= sizeof hd_data->edd / sizeof *hd_data->edd) continue;
1117
1118 ei = hd_data->edd + id;
1119
1120 if(ei->edd.cyls) {
1121 res = add_res_entry(&hd->res, new_mem(sizeof *res));
1122 res->disk_geo.type = res_disk_geo;
1123 res->disk_geo.cyls = ei->edd.cyls;
1124 res->disk_geo.heads = ei->edd.heads;
1125 res->disk_geo.sectors = ei->edd.sectors;
1126 res->disk_geo.size = ei->sectors;
1127 res->disk_geo.geotype = geo_bios_edd;
1128 }
1129
1130 if(ei->legacy.cyls) {
1131 res = add_res_entry(&hd->res, new_mem(sizeof *res));
1132 res->disk_geo.type = res_disk_geo;
1133 res->disk_geo.cyls = ei->legacy.cyls;
1134 res->disk_geo.heads = ei->legacy.heads;
1135 res->disk_geo.sectors = ei->legacy.sectors;
1136 res->disk_geo.geotype = geo_bios_legacy;
1137 }
1138
1139 }
1140 }
1141
1142
1143 }
1144
1145 #endif
1146
1147