core.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185
  1. /*
  2. * ISA Plug & Play support
  3. * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
  4. *
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. *
  20. * Changelog:
  21. * 2000-01-01 Added quirks handling for buggy hardware
  22. * Peter Denison <peterd@pnd-pc.demon.co.uk>
  23. * 2000-06-14 Added isapnp_probe_devs() and isapnp_activate_dev()
  24. * Christoph Hellwig <hch@infradead.org>
  25. * 2001-06-03 Added release_region calls to correspond with
  26. * request_region calls when a failure occurs. Also
  27. * added KERN_* constants to printk() calls.
  28. * 2001-11-07 Added isapnp_{,un}register_driver calls along the lines
  29. * of the pci driver interface
  30. * Kai Germaschewski <kai.germaschewski@gmx.de>
  31. * 2002-06-06 Made the use of dma channel 0 configurable
  32. * Gerald Teschl <gerald.teschl@univie.ac.at>
  33. * 2002-10-06 Ported to PnP Layer - Adam Belay <ambx1@neo.rr.com>
  34. * 2003-08-11 Resource Management Updates - Adam Belay <ambx1@neo.rr.com>
  35. */
  36. #include <linux/module.h>
  37. #include <linux/kernel.h>
  38. #include <linux/errno.h>
  39. #include <linux/slab.h>
  40. #include <linux/delay.h>
  41. #include <linux/init.h>
  42. #include <linux/isapnp.h>
  43. #include <linux/mutex.h>
  44. #include <asm/io.h>
  45. #if 0
  46. #define ISAPNP_REGION_OK
  47. #endif
  48. #if 0
  49. #define ISAPNP_DEBUG
  50. #endif
  51. int isapnp_disable; /* Disable ISA PnP */
  52. static int isapnp_rdp; /* Read Data Port */
  53. static int isapnp_reset = 1; /* reset all PnP cards (deactivate) */
  54. static int isapnp_verbose = 1; /* verbose mode */
  55. MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
  56. MODULE_DESCRIPTION("Generic ISA Plug & Play support");
  57. module_param(isapnp_disable, int, 0);
  58. MODULE_PARM_DESC(isapnp_disable, "ISA Plug & Play disable");
  59. module_param(isapnp_rdp, int, 0);
  60. MODULE_PARM_DESC(isapnp_rdp, "ISA Plug & Play read data port");
  61. module_param(isapnp_reset, int, 0);
  62. MODULE_PARM_DESC(isapnp_reset, "ISA Plug & Play reset all cards");
  63. module_param(isapnp_verbose, int, 0);
  64. MODULE_PARM_DESC(isapnp_verbose, "ISA Plug & Play verbose mode");
  65. MODULE_LICENSE("GPL");
  66. #define _PIDXR 0x279
  67. #define _PNPWRP 0xa79
  68. /* short tags */
  69. #define _STAG_PNPVERNO 0x01
  70. #define _STAG_LOGDEVID 0x02
  71. #define _STAG_COMPATDEVID 0x03
  72. #define _STAG_IRQ 0x04
  73. #define _STAG_DMA 0x05
  74. #define _STAG_STARTDEP 0x06
  75. #define _STAG_ENDDEP 0x07
  76. #define _STAG_IOPORT 0x08
  77. #define _STAG_FIXEDIO 0x09
  78. #define _STAG_VENDOR 0x0e
  79. #define _STAG_END 0x0f
  80. /* long tags */
  81. #define _LTAG_MEMRANGE 0x81
  82. #define _LTAG_ANSISTR 0x82
  83. #define _LTAG_UNICODESTR 0x83
  84. #define _LTAG_VENDOR 0x84
  85. #define _LTAG_MEM32RANGE 0x85
  86. #define _LTAG_FIXEDMEM32RANGE 0x86
  87. static unsigned char isapnp_checksum_value;
  88. static DEFINE_MUTEX(isapnp_cfg_mutex);
  89. static int isapnp_detected;
  90. static int isapnp_csn_count;
  91. /* some prototypes */
  92. static inline void write_data(unsigned char x)
  93. {
  94. outb(x, _PNPWRP);
  95. }
  96. static inline void write_address(unsigned char x)
  97. {
  98. outb(x, _PIDXR);
  99. udelay(20);
  100. }
  101. static inline unsigned char read_data(void)
  102. {
  103. unsigned char val = inb(isapnp_rdp);
  104. return val;
  105. }
  106. unsigned char isapnp_read_byte(unsigned char idx)
  107. {
  108. write_address(idx);
  109. return read_data();
  110. }
  111. static unsigned short isapnp_read_word(unsigned char idx)
  112. {
  113. unsigned short val;
  114. val = isapnp_read_byte(idx);
  115. val = (val << 8) + isapnp_read_byte(idx + 1);
  116. return val;
  117. }
  118. void isapnp_write_byte(unsigned char idx, unsigned char val)
  119. {
  120. write_address(idx);
  121. write_data(val);
  122. }
  123. static void isapnp_write_word(unsigned char idx, unsigned short val)
  124. {
  125. isapnp_write_byte(idx, val >> 8);
  126. isapnp_write_byte(idx + 1, val);
  127. }
  128. static void isapnp_key(void)
  129. {
  130. unsigned char code = 0x6a, msb;
  131. int i;
  132. mdelay(1);
  133. write_address(0x00);
  134. write_address(0x00);
  135. write_address(code);
  136. for (i = 1; i < 32; i++) {
  137. msb = ((code & 0x01) ^ ((code & 0x02) >> 1)) << 7;
  138. code = (code >> 1) | msb;
  139. write_address(code);
  140. }
  141. }
  142. /* place all pnp cards in wait-for-key state */
  143. static void isapnp_wait(void)
  144. {
  145. isapnp_write_byte(0x02, 0x02);
  146. }
  147. static void isapnp_wake(unsigned char csn)
  148. {
  149. isapnp_write_byte(0x03, csn);
  150. }
  151. static void isapnp_device(unsigned char logdev)
  152. {
  153. isapnp_write_byte(0x07, logdev);
  154. }
  155. static void isapnp_activate(unsigned char logdev)
  156. {
  157. isapnp_device(logdev);
  158. isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 1);
  159. udelay(250);
  160. }
  161. static void isapnp_deactivate(unsigned char logdev)
  162. {
  163. isapnp_device(logdev);
  164. isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 0);
  165. udelay(500);
  166. }
  167. static void __init isapnp_peek(unsigned char *data, int bytes)
  168. {
  169. int i, j;
  170. unsigned char d = 0;
  171. for (i = 1; i <= bytes; i++) {
  172. for (j = 0; j < 20; j++) {
  173. d = isapnp_read_byte(0x05);
  174. if (d & 1)
  175. break;
  176. udelay(100);
  177. }
  178. if (!(d & 1)) {
  179. if (data != NULL)
  180. *data++ = 0xff;
  181. continue;
  182. }
  183. d = isapnp_read_byte(0x04); /* PRESDI */
  184. isapnp_checksum_value += d;
  185. if (data != NULL)
  186. *data++ = d;
  187. }
  188. }
  189. #define RDP_STEP 32 /* minimum is 4 */
  190. static int isapnp_next_rdp(void)
  191. {
  192. int rdp = isapnp_rdp;
  193. static int old_rdp = 0;
  194. if (old_rdp) {
  195. release_region(old_rdp, 1);
  196. old_rdp = 0;
  197. }
  198. while (rdp <= 0x3ff) {
  199. /*
  200. * We cannot use NE2000 probe spaces for ISAPnP or we
  201. * will lock up machines.
  202. */
  203. if ((rdp < 0x280 || rdp > 0x380)
  204. && request_region(rdp, 1, "ISAPnP")) {
  205. isapnp_rdp = rdp;
  206. old_rdp = rdp;
  207. return 0;
  208. }
  209. rdp += RDP_STEP;
  210. }
  211. return -1;
  212. }
  213. /* Set read port address */
  214. static inline void isapnp_set_rdp(void)
  215. {
  216. isapnp_write_byte(0x00, isapnp_rdp >> 2);
  217. udelay(100);
  218. }
  219. /*
  220. * Perform an isolation. The port selection code now tries to avoid
  221. * "dangerous to read" ports.
  222. */
  223. static int __init isapnp_isolate_rdp_select(void)
  224. {
  225. isapnp_wait();
  226. isapnp_key();
  227. /* Control: reset CSN and conditionally everything else too */
  228. isapnp_write_byte(0x02, isapnp_reset ? 0x05 : 0x04);
  229. mdelay(2);
  230. isapnp_wait();
  231. isapnp_key();
  232. isapnp_wake(0x00);
  233. if (isapnp_next_rdp() < 0) {
  234. isapnp_wait();
  235. return -1;
  236. }
  237. isapnp_set_rdp();
  238. udelay(1000);
  239. write_address(0x01);
  240. udelay(1000);
  241. return 0;
  242. }
  243. /*
  244. * Isolate (assign uniqued CSN) to all ISA PnP devices.
  245. */
  246. static int __init isapnp_isolate(void)
  247. {
  248. unsigned char checksum = 0x6a;
  249. unsigned char chksum = 0x00;
  250. unsigned char bit = 0x00;
  251. int data;
  252. int csn = 0;
  253. int i;
  254. int iteration = 1;
  255. isapnp_rdp = 0x213;
  256. if (isapnp_isolate_rdp_select() < 0)
  257. return -1;
  258. while (1) {
  259. for (i = 1; i <= 64; i++) {
  260. data = read_data() << 8;
  261. udelay(250);
  262. data = data | read_data();
  263. udelay(250);
  264. if (data == 0x55aa)
  265. bit = 0x01;
  266. checksum =
  267. ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7)
  268. | (checksum >> 1);
  269. bit = 0x00;
  270. }
  271. for (i = 65; i <= 72; i++) {
  272. data = read_data() << 8;
  273. udelay(250);
  274. data = data | read_data();
  275. udelay(250);
  276. if (data == 0x55aa)
  277. chksum |= (1 << (i - 65));
  278. }
  279. if (checksum != 0x00 && checksum == chksum) {
  280. csn++;
  281. isapnp_write_byte(0x06, csn);
  282. udelay(250);
  283. iteration++;
  284. isapnp_wake(0x00);
  285. isapnp_set_rdp();
  286. udelay(1000);
  287. write_address(0x01);
  288. udelay(1000);
  289. goto __next;
  290. }
  291. if (iteration == 1) {
  292. isapnp_rdp += RDP_STEP;
  293. if (isapnp_isolate_rdp_select() < 0)
  294. return -1;
  295. } else if (iteration > 1) {
  296. break;
  297. }
  298. __next:
  299. if (csn == 255)
  300. break;
  301. checksum = 0x6a;
  302. chksum = 0x00;
  303. bit = 0x00;
  304. }
  305. isapnp_wait();
  306. isapnp_csn_count = csn;
  307. return csn;
  308. }
  309. /*
  310. * Read one tag from stream.
  311. */
  312. static int __init isapnp_read_tag(unsigned char *type, unsigned short *size)
  313. {
  314. unsigned char tag, tmp[2];
  315. isapnp_peek(&tag, 1);
  316. if (tag == 0) /* invalid tag */
  317. return -1;
  318. if (tag & 0x80) { /* large item */
  319. *type = tag;
  320. isapnp_peek(tmp, 2);
  321. *size = (tmp[1] << 8) | tmp[0];
  322. } else {
  323. *type = (tag >> 3) & 0x0f;
  324. *size = tag & 0x07;
  325. }
  326. #if 0
  327. printk(KERN_DEBUG "tag = 0x%x, type = 0x%x, size = %i\n", tag, *type,
  328. *size);
  329. #endif
  330. if (*type == 0xff && *size == 0xffff) /* probably invalid data */
  331. return -1;
  332. return 0;
  333. }
  334. /*
  335. * Skip specified number of bytes from stream.
  336. */
  337. static void __init isapnp_skip_bytes(int count)
  338. {
  339. isapnp_peek(NULL, count);
  340. }
  341. /*
  342. * Parse EISA id.
  343. */
  344. static void isapnp_parse_id(struct pnp_dev *dev, unsigned short vendor,
  345. unsigned short device)
  346. {
  347. struct pnp_id *id;
  348. if (!dev)
  349. return;
  350. id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
  351. if (!id)
  352. return;
  353. sprintf(id->id, "%c%c%c%x%x%x%x",
  354. 'A' + ((vendor >> 2) & 0x3f) - 1,
  355. 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1,
  356. 'A' + ((vendor >> 8) & 0x1f) - 1,
  357. (device >> 4) & 0x0f,
  358. device & 0x0f, (device >> 12) & 0x0f, (device >> 8) & 0x0f);
  359. pnp_add_id(id, dev);
  360. }
  361. /*
  362. * Parse logical device tag.
  363. */
  364. static struct pnp_dev *__init isapnp_parse_device(struct pnp_card *card,
  365. int size, int number)
  366. {
  367. unsigned char tmp[6];
  368. struct pnp_dev *dev;
  369. isapnp_peek(tmp, size);
  370. dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL);
  371. if (!dev)
  372. return NULL;
  373. dev->number = number;
  374. isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0], (tmp[3] << 8) | tmp[2]);
  375. dev->regs = tmp[4];
  376. dev->card = card;
  377. if (size > 5)
  378. dev->regs |= tmp[5] << 8;
  379. dev->protocol = &isapnp_protocol;
  380. dev->capabilities |= PNP_CONFIGURABLE;
  381. dev->capabilities |= PNP_READ;
  382. dev->capabilities |= PNP_WRITE;
  383. dev->capabilities |= PNP_DISABLE;
  384. pnp_init_resource_table(&dev->res);
  385. return dev;
  386. }
  387. /*
  388. * Add IRQ resource to resources list.
  389. */
  390. static void __init isapnp_parse_irq_resource(struct pnp_option *option,
  391. int size)
  392. {
  393. unsigned char tmp[3];
  394. struct pnp_irq *irq;
  395. unsigned long bits;
  396. isapnp_peek(tmp, size);
  397. irq = kzalloc(sizeof(struct pnp_irq), GFP_KERNEL);
  398. if (!irq)
  399. return;
  400. bits = (tmp[1] << 8) | tmp[0];
  401. bitmap_copy(irq->map, &bits, 16);
  402. if (size > 2)
  403. irq->flags = tmp[2];
  404. else
  405. irq->flags = IORESOURCE_IRQ_HIGHEDGE;
  406. pnp_register_irq_resource(option, irq);
  407. }
  408. /*
  409. * Add DMA resource to resources list.
  410. */
  411. static void __init isapnp_parse_dma_resource(struct pnp_option *option,
  412. int size)
  413. {
  414. unsigned char tmp[2];
  415. struct pnp_dma *dma;
  416. isapnp_peek(tmp, size);
  417. dma = kzalloc(sizeof(struct pnp_dma), GFP_KERNEL);
  418. if (!dma)
  419. return;
  420. dma->map = tmp[0];
  421. dma->flags = tmp[1];
  422. pnp_register_dma_resource(option, dma);
  423. }
  424. /*
  425. * Add port resource to resources list.
  426. */
  427. static void __init isapnp_parse_port_resource(struct pnp_option *option,
  428. int size)
  429. {
  430. unsigned char tmp[7];
  431. struct pnp_port *port;
  432. isapnp_peek(tmp, size);
  433. port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
  434. if (!port)
  435. return;
  436. port->min = (tmp[2] << 8) | tmp[1];
  437. port->max = (tmp[4] << 8) | tmp[3];
  438. port->align = tmp[5];
  439. port->size = tmp[6];
  440. port->flags = tmp[0] ? PNP_PORT_FLAG_16BITADDR : 0;
  441. pnp_register_port_resource(option, port);
  442. }
  443. /*
  444. * Add fixed port resource to resources list.
  445. */
  446. static void __init isapnp_parse_fixed_port_resource(struct pnp_option *option,
  447. int size)
  448. {
  449. unsigned char tmp[3];
  450. struct pnp_port *port;
  451. isapnp_peek(tmp, size);
  452. port = kzalloc(sizeof(struct pnp_port), GFP_KERNEL);
  453. if (!port)
  454. return;
  455. port->min = port->max = (tmp[1] << 8) | tmp[0];
  456. port->size = tmp[2];
  457. port->align = 0;
  458. port->flags = PNP_PORT_FLAG_FIXED;
  459. pnp_register_port_resource(option, port);
  460. }
  461. /*
  462. * Add memory resource to resources list.
  463. */
  464. static void __init isapnp_parse_mem_resource(struct pnp_option *option,
  465. int size)
  466. {
  467. unsigned char tmp[9];
  468. struct pnp_mem *mem;
  469. isapnp_peek(tmp, size);
  470. mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
  471. if (!mem)
  472. return;
  473. mem->min = ((tmp[2] << 8) | tmp[1]) << 8;
  474. mem->max = ((tmp[4] << 8) | tmp[3]) << 8;
  475. mem->align = (tmp[6] << 8) | tmp[5];
  476. mem->size = ((tmp[8] << 8) | tmp[7]) << 8;
  477. mem->flags = tmp[0];
  478. pnp_register_mem_resource(option, mem);
  479. }
  480. /*
  481. * Add 32-bit memory resource to resources list.
  482. */
  483. static void __init isapnp_parse_mem32_resource(struct pnp_option *option,
  484. int size)
  485. {
  486. unsigned char tmp[17];
  487. struct pnp_mem *mem;
  488. isapnp_peek(tmp, size);
  489. mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
  490. if (!mem)
  491. return;
  492. mem->min = (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
  493. mem->max = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
  494. mem->align =
  495. (tmp[12] << 24) | (tmp[11] << 16) | (tmp[10] << 8) | tmp[9];
  496. mem->size =
  497. (tmp[16] << 24) | (tmp[15] << 16) | (tmp[14] << 8) | tmp[13];
  498. mem->flags = tmp[0];
  499. pnp_register_mem_resource(option, mem);
  500. }
  501. /*
  502. * Add 32-bit fixed memory resource to resources list.
  503. */
  504. static void __init isapnp_parse_fixed_mem32_resource(struct pnp_option *option,
  505. int size)
  506. {
  507. unsigned char tmp[9];
  508. struct pnp_mem *mem;
  509. isapnp_peek(tmp, size);
  510. mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL);
  511. if (!mem)
  512. return;
  513. mem->min = mem->max =
  514. (tmp[4] << 24) | (tmp[3] << 16) | (tmp[2] << 8) | tmp[1];
  515. mem->size = (tmp[8] << 24) | (tmp[7] << 16) | (tmp[6] << 8) | tmp[5];
  516. mem->align = 0;
  517. mem->flags = tmp[0];
  518. pnp_register_mem_resource(option, mem);
  519. }
  520. /*
  521. * Parse card name for ISA PnP device.
  522. */
  523. static void __init
  524. isapnp_parse_name(char *name, unsigned int name_max, unsigned short *size)
  525. {
  526. if (name[0] == '\0') {
  527. unsigned short size1 =
  528. *size >= name_max ? (name_max - 1) : *size;
  529. isapnp_peek(name, size1);
  530. name[size1] = '\0';
  531. *size -= size1;
  532. /* clean whitespace from end of string */
  533. while (size1 > 0 && name[--size1] == ' ')
  534. name[size1] = '\0';
  535. }
  536. }
  537. /*
  538. * Parse resource map for logical device.
  539. */
  540. static int __init isapnp_create_device(struct pnp_card *card,
  541. unsigned short size)
  542. {
  543. int number = 0, skip = 0, priority = 0, compat = 0;
  544. unsigned char type, tmp[17];
  545. struct pnp_option *option;
  546. struct pnp_dev *dev;
  547. if ((dev = isapnp_parse_device(card, size, number++)) == NULL)
  548. return 1;
  549. option = pnp_register_independent_option(dev);
  550. if (!option) {
  551. kfree(dev);
  552. return 1;
  553. }
  554. pnp_add_card_device(card, dev);
  555. while (1) {
  556. if (isapnp_read_tag(&type, &size) < 0)
  557. return 1;
  558. if (skip && type != _STAG_LOGDEVID && type != _STAG_END)
  559. goto __skip;
  560. switch (type) {
  561. case _STAG_LOGDEVID:
  562. if (size >= 5 && size <= 6) {
  563. if ((dev =
  564. isapnp_parse_device(card, size,
  565. number++)) == NULL)
  566. return 1;
  567. size = 0;
  568. skip = 0;
  569. option = pnp_register_independent_option(dev);
  570. if (!option) {
  571. kfree(dev);
  572. return 1;
  573. }
  574. pnp_add_card_device(card, dev);
  575. } else {
  576. skip = 1;
  577. }
  578. priority = 0;
  579. compat = 0;
  580. break;
  581. case _STAG_COMPATDEVID:
  582. if (size == 4 && compat < DEVICE_COUNT_COMPATIBLE) {
  583. isapnp_peek(tmp, 4);
  584. isapnp_parse_id(dev, (tmp[1] << 8) | tmp[0],
  585. (tmp[3] << 8) | tmp[2]);
  586. compat++;
  587. size = 0;
  588. }
  589. break;
  590. case _STAG_IRQ:
  591. if (size < 2 || size > 3)
  592. goto __skip;
  593. isapnp_parse_irq_resource(option, size);
  594. size = 0;
  595. break;
  596. case _STAG_DMA:
  597. if (size != 2)
  598. goto __skip;
  599. isapnp_parse_dma_resource(option, size);
  600. size = 0;
  601. break;
  602. case _STAG_STARTDEP:
  603. if (size > 1)
  604. goto __skip;
  605. priority = 0x100 | PNP_RES_PRIORITY_ACCEPTABLE;
  606. if (size > 0) {
  607. isapnp_peek(tmp, size);
  608. priority = 0x100 | tmp[0];
  609. size = 0;
  610. }
  611. option = pnp_register_dependent_option(dev, priority);
  612. if (!option)
  613. return 1;
  614. break;
  615. case _STAG_ENDDEP:
  616. if (size != 0)
  617. goto __skip;
  618. priority = 0;
  619. break;
  620. case _STAG_IOPORT:
  621. if (size != 7)
  622. goto __skip;
  623. isapnp_parse_port_resource(option, size);
  624. size = 0;
  625. break;
  626. case _STAG_FIXEDIO:
  627. if (size != 3)
  628. goto __skip;
  629. isapnp_parse_fixed_port_resource(option, size);
  630. size = 0;
  631. break;
  632. case _STAG_VENDOR:
  633. break;
  634. case _LTAG_MEMRANGE:
  635. if (size != 9)
  636. goto __skip;
  637. isapnp_parse_mem_resource(option, size);
  638. size = 0;
  639. break;
  640. case _LTAG_ANSISTR:
  641. isapnp_parse_name(dev->name, sizeof(dev->name), &size);
  642. break;
  643. case _LTAG_UNICODESTR:
  644. /* silently ignore */
  645. /* who use unicode for hardware identification? */
  646. break;
  647. case _LTAG_VENDOR:
  648. break;
  649. case _LTAG_MEM32RANGE:
  650. if (size != 17)
  651. goto __skip;
  652. isapnp_parse_mem32_resource(option, size);
  653. size = 0;
  654. break;
  655. case _LTAG_FIXEDMEM32RANGE:
  656. if (size != 9)
  657. goto __skip;
  658. isapnp_parse_fixed_mem32_resource(option, size);
  659. size = 0;
  660. break;
  661. case _STAG_END:
  662. if (size > 0)
  663. isapnp_skip_bytes(size);
  664. return 1;
  665. default:
  666. printk(KERN_ERR
  667. "isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n",
  668. type, dev->number, card->number);
  669. }
  670. __skip:
  671. if (size > 0)
  672. isapnp_skip_bytes(size);
  673. }
  674. return 0;
  675. }
  676. /*
  677. * Parse resource map for ISA PnP card.
  678. */
  679. static void __init isapnp_parse_resource_map(struct pnp_card *card)
  680. {
  681. unsigned char type, tmp[17];
  682. unsigned short size;
  683. while (1) {
  684. if (isapnp_read_tag(&type, &size) < 0)
  685. return;
  686. switch (type) {
  687. case _STAG_PNPVERNO:
  688. if (size != 2)
  689. goto __skip;
  690. isapnp_peek(tmp, 2);
  691. card->pnpver = tmp[0];
  692. card->productver = tmp[1];
  693. size = 0;
  694. break;
  695. case _STAG_LOGDEVID:
  696. if (size >= 5 && size <= 6) {
  697. if (isapnp_create_device(card, size) == 1)
  698. return;
  699. size = 0;
  700. }
  701. break;
  702. case _STAG_VENDOR:
  703. break;
  704. case _LTAG_ANSISTR:
  705. isapnp_parse_name(card->name, sizeof(card->name),
  706. &size);
  707. break;
  708. case _LTAG_UNICODESTR:
  709. /* silently ignore */
  710. /* who use unicode for hardware identification? */
  711. break;
  712. case _LTAG_VENDOR:
  713. break;
  714. case _STAG_END:
  715. if (size > 0)
  716. isapnp_skip_bytes(size);
  717. return;
  718. default:
  719. printk(KERN_ERR
  720. "isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n",
  721. type, card->number);
  722. }
  723. __skip:
  724. if (size > 0)
  725. isapnp_skip_bytes(size);
  726. }
  727. }
  728. /*
  729. * Compute ISA PnP checksum for first eight bytes.
  730. */
  731. static unsigned char __init isapnp_checksum(unsigned char *data)
  732. {
  733. int i, j;
  734. unsigned char checksum = 0x6a, bit, b;
  735. for (i = 0; i < 8; i++) {
  736. b = data[i];
  737. for (j = 0; j < 8; j++) {
  738. bit = 0;
  739. if (b & (1 << j))
  740. bit = 1;
  741. checksum =
  742. ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7)
  743. | (checksum >> 1);
  744. }
  745. }
  746. return checksum;
  747. }
  748. /*
  749. * Parse EISA id for ISA PnP card.
  750. */
  751. static void isapnp_parse_card_id(struct pnp_card *card, unsigned short vendor,
  752. unsigned short device)
  753. {
  754. struct pnp_id *id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
  755. if (!id)
  756. return;
  757. sprintf(id->id, "%c%c%c%x%x%x%x",
  758. 'A' + ((vendor >> 2) & 0x3f) - 1,
  759. 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1,
  760. 'A' + ((vendor >> 8) & 0x1f) - 1,
  761. (device >> 4) & 0x0f,
  762. device & 0x0f, (device >> 12) & 0x0f, (device >> 8) & 0x0f);
  763. pnp_add_card_id(id, card);
  764. }
  765. /*
  766. * Build device list for all present ISA PnP devices.
  767. */
  768. static int __init isapnp_build_device_list(void)
  769. {
  770. int csn;
  771. unsigned char header[9], checksum;
  772. struct pnp_card *card;
  773. isapnp_wait();
  774. isapnp_key();
  775. for (csn = 1; csn <= isapnp_csn_count; csn++) {
  776. isapnp_wake(csn);
  777. isapnp_peek(header, 9);
  778. checksum = isapnp_checksum(header);
  779. #if 0
  780. printk(KERN_DEBUG
  781. "vendor: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
  782. header[0], header[1], header[2], header[3], header[4],
  783. header[5], header[6], header[7], header[8]);
  784. printk(KERN_DEBUG "checksum = 0x%x\n", checksum);
  785. #endif
  786. if ((card =
  787. kzalloc(sizeof(struct pnp_card), GFP_KERNEL)) == NULL)
  788. continue;
  789. card->number = csn;
  790. INIT_LIST_HEAD(&card->devices);
  791. isapnp_parse_card_id(card, (header[1] << 8) | header[0],
  792. (header[3] << 8) | header[2]);
  793. card->serial =
  794. (header[7] << 24) | (header[6] << 16) | (header[5] << 8) |
  795. header[4];
  796. isapnp_checksum_value = 0x00;
  797. isapnp_parse_resource_map(card);
  798. if (isapnp_checksum_value != 0x00)
  799. printk(KERN_ERR
  800. "isapnp: checksum for device %i is not valid (0x%x)\n",
  801. csn, isapnp_checksum_value);
  802. card->checksum = isapnp_checksum_value;
  803. card->protocol = &isapnp_protocol;
  804. pnp_add_card(card);
  805. }
  806. isapnp_wait();
  807. return 0;
  808. }
  809. /*
  810. * Basic configuration routines.
  811. */
  812. int isapnp_present(void)
  813. {
  814. struct pnp_card *card;
  815. pnp_for_each_card(card) {
  816. if (card->protocol == &isapnp_protocol)
  817. return 1;
  818. }
  819. return 0;
  820. }
  821. int isapnp_cfg_begin(int csn, int logdev)
  822. {
  823. if (csn < 1 || csn > isapnp_csn_count || logdev > 10)
  824. return -EINVAL;
  825. mutex_lock(&isapnp_cfg_mutex);
  826. isapnp_wait();
  827. isapnp_key();
  828. isapnp_wake(csn);
  829. #if 0
  830. /* to avoid malfunction when the isapnptools package is used */
  831. /* we must set RDP to our value again */
  832. /* it is possible to set RDP only in the isolation phase */
  833. /* Jens Thoms Toerring <Jens.Toerring@physik.fu-berlin.de> */
  834. isapnp_write_byte(0x02, 0x04); /* clear CSN of card */
  835. mdelay(2); /* is this necessary? */
  836. isapnp_wake(csn); /* bring card into sleep state */
  837. isapnp_wake(0); /* bring card into isolation state */
  838. isapnp_set_rdp(); /* reset the RDP port */
  839. udelay(1000); /* delay 1000us */
  840. isapnp_write_byte(0x06, csn); /* reset CSN to previous value */
  841. udelay(250); /* is this necessary? */
  842. #endif
  843. if (logdev >= 0)
  844. isapnp_device(logdev);
  845. return 0;
  846. }
  847. int isapnp_cfg_end(void)
  848. {
  849. isapnp_wait();
  850. mutex_unlock(&isapnp_cfg_mutex);
  851. return 0;
  852. }
  853. /*
  854. * Initialization.
  855. */
  856. EXPORT_SYMBOL(isapnp_protocol);
  857. EXPORT_SYMBOL(isapnp_present);
  858. EXPORT_SYMBOL(isapnp_cfg_begin);
  859. EXPORT_SYMBOL(isapnp_cfg_end);
  860. #if 0
  861. EXPORT_SYMBOL(isapnp_read_byte);
  862. #endif
  863. EXPORT_SYMBOL(isapnp_write_byte);
  864. static int isapnp_read_resources(struct pnp_dev *dev,
  865. struct pnp_resource_table *res)
  866. {
  867. int tmp, ret;
  868. dev->active = isapnp_read_byte(ISAPNP_CFG_ACTIVATE);
  869. if (dev->active) {
  870. for (tmp = 0; tmp < PNP_MAX_PORT; tmp++) {
  871. ret = isapnp_read_word(ISAPNP_CFG_PORT + (tmp << 1));
  872. if (!ret)
  873. continue;
  874. res->port_resource[tmp].start = ret;
  875. res->port_resource[tmp].flags = IORESOURCE_IO;
  876. }
  877. for (tmp = 0; tmp < PNP_MAX_MEM; tmp++) {
  878. ret =
  879. isapnp_read_word(ISAPNP_CFG_MEM + (tmp << 3)) << 8;
  880. if (!ret)
  881. continue;
  882. res->mem_resource[tmp].start = ret;
  883. res->mem_resource[tmp].flags = IORESOURCE_MEM;
  884. }
  885. for (tmp = 0; tmp < PNP_MAX_IRQ; tmp++) {
  886. ret =
  887. (isapnp_read_word(ISAPNP_CFG_IRQ + (tmp << 1)) >>
  888. 8);
  889. if (!ret)
  890. continue;
  891. res->irq_resource[tmp].start =
  892. res->irq_resource[tmp].end = ret;
  893. res->irq_resource[tmp].flags = IORESOURCE_IRQ;
  894. }
  895. for (tmp = 0; tmp < PNP_MAX_DMA; tmp++) {
  896. ret = isapnp_read_byte(ISAPNP_CFG_DMA + tmp);
  897. if (ret == 4)
  898. continue;
  899. res->dma_resource[tmp].start =
  900. res->dma_resource[tmp].end = ret;
  901. res->dma_resource[tmp].flags = IORESOURCE_DMA;
  902. }
  903. }
  904. return 0;
  905. }
  906. static int isapnp_get_resources(struct pnp_dev *dev,
  907. struct pnp_resource_table *res)
  908. {
  909. int ret;
  910. pnp_init_resource_table(res);
  911. isapnp_cfg_begin(dev->card->number, dev->number);
  912. ret = isapnp_read_resources(dev, res);
  913. isapnp_cfg_end();
  914. return ret;
  915. }
  916. static int isapnp_set_resources(struct pnp_dev *dev,
  917. struct pnp_resource_table *res)
  918. {
  919. int tmp;
  920. isapnp_cfg_begin(dev->card->number, dev->number);
  921. dev->active = 1;
  922. for (tmp = 0;
  923. tmp < PNP_MAX_PORT
  924. && (res->port_resource[tmp].
  925. flags & (IORESOURCE_IO | IORESOURCE_UNSET)) == IORESOURCE_IO;
  926. tmp++)
  927. isapnp_write_word(ISAPNP_CFG_PORT + (tmp << 1),
  928. res->port_resource[tmp].start);
  929. for (tmp = 0;
  930. tmp < PNP_MAX_IRQ
  931. && (res->irq_resource[tmp].
  932. flags & (IORESOURCE_IRQ | IORESOURCE_UNSET)) == IORESOURCE_IRQ;
  933. tmp++) {
  934. int irq = res->irq_resource[tmp].start;
  935. if (irq == 2)
  936. irq = 9;
  937. isapnp_write_byte(ISAPNP_CFG_IRQ + (tmp << 1), irq);
  938. }
  939. for (tmp = 0;
  940. tmp < PNP_MAX_DMA
  941. && (res->dma_resource[tmp].
  942. flags & (IORESOURCE_DMA | IORESOURCE_UNSET)) == IORESOURCE_DMA;
  943. tmp++)
  944. isapnp_write_byte(ISAPNP_CFG_DMA + tmp,
  945. res->dma_resource[tmp].start);
  946. for (tmp = 0;
  947. tmp < PNP_MAX_MEM
  948. && (res->mem_resource[tmp].
  949. flags & (IORESOURCE_MEM | IORESOURCE_UNSET)) == IORESOURCE_MEM;
  950. tmp++)
  951. isapnp_write_word(ISAPNP_CFG_MEM + (tmp << 3),
  952. (res->mem_resource[tmp].start >> 8) & 0xffff);
  953. /* FIXME: We aren't handling 32bit mems properly here */
  954. isapnp_activate(dev->number);
  955. isapnp_cfg_end();
  956. return 0;
  957. }
  958. static int isapnp_disable_resources(struct pnp_dev *dev)
  959. {
  960. if (!dev || !dev->active)
  961. return -EINVAL;
  962. isapnp_cfg_begin(dev->card->number, dev->number);
  963. isapnp_deactivate(dev->number);
  964. dev->active = 0;
  965. isapnp_cfg_end();
  966. return 0;
  967. }
  968. struct pnp_protocol isapnp_protocol = {
  969. .name = "ISA Plug and Play",
  970. .get = isapnp_get_resources,
  971. .set = isapnp_set_resources,
  972. .disable = isapnp_disable_resources,
  973. };
  974. static int __init isapnp_init(void)
  975. {
  976. int cards;
  977. struct pnp_card *card;
  978. struct pnp_dev *dev;
  979. if (isapnp_disable) {
  980. isapnp_detected = 0;
  981. printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n");
  982. return 0;
  983. }
  984. #ifdef CONFIG_PPC_MERGE
  985. if (check_legacy_ioport(_PIDXR) || check_legacy_ioport(_PNPWRP))
  986. return -EINVAL;
  987. #endif
  988. #ifdef ISAPNP_REGION_OK
  989. if (!request_region(_PIDXR, 1, "isapnp index")) {
  990. printk(KERN_ERR "isapnp: Index Register 0x%x already used\n",
  991. _PIDXR);
  992. return -EBUSY;
  993. }
  994. #endif
  995. if (!request_region(_PNPWRP, 1, "isapnp write")) {
  996. printk(KERN_ERR
  997. "isapnp: Write Data Register 0x%x already used\n",
  998. _PNPWRP);
  999. #ifdef ISAPNP_REGION_OK
  1000. release_region(_PIDXR, 1);
  1001. #endif
  1002. return -EBUSY;
  1003. }
  1004. if (pnp_register_protocol(&isapnp_protocol) < 0)
  1005. return -EBUSY;
  1006. /*
  1007. * Print a message. The existing ISAPnP code is hanging machines
  1008. * so let the user know where.
  1009. */
  1010. printk(KERN_INFO "isapnp: Scanning for PnP cards...\n");
  1011. if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) {
  1012. isapnp_rdp |= 3;
  1013. if (!request_region(isapnp_rdp, 1, "isapnp read")) {
  1014. printk(KERN_ERR
  1015. "isapnp: Read Data Register 0x%x already used\n",
  1016. isapnp_rdp);
  1017. #ifdef ISAPNP_REGION_OK
  1018. release_region(_PIDXR, 1);
  1019. #endif
  1020. release_region(_PNPWRP, 1);
  1021. return -EBUSY;
  1022. }
  1023. isapnp_set_rdp();
  1024. }
  1025. isapnp_detected = 1;
  1026. if (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff) {
  1027. cards = isapnp_isolate();
  1028. if (cards < 0 || (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) {
  1029. #ifdef ISAPNP_REGION_OK
  1030. release_region(_PIDXR, 1);
  1031. #endif
  1032. release_region(_PNPWRP, 1);
  1033. isapnp_detected = 0;
  1034. printk(KERN_INFO
  1035. "isapnp: No Plug & Play device found\n");
  1036. return 0;
  1037. }
  1038. request_region(isapnp_rdp, 1, "isapnp read");
  1039. }
  1040. isapnp_build_device_list();
  1041. cards = 0;
  1042. protocol_for_each_card(&isapnp_protocol, card) {
  1043. cards++;
  1044. if (isapnp_verbose) {
  1045. printk(KERN_INFO "isapnp: Card '%s'\n",
  1046. card->name[0] ? card->name : "Unknown");
  1047. if (isapnp_verbose < 2)
  1048. continue;
  1049. card_for_each_dev(card, dev) {
  1050. printk(KERN_INFO "isapnp: Device '%s'\n",
  1051. dev->name[0] ? dev->name : "Unknown");
  1052. }
  1053. }
  1054. }
  1055. if (cards) {
  1056. printk(KERN_INFO
  1057. "isapnp: %i Plug & Play card%s detected total\n", cards,
  1058. cards > 1 ? "s" : "");
  1059. } else {
  1060. printk(KERN_INFO "isapnp: No Plug & Play card found\n");
  1061. }
  1062. isapnp_proc_init();
  1063. return 0;
  1064. }
  1065. device_initcall(isapnp_init);
  1066. /* format is: noisapnp */
  1067. static int __init isapnp_setup_disable(char *str)
  1068. {
  1069. isapnp_disable = 1;
  1070. return 1;
  1071. }
  1072. __setup("noisapnp", isapnp_setup_disable);
  1073. /* format is: isapnp=rdp,reset,skip_pci_scan,verbose */
  1074. static int __init isapnp_setup_isapnp(char *str)
  1075. {
  1076. (void)((get_option(&str, &isapnp_rdp) == 2) &&
  1077. (get_option(&str, &isapnp_reset) == 2) &&
  1078. (get_option(&str, &isapnp_verbose) == 2));
  1079. return 1;
  1080. }
  1081. __setup("isapnp=", isapnp_setup_isapnp);