2 * rsparser.c - parses and encodes pnpbios resource data streams
5 #include <linux/ctype.h>
7 #include <linux/pnpbios.h>
8 #include <linux/string.h>
9 #include <linux/slab.h>
12 #include <linux/pci.h>
14 inline void pcibios_penalize_isa_irq(int irq, int active)
17 #endif /* CONFIG_PCI */
22 /* standard resource tags */
23 #define SMALL_TAG_PNPVERNO 0x01
24 #define SMALL_TAG_LOGDEVID 0x02
25 #define SMALL_TAG_COMPATDEVID 0x03
26 #define SMALL_TAG_IRQ 0x04
27 #define SMALL_TAG_DMA 0x05
28 #define SMALL_TAG_STARTDEP 0x06
29 #define SMALL_TAG_ENDDEP 0x07
30 #define SMALL_TAG_PORT 0x08
31 #define SMALL_TAG_FIXEDPORT 0x09
32 #define SMALL_TAG_VENDOR 0x0e
33 #define SMALL_TAG_END 0x0f
34 #define LARGE_TAG 0x80
35 #define LARGE_TAG_MEM 0x81
36 #define LARGE_TAG_ANSISTR 0x82
37 #define LARGE_TAG_UNICODESTR 0x83
38 #define LARGE_TAG_VENDOR 0x84
39 #define LARGE_TAG_MEM32 0x85
40 #define LARGE_TAG_FIXEDMEM32 0x86
43 * Resource Data Stream Format:
45 * Allocated Resources (required)
47 * Resource Configuration Options (optional)
49 * Compitable Device IDs (optional)
57 static void pnpbios_parse_allocated_ioresource(struct pnp_dev *dev,
61 int end = start + len - 1;
63 if (len <= 0 || end >= 0x10003)
64 flags |= IORESOURCE_DISABLED;
66 pnp_add_io_resource(dev, start, end, flags);
69 static void pnpbios_parse_allocated_memresource(struct pnp_dev *dev,
73 int end = start + len - 1;
76 flags |= IORESOURCE_DISABLED;
78 pnp_add_mem_resource(dev, start, end, flags);
81 static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev,
85 unsigned int len, tag;
86 int io, size, mask, i, flags;
91 dev_dbg(&dev->dev, "parse allocated resources\n");
93 pnp_init_resources(dev);
95 while ((char *)p < (char *)end) {
97 /* determine the type of tag */
98 if (p[0] & LARGE_TAG) { /* large tag */
99 len = (p[2] << 8) | p[1];
101 } else { /* small tag */
103 tag = ((p[0] >> 3) & 0x0f);
111 io = *(short *)&p[4];
112 size = *(short *)&p[10];
113 pnpbios_parse_allocated_memresource(dev, io, size);
116 case LARGE_TAG_ANSISTR:
117 /* ignore this for now */
120 case LARGE_TAG_VENDOR:
124 case LARGE_TAG_MEM32:
128 size = *(int *)&p[16];
129 pnpbios_parse_allocated_memresource(dev, io, size);
132 case LARGE_TAG_FIXEDMEM32:
136 size = *(int *)&p[8];
137 pnpbios_parse_allocated_memresource(dev, io, size);
141 if (len < 2 || len > 3)
145 mask = p[1] + p[2] * 256;
146 for (i = 0; i < 16; i++, mask = mask >> 1)
150 pcibios_penalize_isa_irq(io, 1);
152 flags = IORESOURCE_DISABLED;
153 pnp_add_irq_resource(dev, io, flags);
162 for (i = 0; i < 8; i++, mask = mask >> 1)
166 flags = IORESOURCE_DISABLED;
167 pnp_add_dma_resource(dev, io, flags);
173 io = p[2] + p[3] * 256;
175 pnpbios_parse_allocated_ioresource(dev, io, size);
178 case SMALL_TAG_VENDOR:
182 case SMALL_TAG_FIXEDPORT:
185 io = p[1] + p[2] * 256;
187 pnpbios_parse_allocated_ioresource(dev, io, size);
192 return (unsigned char *)p;
195 default: /* an unkown tag */
197 dev_err(&dev->dev, "unknown tag %#x length %d\n",
202 /* continue to the next tag */
203 if (p[0] & LARGE_TAG)
209 dev_err(&dev->dev, "no end tag in resource structure\n");
215 * Resource Configuration Options
218 static __init void pnpbios_parse_mem_option(struct pnp_dev *dev,
219 unsigned char *p, int size,
220 struct pnp_option *option)
224 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
227 mem->min = ((p[5] << 8) | p[4]) << 8;
228 mem->max = ((p[7] << 8) | p[6]) << 8;
229 mem->align = (p[9] << 8) | p[8];
230 mem->size = ((p[11] << 8) | p[10]) << 8;
232 pnp_register_mem_resource(dev, option, mem);
235 static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev,
236 unsigned char *p, int size,
237 struct pnp_option *option)
241 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
244 mem->min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
245 mem->max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
246 mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
247 mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
249 pnp_register_mem_resource(dev, option, mem);
252 static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev,
253 unsigned char *p, int size,
254 struct pnp_option *option)
258 mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
261 mem->min = mem->max = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
262 mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
265 pnp_register_mem_resource(dev, option, mem);
268 static __init void pnpbios_parse_irq_option(struct pnp_dev *dev,
269 unsigned char *p, int size,
270 struct pnp_option *option)
275 irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
278 bits = (p[2] << 8) | p[1];
279 bitmap_copy(irq->map, &bits, 16);
283 irq->flags = IORESOURCE_IRQ_HIGHEDGE;
284 pnp_register_irq_resource(dev, option, irq);
287 static __init void pnpbios_parse_dma_option(struct pnp_dev *dev,
288 unsigned char *p, int size,
289 struct pnp_option *option)
293 dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
298 pnp_register_dma_resource(dev, option, dma);
301 static __init void pnpbios_parse_port_option(struct pnp_dev *dev,
302 unsigned char *p, int size,
303 struct pnp_option *option)
305 struct pnp_port *port;
307 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
310 port->min = (p[3] << 8) | p[2];
311 port->max = (p[5] << 8) | p[4];
314 port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0;
315 pnp_register_port_resource(dev, option, port);
318 static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev,
319 unsigned char *p, int size,
320 struct pnp_option *option)
322 struct pnp_port *port;
324 port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
327 port->min = port->max = (p[2] << 8) | p[1];
330 port->flags = PNP_PORT_FLAG_FIXED;
331 pnp_register_port_resource(dev, option, port);
334 static __init unsigned char *
335 pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
338 unsigned int len, tag;
340 struct pnp_option *option, *option_independent;
345 dev_dbg(&dev->dev, "parse resource options\n");
347 option_independent = option = pnp_register_independent_option(dev);
351 while ((char *)p < (char *)end) {
353 /* determine the type of tag */
354 if (p[0] & LARGE_TAG) { /* large tag */
355 len = (p[2] << 8) | p[1];
357 } else { /* small tag */
359 tag = ((p[0] >> 3) & 0x0f);
367 pnpbios_parse_mem_option(dev, p, len, option);
370 case LARGE_TAG_MEM32:
373 pnpbios_parse_mem32_option(dev, p, len, option);
376 case LARGE_TAG_FIXEDMEM32:
379 pnpbios_parse_fixed_mem32_option(dev, p, len, option);
383 if (len < 2 || len > 3)
385 pnpbios_parse_irq_option(dev, p, len, option);
391 pnpbios_parse_dma_option(dev, p, len, option);
397 pnpbios_parse_port_option(dev, p, len, option);
400 case SMALL_TAG_VENDOR:
404 case SMALL_TAG_FIXEDPORT:
407 pnpbios_parse_fixed_port_option(dev, p, len, option);
410 case SMALL_TAG_STARTDEP:
413 priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
415 priority = 0x100 | p[1];
416 option = pnp_register_dependent_option(dev, priority);
421 case SMALL_TAG_ENDDEP:
424 if (option_independent == option)
425 dev_warn(&dev->dev, "missing "
426 "SMALL_TAG_STARTDEP tag\n");
427 option = option_independent;
428 dev_dbg(&dev->dev, "end dependent options\n");
434 default: /* an unkown tag */
436 dev_err(&dev->dev, "unknown tag %#x length %d\n",
441 /* continue to the next tag */
442 if (p[0] & LARGE_TAG)
448 dev_err(&dev->dev, "no end tag in resource structure\n");
454 * Compatible Device IDs
457 static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
464 struct pnp_id *dev_id;
469 while ((char *)p < (char *)end) {
471 /* determine the type of tag */
472 if (p[0] & LARGE_TAG) { /* large tag */
473 len = (p[2] << 8) | p[1];
475 } else { /* small tag */
477 tag = ((p[0] >> 3) & 0x0f);
482 case LARGE_TAG_ANSISTR:
483 strncpy(dev->name, p + 3,
484 len >= PNP_NAME_LEN ? PNP_NAME_LEN - 2 : len);
486 PNP_NAME_LEN ? PNP_NAME_LEN - 1 : len] = '\0';
489 case SMALL_TAG_COMPATDEVID: /* compatible ID */
492 eisa_id = p[1] | p[2] << 8 | p[3] << 16 | p[4] << 24;
493 pnp_eisa_id_to_string(eisa_id & PNP_EISA_ID_MASK, id);
494 dev_id = pnp_add_id(dev, id);
501 return (unsigned char *)p;
504 default: /* an unkown tag */
506 dev_err(&dev->dev, "unknown tag %#x length %d\n",
511 /* continue to the next tag */
512 if (p[0] & LARGE_TAG)
518 dev_err(&dev->dev, "no end tag in resource structure\n");
524 * Allocated Resource Encoding
527 static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
528 struct resource *res)
530 unsigned long base = res->start;
531 unsigned long len = res->end - res->start + 1;
533 p[4] = (base >> 8) & 0xff;
534 p[5] = ((base >> 8) >> 8) & 0xff;
535 p[6] = (base >> 8) & 0xff;
536 p[7] = ((base >> 8) >> 8) & 0xff;
537 p[10] = (len >> 8) & 0xff;
538 p[11] = ((len >> 8) >> 8) & 0xff;
540 dev_dbg(&dev->dev, " encode mem %#llx-%#llx\n",
541 (unsigned long long) res->start, (unsigned long long) res->end);
544 static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
545 struct resource *res)
547 unsigned long base = res->start;
548 unsigned long len = res->end - res->start + 1;
551 p[5] = (base >> 8) & 0xff;
552 p[6] = (base >> 16) & 0xff;
553 p[7] = (base >> 24) & 0xff;
555 p[9] = (base >> 8) & 0xff;
556 p[10] = (base >> 16) & 0xff;
557 p[11] = (base >> 24) & 0xff;
559 p[17] = (len >> 8) & 0xff;
560 p[18] = (len >> 16) & 0xff;
561 p[19] = (len >> 24) & 0xff;
563 dev_dbg(&dev->dev, " encode mem32 %#llx-%#llx\n",
564 (unsigned long long) res->start, (unsigned long long) res->end);
567 static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
568 struct resource *res)
570 unsigned long base = res->start;
571 unsigned long len = res->end - res->start + 1;
574 p[5] = (base >> 8) & 0xff;
575 p[6] = (base >> 16) & 0xff;
576 p[7] = (base >> 24) & 0xff;
578 p[9] = (len >> 8) & 0xff;
579 p[10] = (len >> 16) & 0xff;
580 p[11] = (len >> 24) & 0xff;
582 dev_dbg(&dev->dev, " encode fixed_mem32 %#llx-%#llx\n",
583 (unsigned long long) res->start, (unsigned long long) res->end);
586 static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p,
587 struct resource *res)
589 unsigned long map = 0;
591 map = 1 << res->start;
593 p[2] = (map >> 8) & 0xff;
595 dev_dbg(&dev->dev, " encode irq %d\n", res->start);
598 static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
599 struct resource *res)
601 unsigned long map = 0;
603 map = 1 << res->start;
606 dev_dbg(&dev->dev, " encode dma %d\n", res->start);
609 static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
610 struct resource *res)
612 unsigned long base = res->start;
613 unsigned long len = res->end - res->start + 1;
616 p[3] = (base >> 8) & 0xff;
618 p[5] = (base >> 8) & 0xff;
621 dev_dbg(&dev->dev, " encode io %#llx-%#llx\n",
622 (unsigned long long) res->start, (unsigned long long) res->end);
625 static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
626 struct resource *res)
628 unsigned long base = res->start;
629 unsigned long len = res->end - res->start + 1;
632 p[2] = (base >> 8) & 0xff;
635 dev_dbg(&dev->dev, " encode fixed_io %#llx-%#llx\n",
636 (unsigned long long) res->start, (unsigned long long) res->end);
639 static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev
644 unsigned int len, tag;
645 int port = 0, irq = 0, dma = 0, mem = 0;
650 while ((char *)p < (char *)end) {
652 /* determine the type of tag */
653 if (p[0] & LARGE_TAG) { /* large tag */
654 len = (p[2] << 8) | p[1];
656 } else { /* small tag */
658 tag = ((p[0] >> 3) & 0x0f);
666 pnpbios_encode_mem(dev, p,
667 pnp_get_resource(dev, IORESOURCE_MEM, mem));
671 case LARGE_TAG_MEM32:
674 pnpbios_encode_mem32(dev, p,
675 pnp_get_resource(dev, IORESOURCE_MEM, mem));
679 case LARGE_TAG_FIXEDMEM32:
682 pnpbios_encode_fixed_mem32(dev, p,
683 pnp_get_resource(dev, IORESOURCE_MEM, mem));
688 if (len < 2 || len > 3)
690 pnpbios_encode_irq(dev, p,
691 pnp_get_resource(dev, IORESOURCE_IRQ, irq));
698 pnpbios_encode_dma(dev, p,
699 pnp_get_resource(dev, IORESOURCE_DMA, dma));
706 pnpbios_encode_port(dev, p,
707 pnp_get_resource(dev, IORESOURCE_IO, port));
711 case SMALL_TAG_VENDOR:
715 case SMALL_TAG_FIXEDPORT:
718 pnpbios_encode_fixed_port(dev, p,
719 pnp_get_resource(dev, IORESOURCE_IO, port));
725 return (unsigned char *)p;
728 default: /* an unkown tag */
730 dev_err(&dev->dev, "unknown tag %#x length %d\n",
735 /* continue to the next tag */
736 if (p[0] & LARGE_TAG)
742 dev_err(&dev->dev, "no end tag in resource structure\n");
748 * Core Parsing Functions
751 int __init pnpbios_parse_data_stream(struct pnp_dev *dev,
752 struct pnp_bios_node *node)
754 unsigned char *p = (char *)node->data;
755 unsigned char *end = (char *)(node->data + node->size);
757 p = pnpbios_parse_allocated_resource_data(dev, p, end);
760 p = pnpbios_parse_resource_option_data(p, end, dev);
763 p = pnpbios_parse_compatible_ids(p, end, dev);
769 int pnpbios_read_resources_from_node(struct pnp_dev *dev,
770 struct pnp_bios_node *node)
772 unsigned char *p = (char *)node->data;
773 unsigned char *end = (char *)(node->data + node->size);
775 p = pnpbios_parse_allocated_resource_data(dev, p, end);
781 int pnpbios_write_resources_to_node(struct pnp_dev *dev,
782 struct pnp_bios_node *node)
784 unsigned char *p = (char *)node->data;
785 unsigned char *end = (char *)(node->data + node->size);
787 p = pnpbios_encode_allocated_resource_data(dev, p, end);