PageRenderTime 75ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/kernel_modules_drivers/gesytec-2.08/lpclinux.c

https://github.com/karlhiramoto/lon4linux
C | 1236 lines | 925 code | 125 blank | 186 comment | 116 complexity | bae46ec9bdb98fe4a5e56ac4c3fd9fe7 MD5 | raw file
  1. /*
  2. * lpclinux.c
  3. *
  4. * Driver for "state of the art" LonWorks interfaces
  5. * Version 1.02b, Apr 2004
  6. * based on the generic LPC/LPP driver written by Ralf Feiland
  7. *
  8. * History:
  9. * Nov 1998 - Implementation of the generic driver
  10. * Mar 1999 - Windows CE driver based on the generic driver released
  11. * Mar 2000 - First beta release (0.90) of the linux driver
  12. * Jun 2000 - Beta release 0.91 bugfixed with IRQ sharing and module parameters
  13. * Oct 2000 - Beta release 0.92 with protocol analyzer interface (Watcher)
  14. * Aug 2002 - Release 1.00 running also on Linux 2.4
  15. * Jan 2003 - Release 1.01 bugfixed in driver unload,
  16. * optional ISA HW check at load time (CHECK_ISA_AT_LOAD_TIME)
  17. * Apr 2004 - Release 1.02 some debug output for
  18. * kernel panic in wake_up_interruptible(&dev->rd_wait);
  19. * Jun 2004 - Release 2.02 running on Linux 2.6 and 2.4
  20. * using PCI-PnP
  21. * Jun 2004 - do not use wake_up_interruptible_sync(), only wake_up_interruptible(),
  22. * it's very slow on Kernel 2.6.5
  23. * Nov 2005 - Release 2.08 used copy_to_user(), copy_from_user(), __get_user(),
  24. * __put_user() instead direct access to user memory
  25. *
  26. * This product may be distributed under the terms of the GNU Public License.
  27. *
  28. *
  29. * Compiling instructions:
  30. *
  31. * Only if you want to build a static driver,
  32. * insert a unique major number in /usr/include/linux/major.h:
  33. * Example: #define LPC_MAJOR 84
  34. *
  35. * Then compile the driver for Linux 2.2:
  36. * gcc -c -Wall -D__KERNEL__ -DMODULE -O2 lpclinux.c
  37. *
  38. * or for Linux 2.4:
  39. * gcc -c -Wall -D__KERNEL__ -DMODULE -O2 -I/usr/src/linux/include lpclinux.c
  40. *
  41. * Add some nodes in the /dev directory:
  42. * Minor number 0..31 are used for ISA cards
  43. * Minor number 32..63 are used for PCI cards
  44. *
  45. * Example:
  46. * mknod /dev/lon1 c 84 0 (lon1 is the 1st ISA card)
  47. * mknod /dev/lon2 c 84 1 (lon2 is the 2nd ISA card)
  48. * mknod /dev/lon3 c 84 32 (lon3 is the 1st PCI card)
  49. * mknod /dev/lon4 c 84 33 (lon4 is the 2nd PCI card)
  50. *
  51. * Don't forget to set the access rights:
  52. * chmod 666 /dev/lon*
  53. *
  54. * Load the driver:
  55. * insmod lpclinux.o [params]
  56. *
  57. * If you build a driver module (-DMODULE) instead of a static driver,
  58. * the major number is set at load time, so it is not necessary to
  59. * change the file major.h.
  60. * Example:
  61. * insmod lpclinux.o major=84
  62. *
  63. * The I/O addresses and IRQs of ISA cards can now be set at load time, so
  64. * it is not necessary to change the driver code.
  65. * ISA parameters are defined here as 16 bit values (4 hex digits)
  66. * Bits 11..0: base I/O address
  67. * Bits 15..12: IRQ, valid values are 3,5,7,9,A,B,C and F.
  68. *
  69. * The parameter isa is a string with 4 hex digits for each card.
  70. * All characters except 0..9, A..F and a..f are ignored and may be used
  71. * as seperators.
  72. * Also some other characters like comma and double quote are not allowed
  73. * by the insmod command.
  74. *
  75. * Example:
  76. * 1st card has address 0x340 and IRQ 5
  77. * 2nd card has address 0x344 and IRQ 7
  78. *
  79. * insmod lpclinux.o isa="53407344"
  80. * or
  81. * insmod lpclinux.o isa="5/340 7/344"
  82. * or
  83. * insmod lpclinux.o isa="irq=5 port=340h : irq=7 port=344h"
  84. *
  85. * Not allowed is
  86. * insmod lpclinux.o isa="interrupt = 5, baseaddress = 0x340"
  87. * ^ ^ ^^ ^^ ^ ^
  88. */
  89. #include "lpclinux.h"
  90. //#include "kdebug.c"
  91. #include "driverdata.c"
  92. //#include "dynbuf.c"
  93. static int downlink( DEV *dev )
  94. {
  95. u8 cmq, len, st;
  96. u8 *p;
  97. int idx;
  98. u32 cport, wport;
  99. dbg8("%s(): dev=%08X", __FUNCTION__, (uint)dev);
  100. cport = dev->cport;
  101. wport = dev->wport;
  102. idx = dev->outhead;
  103. p = dev->outbuf[idx];
  104. #if 0
  105. len = *p++;
  106. cmq = *p++;
  107. #else
  108. cmq = *p++;
  109. len = *p++;
  110. // len ++;
  111. #endif
  112. if (debug & DEBUG_DUMP2) DumpBuffer(">>", p-2, len+2);
  113. // printk(KERN_DEBUG ">len=%02X cmq=%02X\n", len, cmq);
  114. HS;
  115. NOUT(CMD_XFER);
  116. HS;
  117. NOUT(len+1);
  118. HS;
  119. NOUT(cmq);
  120. HS;
  121. // printk(KERN_DEBUG "len=%02X Loop: ", len);
  122. while(len--)
  123. {
  124. // printk ("%.2x ", *p);
  125. HS;
  126. NOUT(*p++);
  127. }
  128. // printk ("\n");
  129. HS;
  130. NOUT(EOM);
  131. idx++;
  132. if(idx >= NUM_OUTBUF) idx=0;
  133. dev->outhead = idx;
  134. return 0;
  135. }
  136. static int uplink( DEV *dev )
  137. {
  138. u8 cmq, len, st;
  139. u8 *p;
  140. int idx;
  141. u32 cport, rport;
  142. dbg8("%s(): dev=%08X", __FUNCTION__, (uint)dev);
  143. cport = dev->cport;
  144. rport = dev->rport;
  145. HS;
  146. if( !NIN ) return 0; // Pass token
  147. HS;
  148. len = NIN;
  149. HS;
  150. cmq = NIN;
  151. if(cmq == 0xC0) return 1; // niACK received
  152. idx = dev->intail; // uplink
  153. p = dev->inbuf[idx];
  154. #if 0
  155. *p++ = len;
  156. *p++ = cmq;
  157. len--;
  158. #else
  159. *p++ = cmq;
  160. len--;
  161. *p++ = len;
  162. #endif
  163. // printk(KERN_DEBUG "<len=%02X cmq=%02X\n", len, cmq);
  164. while( len-- )
  165. {
  166. HS;
  167. *p++ = NIN;
  168. }
  169. if (debug & DEBUG_DUMP2)
  170. {
  171. p = dev->inbuf[idx];
  172. len = p[1];
  173. DumpBuffer("<<", p, len+2);
  174. }
  175. idx++;
  176. if(idx >= NUM_INBUF) idx=0;
  177. if(idx != dev->inhead)
  178. {
  179. dev->intail = idx;
  180. dbg8(" %s(): before waitqueue_active()", __FUNCTION__);
  181. if (waitqueue_active(&dev->rd_wait))
  182. {
  183. dbg8(" %s(): before wake_up_interruptible()", __FUNCTION__);
  184. wake_up_interruptible( &dev->rd_wait );
  185. }
  186. else
  187. dbg8(" %s(): waitqueue_active()=0", __FUNCTION__);
  188. }
  189. return 0;
  190. }
  191. static int sm_lpc(register DEV *dev)
  192. {
  193. u8 *p;
  194. u8 st;
  195. int g;
  196. // int flags;
  197. u16 idx; // avoid critical section
  198. u32 cport, rport, wport;
  199. dbg4(" %s(): dev=%08X", __FUNCTION__, (uint)dev);
  200. cport = dev->cport;
  201. rport = dev->rport;
  202. wport = dev->wport;
  203. switch( dev->state )
  204. {
  205. case ST_RESYNC:
  206. if(LPCSTAT & 1) return 0;
  207. dev->ctl &= ~4;
  208. SETCTL; // clear reset flipflop
  209. SETCTL;
  210. SETCTL;
  211. dev->ctl |= 4;
  212. SETCTL;
  213. HS;
  214. NOUT(CMD_RESYNC); // send RESYNC
  215. HS;
  216. NOUT(EOM);
  217. HS;
  218. if(NIN != CMD_ACKSYNC) return -1; // get ACKSYNC
  219. dev->state = ST_RESET;
  220. return 0;
  221. case ST_RESET:
  222. HS;
  223. NOUT(CMD_NULL); // send NULL
  224. HS;
  225. NOUT(EOM);
  226. dev->state = ST_FLCAN;
  227. return 0;
  228. case ST_FLCAN:
  229. HS;
  230. if(NIN != CMD_XFER) return -1; // get niRESET
  231. HS;
  232. if(NIN != 1) return -1;
  233. HS;
  234. if(NIN != 0x50) return -1;
  235. // dev->intail = dev->inhead;
  236. // dev->outhead = dev->outtail;
  237. idx = dev->intail;
  238. p = dev->inbuf[idx];
  239. *p++ = 0x50;
  240. *p++ = 0x00;
  241. idx++;
  242. if(idx >= NUM_INBUF) idx=0;
  243. if(idx != dev->inhead)
  244. {
  245. dev->intail = idx;
  246. dbg8(" %s(): before waitqueue_active()", __FUNCTION__);
  247. if (waitqueue_active(&dev->rd_wait))
  248. {
  249. dbg8(" %s(): before wake_up_interruptible()", __FUNCTION__);
  250. wake_up_interruptible( &dev->rd_wait );
  251. }
  252. else
  253. dbg8(" %s(): waitqueue_active()=0", __FUNCTION__);
  254. }
  255. HS;
  256. NOUT(CMD_XFER); // send FLUSH_CANCEL
  257. HS;
  258. NOUT(1);
  259. HS;
  260. NOUT(0x60);
  261. HS;
  262. NOUT(EOM);
  263. dev->state = ST_UPLINK;
  264. return 0;
  265. case ST_IDLE:
  266. if(dev->outhead == dev->outtail) {
  267. HS;
  268. NOUT(CMD_NULL); // send NULL
  269. HS;
  270. NOUT(EOM);
  271. dev->state = ST_UPLINK;
  272. return 0;
  273. }
  274. p = dev->outbuf[dev->outhead];
  275. if( !((p[0]-0x10) & 0xE0) )
  276. { // 1x or 2x
  277. HS;
  278. NOUT(CMD_XFER); // buffer request
  279. HS;
  280. NOUT(0x01);
  281. HS;
  282. NOUT(p[0]);
  283. HS;
  284. NOUT(EOM);
  285. HS;
  286. dev->state = ST_NIACK;
  287. return 0;
  288. }
  289. if( downlink( dev ) ) return -1;
  290. dev->state = ST_UPLINK;
  291. return 0;
  292. case ST_UPLINK:
  293. if( uplink( dev ) < 0 ) return -1;
  294. dev->state = ST_IDLE;
  295. if(dev->outhead != dev->outtail) {
  296. // CLI;
  297. dev->active++;
  298. // STI;
  299. }
  300. return 0;
  301. case ST_NIACK:
  302. g = uplink( dev );
  303. if( g < 0 ) return -1;
  304. if( g == 1 ) {
  305. downlink( dev );
  306. dev->state = ST_UPLINK;
  307. return 0;
  308. }
  309. HS;
  310. NOUT(CMD_NULL); // send NULL
  311. HS;
  312. NOUT(EOM);
  313. dev->state = ST_NIACK;
  314. return 0;
  315. }
  316. return 0;
  317. }
  318. static void DpcForIsr(unsigned long dev_addr)
  319. {
  320. DEV *dev = (DEV *) dev_addr;
  321. dbg4(" %s(): dev=%08X active=%X", __FUNCTION__, (uint)dev, dev->active);
  322. // do
  323. {
  324. int result;
  325. u32 cport;
  326. result = sm_lpc( dev );
  327. if (result < 0)
  328. {
  329. dev->active = 1; // will be 0
  330. dev->state = 0;
  331. cport = dev->cport;
  332. dbg4(" %s(): active=%X RST_CMND:", __FUNCTION__, dev->active);
  333. dev->ctl |= 0x01; // RST_CMND
  334. SETCTL;
  335. SETCTL;
  336. dev->ctl &= 0xFE;
  337. SETCTL;
  338. }
  339. --dev->active;
  340. }
  341. // while (--dev->active > 0);
  342. dev->drvtimer.expires = jiffies + HZ/5;
  343. add_timer( &dev->drvtimer );
  344. dbg4(" %s(): dev=%08X active=%X return", __FUNCTION__, (uint)dev, dev->active);
  345. }
  346. #if 0
  347. // tasklet does not work with ISA-Card !!!
  348. static void sm_stub( DEV *dev )
  349. {
  350. dbg4(" %s(): dev=%08X active=%X", __FUNCTION__, (uint)dev, dev->active);
  351. ++dev->active;
  352. tasklet_schedule(&dev->Dpc);
  353. }
  354. #else
  355. static BOOLEAN sm_stub( DEV *dev )
  356. {
  357. int result;
  358. // int flags;
  359. u32 cport;
  360. dbg4(" %s(): dev=%08X active=%X", __FUNCTION__, (uint)dev, dev->active);
  361. if (++dev->active > 1)
  362. {
  363. dbg4(" %s(): active=%X", __FUNCTION__, dev->active);
  364. return FALSE;
  365. }
  366. do {
  367. result = sm_lpc( dev );
  368. if (result < 0)
  369. {
  370. dev->active = 1; // will be 0
  371. dev->state = 0;
  372. cport = dev->cport;
  373. dev->ctl |= 0x01;
  374. SETCTL;
  375. SETCTL;
  376. dev->ctl &= 0xFE;
  377. SETCTL;
  378. }
  379. } while (--dev->active > 0);
  380. dev->drvtimer.expires = jiffies + HZ/5;
  381. add_timer( &dev->drvtimer );
  382. return TRUE;
  383. }
  384. #endif
  385. static irqreturn_t lpc_isa_interrupt( int irq, void *ptr, struct pt_regs *regs )
  386. {
  387. DEV *dev;
  388. dev = (DEV *)ptr;
  389. if( inb(dev->cport) & 8 ) return IRQ_NONE; // Its not for me
  390. dbg2("+ %s(): dev=%08X", __FUNCTION__, (uint)dev);
  391. del_timer( &dev->drvtimer );
  392. outb(0, dev->rport); // Clear interrupt flipflop (ISA)
  393. sm_stub( dev );
  394. dbg2("- %s(): dev=%08X return", __FUNCTION__, (uint)dev);
  395. return IRQ_HANDLED;
  396. }
  397. static irqreturn_t lpc_pci_interrupt( int irq, void *ptr, struct pt_regs *regs )
  398. {
  399. DEV *dev = (DEV *)ptr;
  400. u32 cport;
  401. u16 IntCsr = inw(dev->PlxIntCsrPort);
  402. // dev->PciIntCount++;
  403. // info("? %s(): dev=%08X IntCsr=%04X", __FUNCTION__, (uint)dev, IntCsr);
  404. if (IntCsr == 0xFFFF) return IRQ_NONE; // Can't read PLX
  405. if (inb(dev->cport) & 8) return IRQ_NONE; // Its not for me
  406. dbg2("+ %s(): dev=%08X", __FUNCTION__, (uint)dev);
  407. del_timer( &dev->drvtimer );
  408. cport = dev->cport;
  409. dev->ctl &= 0xEF; // Clear interrupt flipflop (PCI)
  410. SETCTL;
  411. SETCTL;
  412. SETCTL;
  413. dev->ctl |= 0x10; // CLR_IFF_CMND
  414. SETCTL;
  415. sm_stub(dev);
  416. dbg2("- %s(): dev=%08X return", __FUNCTION__, (uint)dev);
  417. return IRQ_HANDLED;
  418. }
  419. static void lpc_timer( unsigned long ptr )
  420. {
  421. DEV *dev = (DEV *)ptr;
  422. dbg1("+ %s(): dev=%08X", __FUNCTION__, (uint)dev);
  423. sm_stub(dev);
  424. dbg1("- %s(): dev=%08X return", __FUNCTION__, (uint)dev);
  425. }
  426. static ssize_t lpc_write( struct file *file, const char *buf,
  427. size_t count, loff_t *off )
  428. {
  429. u8 *p;
  430. int idx;
  431. int len;
  432. // int flags;
  433. register DEV *dev = (DEV *)(file->private_data);
  434. dbg1("%s(): dev=%08X", __FUNCTION__, (uint)dev);
  435. // DbgFlush();
  436. if(count < 0) return -EINVAL;
  437. if(count > 256) return -EINVAL;
  438. idx = dev->outtail + 1;
  439. if(idx >= NUM_OUTBUF) idx = 0;
  440. // CLI;
  441. if(idx == dev->outhead)
  442. {
  443. // STI;
  444. dbg1("%s(): dev=%08X return -EWOULDBLOCK", __FUNCTION__, (uint)dev);
  445. return -EWOULDBLOCK;
  446. }
  447. // STI;
  448. p = dev->outbuf[ dev->outtail ];
  449. copy_from_user(p, buf, count);
  450. if (debug & DEBUG_DUMP1) DumpBuffer("> ", p, count);
  451. #if 0
  452. // app layer -> link layer
  453. len = p[1] + 1;
  454. p[1] = p[0];
  455. p[0] = (u8)len;
  456. len++;
  457. #else
  458. len = p[1] + 2;
  459. #endif
  460. dev->outtail = idx;
  461. if( dev->state == ST_IDLE )
  462. {
  463. del_timer( &dev->drvtimer );
  464. sm_stub( dev );
  465. }
  466. dbg1("%s(): dev=%08X return %d", __FUNCTION__, (uint)dev, len);
  467. return len;
  468. }
  469. static ssize_t lpc_read( struct file *file, char *buf,
  470. size_t count, loff_t *off )
  471. {
  472. // int flags;
  473. int idx;
  474. int len;
  475. u8 *p;
  476. register DEV *dev = (DEV *)(file->private_data);
  477. if(count < 0) return -EINVAL;
  478. dbg1("%s(): dev=%08X", __FUNCTION__, (uint)dev);
  479. // DbgFlush();
  480. idx = dev->inhead;
  481. #if 0
  482. CLI;
  483. if( idx == dev->intail )
  484. {
  485. if(file->f_flags & O_NONBLOCK)
  486. {
  487. STI;
  488. return -EWOULDBLOCK;
  489. }
  490. interruptible_sleep_on( &dev->rd_wait );
  491. /*
  492. The next line produces compiling errors, so I use a workaround
  493. if( current->signal & ~current->blocked ) return -ERESTARTSYS;
  494. */
  495. if( idx == dev->intail ) return -ERESTARTSYS;
  496. }
  497. STI;
  498. #else
  499. // if (qempty(&dev->ReadBufferQueue))
  500. if (idx == dev->intail)
  501. {
  502. dbg1("%s(): qempty", __FUNCTION__);
  503. // up (&dev->sem);
  504. if (file->f_flags & O_NONBLOCK)
  505. {
  506. dbg1("%s()=-EAGAIN !!!", __FUNCTION__);
  507. return -EAGAIN; // -EWOULDBLOCK;
  508. }
  509. // if (wait_event_interruptible(dev->rd_wait, qhasdata(&dev->ReadBufferQueue)))
  510. if (wait_event_interruptible(dev->rd_wait, (idx != dev->intail) ))
  511. {
  512. dbg1("%s(): dev=%08X return -ERESTARTSYS", __FUNCTION__, (uint)dev);
  513. return -ERESTARTSYS; /* signal: tell the fs layer to handle it */
  514. }
  515. dbg8("%s(): nach wait_event_interruptible(rd_wait)", __FUNCTION__);
  516. // if (down_interruptible(&dev->sem))
  517. // return -ERESTARTSYS;
  518. }
  519. #endif
  520. p = dev->inbuf[idx];
  521. #if 0
  522. // link layer -> app layer
  523. len = p[0];
  524. p[0] = p[1];
  525. p[1] = (u8)(len - 1);
  526. if( count > len + 1 ) count = len + 1;
  527. #else
  528. len = p[1]+2;
  529. if (count > len) count = len;
  530. #endif
  531. if (debug & DEBUG_DUMP1) DumpBuffer("< ", p, count);
  532. copy_to_user(buf, p, count);
  533. idx++;
  534. if(idx >= NUM_INBUF) idx = 0;
  535. dev->inhead = idx;
  536. dbg1("%s(): dev=%08X return %d", __FUNCTION__, (uint)dev, count);
  537. return count;
  538. }
  539. static unsigned lpc_poll( struct file *file, struct poll_table_struct *wait)
  540. {
  541. DEV *dev = file->private_data;
  542. unsigned mask = 0;
  543. dbg1("%s(): dev=%08X", __FUNCTION__, (uint)dev);
  544. // DbgFlush();
  545. poll_wait( file, &dev->rd_wait, wait);
  546. if(dev->inhead != dev->intail) mask |= POLLIN | POLLRDNORM;
  547. return mask;
  548. }
  549. static int initialize_isacard( DEV *dev, int index )
  550. {
  551. u32 cport, rport;
  552. int irq;
  553. dbg1("%s(): dev=%08X", __FUNCTION__, (uint)dev);
  554. /*
  555. if( !lpcs[index] ) {
  556. err( "invalid minor number %d\n", index );
  557. return -ENODEV;
  558. }
  559. iobase = lpcs[index] & 0x0FFF;
  560. irq = lpcs[index] >> 12;
  561. cport = iobase+1;
  562. rport = iobase+2;
  563. */
  564. cport = dev->cport;
  565. rport = dev->rport;
  566. irq = dev->irq;
  567. #ifndef CHECK_ISA_AT_LOAD_TIME
  568. {
  569. int hwfail = 0;
  570. if( ((u8)irq > 15) || !irq_table[irq] )
  571. {
  572. err("IRQ%d not supported\n", irq );
  573. return -ENODEV;
  574. }
  575. if( check_region(iobase, 4) )
  576. {
  577. err( "unable to register port 0x%X\n", iobase);
  578. return -ENODEV;
  579. }
  580. outb(0x5F, cport);
  581. outb(0, rport);
  582. outb(0, rport);
  583. outb(0, rport);
  584. if( (inb(cport) & 0xF0) != 0x50 ) hwfail = 1;
  585. outb(0x0F, cport);
  586. outb(0, rport);
  587. outb(0, rport);
  588. outb(0, rport);
  589. if( inb(cport) & 0xF0 ) hwfail = 1;
  590. if( hwfail )
  591. {
  592. err("interface card not responding at port 0x%X\n", iobase);
  593. return -ENODEV;
  594. }
  595. request_region( iobase, 4, DRIVER_DEV_NAME );
  596. }
  597. #endif
  598. /*
  599. dev->cport = iobase+1;
  600. dev->rport = iobase+2;
  601. dev->wport = iobase+3;
  602. dev->wtcport = iobase+0;
  603. dev->irq = irq;
  604. dev->PlxIntCsrPort = 0;
  605. */
  606. dev->ctl = 0x0F;
  607. SETCTL;
  608. SETCTL;
  609. dev->ctl = 0x0D;
  610. SETCTL;
  611. SETCTL;
  612. dev->ctl |= irq_table[dev->irq];
  613. SETCTL;
  614. SETCTL;
  615. dev->ctl &= 0xF6;
  616. SETCTL;
  617. if( request_irq(irq, lpc_isa_interrupt, SA_SHIRQ, DRIVER_DEV_NAME, dev) )
  618. {
  619. err("unable to register IRQ%d\n", irq);
  620. #ifndef CHECK_ISA_AT_LOAD_TIME
  621. release_region(iobase, 4);
  622. #endif
  623. return -ENODEV;
  624. }
  625. return 0;
  626. }
  627. static int initialize_pcicard( DEV *dev, int index )
  628. {
  629. dbg1("%s(): dev=%08X", __FUNCTION__, (uint)dev);
  630. {
  631. #if 0
  632. u32 PlxIntCsrPort, cport, rport, wtcport, rtr;
  633. int irq;
  634. char bus, function;
  635. if( !pcibios_present() )
  636. {
  637. err( "PCI bios not present\n" );
  638. return -ENODEV;
  639. }
  640. if( pcibios_find_device( VENDOR_ID, DEVICE_ID, index, &bus, &function ) )
  641. {
  642. err( "PCI device not found\n" );
  643. return -ENODEV;
  644. }
  645. pcibios_read_config_dword( bus, function, 0x14, (int *)&rtr );
  646. pcibios_read_config_dword( bus, function, 0x18, (int *)&cport );
  647. pcibios_read_config_dword( bus, function, 0x1C, (int *)&rport );
  648. pcibios_read_config_dword( bus, function, 0x24, (int *)&wtcport );
  649. pcibios_read_config_dword( bus, function, 0x3C, &irq );
  650. PlxIntCsrPort = (rtr & 0xFFF0) + P9050_INTCSR;
  651. cport &= 0xFFF0;
  652. rport &= 0xFFF0;
  653. irq &= 0x0F;
  654. outw( 0, PlxIntCsrPort );
  655. if( check_region(cport, 4) ) {
  656. err( "unable to register port 0x%X\n", cport );
  657. return -ENODEV;
  658. }
  659. if( check_region(rport, 4) ) {
  660. err( "unable to register port 0x%X\n", rport );
  661. return -ENODEV;
  662. }
  663. request_region( cport, 4, DRIVER_DEV_NAME );
  664. request_region( rport, 4, DRIVER_DEV_NAME );
  665. dev->cport = cport;
  666. dev->rport = rport;
  667. dev->wport = rport;
  668. dev->wtcport = wtcport;
  669. dev->irq = irq;
  670. dev->PlxIntCsrPort = PlxIntCsrPort;
  671. #else
  672. u32 cport;
  673. u16 IntCsr;
  674. cport = dev->cport;
  675. #endif
  676. dev->ctl = 0x0D;
  677. SETCTL;
  678. SETCTL;
  679. dev->ctl = 0x16;
  680. SETCTL;
  681. SETCTL;
  682. dev->ctl = 0x02;
  683. SETCTL;
  684. SETCTL;
  685. dev->ctl = 0x16;
  686. SETCTL;
  687. IntCsr = inw(dev->PlxIntCsrPort);
  688. dbg1("? %s(): PlxIntCsrPort=%04X IntCsr=%04X", __FUNCTION__, dev->PlxIntCsrPort, IntCsr);
  689. IntCsr |= PLX_9050_INTR_ENABLE | PLX_9050_LINT1_ENABLE; // | PLX_9050_LINT2_ENABLE;
  690. outw(IntCsr, dev->PlxIntCsrPort);
  691. dbg1("? %s(): PlxIntCsrPort=%04X IntCsr=%04X", __FUNCTION__, dev->PlxIntCsrPort, IntCsr);
  692. if( request_irq(dev->irq, lpc_pci_interrupt, SA_SHIRQ, DRIVER_DEV_NAME, dev) )
  693. {
  694. err("unable to register IRQ%d\n", dev->irq);
  695. #if 0
  696. release_region(rport, 4);
  697. release_region(cport, 4);
  698. #endif
  699. return -ENODEV;
  700. }
  701. return 0;
  702. }
  703. }
  704. static int lpc_open(struct inode *inode, struct file *file)
  705. {
  706. int minor;
  707. // u32 cport;
  708. int idx;
  709. register DEV *dev;
  710. dbg1("%s(): MINOR=%d", __FUNCTION__, MINOR (inode->i_rdev));
  711. /*
  712. DbgFlush();
  713. struct timeval tv;
  714. do {
  715. do_gettimeofday(&tv);
  716. } while ( (tv.tv_sec % 10) != 0);
  717. */
  718. minor = iminor(inode);
  719. if( minor > MAX_DEVICES )
  720. {
  721. err("%s - invalid minor number %d", __FUNCTION__, minor);
  722. return -ENODEV;
  723. }
  724. dev = minor_table[minor];
  725. if( !dev )
  726. {
  727. err ("%s - error, can't find device for minor %d", __FUNCTION__, minor);
  728. return -ENODEV;
  729. }
  730. /* increment our usage count for the driver */
  731. if (++dev->open_count == 1)
  732. {
  733. dev->active = 1;
  734. if( minor < MAX_LPCS )
  735. {
  736. if( initialize_isacard(dev, minor) )
  737. {
  738. /* decrement our usage count for the device */
  739. --dev->open_count;
  740. return -ENODEV;
  741. }
  742. }
  743. else
  744. {
  745. if( initialize_pcicard(dev, minor - MAX_LPCS) )
  746. {
  747. /* decrement our usage count for the device */
  748. --dev->open_count;
  749. return -ENODEV;
  750. }
  751. }
  752. // dev->PciIntCount = dev->PciIntCountPlus = dev->PciIntCountMinus = 0;
  753. // dev->TimerCountPlus = dev->TimerCountMinus = 0;
  754. #if LINUX_VERSION_CODE < 0x020400
  755. dev->rd_wait = NULL;
  756. // dev->wr_wait = NULL;
  757. #else
  758. // #ifdef DECLARE_WAITQUEUE
  759. init_waitqueue_head(&dev->rd_wait);
  760. // dbg8("%s(): init_waitqueue_head()", __FUNCTION__);
  761. // init_waitqueue_head(&dev->wr_wait);
  762. // #endif
  763. #endif
  764. dev->inhead = dev->intail = 0;
  765. dev->outhead = dev->outtail = 0;
  766. dev->state = ST_RESYNC;
  767. dev->active = 0;
  768. dev->wtc_exist = 0;
  769. init_timer( &dev->drvtimer );
  770. dev->drvtimer.function = lpc_timer;
  771. dev->drvtimer.data = (unsigned long)dev;
  772. // cport = dev->cport;
  773. #if LINUX_VERSION_CODE < 0x020500
  774. MOD_INC_USE_COUNT;
  775. #endif
  776. dbg1("%s(): before sm_stub()", __FUNCTION__);
  777. sm_stub( dev ); // Start state machine
  778. #if 01
  779. #if 0
  780. dbg8("%s(): before interruptible_sleep_on()", __FUNCTION__);
  781. interruptible_sleep_on( &dev->rd_wait ); // and read 1st reset msg
  782. dbg8("%s(): after interruptible_sleep_on()", __FUNCTION__);
  783. idx = dev->inhead;
  784. #else
  785. idx = dev->inhead;
  786. // if (qempty(&dev->ReadBufferQueue))
  787. if (idx == dev->intail)
  788. {
  789. dbg1("%s(): qempty", __FUNCTION__);
  790. // up (&dev->sem);
  791. // if (wait_event_interruptible(dev->rd_wait, qhasdata(&dev->ReadBufferQueue)))
  792. if (wait_event_interruptible(dev->rd_wait, (idx != dev->intail) ))
  793. {
  794. /* decrement our usage count for the device */
  795. --dev->open_count;
  796. return -ERESTARTSYS; /* signal: tell the fs layer to handle it */
  797. }
  798. dbg8("%s(): nach wait_event_interruptible(rd_wait)", __FUNCTION__);
  799. // if (down_interruptible(&dev->sem))
  800. // return -ERESTARTSYS;
  801. }
  802. #endif
  803. idx++;
  804. if(idx >= NUM_INBUF) idx = 0;
  805. dev->inhead = idx;
  806. #endif
  807. }
  808. /* save our object in the file's private structure */
  809. file->private_data = dev;
  810. dbg1("%s(): return 0", __FUNCTION__);
  811. return 0;
  812. }
  813. static int lpc_release(struct inode *inode, struct file *file)
  814. {
  815. register DEV *dev = (DEV *)(file->private_data);
  816. if (dev == NULL)
  817. {
  818. dbg1("%s() dev=NULL", __FUNCTION__);
  819. return -ENODEV;
  820. }
  821. dbg1("%s(): minor=%d open_count=%d", __FUNCTION__, dev->minor, dev->open_count);
  822. /*
  823. dbg("PciIntCount=%5d PciIntCountPlus=%5d PciIntCountMinus=%5d"
  824. "\nTimerCountPlus=%5d TimerCountMinus=%5d",
  825. dev->PciIntCount, dev->PciIntCountPlus, dev->PciIntCountMinus,
  826. dev->TimerCountPlus, dev->TimerCountMinus);
  827. DbgFlush();
  828. */
  829. if (dev->open_count <= 0)
  830. {
  831. dbg1("%s() device not opened", __FUNCTION__);
  832. return -ENODEV;
  833. }
  834. /* decrement our usage count for the device */
  835. if (--dev->open_count <= 0)
  836. {
  837. u32 cport = dev->cport;
  838. dev->active = 1;
  839. dbg8("%s(): before del_timer()", __FUNCTION__);
  840. del_timer( &dev->drvtimer );
  841. free_irq(dev->irq, dev);
  842. dbg8("%s(): after free_irq()", __FUNCTION__);
  843. dev->ctl = 0x0D;
  844. SETCTL;
  845. if (dev->PlxIntCsrPort)
  846. {
  847. u16 IntCsr = inw(dev->PlxIntCsrPort);
  848. dbg1("? %s(): PlxIntCsrPort=%04X IntCsr=%04X", __FUNCTION__, dev->PlxIntCsrPort, IntCsr);
  849. IntCsr &= ~PLX_9050_INTR_ENABLE;
  850. outw(IntCsr, dev->PlxIntCsrPort);
  851. dbg1("? %s(): PlxIntCsrPort=%04X IntCsr=%04X", __FUNCTION__, dev->PlxIntCsrPort, IntCsr);
  852. // release_region(dev->cport, 4);
  853. // release_region(dev->rport, 4);
  854. }
  855. else
  856. {
  857. outw( 0, dev->rport );
  858. #ifndef CHECK_ISA_AT_LOAD_TIME
  859. release_region(cport-1, 4);
  860. #endif
  861. }
  862. // devs[minor] = NULL;
  863. // kfree( dev );
  864. dev->open_count = 0;
  865. }
  866. file->private_data = 0;
  867. #if LINUX_VERSION_CODE < 0x020500
  868. MOD_DEC_USE_COUNT;
  869. #endif
  870. dbg1("%s(): return 0", __FUNCTION__);
  871. // DbgFlush();
  872. return 0;
  873. }
  874. int lpc_watcher( DEV* dev, u8* buf )
  875. {
  876. u32 cport, wtcport;
  877. u8 *s, *d;
  878. s16 count, i;
  879. u8 xcvr, cmd, tmp;
  880. int t;
  881. dbg1("%s(): dev=%08X", __FUNCTION__, (uint)dev);
  882. cport = dev->cport;
  883. wtcport = dev->wtcport;
  884. s = d = buf;
  885. #if 01
  886. __get_user(count, s++); // Get the length
  887. __get_user(tmp, s++);
  888. count = (count << 8) + tmp;
  889. __get_user(cmd, s++);
  890. cmd &= 0x7F;
  891. #else
  892. count = *s++; // Get the length
  893. count = (count << 8) + *s++;
  894. cmd = *s++ & 0x7F;
  895. #endif
  896. if( cmd )
  897. { // Normal case: request watcher firmware
  898. if(!dev->wtc_exist) return -ENODEV;
  899. t = jiffies + HZ/2;
  900. WTCHS;
  901. WOUT((u8)(count >> 8)); // Send the length
  902. WTCHS;
  903. WOUT((u8)(count & 0xFF));
  904. WTCHS;
  905. WOUT(cmd);
  906. count--;
  907. while( count > 0 ) {
  908. WTCHS;
  909. #if 01
  910. __get_user(tmp, s++);
  911. WOUT(tmp); // Send the data bytes
  912. #else
  913. WOUT(*s++); // Send the data bytes
  914. #endif
  915. count--;
  916. }
  917. WTCHS;
  918. WOUT(0); // EOM
  919. WTCHS;
  920. count = WIN; // Receive the length
  921. #if 01
  922. __put_user(count & 0xFF, d++);
  923. WTCHS;
  924. count = (count << 8) + WIN;
  925. __put_user(count & 0xFF, d++);
  926. #else
  927. *d++ = count & 0xFF;
  928. WTCHS;
  929. count = (count << 8) + WIN;
  930. *d++ = count & 0xFF;
  931. #endif
  932. i = count;
  933. while( i > 0 ) {
  934. WTCHS;
  935. #if 01
  936. tmp = WIN;
  937. __put_user(tmp, d++);
  938. #else
  939. *d++ = WIN;
  940. #endif
  941. i--;
  942. }
  943. } else { // Special case: firmware download
  944. dev->ctl |= 0x02; // Reset LWA
  945. SETCTL;
  946. WIN; // Switch to Bootloader
  947. dev->ctl &= ~0x02; // Start LWA
  948. SETCTL;
  949. #if 01
  950. __get_user(xcvr, s++);
  951. #else
  952. xcvr = *s++;
  953. #endif
  954. count -=2;
  955. schedule();
  956. t = jiffies + HZ;
  957. while( count > 0 ) {
  958. WTCHS;
  959. #if 01
  960. __get_user(tmp, s++);
  961. WOUT(tmp); // Send the data bytes
  962. #else
  963. WOUT(*s++); // Send the data bytes
  964. #endif
  965. count--;
  966. }
  967. WTCHS;
  968. WOUT(0); // EOM
  969. WTCHS; // Wait until finished
  970. dev->ctl |= 0x02;
  971. SETCTL; // Reset LWA
  972. WOUT(xcvr); // Switch to Firmware
  973. dev->ctl &= ~0x02;
  974. SETCTL; // Start LWA
  975. t = HZ * 2; // Give the LWA some time to answer
  976. do {
  977. t--;
  978. if( !t ) return -ENODEV;
  979. schedule();
  980. }
  981. while(LPCSTAT & 2);
  982. #if 01
  983. __put_user(0, d++);
  984. __put_user(0, d++);
  985. #else
  986. *d++ = 0; // Acknowledge
  987. *d++ = 0;
  988. #endif
  989. dev->wtc_exist = 1;
  990. }
  991. return d - buf;
  992. }
  993. static int lpc_ioctl(struct inode *inode, struct file *file,
  994. unsigned int cmd, unsigned long arg)
  995. {
  996. int retval = -EINVAL;
  997. register DEV *dev = (DEV *)(file->private_data);
  998. char tmpBuf[80];
  999. dbg1("%s(): dev=%08X", __FUNCTION__, (uint)dev);
  1000. switch( cmd )
  1001. {
  1002. case IOCTL_VERSION:
  1003. retval = sprintf(tmpBuf, DRIVER_DESC " " DRIVER_VERSION ", Linux %d.%d.%d",
  1004. (LINUX_VERSION_CODE >> 16) & 0xFF,
  1005. (LINUX_VERSION_CODE >> 8) & 0xFF,
  1006. LINUX_VERSION_CODE & 0xFF ) + 1;
  1007. if (copy_to_user ((char *)arg, tmpBuf, retval))
  1008. retval = -EFAULT;
  1009. break;
  1010. case IOCTL_WATCHER:
  1011. return lpc_watcher( dev, (u8 *)arg );
  1012. }
  1013. return retval;
  1014. }
  1015. int lpc_init( void )
  1016. {
  1017. int i;
  1018. u32 iobase, cport, rport;
  1019. int irq;
  1020. int rc = -ENODEV;
  1021. dbg1("%s():", __FUNCTION__);
  1022. for( i=0; i<MAX_LPCS; i++ )
  1023. {
  1024. if( !lpcs[i] ) continue;
  1025. iobase = lpcs[i] & 0x0FFF;
  1026. irq = lpcs[i] >> 12;
  1027. cport = iobase+1;
  1028. rport = iobase+2;
  1029. dbg1("lpc[%2d]: iobase=%04X irq=%X", i, iobase, irq);
  1030. #ifdef CHECK_ISA_AT_LOAD_TIME
  1031. if( ((u8)irq > 15) || !irq_table[irq] ) {
  1032. err( "IRQ%d not supported\n", irq );
  1033. lpcs[i] = 0;
  1034. continue;
  1035. }
  1036. if (!request_region( iobase, 4, DRIVER_DEV_NAME ))
  1037. // if( check_region(iobase, 4) )
  1038. {
  1039. err("unable to register port 0x%X", iobase);
  1040. lpcs[i] = 0;
  1041. continue;
  1042. }
  1043. {
  1044. int hwfail = 0;
  1045. outb(0x5F, cport);
  1046. outb(0, rport);
  1047. outb(0, rport);
  1048. outb(0, rport);
  1049. if( (inb(cport) & 0xF0) != 0x50 ) hwfail = 1;
  1050. outb(0x0F, cport);
  1051. outb(0, rport);
  1052. outb(0, rport);
  1053. outb(0, rport);
  1054. if( inb(cport) & 0xF0 ) hwfail = 1;
  1055. if( hwfail )
  1056. {
  1057. err( "interface card not responding at port 0x%04X", iobase );
  1058. lpcs[i] = 0;
  1059. release_region( iobase, 4);
  1060. continue;
  1061. }
  1062. // request_region( iobase, 4, DRIVER_DEV_NAME );
  1063. }
  1064. #endif
  1065. {
  1066. DEV *dev = NULL;
  1067. uint minor;
  1068. /* select a "subminor" number (part of a minor number) */
  1069. down (&minor_table_mutex);
  1070. for (minor = 0; minor < MAX_LPCS; ++minor)
  1071. {
  1072. if (minor_table[minor] == NULL)
  1073. break;
  1074. }
  1075. if (minor >= MAX_LPCS)
  1076. {
  1077. info ("Too many devices plugged in, can not handle this device.");
  1078. rc = -EINVAL;
  1079. goto err_minor_table;
  1080. }
  1081. dev = kmalloc (sizeof(DEV), GFP_KERNEL);
  1082. if (!dev)
  1083. {
  1084. up (&minor_table_mutex);
  1085. #ifdef CHECK_ISA_AT_LOAD_TIME
  1086. release_region( iobase, 4);
  1087. #endif
  1088. return -ENOMEM;
  1089. }
  1090. memset (dev, 0x00, sizeof (*dev));
  1091. dev->cport = iobase+1;
  1092. dev->rport = iobase+2;
  1093. dev->wport = iobase+3;
  1094. dev->wtcport = iobase+0;
  1095. dev->irq = irq;
  1096. dev->PlxIntCsrPort = 0;
  1097. dev->minor = minor;
  1098. minor_table[minor] = dev;
  1099. up (&minor_table_mutex);
  1100. rc = 0; // found on or more devices
  1101. }
  1102. }
  1103. return rc;
  1104. err_minor_table:
  1105. up (&minor_table_mutex);
  1106. #ifdef CHECK_ISA_AT_LOAD_TIME
  1107. release_region( iobase, 4);
  1108. #endif
  1109. return rc;
  1110. }
  1111. #include "driverentry.c"