]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/hwinfo/src/hd/isapnp.c
Kleiner netter neuer Versuch.
[people/pmueller/ipfire-2.x.git] / src / hwinfo / src / hd / isapnp.c
CommitLineData
a6316ce4
MT
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "hd.h"
6#include "hd_int.h"
7#include "hddb.h"
8#include "isapnp.h"
9
10
11/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
12 * isapnp stuff
13 *
14 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
15 */
16
17#if defined(__i386__) || defined(__alpha__)
18
19static void get_pnp_devs(hd_data_t *hd_data);
20
21#if 0
22static void get_read_port(hd_data_t *hd_data, isapnp_t *);
23static void build_list(hd_data_t *hd_data, str_list_t *isapnp_list);
24#endif
25
26void hd_scan_isapnp(hd_data_t *hd_data)
27{
28#if 0
29 hd_t *hd;
30 hd_res_t *res;
31 int isapnp_ok;
32 str_list_t *isapnp_list = NULL, *sl;
33#endif
34
35 if(!hd_probe_feature(hd_data, pr_isapnp)) return;
36
37 hd_data->module = mod_isapnp;
38
39 /* some clean-up */
40 remove_hd_entries(hd_data);
41
42 PROGRESS(1, 0, "pnp devices");
43
44 get_pnp_devs(hd_data);
45
46#if 0
47 PROGRESS(1, 0, "read port");
48
49 if(!hd_data->isapnp) {
50 hd_data->isapnp = new_mem(sizeof *hd_data->isapnp);
51 }
52 else {
53 hd_data->isapnp->cards = 0;
54 /* just in case... */
55 hd_data->isapnp->card = free_mem(hd_data->isapnp->card);
56 /* keep the port */
57 }
58
59 if(!hd_data->isapnp->read_port) get_read_port(hd_data, hd_data->isapnp);
60
61 PROGRESS(3, 0, "get pnp data");
62
63 isapnp_list = read_file(PROC_ISAPNP, 0, 0);
64
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);
69 }
70 ADD2LOG("----- %s end -----\n", PROC_ISAPNP);
71 }
72
73 isapnp_ok = isapnp_list && hd_data->isapnp->read_port ? 1 : 1;
74
75 PROGRESS(4, 0, "build list");
76
77 if(isapnp_ok) {
78 hd = add_hd_entry(hd_data, __LINE__, 0);
79 hd->bus.id = bus_isa;
80 hd->base_class.id = bc_internal;
81 hd->sub_class.id = sc_int_isapnp_if;
82
83 res = add_res_entry(&hd->res, new_mem(sizeof *res));
84 res->io.type = res_io;
85 res->io.enabled = 1;
86 res->io.base = ISAPNP_ADDR_PORT;
87 res->io.range = 1;
88 res->io.access = acc_wo;
89
90 res = add_res_entry(&hd->res, new_mem(sizeof *res));
91 res->io.type = res_io;
92 res->io.enabled = 1;
93 res->io.base = ISAPNP_DATA_PORT;
94 res->io.range = 1;
95 res->io.access = acc_wo;
96
97 res = add_res_entry(&hd->res, new_mem(sizeof *res));
98 res->io.type = res_io;
99 res->io.enabled = 1;
100 res->io.base = hd_data->isapnp->read_port;
101 res->io.range = 1;
102 res->io.access = acc_ro;
103 }
104
105 build_list(hd_data, isapnp_list);
106
107 free_str_list(isapnp_list);
108#endif
109
110}
111
112
113void get_pnp_devs(hd_data_t *hd_data)
114{
115 hd_t *hd;
116 char *s, *t, buf[4];
117 unsigned u1, u2, u3;
118
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;
123
124 sf_bus = sysfs_open_bus("pnp");
125
126 if(!sf_bus) {
127 ADD2LOG("sysfs: no such bus: pnp\n");
128 return;
129 }
130
131 sf_dev_list = sysfs_get_bus_devices(sf_bus);
132
133
134 if(sf_dev_list) dlist_for_each_data(sf_dev_list, sf_dev, struct sysfs_device) {
135 ADD2LOG(
136 " pnp device: name = %s, bus_id = %s, bus = %s\n path = %s\n",
137 sf_dev->name,
138 sf_dev->bus_id,
139 sf_dev->bus,
140 hd_sysfs_id(sf_dev->path)
141 );
142
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);
146
147 hd = add_hd_entry(hd_data, __LINE__, 0);
148
149 hd->sysfs_id = new_str(hd_sysfs_id(sf_dev->path));
150 hd->sysfs_bus_id = new_str(sf_dev->bus_id);
151
152 hd->bus.id = bus_isa;
153 hd->is.isapnp = 1;
154
155 hd->sub_vendor.id = u2;
156 hd->sub_device.id = MAKE_ID(TAG_EISA, u1);
157
158 if(sscanf(hd->sysfs_bus_id, "%2x:%2x.%2x", &u1, &u2, &u3) == 3) {
159 hd->slot = u2;
160 hd->func = u3;
161 }
162
163 s = new_str(sf_dev->path);
164 if((t = strrchr(s, '/'))) *t = 0;
165
166 sf_dev_2 = sysfs_open_device_path(s);
167 if(sf_dev_2) {
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);
171
172 hd->vendor.id = u2;
173 hd->device.id = MAKE_ID(TAG_EISA, u1);
174 }
175 }
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);
180 }
181 }
182
183 sysfs_close_device(sf_dev_2);
184 }
185
186
187 free_mem(s);
188
189
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;
192 }
193
194 }
195 }
196
197 }
198
199
200 sysfs_close_bus(sf_bus);
201
202}
203
204
205#if 0
206unsigned char *add_isapnp_card_res(isapnp_card_t *ic, int len, int type)
207{
208 ic->res = add_mem(ic->res, sizeof *ic->res, ic->res_len);
209
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);
213
214 if(type == RES_LOG_DEV_ID) { /* logical device id */
215 ic->log_devs++;
216 }
217
218 return ic->res[ic->res_len++].data;
219}
220
221
222isapnp_card_t *add_isapnp_card(isapnp_t *ip, int csn)
223{
224 isapnp_card_t *c;
225
226 ip->card = add_mem(ip->card, sizeof *ip->card, ip->cards);
227 c = ip->card + ip->cards++;
228
229 c->csn = csn;
230 c->serial = new_mem(sizeof *c->serial * 8);
231 c->card_regs = new_mem(sizeof *c->card_regs * 0x30);
232
233 return c;
234}
235
236
237void get_read_port(hd_data_t *hd_data, isapnp_t *p)
238{
239 hd_res_t *res;
240
241 p->read_port = 0;
242
243 res = NULL;
244 gather_resources(hd_data->misc, &res, "ISAPnP", W_IO);
245 if(res && res->any.type == res_io) p->read_port = res->io.base;
246 free_res_list(res);
247}
248
249
250void build_list(hd_data_t *hd_data, str_list_t *isapnp_list)
251{
252 hd_t *hd = NULL;
253 str_list_t *sl;
254 char s1[4], s2[100];
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;
258 unsigned u, ux[5];
259 int i, j;
260 hd_res_t *res;
261
262 for(sl = isapnp_list; sl; sl = sl->next) {
263
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);
266
267 dev_name = free_mem(dev_name);
268 if(strcmp(s2, "Unknown")) dev_name = new_str(s2);
269
270 dev_id = MAKE_ID(TAG_EISA, dev_id);
271 vend_id = name2eisa_id(s1);
272
273 base_class = sub_class = 0;
274 if((u = device_class(hd_data, vend_id, dev_id))) {
275 base_class = u >> 8;
276 sub_class = u & 0xff;
277 }
278
279#if 0
280// ########## FIXME
281 if(
282 (ID_VALUE(vend_id) || ID_VALUE(dev_id)) &&
283 !((db_name = hd_device_name(hd_data, vend_id, dev_id)) && *db_name)
284 ) {
285 if(dev_name) {
286 add_device_name(hd_data, vend_id, dev_id, dev_name);
287 }
288 }
289#endif
290
291 continue;
292 }
293
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);
296
297 ldev_name = free_mem(ldev_name);
298 if(strcmp(s2, "Unknown")) ldev_name = new_str(s2);
299
300 hd = add_hd_entry(hd_data, __LINE__, 0);
301
302 hd->bus.id = bus_isa;
303 hd->is.isapnp = 1;
304 hd->slot = card;
305 hd->func = ldev;
306
307 hd->vendor.id = vend_id;
308 hd->device.id = dev_id;
309
310 hd->base_class.id = base_class;
311 hd->sub_class.id = sub_class;
312
313 hd->sub_device.id = MAKE_ID(TAG_EISA, ldev_id);
314 hd->sub_vendor.id = name2eisa_id(s1);
315
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;
318 }
319
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;
323 }
324
325#if 0
326# ############# FIXME
327 if(
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)
330 ) {
331 if(ldev_name) {
332 add_sub_device_name(hd_data, hd->vend, hd->dev, hd->sub_vend, hd->sub_device.id, ldev_name);
333 }
334 }
335#endif
336
337 continue;
338 }
339
340 if(strstr(sl->str, "Device is not active")) {
341 ldev_active = 0;
342 continue;
343 }
344
345 if(strstr(sl->str, "Device is active")) {
346 ldev_active = 1;
347 continue;
348 }
349
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);
352
353 hd->compat_device.id = MAKE_ID(TAG_EISA, cdev_id);
354 hd->compat_vendor.id = name2eisa_id(s1);
355
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;
360 }
361 else if(hd->compat_vendor.id == MAKE_ID(TAG_EISA, 0x41d0)) {
362 /* 0x41d0 is 'PNP' */
363 switch((hd->compat_device.id >> 12) & 0xf) {
364 case 8:
365 hd->base_class.id = bc_network;
366 hd->sub_class.id = 0x80;
367 break;
368 case 0xa:
369 hd->base_class.id = bc_storage;
370 hd->sub_class.id = 0x80;
371 break;
372 case 0xb:
373 hd->base_class.id = bc_multimedia;
374 hd->sub_class.id = 0x80;
375 break;
376 case 0xc:
377 case 0xd:
378 hd->base_class.id = bc_modem;
379 break;
380 }
381 }
382 }
383
384 continue;
385 }
386
387 if(
388 hd &&
389 (j = sscanf(sl->str,
390 " Active port %x, %x, %x, %x, %x, %x",
391 ux, ux + 1, ux + 2, ux + 3, ux + 4, ux + 5
392 )) >= 1
393 ) {
394
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;
401 }
402
403 continue;
404 }
405
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];
412 }
413
414 continue;
415 }
416
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];
423 }
424
425 continue;
426 }
427
428
429 }
430
431 free_mem(dev_name);
432 free_mem(ldev_name);
433}
434#endif
435
436
437#endif /* defined(__i386__) || defined(__alpha__) */
438