5 #include <sys/utsname.h>
13 extern hddb2_data_t hddb_internal
;
15 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
18 // #define HDDB_EXTERNAL_ONLY
20 static char *hid_tag_names
[] = { "", "pci ", "eisa ", "usb ", "special ", "pcmcia " };
21 // just experimenting...
22 static char *hid_tag_names2
[] = { "", "pci ", "eisa ", "usb ", "int ", "pcmcia " };
25 pref_empty
, pref_new
, pref_and
, pref_or
, pref_add
28 typedef struct line_s
{
36 unsigned val
[32]; /* arbitrary (approx. max. number of modules/xf86 config lines) */
39 /* except for driver, all strings are static and _must not_ be freed */
41 hddb_entry_mask_t key
;
42 hddb_entry_mask_t value
;
43 hddb_entry_mask_t value_mask
[he_nomask
];
60 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
61 static void hddb_init_pci(hd_data_t
*hd_data
);
62 static hddb_pci_t
*parse_pcimap(str_list_t
*file
);
63 static driver_info_t
*hd_pcidb(hd_data_t
*hd_data
, hddb_pci_t
*pci_db
, hd_t
*hd
, driver_info_t
*drv_info
);
64 static void hddb_init_external(hd_data_t
*hd_data
);
66 static line_t
*parse_line(char *str
);
67 static unsigned store_string(hddb2_data_t
*x
, char *str
);
68 static unsigned store_list(hddb2_data_t
*x
, hddb_list_t
*list
);
69 static unsigned store_value(hddb2_data_t
*x
, unsigned val
);
70 static unsigned store_entry(hddb2_data_t
*x
, tmp_entry_t
*te
);
71 static void clear_entry(tmp_entry_t
*te
);
72 static void add_value(tmp_entry_t
*te
, hddb_entry_t idx
, unsigned val
);
73 static hddb_entry_mask_t
add_entry(hddb2_data_t
*hddb2
, tmp_entry_t
*te
, hddb_entry_t idx
, char *str
);
74 static int compare_ids(hddb2_data_t
*hddb
, hddb_search_t
*hs
, hddb_entry_mask_t mask
, unsigned key
);
75 static void complete_ids(hddb2_data_t
*hddb
, hddb_search_t
*hs
, hddb_entry_mask_t key_mask
, hddb_entry_mask_t mask
, unsigned val_idx
);
76 static int hddb_search(hd_data_t
*hd_data
, hddb_search_t
*hs
, int max_recursions
);
78 static void test_db(hd_data_t
*hd_data
);
80 static driver_info_t
*hddb_to_device_driver(hd_data_t
*hd_data
, hddb_search_t
*hs
);
81 static driver_info_t
*kbd_driver(hd_data_t
*hd_data
, hd_t
*hd
);
82 static driver_info_t
*monitor_driver(hd_data_t
*hd_data
, hd_t
*hd
);
85 /* static int chk_free_biosmem(hd_data_t *hd_data, unsigned addr, unsigned len); */
86 /* static isdn_parm_t *new_isdn_parm(isdn_parm_t **ip); */
87 static driver_info_t
*isdn_driver(hd_data_t
*hd_data
, hd_t
*hd
, cdb_isdn_card
*cic
);
88 static driver_info_t
*dsl_driver(hd_data_t
*hd_data
, hd_t
*hd
, cdb_isdn_card
*cic
);
91 static hd_res_t
*get_res(hd_t
*h
, enum resource_types t
, unsigned index
);
92 static driver_info_t
*reorder_x11(driver_info_t
*di0
, char *info
);
93 static void expand_driver_info(hd_data_t
*hd_data
, hd_t
*hd
);
94 static char *module_cmd(hd_t
*hd
, char *cmd
);
97 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
98 void hddb_init_pci(hd_data_t
*hd_data
)
100 str_list_t
*sl
= NULL
;
104 if(!hd_data
->hddb_pci
) {
106 r
= getenv("LIBHD_KERNELVERSION");
107 if(!r
|| !*r
) r
= ubuf
.release
;
108 str_printf(&s
, 0, "/lib/modules/%s/modules.pcimap", r
);
109 sl
= read_file(s
, 0, 0);
113 hd_data
->hddb_pci
= parse_pcimap(sl
);
115 sl
= free_str_list(sl
);
118 if(!hd_data
->hddb_pci_hm
) {
119 sl
= read_file("/etc/hotplug/pci.handmap", 0, 0);
120 hd_data
->hddb_pci_hm
= parse_pcimap(sl
);
121 sl
= free_str_list(sl
);
126 hddb_pci_t
*parse_pcimap(str_list_t
*file
)
132 unsigned u0
, u1
, u2
, u3
, u4
, u5
;
134 for(len
= 1, sl
= file
; sl
; sl
= sl
->next
) len
++;
136 pci
= new_mem(len
* sizeof *pci
);
138 for(p
= pci
, sl
= file
; sl
; sl
= sl
->next
) {
139 if(sscanf(sl
->str
, "%63s %x %x %x %x %x %x", buf
, &u0
, &u1
, &u2
, &u3
, &u4
, &u5
) == 7) {
140 p
->module
= new_str(buf
);
153 fprintf(stderr
, "--- pcimap ---\n");
154 for(p
= pci
; p
->module
; p
++) {
155 fprintf(stderr
, "%s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
156 p
->module
, p
->vendor
, p
->device
, p
->subvendor
, p
->subdevice
,
157 p
->pciclass
, p
->classmask
166 driver_info_t
*hd_pcidb(hd_data_t
*hd_data
, hddb_pci_t
*pci_db
, hd_t
*hd
, driver_info_t
*drv_info
)
168 unsigned vendor
, device
, subvendor
, subdevice
, pciclass
;
169 driver_info_t
**di
= NULL
, *di2
;
171 char *mod_list
[16 /* arbitrary */];
172 int mod_prio
[sizeof mod_list
/ sizeof *mod_list
];
173 int i
, prio
, mod_list_len
;
175 if(!pci_db
) return drv_info
;
177 if(ID_TAG(hd
->vendor
.id
) != TAG_PCI
) return drv_info
;
179 /* don't add module info if driver info of some other type exists */
180 for(di
= &drv_info
; *di
; di
= &(*di
)->next
) {
181 if((*di
)->any
.type
!= di_module
) return drv_info
;
184 vendor
= ID_VALUE(hd
->vendor
.id
);
185 device
= ID_VALUE(hd
->device
.id
);
186 subvendor
= ID_VALUE(hd
->sub_vendor
.id
);
187 subdevice
= ID_VALUE(hd
->sub_device
.id
);
188 pciclass
= (hd
->base_class
.id
<< 16) + ((hd
->sub_class
.id
& 0xff) << 8) + (hd
->prog_if
.id
& 0xff);
192 hd
->detail
->type
== hd_detail_pci
&&
193 (pci
= hd
->detail
->pci
.data
)
195 pciclass
= (pci
->base_class
<< 16) + ((pci
->sub_class
& 0xff) << 8) + (pci
->prog_if
& 0xff);
198 for(mod_list_len
= 0; pci_db
->module
; pci_db
++) {
200 (pci_db
->vendor
== 0xffffffff || pci_db
->vendor
== vendor
) &&
201 (pci_db
->device
== 0xffffffff || pci_db
->device
== device
) &&
202 (pci_db
->subvendor
== 0xffffffff || pci_db
->subvendor
== subvendor
) &&
203 (pci_db
->subdevice
== 0xffffffff || pci_db
->subdevice
== subdevice
) &&
204 !((pci_db
->pciclass
^ pciclass
) & pci_db
->classmask
)
206 for(di2
= drv_info
; di2
; di2
= di2
->next
) {
208 di2
->any
.type
== di_module
&&
210 di2
->any
.hddb0
->str
&&
211 !strcmp(di2
->any
.hddb0
->str
, pci_db
->module
)
218 if(pci_db
->vendor
== vendor
) prio
= 1;
219 if(pci_db
->device
== device
) prio
= 2;
220 if(pci_db
->subvendor
== subvendor
) prio
= 3;
221 if(pci_db
->subdevice
== subdevice
) prio
= 4;
223 mod_prio
[mod_list_len
] = prio
;
224 mod_list
[mod_list_len
++] = pci_db
->module
;
226 if(mod_list_len
>= sizeof mod_list
/ sizeof *mod_list
) break;
230 for(prio
= 4; prio
>= 0; prio
--) {
231 for(i
= 0; i
< mod_list_len
; i
++) {
232 if(mod_prio
[i
] == prio
) {
233 *di
= new_mem(sizeof **di
);
234 (*di
)->any
.type
= di_module
;
235 (*di
)->module
.modprobe
= 1;
236 add_str_list(&(*di
)->any
.hddb0
, mod_list
[i
]);
246 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
247 void hddb_init(hd_data_t
*hd_data
)
249 hddb_init_pci(hd_data
);
250 hddb_init_external(hd_data
);
252 #ifndef HDDB_EXTERNAL_ONLY
253 hd_data
->hddb2
[1] = &hddb_internal
;
262 void hddb_init_external(hd_data_t
*hd_data
)
264 str_list_t
*sl
, *sl0
;
266 unsigned l_start
, l_end
/* end points _past_ last element */;
267 unsigned u
, ent
, l_nr
= 1;
268 tmp_entry_t tmp_entry
[he_nomask
/* _must_ be he_nomask! */];
269 hddb_entry_mask_t entry_mask
= 0;
271 hddb_list_t dbl
= {};
274 if(hd_data
->hddb2
[0]) return;
276 hddb2
= hd_data
->hddb2
[0] = new_mem(sizeof *hd_data
->hddb2
[0]);
278 sl0
= read_file(ID_LIST
, 0, 0);
283 for(sl
= sl0
; sl
; sl
= sl
->next
, l_nr
++) {
284 l
= parse_line(sl
->str
);
286 ADD2LOG("hd.ids line %d: invalid line\n", l_nr
);
290 if(l
->prefix
== pref_empty
) continue;
293 if((state
== 2 && !entry_mask
) || state
== 1) {
294 ADD2LOG("hd.ids line %d: new item not allowed\n", l_nr
);
298 if(state
== 2 && entry_mask
) {
299 ent
= store_entry(hddb2
, tmp_entry
);
301 ADD2LOG("hd.ids line %d: internal hddb oops 1\n", l_nr
);
305 if(l_end
&& l_end
> l_start
) {
306 for(u
= l_start
; u
< l_end
; u
++) {
307 hddb2
->list
[u
].value_mask
= entry_mask
;
308 hddb2
->list
[u
].value
= ent
;
313 clear_entry(tmp_entry
);
315 l_start
= store_list(hddb2
, &dbl
);
321 ADD2LOG("hd.ids line %d: must start item first\n", l_nr
);
328 if(state
!= 1 || !entry_mask
|| l_end
<= l_start
|| l_end
< 1) {
329 ADD2LOG("hd.ids line %d: must start item first\n", l_nr
);
333 ent
= store_entry(hddb2
, tmp_entry
);
335 ADD2LOG("hd.ids line %d: internal hddb oops 2\n", l_nr
);
339 hddb2
->list
[l_end
- 1].key_mask
= entry_mask
;
340 hddb2
->list
[l_end
- 1].key
= ent
;
342 clear_entry(tmp_entry
);
343 u
= store_list(hddb2
, &dbl
);
345 ADD2LOG("hd.ids line %d: internal hddb oops 2\n", l_nr
);
353 if(state
== 1 && !entry_mask
) {
354 ADD2LOG("hd.ids line %d: driver info not allowed\n", l_nr
);
358 if(state
== 1 && l_end
> l_start
) {
359 ent
= store_entry(hddb2
, tmp_entry
);
361 ADD2LOG("hd.ids line %d: internal hddb oops 3\n", l_nr
);
365 hddb2
->list
[l_end
- 1].key_mask
= entry_mask
;
366 hddb2
->list
[l_end
- 1].key
= ent
;
368 clear_entry(tmp_entry
);
371 if(state
!= 2 || l_end
== 0) {
372 ADD2LOG("hd.ids line %d: driver info not allowed\n", l_nr
);
383 u
= add_entry(hddb2
, tmp_entry
, l
->key
, l
->value
);
388 ADD2LOG("hd.ids line %d: invalid info\n", l_nr
);
393 if(state
== 4) break; /* error */
396 /* finalize last item */
397 if(state
== 2 && entry_mask
) {
398 ent
= store_entry(hddb2
, tmp_entry
);
400 ADD2LOG("hd.ids line %d: internal hddb oops 4\n", l_nr
);
403 else if(l_end
&& l_end
> l_start
) {
404 for(u
= l_start
; u
< l_end
; u
++) {
405 hddb2
->list
[u
].value_mask
= entry_mask
;
406 hddb2
->list
[u
].value
= ent
;
411 sl0
= free_str_list(sl0
);
414 /* there was an error */
416 free_mem(hddb2
->list
);
417 free_mem(hddb2
->ids
);
418 free_mem(hddb2
->strings
);
419 hd_data
->hddb2
[0] = free_mem(hd_data
->hddb2
[0]);
424 line_t
*parse_line(char *str
)
430 /* drop leading spaces */
431 while(isspace(*str
)) str
++;
433 /* skip emtpy lines and comments */
434 if(!*str
|| *str
== ';' || *str
== '#') {
435 l
.prefix
= pref_empty
;
459 while(isspace(*str
)) str
++;
462 while(*str
&& !isspace(*str
)) str
++;
464 while(isspace(*str
)) str
++;
466 for(i
= 0; (unsigned) i
< sizeof hddb_entry_strings
/ sizeof *hddb_entry_strings
; i
++) {
467 if(!strcmp(s
, hddb_entry_strings
[i
])) {
473 if((unsigned) i
>= sizeof hddb_entry_strings
/ sizeof *hddb_entry_strings
) return NULL
;
477 /* drop trailing white space */
480 if(isspace(str
[i
- 1]))
486 /* special case: drop leading and final double quotes, if any */
488 if(i
>= 2 && l
.value
[0] == '"' && l
.value
[i
- 1] == '"') {
493 // fprintf(stderr, "pre = %d, key = %d, val = \"%s\"\n", l.prefix, l.key, l.value);
499 unsigned store_string(hddb2_data_t
*x
, char *str
)
501 unsigned l
= strlen(str
), u
;
503 if(x
->strings_len
+ l
>= x
->strings_max
) {
504 x
->strings_max
+= l
+ 0x1000; /* >4k steps */
505 x
->strings
= resize_mem(x
->strings
, x
->strings_max
* sizeof *x
->strings
);
508 /* make sure the 1st byte is 0 */
509 if(x
->strings_len
== 0) {
510 *x
->strings
= 0; /* resize_mem does _not_ clear memory */
514 if(l
== 0) return 0; /* 1st byte is always 0 */
516 strcpy(x
->strings
+ (u
= x
->strings_len
), str
);
517 x
->strings_len
+= l
+ 1;
523 unsigned store_list(hddb2_data_t
*x
, hddb_list_t
*list
)
525 if(x
->list_len
== x
->list_max
) {
526 x
->list_max
+= 0x100; /* 4k steps */
527 x
->list
= resize_mem(x
->list
, x
->list_max
* sizeof *x
->list
);
530 x
->list
[x
->list_len
++] = *list
;
532 return x
->list_len
- 1;
536 unsigned store_value(hddb2_data_t
*x
, unsigned val
)
538 if(x
->ids_len
== x
->ids_max
) {
539 x
->ids_max
+= 0x400; /* 4k steps */
540 x
->ids
= resize_mem(x
->ids
, x
->ids_max
* sizeof *x
->ids
);
543 x
->ids
[x
->ids_len
++] = val
;
545 return x
->ids_len
- 1;
549 /* returns index in hddb2->ids */
550 unsigned store_entry(hddb2_data_t
*x
, tmp_entry_t
*te
)
553 unsigned ent
= -1, u
, v
;
555 for(i
= 0; i
< he_nomask
; i
++) {
557 for(j
= 0; j
< te
[i
].len
; j
++) {
558 v
= te
[i
].val
[j
] | (1 << 31);
559 if(j
== te
[i
].len
- 1) v
&= ~(1 << 31);
560 u
= store_value(x
, v
);
561 if(ent
== -1u) ent
= u
;
569 void clear_entry(tmp_entry_t
*te
)
571 memset(te
, 0, he_nomask
* sizeof *te
);
574 void add_value(tmp_entry_t
*te
, hddb_entry_t idx
, unsigned val
)
576 if(idx
>= he_nomask
) return;
579 if((unsigned) te
->len
>= sizeof te
->val
/ sizeof *te
->val
) return;
581 te
->val
[te
->len
++] = val
;
584 int parse_id(char *str
, unsigned *id
, unsigned *range
, unsigned *mask
)
586 static unsigned id0
, val
;
588 char c
= 0, *s
, *t
= NULL
;
590 *id
= *range
= *mask
= 0;
592 if(!str
|| !*str
) return 0;
594 for(s
= str
; *str
&& !isspace(*str
); str
++);
596 c
= *(t
= str
); /* remember for later */
599 while(isspace(*str
)) str
++;
602 if(!strcmp(s
, "pci")) tag
= TAG_PCI
;
603 else if(!strcmp(s
, "usb")) tag
= TAG_USB
;
604 else if(!strcmp(s
, "special")) tag
= TAG_SPECIAL
;
605 else if(!strcmp(s
, "eisa")) tag
= TAG_EISA
;
606 else if(!strcmp(s
, "isapnp")) tag
= TAG_EISA
;
607 else if(!strcmp(s
, "pcmcia")) tag
= TAG_PCMCIA
;
610 if(t
) *t
= c
; /* restore */
614 id0
= strtoul(str
, &s
, 0);
617 id0
= name2eisa_id(str
);
621 if(!tag
) tag
= TAG_EISA
;
624 while(isspace(*s
)) s
++;
625 if(*s
&& *s
!= '&' && *s
!= '+') return 0;
627 *id
= MAKE_ID(tag
, id0
);
633 while(isspace(*s
)) s
++;
635 val
= strtoul(s
, &str
, 0);
637 if(s
== str
) return 0;
639 while(isspace(*str
)) str
++;
643 if(c
== '+') *range
= val
; else *mask
= val
;
645 return c
== '+' ? 2 : 3;
649 hddb_entry_mask_t
add_entry(hddb2_data_t
*hddb2
, tmp_entry_t
*te
, hddb_entry_t idx
, char *str
)
651 hddb_entry_mask_t mask
= 0;
653 unsigned u
, u0
, u1
, u2
;
656 for(i
= 0; (unsigned) i
< sizeof hddb_is_numeric
/ sizeof *hddb_is_numeric
; i
++) {
657 if(idx
== hddb_is_numeric
[i
]) break;
660 if((unsigned) i
< sizeof hddb_is_numeric
/ sizeof *hddb_is_numeric
) {
664 i
= parse_id(str
, &u0
, &u1
, &u2
);
668 add_value(te
, idx
, MAKE_DATA(FLAG_ID
, u0
));
672 add_value(te
, idx
, MAKE_DATA(FLAG_RANGE
, u1
));
673 add_value(te
, idx
, MAKE_DATA(FLAG_ID
, u0
));
677 add_value(te
, idx
, MAKE_DATA(FLAG_MASK
, u2
));
678 add_value(te
, idx
, MAKE_DATA(FLAG_ID
, u0
));
686 if(idx
< he_nomask
) {
690 u
= store_string(hddb2
, str
);
691 // fprintf(stderr, ">>> %s\n", str);
692 add_value(te
, idx
, MAKE_DATA(FLAG_STRING
, u
));
697 if(idx
== he_class_id
) {
698 i
= parse_id(str
, &u0
, &u1
, &u2
);
700 u
= ID_VALUE(u0
) >> 8;
701 add_value(te
, he_baseclass_id
, MAKE_DATA(FLAG_ID
, u
));
703 add_value(te
, he_subclass_id
, MAKE_DATA(FLAG_ID
, u
));
704 /* add_value(te, he_progif_id, MAKE_DATA(FLAG_ID, 0)); */
705 mask
|= (1 << he_baseclass_id
) + (1 << he_subclass_id
) /* + (1 << he_progif_id) */;
709 case he_driver_module_insmod
:
713 case he_driver_module_modprobe
:
717 case he_driver_module_config
:
721 case he_driver_xfree
:
725 case he_driver_xfree_config
:
729 case he_driver_mouse
:
733 case he_driver_display
:
746 s
= new_mem(strlen(str
) + 3);
750 mask
|= add_entry(hddb2
, te
, he_driver
, s
);
761 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
762 void hddb_dump_raw(hddb2_data_t
*hddb
, FILE *f
)
765 unsigned u
, fl
, v
, t
, id
;
770 fprintf(f
, "=== strings 0x%05x/0x%05x ===\n", hddb
->strings_len
, hddb
->strings_max
);
772 for(s
= hddb
->strings
, i
= 0, u
= 0; u
< hddb
->strings_len
; u
++) {
773 if(!hddb
->strings
[u
]) {
774 fprintf(f
, "%4d (0x%05x): \"%s\"\n", i
, (unsigned) (s
- hddb
->strings
), s
);
776 s
= hddb
->strings
+ u
+ 1;
780 fprintf(f
, "\n=== ids 0x%05x/0x%05x ===\n", hddb
->ids_len
, hddb
->ids_max
);
782 for(u
= 0; u
< hddb
->ids_len
; u
++) {
783 fprintf(f
, "0x%05x: 0x%08x ", u
, hddb
->ids
[u
]);
784 if(hddb
->ids
[u
] & (1 << 31)) fprintf(f
, " ");
785 fl
= DATA_FLAG(hddb
->ids
[u
]) & 0x7;
786 v
= DATA_VALUE(hddb
->ids
[u
]);
787 if(fl
== FLAG_STRING
&& v
< hddb
->strings_len
) {
788 fprintf(f
, "\"%s\"", hddb
->strings
+ v
);
790 else if(fl
== FLAG_MASK
) {
791 fprintf(f
, "&0x%04x", v
);
793 else if(fl
== FLAG_RANGE
) {
794 fprintf(f
, "+0x%04x", v
);
796 else if(fl
== FLAG_ID
) {
799 fprintf(f
, "%s0x%04x", hid_tag_name(t
), id
);
801 fprintf(f
, " (%s)", eisa_vendor_str(id
));
807 fprintf(f
, "\n=== search list 0x%05x/0x%05x ===\n", hddb
->list_len
, hddb
->list_max
);
809 for(u
= 0; u
< hddb
->list_len
; u
++) {
811 "%4d: 0x%08x 0x%08x 0x%05x 0x%05x\n",
812 u
, hddb
->list
[u
].key_mask
, hddb
->list
[u
].value_mask
,
813 hddb
->list
[u
].key
, hddb
->list
[u
].value
819 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
820 void hddb_dump_ent_name(hddb2_data_t
*hddb
, FILE *f
, char pre
, hddb_entry_t ent
)
822 int len
, tab_ind
= 24;
824 if(ent
>= sizeof hddb_entry_strings
/ sizeof *hddb_entry_strings
) return;
826 fprintf(f
, "%c%s\t", pre
, hddb_entry_strings
[ent
]);
828 len
= strlen(hddb_entry_strings
[ent
]) + 1;
830 for(len
= (len
& ~7) + 8; len
< tab_ind
; len
+= 8) {
836 void hddb_dump_skey(hddb2_data_t
*hddb
, FILE *f
, prefix_t pre
, hddb_entry_mask_t key_mask
, unsigned key
)
838 static char pref_char
[5] = { ' ', ' ', '&', '|', '+' };
840 unsigned rm_val
= 0, r_or_m
= 0;
841 unsigned fl
, val
, *ids
, id
, tag
, u
;
845 if(pre
>= sizeof pref_char
) return;
847 if(key
>= hddb
->ids_len
) return;
849 ids
= hddb
->ids
+ key
;
851 for(ent
= 0; ent
< he_nomask
&& key_mask
; ent
++, key_mask
>>= 1) {
852 if(!(key_mask
& 1)) continue;
854 fl
= DATA_FLAG(*ids
);
855 val
= DATA_VALUE(*ids
);
859 while((fl
& FLAG_CONT
)) {
860 if(fl
== (FLAG_CONT
| FLAG_RANGE
)) {
864 else if(fl
== (FLAG_CONT
| FLAG_MASK
)) {
874 fl
= DATA_FLAG(*ids
);
875 val
= DATA_VALUE(*ids
);
880 if(ent
!= he_driver
) {
881 hddb_dump_ent_name(hddb
, f
, pref_char
[pre
], ent
);
886 if(tag
== TAG_EISA
&& (ent
== he_vendor_id
|| ent
== he_subvendor_id
)) {
887 fprintf(f
, "%s", eisa_vendor_str(id
));
891 if(ent
== he_bus_id
|| ent
== he_subclass_id
|| ent
== he_progif_id
) {
894 else if(ent
== he_baseclass_id
) {
897 fprintf(f
, "%s0x%0*x", hid_tag_name(tag
), u
, id
);
900 fprintf(f
, "%c0x%04x", r_or_m
== 1 ? '+' : '&', rm_val
);
903 else if(fl
== FLAG_STRING
) {
904 if(val
< hddb
->strings_len
) {
905 str_val
= hddb
->strings
+ val
;
906 fprintf(f
, "%s", str_val
);
915 fl
= DATA_FLAG(*ids
) & ~FLAG_CONT
;
916 val
= DATA_VALUE(*ids
);
917 if(fl
!= FLAG_STRING
) break;
919 if(val
< hddb
->strings_len
) str_val
= hddb
->strings
+ val
;
921 if(!*str_val
&& !str_val
[1] == '\t') break;
929 i
= he_driver_xfree_config
;
933 i
= he_driver_module_insmod
;
937 i
= he_driver_module_modprobe
;
941 i
= he_driver_module_config
;
949 i
= he_driver_display
;
962 hddb_dump_ent_name(hddb
, f
, pref_char
[pre
], i
);
963 fprintf(f
, "%s\n", str_val
+ 2);
965 while((*ids
& (1 << 31)));
968 /* at this point 'ids' must be the _current_ entry (_not_ the next) */
970 /* skip potential garbage/unhandled entries */
971 while((*ids
& (1 << 31))) ids
++;
975 if(pre
!= pref_add
) pre
= pref_and
;
980 void hddb_dump(hddb2_data_t
*hddb
, FILE *f
)
986 for(u
= 0; u
< hddb
->list_len
; u
++) {
987 hddb_dump_skey(hddb
, f
, pref_new
, hddb
->list
[u
].key_mask
, hddb
->list
[u
].key
);
988 hddb_dump_skey(hddb
, f
, pref_add
, hddb
->list
[u
].value_mask
, hddb
->list
[u
].value
);
994 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
995 int compare_ids(hddb2_data_t
*hddb
, hddb_search_t
*hs
, hddb_entry_mask_t mask
, unsigned key
)
998 unsigned rm_val
= 0, r_or_m
= 0, res
= 0;
999 unsigned fl
, val
, ok
, *ids
, id
;
1000 char *str
, *str_val
;
1002 if(key
>= hddb
->ids_len
) return 1;
1004 ids
= hddb
->ids
+ key
;
1006 for(ent
= 0; ent
< he_nomask
&& mask
&& !res
; ent
++, mask
>>= 1) {
1007 if(!(mask
& 1)) continue;
1009 fl
= DATA_FLAG(*ids
);
1010 val
= DATA_VALUE(*ids
);
1014 while((fl
& FLAG_CONT
)) {
1015 if(fl
== (FLAG_CONT
| FLAG_RANGE
)) {
1019 else if(fl
== (FLAG_CONT
| FLAG_MASK
)) {
1029 fl
= DATA_FLAG(*ids
);
1030 val
= DATA_VALUE(*ids
);
1036 str
= str_val
= NULL
;
1045 case he_baseclass_id
:
1046 id
= hs
->base_class
.id
;
1049 case he_subclass_id
:
1050 id
= hs
->sub_class
.id
;
1054 id
= hs
->prog_if
.id
;
1065 case he_subvendor_id
:
1066 id
= hs
->sub_vendor
.id
;
1069 case he_subdevice_id
:
1070 id
= hs
->sub_device
.id
;
1074 id
= hs
->revision
.id
;
1076 case he_detail_ccw_data_cu_model
:
1077 id
= hs
->cu_model
.id
;
1085 else if(fl
== FLAG_STRING
) {
1086 if(val
< hddb
->strings_len
) str_val
= hddb
->strings
+ val
;
1093 case he_baseclass_name
:
1094 str
= hs
->base_class
.name
;
1097 case he_subclass_name
:
1098 str
= hs
->sub_class
.name
;
1101 case he_progif_name
:
1102 str
= hs
->prog_if
.name
;
1105 case he_vendor_name
:
1106 str
= hs
->vendor
.name
;
1109 case he_device_name
:
1110 str
= hs
->device
.name
;
1113 case he_subvendor_name
:
1114 str
= hs
->sub_vendor
.name
;
1117 case he_subdevice_name
:
1118 str
= hs
->sub_device
.name
;
1122 str
= hs
->revision
.name
;
1142 if(id
< val
|| id
>= val
+ rm_val
) res
= 1;
1146 if((id
& ~rm_val
) != val
) res
= 1;
1150 if(id
!= val
) res
= 1;
1155 if(str
&& str_val
) {
1156 if(strcmp(str
, str_val
)) res
= 1;
1172 "cmp: 0x%05x: (ent = %2d, id = 0x%x, val = 0x%x%c0x%x) = %d\n",
1173 key
, ent
, id
, val
, r_or_m
== 1 ? '+' : '&', rm_val
, res
1178 "cmp: 0x%05x: (ent = %2d, id = 0x%x, val = 0x%x) = %d\n",
1179 key
, ent
, id
, val
, res
1186 "cmp: 0x%05x: (ent = %2d, id = \"%s\", val = \"%s\") = %d\n",
1187 key
, ent
, str
, str_val
, res
1193 printf("cmp: 0x%05x: (ent = %2d, *** unhandled key ***) = %d\n", key
, ent
, res
);
1197 /* at this point 'ids' must be the _current_ entry (_not_ the next) */
1199 /* skip potential garbage/unhandled entries */
1200 while((*ids
& (1 << 31))) ids
++;
1209 hddb2_data_t
*hddb
, hddb_search_t
*hs
,
1210 hddb_entry_mask_t key_mask
, hddb_entry_mask_t mask
, unsigned val_idx
1215 unsigned fl
, val
, ok
;
1216 char **str
, *str_val
;
1218 if(val_idx
>= hddb
->ids_len
) return;
1220 ids
= hddb
->ids
+ val_idx
;
1222 for(ent
= 0; ent
< he_nomask
&& mask
; ent
++, mask
>>= 1) {
1223 if(!(mask
& 1)) continue;
1225 fl
= DATA_FLAG(*ids
);
1226 val
= DATA_VALUE(*ids
);
1241 case he_baseclass_id
:
1242 id
= &hs
->base_class
.id
;
1245 case he_subclass_id
:
1246 id
= &hs
->sub_class
.id
;
1250 id
= &hs
->prog_if
.id
;
1254 id
= &hs
->vendor
.id
;
1258 id
= &hs
->device
.id
;
1261 case he_subvendor_id
:
1262 id
= &hs
->sub_vendor
.id
;
1265 case he_subdevice_id
:
1266 id
= &hs
->sub_device
.id
;
1270 id
= &hs
->revision
.id
;
1273 case he_detail_ccw_data_cu_model
:
1274 id
= &hs
->cu_model
.id
;
1282 else if(fl
== FLAG_STRING
) {
1283 if(val
< hddb
->strings_len
) str_val
= hddb
->strings
+ val
;
1287 str
= &hs
->bus
.name
;
1290 case he_baseclass_name
:
1291 str
= &hs
->base_class
.name
;
1294 case he_subclass_name
:
1295 str
= &hs
->sub_class
.name
;
1298 case he_progif_name
:
1299 str
= &hs
->prog_if
.name
;
1302 case he_vendor_name
:
1303 str
= &hs
->vendor
.name
;
1306 case he_device_name
:
1307 str
= &hs
->device
.name
;
1310 case he_subvendor_name
:
1311 str
= &hs
->sub_vendor
.name
;
1314 case he_subdevice_name
:
1315 str
= &hs
->sub_device
.name
;
1319 str
= &hs
->revision
.name
;
1331 str
= &hs
->requires
;
1341 (hs
->value_mask
[ent
] & key_mask
) == hs
->value_mask
[ent
] &&
1342 key_mask
!= hs
->value_mask
[ent
]
1344 hs
->value_mask
[ent
] = key_mask
;
1345 hs
->value
|= 1 << ent
;
1348 /* don't change if already set */
1353 if((hs
->value
& (1 << ent
))) {
1354 /* don't change if already set */
1357 else if(ent
!= he_driver
) {
1358 hs
->value
|= 1 << ent
;
1367 printf("add: 0x%05x: (ent = %2d, val = 0x%08x)\n", val_idx
, ent
, val
);
1374 printf("add: 0x%05x: (ent = %2d, val = \"%s\")\n", val_idx
, ent
, str_val
);
1380 hs
->driver
= free_str_list(hs
->driver
);
1383 fl
= DATA_FLAG(*ids
) & ~FLAG_CONT
;
1384 val
= DATA_VALUE(*ids
);
1385 if(fl
!= FLAG_STRING
) break;
1387 if(val
< hddb
->strings_len
) str_val
= hddb
->strings
+ val
;
1390 printf("add: 0x%05x: (ent = %2d, val = \"%s\")\n", val_idx
, ent
, str_val
);
1392 add_str_list(&hs
->driver
, str_val
);
1394 while((*ids
& (1 << 31)));
1402 printf("add: 0x%05x: (ent = %2d, *** unhandled value ***)\n", val_idx
, ent
);
1406 /* at this point 'ids' must be the _current_ entry (_not_ the next) */
1408 /* skip potential garbage/unhandled entries */
1409 while((*ids
& (1 << 31))) ids
++;
1415 int hddb_search(hd_data_t
*hd_data
, hddb_search_t
*hs
, int max_recursions
)
1421 hddb_entry_mask_t all_values
= 0;
1425 if(!max_recursions
) max_recursions
= 2;
1427 while(max_recursions
--) {
1428 for(db_idx
= 0; (unsigned) db_idx
< sizeof hd_data
->hddb2
/ sizeof *hd_data
->hddb2
; db_idx
++) {
1429 if(!(hddb
= hd_data
->hddb2
[db_idx
])) continue;
1431 for(u
= 0; u
< hddb
->list_len
; u
++) {
1433 (hs
->key
& hddb
->list
[u
].key_mask
) == hddb
->list
[u
].key_mask
1434 /* && (hs->value & hddb->list[u].value_mask) != hddb->list[u].value_mask */
1436 i
= compare_ids(hddb
, hs
, hddb
->list
[u
].key_mask
, hddb
->list
[u
].key
);
1438 complete_ids(hddb
, hs
,
1439 hddb
->list
[u
].key_mask
,
1440 hddb
->list
[u
].value_mask
, hddb
->list
[u
].value
1447 all_values
|= hs
->value
;
1449 if(!max_recursions
) break;
1451 hs
->key
|= hs
->value
;
1453 memset(hs
->value_mask
, 0, sizeof hs
->value_mask
);
1456 hs
->value
= all_values
;
1461 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1463 void test_db(hd_data_t
*hd_data
)
1465 hddb_search_t hs
= {};
1469 hs
.key
|= (1 << he_bus_id
) + (1 << he_serial
);
1471 hs
.serial
= "ser 0123";
1473 i
= hddb_search(hd_data
, &hs
, 0);
1475 printf("%d, >%s<\n", i
, hs
.bus
.name
);
1480 str_list_t
*get_hddb_packages(hd_data_t
*hd_data
)
1486 unsigned device_class(hd_data_t
*hd_data
, unsigned vendor
, unsigned device
)
1488 hddb_search_t hs
= {};
1490 hs
.vendor
.id
= vendor
;
1491 hs
.device
.id
= device
;
1492 hs
.key
|= (1 << he_vendor_id
) + (1 << he_device_id
);
1494 hddb_search(hd_data
, &hs
, 1);
1497 (hs
.value
& ((1 << he_baseclass_id
) + (1 << he_subclass_id
))) ==
1498 ((1 << he_baseclass_id
) + (1 << he_subclass_id
))
1500 return (hs
.base_class
.id
<< 8) + (hs
.sub_class
.id
& 0xff);
1507 unsigned sub_device_class(hd_data_t
*hd_data
, unsigned vendor
, unsigned device
, unsigned sub_vendor
, unsigned sub_device
)
1509 hddb_search_t hs
= {};
1511 hs
.vendor
.id
= vendor
;
1512 hs
.device
.id
= device
;
1513 hs
.sub_vendor
.id
= sub_vendor
;
1514 hs
.sub_device
.id
= sub_device
;
1515 hs
.key
|= (1 << he_vendor_id
) + (1 << he_device_id
) + (1 << he_subvendor_id
) + (1 << he_subdevice_id
);
1517 hddb_search(hd_data
, &hs
, 1);
1520 (hs
.value
& ((1 << he_baseclass_id
) + (1 << he_subclass_id
))) ==
1521 ((1 << he_baseclass_id
) + (1 << he_subclass_id
))
1523 return (hs
.base_class
.id
<< 8) + (hs
.sub_class
.id
& 0xff);
1530 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1531 void hddb_add_info(hd_data_t
*hd_data
, hd_t
*hd
)
1533 hddb_search_t hs
= {};
1534 driver_info_t
*new_driver_info
= NULL
;
1539 if(hd
->tag
.fixed
) return;
1541 hs
.bus
.id
= hd
->bus
.id
;
1542 hs
.key
|= 1 << he_bus_id
;
1544 hs
.base_class
.id
= hd
->base_class
.id
;
1545 hs
.key
|= 1 << he_baseclass_id
;
1547 hs
.sub_class
.id
= hd
->sub_class
.id
;
1548 hs
.key
|= 1 << he_subclass_id
;
1550 hs
.prog_if
.id
= hd
->prog_if
.id
;
1551 hs
.key
|= 1 << he_progif_id
;
1554 hs
.vendor
.id
= hd
->vendor
.id
;
1555 hs
.key
|= 1 << he_vendor_id
;
1558 if(hd
->vendor
.name
) {
1559 hs
.vendor
.name
= hd
->vendor
.name
;
1560 hs
.key
|= 1 << he_vendor_name
;
1564 hs
.device
.id
= hd
->device
.id
;
1565 hs
.key
|= 1 << he_device_id
;
1568 if(hd
->device
.name
) {
1569 hs
.device
.name
= hd
->device
.name
;
1570 hs
.key
|= 1 << he_device_name
;
1573 if(hd
->sub_vendor
.id
) {
1574 hs
.sub_vendor
.id
= hd
->sub_vendor
.id
;
1575 hs
.key
|= 1 << he_subvendor_id
;
1578 if(hd
->sub_device
.id
) {
1579 hs
.sub_device
.id
= hd
->sub_device
.id
;
1580 hs
.key
|= 1 << he_subdevice_id
;
1583 hs
.revision
.id
= hd
->revision
.id
;
1584 hs
.key
|= 1 << he_rev_id
;
1586 if(hd
->revision
.name
) {
1587 hs
.revision
.name
= hd
->revision
.name
;
1588 hs
.key
|= 1 << he_rev_name
;
1592 hs
.serial
= hd
->serial
;
1593 hs
.key
|= 1 << he_serial
;
1596 if(hd
->detail
&& hd
->detail
->ccw
.data
) {
1597 hs
.cu_model
.id
=hd
->detail
->ccw
.data
->cu_model
;
1598 hs
.key
|= 1 << he_detail_ccw_data_cu_model
;
1601 hddb_search(hd_data
, &hs
, 0);
1603 if((hs
.value
& (1 << he_bus_id
))) {
1604 hd
->bus
.id
= hs
.bus
.id
;
1607 if((hs
.value
& (1 << he_bus_name
))) {
1608 if(!hd
->ref
) free_mem(hd
->bus
.name
);
1609 hd
->bus
.name
= new_str(hs
.bus
.name
);
1612 if((hs
.value
& (1 << he_baseclass_id
))) {
1613 hd
->base_class
.id
= hs
.base_class
.id
;
1616 if((hs
.value
& (1 << he_baseclass_name
))) {
1617 if(!hd
->ref
) free_mem(hd
->base_class
.name
);
1618 hd
->base_class
.name
= new_str(hs
.base_class
.name
);
1621 if((hs
.value
& (1 << he_subclass_id
))) {
1622 hd
->sub_class
.id
= hs
.sub_class
.id
;
1625 if((hs
.value
& (1 << he_subclass_name
))) {
1626 if(!hd
->ref
) free_mem(hd
->sub_class
.name
);
1627 hd
->sub_class
.name
= new_str(hs
.sub_class
.name
);
1630 if((hs
.value
& (1 << he_progif_id
))) {
1631 hd
->prog_if
.id
= hs
.prog_if
.id
;
1634 if((hs
.value
& (1 << he_progif_name
))) {
1635 if(!hd
->ref
) free_mem(hd
->prog_if
.name
);
1636 hd
->prog_if
.name
= new_str(hs
.prog_if
.name
);
1639 if((hs
.value
& (1 << he_requires
))) {
1640 if(!hd
->ref
) hd
->requires
= free_str_list(hd
->requires
);
1641 hd
->requires
= hd_split('|', hs
.requires
);
1644 if((hs
.value
& (1 << he_vendor_id
))) {
1645 hd
->vendor
.id
= hs
.vendor
.id
;
1648 if((hs
.value
& (1 << he_vendor_name
))) {
1649 if(!hd
->ref
) free_mem(hd
->vendor
.name
);
1650 hd
->vendor
.name
= new_str(hs
.vendor
.name
);
1653 if((hs
.value
& (1 << he_device_id
))) {
1654 hd
->device
.id
= hs
.device
.id
;
1657 if((hs
.value
& (1 << he_device_name
))) {
1658 if(!hd
->ref
) free_mem(hd
->device
.name
);
1659 hd
->device
.name
= new_str(hs
.device
.name
);
1662 if((hs
.value
& (1 << he_subvendor_id
))) {
1663 hd
->sub_vendor
.id
= hs
.sub_vendor
.id
;
1666 if((hs
.value
& (1 << he_subvendor_name
))) {
1667 if(!hd
->ref
) free_mem(hd
->sub_vendor
.name
);
1668 hd
->sub_vendor
.name
= new_str(hs
.sub_vendor
.name
);
1671 if((hs
.value
& (1 << he_subdevice_id
))) {
1672 hd
->sub_device
.id
= hs
.sub_device
.id
;
1675 if((hs
.value
& (1 << he_subdevice_name
))) {
1676 if(!hd
->ref
) free_mem(hd
->sub_device
.name
);
1677 hd
->sub_device
.name
= new_str(hs
.sub_device
.name
);
1680 if((hs
.value
& (1 << he_detail_ccw_data_cu_model
))) {
1681 if(hd
->detail
&& hd
->detail
->ccw
.data
)
1682 hd
->detail
->ccw
.data
->cu_model
=hs
.cu_model
.id
;
1685 /* look for sub vendor again */
1687 if(!hd
->sub_vendor
.name
&& hd
->sub_vendor
.id
) {
1688 hddb_search_t hs2
= {};
1690 hs2
.vendor
.id
= hd
->sub_vendor
.id
;
1691 hs2
.key
|= 1 << he_vendor_id
;
1693 hddb_search(hd_data
, &hs2
, 1);
1695 if((hs2
.value
& (1 << he_vendor_name
))) {
1696 hd
->sub_vendor
.name
= new_str(hs2
.vendor
.name
);
1700 /* look for compat device name */
1702 hd
->compat_vendor
.id
&&
1703 hd
->compat_device
.id
&&
1704 !hd
->compat_vendor
.name
&&
1705 !hd
->compat_device
.name
1707 hddb_search_t hs2
= {};
1709 hs2
.vendor
.id
= hd
->compat_vendor
.id
;
1710 hs2
.key
|= 1 << he_vendor_id
;
1712 hs2
.device
.id
= hd
->compat_device
.id
;
1713 hs2
.key
|= 1 << he_device_id
;
1715 hddb_search(hd_data
, &hs2
, 1);
1717 if((hs2
.value
& (1 << he_vendor_name
))) {
1718 hd
->compat_vendor
.name
= new_str(hs2
.vendor
.name
);
1721 if((hs2
.value
& (1 << he_device_name
))) {
1722 hd
->compat_device
.name
= new_str(hs2
.device
.name
);
1726 /* get package info for compat device id */
1729 hddb_search_t hs2
= {};
1731 hs2
.vendor
.id
= hd
->compat_vendor
.id
;
1732 hs2
.key
|= 1 << he_vendor_id
;
1734 hs2
.device
.id
= hd
->compat_device
.id
;
1735 hs2
.key
|= 1 << he_device_id
;
1737 hddb_search(hd_data
, &hs2
, 1);
1739 if((hs2
.value
& (1 << he_requires
))) {
1740 hd
->requires
= hd_split('|', hs2
.requires
);
1744 /* get driver info */
1747 if((cic
= get_isdn_info(hd
))) {
1748 new_driver_info
= isdn_driver(hd_data
, hd
, cic
);
1749 if(!hd
->model
&& cic
->lname
&& *cic
->lname
) {
1750 hd
->model
= new_str(cic
->lname
);
1754 if (!new_driver_info
&& ((cic
= get_dsl_info(hd
)))) {
1755 new_driver_info
= dsl_driver(hd_data
, hd
, cic
);
1756 if(!hd
->model
&& cic
->lname
&& *cic
->lname
) {
1757 hd
->model
= new_str(cic
->lname
);
1763 if(!new_driver_info
) {
1764 new_driver_info
= hd_pcidb(hd_data
, hd_data
->hddb_pci_hm
, hd
, new_driver_info
);
1767 if(!new_driver_info
&& (hs
.value
& (1 << he_driver
))) {
1768 new_driver_info
= hddb_to_device_driver(hd_data
, &hs
);
1771 if(!new_driver_info
&& (hd
->compat_vendor
.id
|| hd
->compat_device
.id
)) {
1772 memset(&hs
, 0, sizeof hs
);
1774 if(hd
->compat_vendor
.id
) {
1775 hs
.vendor
.id
= hd
->compat_vendor
.id
;
1776 hs
.key
|= 1 << he_vendor_id
;
1778 if(hd
->compat_device
.id
) {
1779 hs
.device
.id
= hd
->compat_device
.id
;
1780 hs
.key
|= 1 << he_device_id
;
1783 hddb_search(hd_data
, &hs
, 1);
1785 if((hs
.value
& (1 << he_driver
))) {
1786 new_driver_info
= hddb_to_device_driver(hd_data
, &hs
);
1790 if(!new_driver_info
&& hd
->base_class
.id
== bc_keyboard
) {
1791 new_driver_info
= kbd_driver(hd_data
, hd
);
1794 if(!new_driver_info
&& hd
->base_class
.id
== bc_monitor
) {
1795 new_driver_info
= monitor_driver(hd_data
, hd
);
1798 new_driver_info
= hd_pcidb(hd_data
, hd_data
->hddb_pci
, hd
, new_driver_info
);
1800 if(new_driver_info
) {
1802 hd
->driver_info
= free_driver_info(hd
->driver_info
);
1804 hd
->driver_info
= new_driver_info
;
1805 expand_driver_info(hd_data
, hd
);
1808 free_str_list(hs
.driver
);
1812 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1813 driver_info_t
*hddb_to_device_driver(hd_data_t
*hd_data
, hddb_search_t
*hs
)
1816 driver_info_t
*di
= NULL
, *di0
= NULL
;
1819 for(sl
= hs
->driver
; sl
; sl
= sl
->next
) {
1820 if(!sl
->str
|| !*sl
->str
|| sl
->str
[1] != '\t') return NULL
;
1822 if(di
&& (*sl
->str
== 'M' || *sl
->str
== 'X')) {
1823 add_str_list(&di
->any
.hddb1
, sl
->str
+ 2);
1828 di
= di
->next
= new_mem(sizeof *di
);
1830 di
= di0
= new_mem(sizeof *di
);
1834 di
->any
.type
= di_display
;
1838 di
->module
.modprobe
= 1;
1840 di
->any
.type
= di_module
;
1844 di
->any
.type
= di_mouse
;
1848 di
->any
.type
= di_x11
;
1852 di
->any
.type
= di_any
;
1855 s
= new_str(sl
->str
+ 2);
1856 for(t0
= s
; (t
= strsep(&t0
, "|")); ) {
1857 add_str_list(&di
->any
.hddb0
, t
);
1866 driver_info_t
*kbd_driver(hd_data_t
*hd_data
, hd_t
*hd
)
1869 driver_info_kbd_t
*ki
;
1870 int arch
= hd_cpu_arch(hd_data
);
1879 3 Canadian-Bilingual
1889 13 International (ISO)
1894 18 Netherlands/Dutch
1916 } country_code
[] = {
1917 { 5, "cs", "cz-us-qwertz" },
1918 { 8, "fr", "fr-latin1" },
1919 { 9, "de", "de-latin1-nodeadkeys" },
1923 { 23, "ru", "ru1" },
1929 if(hd
->sub_class
.id
== sc_keyboard_console
) return NULL
;
1931 di
= new_mem(sizeof *di
);
1932 di
->kbd
.type
= di_kbd
;
1939 ki
->XkbRules
= new_str("xfree86");
1940 ki
->XkbModel
= new_str("pc104");
1945 ki
->XkbRules
= new_str("xfree86");
1946 ki
->XkbModel
= new_str("macintosh");
1947 for(hd_tmp
= hd_data
->hd
; hd_tmp
; hd_tmp
= hd_tmp
->next
) {
1949 hd_tmp
->base_class
.id
== bc_internal
&&
1950 hd_tmp
->sub_class
.id
== sc_int_cpu
&&
1952 hd_tmp
->detail
->type
== hd_detail_cpu
&&
1953 hd_tmp
->detail
->cpu
.data
1955 s1
= hd_tmp
->detail
->cpu
.data
->vend_name
;
1956 if(s1
&& (strstr(s1
, "CHRP ") == s1
|| strstr(s1
, "PReP ") == s1
)) {
1957 free_mem(ki
->XkbModel
);
1958 ki
->XkbModel
= new_str("pc104");
1966 if(hd
->vendor
.id
== MAKE_ID(TAG_SPECIAL
, 0x0202)) {
1967 ki
->XkbRules
= new_str("sun");
1968 u
= ID_VALUE(hd
->device
.id
);
1969 if(u
== 4) ki
->XkbModel
= new_str("type4");
1971 ki
->XkbModel
= new_str(ID_VALUE(hd
->sub_device
.id
) == 2 ? "type5_euro" : "type5");
1975 switch(hd
->prog_if
.id
) {
1976 case 0: case 1: case 33: case 34: case 80: case 81:
1978 s1
= "us"; s2
= "sunkeymap";
1982 s1
= "fr"; s2
= "sunt5-fr-latin1"; // fr_BE?
1989 case 4: case 36: case 83:
1993 case 5: case 37: case 84:
1994 s1
= "de"; s2
= "sunt5-de-latin1";
1997 case 6: case 38: case 85:
2001 case 7: case 39: case 86:
2005 case 8: case 40: case 87:
2007 if(u
== 4) s2
= "sunt4-no-latin1";
2010 case 9: case 41: case 88:
2014 case 10: case 42: case 89:
2016 s2
= u
== 4 ? "sunt4-es" : "sunt5-es";
2019 case 11: case 43: case 90:
2020 s1
= "se"; s2
= "sunt5-fi-latin1"; // se is swedish, not fi
2023 case 12: case 44: case 91:
2024 s1
= "fr"; s2
= "sunt5-fr-latin1"; // fr_CH
2027 case 13: case 45: case 92:
2028 s1
= "de"; s2
= "sunt5-de-latin1"; // de_CH
2031 case 14: case 46: case 93:
2032 s1
= "gb"; s2
= "sunt5-uk";
2035 case 16: case 47: case 94:
2039 case 17: case 48: case 95:
2043 case 32: case 49: case 96:
2048 s1
= "fr"; s2
= "sunt5-fr-latin1"; // fr_CA
2056 s1
= "pl"; s2
= "sun-pl";
2064 s1
= "ru"; s2
= "sunt5-ru";
2067 ki
->XkbLayout
= new_str(s1
);
2068 ki
->keymap
= new_str(s2
);
2071 ki
->XkbRules
= new_str("xfree86");
2072 ki
->XkbModel
= new_str("pc104");
2077 ki
->XkbRules
= new_str("xfree86");
2081 hd
->bus
.id
== bus_usb
&&
2083 hd
->detail
->type
== hd_detail_usb
&&
2084 (usb
= hd
->detail
->usb
.data
) &&
2087 for(u
= 0; u
< sizeof country_code
/ sizeof *country_code
; u
++) {
2088 if(country_code
[u
].country
== usb
->country
) {
2089 if(!ki
->XkbLayout
) ki
->XkbLayout
= new_str(country_code
[u
].layout
);
2090 if(!ki
->keymap
) ki
->keymap
= new_str(country_code
[u
].keymap
);
2100 driver_info_t
*monitor_driver(hd_data_t
*hd_data
, hd_t
*hd
)
2102 driver_info_t
*di
= NULL
;
2103 driver_info_display_t
*ddi
;
2106 unsigned width
= 640, height
= 480;
2110 hd
->detail
->type
== hd_detail_monitor
&&
2111 (mi
= hd
->detail
->monitor
.data
) &&
2114 di
= new_mem(sizeof *di
);
2115 di
->display
.type
= di_display
;
2116 ddi
= &(di
->display
);
2118 ddi
->min_vsync
= mi
->min_vsync
;
2119 ddi
->max_vsync
= mi
->max_vsync
;
2120 ddi
->min_hsync
= mi
->min_hsync
;
2121 ddi
->max_hsync
= mi
->max_hsync
;
2123 for(res
= hd
->res
; res
; res
= res
->next
) {
2124 if(res
->any
.type
== res_monitor
) {
2125 if(res
->monitor
.width
* res
->monitor
.height
> width
* height
) {
2126 width
= res
->monitor
.width
;
2127 height
= res
->monitor
.height
;
2133 ddi
->height
= height
;
2143 int chk_free_biosmem(hd_data_t
*hd_data
, unsigned addr
, unsigned len
)
2148 addr
-= hd_data
->bios_rom
.start
;
2150 !hd_data
->bios_rom
.data
||
2151 addr
>= hd_data
->bios_rom
.size
||
2152 addr
+ len
> hd_data
->bios_rom
.size
2155 for(c
= 0xff, u
= addr
; u
< addr
+ len
; u
++) {
2156 c
&= hd_data
->bios_rom
.data
[u
];
2159 return c
== 0xff ? 1 : 0;
2162 isdn_parm_t
*new_isdn_parm(isdn_parm_t
**ip
)
2164 while(*ip
) ip
= &(*ip
)->next
;
2166 return *ip
= new_mem(sizeof **ip
);
2170 driver_info_t
*isdn_driver(hd_data_t
*hd_data
, hd_t
*hd
, cdb_isdn_card
*cic
)
2172 driver_info_t
*di0
, *di
;
2173 cdb_isdn_vario
*civ
;
2175 uint64_t i, irqs, irqs2;
2179 str_list_t
*sl
, *sl0
;
2181 if(!cic
) return NULL
;
2183 di0
= new_mem(sizeof *di0
);
2188 while((civ
= hd_cdbisdn_get_vario(drv
))) {
2189 drv
= civ
->next_vario
;
2191 di
->next
= new_mem(sizeof *di
);
2196 di
->isdn
.type
= di_isdn
;
2197 di
->isdn
.i4l_type
= civ
->typ
;
2198 di
->isdn
.i4l_subtype
= civ
->subtyp
;
2199 di
->isdn
.i4l_name
= new_str(cic
->lname
);
2201 if(civ
->need_pkg
&& *civ
->need_pkg
) {
2202 sl0
= hd_split(',', (char *) civ
->need_pkg
);
2203 for(sl
= sl0
; sl
; sl
= sl
->next
) {
2204 if(!search_str_list(hd
->requires
, sl
->str
)) {
2205 add_str_list(&hd
->requires
, sl
->str
);
2211 if(hd
->bus
.id
== bus_pci
) continue;
2214 civ
= hd_cdbisdn_get_vario(cic
->vario
);
2216 if (civ
->irq
&& civ
->irq
[0]) {
2217 ip
= new_isdn_parm(&di
->isdn
.params
);
2218 ip
->name
= new_str("IRQ");
2219 ip
->type
= CDBISDN_P_IRQ
;
2221 if (civ
->io
&& civ
->io
[0]) {
2222 ip
= new_isdn_parm(&di
->isdn
.params
);
2223 ip
->name
= new_str("IO");
2224 ip
->type
= CDBISDN_P_IO
;
2226 if (civ
->membase
&& civ
->membase
[0]) {
2227 ip
= new_isdn_parm(&di
->isdn
.params
);
2228 ip
->name
= new_str("MEMBASE");
2229 ip
->type
= CDBISDN_P_MEM
;
2231 while((ipi
= hd_ihw_get_parameter(ici
->handle
, pnr
++))) {
2232 ip
= new_isdn_parm(&di
->isdn
.params
);
2233 ip
->name
= new_str(ipi
->name
);
2234 ip
->type
= ipi
->type
& P_TYPE_MASK
;
2235 ip
->flags
= ipi
->flags
& P_PROPERTY_MASK
;
2236 ip
->def_value
= ipi
->def_value
;
2237 if(ipi
->list
) ip
->alt_values
= *ipi
->list
;
2238 ip
->alt_value
= new_mem(ip
->alt_values
* sizeof *ip
->alt_value
);
2239 for(i
= 0; i
< ip
->alt_values
; i
++) {
2240 ip
->alt_value
[i
] = ipi
->list
[i
+ 1];
2244 if((ip
->flags
& P_SOFTSET
)) {
2247 update_irq_usage(hd_data
);
2249 for(i
= 0; i
< ip
->alt_values
; i
++) {
2250 irqs
|= 1ull << ip
->alt_value
[i
];
2252 irqs
&= ~(hd_data
->used_irqs
| hd_data
->assigned_irqs
);
2254 irqs
&= 0xffffull
; /* max. 16 on intel */
2256 * The point is, that this is relevant for isa boards only
2257 * and those have irq values < 16 anyway. So it really
2258 * doesn't matter if we mask with 0xffff or not.
2266 irqs2
= irqs
& ~0xc018ull
;
2267 /* see if we can avoid irqs 3,4,14,15 */
2268 if(irqs2
) irqs
= irqs2
;
2270 /* try default value first */
2271 if(ip
->def_value
&& (irqs
& (1ull << ip
->def_value
))) {
2272 irq_val
= ip
->def_value
;
2275 for(i
= 0; i
< 64 && irqs
; i
++, irqs
>>= 1) {
2276 if((irqs
& 1)) irq_val
= i
;
2280 ip
->value
= irq_val
;
2281 hd_data
->assigned_irqs
|= 1ull << irq_val
;
2289 if(!hd_data
->bios_rom
.data
) {
2291 ip
->value
= ip
->def_value
;
2295 /* ###### 0x2000 is just guessing -> should be provided by libihw */
2296 if(ip
->def_value
&& chk_free_biosmem(hd_data
, ip
->def_value
, 0x2000)) {
2297 ip
->value
= ip
->def_value
;
2300 for(i
= ip
->alt_values
- 1; i
>= 0; i
--) {
2301 if(chk_free_biosmem(hd_data
, ip
->alt_value
[i
], 0x2000)) {
2302 ip
->value
= ip
->alt_value
[i
];
2308 if(!ip
->value
) ip
->conflict
= 1;
2314 else if((ip
->flags
& P_DEFINE
)) {
2318 res
= get_res(hd
, res_irq
, 0);
2319 if(res
) ip
->value
= res
->irq
.base
;
2322 res
= get_res(hd
, res_mem
, 0);
2323 if(res
) ip
->value
= res
->mem
.base
;
2326 res
= get_res(hd
, res_io
, 0);
2327 if(res
) ip
->value
= res
->io
.base
;
2332 res
= get_res(hd
, res_io
, ip
->type
- P_IO0
);
2333 if(res
) ip
->value
= res
->io
.base
;
2335 // ##### might break for 64bit pci entries?
2342 res
= get_res(hd
, res_mem
, ip
->type
- P_BASE0
);
2343 if(res
) ip
->value
= res
->mem
.base
;
2348 if(!res
) ip
->valid
= 0;
2353 if(!di
) di0
= free_mem(di0
);
2358 driver_info_t
*dsl_driver(hd_data_t
*hd_data
, hd_t
*hd
, cdb_isdn_card
*cic
)
2360 driver_info_t
*di0
, *di
;
2361 cdb_isdn_vario
*civ
;
2363 str_list_t
*sl
, *sl0
;
2365 if(!cic
) return NULL
;
2367 di0
= new_mem(sizeof *di0
);
2372 while((civ
= hd_cdbisdn_get_vario(drv
))) {
2373 drv
= civ
->next_vario
;
2375 di
->next
= new_mem(sizeof *di
);
2380 di
->dsl
.type
= di_dsl
;
2381 if(civ
->interface
&& *civ
->interface
) {
2382 if (!strcmp(civ
->interface
, "CAPI20")) {
2383 di
->dsl
.mode
= new_str("capiadsl");
2384 if(civ
->mod_name
&& *civ
->mod_name
)
2385 di
->dsl
.name
= new_str(civ
->mod_name
);
2387 di
->dsl
.name
= new_str("unknown");
2388 } else if (!strcmp(civ
->interface
, "pppoe")) {
2389 di
->dsl
.mode
= new_str("pppoe");
2390 if(civ
->mod_name
&& *civ
->mod_name
)
2391 di
->dsl
.name
= new_str(civ
->mod_name
);
2393 di
->dsl
.name
= new_str("none");
2395 di
->dsl
.mode
= new_str("unknown");
2396 di
->dsl
.name
= new_str("unknown");
2399 di
->dsl
.mode
= new_str("unknown");
2400 di
->dsl
.name
= new_str("unknown");
2403 if(civ
->need_pkg
&& *civ
->need_pkg
) {
2404 sl0
= hd_split(',', (char *) civ
->need_pkg
);
2405 for(sl
= sl0
; sl
; sl
= sl
->next
) {
2406 if(!search_str_list(hd
->requires
, sl
->str
)) {
2407 add_str_list(&hd
->requires
, sl
->str
);
2413 if(hd
->bus
.id
== bus_pci
) continue;
2415 if(!di
) di0
= free_mem(di0
);
2420 #endif /* WITH_ISDN */
2423 hd_res_t
*get_res(hd_t
*hd
, enum resource_types t
, unsigned index
)
2427 for(res
= hd
->res
; res
; res
= res
->next
) {
2428 if(res
->any
.type
== t
) {
2429 if(!index
) return res
;
2438 driver_info_t
*reorder_x11(driver_info_t
*di0
, char *info
)
2440 driver_info_t
*di
, *di_new
, **di_list
;
2443 for(dis
= 0, di
= di0
; di
; di
= di
->next
) dis
++;
2445 di_list
= new_mem(dis
* sizeof *di_list
);
2447 for(i
= 0, di
= di0
; di
; di
= di
->next
) {
2452 for(i
= found
= 0; i
< dis
; i
++) {
2454 !strcmp(di_list
[i
]->x11
.xf86_ver
, info
) ||
2455 !strcmp(di_list
[i
]->x11
.server
, info
)
2459 di
= di
->next
= di_list
[i
];
2462 di
= di_new
= di_list
[i
];
2469 for(i
= 0; i
< dis
; i
++) {
2472 di
= di
->next
= di_list
[i
];
2475 di
= di_new
= di_list
[i
];
2484 if(!found
&& strlen(info
) > 1) {
2485 free_driver_info(di_new
);
2486 di_new
= new_mem(sizeof *di_new
);
2487 di_new
->any
.type
= di_x11
;
2488 di_new
->x11
.server
= new_str(info
);
2489 di_new
->x11
.xf86_ver
= new_str(*info
>= 'A' && *info
<= 'Z' ? "3" : "4");
2496 void expand_driver_info(hd_data_t
*hd_data
, hd_t
*hd
)
2502 str_list_t
*sl
, *sl1
, *sl2
, *cmd
;
2504 if(!hd
|| !hd
->driver_info
) return;
2506 for(di
= hd
->driver_info
; di
; di
= di
->next
) {
2507 switch(di
->any
.type
) {
2509 for(i
= 0, sl
= di
->display
.hddb0
; sl
; sl
= sl
->next
, i
++) {
2510 if(i
== 0 && sscanf(sl
->str
, "%ux%u", &u1
, &u2
) == 2) {
2511 di
->display
.width
= u1
;
2512 di
->display
.height
= u2
;
2514 else if(i
== 1 && sscanf(sl
->str
, "%u-%u", &u1
, &u2
) == 2) {
2515 di
->display
.min_vsync
= u1
;
2516 di
->display
.max_vsync
= u2
;
2518 else if(i
== 2 && sscanf(sl
->str
, "%u-%u", &u1
, &u2
) == 2) {
2519 di
->display
.min_hsync
= u1
;
2520 di
->display
.max_hsync
= u2
;
2522 else if(i
== 3 && sscanf(sl
->str
, "%u", &u1
) == 1) {
2523 di
->display
.bandwidth
= u1
;
2529 for(di
->module
.active
= 1, sl
= di
->module
.hddb0
; sl
; sl
= sl
->next
) {
2530 t0
= s
= new_str(sl
->str
);
2532 t
= strsep(&t0
, " ");
2534 add_str_list(&di
->module
.names
, t
);
2535 di
->module
.active
&= (
2536 hd_module_is_active(hd_data
, t
) |
2537 (search_str_list(hd
->drivers
, t
) ? 1 : 0)
2541 add_str_list(&di
->module
.mod_args
, module_cmd(hd
, t0
));
2544 add_str_list(&di
->module
.mod_args
, NULL
);
2549 for(sl
= di
->module
.hddb1
; sl
; sl
= sl
->next
) {
2550 s
= module_cmd(hd
, sl
->str
);
2551 if(s
) str_printf(&di
->module
.conf
, -1, "%s\n", s
);
2556 di
->mouse
.buttons
= di
->mouse
.wheels
= -1;
2559 hd
->compat_vendor
.id
== MAKE_ID(TAG_SPECIAL
, 0x0210) &&
2560 ID_TAG(hd
->compat_device
.id
) == TAG_SPECIAL
2562 u1
= hd
->compat_device
.id
;
2565 hd
->vendor
.id
== MAKE_ID(TAG_SPECIAL
, 0x0210) &&
2566 ID_TAG(hd
->device
.id
) == TAG_SPECIAL
2571 di
->mouse
.wheels
= ID_VALUE(u1
) >> 4;
2572 di
->mouse
.buttons
= ID_VALUE(u1
) & 15;
2574 for(i
= 0, sl
= di
->mouse
.hddb0
; sl
; sl
= sl
->next
, i
++) {
2576 di
->mouse
.xf86
= new_str(sl
->str
);
2579 di
->mouse
.gpm
= new_str(sl
->str
);
2581 else if(i
== 2 && *sl
->str
) {
2582 di
->mouse
.buttons
= strtol(sl
->str
, NULL
, 10);
2584 else if(i
== 3 && *sl
->str
) {
2585 di
->mouse
.wheels
= strtol(sl
->str
, NULL
, 10);
2591 for(i
= 0, sl
= di
->x11
.hddb0
; sl
; sl
= sl
->next
, i
++) {
2593 di
->x11
.xf86_ver
= new_str(sl
->str
);
2596 di
->x11
.server
= new_str(sl
->str
);
2599 if(!strcmp(sl
->str
, "3d")) di
->x11
.x3d
= 1;
2603 s
= new_str(sl
->str
);
2604 for(t0
= s
; (t
= strsep(&t0
, ",")); ) {
2605 add_str_list(&di
->x11
.packages
, t
);
2611 s
= new_str(sl
->str
);
2612 for(t0
= s
; (t
= strsep(&t0
, ",")); ) {
2613 add_str_list(&di
->x11
.extensions
, t
);
2618 s
= new_str(sl
->str
);
2619 for(t0
= s
; (t
= strsep(&t0
, ",")); ) {
2620 add_str_list(&di
->x11
.options
, t
);
2625 for(sl2
= sl1
= hd_split(',', sl
->str
); sl2
; sl2
= sl2
->next
) {
2626 u1
= strtoul(sl2
->str
, NULL
, 0);
2629 di
->x11
.colors
.c8
= 1;
2630 di
->x11
.colors
.all
|= (1 << 0);
2634 di
->x11
.colors
.c15
= 1;
2635 di
->x11
.colors
.all
|= (1 << 1);
2639 di
->x11
.colors
.c16
= 1;
2640 di
->x11
.colors
.all
|= (1 << 2);
2644 di
->x11
.colors
.c24
= 1;
2645 di
->x11
.colors
.all
|= (1 << 3);
2649 di
->x11
.colors
.c32
= 1;
2650 di
->x11
.colors
.all
|= (1 << 4);
2657 di
->x11
.dacspeed
= strtol(sl
->str
, NULL
, 10);
2660 di
->x11
.script
= new_str(sl
->str
);
2663 for(i
= 0, sl
= di
->x11
.hddb1
; sl
; sl
= sl
->next
, i
++) {
2664 add_str_list(&di
->x11
.raw
, sl
->str
);
2667 // ######## for compatibility
2668 for(sl
= hd
->requires
; sl
; sl
= sl
->next
) {
2669 add_str_list(&di
->x11
.packages
, sl
->str
);
2679 di
= hd
->driver_info
;
2680 if(di
&& di
->any
.type
== di_x11
&& !hd_probe_feature(hd_data
, pr_ignx11
)) {
2681 cmd
= get_cmdline(hd_data
, "x11");
2682 if(cmd
&& *cmd
->str
) {
2683 hd
->driver_info
= reorder_x11(di
, cmd
->str
);
2690 char *module_cmd(hd_t
*hd
, char *cmd
)
2692 static char buf
[256];
2697 // skip inactive PnP cards
2698 // ##### Really necessary here?
2702 hd
->detail
->isapnp
.data
&&
2703 !(hd
->detail
->isapnp
.data
->flags
& (1 << isapnp_flag_act
))
2708 if(sscanf(cmd
, "<io%u>%n", &idx
, &ofs
) >= 1) {
2709 if((res
= get_res(hd
, res_io
, idx
))) {
2710 s
+= sprintf(s
, "0x%02"PRIx64
, res
->io
.base
);
2717 else if(sscanf(cmd
, "<irq%u>%n", &idx
, &ofs
) >= 1) {
2718 if((res
= get_res(hd
, res_irq
, idx
))) {
2719 s
+= sprintf(s
, "%u", res
->irq
.base
);
2730 if(s
- buf
> (int) sizeof buf
- 20) return NULL
;
2738 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2739 char *hid_tag_name(int tag
)
2741 return (unsigned) tag
< sizeof hid_tag_names
/ sizeof *hid_tag_names
? hid_tag_names
[tag
] : "";
2744 char *hid_tag_name2(int tag
)
2746 return (unsigned) tag
< sizeof hid_tag_names2
/ sizeof *hid_tag_names2
? hid_tag_names2
[tag
] : "";