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