]>
git.ipfire.org Git - people/dweismueller/ipfire-2.x.git/blob - src/hwinfo/src/hd/isapnp.c
28fbdde6b68d27837ea2f09b000ff8e21c7455d4
11 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
14 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
17 #if defined(__i386__) || defined(__alpha__)
19 static void get_pnp_devs(hd_data_t
*hd_data
);
22 static void get_read_port(hd_data_t
*hd_data
, isapnp_t
*);
23 static void build_list(hd_data_t
*hd_data
, str_list_t
*isapnp_list
);
26 void hd_scan_isapnp(hd_data_t
*hd_data
)
32 str_list_t
*isapnp_list
= NULL
, *sl
;
35 if(!hd_probe_feature(hd_data
, pr_isapnp
)) return;
37 hd_data
->module
= mod_isapnp
;
40 remove_hd_entries(hd_data
);
42 PROGRESS(1, 0, "pnp devices");
44 get_pnp_devs(hd_data
);
47 PROGRESS(1, 0, "read port");
49 if(!hd_data
->isapnp
) {
50 hd_data
->isapnp
= new_mem(sizeof *hd_data
->isapnp
);
53 hd_data
->isapnp
->cards
= 0;
55 hd_data
->isapnp
->card
= free_mem(hd_data
->isapnp
->card
);
59 if(!hd_data
->isapnp
->read_port
) get_read_port(hd_data
, hd_data
->isapnp
);
61 PROGRESS(3, 0, "get pnp data");
63 isapnp_list
= read_file(PROC_ISAPNP
, 0, 0);
65 if((hd_data
->debug
& HD_DEB_ISAPNP
)) {
66 ADD2LOG("----- %s -----\n", PROC_ISAPNP
);
67 for(sl
= isapnp_list
; sl
; sl
= sl
->next
) {
68 ADD2LOG(" %s", sl
->str
);
70 ADD2LOG("----- %s end -----\n", PROC_ISAPNP
);
73 isapnp_ok
= isapnp_list
&& hd_data
->isapnp
->read_port
? 1 : 1;
75 PROGRESS(4, 0, "build list");
78 hd
= add_hd_entry(hd_data
, __LINE__
, 0);
80 hd
->base_class
.id
= bc_internal
;
81 hd
->sub_class
.id
= sc_int_isapnp_if
;
83 res
= add_res_entry(&hd
->res
, new_mem(sizeof *res
));
84 res
->io
.type
= res_io
;
86 res
->io
.base
= ISAPNP_ADDR_PORT
;
88 res
->io
.access
= acc_wo
;
90 res
= add_res_entry(&hd
->res
, new_mem(sizeof *res
));
91 res
->io
.type
= res_io
;
93 res
->io
.base
= ISAPNP_DATA_PORT
;
95 res
->io
.access
= acc_wo
;
97 res
= add_res_entry(&hd
->res
, new_mem(sizeof *res
));
98 res
->io
.type
= res_io
;
100 res
->io
.base
= hd_data
->isapnp
->read_port
;
102 res
->io
.access
= acc_ro
;
105 build_list(hd_data
, isapnp_list
);
107 free_str_list(isapnp_list
);
113 void get_pnp_devs(hd_data_t
*hd_data
)
119 struct sysfs_bus
*sf_bus
;
120 struct dlist
*sf_dev_list
;
121 struct sysfs_device
*sf_dev
;
122 struct sysfs_device
*sf_dev_2
;
124 sf_bus
= sysfs_open_bus("pnp");
127 ADD2LOG("sysfs: no such bus: pnp\n");
131 sf_dev_list
= sysfs_get_bus_devices(sf_bus
);
134 if(sf_dev_list
) dlist_for_each_data(sf_dev_list
, sf_dev
, struct sysfs_device
) {
136 " pnp device: name = %s, bus_id = %s, bus = %s\n path = %s\n",
140 hd_sysfs_id(sf_dev
->path
)
143 if((s
= hd_attr_str(sysfs_get_device_attr(sf_dev
, "id")))) {
144 if(sscanf(s
, "%3s%4x", buf
, &u1
) == 2 && (u2
= name2eisa_id(buf
))) {
145 ADD2LOG(" id = %s %04x\n", eisa_vendor_str(u2
), u1
);
147 hd
= add_hd_entry(hd_data
, __LINE__
, 0);
149 hd
->sysfs_id
= new_str(hd_sysfs_id(sf_dev
->path
));
150 hd
->sysfs_bus_id
= new_str(sf_dev
->bus_id
);
152 hd
->bus
.id
= bus_isa
;
155 hd
->sub_vendor
.id
= u2
;
156 hd
->sub_device
.id
= MAKE_ID(TAG_EISA
, u1
);
158 if(sscanf(hd
->sysfs_bus_id
, "%2x:%2x.%2x", &u1
, &u2
, &u3
) == 3) {
163 s
= new_str(sf_dev
->path
);
164 if((t
= strrchr(s
, '/'))) *t
= 0;
166 sf_dev_2
= sysfs_open_device_path(s
);
168 if((t
= hd_attr_str(sysfs_get_device_attr(sf_dev_2
, "card_id")))) {
169 if(sscanf(t
, "%3s%4x", buf
, &u1
) == 2 && (u2
= name2eisa_id(buf
))) {
170 ADD2LOG(" card id = %s %04x\n", eisa_vendor_str(u2
), u1
);
173 hd
->device
.id
= MAKE_ID(TAG_EISA
, u1
);
176 if((t
= hd_attr_str(sysfs_get_device_attr(sf_dev_2
, "name")))) {
177 hd
->device
.name
= canon_str(t
, strlen(t
));
178 if(!strcasecmp(hd
->device
.name
, "unknown")) {
179 hd
->device
.name
= free_mem(hd
->device
.name
);
183 sysfs_close_device(sf_dev_2
);
190 if(hd
->sub_vendor
.id
== hd
->vendor
.id
&& hd
->sub_device
.id
== hd
->device
.id
) {
191 hd
->sub_vendor
.id
= hd
->sub_device
.id
= 0;
200 sysfs_close_bus(sf_bus
);
206 unsigned char *add_isapnp_card_res(isapnp_card_t
*ic
, int len
, int type
)
208 ic
->res
= add_mem(ic
->res
, sizeof *ic
->res
, ic
->res_len
);
210 ic
->res
[ic
->res_len
].len
= len
;
211 ic
->res
[ic
->res_len
].type
= type
;
212 ic
->res
[ic
->res_len
].data
= new_mem(len
);
214 if(type
== RES_LOG_DEV_ID
) { /* logical device id */
218 return ic
->res
[ic
->res_len
++].data
;
222 isapnp_card_t
*add_isapnp_card(isapnp_t
*ip
, int csn
)
226 ip
->card
= add_mem(ip
->card
, sizeof *ip
->card
, ip
->cards
);
227 c
= ip
->card
+ ip
->cards
++;
230 c
->serial
= new_mem(sizeof *c
->serial
* 8);
231 c
->card_regs
= new_mem(sizeof *c
->card_regs
* 0x30);
237 void get_read_port(hd_data_t
*hd_data
, isapnp_t
*p
)
244 gather_resources(hd_data
->misc
, &res
, "ISAPnP", W_IO
);
245 if(res
&& res
->any
.type
== res_io
) p
->read_port
= res
->io
.base
;
250 void build_list(hd_data_t
*hd_data
, str_list_t
*isapnp_list
)
255 int card
, ldev
, cdev_id
, ldev_active
= 0;
256 char *dev_name
= NULL
, *ldev_name
= NULL
;
257 unsigned dev_id
= 0, vend_id
= 0, base_class
= 0, sub_class
= 0, ldev_id
;
262 for(sl
= isapnp_list
; sl
; sl
= sl
->next
) {
264 if(sscanf(sl
->str
, "Card %d '%3s%4x:%99[^']", &card
, s1
, &dev_id
, s2
) == 4) {
265 // ADD2LOG("\n\n** card %d >%s< %04x >%s<**\n", card, s1, dev_id, s2);
267 dev_name
= free_mem(dev_name
);
268 if(strcmp(s2
, "Unknown")) dev_name
= new_str(s2
);
270 dev_id
= MAKE_ID(TAG_EISA
, dev_id
);
271 vend_id
= name2eisa_id(s1
);
273 base_class
= sub_class
= 0;
274 if((u
= device_class(hd_data
, vend_id
, dev_id
))) {
276 sub_class
= u
& 0xff;
282 (ID_VALUE(vend_id
) || ID_VALUE(dev_id
)) &&
283 !((db_name
= hd_device_name(hd_data
, vend_id
, dev_id
)) && *db_name
)
286 add_device_name(hd_data
, vend_id
, dev_id
, dev_name
);
294 if(sscanf(sl
->str
, " Logical device %d '%3s%4x:%99[^']", &ldev
, s1
, &ldev_id
, s2
) == 4) {
295 // ADD2LOG("\n\n** ldev %d >%s< %04x >%s<**\n", ldev, s1, ldev_id, s2);
297 ldev_name
= free_mem(ldev_name
);
298 if(strcmp(s2
, "Unknown")) ldev_name
= new_str(s2
);
300 hd
= add_hd_entry(hd_data
, __LINE__
, 0);
302 hd
->bus
.id
= bus_isa
;
307 hd
->vendor
.id
= vend_id
;
308 hd
->device
.id
= dev_id
;
310 hd
->base_class
.id
= base_class
;
311 hd
->sub_class
.id
= sub_class
;
313 hd
->sub_device
.id
= MAKE_ID(TAG_EISA
, ldev_id
);
314 hd
->sub_vendor
.id
= name2eisa_id(s1
);
316 if(hd
->sub_vendor
.id
== hd
->vendor
.id
&& hd
->sub_device
.id
== hd
->device
.id
) {
317 hd
->sub_vendor
.id
= hd
->sub_device
.id
= 0;
320 if((u
= sub_device_class(hd_data
, hd
->vendor
.id
, hd
->device
.id
, hd
->sub_vendor
.id
, hd
->sub_device
.id
))) {
321 hd
->base_class
.id
= u
>> 8;
322 hd
->sub_class
.id
= u
& 0xff;
326 # ############# FIXME
328 (ID_VALUE(hd
->sub_vendor
.id
) || ID_VALUE(hd
->sub_device
.id
)) &&
329 !hd_sub_device_name(hd_data
, hd
->vend
, hd
->dev
, hd
->sub_vend
, hd
->sub_device
.id
)
332 add_sub_device_name(hd_data
, hd
->vend
, hd
->dev
, hd
->sub_vend
, hd
->sub_device
.id
, ldev_name
);
340 if(strstr(sl
->str
, "Device is not active")) {
345 if(strstr(sl
->str
, "Device is active")) {
350 if(hd
&& sscanf(sl
->str
, " Compatible device %3s%4x", s1
, &cdev_id
) == 2) {
351 // ADD2LOG("\n\n** cdev >%s< %04x **\n", s1, cdev_id);
353 hd
->compat_device
.id
= MAKE_ID(TAG_EISA
, cdev_id
);
354 hd
->compat_vendor
.id
= name2eisa_id(s1
);
356 if(!(hd
->base_class
.id
|| hd
->sub_class
.id
)) {
357 if((u
= device_class(hd_data
, hd
->compat_vendor
.id
, hd
->compat_device
.id
))) {
358 hd
->base_class
.id
= u
>> 8;
359 hd
->sub_class
.id
= u
& 0xff;
361 else if(hd
->compat_vendor
.id
== MAKE_ID(TAG_EISA
, 0x41d0)) {
362 /* 0x41d0 is 'PNP' */
363 switch((hd
->compat_device
.id
>> 12) & 0xf) {
365 hd
->base_class
.id
= bc_network
;
366 hd
->sub_class
.id
= 0x80;
369 hd
->base_class
.id
= bc_storage
;
370 hd
->sub_class
.id
= 0x80;
373 hd
->base_class
.id
= bc_multimedia
;
374 hd
->sub_class
.id
= 0x80;
378 hd
->base_class
.id
= bc_modem
;
390 " Active port %x, %x, %x, %x, %x, %x",
391 ux
, ux
+ 1, ux
+ 2, ux
+ 3, ux
+ 4, ux
+ 5
395 for(i
= 0; i
< j
; i
++) {
396 res
= add_res_entry(&hd
->res
, new_mem(sizeof *res
));
397 res
->io
.type
= res_io
;
398 res
->io
.enabled
= ldev_active
? 1 : 0;
399 res
->io
.base
= ux
[i
];
400 res
->io
.access
= acc_rw
;
406 if(hd
&& (j
= sscanf(sl
->str
, " Active IRQ %d [%x], %d [%x]", ux
, ux
+ 1, ux
+ 2, ux
+ 3)) >= 1) {
407 for(i
= 0; i
< j
; i
+= 2) {
408 res
= add_res_entry(&hd
->res
, new_mem(sizeof *res
));
409 res
->irq
.type
= res_irq
;
410 res
->irq
.enabled
= ldev_active
? 1 : 0;
411 res
->irq
.base
= ux
[i
];
417 if(hd
&& (j
= sscanf(sl
->str
, " Active DMA %d, %d", ux
, ux
+ 1)) >= 1) {
418 for(i
= 0; i
< j
; i
++) {
419 res
= add_res_entry(&hd
->res
, new_mem(sizeof *res
));
420 res
->dma
.type
= res_dma
;
421 res
->dma
.enabled
= ldev_active
? 1 : 0;
422 res
->dma
.base
= ux
[i
];
437 #endif /* defined(__i386__) || defined(__alpha__) */