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 return p + 2; 452 453 default: /* an unkown tag */ 454 len_err: 455 printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len); 456 break; 457 } 458 459 /* continue to the next tag */ 460 if (p[0] & LARGE_TAG) 461 p += len + 3; 462 else 463 p += len + 1; 464 } 465 466 printk(KERN_ERR "PnPBIOS: Resource structure does not contain an end tag.\n"); 467 468 return NULL; 469 } 470 471 472 /* 473 * Compatible Device IDs 474 */ 475 476 #define HEX(id,a) hex[((id)>>a) & 15] 477 #define CHAR(id,a) (0x40 + (((id)>>a) & 31)) 478 // 479 480 void pnpid32_to_pnpid(u32 id, char *str) 481 { 482 const char *hex = "0123456789abcdef"; 483 484 id = be32_to_cpu(id); 485 str[0] = CHAR(id, 26); 486 str[1] = CHAR(id, 21); 487 str[2] = CHAR(id,16); 488 str[3] = HEX(id, 12); 489 str[4] = HEX(id, 8); 490 str[5] = HEX(id, 4); 491 str[6] = HEX(id, 0); 492 str[7] = '\0'; 493 494 return; 495 } 496 // 497 #undef CHAR 498 #undef HEX 499 500 static unsigned char * 501 pnpbios_parse_compatible_ids(unsigned char *p, unsigned char *end, struct pnp_dev *dev) 502 { 503 int len, tag; 504 char id[8]; 505 struct pnp_id *dev_id; 506 507 if (!p) 508 return NULL; 509 510 while ((char *)p < (char *)end) { 511 512 /* determine the type of tag */ 513 if (p[0] & LARGE_TAG) { /* large tag */ 514 len = (p[2] << 8) | p[1]; 515 tag = p[0]; 516 } else { /* small tag */ 517 len = p[0] & 0x07; 518 tag = ((p[0]>>3) & 0x0f); 519 } 520 521 switch (tag) { 522 523 case LARGE_TAG_ANSISTR: 524 strncpy(dev->name, p + 3, len >= PNP_NAME_LEN ? PNP_NAME_LEN - 2 : len); 525 dev->name[len >= PNP_NAME_LEN ? PNP_NAME_LEN - 1 : len] = '\0'; 526 break; 527 528 case SMALL_TAG_COMPATDEVID: /* compatible ID */ 529 if (len != 4) 530 goto len_err; 531 dev_id = kcalloc(1, sizeof (struct pnp_id), GFP_KERNEL); 532 if (!dev_id) 533 return NULL; 534 memset(dev_id, 0, sizeof(struct pnp_id)); 535 pnpid32_to_pnpid(p[1] | p[2] << 8 | p[3] << 16 | p[4] << 24,id); 536 memcpy(&dev_id->id, id, 7); 537 pnp_add_id(dev_id, dev); 538 break; 539 540 case SMALL_TAG_END: 541 p = p + 2; 542 return (unsigned char *)p; 543 break; 544 545 default: /* an unkown tag */ 546 len_err: 547 printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len); 548 break; 549 } 550 551 /* continue to the next tag */ 552 if (p[0] & LARGE_TAG) 553 p += len + 3; 554 else 555 p += len + 1; 556 } 557 558 printk(KERN_ERR "PnPBIOS: Resource structure does not contain an end tag.\n"); 559 560 return NULL; 561 } 562 563 564 /* 565 * Allocated Resource Encoding 566 */ 567 568 static void pnpbios_encode_mem(unsigned char *p, struct resource * res) 569 { 570 unsigned long base = res->start; 571 unsigned long len = res->end - res->start + 1; 572 p[4] = (base >> 8) & 0xff; 573 p[5] = ((base >> 8) >> 8) & 0xff; 574 p[6] = (base >> 8) & 0xff; 575 p[7] = ((base >> 8) >> 8) & 0xff; 576 p[10] = (len >> 8) & 0xff; 577 p[11] = ((len >> 8) >> 8) & 0xff; 578 return; 579 } 580 581 static void pnpbios_encode_mem32(unsigned char *p, struct resource * res) 582 { 583 unsigned long base = res->start; 584 unsigned long len = res->end - res->start + 1; 585 p[4] = base & 0xff; 586 p[5] = (base >> 8) & 0xff; 587 p[6] = (base >> 16) & 0xff; 588 p[7] = (base >> 24) & 0xff; 589 p[8] = base & 0xff; 590 p[9] = (base >> 8) & 0xff; 591 p[10] = (base >> 16) & 0xff; 592 p[11] = (base >> 24) & 0xff; 593 p[16] = len & 0xff; 594 p[17] = (len >> 8) & 0xff; 595 p[18] = (len >> 16) & 0xff; 596 p[19] = (len >> 24) & 0xff; 597 return; 598 } 599 600 static void pnpbios_encode_fixed_mem32(unsigned char *p, struct resource * res) 601 { unsigned long base = res->start; 602 unsigned long len = res->end - res->start + 1; 603 p[4] = base & 0xff; 604 p[5] = (base >> 8) & 0xff; 605 p[6] = (base >> 16) & 0xff; 606 p[7] = (base >> 24) & 0xff; 607 p[8] = len & 0xff; 608 p[9] = (len >> 8) & 0xff; 609 p[10] = (len >> 16) & 0xff; 610 p[11] = (len >> 24) & 0xff; 611 return; 612 } 613 614 static void pnpbios_encode_irq(unsigned char *p, struct resource * res) 615 { 616 unsigned long map = 0; 617 map = 1 << res->start; 618 p[1] = map & 0xff; 619 p[2] = (map >> 8) & 0xff; 620 return; 621 } 622 623 static void pnpbios_encode_dma(unsigned char *p, struct resource * res) 624 { 625 unsigned long map = 0; 626 map = 1 << res->start; 627 p[1] = map & 0xff; 628 return; 629 } 630 631 static void pnpbios_encode_port(unsigned char *p, struct resource * res) 632 { 633 unsigned long base = res->start; 634 unsigned long len = res->end - res->start + 1; 635 p[2] = base & 0xff; 636 p[3] = (base >> 8) & 0xff; 637 p[4] = base & 0xff; 638 p[5] = (base >> 8) & 0xff; 639 p[7] = len & 0xff; 640 return; 641 } 642 643 static void pnpbios_encode_fixed_port(unsigned char *p, struct resource * res) 644 { 645 unsigned long base = res->start; 646 unsigned long len = res->end - res->start + 1; 647 p[1] = base & 0xff; 648 p[2] = (base >> 8) & 0xff; 649 p[3] = len & 0xff; 650 return; 651 } 652 653 static unsigned char * 654 pnpbios_encode_allocated_resource_data(unsigned char * p, unsigned char * end, struct pnp_resource_table * res) 655 { 656 unsigned int len, tag; 657 int port = 0, irq = 0, dma = 0, mem = 0; 658 659 if (!p) 660 return NULL; 661 662 while ((char *)p < (char *)end) { 663 664 /* determine the type of tag */ 665 if (p[0] & LARGE_TAG) { /* large tag */ 666 len = (p[2] << 8) | p[1]; 667 tag = p[0]; 668 } else { /* small tag */ 669 len = p[0] & 0x07; 670 tag = ((p[0]>>3) & 0x0f); 671 } 672 673 switch (tag) { 674 675 case LARGE_TAG_MEM: 676 if (len != 9) 677 goto len_err; 678 pnpbios_encode_mem(p, &res->mem_resource[mem]); 679 mem++; 680 break; 681 682 case LARGE_TAG_MEM32: 683 if (len != 17) 684 goto len_err; 685 pnpbios_encode_mem32(p, &res->mem_resource[mem]); 686 mem++; 687 break; 688 689 case LARGE_TAG_FIXEDMEM32: 690 if (len != 9) 691 goto len_err; 692 pnpbios_encode_fixed_mem32(p, &res->mem_resource[mem]); 693 mem++; 694 break; 695 696 case SMALL_TAG_IRQ: 697 if (len < 2 || len > 3) 698 goto len_err; 699 pnpbios_encode_irq(p, &res->irq_resource[irq]); 700 irq++; 701 break; 702 703 case SMALL_TAG_DMA: 704 if (len != 2) 705 goto len_err; 706 pnpbios_encode_dma(p, &res->dma_resource[dma]); 707 dma++; 708 break; 709 710 case SMALL_TAG_PORT: 711 if (len != 7) 712 goto len_err; 713 pnpbios_encode_port(p, &res->port_resource[port]); 714 port++; 715 break; 716 717 case SMALL_TAG_VENDOR: 718 /* do nothing */ 719 break; 720 721 case SMALL_TAG_FIXEDPORT: 722 if (len != 3) 723 goto len_err; 724 pnpbios_encode_fixed_port(p, &res->port_resource[port]); 725 port++; 726 break; 727 728 case SMALL_TAG_END: 729 p = p + 2; 730 return (unsigned char *)p; 731 break; 732 733 default: /* an unkown tag */ 734 len_err: 735 printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len); 736 break; 737 } 738 739 /* continue to the next tag */ 740 if (p[0] & LARGE_TAG) 741 p += len + 3; 742 else 743 p += len + 1; 744 } 745 746 printk(KERN_ERR "PnPBIOS: Resource structure does not contain an end tag.\n"); 747 748 return NULL; 749 } 750 751 752 /* 753 * Core Parsing Functions 754 */ 755 756 int 757 pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node * node) 758 { 759 unsigned char * p = (char *)node->data; 760 unsigned char * end = (char *)(node->data + node->size); 761 p = pnpbios_parse_allocated_resource_data(p,end,&dev->res); 762 if (!p) 763 return -EIO; 764 p = pnpbios_parse_resource_option_data(p,end,dev); 765 if (!p) 766 return -EIO; 767 p = pnpbios_parse_compatible_ids(p,end,dev); 768 if (!p) 769 return -EIO; 770 return 0; 771 } 772 773 int 774 pnpbios_read_resources_from_node(struct pnp_resource_table *res, 775 struct pnp_bios_node * node) 776 { 777 unsigned char * p = (char *)node->data; 778 unsigned char * end = (char *)(node->data + node->size); 779 p = pnpbios_parse_allocated_resource_data(p,end,res); 780 if (!p) 781 return -EIO; 782 return 0; 783 } 784 785 int 786 pnpbios_write_resources_to_node(struct pnp_resource_table *res, 787 struct pnp_bios_node * node) 788 { 789 unsigned char * p = (char *)node->data; 790 unsigned char * end = (char *)(node->data + node->size); 791 p = pnpbios_encode_allocated_resource_data(p,end,res); 792 if (!p) 793 return -EIO; 794 return 0; 795 } 796