isapnp.c
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:52k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /*
  2.  *  ISA Plug & Play support
  3.  *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
  4.  *
  5.  *  Modified by Ed Okerson <eokerson@quicknet.net> to work with the 2.2.x
  6.  *  series of Linux kernels. 11/17/99
  7.  *
  8.  *   This program is free software; you can redistribute it and/or modify
  9.  *   it under the terms of the GNU General Public License as published by
  10.  *   the Free Software Foundation; either version 2 of the License, or
  11.  *   (at your option) any later version.
  12.  *
  13.  *   This program is distributed in the hope that it will be useful,
  14.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *   GNU General Public License for more details.
  17.  *
  18.  *   You should have received a copy of the GNU General Public License
  19.  *   along with this program; if not, write to the Free Software
  20.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  */
  23. #include <linux/autoconf.h>
  24. #if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
  25. #define MODVERSIONS
  26. #endif
  27. #ifdef MODVERSIONS
  28. #include <linux/modversions.h>
  29. #endif
  30. #include <linux/config.h>
  31. #include <linux/version.h>
  32. #define EXPORT_SYMTAB
  33. #include <linux/module.h>
  34. #include <linux/kernel.h>
  35. #include <linux/errno.h>
  36. #include <linux/ioport.h>
  37. #include <linux/string.h>
  38. #include <linux/malloc.h>
  39. #include <linux/proc_fs.h>
  40. #include <linux/delay.h>
  41. #include <asm/io.h>
  42. #include <asm/dma.h>
  43. #include <asm/irq.h>
  44. #include <linux/pci.h>
  45. #include <linux/vmalloc.h>
  46. #include <linux/poll.h>
  47. #include <linux/init.h>
  48. #include <asm/uaccess.h>
  49. #include "pnpio.h"
  50. #include "isapnp.h"
  51. #ifdef CONFIG_PROC_FS
  52. #include "isapnp_proc.c"
  53. #endif
  54. #if 0
  55. #define ISAPNP_REGION_OK
  56. #endif
  57. #if 0
  58. #define ISAPNP_DEBUG
  59. #endif
  60. //struct resource *pidxr_res = NULL;
  61. //struct resource *pnpwrp_res = NULL;
  62. //struct resource *isapnp_rdp_res = NULL;
  63. int isapnp_disable = 0; /* Disable ISA PnP */
  64. int isapnp_rdp = 0; /* Read Data Port */
  65. int isapnp_reset = 0; /* reset all PnP cards (deactivate) */
  66. int isapnp_skip_pci_scan = 0; /* skip PCI resource scanning */
  67. int isapnp_verbose = 1; /* verbose mode */
  68. int isapnp_reserve_irq[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some IRQ */
  69. int isapnp_reserve_dma[8] = { [0 ... 7] = -1 }; /* reserve (don't use) some DMA */
  70. int isapnp_reserve_io[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some I/O region */
  71. int isapnp_reserve_mem[16] = { [0 ... 15] = -1 }; /* reserve (don't use) some memory region */
  72. int isapnp_debug = 0;
  73. MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
  74. MODULE_DESCRIPTION("Generic ISA Plug & Play support");
  75. MODULE_PARM(isapnp_disable, "i");
  76. MODULE_PARM_DESC(isapnp_disable, "ISA Plug & Play disable");
  77. MODULE_PARM(isapnp_rdp, "i");
  78. MODULE_PARM_DESC(isapnp_rdp, "ISA Plug & Play read data port");
  79. MODULE_PARM(isapnp_reset, "i");
  80. MODULE_PARM_DESC(isapnp_reset, "ISA Plug & Play reset all cards");
  81. MODULE_PARM(isapnp_skip_pci_scan, "i");
  82. MODULE_PARM_DESC(isapnp_skip_pci_scan, "ISA Plug & Play skip PCI resource scanning");
  83. MODULE_PARM(isapnp_verbose, "i");
  84. MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
  85. MODULE_PARM(isapnp_reserve_irq, "1-16i");
  86. MODULE_PARM_DESC(isapnp_reserve_irq, "ISA Plug & Play - reserve IRQ line(s)");
  87. MODULE_PARM(isapnp_reserve_dma, "1-8i");
  88. MODULE_PARM_DESC(isapnp_reserve_dma, "ISA Plug & Play - reserve DMA channel(s)");
  89. MODULE_PARM(isapnp_reserve_io, "1-16i");
  90. MODULE_PARM_DESC(isapnp_reserve_io, "ISA Plug & Play - reserve I/O region(s) - port,size");
  91. MODULE_PARM(isapnp_reserve_mem, "1-16i");
  92. MODULE_PARM_DESC(isapnp_reserve_mem, "ISA Plug & Play - reserve memory region(s) - address,size");
  93. MODULE_PARM(isapnp_debug, "i");
  94. MODULE_PARM_DESC(isapnp_debug, "ISA Plug & Play - Turn on some debugging messages");
  95. #define _PIDXR 0x279
  96. #define _PNPWRP 0xa79
  97. /* short tags */
  98. #define _STAG_PNPVERNO 0x01
  99. #define _STAG_LOGDEVID 0x02
  100. #define _STAG_COMPATDEVID 0x03
  101. #define _STAG_IRQ 0x04
  102. #define _STAG_DMA 0x05
  103. #define _STAG_STARTDEP 0x06
  104. #define _STAG_ENDDEP 0x07
  105. #define _STAG_IOPORT 0x08
  106. #define _STAG_FIXEDIO 0x09
  107. #define _STAG_VENDOR 0x0e
  108. #define _STAG_END 0x0f
  109. /* long tags */
  110. #define _LTAG_MEMRANGE 0x81
  111. #define _LTAG_ANSISTR 0x82
  112. #define _LTAG_UNICODESTR 0x83
  113. #define _LTAG_VENDOR 0x84
  114. #define _LTAG_MEM32RANGE 0x85
  115. #define _LTAG_FIXEDMEM32RANGE 0x86
  116. struct pnp_bus *isapnp_cards = NULL; /* ISA PnP cards */
  117. struct pnp_dev *isapnp_devices = NULL; /* ISA PnP devices */
  118. static struct pnp_dev *isapnp_last_device = NULL;
  119. static unsigned char isapnp_checksum_value;
  120. static struct semaphore isapnp_cfg_mutex = MUTEX;
  121. static int isapnp_detected = 0;
  122. /* some prototypes */
  123. static int isapnp_config_prepare(struct pnp_dev *dev);
  124. static int isapnp_config_activate(struct pnp_dev *dev);
  125. static int isapnp_config_deactivate(struct pnp_dev *dev);
  126. static inline void write_data(unsigned char x)
  127. {
  128. outb(x, _PNPWRP);
  129. }
  130. static inline void write_address(unsigned char x)
  131. {
  132. outb(x, _PIDXR);
  133. udelay(10);
  134. }
  135. static inline unsigned char read_data(void)
  136. {
  137. unsigned char val = inb(isapnp_rdp);
  138. return val;
  139. }
  140. unsigned char isapnp_read_byte(unsigned char idx)
  141. {
  142. write_address(idx);
  143. return read_data();
  144. }
  145. unsigned short isapnp_read_word(unsigned char idx)
  146. {
  147. unsigned short val;
  148. val = isapnp_read_byte(idx);
  149. val = (val << 8) + isapnp_read_byte(idx+1);
  150. return val;
  151. }
  152. unsigned int isapnp_read_dword(unsigned char idx)
  153. {
  154. unsigned int val;
  155. val = isapnp_read_byte(idx);
  156. val = (val << 8) + isapnp_read_byte(idx+1);
  157. val = (val << 8) + isapnp_read_byte(idx+2);
  158. val = (val << 8) + isapnp_read_byte(idx+3);
  159. return val;
  160. }
  161. void isapnp_write_byte(unsigned char idx, unsigned char val)
  162. {
  163. write_address(idx);
  164. write_data(val);
  165. }
  166. void isapnp_write_word(unsigned char idx, unsigned short val)
  167. {
  168. isapnp_write_byte(idx, val >> 8);
  169. isapnp_write_byte(idx+1, val);
  170. }
  171. void isapnp_write_dword(unsigned char idx, unsigned int val)
  172. {
  173. isapnp_write_byte(idx, val >> 24);
  174. isapnp_write_byte(idx+1, val >> 16);
  175. isapnp_write_byte(idx+2, val >> 8);
  176. isapnp_write_byte(idx+3, val);
  177. }
  178. static void *isapnp_alloc(long size)
  179. {
  180. void *result;
  181. result = kmalloc(size, GFP_KERNEL);
  182. if (!result)
  183. return NULL;
  184. memset(result, 0, size);
  185. return result;
  186. }
  187. static void isapnp_key(void)
  188. {
  189. unsigned char code = 0x6a, msb;
  190. int i;
  191. mdelay(1);
  192. write_address(0x00);
  193. write_address(0x00);
  194. write_address(code);
  195. for (i = 1; i < 32; i++) {
  196. msb = ((code & 0x01) ^ ((code & 0x02) >> 1)) << 7;
  197. code = (code >> 1) | msb;
  198. write_address(code);
  199. }
  200. }
  201. /* place all pnp cards in wait-for-key state */
  202. static void isapnp_wait(void)
  203. {
  204. isapnp_write_byte(0x02, 0x02);
  205. }
  206. void isapnp_wake(unsigned char csn)
  207. {
  208. isapnp_write_byte(0x03, csn);
  209. }
  210. void isapnp_device(unsigned char logdev)
  211. {
  212. isapnp_write_byte(0x07, logdev);
  213. }
  214. void isapnp_activate(unsigned char logdev)
  215. {
  216. isapnp_device(logdev);
  217. isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 1);
  218. udelay(250);
  219. }
  220. void isapnp_deactivate(unsigned char logdev)
  221. {
  222. isapnp_device(logdev);
  223. isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 0);
  224. }
  225. static void __init isapnp_peek(unsigned char *data, int bytes)
  226. {
  227. int i, j;
  228. unsigned char d;
  229. for (i = 1; i <= bytes; i++) {
  230. for (j = 0; j < 10; j++) {
  231. d = isapnp_read_byte(0x05);
  232. if (d & 1)
  233. break;
  234. udelay(10);
  235. }
  236. if (!(d & 1)) {
  237. *data++ = 0xff;
  238. continue;
  239. }
  240. d = isapnp_read_byte(0x04); /* PRESDI */
  241. isapnp_checksum_value += d;
  242. if (data != NULL)
  243. *data++ = d;
  244. }
  245. }
  246. #define RDP_STEP 32 /* minimum is 4 */
  247. static int isapnp_next_rdp(void)
  248. {
  249. int rdp = isapnp_rdp;
  250. while (rdp <= 0x3ff) {
  251. if (!check_region(rdp, 1)) {
  252. isapnp_rdp = rdp;
  253. return 0;
  254. }
  255. rdp += RDP_STEP;
  256. }
  257. return -1;
  258. }
  259. /* Set read port address */
  260. static inline void isapnp_set_rdp(void)
  261. {
  262. isapnp_write_byte(0x00, isapnp_rdp >> 2);
  263. udelay(100);
  264. }
  265. /*
  266.  * This code is badly broken. We cannot simply pick ports as the 
  267.  * ISAPnP specification implies. We should try 4 or 5 safe ports
  268.  * then bale by default.
  269.  *
  270.  * This code touches NE2K cards or other devices and your box is
  271.  * history.
  272.  */
  273. static int __init isapnp_isolate_rdp_select(void)
  274. {
  275. isapnp_wait();
  276. isapnp_key();
  277. /* Control: reset CSN and conditionally everything else too */
  278. isapnp_write_byte(0x02, isapnp_reset ? 0x05 : 0x04);
  279. mdelay(2);
  280. isapnp_wait();
  281. isapnp_key();
  282. isapnp_wake(0x00);
  283. if (isapnp_next_rdp() < 0) {
  284. isapnp_wait();
  285. return -1;
  286. }
  287. isapnp_set_rdp();
  288. udelay(1000);
  289. write_address(0x01);
  290. udelay(1000);
  291. return 0;
  292. }
  293. /*
  294.  *  Isolate (assign uniqued CSN) to all ISA PnP devices.
  295.  */
  296. static int __init isapnp_isolate(void)
  297. {
  298. unsigned char checksum = 0x6a;
  299. unsigned char chksum = 0x00;
  300. unsigned char bit = 0x00;
  301. int data;
  302. int csn = 0;
  303. int i;
  304. int iteration = 1;
  305. isapnp_rdp = 0x213;
  306. if (isapnp_isolate_rdp_select() < 0)
  307. return -1;
  308. while (1) {
  309. for (i = 1; i <= 64; i++) {
  310. data = read_data() << 8;
  311. udelay(250);
  312. data = data | read_data();
  313. udelay(250);
  314. if (data == 0x55aa)
  315. bit = 0x01;
  316. checksum = ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7) | (checksum >> 1);
  317. bit = 0x00;
  318. }
  319. for (i = 65; i <= 72; i++) {
  320. data = read_data() << 8;
  321. udelay(250);
  322. data = data | read_data();
  323. udelay(250);
  324. if (data == 0x55aa)
  325. chksum |= (1 << (i - 65));
  326. }
  327. if (checksum != 0x00 && checksum == chksum) {
  328. csn++;
  329. isapnp_write_byte(0x06, csn);
  330. udelay(250);
  331. iteration++;
  332. isapnp_wake(0x00);
  333. write_address(0x01);
  334. goto __next;
  335. }
  336. if (iteration == 1) {
  337. isapnp_rdp += RDP_STEP;
  338. if (isapnp_isolate_rdp_select() < 0)
  339. return -1;
  340. } else if (iteration > 1) {
  341. break;
  342. }
  343.       __next:
  344. checksum = 0x6a;
  345. chksum = 0x00;
  346. bit = 0x00;
  347. }
  348. isapnp_wait();
  349. return csn;
  350. }
  351. /*
  352.  *  Read one tag from stream.
  353.  */
  354. static int __init isapnp_read_tag(unsigned char *type, unsigned short *size)
  355. {
  356. unsigned char tag, tmp[2];
  357. isapnp_peek(&tag, 1);
  358. if (tag == 0) /* invalid tag */
  359. return -1;
  360. if (tag & 0x80) { /* large item */
  361. *type = tag;
  362. isapnp_peek(tmp, 2);
  363. *size = (tmp[1] << 8) | tmp[0];
  364. } else {
  365. *type = (tag >> 3) & 0x0f;
  366. *size = tag & 0x07;
  367. }
  368.         if(isapnp_debug > 0)
  369.         {
  370.   printk("tag = 0x%x, type = 0x%x, size = %in", tag, *type, *size);
  371.         }
  372. if (type == 0) /* wrong type */
  373. return -1;
  374. if (*type == 0xff && *size == 0xffff) /* probably invalid data */
  375. return -1;
  376. return 0;
  377. }
  378. /*
  379.  *  Skip specified number of bytes from stream.
  380.  */
  381.  
  382. static void __init isapnp_skip_bytes(int count)
  383. {
  384. isapnp_peek(NULL, count);
  385. }
  386. /*
  387.  *  Parse logical device tag.
  388.  */
  389. static struct pnp_dev * __init isapnp_parse_device(struct pnp_bus *card,
  390. int size, int number)
  391. {
  392. unsigned char tmp[6];
  393. struct pnp_dev *dev;
  394. isapnp_peek(tmp, size);
  395. dev = isapnp_alloc(sizeof(struct pnp_dev));
  396. if (!dev)
  397. return NULL;
  398. dev->devfn = number;
  399. dev->vendor = (tmp[1] << 8) | tmp[0];
  400. dev->device = (tmp[3] << 8) | tmp[2];
  401. dev->regs = tmp[4];
  402. dev->bus = card;
  403. if (size > 5)
  404. dev->regs |= tmp[5] << 8;
  405. dev->prepare = isapnp_config_prepare;
  406. dev->activate = isapnp_config_activate;
  407. dev->deactivate = isapnp_config_deactivate;
  408. return dev;
  409. }
  410. /*
  411.  *  Build new resources structure
  412.  */
  413. static struct isapnp_resources * __init isapnp_build_resources(struct pnp_dev *dev, int dependent)
  414. {
  415. struct isapnp_resources *res, *ptr, *ptra;
  416. res = isapnp_alloc(sizeof(struct isapnp_resources));
  417. if (!res)
  418. return NULL;
  419. res->dev = dev;
  420. ptr = (struct isapnp_resources *)dev->sysdata;
  421. while (ptr && ptr->next)
  422. ptr = ptr->next;
  423. if (ptr && ptr->dependent && dependent) { /* add to another list */
  424. ptra = ptr->alt;
  425. while (ptra && ptra->alt)
  426. ptra = ptra->alt;
  427. if (!ptra)
  428. ptr->alt = res;
  429. else
  430. ptra->alt = res;
  431. } else {
  432. if (!ptr)
  433. dev->sysdata = res;
  434. else
  435. ptr->next = res;
  436. }
  437. if (dependent) {
  438. res->priority = dependent & 0xff;
  439. if (res->priority > ISAPNP_RES_PRIORITY_FUNCTIONAL)
  440. res->priority = ISAPNP_RES_PRIORITY_INVALID;
  441. res->dependent = 1;
  442. } else {
  443. res->priority = ISAPNP_RES_PRIORITY_PREFERRED;
  444. res->dependent = 0;
  445. }
  446. return res;
  447. }
  448. /*
  449.  *  Add IRQ resource to resources list.
  450.  */
  451. static void __init isapnp_add_irq_resource(struct pnp_dev *dev,
  452.                                             struct isapnp_resources **res,
  453.                                                int dependent, int size)
  454. {
  455. unsigned char tmp[3];
  456. struct isapnp_irq *irq, *ptr;
  457. isapnp_peek(tmp, size);
  458. irq = isapnp_alloc(sizeof(struct isapnp_irq));
  459. if (!irq)
  460. return;
  461. if (*res == NULL) {
  462. *res = isapnp_build_resources(dev, dependent);
  463. if (*res == NULL) {
  464. kfree(irq);
  465. return;
  466. }
  467. }
  468. irq->map = (tmp[1] << 8) | tmp[0];
  469. if (size > 2)
  470. irq->flags = tmp[2];
  471. else
  472. irq->flags = IORESOURCE_IRQ_HIGHEDGE;
  473. irq->res = *res;
  474. ptr = (*res)->irq;
  475. while (ptr && ptr->next)
  476. ptr = ptr->next;
  477. if (ptr)
  478. ptr->next = irq;
  479. else
  480. (*res)->irq = irq;
  481. }
  482. /*
  483.  *  Add DMA resource to resources list.
  484.  */
  485. static void __init isapnp_add_dma_resource(struct pnp_dev *dev,
  486.                                             struct isapnp_resources **res,
  487.                                             int dependent, int size)
  488. {
  489. unsigned char tmp[2];
  490. struct isapnp_dma *dma, *ptr;
  491. isapnp_peek(tmp, size);
  492. dma = isapnp_alloc(sizeof(struct isapnp_dma));
  493. if (!dma)
  494. return;
  495. if (*res == NULL) {
  496. *res = isapnp_build_resources(dev, dependent);
  497. if (*res == NULL) {
  498. kfree(dma);
  499. return;
  500. }
  501. }
  502. dma->map = tmp[0];
  503. dma->flags = tmp[1];
  504. dma->res = *res;
  505. ptr = (*res)->dma;
  506. while (ptr && ptr->next)
  507. ptr = ptr->next;
  508. if (ptr)
  509. ptr->next = dma;
  510. else
  511. (*res)->dma = dma;
  512. }
  513. /*
  514.  *  Add port resource to resources list.
  515.  */
  516. static void __init isapnp_add_port_resource(struct pnp_dev *dev,
  517. struct isapnp_resources **res,
  518. int dependent, int size)
  519. {
  520. unsigned char tmp[7];
  521. struct isapnp_port *port, *ptr;
  522. isapnp_peek(tmp, size);
  523. port = isapnp_alloc(sizeof(struct isapnp_port));
  524. if (!port)
  525. return;
  526. if (*res == NULL) {
  527. *res = isapnp_build_resources(dev, dependent);
  528. if (*res == NULL) {
  529. kfree(port);
  530. return;
  531. }
  532. }
  533. port->min = (tmp[2] << 8) | tmp[1];
  534. port->max = (tmp[4] << 8) | tmp[3];
  535. port->align = tmp[5];
  536. port->size = tmp[6];
  537. port->flags = tmp[0] ? ISAPNP_PORT_FLAG_16BITADDR : 0;
  538. port->res = *res;
  539. ptr = (*res)->port;
  540. while (ptr && ptr->next)
  541. ptr = ptr->next;
  542. if (ptr)
  543. ptr->next = port;
  544. else
  545. (*res)->port = port;
  546. }
  547. /*
  548.  *  Add fixed port resource to resources list.
  549.  */
  550. static void __init isapnp_add_fixed_port_resource(struct pnp_dev *dev,
  551.       struct isapnp_resources **res,
  552.       int dependent, int size)
  553. {
  554. unsigned char tmp[3];
  555. struct isapnp_port *port, *ptr;
  556. isapnp_peek(tmp, size);
  557. port = isapnp_alloc(sizeof(struct isapnp_port));
  558. if (!port)
  559. return;
  560. if (*res == NULL) {
  561. *res = isapnp_build_resources(dev, dependent);
  562. if (*res == NULL) {
  563. kfree(port);
  564. return;
  565. }
  566. }
  567. port->min = port->max = (tmp[1] << 8) | tmp[0];
  568. port->size = tmp[2];
  569. port->align = 0;
  570. port->flags = ISAPNP_PORT_FLAG_FIXED;
  571. port->res = *res;
  572. ptr = (*res)->port;
  573. while (ptr && ptr->next)
  574. ptr = ptr->next;
  575. if (ptr)
  576. ptr->next = port;
  577. else
  578. (*res)->port = port;
  579. }
  580. /*
  581.  *  Add memory resource to resources list.
  582.  */
  583. static void __init isapnp_add_mem_resource(struct pnp_dev *dev,
  584.        struct isapnp_resources **res,
  585.        int dependent, int size)
  586. {
  587. unsigned char tmp[9];
  588. struct isapnp_mem *mem, *ptr;
  589. isapnp_peek(tmp, size);
  590. mem = isapnp_alloc(sizeof(struct isapnp_mem));
  591. if (!mem)
  592. return;
  593. if (*res == NULL) {
  594. *res = isapnp_build_resources(dev, dependent);
  595. if (*res == NULL) {
  596. kfree(mem);
  597. return;
  598. }
  599. }
  600. mem->min = ((tmp[2] << 8) | tmp[1]) << 8;
  601. mem->max = ((tmp[4] << 8) | tmp[3]) << 8;
  602. mem->align = (tmp[6] << 8) | tmp[5];
  603. mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
  604. mem->flags = tmp[0];
  605. mem->res = *res;
  606. ptr = (*res)->mem;
  607. while (ptr && ptr->next)
  608. ptr = ptr->next;
  609. if (ptr)
  610. ptr->next = mem;
  611. else
  612. (*res)->mem = mem;
  613. }
  614. /*
  615.  *  Add 32-bit memory resource to resources list.
  616.  */
  617. static void __init isapnp_add_mem32_resource(struct pnp_dev *dev,
  618.  struct isapnp_resources **res,
  619.  int dependent, int size)
  620. {
  621. unsigned char tmp[17];
  622. struct isapnp_mem32 *mem32, *ptr;
  623. isapnp_peek(tmp, size);
  624. mem32 = isapnp_alloc(sizeof(struct isapnp_mem32));
  625. if (!mem32)
  626. return;
  627. if (*res == NULL) {
  628. *res = isapnp_build_resources(dev, dependent);
  629. if (*res == NULL) {
  630. kfree(mem32);
  631. return;
  632. }
  633. }
  634. memcpy(mem32->data, tmp, 17);
  635. mem32->res = *res;
  636. ptr = (*res)->mem32;
  637. while (ptr && ptr->next)
  638. ptr = ptr->next;
  639. if (ptr)
  640. ptr->next = mem32;
  641. else
  642. (*res)->mem32 = mem32;
  643. }
  644. /*
  645.  *  Add 32-bit fixed memory resource to resources list.
  646.  */
  647. static void __init isapnp_add_fixed_mem32_resource(struct pnp_dev *dev,
  648.        struct isapnp_resources **res,
  649.        int dependent, int size)
  650. {
  651. unsigned char tmp[17];
  652. struct isapnp_mem32 *mem32, *ptr;
  653. isapnp_peek(tmp, size);
  654. mem32 = isapnp_alloc(sizeof(struct isapnp_mem32));
  655. if (!mem32)
  656. return;
  657. if (*res == NULL) {
  658. *res = isapnp_build_resources(dev, dependent);
  659. if (*res == NULL) {
  660. kfree(mem32);
  661. return;
  662. }
  663. }
  664. memcpy(mem32->data, tmp, 17);
  665. mem32->res = *res;
  666. ptr = (*res)->mem32;
  667. while (ptr && ptr->next)
  668. ptr = ptr->next;
  669. if (ptr)
  670. ptr->next = mem32;
  671. else
  672. (*res)->mem32 = mem32;
  673. }
  674. /*
  675.  *  Parse resource map for logical device.
  676.  */
  677. static int __init isapnp_create_device(struct pnp_bus *card,
  678.    unsigned short size)
  679. {
  680. int number = 0, skip = 0, dependent = 0, compat = 0;
  681. unsigned char type, tmp[17];
  682. struct pnp_dev *dev, *prev_dev;
  683. struct isapnp_resources *res = NULL;
  684. if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
  685. return 1;
  686. card->devices = dev;
  687. if (isapnp_last_device) {
  688. isapnp_last_device->next = dev;
  689. isapnp_last_device = dev;
  690. } else {
  691. isapnp_devices = isapnp_last_device = dev;
  692. }
  693. while (1) {
  694. if (isapnp_read_tag(&type, &size)<0)
  695. return 1;
  696. if (skip && type != _STAG_LOGDEVID && type != _STAG_END)
  697. goto __skip;
  698. switch (type) {
  699. case _STAG_LOGDEVID:
  700. if (size >= 5 && size <= 6) {
  701. prev_dev = dev;
  702. isapnp_config_prepare(dev);
  703. if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
  704. return 1;
  705. prev_dev->sibling = dev;
  706. isapnp_last_device->next = dev;
  707. isapnp_last_device = dev;
  708. size = 0;
  709. skip = 0;
  710. } else {
  711. skip = 1;
  712. }
  713. res = NULL;
  714. dependent = 0;
  715. compat = 0;
  716. break;
  717. case _STAG_COMPATDEVID:
  718. if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) {
  719. isapnp_peek(tmp, 4);
  720. dev->vendor_compatible[compat] = (tmp[1] << 8) | tmp[0];
  721. dev->device_compatible[compat] = (tmp[3] << 8) | tmp[2];
  722. compat++;
  723. size = 0;
  724. }
  725. break;
  726. case _STAG_IRQ:
  727. if (size < 2 || size > 3)
  728. goto __skip;
  729. isapnp_add_irq_resource(dev, &res, dependent, size);
  730. size = 0;
  731. break;
  732. case _STAG_DMA:
  733. if (size != 2)
  734. goto __skip;
  735. isapnp_add_dma_resource(dev, &res, dependent, size);
  736. size = 0;
  737. break;
  738. case _STAG_STARTDEP:
  739. if (size > 1)
  740. goto __skip;
  741. res = NULL;
  742. dependent = 0x100 | ISAPNP_RES_PRIORITY_ACCEPTABLE;
  743. if (size > 0) {
  744. isapnp_peek(tmp, size);
  745. dependent = 0x100 | tmp[0];
  746. size = 0;
  747. }
  748. break;
  749. case _STAG_ENDDEP:
  750. if (size != 0)
  751. goto __skip;
  752. res = NULL;
  753. dependent = 0;
  754. break;
  755. case _STAG_IOPORT:
  756. if (size != 7)
  757. goto __skip;
  758. isapnp_add_port_resource(dev, &res, dependent, size);
  759. size = 0;
  760. break;
  761. case _STAG_FIXEDIO:
  762. if (size != 3)
  763. goto __skip;
  764. isapnp_add_fixed_port_resource(dev, &res, dependent, size);
  765. size = 0;
  766. break;
  767. case _STAG_VENDOR:
  768. break;
  769. case _LTAG_MEMRANGE:
  770. if (size != 9)
  771. goto __skip;
  772. isapnp_add_mem_resource(dev, &res, dependent, size);
  773. size = 0;
  774. break;
  775. case _LTAG_ANSISTR:
  776. if (dev->name[0] == '') {
  777. unsigned short size1 = size > 47 ? 47 : size;
  778. isapnp_peek(dev->name, size1);
  779. dev->name[size1] = '';
  780. size -= size1;
  781. }
  782. break;
  783. case _LTAG_UNICODESTR:
  784. /* silently ignore */
  785. /* who use unicode for hardware identification? */
  786. break;
  787. case _LTAG_VENDOR:
  788. break;
  789. case _LTAG_MEM32RANGE:
  790. if (size != 17)
  791. goto __skip;
  792. isapnp_add_mem32_resource(dev, &res, dependent, size);
  793. size = 0;
  794. break;
  795. case _LTAG_FIXEDMEM32RANGE:
  796. if (size != 17)
  797. goto __skip;
  798. isapnp_add_fixed_mem32_resource(dev, &res, dependent, size);
  799. size = 0;
  800. break;
  801. case _STAG_END:
  802. if (size > 0)
  803. isapnp_skip_bytes(size);
  804. return 1;
  805. default:
  806. printk("isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignoredn", type, dev->devfn, card->number);
  807. }
  808.       __skip:
  809.        if (size > 0)
  810.        isapnp_skip_bytes(size);
  811. }
  812. isapnp_config_prepare(dev);
  813. return 0;
  814. }
  815. /*
  816.  *  Parse resource map for ISA PnP card.
  817.  */
  818.  
  819. static void __init isapnp_parse_resource_map(struct pnp_bus *card)
  820. {
  821. unsigned char type, tmp[17];
  822. unsigned short size;
  823. while (1) {
  824. if (isapnp_read_tag(&type, &size)<0)
  825. return;
  826. switch (type) {
  827. case _STAG_PNPVERNO:
  828. if (size != 2)
  829. goto __skip;
  830. isapnp_peek(tmp, 2);
  831. card->pnpver = tmp[0];
  832. card->productver = tmp[1];
  833. size = 0;
  834. break;
  835. case _STAG_LOGDEVID:
  836. if (size >= 5 && size <= 6) {
  837. if (isapnp_create_device(card, size)==1)
  838. return;
  839. size = 0;
  840. }
  841. break;
  842. case _STAG_VENDOR:
  843. break;
  844. case _LTAG_ANSISTR:
  845. if (card->name[0] == '') {
  846. unsigned short size1 = size > 47 ? 47 : size;
  847. isapnp_peek(card->name, size1);
  848. card->name[size1] = '';
  849. size -= size1;
  850. }
  851. break;
  852. case _LTAG_UNICODESTR:
  853. /* silently ignore */
  854. /* who use unicode for hardware identification? */
  855. break;
  856. case _LTAG_VENDOR:
  857. break;
  858. case _STAG_END:
  859. if (size > 0)
  860. isapnp_skip_bytes(size);
  861. return;
  862. default:
  863. printk("isapnp: unexpected or unknown tag type 0x%x for device %i, ignoredn", type, card->number);
  864. }
  865.       __skip:
  866.        if (size > 0)
  867.        isapnp_skip_bytes(size);
  868. }
  869. }
  870. /*
  871.  *  Compute ISA PnP checksum for first eight bytes.
  872.  */
  873. static unsigned char __init isapnp_checksum(unsigned char *data)
  874. {
  875. int i, j;
  876. unsigned char checksum = 0x6a, bit, b;
  877. for (i = 0; i < 8; i++) {
  878. b = data[i];
  879. for (j = 0; j < 8; j++) {
  880. bit = 0;
  881. if (b & (1 << j))
  882. bit = 1;
  883. checksum = ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7) | (checksum >> 1);
  884. }
  885. }
  886. return checksum;
  887. }
  888. /*
  889.  *  Build device list for all present ISA PnP devices.
  890.  */
  891. static int __init isapnp_build_device_list(void)
  892. {
  893. int csn;
  894. unsigned char header[9], checksum;
  895. struct pnp_bus *card, *prev = NULL;
  896. isapnp_wait();
  897. isapnp_key();
  898. for (csn = 1; csn <= 10; csn++) {
  899. isapnp_wake(csn);
  900. isapnp_peek(header, 9);
  901. checksum = isapnp_checksum(header);
  902.         if(isapnp_debug > 0)
  903.         {
  904. printk("vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02xn",
  905. header[0], header[1], header[2], header[3],
  906. header[4], header[5], header[6], header[7], header[8]);
  907. printk("checksum = 0x%xn", checksum);
  908.         }
  909. if (checksum == 0x00 || checksum != header[8]) /* not valid CSN */
  910. continue;
  911. if ((card = isapnp_alloc(sizeof(struct pnp_bus))) == NULL)
  912. continue;
  913. card->number = csn;
  914. card->vendor = (header[1] << 8) | header[0];
  915. card->device = (header[3] << 8) | header[2];
  916. card->serial = (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | header[4];
  917. isapnp_checksum_value = 0x00;
  918. isapnp_parse_resource_map(card);
  919. if (isapnp_checksum_value != 0x00)
  920. printk("isapnp: checksum for device %i is not valid (0x%x)n", csn, isapnp_checksum_value);
  921. card->checksum = isapnp_checksum_value;
  922. if (!isapnp_cards)
  923. isapnp_cards = card;
  924. else
  925. prev->next = card;
  926. prev = card;
  927. }
  928. return 0;
  929. }
  930. /*
  931.  *  Basic configuration routines.
  932.  */
  933. int isapnp_present(void)
  934. {
  935. if (isapnp_devices)
  936. return 1;
  937. return 0;
  938. }
  939. int isapnp_cfg_begin(int csn, int logdev)
  940. {
  941. if (csn < 1 || csn > 10 || logdev > 10)
  942. return -EINVAL;
  943. MOD_INC_USE_COUNT;
  944. down(&isapnp_cfg_mutex);
  945. isapnp_wait();
  946. isapnp_key();
  947. isapnp_wake(csn);
  948. #if 1 /* to avoid malfunction when the isapnptools package is used */
  949. isapnp_set_rdp();
  950. udelay(1000); /* delay 1000us */
  951. write_address(0x01);
  952. udelay(1000); /* delay 1000us */
  953. #endif
  954. if (logdev >= 0)
  955. isapnp_device(logdev);
  956. return 0;
  957. }
  958. int isapnp_cfg_end(void)
  959. {
  960. isapnp_wait();
  961. up(&isapnp_cfg_mutex);
  962. MOD_DEC_USE_COUNT;
  963. return 0;
  964. }
  965. /*
  966.  *  Resource manager.
  967.  */
  968. static struct isapnp_port *isapnp_find_port(struct pnp_dev *dev, int index)
  969. {
  970. struct isapnp_resources *res;
  971. struct isapnp_port *port;
  972. if (!dev || index < 0 || index > 7)
  973. return NULL;
  974. for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
  975. for (port = res->port; port; port = port->next) {
  976. if (!index)
  977. return port;
  978. index--;
  979. }
  980. }
  981. return NULL;
  982. }
  983. struct isapnp_irq *isapnp_find_irq(struct pnp_dev *dev, int index)
  984. {
  985. struct isapnp_resources *res, *resa;
  986. struct isapnp_irq *irq;
  987. int index1, index2, index3;
  988. if (!dev || index < 0 || index > 7)
  989. return NULL;
  990. for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
  991. index3 = 0;
  992. for (resa = res; resa; resa = resa->alt) {
  993. index1 = index;
  994. index2 = 0;
  995. for (irq = resa->irq; irq; irq = irq->next) {
  996. if (!index1)
  997. return irq;
  998. index1--;
  999. index2++;
  1000. }
  1001. if (index3 < index2)
  1002. index3 = index2;
  1003. }
  1004. index -= index3;
  1005. }
  1006. return NULL;
  1007. }
  1008. struct isapnp_dma *isapnp_find_dma(struct pnp_dev *dev, int index)
  1009. {
  1010. struct isapnp_resources *res;
  1011. struct isapnp_dma *dma;
  1012. if (!dev || index < 0 || index > 7)
  1013. return NULL;
  1014. for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
  1015. for (dma = res->dma; dma; dma = dma->next) {
  1016. if (!index)
  1017. return dma;
  1018. index--;
  1019. }
  1020. }
  1021. return NULL;
  1022. }
  1023. struct isapnp_mem *isapnp_find_mem(struct pnp_dev *dev, int index)
  1024. {
  1025. struct isapnp_resources *res;
  1026. struct isapnp_mem *mem;
  1027. if (!dev || index < 0 || index > 7)
  1028. return NULL;
  1029. for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
  1030. for (mem = res->mem; mem; mem = mem->next) {
  1031. if (!index)
  1032. return mem;
  1033. index--;
  1034. }
  1035. }
  1036. return NULL;
  1037. }
  1038. struct isapnp_mem32 *isapnp_find_mem32(struct pnp_dev *dev, int index)
  1039. {
  1040. struct isapnp_resources *res;
  1041. struct isapnp_mem32 *mem32;
  1042. if (!dev || index < 0 || index > 7)
  1043. return NULL;
  1044. for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
  1045. for (mem32 = res->mem32; mem32; mem32 = mem32->next) {
  1046. if (!index)
  1047. return mem32;
  1048. index--;
  1049. }
  1050. }
  1051. return NULL;
  1052. }
  1053. /*
  1054.  *  Device manager.
  1055.  */
  1056. struct pnp_bus *isapnp_find_card(unsigned short vendor,
  1057.  unsigned short device,
  1058.  struct pnp_bus *from)
  1059. {
  1060. struct pnp_bus *card;
  1061. if (from == NULL) {
  1062. from = isapnp_cards;
  1063. } else {
  1064. from = from->next;
  1065. }
  1066. for (card = from; card; card = card->next) {
  1067. if (card->vendor == vendor && card->device == device)
  1068. return card;
  1069. }
  1070. return NULL;
  1071. }
  1072. struct pnp_dev *isapnp_find_dev(struct pnp_bus *card,
  1073. unsigned short vendor,
  1074. unsigned short function,
  1075. struct pnp_dev *from)
  1076. {
  1077. struct pnp_dev *dev;
  1078. int idx;
  1079. if (card == NULL) { /* look for a logical device from all cards */
  1080. if (from == NULL) {
  1081. from = isapnp_devices;
  1082. } else {
  1083. from = from->next;
  1084. }
  1085. for (dev = from; dev; dev = dev->next) {
  1086. if (dev->vendor == vendor && dev->device == function)
  1087. return dev;
  1088. for (idx = 0; idx < DEVICE_COUNT_COMPATIBLE; idx++)
  1089. if (dev->vendor_compatible[idx] == vendor &&
  1090.     dev->device_compatible[idx] == function)
  1091. return dev;
  1092. }
  1093. } else {
  1094. if (from == NULL) {
  1095. from = card->devices;
  1096. } else {
  1097. from = from->next;
  1098. }
  1099. if (from->bus != card) /* something is wrong */
  1100. return NULL;
  1101. for (dev = from; dev; dev = dev->sibling) {
  1102. if (dev->vendor == vendor && dev->device == function)
  1103. return dev;
  1104. for (idx = 0; idx < DEVICE_COUNT_COMPATIBLE; idx++)
  1105. if (dev->vendor_compatible[idx] == vendor &&
  1106.     dev->device_compatible[idx] == function)
  1107. return dev;
  1108. }
  1109. }
  1110. return NULL;
  1111. }
  1112. static unsigned int isapnp_dma_resource_flags(struct isapnp_dma *dma)
  1113. {
  1114. return dma->flags | IORESOURCE_DMA | IORESOURCE_AUTO;
  1115. }
  1116. static unsigned int isapnp_mem_resource_flags(struct isapnp_mem *mem)
  1117. {
  1118. unsigned int result;
  1119. result = mem->flags | IORESOURCE_MEM | IORESOURCE_AUTO;
  1120. if (!(mem->flags & IORESOURCE_MEM_WRITEABLE))
  1121. result |= IORESOURCE_READONLY;
  1122. if (mem->flags & IORESOURCE_MEM_CACHEABLE)
  1123. result |= IORESOURCE_CACHEABLE;
  1124. if (mem->flags & IORESOURCE_MEM_RANGELENGTH)
  1125. result |= IORESOURCE_RANGELENGTH;
  1126. if (mem->flags & IORESOURCE_MEM_SHADOWABLE)
  1127. result |= IORESOURCE_SHADOWABLE;
  1128. return result;
  1129. }
  1130. static unsigned int isapnp_irq_resource_flags(struct isapnp_irq *irq)
  1131. {
  1132. return irq->flags | IORESOURCE_IRQ | IORESOURCE_AUTO;
  1133. }
  1134. static unsigned int isapnp_port_resource_flags(struct isapnp_port *port)
  1135. {
  1136. return port->flags | IORESOURCE_IO | IORESOURCE_AUTO;
  1137. }
  1138. static int isapnp_config_prepare(struct pnp_dev *dev)
  1139. {
  1140. struct isapnp_resources *res, *resa;
  1141. struct isapnp_port *port;
  1142. struct isapnp_irq *irq;
  1143. struct isapnp_dma *dma;
  1144. struct isapnp_mem *mem;
  1145. int port_count, port_count1;
  1146. int irq_count, irq_count1;
  1147. int dma_count, dma_count1;
  1148. int mem_count, mem_count1;
  1149. int idx;
  1150. if (dev == NULL)
  1151. return -EINVAL;
  1152. if (dev->active) // || dev->ro)
  1153. return -EBUSY;
  1154. for (idx = 0; idx < DEVICE_COUNT_IRQ; idx++) {
  1155. dev->irq_resource[idx].name = NULL;
  1156. dev->irq_resource[idx].start = 0;
  1157. dev->irq_resource[idx].end = 0;
  1158. dev->irq_resource[idx].flags = 0;
  1159. }
  1160. for (idx = 0; idx < DEVICE_COUNT_DMA; idx++) {
  1161. dev->dma_resource[idx].name = NULL;
  1162. dev->dma_resource[idx].start = 0;
  1163. dev->dma_resource[idx].end = 0;
  1164. dev->dma_resource[idx].flags = 0;
  1165. }
  1166. for (idx = 0; idx < DEVICE_COUNT_RESOURCE; idx++) {
  1167. dev->resource[idx].name = NULL;
  1168. dev->resource[idx].start = 0;
  1169. dev->resource[idx].end = 0;
  1170. dev->resource[idx].flags = 0;
  1171. }
  1172. port_count = irq_count = dma_count = mem_count = 0;
  1173. for (res = (struct isapnp_resources *)dev->sysdata; res; res = res->next) {
  1174. port_count1 = irq_count1 = dma_count1 = mem_count1 = 0;
  1175. for (resa = res; resa; resa = resa->alt) {
  1176. for (port = resa->port, idx = 0; port; port = port->next, idx++) {
  1177. if (dev->resource[port_count + idx].flags == 0) {
  1178. dev->resource[port_count + idx].flags = isapnp_port_resource_flags(port);
  1179. dev->resource[port_count + idx].end = port->size;
  1180. }
  1181. }
  1182. if (port_count1 < idx)
  1183. port_count1 = idx;
  1184. for (irq = resa->irq, idx = 0; irq; irq = irq->next, idx++) {
  1185. int count = irq_count + idx;
  1186. if (count < DEVICE_COUNT_IRQ) {
  1187. if (dev->irq_resource[count].flags == 0) {
  1188. dev->irq_resource[count].flags = isapnp_irq_resource_flags(irq);
  1189. }
  1190. }
  1191. }
  1192. if (irq_count1 < idx)
  1193. irq_count1 = idx;
  1194. for (dma = resa->dma, idx = 0; dma; dma = dma->next, idx++)
  1195. if (dev->dma_resource[idx].flags == 0) {
  1196. dev->dma_resource[idx].flags = isapnp_dma_resource_flags(dma);
  1197. }
  1198. if (dma_count1 < idx)
  1199. dma_count1 = idx;
  1200. for (mem = resa->mem, idx = 0; mem; mem = mem->next, idx++)
  1201. if (dev->resource[mem_count + idx + 8].flags == 0) {
  1202. dev->resource[mem_count + idx + 8].flags = isapnp_mem_resource_flags(mem);
  1203. }
  1204. if (mem_count1 < idx)
  1205. mem_count1 = idx;
  1206. }
  1207. port_count += port_count1;
  1208. irq_count += irq_count1;
  1209. dma_count += dma_count1;
  1210. mem_count += mem_count1;
  1211. }
  1212. return 0;
  1213. }
  1214. struct isapnp_cfgtmp {
  1215. struct isapnp_port *port[8];
  1216. struct isapnp_irq *irq[2];
  1217. struct isapnp_dma *dma[2];
  1218. struct isapnp_mem *mem[4];
  1219. struct pnp_dev *request;
  1220. struct pnp_dev result;
  1221. };
  1222. static int isapnp_alternative_switch(struct isapnp_cfgtmp *cfg,
  1223.      struct isapnp_resources *from,
  1224.      struct isapnp_resources *to)
  1225. {
  1226. int tmp, tmp1;
  1227. struct isapnp_port *port;
  1228. struct isapnp_irq *irq;
  1229. struct isapnp_dma *dma;
  1230. struct isapnp_mem *mem;
  1231. if (!cfg)
  1232. return -EINVAL;
  1233. /* process port settings */
  1234. for (tmp = 0; tmp < 8; tmp++) {
  1235. if (!(cfg->request->resource[tmp].flags & IORESOURCE_AUTO))
  1236. continue; /* don't touch */
  1237. port = cfg->port[tmp];
  1238. if (!port) {
  1239. cfg->port[tmp] = port = isapnp_find_port(cfg->request, tmp);
  1240. if (!port)
  1241. return -EINVAL;
  1242. }
  1243. if (from && port->res == from) {
  1244. while (port->res != to) {
  1245. if (!port->res->alt)
  1246. return -EINVAL;
  1247. port = port->res->alt->port;
  1248. for (tmp1 = tmp; tmp1 > 0 && port; tmp1--)
  1249. port = port->next;
  1250. cfg->port[tmp] = port;
  1251. if (!port)
  1252. return -ENOENT;
  1253. cfg->result.resource[tmp].flags = isapnp_port_resource_flags(port);
  1254. }
  1255. }
  1256. }
  1257. /* process irq settings */
  1258. for (tmp = 0; tmp < 2; tmp++) {
  1259. if (!(cfg->request->irq_resource[tmp].flags & IORESOURCE_AUTO))
  1260. continue; /* don't touch */
  1261. irq = cfg->irq[tmp];
  1262. if (!irq) {
  1263. cfg->irq[tmp] = irq = isapnp_find_irq(cfg->request, tmp);
  1264. if (!irq)
  1265. return -EINVAL;
  1266. }
  1267. if (from && irq->res == from) {
  1268. while (irq->res != to) {
  1269. if (!irq->res->alt)
  1270. return -EINVAL;
  1271. irq = irq->res->alt->irq;
  1272. for (tmp1 = tmp; tmp1 > 0 && irq; tmp1--)
  1273. irq = irq->next;
  1274. cfg->irq[tmp] = irq;
  1275. if (!irq)
  1276. return -ENOENT;
  1277. cfg->result.irq_resource[tmp].flags = isapnp_irq_resource_flags(irq);
  1278. }
  1279. }
  1280. }
  1281. /* process dma settings */
  1282. for (tmp = 0; tmp < 2; tmp++) {
  1283. if (!(cfg->request->dma_resource[tmp].flags & IORESOURCE_AUTO))
  1284. continue; /* don't touch */
  1285. dma = cfg->dma[tmp];
  1286. if (!dma) {
  1287. cfg->dma[tmp] = dma = isapnp_find_dma(cfg->request, tmp);
  1288. if (!dma)
  1289. return -EINVAL;
  1290. }
  1291. if (from && dma->res == from) {
  1292. while (dma->res != to) {
  1293. if (!dma->res->alt)
  1294. return -EINVAL;
  1295. dma = dma->res->alt->dma;
  1296. for (tmp1 = tmp; tmp1 > 0 && dma; tmp1--)
  1297. dma = dma->next;
  1298. cfg->dma[tmp] = dma;
  1299. if (!dma)
  1300. return -ENOENT;
  1301. cfg->result.dma_resource[tmp].flags = isapnp_dma_resource_flags(dma);
  1302. }
  1303. }
  1304. }
  1305. /* process memory settings */
  1306. for (tmp = 0; tmp < 4; tmp++) {
  1307. if (!(cfg->request->resource[tmp + 8].flags & IORESOURCE_AUTO))
  1308. continue; /* don't touch */
  1309. mem = cfg->mem[tmp];
  1310. if (!mem) {
  1311. cfg->mem[tmp] = mem = isapnp_find_mem(cfg->request, tmp);
  1312. if (!mem)
  1313. return -EINVAL;
  1314. }
  1315. if (from && mem->res == from) {
  1316. while (mem->res != to) {
  1317. if (!mem->res->alt)
  1318. return -EINVAL;
  1319. mem = mem->res->alt->mem;
  1320. for (tmp1 = tmp; tmp1 > 0 && mem; tmp1--)
  1321. mem = mem->next;
  1322. cfg->mem[tmp] = mem;
  1323. if (!mem)
  1324. return -ENOENT;
  1325. cfg->result.resource[tmp + 8].flags = isapnp_mem_resource_flags(mem);
  1326. }
  1327. }
  1328. }
  1329. return 0;
  1330. }
  1331. static int isapnp_check_port(struct isapnp_cfgtmp *cfg, int port, int size, int idx)
  1332. {
  1333. int i, tmp, rport, rsize;
  1334. struct isapnp_port *xport;
  1335. struct pnp_dev *dev;
  1336. if (check_region(port, size))
  1337. return 1;
  1338. for (i = 0; i < 8; i++) {
  1339. rport = isapnp_reserve_io[i << 1];
  1340. rsize = isapnp_reserve_io[(i << 1) + 1];
  1341. if (port >= rport && port < rport + rsize)
  1342. return 1;
  1343. if (port + size > rport && port + size < (rport + rsize) - 1)
  1344. return 1;
  1345. }
  1346. for (dev = isapnp_devices; dev; dev = dev->next) {
  1347. if (dev->active) {
  1348. for (tmp = 0; tmp < 8; tmp++) {
  1349. if (dev->resource[tmp].flags) {
  1350. rport = dev->resource[tmp].start;
  1351. rsize = (dev->resource[tmp].end - rport) + 1;
  1352. if (port >= rport && port < rport + rsize)
  1353. return 1;
  1354. if (port + size > rport && port + size < (rport + rsize) - 1)
  1355. return 1;
  1356. }
  1357. }
  1358. }
  1359. }
  1360. for (i = 0; i < 8; i++) {
  1361. unsigned int flags;
  1362. if (i == idx)
  1363. continue;
  1364. flags = cfg->request->resource[i].flags;
  1365. if (!flags)
  1366. continue;
  1367. tmp = cfg->request->resource[i].start;
  1368. if (flags & IORESOURCE_AUTO) { /* auto */
  1369. xport = cfg->port[i];
  1370. if (!xport)
  1371. return 1;
  1372. if (cfg->result.resource[i].flags & IORESOURCE_AUTO)
  1373. continue;
  1374. tmp = cfg->result.resource[i].start;
  1375. if (tmp + xport->size >= port && tmp <= port + xport->size)
  1376. return 1;
  1377. continue;
  1378. }
  1379. if (port == tmp)
  1380. return 1;
  1381. xport = isapnp_find_port(cfg->request, i);
  1382. if (!xport)
  1383. return 1;
  1384. if (tmp + xport->size >= port && tmp <= port + xport->size)
  1385. return 1;
  1386. }
  1387. return 0;
  1388. }
  1389. static int isapnp_valid_port(struct isapnp_cfgtmp *cfg, int idx)
  1390. {
  1391. int err;
  1392. unsigned long *value1, *value2;
  1393. struct isapnp_port *port;
  1394. if (!cfg || idx < 0 || idx > 7)
  1395. return -EINVAL;
  1396. if (!(cfg->result.resource[idx].flags & IORESOURCE_AUTO)) /* don't touch */
  1397. return 0;
  1398.       __again:
  1399.        port = cfg->port[idx];
  1400.        if (!port)
  1401.        return -EINVAL;
  1402.        value1 = &cfg->result.resource[idx].start;
  1403.        value2 = &cfg->result.resource[idx].end;
  1404. if (cfg->result.resource[idx].flags & IORESOURCE_AUTO) {
  1405. cfg->result.resource[idx].flags &= ~IORESOURCE_AUTO;
  1406. *value1 = port->min;
  1407. *value2 = port->min + port->size - 1;
  1408. if (!isapnp_check_port(cfg, *value1, port->size, idx))
  1409. return 0;
  1410. }
  1411. do {
  1412. *value1 += port->align;
  1413. *value2 = *value1 + port->size - 1;
  1414. if (*value1 > port->max || !port->align) {
  1415. if (port->res && port->res->alt) {
  1416. if ((err = isapnp_alternative_switch(cfg, port->res, port->res->alt))<0)
  1417. return err;
  1418. goto __again;
  1419. }
  1420. return -ENOENT;
  1421. }
  1422. } while (isapnp_check_port(cfg, *value1, port->size, idx));
  1423. return 0;
  1424. }
  1425. static void isapnp_test_handler(int irq, void *dev_id, struct pt_regs *regs)
  1426. {
  1427. }
  1428. static int isapnp_check_interrupt(struct isapnp_cfgtmp *cfg, int irq, int idx)
  1429. {
  1430. int i;
  1431. struct pnp_dev *dev;
  1432. if (irq < 0 || irq > 15)
  1433. return 1;
  1434. for (i = 0; i < 16; i++) {
  1435. if (isapnp_reserve_irq[i] == irq)
  1436. return 1;
  1437. }
  1438. for (dev = isapnp_devices; dev; dev = dev->next) {
  1439. if (dev->active) {
  1440. if (dev->irq_resource[0].start == irq ||
  1441.     dev->irq_resource[1].start == irq)
  1442. return 1;
  1443. }
  1444. }
  1445. if (request_irq(irq, isapnp_test_handler, SA_INTERRUPT, "isapnp", NULL))
  1446. return 1;
  1447. free_irq(irq, NULL);
  1448. for (i = 0; i < DEVICE_COUNT_IRQ; i++) {
  1449. if (i == idx)
  1450. continue;
  1451. if (!cfg->result.irq_resource[i].flags)
  1452. continue;
  1453. if (cfg->result.irq_resource[i].flags & IORESOURCE_AUTO)
  1454. continue;
  1455. if (cfg->result.irq_resource[i].start == irq)
  1456. return 1;
  1457. }
  1458. return 0;
  1459. }
  1460. static int isapnp_valid_irq(struct isapnp_cfgtmp *cfg, int idx)
  1461. {
  1462. /* IRQ priority: this table is good for i386 */
  1463. static unsigned short xtab[16] = {
  1464. 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2
  1465. };
  1466. int err, i;
  1467. unsigned long *value1, *value2;
  1468. struct isapnp_irq *irq;
  1469. if (!cfg || idx < 0 || idx > 1)
  1470. return -EINVAL;
  1471. if (!(cfg->result.irq_resource[idx].flags & IORESOURCE_AUTO))
  1472. return 0;
  1473.       __again:
  1474.        irq = cfg->irq[idx];
  1475.        if (!irq)
  1476.        return -EINVAL;
  1477.        value1 = &cfg->result.irq_resource[idx].start;
  1478.        value2 = &cfg->result.irq_resource[idx].end;
  1479. if (cfg->result.irq_resource[idx].flags & IORESOURCE_AUTO) {
  1480. for (i = 0; i < 16 && !(irq->map & (1<<xtab[i])); i++);
  1481. if (i >= 16)
  1482. return -ENOENT;
  1483. cfg->result.irq_resource[idx].flags &= ~IORESOURCE_AUTO;
  1484. if (!isapnp_check_interrupt(cfg, *value1 = *value2 = xtab[i], idx))
  1485. return 0;
  1486. }
  1487. do {
  1488. for (i = 0; i < 16 && xtab[i] != *value1; i++);
  1489. for (i++; i < 16 && !(irq->map & (1<<xtab[i])); i++);
  1490. if (i >= 16) {
  1491. if (irq->res && irq->res->alt) {
  1492. if ((err = isapnp_alternative_switch(cfg, irq->res, irq->res->alt))<0)
  1493. return err;
  1494. goto __again;
  1495. }
  1496. return -ENOENT;
  1497. } else {
  1498. *value1 = *value2 = xtab[i];
  1499. }
  1500. } while (isapnp_check_interrupt(cfg, *value1, idx));
  1501. return 0;
  1502. }
  1503. static int isapnp_check_dma(struct isapnp_cfgtmp *cfg, int dma, int idx)
  1504. {
  1505. int i;
  1506. struct pnp_dev *dev;
  1507. if (dma < 0 || dma == 4 || dma > 7)
  1508. return 1;
  1509. for (i = 0; i < 8; i++) {
  1510. if (isapnp_reserve_dma[i] == dma)
  1511. return 1;
  1512. }
  1513. for (dev = isapnp_devices; dev; dev = dev->next) {
  1514. if (dev->active) {
  1515. if (dev->dma_resource[0].start == dma || dev->dma_resource[1].start == dma)
  1516. return 1;
  1517. }
  1518. }
  1519. if (request_dma(dma, "isapnp"))
  1520. return 1;
  1521. free_dma(dma);
  1522. for (i = 0; i < 2; i++) {
  1523. if (i == idx)
  1524. continue;
  1525. if (!cfg->result.dma_resource[i].flags ||
  1526.     (cfg->result.dma_resource[i].flags & IORESOURCE_AUTO))
  1527. continue;
  1528. if (cfg->result.dma_resource[i].start == dma)
  1529. return 1;
  1530. }
  1531. return 0;
  1532. }
  1533. static int isapnp_valid_dma(struct isapnp_cfgtmp *cfg, int idx)
  1534. {
  1535. int err, i;
  1536. unsigned long *value1, *value2;
  1537. struct isapnp_dma *dma;
  1538. if (!cfg || idx < 0 || idx > 1)
  1539. return -EINVAL;
  1540. if (!(cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO)) /* don't touch */
  1541. return 0;
  1542.       __again:
  1543.        dma = cfg->dma[idx];
  1544.        if (!dma)
  1545.        return -EINVAL;
  1546.        value1 = &cfg->result.dma_resource[idx].start;
  1547.        value2 = &cfg->result.dma_resource[idx].end;
  1548. if (cfg->result.dma_resource[idx].flags & IORESOURCE_AUTO) {
  1549. for (i = 0; i < 8 && !(dma->map & (1<<i)); i++);
  1550. if (i >= 8)
  1551. return -ENOENT;
  1552. cfg->result.dma_resource[idx].flags &= ~IORESOURCE_AUTO;
  1553. if (!isapnp_check_dma(cfg, *value1 = *value2 = i, idx))
  1554. return 0;
  1555. }
  1556. do {
  1557. for (i = *value1 + 1; i < 8 && !(dma->map & (1<<i)); i++);
  1558. if (i >= 8) {
  1559. if (dma->res && dma->res->alt) {
  1560. if ((err = isapnp_alternative_switch(cfg, dma->res, dma->res->alt))<0)
  1561. return err;
  1562. goto __again;
  1563. }
  1564. return -ENOENT;
  1565. } else {
  1566. *value1 = *value2 = i;
  1567. }
  1568. } while (isapnp_check_dma(cfg, *value1, idx));
  1569. return 0;
  1570. }
  1571. static int isapnp_check_mem(struct isapnp_cfgtmp *cfg, unsigned int addr, unsigned int size, int idx)
  1572. {
  1573. int i, tmp;
  1574. unsigned int raddr, rsize;
  1575. struct pnp_dev *dev;
  1576. struct isapnp_mem *xmem;
  1577. for (i = 0; i < 8; i++) {
  1578. raddr = (unsigned int)isapnp_reserve_mem[i << 1];
  1579. rsize = (unsigned int)isapnp_reserve_mem[(i << 1) + 1];
  1580. if (addr >= raddr && addr < raddr + rsize)
  1581. return 1;
  1582. if (addr + size > raddr && addr + size < (raddr + rsize) - 1)
  1583. return 1;
  1584. // if (__check_region(&iomem_resource, addr, size))
  1585. if (check_region(addr, size))
  1586. return 1;
  1587. }
  1588. for (dev = isapnp_devices; dev; dev = dev->next) {
  1589. if (dev->active) {
  1590. for (tmp = 0; tmp < 4; tmp++) {
  1591. if (dev->resource[tmp].flags) {
  1592. raddr = dev->resource[tmp + 8].start;
  1593. rsize = (dev->resource[tmp + 8].end - raddr) + 1;
  1594. if (addr >= raddr && addr < raddr + rsize)
  1595. return 1;
  1596. if (addr + size > raddr && addr + size < (raddr + rsize) - 1)
  1597. return 1;
  1598. }
  1599. }
  1600. }
  1601. }
  1602. for (i = 0; i < 4; i++) {
  1603. unsigned int flags = cfg->request->resource[i + 8].flags;
  1604. if (i == idx)
  1605. continue;
  1606. if (!flags)
  1607. continue;
  1608. tmp = cfg->result.resource[i + 8].start;
  1609. if (flags & IORESOURCE_AUTO) { /* auto */
  1610. xmem = cfg->mem[i];
  1611. if (!xmem)
  1612. return 1;
  1613. if (cfg->result.resource[i + 8].flags & IORESOURCE_AUTO)
  1614. continue;
  1615. if (tmp + xmem->size >= addr && tmp <= addr + xmem->size)
  1616. return 1;
  1617. continue;
  1618. }
  1619. if (addr == tmp)
  1620. return 1;
  1621. xmem = isapnp_find_mem(cfg->request, i);
  1622. if (!xmem)
  1623. return 1;
  1624. if (tmp + xmem->size >= addr && tmp <= addr + xmem->size)
  1625. return 1;
  1626. }
  1627. return 0;
  1628. }
  1629. static int isapnp_valid_mem(struct isapnp_cfgtmp *cfg, int idx)
  1630. {
  1631. int err;
  1632. unsigned long *value1, *value2;
  1633. struct isapnp_mem *mem;
  1634. if (!cfg || idx < 0 || idx > 3)
  1635. return -EINVAL;
  1636. if (!(cfg->result.resource[idx + 8].flags & IORESOURCE_AUTO)) /* don't touch */
  1637. return 0;
  1638.       __again:
  1639.        mem = cfg->mem[idx];
  1640.        if (!mem)
  1641.        return -EINVAL;
  1642.        value1 = &cfg->result.resource[idx].start;
  1643.        value2 = &cfg->result.resource[idx].end;
  1644. if (cfg->result.resource[idx + 8].flags & IORESOURCE_AUTO) {
  1645. cfg->result.resource[idx + 8].flags &= ~IORESOURCE_AUTO;
  1646. *value1 = mem->min;
  1647. *value2 = mem->min + mem->size - 1;
  1648. if (!isapnp_check_mem(cfg, *value1, mem->size, idx))
  1649. return 0;
  1650. }
  1651. do {
  1652. *value1 += mem->align;
  1653. *value2 = *value1 + mem->size - 1;
  1654. if (*value1 >= 8 || !mem->align) {
  1655. if (mem->res && mem->res->alt) {
  1656. if ((err = isapnp_alternative_switch(cfg, mem->res, mem->res->alt))<0)
  1657. return err;
  1658. goto __again;
  1659. }
  1660. return -ENOENT;
  1661. }
  1662. } while (isapnp_check_mem(cfg, *value1, mem->size, idx));
  1663. return 0;
  1664. }
  1665. static int isapnp_check_valid(struct isapnp_cfgtmp *cfg)
  1666. {
  1667. int tmp;
  1668. for (tmp = 0; tmp < 8; tmp++)
  1669. if (cfg->result.resource[tmp].flags & IORESOURCE_AUTO)
  1670. return -EAGAIN;
  1671. for (tmp = 0; tmp < 2; tmp++)
  1672. if (cfg->result.irq_resource[tmp].flags & IORESOURCE_AUTO)
  1673. return -EAGAIN;
  1674. for (tmp = 0; tmp < 2; tmp++)
  1675. if (cfg->result.dma_resource[tmp].flags & IORESOURCE_AUTO)
  1676. return -EAGAIN;
  1677. for (tmp = 0; tmp < 4; tmp++)
  1678. if (cfg->result.resource[tmp + 8].flags & IORESOURCE_AUTO)
  1679. return -EAGAIN;
  1680. return 0;
  1681. }
  1682. static int isapnp_config_activate(struct pnp_dev *dev)
  1683. {
  1684. struct isapnp_cfgtmp cfg;
  1685. int tmp, fauto, err;
  1686. if (!dev)
  1687. return -EINVAL;
  1688. if (dev->active)
  1689. return -EBUSY;
  1690. memset(&cfg, 0, sizeof(cfg));
  1691. cfg.request = dev;
  1692. memcpy(&cfg.result, dev, sizeof(struct pnp_dev));
  1693. /* check if all values are set, otherwise try auto-configuration */
  1694. for (tmp = fauto = 0; !fauto && tmp < 8; tmp++) {
  1695. if (dev->resource[tmp].flags & IORESOURCE_AUTO)
  1696. fauto++;
  1697. }
  1698. for (tmp = 0; !fauto && tmp < 2; tmp++) {
  1699. if (dev->irq_resource[tmp].flags & IORESOURCE_AUTO)
  1700. fauto++;
  1701. }
  1702. for (tmp = 0; !fauto && tmp < 2; tmp++) {
  1703. if (dev->dma_resource[tmp].flags & IORESOURCE_AUTO)
  1704. fauto++;
  1705. }
  1706. for (tmp = 0; !fauto && tmp < 4; tmp++) {
  1707. if (dev->resource[tmp + 8].flags & IORESOURCE_AUTO)
  1708. fauto++;
  1709. }
  1710. if (!fauto)
  1711. goto __skip_auto;
  1712. /* set variables to initial values */
  1713. if ((err = isapnp_alternative_switch(&cfg, NULL, NULL))<0)
  1714. return err;
  1715. /* find first valid configuration */
  1716. fauto = 0;
  1717. do {
  1718. for (tmp = 0; tmp < 8 && cfg.result.resource[tmp].flags; tmp++)
  1719. if ((err = isapnp_valid_port(&cfg, tmp))<0)
  1720. return err;
  1721. for (tmp = 0; tmp < 2 && cfg.result.irq_resource[tmp].flags; tmp++)
  1722. if ((err = isapnp_valid_irq(&cfg, tmp))<0)
  1723. return err;
  1724. for (tmp = 0; tmp < 2 && cfg.result.dma_resource[tmp].flags; tmp++)
  1725. if ((err = isapnp_valid_dma(&cfg, tmp))<0)
  1726. return err;
  1727. for (tmp = 0; tmp < 4 && cfg.result.resource[tmp + 8].flags; tmp++)
  1728. if ((err = isapnp_valid_mem(&cfg, tmp))<0)
  1729. return err;
  1730. } while (isapnp_check_valid(&cfg)<0 && fauto++ < 20);
  1731. if (fauto >= 20)
  1732. return -EAGAIN;
  1733.       __skip_auto:
  1734.        /* we have valid configuration, try configure hardware */
  1735.        isapnp_cfg_begin(dev->bus->number, dev->devfn);
  1736. dev->active = 1;
  1737. dev->irq_resource[0] = cfg.result.irq_resource[0];
  1738. dev->irq_resource[1] = cfg.result.irq_resource[1];
  1739. dev->dma_resource[0] = cfg.result.dma_resource[0];
  1740. dev->dma_resource[1] = cfg.result.dma_resource[1];
  1741. for (tmp = 0; tmp < 12; tmp++) {
  1742. dev->resource[tmp] = cfg.result.resource[tmp];
  1743. }
  1744. for (tmp = 0; tmp < 8 && dev->resource[tmp].flags; tmp++)
  1745. isapnp_write_word(ISAPNP_CFG_PORT+(tmp<<1), dev->resource[tmp].start);
  1746. for (tmp = 0; tmp < 2 && dev->irq_resource[tmp].flags; tmp++) {
  1747. int irq = dev->irq_resource[tmp].start;
  1748. if (irq == 2)
  1749. irq = 9;
  1750. isapnp_write_byte(ISAPNP_CFG_IRQ+(tmp<<1), irq);
  1751. }
  1752. for (tmp = 0; tmp < 2 && dev->dma_resource[tmp].flags; tmp++)
  1753. isapnp_write_byte(ISAPNP_CFG_DMA+tmp, dev->dma_resource[tmp].start);
  1754. for (tmp = 0; tmp < 4 && dev->resource[tmp+8].flags; tmp++)
  1755. isapnp_write_word(ISAPNP_CFG_MEM+(tmp<<2), (dev->resource[tmp + 8].start >> 8) & 0xffff);
  1756. isapnp_activate(dev->devfn);
  1757. isapnp_cfg_end();
  1758. return 0;
  1759. }
  1760. static int isapnp_config_deactivate(struct pnp_dev *dev)
  1761. {
  1762. if (!dev || !dev->active)
  1763. return -EINVAL;
  1764.        isapnp_cfg_begin(dev->bus->number, dev->devfn);
  1765. isapnp_deactivate(dev->devfn);
  1766. dev->active = 0;
  1767. isapnp_cfg_end();
  1768. return 0;
  1769. }
  1770. void isapnp_resource_change(struct resource *resource,
  1771.     unsigned long start,
  1772.     unsigned long size)
  1773. {
  1774. if (resource == NULL)
  1775. return;
  1776. resource->flags &= ~IORESOURCE_AUTO;
  1777. resource->start = start;
  1778. resource->end = start + size - 1;
  1779. }
  1780. /*
  1781.  *  Inititialization.
  1782.  */
  1783. #ifdef MODULE
  1784. static void isapnp_free_port(struct isapnp_port *port)
  1785. {
  1786. struct isapnp_port *next;
  1787. while (port) {
  1788. next = port->next;
  1789. kfree(port);
  1790. port = next;
  1791. }
  1792. }
  1793. static void isapnp_free_irq(struct isapnp_irq *irq)
  1794. {
  1795. struct isapnp_irq *next;
  1796. while (irq) {
  1797. next = irq->next;
  1798. kfree(irq);
  1799. irq = next;
  1800. }
  1801. }
  1802. static void isapnp_free_dma(struct isapnp_dma *dma)
  1803. {
  1804. struct isapnp_dma *next;
  1805. while (dma) {
  1806. next = dma->next;
  1807. kfree(dma);
  1808. dma = next;
  1809. }
  1810. }
  1811. static void isapnp_free_mem(struct isapnp_mem *mem)
  1812. {
  1813. struct isapnp_mem *next;
  1814. while (mem) {
  1815. next = mem->next;
  1816. kfree(mem);
  1817. mem = next;
  1818. }
  1819. }
  1820. static void isapnp_free_mem32(struct isapnp_mem32 *mem32)
  1821. {
  1822. struct isapnp_mem32 *next;
  1823. while (mem32) {
  1824. next = mem32->next;
  1825. kfree(mem32);
  1826. mem32 = next;
  1827. }
  1828. }
  1829. static void isapnp_free_resources(struct isapnp_resources *resources, int alt)
  1830. {
  1831. struct isapnp_resources *next;
  1832. while (resources) {
  1833. next = alt ? resources->alt : resources->next;
  1834. isapnp_free_port(resources->port);
  1835. isapnp_free_irq(resources->irq);
  1836. isapnp_free_dma(resources->dma);
  1837. isapnp_free_mem(resources->mem);
  1838. isapnp_free_mem32(resources->mem32);
  1839. if (!alt && resources->alt)
  1840. isapnp_free_resources(resources->alt, 1);
  1841. kfree(resources);
  1842. resources = next;
  1843. }
  1844. }
  1845. static void isapnp_free_device(struct pnp_dev *dev)
  1846. {
  1847. struct pnp_dev *next;
  1848. while (dev) {
  1849. next = dev->sibling;
  1850. isapnp_free_resources((struct isapnp_resources *)dev->sysdata, 0);
  1851. kfree(dev);
  1852. dev = next;
  1853. }
  1854. }
  1855. #endif /* MODULE */
  1856. static void isapnp_free_all_resources(void)
  1857. {
  1858. #ifdef MODULE
  1859. struct pnp_bus *card, *cardnext;
  1860. #endif
  1861. #ifdef ISAPNP_REGION_OK
  1862. // release_resource(pidxr_res);
  1863.         release_region(_PIDXR, 1);
  1864. #endif
  1865. // release_resource(pnpwrp_res);
  1866.         release_region(_PNPWRP, 1);
  1867. if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff)
  1868. // release_resource(isapnp_rdp_res);
  1869. release_region(isapnp_rdp, 1);
  1870. #ifdef MODULE
  1871. for (card = isapnp_cards; card; card = cardnext) {
  1872. cardnext = card->next;
  1873. isapnp_free_device(card->devices);
  1874. kfree(card);
  1875. }
  1876. #ifdef CONFIG_PROC_FS
  1877. isapnp_proc_done();
  1878. #endif
  1879. #endif
  1880. }
  1881. static int __init isapnp_do_reserve_irq(int irq)
  1882. {
  1883. int i;
  1884. if (irq < 0 || irq > 15)
  1885. return -EINVAL;
  1886. for (i = 0; i < 16; i++) {
  1887. if (isapnp_reserve_irq[i] == irq)
  1888. return 0;
  1889. }
  1890. for (i = 0; i < 16; i++) {
  1891. if (isapnp_reserve_irq[i] < 0) {
  1892. isapnp_reserve_irq[i] = irq;
  1893. #ifdef ISAPNP_DEBUG
  1894. printk("IRQ %i is reserved now.n", irq);
  1895. #endif
  1896. return 0;
  1897. }
  1898. }
  1899. return -ENOMEM;
  1900. }
  1901. #ifdef CONFIG_PCI
  1902. struct pnp_dev *
  1903. pnp_find_slot(unsigned int bus, unsigned int devfn)
  1904. {
  1905.         struct pnp_dev *dev;
  1906.         for(dev=isapnp_devices; dev; dev=dev->next)
  1907.                 if (dev->bus->number == bus && dev->devfn == devfn)
  1908.                         break;
  1909.         return dev;
  1910. }
  1911. static void __init isapnp_pci_init(void)
  1912. {
  1913. int devfn;
  1914. struct pnp_dev *dev;
  1915. for (devfn = 0; devfn < 255; devfn++) {
  1916. dev = pnp_find_slot(0, devfn);
  1917. if (dev != NULL)
  1918. break;
  1919. }
  1920. if (dev == NULL)
  1921. return;
  1922. while (dev) {
  1923. #ifdef ISAPNP_DEBUG
  1924. printk("PCI: reserved IRQ: %in", dev->irq);
  1925. #endif
  1926. if (dev->irq > 0)
  1927. isapnp_do_reserve_irq(dev->irq);
  1928. dev = dev->next;
  1929. }
  1930. }
  1931. #endif /* CONFIG_PCI */
  1932. EXPORT_SYMBOL(isapnp_present);
  1933. EXPORT_SYMBOL(isapnp_cfg_begin);
  1934. EXPORT_SYMBOL(isapnp_cfg_end);
  1935. EXPORT_SYMBOL(isapnp_read_byte);
  1936. EXPORT_SYMBOL(isapnp_read_word);
  1937. EXPORT_SYMBOL(isapnp_read_dword);
  1938. EXPORT_SYMBOL(isapnp_write_byte);
  1939. EXPORT_SYMBOL(isapnp_write_word);
  1940. EXPORT_SYMBOL(isapnp_write_dword);
  1941. EXPORT_SYMBOL(isapnp_wake);
  1942. EXPORT_SYMBOL(isapnp_device);
  1943. EXPORT_SYMBOL(isapnp_activate);
  1944. EXPORT_SYMBOL(isapnp_deactivate);
  1945. EXPORT_SYMBOL(isapnp_find_card);
  1946. EXPORT_SYMBOL(isapnp_find_dev);
  1947. EXPORT_SYMBOL(isapnp_resource_change);
  1948. int __init isapnp_init(void)
  1949. {
  1950. int cards;
  1951. struct pnp_bus *card;
  1952. struct pnp_dev *dev;
  1953. if (isapnp_disable) {
  1954. isapnp_detected = 0;
  1955. printk("isapnp: ISA Plug & Play support disabledn");
  1956. return 0;
  1957. }
  1958. #ifdef ISAPNP_REGION_OK
  1959. request_region(_PIDXR, 1, "isapnp index");
  1960. // pidxr_res=request_region(_PIDXR, 1, "isapnp index");
  1961. // if(!pidxr_res) {
  1962. // printk("isapnp: Index Register 0x%x already usedn", _PIDXR);
  1963. // return -EBUSY;
  1964. // }
  1965. #endif
  1966. request_region(_PNPWRP, 1, "isapnp write");
  1967. // pnpwrp_res=request_region(_PNPWRP, 1, "isapnp write");
  1968. // if(!pnpwrp_res) {
  1969. // printk("isapnp: Write Data Register 0x%x already usedn", _PNPWRP);
  1970. // return -EBUSY;
  1971. // }
  1972. /*
  1973.  * Print a message. The existing ISAPnP code is hanging machines
  1974.  * so let the user know where.
  1975.  */
  1976.  
  1977. printk("isapnp: Scanning for Pnp cards...n");
  1978. if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) {
  1979. isapnp_rdp |= 3;
  1980. request_region(isapnp_rdp, 1, "isapnp read");
  1981. // isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read");
  1982. // if(!isapnp_rdp_res) {
  1983. // printk("isapnp: Read Data Register 0x%x already usedn", isapnp_rdp);
  1984. // return -EBUSY;
  1985. // }
  1986. isapnp_set_rdp();
  1987. }
  1988. isapnp_detected = 1;
  1989. if (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff) {
  1990. cards = isapnp_isolate();
  1991. if (cards < 0 || 
  1992.     (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) {
  1993. isapnp_free_all_resources();
  1994. isapnp_detected = 0;
  1995. printk("isapnp: No Plug & Play device foundn");
  1996. return 0;
  1997. }
  1998. request_region(isapnp_rdp, 1, "isapnp read");
  1999. // isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read");
  2000. }
  2001. isapnp_build_device_list();
  2002. cards = 0;
  2003. for (card = isapnp_cards; card; card = card->next)
  2004. cards++;
  2005. if (isapnp_verbose) {
  2006. for (card = isapnp_cards; card; card = card->next) {
  2007. printk( "isapnp: Card '%s'n", card->name[0]?card->name:"Unknown");
  2008. if (isapnp_verbose < 2)
  2009. continue;
  2010. for (dev = card->devices; dev; dev = dev->next)
  2011. printk("isapnp:   Device '%s'n", dev->name[0]?card->name:"Unknown");
  2012. }
  2013. }
  2014. if (cards) {
  2015. printk("isapnp: %i Plug & Play card%s detected totaln", cards, cards>1?"s":"");
  2016. } else {
  2017. printk("isapnp: No Plug & Play card foundn");
  2018. }
  2019. #ifdef CONFIG_PCI
  2020. if (!isapnp_skip_pci_scan)
  2021. isapnp_pci_init();
  2022. #endif
  2023. #ifdef CONFIG_PROC_FS
  2024. isapnp_proc_init();
  2025. #endif
  2026. return 0;
  2027. }
  2028. #ifdef MODULE
  2029. int init_module(void)
  2030. {
  2031. return isapnp_init();
  2032. }
  2033. void cleanup_module(void)
  2034. {
  2035. if (isapnp_detected)
  2036. isapnp_free_all_resources();
  2037. }
  2038. #endif