]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/hwinfo/src/hd/misc.c
Kleiner netter neuer Versuch.
[people/teissler/ipfire-2.x.git] / src / hwinfo / src / hd / misc.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <fcntl.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <sys/ioctl.h>
9
10 #include <linux/hdreg.h>
11
12 #include "hd.h"
13 #include "hd_int.h"
14 #include "misc.h"
15 #include "klog.h"
16
17 static void read_ioports(misc_t *m);
18 static void read_dmas(misc_t *m);
19 static void read_irqs(misc_t *m);
20 static int active_vga_card(hd_t *);
21
22 static void dump_misc_proc_data(hd_data_t *hd_data);
23 static void dump_misc_data(hd_data_t *hd_data);
24
25 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
26 * misc info
27 *
28 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
29 */
30
31 void hd_scan_misc(hd_data_t *hd_data)
32 {
33 hd_t *hd;
34 hd_res_t *res;
35 int fd, i;
36 char *s = NULL;
37 bios_info_t *bt = NULL;
38 char par[] = "parport0";
39 int fd_ser0, fd_ser1;
40
41 if(!hd_probe_feature(hd_data, pr_misc)) return;
42
43 hd_data->module = mod_misc;
44
45 /* some clean-up */
46 remove_hd_entries(hd_data);
47 hd_data->misc = free_misc(hd_data->misc);
48
49 PROGRESS(9, 0, "kernel log");
50 read_klog(hd_data);
51 if((hd_data->debug & HD_DEB_MISC)) dump_klog(hd_data);
52
53 PROGRESS(1, 0, "misc data");
54 hd_data->misc = new_mem(sizeof *hd_data->misc);
55
56 /* this is enough to load the module */
57 fd_ser0 = fd_ser1 = -1;
58
59 #if !defined(__sparc__)
60 /* On sparc, the close needs too long */
61 if(hd_probe_feature(hd_data, pr_misc_serial)) {
62 PROGRESS(1, 1, "open serial");
63 fd_ser0 = open("/dev/ttyS0", O_RDONLY | O_NONBLOCK);
64 fd_ser1 = open("/dev/ttyS1", O_RDONLY | O_NONBLOCK);
65 /* keep the devices open until the resources have been read */
66 }
67 #endif
68
69 /* this is enough to load the module */
70 if(!hd_data->flags.no_parport && hd_probe_feature(hd_data, pr_misc_par)) {
71 PROGRESS(1, 2, "open parallel");
72 /* what can the BIOS tell us? */
73 for(hd = hd_data->hd; hd; hd = hd->next) {
74 if(
75 hd->base_class.id == bc_internal &&
76 hd->sub_class.id == sc_int_bios &&
77 hd->detail &&
78 hd->detail->type == hd_detail_bios &&
79 hd->detail->bios.data
80 ) break;
81 }
82 if(hd) {
83 bt = hd->detail->bios.data;
84 if(bt->par_port0) {
85 str_printf(&s, 0, "io=0x%x", bt->par_port0);
86 if(bt->par_port1) {
87 str_printf(&s, -1, ",0x%x", bt->par_port1);
88 if(bt->par_port2) str_printf(&s, -1, ",0x%x", bt->par_port2);
89 }
90 str_printf(&s, -1, " irq=none,none,none");
91 }
92 unload_module(hd_data, "parport_probe");
93 unload_module(hd_data, "lp");
94 unload_module(hd_data, "parport_pc");
95 unload_module(hd_data, "parport");
96
97 /* now load it with the right io */
98 load_module(hd_data, "parport");
99 load_module_with_params(hd_data, "parport_pc", s);
100 free_mem(s);
101 }
102 /* now load the rest of the modules */
103 fd = open("/dev/lp0", O_RDONLY | O_NONBLOCK);
104 if(fd >= 0) close(fd);
105 }
106
107 /*
108 * floppy driver resources are allocated only temporarily,
109 * so we access it just before we read the resources
110 */
111 if(hd_probe_feature(hd_data, pr_misc_floppy)) {
112 /* look for a floppy *device* entry... */
113 for(hd = hd_data->hd; hd; hd = hd->next) {
114 if(
115 hd->base_class.id == bc_storage_device &&
116 hd->sub_class.id == sc_sdev_floppy &&
117 hd->unix_dev_name &&
118 !strncmp(hd->unix_dev_name, "/dev/fd", sizeof "/dev/fd" - 1)
119 ) {
120
121 PROGRESS(1, 3, "read floppy");
122 i = 5;
123 hd->block0 = read_block0(hd_data, hd->unix_dev_name, &i);
124 hd->is.notready = hd->block0 ? 0 : 1;
125 if(i < 0) {
126 hd->tag.remove = 1;
127 ADD2LOG("misc.floppy: removing floppy entry %u (timed out)\n", hd->idx);
128 }
129
130 if(!hd->is.notready) {
131 struct hd_geometry geo;
132 int fd;
133 unsigned size, blk_size = 0x200;
134
135 fd = open(hd->unix_dev_name, O_RDONLY | O_NONBLOCK);
136 if(fd >= 0) {
137 if(!ioctl(fd, HDIO_GETGEO, &geo)) {
138 ADD2LOG("floppy ioctl(geo) ok\n");
139 res = add_res_entry(&hd->res, new_mem(sizeof *res));
140 res->disk_geo.type = res_disk_geo;
141 res->disk_geo.cyls = geo.cylinders;
142 res->disk_geo.heads = geo.heads;
143 res->disk_geo.sectors = geo.sectors;
144 res->disk_geo.geotype = geo_logical;
145 size = geo.cylinders * geo.heads * geo.sectors;
146 for(res = hd->res; res; res = res->next) {
147 if(res->any.type == res_size && res->size.unit == size_unit_sectors) {
148 res->size.val1 = size; res->size.val2 = blk_size;
149 break;
150 }
151 }
152 if(!res) {
153 res = add_res_entry(&hd->res, new_mem(sizeof *res));
154 res->size.type = res_size;
155 res->size.unit = size_unit_sectors;
156 res->size.val1 = size; res->size.val2 = blk_size;
157 }
158 }
159 close(fd);
160 }
161 }
162
163 break;
164 }
165 }
166 remove_tagged_hd_entries(hd_data);
167 }
168
169 PROGRESS(2, 1, "io");
170 read_ioports(hd_data->misc);
171
172 PROGRESS(2, 2, "dma");
173 read_dmas(hd_data->misc);
174
175 PROGRESS(2, 3, "irq");
176 read_irqs(hd_data->misc);
177
178 if((hd_data->debug & HD_DEB_MISC)) dump_misc_proc_data(hd_data);
179
180 if(fd_ser0 >= 0) close(fd_ser0);
181 if(fd_ser1 >= 0) close(fd_ser1);
182
183 /* now create some system generic entries */
184
185 /* FPU */
186 PROGRESS(3, 0, "FPU");
187 res = NULL;
188 gather_resources(hd_data->misc, &res, "fpu", 0);
189 if(res) {
190 hd = add_hd_entry(hd_data, __LINE__, 0);
191 hd->base_class.id = bc_internal;
192 hd->sub_class.id = sc_int_fpu;
193 hd->res = res;
194 }
195
196 /* DMA */
197 PROGRESS(3, 1, "DMA");
198 res = NULL;
199 gather_resources(hd_data->misc, &res, "dma1", 0);
200 gather_resources(hd_data->misc, &res, "dma2", 0);
201 gather_resources(hd_data->misc, &res, "dma page reg", 0);
202 gather_resources(hd_data->misc, &res, "cascade", W_DMA);
203 if(res) {
204 hd = add_hd_entry(hd_data, __LINE__, 0);
205 hd->base_class.id = bc_system;
206 hd->sub_class.id = sc_sys_dma;
207 hd->res = res;
208 }
209
210 /* PIC */
211 PROGRESS(3, 2, "PIC");
212 res = NULL;
213 gather_resources(hd_data->misc, &res, "pic1", 0);
214 gather_resources(hd_data->misc, &res, "pic2", 0);
215 gather_resources(hd_data->misc, &res, "cascade", W_IRQ);
216 if(res) {
217 hd = add_hd_entry(hd_data, __LINE__, 0);
218 hd->base_class.id = bc_system;
219 hd->sub_class.id = sc_sys_pic;
220 hd->res = res;
221 }
222
223 /* timer */
224 PROGRESS(3, 3, "timer");
225 res = NULL;
226 gather_resources(hd_data->misc, &res, "timer", 0);
227 if(res) {
228 hd = add_hd_entry(hd_data, __LINE__, 0);
229 hd->base_class.id = bc_system;
230 hd->sub_class.id = sc_sys_timer;
231 hd->res = res;
232 }
233
234 /* real time clock */
235 PROGRESS(3, 4, "RTC");
236 res = NULL;
237 gather_resources(hd_data->misc, &res, "rtc", 0);
238 if(res) {
239 hd = add_hd_entry(hd_data, __LINE__, 0);
240 hd->base_class.id = bc_system;
241 hd->sub_class.id = sc_sys_rtc;
242 hd->res = res;
243 }
244
245 /* keyboard */
246 res = NULL;
247 gather_resources(hd_data->misc, &res, "keyboard", 0);
248 if(res) {
249 hd = add_hd_entry(hd_data, __LINE__, 0);
250 hd->base_class.id = bc_input;
251 hd->sub_class.id = sc_inp_keyb;
252 hd->res = res;
253 }
254
255 /* parallel ports */
256 for(i = 0; i < 1; i++, par[sizeof par - 2]++) {
257 res = NULL;
258 gather_resources(hd_data->misc, &res, par, 0);
259 if(res) {
260 hd = add_hd_entry(hd_data, __LINE__, 0);
261 hd->base_class.id = bc_comm;
262 hd->sub_class.id = sc_com_par;
263 str_printf(&hd->unix_dev_name, 0, "/dev/lp%d", i);
264 hd->res = res;
265 }
266 }
267
268 /* floppy controller */
269 res = NULL;
270 gather_resources(hd_data->misc, &res, "floppy", 0);
271 gather_resources(hd_data->misc, &res, "floppy DIR", 0);
272 if(res) {
273 /* look for an existing entry */
274 for(hd = hd_data->hd; hd; hd = hd->next) {
275 if(hd->base_class.id == bc_storage && hd->sub_class.id == sc_sto_floppy) break;
276 }
277
278 /* missing, so create one */
279 if(!hd) {
280 hd = add_hd_entry(hd_data, __LINE__, 0);
281 hd->base_class.id = bc_storage;
282 hd->sub_class.id = sc_sto_floppy;
283 }
284
285 hd->res = res;
286 }
287
288 /*
289 * look for PS/2 port
290 *
291 * The catch is, that sometimes /dev/psaux is accessible only for root,
292 * so the open() may fail but there are irq events registered.
293 *
294 */
295 fd = open(DEV_PSAUX, O_RDONLY | O_NONBLOCK);
296 if(fd >= 0) close(fd);
297
298 res = NULL;
299 gather_resources(hd_data->misc, &res, "PS/2 Mouse", 0);
300
301 if(res || fd >= 0) {
302 hd = add_hd_entry(hd_data, __LINE__, 0);
303 hd->base_class.id = bc_ps2;
304
305 if(res) {
306 hd->res = res;
307 }
308 }
309 }
310
311
312 void hd_scan_misc2(hd_data_t *hd_data)
313 {
314 hd_t *hd, *hd1;
315 misc_t *m;
316 hd_res_t *res, *res1, *res2;
317 int i;
318
319 if(!hd_probe_feature(hd_data, pr_misc)) return;
320
321 hd_data->module = mod_misc;
322
323 PROGRESS(5, 0, "misc data");
324
325 /* create some more system generic entries */
326
327 /* IDE */
328
329 // ###### add special ide detail to hd_t!!!
330 res = NULL;
331 gather_resources(hd_data->misc, &res, "ide0", 0);
332 gather_resources(hd_data->misc, &res, "ide1", 0);
333 gather_resources(hd_data->misc, &res, "ide2", 0);
334 gather_resources(hd_data->misc, &res, "ide3", 0);
335 if(res) {
336 for(hd = hd_data->hd; hd; hd = hd->next) {
337 if(
338 hd->base_class.id == bc_storage &&
339 hd->sub_class.id == sc_sto_ide &&
340 have_common_res(hd->res, res)
341 ) break;
342 }
343 if(!hd) {
344 /* eg. non-PCI IDE controller */
345 hd = add_hd_entry(hd_data, __LINE__, 0);
346 hd->base_class.id = bc_storage;
347 hd->sub_class.id = sc_sto_ide;
348 /* use join_res to join the i/o ranges of ide0/1 */
349 join_res_io(&hd->res, res);
350 join_res_irq(&hd->res, res);
351 join_res_dma(&hd->res, res);
352 free_res_list(res);
353 }
354 else {
355 /* eg. PCI IDE controller, add resources */
356 join_res_io(&hd->res, res);
357 join_res_irq(&hd->res, res);
358 join_res_dma(&hd->res, res);
359 free_res_list(res);
360 }
361 }
362
363 /* VGA */
364 res = NULL;
365 gather_resources(hd_data->misc, &res, "vga+", 0);
366 gather_resources(hd_data->misc, &res, "vesafb", 0);
367 if(res) {
368 for(i = 0, hd1 = NULL, hd = hd_data->hd; hd; hd = hd->next) {
369 if(hd->base_class.id == bc_display && hd->sub_class.id == sc_dis_vga) {
370 i++;
371 hd1 = hd;
372 }
373 }
374 if(i == 0) {
375 /* non-PCI VGA card ??? - really, we shouldn't care... */
376 /* FIX THIS !!! ############### */
377 #ifdef __alpha__
378 free_res_list(res);
379 #else
380 hd = add_hd_entry(hd_data, __LINE__, 0);
381 hd->base_class.id = bc_display;
382 hd->sub_class.id = sc_dis_vga;
383 hd->res = res;
384 #endif
385 }
386 else if(i == 1) {
387 /* 1 PCI vga card, add resources */
388 join_res_io(&hd1->res, res);
389 join_res_irq(&hd1->res, res);
390 join_res_dma(&hd1->res, res);
391 free_res_list(res);
392 hd_data->display = hd1->idx;
393 }
394 else {
395 /* more than 1: look again, now only 'active' cards */
396 for(i = 0, hd1 = NULL, hd = hd_data->hd; hd; hd = hd->next) {
397 if(
398 hd->base_class.id == bc_display &&
399 hd->sub_class.id == sc_dis_vga &&
400 active_vga_card(hd)
401 ) {
402 i++;
403 hd1 = hd;
404 }
405 }
406 if(i == 1) {
407 /* 'the' active PCI vga card, add resources */
408 join_res_io(&hd1->res, res);
409 join_res_irq(&hd1->res, res);
410 join_res_dma(&hd1->res, res);
411 hd_data->display = hd1->idx;
412 }
413 else {
414 /* now, what??? */
415 ADD2LOG("Oopy, could not figure out *the* active display adapter!\n");
416 }
417 free_res_list(res);
418 }
419 }
420
421 /* serial ports */
422 res = NULL;
423 gather_resources(hd_data->misc, &res, "serial(auto)", 0);
424 gather_resources(hd_data->misc, &res, "serial(set)", 0);
425 gather_resources(hd_data->misc, &res, "serial", 0);
426 for(hd = hd_data->hd; hd; hd = hd->next) {
427 if(hd->base_class.id == bc_comm && hd->sub_class.id == sc_com_ser) {
428 for(res1 = hd->res; res1; res1 = res1->next) {
429 for(res2 = res; res2; res2 = res2->next) {
430 if(res1->any.type == res2->any.type) {
431 switch(res1->any.type) {
432 case res_irq:
433 if(res1->irq.base == res2->irq.base) {
434 res2->any.type = res_any;
435 }
436 break;
437 case res_io:
438 if(
439 res1->io.base == res2->io.base &&
440 (!res1->io.range || res1->io.range == res2->io.range)
441 ) {
442 res1->io.range = res2->io.range;
443 res2->any.type = res_any;
444 }
445 break;
446 default: /* gcc -Wall */
447 break;
448 }
449 }
450 }
451 }
452 }
453 }
454
455 /* if any of the serial resources are unaccounted for, make an extra entry */
456 for(res2 = res; res2; res2 = res2->next) {
457 if(res2->any.type != res_any) {
458 hd = add_hd_entry(hd_data, __LINE__, 0);
459 hd->base_class.id = bc_comm;
460 hd->sub_class.id = sc_com_ser;
461 hd->prog_if.id = 0x80;
462 for(; res2; res2 = res2->next) {
463 if(res2->any.type != res_any) {
464 res1 = add_res_entry(&hd->res, new_mem(sizeof *res));
465 *res1 = *res2;
466 res1->next = NULL;
467 }
468 }
469 break;
470 }
471 }
472 free_res_list(res);
473
474 /* go through our list and assign event counts to irq entries */
475 m = hd_data->misc;
476 for(hd = hd_data->hd; hd; hd = hd->next) {
477 for(res = hd->res; res; res = res->next) {
478 if(res->irq.type == res_irq) {
479 for(i = 0; (unsigned) i < m->irq_len; i++) {
480 if(res->irq.base == m->irq[i].irq) {
481 res->irq.triggered = m->irq[i].events;
482 break;
483 }
484 }
485 }
486 }
487 }
488
489 /* look for entries with matching start address */
490 m = hd_data->misc;
491 for(hd = hd_data->hd; hd; hd = hd->next) {
492 for(res = hd->res; res; res = res->next) {
493 if(res->io.type == res_io) {
494 for(i = 0; (unsigned) i < m->io_len; i++) {
495 if(res->io.base == m->io[i].addr && res->io.range < m->io[i].size) {
496 res->io.range = m->io[i].size;
497 break;
498 }
499 }
500 }
501 }
502 }
503
504 if((hd_data->debug & HD_DEB_MISC)) dump_misc_data(hd_data);
505 }
506
507
508 /*
509 * read /proc/ioports
510 */
511 void read_ioports(misc_t *m)
512 {
513 char buf[100];
514 misc_io_t *r;
515 uint64_t u, v;
516 str_list_t *sl;
517
518 if(!(m->proc_io = read_file(PROC_IOPORTS, 0, 0))) return;
519
520 for(sl = m->proc_io; sl; sl = sl->next) {
521 if(sscanf(sl->str, " %"PRIx64" - %"PRIx64" : %99[^\n]", &u, &v, buf) == 3) {
522 m->io = add_mem(m->io, sizeof *m->io, m->io_len);
523 r = m->io + m->io_len++;
524 r->addr = u;
525 r->size = v >= u ? v - u + 1 : 0;
526 r->dev = new_str(buf);
527 }
528 }
529 }
530
531 /*
532 * read /proc/dma
533 */
534 void read_dmas(misc_t *m)
535 {
536 char buf[100];
537 misc_dma_t *d;
538 unsigned u;
539 str_list_t *sl;
540
541 if(!(m->proc_dma = read_file(PROC_DMA, 0, 0))) return;
542
543 for(sl = m->proc_dma; sl; sl = sl->next) {
544 if(sscanf(sl->str, " %u : %99[^\n]", &u, buf) == 2) {
545 m->dma = add_mem(m->dma, sizeof *m->dma, m->dma_len);
546 d = m->dma + m->dma_len++;
547 d->channel = u;
548 d->dev = new_str(buf);
549 }
550 }
551 }
552
553
554 /*
555 * read /proc/interrupts
556 *
557 * This is somewhat more tricky, as the irq event counts are done separately
558 * per cpu *and* there may be irq sharing.
559 */
560 void read_irqs(misc_t *m)
561 {
562 char buf[100], buf2[100], *s;
563 misc_irq_t *ir;
564 int i, j;
565 unsigned u, v, k;
566 str_list_t *sl;
567
568 if(!(m->proc_irq = read_file(PROC_INTERRUPTS, 1, 0))) return;
569
570 for(sl = m->proc_irq; sl; sl = sl->next) {
571 /* irq */
572 i = 0;
573 if(sscanf(sl->str, " %u: %n", &u, &i) < 1) continue;
574 v = 0;
575 j = i;
576 /* add up all event counters */
577 while(j < (int) strlen(sl->str) && sscanf(sl->str + j, " %u %n", &k, &i) >= 1) {
578 if(!i) break;
579 v += k;
580 j += i;
581 }
582 /* device driver name string */
583 #if defined(__PPC__)
584 if(
585 sscanf(sl->str + j, " %*s Edge %99[^\n]", buf) == 1 ||
586 sscanf(sl->str + j, " %*s Level %99[^\n]", buf) == 1 ||
587 sscanf(sl->str + j, " %*s %99[^\n]", buf) == 1
588 ) {
589 #else
590 #if defined(__alpha__) || defined(__sparc__)
591 if(sscanf(sl->str + j, " %99[^\n]", buf) == 1) {
592 #else /* __i386__ || __x86_64__ || __ia64__ */
593 if(sscanf(sl->str + j, " %*s %99[^\n]", buf) == 1) {
594 #endif
595 #endif
596 m->irq = add_mem(m->irq, sizeof *m->irq, m->irq_len);
597 ir = m->irq + m->irq_len++;
598 ir->irq = u;
599 ir->events = v;
600
601 /* split device driver names (separated by ',') */
602 s = buf;
603 while(*s && sscanf(s, " %99[^,] %n", buf2, &j) >= 1) {
604 ir->dev = add_mem(ir->dev, sizeof *ir->dev, ir->devs);
605 ir->dev[ir->devs++] = new_str(buf2);
606 s += j;
607 if(*s) s++; /* skip ',' */
608 }
609 }
610 }
611 }
612
613 void gather_resources(misc_t *m, hd_res_t **r, char *name, unsigned which)
614 {
615 int i, j;
616 hd_res_t *res;
617
618 if(!m) return;
619
620 if(!which) which = W_IO | W_DMA | W_IRQ;
621
622 if((which & W_IO)) for(i = 0; (unsigned) i < m->io_len; i++) {
623 if(!strcmp(name, m->io[i].dev)) {
624 res = add_res_entry(r, new_mem(sizeof **r));
625 res->io.type = res_io;
626 res->io.enabled = 1;
627 res->io.base = m->io[i].addr;
628 res->io.range = m->io[i].size;
629 res->io.access = acc_rw;
630 m->io[i].tag++;
631 }
632 }
633
634 if((which & W_DMA)) for(i = 0; (unsigned) i < m->dma_len; i++) {
635 if(!strcmp(name, m->dma[i].dev)) {
636 res = add_res_entry(r, new_mem(sizeof **r));
637 res->dma.type = res_dma;
638 res->dma.enabled = 1;
639 res->dma.base = m->dma[i].channel;
640 m->dma[i].tag++;
641 }
642 }
643
644 if((which & W_IRQ)) for(i = 0; (unsigned) i < m->irq_len; i++) {
645 for(j = 0; j < m->irq[i].devs; j++) {
646 if(!strcmp(name, m->irq[i].dev[j])) {
647 res = add_res_entry(r, new_mem(sizeof **r));
648 res->irq.type = res_irq;
649 res->irq.enabled = 1;
650 res->irq.base = m->irq[i].irq;
651 res->irq.triggered = m->irq[i].events;
652 m->irq[i].tag++;
653 }
654 }
655 }
656 }
657
658
659 int active_vga_card(hd_t *hd)
660 {
661 hd_res_t *res;
662
663 if(hd->bus.id != bus_pci) return 1;
664
665 for(res = hd->res; res; res = res->next) {
666 if(
667 (res->mem.type == res_mem && res->mem.enabled) ||
668 (res->io.type == res_io && res->io.enabled)
669 ) return 1;
670 }
671
672 return 0;
673 }
674
675
676 /*
677 * Add some proc info to the global log.
678 */
679 void dump_misc_proc_data(hd_data_t *hd_data)
680 {
681 str_list_t *sl;
682
683 ADD2LOG("----- /proc/ioports -----\n");
684 for(sl = hd_data->misc->proc_io; sl; sl = sl->next) {
685 ADD2LOG(" %s", sl->str);
686 }
687 ADD2LOG("----- /proc/ioports end -----\n");
688
689 ADD2LOG("----- /proc/interrupts -----\n");
690 for(sl = hd_data->misc->proc_irq; sl; sl = sl->next) {
691 ADD2LOG(" %s", sl->str);
692 }
693 ADD2LOG("----- /proc/interrupts end -----\n");
694
695 ADD2LOG("----- /proc/dma -----\n");
696 for(sl = hd_data->misc->proc_dma; sl; sl = sl->next) {
697 ADD2LOG(" %s", sl->str);
698 }
699 ADD2LOG("----- /proc/dma end -----\n");
700
701 }
702
703
704 /*
705 * Add the resource usage to the global log.
706 */
707 void dump_misc_data(hd_data_t *hd_data)
708 {
709 misc_t *m = hd_data->misc;
710 int i, j;
711
712 ADD2LOG("----- misc resources -----\n");
713
714 for(i = 0; (unsigned) i < m->io_len; i++) {
715 ADD2LOG(
716 "i/o:%u 0x%04"PRIx64" - 0x%04"PRIx64" (0x%02"PRIx64") \"%s\"\n",
717 m->io[i].tag,
718 m->io[i].addr, m->io[i].addr + m->io[i].size - 1,
719 m->io[i].size, m->io[i].dev
720 );
721 }
722
723 for(i = 0; (unsigned) i < m->irq_len; i++) {
724 ADD2LOG(
725 "irq:%u %2u (%9u)",
726 m->irq[i].tag, m->irq[i].irq, m->irq[i].events
727 );
728 for(j = 0; j < m->irq[i].devs; j++) {
729 ADD2LOG(" \"%s\"", m->irq[i].dev[j]);
730 }
731 ADD2LOG("\n");
732 }
733
734 for(i = 0; (unsigned) i < m->dma_len; i++) {
735 ADD2LOG(
736 "dma:%u %u \"%s\"\n",
737 m->dma[i].tag, m->dma[i].channel, m->dma[i].dev
738 );
739 }
740
741 ADD2LOG("----- misc resources end -----\n");
742 }