cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rsparser.c (17089B)


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