845730c57edcec60a63dd5a23eed0198c9e3aee0
[pandora-kernel.git] / drivers / pnp / pnpbios / rsparser.c
1 /*
2  * rsparser.c - parses and encodes pnpbios resource data streams
3  */
4
5 #include <linux/ctype.h>
6 #include <linux/pnp.h>
7 #include <linux/pnpbios.h>
8 #include <linux/string.h>
9 #include <linux/slab.h>
10
11 #ifdef CONFIG_PCI
12 #include <linux/pci.h>
13 #else
14 inline void pcibios_penalize_isa_irq(int irq, int active)
15 {
16 }
17 #endif                          /* CONFIG_PCI */
18
19 #include "../base.h"
20 #include "pnpbios.h"
21
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
41
42 /*
43  * Resource Data Stream Format:
44  *
45  * Allocated Resources (required)
46  * end tag ->
47  * Resource Configuration Options (optional)
48  * end tag ->
49  * Compitable Device IDs (optional)
50  * final end tag ->
51  */
52
53 /*
54  * Allocated Resources
55  */
56
57 static void pnpbios_parse_allocated_dmaresource(struct pnp_dev *dev, int dma)
58 {
59         struct resource *res;
60         int i;
61
62         for (i = 0; i < PNP_MAX_DMA; i++) {
63                 res = pnp_get_resource(dev, IORESOURCE_DMA, i);
64                 if (!pnp_resource_valid(res))
65                         break;
66         }
67
68         if (i < PNP_MAX_DMA) {
69                 res->flags = IORESOURCE_DMA;    // Also clears _UNSET flag
70                 if (dma == -1) {
71                         res->flags |= IORESOURCE_DISABLED;
72                         return;
73                 }
74                 res->start = res->end = (unsigned long)dma;
75         }
76 }
77
78 static void pnpbios_parse_allocated_ioresource(struct pnp_dev *dev,
79                                                int io, int len)
80 {
81         struct resource *res;
82         int i;
83
84         for (i = 0; i < PNP_MAX_PORT; i++) {
85                 res = pnp_get_resource(dev, IORESOURCE_IO, i);
86                 if (!pnp_resource_valid(res))
87                         break;
88         }
89
90         if (i < PNP_MAX_PORT) {
91                 res->flags = IORESOURCE_IO;     // Also clears _UNSET flag
92                 if (len <= 0 || (io + len - 1) >= 0x10003) {
93                         res->flags |= IORESOURCE_DISABLED;
94                         return;
95                 }
96                 res->start = (unsigned long)io;
97                 res->end = (unsigned long)(io + len - 1);
98         }
99 }
100
101 static void pnpbios_parse_allocated_memresource(struct pnp_dev *dev,
102                                                 int mem, int len)
103 {
104         struct resource *res;
105         int i;
106
107         for (i = 0; i < PNP_MAX_MEM; i++) {
108                 res = pnp_get_resource(dev, IORESOURCE_MEM, i);
109                 if (!pnp_resource_valid(res))
110                         break;
111         }
112
113         if (i < PNP_MAX_MEM) {
114                 res->flags = IORESOURCE_MEM;    // Also clears _UNSET flag
115                 if (len <= 0) {
116                         res->flags |= IORESOURCE_DISABLED;
117                         return;
118                 }
119                 res->start = (unsigned long)mem;
120                 res->end = (unsigned long)(mem + len - 1);
121         }
122 }
123
124 static unsigned char *pnpbios_parse_allocated_resource_data(struct pnp_dev *dev,
125                                                             unsigned char *p,
126                                                             unsigned char *end)
127 {
128         unsigned int len, tag;
129         int io, size, mask, i, flags;
130
131         if (!p)
132                 return NULL;
133
134         dev_dbg(&dev->dev, "parse allocated resources\n");
135
136         pnp_init_resources(dev);
137
138         while ((char *)p < (char *)end) {
139
140                 /* determine the type of tag */
141                 if (p[0] & LARGE_TAG) { /* large tag */
142                         len = (p[2] << 8) | p[1];
143                         tag = p[0];
144                 } else {        /* small tag */
145                         len = p[0] & 0x07;
146                         tag = ((p[0] >> 3) & 0x0f);
147                 }
148
149                 switch (tag) {
150
151                 case LARGE_TAG_MEM:
152                         if (len != 9)
153                                 goto len_err;
154                         io = *(short *)&p[4];
155                         size = *(short *)&p[10];
156                         pnpbios_parse_allocated_memresource(dev, io, size);
157                         break;
158
159                 case LARGE_TAG_ANSISTR:
160                         /* ignore this for now */
161                         break;
162
163                 case LARGE_TAG_VENDOR:
164                         /* do nothing */
165                         break;
166
167                 case LARGE_TAG_MEM32:
168                         if (len != 17)
169                                 goto len_err;
170                         io = *(int *)&p[4];
171                         size = *(int *)&p[16];
172                         pnpbios_parse_allocated_memresource(dev, io, size);
173                         break;
174
175                 case LARGE_TAG_FIXEDMEM32:
176                         if (len != 9)
177                                 goto len_err;
178                         io = *(int *)&p[4];
179                         size = *(int *)&p[8];
180                         pnpbios_parse_allocated_memresource(dev, io, size);
181                         break;
182
183                 case SMALL_TAG_IRQ:
184                         if (len < 2 || len > 3)
185                                 goto len_err;
186                         flags = 0;
187                         io = -1;
188                         mask = p[1] + p[2] * 256;
189                         for (i = 0; i < 16; i++, mask = mask >> 1)
190                                 if (mask & 0x01)
191                                         io = i;
192                         if (io != -1)
193                                 pcibios_penalize_isa_irq(io, 1);
194                         else
195                                 flags = IORESOURCE_DISABLED;
196                         pnp_add_irq_resource(dev, io, flags);
197                         break;
198
199                 case SMALL_TAG_DMA:
200                         if (len != 2)
201                                 goto len_err;
202                         io = -1;
203                         mask = p[1];
204                         for (i = 0; i < 8; i++, mask = mask >> 1)
205                                 if (mask & 0x01)
206                                         io = i;
207                         pnpbios_parse_allocated_dmaresource(dev, io);
208                         break;
209
210                 case SMALL_TAG_PORT:
211                         if (len != 7)
212                                 goto len_err;
213                         io = p[2] + p[3] * 256;
214                         size = p[7];
215                         pnpbios_parse_allocated_ioresource(dev, io, size);
216                         break;
217
218                 case SMALL_TAG_VENDOR:
219                         /* do nothing */
220                         break;
221
222                 case SMALL_TAG_FIXEDPORT:
223                         if (len != 3)
224                                 goto len_err;
225                         io = p[1] + p[2] * 256;
226                         size = p[3];
227                         pnpbios_parse_allocated_ioresource(dev, io, size);
228                         break;
229
230                 case SMALL_TAG_END:
231                         p = p + 2;
232                         return (unsigned char *)p;
233                         break;
234
235                 default:        /* an unkown tag */
236 len_err:
237                         dev_err(&dev->dev, "unknown tag %#x length %d\n",
238                                 tag, len);
239                         break;
240                 }
241
242                 /* continue to the next tag */
243                 if (p[0] & LARGE_TAG)
244                         p += len + 3;
245                 else
246                         p += len + 1;
247         }
248
249         dev_err(&dev->dev, "no end tag in resource structure\n");
250
251         return NULL;
252 }
253
254 /*
255  * Resource Configuration Options
256  */
257
258 static __init void pnpbios_parse_mem_option(struct pnp_dev *dev,
259                                             unsigned char *p, int size,
260                                             struct pnp_option *option)
261 {
262         struct pnp_mem *mem;
263
264         mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
265         if (!mem)
266                 return;
267         mem->min = ((p[5] << 8) | p[4]) << 8;
268         mem->max = ((p[7] << 8) | p[6]) << 8;
269         mem->align = (p[9] << 8) | p[8];
270         mem->size = ((p[11] << 8) | p[10]) << 8;
271         mem->flags = p[3];
272         pnp_register_mem_resource(dev, option, mem);
273 }
274
275 static __init void pnpbios_parse_mem32_option(struct pnp_dev *dev,
276                                               unsigned char *p, int size,
277                                               struct pnp_option *option)
278 {
279         struct pnp_mem *mem;
280
281         mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
282         if (!mem)
283                 return;
284         mem->min = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
285         mem->max = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
286         mem->align = (p[15] << 24) | (p[14] << 16) | (p[13] << 8) | p[12];
287         mem->size = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | p[16];
288         mem->flags = p[3];
289         pnp_register_mem_resource(dev, option, mem);
290 }
291
292 static __init void pnpbios_parse_fixed_mem32_option(struct pnp_dev *dev,
293                                                     unsigned char *p, int size,
294                                                     struct pnp_option *option)
295 {
296         struct pnp_mem *mem;
297
298         mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
299         if (!mem)
300                 return;
301         mem->min = mem->max = (p[7] << 24) | (p[6] << 16) | (p[5] << 8) | p[4];
302         mem->size = (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | p[8];
303         mem->align = 0;
304         mem->flags = p[3];
305         pnp_register_mem_resource(dev, option, mem);
306 }
307
308 static __init void pnpbios_parse_irq_option(struct pnp_dev *dev,
309                                             unsigned char *p, int size,
310                                             struct pnp_option *option)
311 {
312         struct pnp_irq *irq;
313         unsigned long bits;
314
315         irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
316         if (!irq)
317                 return;
318         bits = (p[2] << 8) | p[1];
319         bitmap_copy(irq->map, &bits, 16);
320         if (size > 2)
321                 irq->flags = p[3];
322         else
323                 irq->flags = IORESOURCE_IRQ_HIGHEDGE;
324         pnp_register_irq_resource(dev, option, irq);
325 }
326
327 static __init void pnpbios_parse_dma_option(struct pnp_dev *dev,
328                                             unsigned char *p, int size,
329                                             struct pnp_option *option)
330 {
331         struct pnp_dma *dma;
332
333         dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
334         if (!dma)
335                 return;
336         dma->map = p[1];
337         dma->flags = p[2];
338         pnp_register_dma_resource(dev, option, dma);
339 }
340
341 static __init void pnpbios_parse_port_option(struct pnp_dev *dev,
342                                              unsigned char *p, int size,
343                                              struct pnp_option *option)
344 {
345         struct pnp_port *port;
346
347         port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
348         if (!port)
349                 return;
350         port->min = (p[3] << 8) | p[2];
351         port->max = (p[5] << 8) | p[4];
352         port->align = p[6];
353         port->size = p[7];
354         port->flags = p[1] ? PNP_PORT_FLAG_16BITADDR : 0;
355         pnp_register_port_resource(dev, option, port);
356 }
357
358 static __init void pnpbios_parse_fixed_port_option(struct pnp_dev *dev,
359                                                    unsigned char *p, int size,
360                                                    struct pnp_option *option)
361 {
362         struct pnp_port *port;
363
364         port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
365         if (!port)
366                 return;
367         port->min = port->max = (p[2] << 8) | p[1];
368         port->size = p[3];
369         port->align = 0;
370         port->flags = PNP_PORT_FLAG_FIXED;
371         pnp_register_port_resource(dev, option, port);
372 }
373
374 static __init unsigned char *
375 pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end,
376                                         struct pnp_dev *dev)
377 {
378         unsigned int len, tag;
379         int priority = 0;
380         struct pnp_option *option, *option_independent;
381
382         if (!p)
383                 return NULL;
384
385         dev_dbg(&dev->dev, "parse resource options\n");
386
387         option_independent = option = pnp_register_independent_option(dev);
388         if (!option)
389                 return NULL;
390
391         while ((char *)p < (char *)end) {
392
393                 /* determine the type of tag */
394                 if (p[0] & LARGE_TAG) { /* large tag */
395                         len = (p[2] << 8) | p[1];
396                         tag = p[0];
397                 } else {        /* small tag */
398                         len = p[0] & 0x07;
399                         tag = ((p[0] >> 3) & 0x0f);
400                 }
401
402                 switch (tag) {
403
404                 case LARGE_TAG_MEM:
405                         if (len != 9)
406                                 goto len_err;
407                         pnpbios_parse_mem_option(dev, p, len, option);
408                         break;
409
410                 case LARGE_TAG_MEM32:
411                         if (len != 17)
412                                 goto len_err;
413                         pnpbios_parse_mem32_option(dev, p, len, option);
414                         break;
415
416                 case LARGE_TAG_FIXEDMEM32:
417                         if (len != 9)
418                                 goto len_err;
419                         pnpbios_parse_fixed_mem32_option(dev, p, len, option);
420                         break;
421
422                 case SMALL_TAG_IRQ:
423                         if (len < 2 || len > 3)
424                                 goto len_err;
425                         pnpbios_parse_irq_option(dev, p, len, option);
426                         break;
427
428                 case SMALL_TAG_DMA:
429                         if (len != 2)
430                                 goto len_err;
431                         pnpbios_parse_dma_option(dev, p, len, option);
432                         break;
433
434                 case SMALL_TAG_PORT:
435                         if (len != 7)
436                                 goto len_err;
437                         pnpbios_parse_port_option(dev, p, len, option);
438                         break;
439
440                 case SMALL_TAG_VENDOR:
441                         /* do nothing */
442                         break;
443
444                 case SMALL_TAG_FIXEDPORT:
445                         if (len != 3)
446                                 goto len_err;
447                         pnpbios_parse_fixed_port_option(dev, p, len, option);
448                         break;
449
450                 case SMALL_TAG_STARTDEP:
451                         if (len > 1)
452                                 goto len_err;
453                         priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
454                         if (len > 0)
455                                 priority = 0x100 | p[1];
456                         option = pnp_register_dependent_option(dev, priority);
457                         if (!option)
458                                 return NULL;
459                         break;
460
461                 case SMALL_TAG_ENDDEP:
462                         if (len != 0)
463                                 goto len_err;
464                         if (option_independent == option)
465                                 dev_warn(&dev->dev, "missing "
466                                          "SMALL_TAG_STARTDEP tag\n");
467                         option = option_independent;
468                         dev_dbg(&dev->dev, "end dependent options\n");
469                         break;
470
471                 case SMALL_TAG_END:
472                         return p + 2;
473
474                 default:        /* an unkown tag */
475 len_err:
476                         dev_err(&dev->dev, "unknown tag %#x length %d\n",
477                                 tag, len);
478                         break;
479                 }
480
481                 /* continue to the next tag */
482                 if (p[0] & LARGE_TAG)
483                         p += len + 3;
484                 else
485                         p += len + 1;
486         }
487
488         dev_err(&dev->dev, "no end tag in resource structure\n");
489
490         return NULL;
491 }
492
493 /*
494  * Compatible Device IDs
495  */
496
497 static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p,
498                                                    unsigned char *end,
499                                                    struct pnp_dev *dev)
500 {
501         int len, tag;
502         u32 eisa_id;
503         char id[8];
504         struct pnp_id *dev_id;
505
506         if (!p)
507                 return NULL;
508
509         while ((char *)p < (char *)end) {
510
511                 /* determine the type of tag */
512                 if (p[0] & LARGE_TAG) { /* large tag */
513                         len = (p[2] << 8) | p[1];
514                         tag = p[0];
515                 } else {        /* small tag */
516                         len = p[0] & 0x07;
517                         tag = ((p[0] >> 3) & 0x0f);
518                 }
519
520                 switch (tag) {
521
522                 case LARGE_TAG_ANSISTR:
523                         strncpy(dev->name, p + 3,
524                                 len >= PNP_NAME_LEN ? PNP_NAME_LEN - 2 : len);
525                         dev->name[len >=
526                                   PNP_NAME_LEN ? PNP_NAME_LEN - 1 : len] = '\0';
527                         break;
528
529                 case SMALL_TAG_COMPATDEVID:     /* compatible ID */
530                         if (len != 4)
531                                 goto len_err;
532                         eisa_id = p[1] | p[2] << 8 | p[3] << 16 | p[4] << 24;
533                         pnp_eisa_id_to_string(eisa_id & PNP_EISA_ID_MASK, id);
534                         dev_id = pnp_add_id(dev, id);
535                         if (!dev_id)
536                                 return NULL;
537                         break;
538
539                 case SMALL_TAG_END:
540                         p = p + 2;
541                         return (unsigned char *)p;
542                         break;
543
544                 default:        /* an unkown tag */
545 len_err:
546                         dev_err(&dev->dev, "unknown tag %#x length %d\n",
547                                 tag, len);
548                         break;
549                 }
550
551                 /* continue to the next tag */
552                 if (p[0] & LARGE_TAG)
553                         p += len + 3;
554                 else
555                         p += len + 1;
556         }
557
558         dev_err(&dev->dev, "no end tag in resource structure\n");
559
560         return NULL;
561 }
562
563 /*
564  * Allocated Resource Encoding
565  */
566
567 static void pnpbios_encode_mem(struct pnp_dev *dev, unsigned char *p,
568                                struct resource *res)
569 {
570         unsigned long base = res->start;
571         unsigned long len = res->end - res->start + 1;
572
573         p[4] = (base >> 8) & 0xff;
574         p[5] = ((base >> 8) >> 8) & 0xff;
575         p[6] = (base >> 8) & 0xff;
576         p[7] = ((base >> 8) >> 8) & 0xff;
577         p[10] = (len >> 8) & 0xff;
578         p[11] = ((len >> 8) >> 8) & 0xff;
579
580         dev_dbg(&dev->dev, "  encode mem %#llx-%#llx\n",
581                 (unsigned long long) res->start, (unsigned long long) res->end);
582 }
583
584 static void pnpbios_encode_mem32(struct pnp_dev *dev, unsigned char *p,
585                                  struct resource *res)
586 {
587         unsigned long base = res->start;
588         unsigned long len = res->end - res->start + 1;
589
590         p[4] = base & 0xff;
591         p[5] = (base >> 8) & 0xff;
592         p[6] = (base >> 16) & 0xff;
593         p[7] = (base >> 24) & 0xff;
594         p[8] = base & 0xff;
595         p[9] = (base >> 8) & 0xff;
596         p[10] = (base >> 16) & 0xff;
597         p[11] = (base >> 24) & 0xff;
598         p[16] = len & 0xff;
599         p[17] = (len >> 8) & 0xff;
600         p[18] = (len >> 16) & 0xff;
601         p[19] = (len >> 24) & 0xff;
602
603         dev_dbg(&dev->dev, "  encode mem32 %#llx-%#llx\n",
604                 (unsigned long long) res->start, (unsigned long long) res->end);
605 }
606
607 static void pnpbios_encode_fixed_mem32(struct pnp_dev *dev, unsigned char *p,
608                                        struct resource *res)
609 {
610         unsigned long base = res->start;
611         unsigned long len = res->end - res->start + 1;
612
613         p[4] = base & 0xff;
614         p[5] = (base >> 8) & 0xff;
615         p[6] = (base >> 16) & 0xff;
616         p[7] = (base >> 24) & 0xff;
617         p[8] = len & 0xff;
618         p[9] = (len >> 8) & 0xff;
619         p[10] = (len >> 16) & 0xff;
620         p[11] = (len >> 24) & 0xff;
621
622         dev_dbg(&dev->dev, "  encode fixed_mem32 %#llx-%#llx\n",
623                 (unsigned long long) res->start, (unsigned long long) res->end);
624 }
625
626 static void pnpbios_encode_irq(struct pnp_dev *dev, unsigned char *p,
627                                struct resource *res)
628 {
629         unsigned long map = 0;
630
631         map = 1 << res->start;
632         p[1] = map & 0xff;
633         p[2] = (map >> 8) & 0xff;
634
635         dev_dbg(&dev->dev, "  encode irq %d\n", res->start);
636 }
637
638 static void pnpbios_encode_dma(struct pnp_dev *dev, unsigned char *p,
639                                struct resource *res)
640 {
641         unsigned long map = 0;
642
643         map = 1 << res->start;
644         p[1] = map & 0xff;
645
646         dev_dbg(&dev->dev, "  encode dma %d\n", res->start);
647 }
648
649 static void pnpbios_encode_port(struct pnp_dev *dev, unsigned char *p,
650                                 struct resource *res)
651 {
652         unsigned long base = res->start;
653         unsigned long len = res->end - res->start + 1;
654
655         p[2] = base & 0xff;
656         p[3] = (base >> 8) & 0xff;
657         p[4] = base & 0xff;
658         p[5] = (base >> 8) & 0xff;
659         p[7] = len & 0xff;
660
661         dev_dbg(&dev->dev, "  encode io %#llx-%#llx\n",
662                 (unsigned long long) res->start, (unsigned long long) res->end);
663 }
664
665 static void pnpbios_encode_fixed_port(struct pnp_dev *dev, unsigned char *p,
666                                       struct resource *res)
667 {
668         unsigned long base = res->start;
669         unsigned long len = res->end - res->start + 1;
670
671         p[1] = base & 0xff;
672         p[2] = (base >> 8) & 0xff;
673         p[3] = len & 0xff;
674
675         dev_dbg(&dev->dev, "  encode fixed_io %#llx-%#llx\n",
676                 (unsigned long long) res->start, (unsigned long long) res->end);
677 }
678
679 static unsigned char *pnpbios_encode_allocated_resource_data(struct pnp_dev
680                                                                 *dev,
681                                                              unsigned char *p,
682                                                              unsigned char *end)
683 {
684         unsigned int len, tag;
685         int port = 0, irq = 0, dma = 0, mem = 0;
686
687         if (!p)
688                 return NULL;
689
690         while ((char *)p < (char *)end) {
691
692                 /* determine the type of tag */
693                 if (p[0] & LARGE_TAG) { /* large tag */
694                         len = (p[2] << 8) | p[1];
695                         tag = p[0];
696                 } else {        /* small tag */
697                         len = p[0] & 0x07;
698                         tag = ((p[0] >> 3) & 0x0f);
699                 }
700
701                 switch (tag) {
702
703                 case LARGE_TAG_MEM:
704                         if (len != 9)
705                                 goto len_err;
706                         pnpbios_encode_mem(dev, p,
707                                 pnp_get_resource(dev, IORESOURCE_MEM, mem));
708                         mem++;
709                         break;
710
711                 case LARGE_TAG_MEM32:
712                         if (len != 17)
713                                 goto len_err;
714                         pnpbios_encode_mem32(dev, p,
715                                 pnp_get_resource(dev, IORESOURCE_MEM, mem));
716                         mem++;
717                         break;
718
719                 case LARGE_TAG_FIXEDMEM32:
720                         if (len != 9)
721                                 goto len_err;
722                         pnpbios_encode_fixed_mem32(dev, p,
723                                 pnp_get_resource(dev, IORESOURCE_MEM, mem));
724                         mem++;
725                         break;
726
727                 case SMALL_TAG_IRQ:
728                         if (len < 2 || len > 3)
729                                 goto len_err;
730                         pnpbios_encode_irq(dev, p,
731                                 pnp_get_resource(dev, IORESOURCE_IRQ, irq));
732                         irq++;
733                         break;
734
735                 case SMALL_TAG_DMA:
736                         if (len != 2)
737                                 goto len_err;
738                         pnpbios_encode_dma(dev, p,
739                                 pnp_get_resource(dev, IORESOURCE_DMA, dma));
740                         dma++;
741                         break;
742
743                 case SMALL_TAG_PORT:
744                         if (len != 7)
745                                 goto len_err;
746                         pnpbios_encode_port(dev, p,
747                                 pnp_get_resource(dev, IORESOURCE_IO, port));
748                         port++;
749                         break;
750
751                 case SMALL_TAG_VENDOR:
752                         /* do nothing */
753                         break;
754
755                 case SMALL_TAG_FIXEDPORT:
756                         if (len != 3)
757                                 goto len_err;
758                         pnpbios_encode_fixed_port(dev, p,
759                                 pnp_get_resource(dev, IORESOURCE_IO, port));
760                         port++;
761                         break;
762
763                 case SMALL_TAG_END:
764                         p = p + 2;
765                         return (unsigned char *)p;
766                         break;
767
768                 default:        /* an unkown tag */
769 len_err:
770                         dev_err(&dev->dev, "unknown tag %#x length %d\n",
771                                 tag, len);
772                         break;
773                 }
774
775                 /* continue to the next tag */
776                 if (p[0] & LARGE_TAG)
777                         p += len + 3;
778                 else
779                         p += len + 1;
780         }
781
782         dev_err(&dev->dev, "no end tag in resource structure\n");
783
784         return NULL;
785 }
786
787 /*
788  * Core Parsing Functions
789  */
790
791 int __init pnpbios_parse_data_stream(struct pnp_dev *dev,
792                                         struct pnp_bios_node *node)
793 {
794         unsigned char *p = (char *)node->data;
795         unsigned char *end = (char *)(node->data + node->size);
796
797         p = pnpbios_parse_allocated_resource_data(dev, p, end);
798         if (!p)
799                 return -EIO;
800         p = pnpbios_parse_resource_option_data(p, end, dev);
801         if (!p)
802                 return -EIO;
803         p = pnpbios_parse_compatible_ids(p, end, dev);
804         if (!p)
805                 return -EIO;
806         return 0;
807 }
808
809 int pnpbios_read_resources_from_node(struct pnp_dev *dev,
810                                      struct pnp_bios_node *node)
811 {
812         unsigned char *p = (char *)node->data;
813         unsigned char *end = (char *)(node->data + node->size);
814
815         p = pnpbios_parse_allocated_resource_data(dev, p, end);
816         if (!p)
817                 return -EIO;
818         return 0;
819 }
820
821 int pnpbios_write_resources_to_node(struct pnp_dev *dev,
822                                     struct pnp_bios_node *node)
823 {
824         unsigned char *p = (char *)node->data;
825         unsigned char *end = (char *)(node->data + node->size);
826
827         p = pnpbios_encode_allocated_resource_data(dev, p, end);
828         if (!p)
829                 return -EIO;
830         return 0;
831 }