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