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