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