resource.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. /*
  2. * resource.c - Contains functions for registering and analyzing resource information
  3. *
  4. * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
  5. * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
  6. * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
  7. * Bjorn Helgaas <bjorn.helgaas@hp.com>
  8. */
  9. #include <linux/module.h>
  10. #include <linux/errno.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/kernel.h>
  13. #include <asm/io.h>
  14. #include <asm/dma.h>
  15. #include <asm/irq.h>
  16. #include <linux/pci.h>
  17. #include <linux/ioport.h>
  18. #include <linux/init.h>
  19. #include <linux/pnp.h>
  20. #include "base.h"
  21. static int pnp_reserve_irq[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some IRQ */
  22. static int pnp_reserve_dma[8] = {[0 ... 7] = -1 }; /* reserve (don't use) some DMA */
  23. static int pnp_reserve_io[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some I/O region */
  24. static int pnp_reserve_mem[16] = {[0 ... 15] = -1 }; /* reserve (don't use) some memory region */
  25. /*
  26. * option registration
  27. */
  28. struct pnp_option *pnp_build_option(struct pnp_dev *dev, unsigned long type,
  29. unsigned int option_flags)
  30. {
  31. struct pnp_option *option;
  32. option = kzalloc(sizeof(struct pnp_option), GFP_KERNEL);
  33. if (!option)
  34. return NULL;
  35. option->flags = option_flags;
  36. option->type = type;
  37. list_add_tail(&option->list, &dev->options);
  38. return option;
  39. }
  40. int pnp_register_irq_resource(struct pnp_dev *dev, unsigned int option_flags,
  41. pnp_irq_mask_t *map, unsigned char flags)
  42. {
  43. struct pnp_option *option;
  44. struct pnp_irq *irq;
  45. option = pnp_build_option(dev, IORESOURCE_IRQ, option_flags);
  46. if (!option)
  47. return -ENOMEM;
  48. irq = &option->u.irq;
  49. irq->map = *map;
  50. irq->flags = flags;
  51. #ifdef CONFIG_PCI
  52. {
  53. int i;
  54. for (i = 0; i < 16; i++)
  55. if (test_bit(i, irq->map.bits))
  56. pcibios_penalize_isa_irq(i, 0);
  57. }
  58. #endif
  59. dbg_pnp_show_option(dev, option);
  60. return 0;
  61. }
  62. int pnp_register_dma_resource(struct pnp_dev *dev, unsigned int option_flags,
  63. unsigned char map, unsigned char flags)
  64. {
  65. struct pnp_option *option;
  66. struct pnp_dma *dma;
  67. option = pnp_build_option(dev, IORESOURCE_DMA, option_flags);
  68. if (!option)
  69. return -ENOMEM;
  70. dma = &option->u.dma;
  71. dma->map = map;
  72. dma->flags = flags;
  73. dbg_pnp_show_option(dev, option);
  74. return 0;
  75. }
  76. int pnp_register_port_resource(struct pnp_dev *dev, unsigned int option_flags,
  77. resource_size_t min, resource_size_t max,
  78. resource_size_t align, resource_size_t size,
  79. unsigned char flags)
  80. {
  81. struct pnp_option *option;
  82. struct pnp_port *port;
  83. option = pnp_build_option(dev, IORESOURCE_IO, option_flags);
  84. if (!option)
  85. return -ENOMEM;
  86. port = &option->u.port;
  87. port->min = min;
  88. port->max = max;
  89. port->align = align;
  90. port->size = size;
  91. port->flags = flags;
  92. dbg_pnp_show_option(dev, option);
  93. return 0;
  94. }
  95. int pnp_register_mem_resource(struct pnp_dev *dev, unsigned int option_flags,
  96. resource_size_t min, resource_size_t max,
  97. resource_size_t align, resource_size_t size,
  98. unsigned char flags)
  99. {
  100. struct pnp_option *option;
  101. struct pnp_mem *mem;
  102. option = pnp_build_option(dev, IORESOURCE_MEM, option_flags);
  103. if (!option)
  104. return -ENOMEM;
  105. mem = &option->u.mem;
  106. mem->min = min;
  107. mem->max = max;
  108. mem->align = align;
  109. mem->size = size;
  110. mem->flags = flags;
  111. dbg_pnp_show_option(dev, option);
  112. return 0;
  113. }
  114. void pnp_free_options(struct pnp_dev *dev)
  115. {
  116. struct pnp_option *option, *tmp;
  117. list_for_each_entry_safe(option, tmp, &dev->options, list) {
  118. list_del(&option->list);
  119. kfree(option);
  120. }
  121. }
  122. /*
  123. * resource validity checking
  124. */
  125. #define length(start, end) (*(end) - *(start) + 1)
  126. /* Two ranges conflict if one doesn't end before the other starts */
  127. #define ranged_conflict(starta, enda, startb, endb) \
  128. !((*(enda) < *(startb)) || (*(endb) < *(starta)))
  129. #define cannot_compare(flags) \
  130. ((flags) & IORESOURCE_DISABLED)
  131. int pnp_check_port(struct pnp_dev *dev, struct resource *res)
  132. {
  133. int i;
  134. struct pnp_dev *tdev;
  135. struct resource *tres;
  136. resource_size_t *port, *end, *tport, *tend;
  137. port = &res->start;
  138. end = &res->end;
  139. /* if the resource doesn't exist, don't complain about it */
  140. if (cannot_compare(res->flags))
  141. return 1;
  142. /* check if the resource is already in use, skip if the
  143. * device is active because it itself may be in use */
  144. if (!dev->active) {
  145. if (__check_region(&ioport_resource, *port, length(port, end)))
  146. return 0;
  147. }
  148. /* check if the resource is reserved */
  149. for (i = 0; i < 8; i++) {
  150. int rport = pnp_reserve_io[i << 1];
  151. int rend = pnp_reserve_io[(i << 1) + 1] + rport - 1;
  152. if (ranged_conflict(port, end, &rport, &rend))
  153. return 0;
  154. }
  155. /* check for internal conflicts */
  156. for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IO, i)); i++) {
  157. if (tres != res && tres->flags & IORESOURCE_IO) {
  158. tport = &tres->start;
  159. tend = &tres->end;
  160. if (ranged_conflict(port, end, tport, tend))
  161. return 0;
  162. }
  163. }
  164. /* check for conflicts with other pnp devices */
  165. pnp_for_each_dev(tdev) {
  166. if (tdev == dev)
  167. continue;
  168. for (i = 0;
  169. (tres = pnp_get_resource(tdev, IORESOURCE_IO, i));
  170. i++) {
  171. if (tres->flags & IORESOURCE_IO) {
  172. if (cannot_compare(tres->flags))
  173. continue;
  174. tport = &tres->start;
  175. tend = &tres->end;
  176. if (ranged_conflict(port, end, tport, tend))
  177. return 0;
  178. }
  179. }
  180. }
  181. return 1;
  182. }
  183. int pnp_check_mem(struct pnp_dev *dev, struct resource *res)
  184. {
  185. int i;
  186. struct pnp_dev *tdev;
  187. struct resource *tres;
  188. resource_size_t *addr, *end, *taddr, *tend;
  189. addr = &res->start;
  190. end = &res->end;
  191. /* if the resource doesn't exist, don't complain about it */
  192. if (cannot_compare(res->flags))
  193. return 1;
  194. /* check if the resource is already in use, skip if the
  195. * device is active because it itself may be in use */
  196. if (!dev->active) {
  197. if (check_mem_region(*addr, length(addr, end)))
  198. return 0;
  199. }
  200. /* check if the resource is reserved */
  201. for (i = 0; i < 8; i++) {
  202. int raddr = pnp_reserve_mem[i << 1];
  203. int rend = pnp_reserve_mem[(i << 1) + 1] + raddr - 1;
  204. if (ranged_conflict(addr, end, &raddr, &rend))
  205. return 0;
  206. }
  207. /* check for internal conflicts */
  208. for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) {
  209. if (tres != res && tres->flags & IORESOURCE_MEM) {
  210. taddr = &tres->start;
  211. tend = &tres->end;
  212. if (ranged_conflict(addr, end, taddr, tend))
  213. return 0;
  214. }
  215. }
  216. /* check for conflicts with other pnp devices */
  217. pnp_for_each_dev(tdev) {
  218. if (tdev == dev)
  219. continue;
  220. for (i = 0;
  221. (tres = pnp_get_resource(tdev, IORESOURCE_MEM, i));
  222. i++) {
  223. if (tres->flags & IORESOURCE_MEM) {
  224. if (cannot_compare(tres->flags))
  225. continue;
  226. taddr = &tres->start;
  227. tend = &tres->end;
  228. if (ranged_conflict(addr, end, taddr, tend))
  229. return 0;
  230. }
  231. }
  232. }
  233. return 1;
  234. }
  235. static irqreturn_t pnp_test_handler(int irq, void *dev_id)
  236. {
  237. return IRQ_HANDLED;
  238. }
  239. #ifdef CONFIG_PCI
  240. static int pci_dev_uses_irq(struct pnp_dev *pnp, struct pci_dev *pci,
  241. unsigned int irq)
  242. {
  243. u32 class;
  244. u8 progif;
  245. if (pci->irq == irq) {
  246. pnp_dbg(&pnp->dev, " device %s using irq %d\n",
  247. pci_name(pci), irq);
  248. return 1;
  249. }
  250. /*
  251. * See pci_setup_device() and ata_pci_sff_activate_host() for
  252. * similar IDE legacy detection.
  253. */
  254. pci_read_config_dword(pci, PCI_CLASS_REVISION, &class);
  255. class >>= 8; /* discard revision ID */
  256. progif = class & 0xff;
  257. class >>= 8;
  258. if (class == PCI_CLASS_STORAGE_IDE) {
  259. /*
  260. * Unless both channels are native-PCI mode only,
  261. * treat the compatibility IRQs as busy.
  262. */
  263. if ((progif & 0x5) != 0x5)
  264. if (pci_get_legacy_ide_irq(pci, 0) == irq ||
  265. pci_get_legacy_ide_irq(pci, 1) == irq) {
  266. pnp_dbg(&pnp->dev, " legacy IDE device %s "
  267. "using irq %d\n", pci_name(pci), irq);
  268. return 1;
  269. }
  270. }
  271. return 0;
  272. }
  273. #endif
  274. static int pci_uses_irq(struct pnp_dev *pnp, unsigned int irq)
  275. {
  276. #ifdef CONFIG_PCI
  277. struct pci_dev *pci = NULL;
  278. for_each_pci_dev(pci) {
  279. if (pci_dev_uses_irq(pnp, pci, irq)) {
  280. pci_dev_put(pci);
  281. return 1;
  282. }
  283. }
  284. #endif
  285. return 0;
  286. }
  287. int pnp_check_irq(struct pnp_dev *dev, struct resource *res)
  288. {
  289. int i;
  290. struct pnp_dev *tdev;
  291. struct resource *tres;
  292. resource_size_t *irq;
  293. irq = &res->start;
  294. /* if the resource doesn't exist, don't complain about it */
  295. if (cannot_compare(res->flags))
  296. return 1;
  297. /* check if the resource is valid */
  298. if (*irq < 0 || *irq > 15)
  299. return 0;
  300. /* check if the resource is reserved */
  301. for (i = 0; i < 16; i++) {
  302. if (pnp_reserve_irq[i] == *irq)
  303. return 0;
  304. }
  305. /* check for internal conflicts */
  306. for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_IRQ, i)); i++) {
  307. if (tres != res && tres->flags & IORESOURCE_IRQ) {
  308. if (tres->start == *irq)
  309. return 0;
  310. }
  311. }
  312. /* check if the resource is being used by a pci device */
  313. if (pci_uses_irq(dev, *irq))
  314. return 0;
  315. /* check if the resource is already in use, skip if the
  316. * device is active because it itself may be in use */
  317. if (!dev->active) {
  318. if (request_irq(*irq, pnp_test_handler,
  319. IRQF_DISABLED | IRQF_PROBE_SHARED, "pnp", NULL))
  320. return 0;
  321. free_irq(*irq, NULL);
  322. }
  323. /* check for conflicts with other pnp devices */
  324. pnp_for_each_dev(tdev) {
  325. if (tdev == dev)
  326. continue;
  327. for (i = 0;
  328. (tres = pnp_get_resource(tdev, IORESOURCE_IRQ, i));
  329. i++) {
  330. if (tres->flags & IORESOURCE_IRQ) {
  331. if (cannot_compare(tres->flags))
  332. continue;
  333. if (tres->start == *irq)
  334. return 0;
  335. }
  336. }
  337. }
  338. return 1;
  339. }
  340. int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
  341. {
  342. #ifndef CONFIG_IA64
  343. int i;
  344. struct pnp_dev *tdev;
  345. struct resource *tres;
  346. resource_size_t *dma;
  347. dma = &res->start;
  348. /* if the resource doesn't exist, don't complain about it */
  349. if (cannot_compare(res->flags))
  350. return 1;
  351. /* check if the resource is valid */
  352. if (*dma < 0 || *dma == 4 || *dma > 7)
  353. return 0;
  354. /* check if the resource is reserved */
  355. for (i = 0; i < 8; i++) {
  356. if (pnp_reserve_dma[i] == *dma)
  357. return 0;
  358. }
  359. /* check for internal conflicts */
  360. for (i = 0; (tres = pnp_get_resource(dev, IORESOURCE_DMA, i)); i++) {
  361. if (tres != res && tres->flags & IORESOURCE_DMA) {
  362. if (tres->start == *dma)
  363. return 0;
  364. }
  365. }
  366. /* check if the resource is already in use, skip if the
  367. * device is active because it itself may be in use */
  368. if (!dev->active) {
  369. if (request_dma(*dma, "pnp"))
  370. return 0;
  371. free_dma(*dma);
  372. }
  373. /* check for conflicts with other pnp devices */
  374. pnp_for_each_dev(tdev) {
  375. if (tdev == dev)
  376. continue;
  377. for (i = 0;
  378. (tres = pnp_get_resource(tdev, IORESOURCE_DMA, i));
  379. i++) {
  380. if (tres->flags & IORESOURCE_DMA) {
  381. if (cannot_compare(tres->flags))
  382. continue;
  383. if (tres->start == *dma)
  384. return 0;
  385. }
  386. }
  387. }
  388. return 1;
  389. #else
  390. /* IA64 does not have legacy DMA */
  391. return 0;
  392. #endif
  393. }
  394. unsigned long pnp_resource_type(struct resource *res)
  395. {
  396. return res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
  397. IORESOURCE_IRQ | IORESOURCE_DMA);
  398. }
  399. struct resource *pnp_get_resource(struct pnp_dev *dev,
  400. unsigned long type, unsigned int num)
  401. {
  402. struct pnp_resource *pnp_res;
  403. struct resource *res;
  404. list_for_each_entry(pnp_res, &dev->resources, list) {
  405. res = &pnp_res->res;
  406. if (pnp_resource_type(res) == type && num-- == 0)
  407. return res;
  408. }
  409. return NULL;
  410. }
  411. EXPORT_SYMBOL(pnp_get_resource);
  412. static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev)
  413. {
  414. struct pnp_resource *pnp_res;
  415. pnp_res = kzalloc(sizeof(struct pnp_resource), GFP_KERNEL);
  416. if (!pnp_res)
  417. return NULL;
  418. list_add_tail(&pnp_res->list, &dev->resources);
  419. return pnp_res;
  420. }
  421. struct pnp_resource *pnp_add_irq_resource(struct pnp_dev *dev, int irq,
  422. int flags)
  423. {
  424. struct pnp_resource *pnp_res;
  425. struct resource *res;
  426. pnp_res = pnp_new_resource(dev);
  427. if (!pnp_res) {
  428. dev_err(&dev->dev, "can't add resource for IRQ %d\n", irq);
  429. return NULL;
  430. }
  431. res = &pnp_res->res;
  432. res->flags = IORESOURCE_IRQ | flags;
  433. res->start = irq;
  434. res->end = irq;
  435. pnp_dbg(&dev->dev, " add irq %d flags %#x\n", irq, flags);
  436. return pnp_res;
  437. }
  438. struct pnp_resource *pnp_add_dma_resource(struct pnp_dev *dev, int dma,
  439. int flags)
  440. {
  441. struct pnp_resource *pnp_res;
  442. struct resource *res;
  443. pnp_res = pnp_new_resource(dev);
  444. if (!pnp_res) {
  445. dev_err(&dev->dev, "can't add resource for DMA %d\n", dma);
  446. return NULL;
  447. }
  448. res = &pnp_res->res;
  449. res->flags = IORESOURCE_DMA | flags;
  450. res->start = dma;
  451. res->end = dma;
  452. pnp_dbg(&dev->dev, " add dma %d flags %#x\n", dma, flags);
  453. return pnp_res;
  454. }
  455. struct pnp_resource *pnp_add_io_resource(struct pnp_dev *dev,
  456. resource_size_t start,
  457. resource_size_t end, int flags)
  458. {
  459. struct pnp_resource *pnp_res;
  460. struct resource *res;
  461. pnp_res = pnp_new_resource(dev);
  462. if (!pnp_res) {
  463. dev_err(&dev->dev, "can't add resource for IO %#llx-%#llx\n",
  464. (unsigned long long) start,
  465. (unsigned long long) end);
  466. return NULL;
  467. }
  468. res = &pnp_res->res;
  469. res->flags = IORESOURCE_IO | flags;
  470. res->start = start;
  471. res->end = end;
  472. pnp_dbg(&dev->dev, " add io %#llx-%#llx flags %#x\n",
  473. (unsigned long long) start, (unsigned long long) end, flags);
  474. return pnp_res;
  475. }
  476. struct pnp_resource *pnp_add_mem_resource(struct pnp_dev *dev,
  477. resource_size_t start,
  478. resource_size_t end, int flags)
  479. {
  480. struct pnp_resource *pnp_res;
  481. struct resource *res;
  482. pnp_res = pnp_new_resource(dev);
  483. if (!pnp_res) {
  484. dev_err(&dev->dev, "can't add resource for MEM %#llx-%#llx\n",
  485. (unsigned long long) start,
  486. (unsigned long long) end);
  487. return NULL;
  488. }
  489. res = &pnp_res->res;
  490. res->flags = IORESOURCE_MEM | flags;
  491. res->start = start;
  492. res->end = end;
  493. pnp_dbg(&dev->dev, " add mem %#llx-%#llx flags %#x\n",
  494. (unsigned long long) start, (unsigned long long) end, flags);
  495. return pnp_res;
  496. }
  497. /*
  498. * Determine whether the specified resource is a possible configuration
  499. * for this device.
  500. */
  501. int pnp_possible_config(struct pnp_dev *dev, int type, resource_size_t start,
  502. resource_size_t size)
  503. {
  504. struct pnp_option *option;
  505. struct pnp_port *port;
  506. struct pnp_mem *mem;
  507. struct pnp_irq *irq;
  508. struct pnp_dma *dma;
  509. list_for_each_entry(option, &dev->options, list) {
  510. if (option->type != type)
  511. continue;
  512. switch (option->type) {
  513. case IORESOURCE_IO:
  514. port = &option->u.port;
  515. if (port->min == start && port->size == size)
  516. return 1;
  517. break;
  518. case IORESOURCE_MEM:
  519. mem = &option->u.mem;
  520. if (mem->min == start && mem->size == size)
  521. return 1;
  522. break;
  523. case IORESOURCE_IRQ:
  524. irq = &option->u.irq;
  525. if (start < PNP_IRQ_NR &&
  526. test_bit(start, irq->map.bits))
  527. return 1;
  528. break;
  529. case IORESOURCE_DMA:
  530. dma = &option->u.dma;
  531. if (dma->map & (1 << start))
  532. return 1;
  533. break;
  534. }
  535. }
  536. return 0;
  537. }
  538. EXPORT_SYMBOL(pnp_possible_config);
  539. int pnp_range_reserved(resource_size_t start, resource_size_t end)
  540. {
  541. struct pnp_dev *dev;
  542. struct pnp_resource *pnp_res;
  543. resource_size_t *dev_start, *dev_end;
  544. pnp_for_each_dev(dev) {
  545. list_for_each_entry(pnp_res, &dev->resources, list) {
  546. dev_start = &pnp_res->res.start;
  547. dev_end = &pnp_res->res.end;
  548. if (ranged_conflict(&start, &end, dev_start, dev_end))
  549. return 1;
  550. }
  551. }
  552. return 0;
  553. }
  554. EXPORT_SYMBOL(pnp_range_reserved);
  555. /* format is: pnp_reserve_irq=irq1[,irq2] .... */
  556. static int __init pnp_setup_reserve_irq(char *str)
  557. {
  558. int i;
  559. for (i = 0; i < 16; i++)
  560. if (get_option(&str, &pnp_reserve_irq[i]) != 2)
  561. break;
  562. return 1;
  563. }
  564. __setup("pnp_reserve_irq=", pnp_setup_reserve_irq);
  565. /* format is: pnp_reserve_dma=dma1[,dma2] .... */
  566. static int __init pnp_setup_reserve_dma(char *str)
  567. {
  568. int i;
  569. for (i = 0; i < 8; i++)
  570. if (get_option(&str, &pnp_reserve_dma[i]) != 2)
  571. break;
  572. return 1;
  573. }
  574. __setup("pnp_reserve_dma=", pnp_setup_reserve_dma);
  575. /* format is: pnp_reserve_io=io1,size1[,io2,size2] .... */
  576. static int __init pnp_setup_reserve_io(char *str)
  577. {
  578. int i;
  579. for (i = 0; i < 16; i++)
  580. if (get_option(&str, &pnp_reserve_io[i]) != 2)
  581. break;
  582. return 1;
  583. }
  584. __setup("pnp_reserve_io=", pnp_setup_reserve_io);
  585. /* format is: pnp_reserve_mem=mem1,size1[,mem2,size2] .... */
  586. static int __init pnp_setup_reserve_mem(char *str)
  587. {
  588. int i;
  589. for (i = 0; i < 16; i++)
  590. if (get_option(&str, &pnp_reserve_mem[i]) != 2)
  591. break;
  592. return 1;
  593. }
  594. __setup("pnp_reserve_mem=", pnp_setup_reserve_mem);