rsparser.c 17 KB

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