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