rsparser.c 17 KB

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