manager.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. /*
  2. * manager.c - Resource Management, Conflict Resolution, Activation and Disabling of Devices
  3. *
  4. * based on isapnp.c resource management (c) Jaroslav Kysela <perex@perex.cz>
  5. * Copyright 2003 Adam Belay <ambx1@neo.rr.com>
  6. */
  7. #include <linux/errno.h>
  8. #include <linux/module.h>
  9. #include <linux/init.h>
  10. #include <linux/kernel.h>
  11. #include <linux/pnp.h>
  12. #include <linux/slab.h>
  13. #include <linux/bitmap.h>
  14. #include <linux/mutex.h>
  15. #include "base.h"
  16. DEFINE_MUTEX(pnp_res_mutex);
  17. static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx)
  18. {
  19. resource_size_t *start, *end;
  20. unsigned long *flags;
  21. if (idx >= PNP_MAX_PORT) {
  22. dev_err(&dev->dev, "too many I/O port resources\n");
  23. /* pretend we were successful so at least the manager won't try again */
  24. return 1;
  25. }
  26. start = &dev->res.port_resource[idx].start;
  27. end = &dev->res.port_resource[idx].end;
  28. flags = &dev->res.port_resource[idx].flags;
  29. /* check if this resource has been manually set, if so skip */
  30. if (!(dev->res.port_resource[idx].flags & IORESOURCE_AUTO)) {
  31. dev_dbg(&dev->dev, " io %d already set to %#llx-%#llx "
  32. "flags %#lx\n", idx, (unsigned long long) *start,
  33. (unsigned long long) *end, *flags);
  34. return 1;
  35. }
  36. /* set the initial values */
  37. *flags |= rule->flags | IORESOURCE_IO;
  38. *flags &= ~IORESOURCE_UNSET;
  39. if (!rule->size) {
  40. *flags |= IORESOURCE_DISABLED;
  41. dev_dbg(&dev->dev, " io %d disabled\n", idx);
  42. return 1; /* skip disabled resource requests */
  43. }
  44. *start = rule->min;
  45. *end = *start + rule->size - 1;
  46. /* run through until pnp_check_port is happy */
  47. while (!pnp_check_port(dev, idx)) {
  48. *start += rule->align;
  49. *end = *start + rule->size - 1;
  50. if (*start > rule->max || !rule->align) {
  51. dev_dbg(&dev->dev, " couldn't assign io %d\n", idx);
  52. return 0;
  53. }
  54. }
  55. dev_dbg(&dev->dev, " assign io %d %#llx-%#llx\n", idx,
  56. (unsigned long long) *start, (unsigned long long) *end);
  57. return 1;
  58. }
  59. static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
  60. {
  61. resource_size_t *start, *end;
  62. unsigned long *flags;
  63. if (idx >= PNP_MAX_MEM) {
  64. dev_err(&dev->dev, "too many memory resources\n");
  65. /* pretend we were successful so at least the manager won't try again */
  66. return 1;
  67. }
  68. start = &dev->res.mem_resource[idx].start;
  69. end = &dev->res.mem_resource[idx].end;
  70. flags = &dev->res.mem_resource[idx].flags;
  71. /* check if this resource has been manually set, if so skip */
  72. if (!(dev->res.mem_resource[idx].flags & IORESOURCE_AUTO)) {
  73. dev_dbg(&dev->dev, " mem %d already set to %#llx-%#llx "
  74. "flags %#lx\n", idx, (unsigned long long) *start,
  75. (unsigned long long) *end, *flags);
  76. return 1;
  77. }
  78. /* set the initial values */
  79. *flags |= rule->flags | IORESOURCE_MEM;
  80. *flags &= ~IORESOURCE_UNSET;
  81. /* convert pnp flags to standard Linux flags */
  82. if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
  83. *flags |= IORESOURCE_READONLY;
  84. if (rule->flags & IORESOURCE_MEM_CACHEABLE)
  85. *flags |= IORESOURCE_CACHEABLE;
  86. if (rule->flags & IORESOURCE_MEM_RANGELENGTH)
  87. *flags |= IORESOURCE_RANGELENGTH;
  88. if (rule->flags & IORESOURCE_MEM_SHADOWABLE)
  89. *flags |= IORESOURCE_SHADOWABLE;
  90. if (!rule->size) {
  91. *flags |= IORESOURCE_DISABLED;
  92. dev_dbg(&dev->dev, " mem %d disabled\n", idx);
  93. return 1; /* skip disabled resource requests */
  94. }
  95. *start = rule->min;
  96. *end = *start + rule->size - 1;
  97. /* run through until pnp_check_mem is happy */
  98. while (!pnp_check_mem(dev, idx)) {
  99. *start += rule->align;
  100. *end = *start + rule->size - 1;
  101. if (*start > rule->max || !rule->align) {
  102. dev_dbg(&dev->dev, " couldn't assign mem %d\n", idx);
  103. return 0;
  104. }
  105. }
  106. dev_dbg(&dev->dev, " assign mem %d %#llx-%#llx\n", idx,
  107. (unsigned long long) *start, (unsigned long long) *end);
  108. return 1;
  109. }
  110. static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx)
  111. {
  112. resource_size_t *start, *end;
  113. unsigned long *flags;
  114. int i;
  115. /* IRQ priority: this table is good for i386 */
  116. static unsigned short xtab[16] = {
  117. 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
  118. };
  119. if (idx >= PNP_MAX_IRQ) {
  120. dev_err(&dev->dev, "too many IRQ resources\n");
  121. /* pretend we were successful so at least the manager won't try again */
  122. return 1;
  123. }
  124. start = &dev->res.irq_resource[idx].start;
  125. end = &dev->res.irq_resource[idx].end;
  126. flags = &dev->res.irq_resource[idx].flags;
  127. /* check if this resource has been manually set, if so skip */
  128. if (!(dev->res.irq_resource[idx].flags & IORESOURCE_AUTO)) {
  129. dev_dbg(&dev->dev, " irq %d already set to %d flags %#lx\n",
  130. idx, (int) *start, *flags);
  131. return 1;
  132. }
  133. /* set the initial values */
  134. *flags |= rule->flags | IORESOURCE_IRQ;
  135. *flags &= ~IORESOURCE_UNSET;
  136. if (bitmap_empty(rule->map, PNP_IRQ_NR)) {
  137. *flags |= IORESOURCE_DISABLED;
  138. dev_dbg(&dev->dev, " irq %d disabled\n", idx);
  139. return 1; /* skip disabled resource requests */
  140. }
  141. /* TBD: need check for >16 IRQ */
  142. *start = find_next_bit(rule->map, PNP_IRQ_NR, 16);
  143. if (*start < PNP_IRQ_NR) {
  144. *end = *start;
  145. dev_dbg(&dev->dev, " assign irq %d %d\n", idx, (int) *start);
  146. return 1;
  147. }
  148. for (i = 0; i < 16; i++) {
  149. if (test_bit(xtab[i], rule->map)) {
  150. *start = *end = xtab[i];
  151. if (pnp_check_irq(dev, idx)) {
  152. dev_dbg(&dev->dev, " assign irq %d %d\n", idx,
  153. (int) *start);
  154. return 1;
  155. }
  156. }
  157. }
  158. dev_dbg(&dev->dev, " couldn't assign irq %d\n", idx);
  159. return 0;
  160. }
  161. static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
  162. {
  163. resource_size_t *start, *end;
  164. unsigned long *flags;
  165. int i;
  166. /* DMA priority: this table is good for i386 */
  167. static unsigned short xtab[8] = {
  168. 1, 3, 5, 6, 7, 0, 2, 4
  169. };
  170. if (idx >= PNP_MAX_DMA) {
  171. dev_err(&dev->dev, "too many DMA resources\n");
  172. return;
  173. }
  174. start = &dev->res.dma_resource[idx].start;
  175. end = &dev->res.dma_resource[idx].end;
  176. flags = &dev->res.dma_resource[idx].flags;
  177. /* check if this resource has been manually set, if so skip */
  178. if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO)) {
  179. dev_dbg(&dev->dev, " dma %d already set to %d flags %#lx\n",
  180. idx, (int) *start, *flags);
  181. return;
  182. }
  183. /* set the initial values */
  184. *flags |= rule->flags | IORESOURCE_DMA;
  185. *flags &= ~IORESOURCE_UNSET;
  186. for (i = 0; i < 8; i++) {
  187. if (rule->map & (1 << xtab[i])) {
  188. *start = *end = xtab[i];
  189. if (pnp_check_dma(dev, idx)) {
  190. dev_dbg(&dev->dev, " assign dma %d %d\n", idx,
  191. (int) *start);
  192. return;
  193. }
  194. }
  195. }
  196. #ifdef MAX_DMA_CHANNELS
  197. *start = *end = MAX_DMA_CHANNELS;
  198. #endif
  199. *flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
  200. dev_dbg(&dev->dev, " disable dma %d\n", idx);
  201. }
  202. /**
  203. * pnp_init_resources - Resets a resource table to default values.
  204. * @table: pointer to the desired resource table
  205. */
  206. void pnp_init_resource_table(struct pnp_resource_table *table)
  207. {
  208. int idx;
  209. for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
  210. table->irq_resource[idx].name = NULL;
  211. table->irq_resource[idx].start = -1;
  212. table->irq_resource[idx].end = -1;
  213. table->irq_resource[idx].flags =
  214. IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
  215. }
  216. for (idx = 0; idx < PNP_MAX_DMA; idx++) {
  217. table->dma_resource[idx].name = NULL;
  218. table->dma_resource[idx].start = -1;
  219. table->dma_resource[idx].end = -1;
  220. table->dma_resource[idx].flags =
  221. IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
  222. }
  223. for (idx = 0; idx < PNP_MAX_PORT; idx++) {
  224. table->port_resource[idx].name = NULL;
  225. table->port_resource[idx].start = 0;
  226. table->port_resource[idx].end = 0;
  227. table->port_resource[idx].flags =
  228. IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
  229. }
  230. for (idx = 0; idx < PNP_MAX_MEM; idx++) {
  231. table->mem_resource[idx].name = NULL;
  232. table->mem_resource[idx].start = 0;
  233. table->mem_resource[idx].end = 0;
  234. table->mem_resource[idx].flags =
  235. IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
  236. }
  237. }
  238. /**
  239. * pnp_clean_resources - clears resources that were not manually set
  240. * @res: the resources to clean
  241. */
  242. static void pnp_clean_resource_table(struct pnp_resource_table *res)
  243. {
  244. int idx;
  245. for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
  246. if (!(res->irq_resource[idx].flags & IORESOURCE_AUTO))
  247. continue;
  248. res->irq_resource[idx].start = -1;
  249. res->irq_resource[idx].end = -1;
  250. res->irq_resource[idx].flags =
  251. IORESOURCE_IRQ | IORESOURCE_AUTO | IORESOURCE_UNSET;
  252. }
  253. for (idx = 0; idx < PNP_MAX_DMA; idx++) {
  254. if (!(res->dma_resource[idx].flags & IORESOURCE_AUTO))
  255. continue;
  256. res->dma_resource[idx].start = -1;
  257. res->dma_resource[idx].end = -1;
  258. res->dma_resource[idx].flags =
  259. IORESOURCE_DMA | IORESOURCE_AUTO | IORESOURCE_UNSET;
  260. }
  261. for (idx = 0; idx < PNP_MAX_PORT; idx++) {
  262. if (!(res->port_resource[idx].flags & IORESOURCE_AUTO))
  263. continue;
  264. res->port_resource[idx].start = 0;
  265. res->port_resource[idx].end = 0;
  266. res->port_resource[idx].flags =
  267. IORESOURCE_IO | IORESOURCE_AUTO | IORESOURCE_UNSET;
  268. }
  269. for (idx = 0; idx < PNP_MAX_MEM; idx++) {
  270. if (!(res->mem_resource[idx].flags & IORESOURCE_AUTO))
  271. continue;
  272. res->mem_resource[idx].start = 0;
  273. res->mem_resource[idx].end = 0;
  274. res->mem_resource[idx].flags =
  275. IORESOURCE_MEM | IORESOURCE_AUTO | IORESOURCE_UNSET;
  276. }
  277. }
  278. /**
  279. * pnp_assign_resources - assigns resources to the device based on the specified dependent number
  280. * @dev: pointer to the desired device
  281. * @depnum: the dependent function number
  282. *
  283. * Only set depnum to 0 if the device does not have dependent options.
  284. */
  285. static int pnp_assign_resources(struct pnp_dev *dev, int depnum)
  286. {
  287. struct pnp_port *port;
  288. struct pnp_mem *mem;
  289. struct pnp_irq *irq;
  290. struct pnp_dma *dma;
  291. int nport = 0, nmem = 0, nirq = 0, ndma = 0;
  292. if (!pnp_can_configure(dev))
  293. return -ENODEV;
  294. dbg_pnp_show_resources(dev, "before pnp_assign_resources");
  295. mutex_lock(&pnp_res_mutex);
  296. pnp_clean_resource_table(&dev->res); /* start with a fresh slate */
  297. if (dev->independent) {
  298. dev_dbg(&dev->dev, "assigning independent options\n");
  299. port = dev->independent->port;
  300. mem = dev->independent->mem;
  301. irq = dev->independent->irq;
  302. dma = dev->independent->dma;
  303. while (port) {
  304. if (!pnp_assign_port(dev, port, nport))
  305. goto fail;
  306. nport++;
  307. port = port->next;
  308. }
  309. while (mem) {
  310. if (!pnp_assign_mem(dev, mem, nmem))
  311. goto fail;
  312. nmem++;
  313. mem = mem->next;
  314. }
  315. while (irq) {
  316. if (!pnp_assign_irq(dev, irq, nirq))
  317. goto fail;
  318. nirq++;
  319. irq = irq->next;
  320. }
  321. while (dma) {
  322. pnp_assign_dma(dev, dma, ndma);
  323. ndma++;
  324. dma = dma->next;
  325. }
  326. }
  327. if (depnum) {
  328. struct pnp_option *dep;
  329. int i;
  330. dev_dbg(&dev->dev, "assigning dependent option %d\n", depnum);
  331. for (i = 1, dep = dev->dependent; i < depnum;
  332. i++, dep = dep->next)
  333. if (!dep)
  334. goto fail;
  335. port = dep->port;
  336. mem = dep->mem;
  337. irq = dep->irq;
  338. dma = dep->dma;
  339. while (port) {
  340. if (!pnp_assign_port(dev, port, nport))
  341. goto fail;
  342. nport++;
  343. port = port->next;
  344. }
  345. while (mem) {
  346. if (!pnp_assign_mem(dev, mem, nmem))
  347. goto fail;
  348. nmem++;
  349. mem = mem->next;
  350. }
  351. while (irq) {
  352. if (!pnp_assign_irq(dev, irq, nirq))
  353. goto fail;
  354. nirq++;
  355. irq = irq->next;
  356. }
  357. while (dma) {
  358. pnp_assign_dma(dev, dma, ndma);
  359. ndma++;
  360. dma = dma->next;
  361. }
  362. } else if (dev->dependent)
  363. goto fail;
  364. mutex_unlock(&pnp_res_mutex);
  365. dbg_pnp_show_resources(dev, "after pnp_assign_resources");
  366. return 1;
  367. fail:
  368. pnp_clean_resource_table(&dev->res);
  369. mutex_unlock(&pnp_res_mutex);
  370. dbg_pnp_show_resources(dev, "after pnp_assign_resources (failed)");
  371. return 0;
  372. }
  373. /**
  374. * pnp_manual_config_dev - Disables Auto Config and Manually sets the resource table
  375. * @dev: pointer to the desired device
  376. * @res: pointer to the new resource config
  377. * @mode: 0 or PNP_CONFIG_FORCE
  378. *
  379. * This function can be used by drivers that want to manually set thier resources.
  380. */
  381. int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res,
  382. int mode)
  383. {
  384. int i;
  385. struct pnp_resource_table *bak;
  386. if (!pnp_can_configure(dev))
  387. return -ENODEV;
  388. bak = pnp_alloc(sizeof(struct pnp_resource_table));
  389. if (!bak)
  390. return -ENOMEM;
  391. *bak = dev->res;
  392. mutex_lock(&pnp_res_mutex);
  393. dev->res = *res;
  394. if (!(mode & PNP_CONFIG_FORCE)) {
  395. for (i = 0; i < PNP_MAX_PORT; i++) {
  396. if (!pnp_check_port(dev, i))
  397. goto fail;
  398. }
  399. for (i = 0; i < PNP_MAX_MEM; i++) {
  400. if (!pnp_check_mem(dev, i))
  401. goto fail;
  402. }
  403. for (i = 0; i < PNP_MAX_IRQ; i++) {
  404. if (!pnp_check_irq(dev, i))
  405. goto fail;
  406. }
  407. for (i = 0; i < PNP_MAX_DMA; i++) {
  408. if (!pnp_check_dma(dev, i))
  409. goto fail;
  410. }
  411. }
  412. mutex_unlock(&pnp_res_mutex);
  413. kfree(bak);
  414. return 0;
  415. fail:
  416. dev->res = *bak;
  417. mutex_unlock(&pnp_res_mutex);
  418. kfree(bak);
  419. return -EINVAL;
  420. }
  421. /**
  422. * pnp_auto_config_dev - automatically assigns resources to a device
  423. * @dev: pointer to the desired device
  424. */
  425. int pnp_auto_config_dev(struct pnp_dev *dev)
  426. {
  427. struct pnp_option *dep;
  428. int i = 1;
  429. if (!pnp_can_configure(dev)) {
  430. dev_dbg(&dev->dev, "configuration not supported\n");
  431. return -ENODEV;
  432. }
  433. if (!dev->dependent) {
  434. if (pnp_assign_resources(dev, 0))
  435. return 0;
  436. } else {
  437. dep = dev->dependent;
  438. do {
  439. if (pnp_assign_resources(dev, i))
  440. return 0;
  441. dep = dep->next;
  442. i++;
  443. } while (dep);
  444. }
  445. dev_err(&dev->dev, "unable to assign resources\n");
  446. return -EBUSY;
  447. }
  448. /**
  449. * pnp_start_dev - low-level start of the PnP device
  450. * @dev: pointer to the desired device
  451. *
  452. * assumes that resources have already been allocated
  453. */
  454. int pnp_start_dev(struct pnp_dev *dev)
  455. {
  456. if (!pnp_can_write(dev)) {
  457. dev_dbg(&dev->dev, "activation not supported\n");
  458. return -EINVAL;
  459. }
  460. dbg_pnp_show_resources(dev, "pnp_start_dev");
  461. if (dev->protocol->set(dev) < 0) {
  462. dev_err(&dev->dev, "activation failed\n");
  463. return -EIO;
  464. }
  465. dev_info(&dev->dev, "activated\n");
  466. return 0;
  467. }
  468. /**
  469. * pnp_stop_dev - low-level disable of the PnP device
  470. * @dev: pointer to the desired device
  471. *
  472. * does not free resources
  473. */
  474. int pnp_stop_dev(struct pnp_dev *dev)
  475. {
  476. if (!pnp_can_disable(dev)) {
  477. dev_dbg(&dev->dev, "disabling not supported\n");
  478. return -EINVAL;
  479. }
  480. if (dev->protocol->disable(dev) < 0) {
  481. dev_err(&dev->dev, "disable failed\n");
  482. return -EIO;
  483. }
  484. dev_info(&dev->dev, "disabled\n");
  485. return 0;
  486. }
  487. /**
  488. * pnp_activate_dev - activates a PnP device for use
  489. * @dev: pointer to the desired device
  490. *
  491. * does not validate or set resources so be careful.
  492. */
  493. int pnp_activate_dev(struct pnp_dev *dev)
  494. {
  495. int error;
  496. if (dev->active)
  497. return 0;
  498. /* ensure resources are allocated */
  499. if (pnp_auto_config_dev(dev))
  500. return -EBUSY;
  501. error = pnp_start_dev(dev);
  502. if (error)
  503. return error;
  504. dev->active = 1;
  505. return 0;
  506. }
  507. /**
  508. * pnp_disable_dev - disables device
  509. * @dev: pointer to the desired device
  510. *
  511. * inform the correct pnp protocol so that resources can be used by other devices
  512. */
  513. int pnp_disable_dev(struct pnp_dev *dev)
  514. {
  515. int error;
  516. if (!dev->active)
  517. return 0;
  518. error = pnp_stop_dev(dev);
  519. if (error)
  520. return error;
  521. dev->active = 0;
  522. /* release the resources so that other devices can use them */
  523. mutex_lock(&pnp_res_mutex);
  524. pnp_clean_resource_table(&dev->res);
  525. mutex_unlock(&pnp_res_mutex);
  526. return 0;
  527. }
  528. /**
  529. * pnp_resource_change - change one resource
  530. * @resource: pointer to resource to be changed
  531. * @start: start of region
  532. * @size: size of region
  533. */
  534. void pnp_resource_change(struct resource *resource, resource_size_t start,
  535. resource_size_t size)
  536. {
  537. resource->flags &= ~(IORESOURCE_AUTO | IORESOURCE_UNSET);
  538. resource->start = start;
  539. resource->end = start + size - 1;
  540. }
  541. EXPORT_SYMBOL(pnp_manual_config_dev);
  542. EXPORT_SYMBOL(pnp_start_dev);
  543. EXPORT_SYMBOL(pnp_stop_dev);
  544. EXPORT_SYMBOL(pnp_activate_dev);
  545. EXPORT_SYMBOL(pnp_disable_dev);
  546. EXPORT_SYMBOL(pnp_resource_change);
  547. EXPORT_SYMBOL(pnp_init_resource_table);