root/drivers/pnp/pnpbios/rsparser.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pcibios_penalize_isa_irq
  2. pnpbios_parse_allocated_ioresource
  3. pnpbios_parse_allocated_memresource
  4. pnpbios_parse_allocated_resource_data
  5. pnpbios_parse_mem_option
  6. pnpbios_parse_mem32_option
  7. pnpbios_parse_fixed_mem32_option
  8. pnpbios_parse_irq_option
  9. pnpbios_parse_dma_option
  10. pnpbios_parse_port_option
  11. pnpbios_parse_fixed_port_option
  12. pnpbios_parse_resource_option_data
  13. pnpbios_parse_compatible_ids
  14. pnpbios_encode_mem
  15. pnpbios_encode_mem32
  16. pnpbios_encode_fixed_mem32
  17. pnpbios_encode_irq
  18. pnpbios_encode_dma
  19. pnpbios_encode_port
  20. pnpbios_encode_fixed_port
  21. pnpbios_encode_allocated_resource_data
  22. pnpbios_parse_data_stream
  23. pnpbios_read_resources_from_node
  24. pnpbios_write_resources_to_node

   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
  13 inline 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 
  56 static 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 
  68 static 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 
  80 static 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 */
 195 len_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 
 217 static __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 
 233 static __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 
 249 static __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 
 262 static __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 
 281 static __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 
 288 static __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 
 304 static __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 
 316 static __init unsigned char *
 317 pnpbios_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 */
 409 len_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 
 431 static 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 */
 479 len_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 
 501 static 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 
 525 static 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 
 555 static 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 
 582 static 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 
 598 static 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 
 613 static 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 
 636 static 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 
 658 static 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 */
 748 len_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 
 770 int __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 
 788 int 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 
 800 int 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 }

/* [<][>][^][v][top][bottom][index][help] */