PageRenderTime 55ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/kernel_modules_drivers/gesytec-2.12/lpclinux.c

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