specialix.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:62k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *      specialix.c  -- specialix IO8+ multiport serial driver.
  3.  *
  4.  *      Copyright (C) 1997  Roger Wolff (R.E.Wolff@BitWizard.nl)
  5.  *      Copyright (C) 1994-1996  Dmitry Gorodchanin (pgmdsg@ibi.com)
  6.  *
  7.  *      Specialix pays for the development and support of this driver.
  8.  *      Please DO contact io8-linux@specialix.co.uk if you require
  9.  *      support. But please read the documentation (specialix.txt)
  10.  *      first.
  11.  *
  12.  *      This driver was developped in the BitWizard linux device
  13.  *      driver service. If you require a linux device driver for your
  14.  *      product, please contact devices@BitWizard.nl for a quote.
  15.  *
  16.  *      This code is firmly based on the riscom/8 serial driver,
  17.  *      written by Dmitry Gorodchanin. The specialix IO8+ card
  18.  *      programming information was obtained from the CL-CD1865 Data
  19.  *      Book, and Specialix document number 6200059: IO8+ Hardware
  20.  *      Functional Specification.
  21.  *
  22.  *      This program is free software; you can redistribute it and/or
  23.  *      modify it under the terms of the GNU General Public License as
  24.  *      published by the Free Software Foundation; either version 2 of
  25.  *      the License, or (at your option) any later version.
  26.  *
  27.  *      This program is distributed in the hope that it will be
  28.  *      useful, but WITHOUT ANY WARRANTY; without even the implied
  29.  *      warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  30.  *      PURPOSE.  See the GNU General Public License for more details.
  31.  *
  32.  *      You should have received a copy of the GNU General Public
  33.  *      License along with this program; if not, write to the Free
  34.  *      Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
  35.  *      USA.
  36.  *
  37.  * Revision history:
  38.  *
  39.  * Revision 1.0:  April 1st 1997.
  40.  *                Initial release for alpha testing.
  41.  * Revision 1.1:  April 14th 1997. 
  42.  *                Incorporated Richard Hudsons suggestions, 
  43.  *                removed some debugging printk's.
  44.  * Revision 1.2:  April 15th 1997.
  45.  *                Ported to 2.1.x kernels.
  46.  * Revision 1.3:  April 17th 1997 
  47.  *                Backported to 2.0. (Compatibility macros). 
  48.  * Revision 1.4:  April 18th 1997
  49.  *                Fixed DTR/RTS bug that caused the card to indicate 
  50.  *                "don't send data" to a modem after the password prompt.  
  51.  *                Fixed bug for premature (fake) interrupts.
  52.  * Revision 1.5:  April 19th 1997
  53.  *                fixed a minor typo in the header file, cleanup a little. 
  54.  *                performance warnings are now MAXed at once per minute.
  55.  * Revision 1.6:  May 23 1997
  56.  *                Changed the specialix=... format to include interrupt.
  57.  * Revision 1.7:  May 27 1997
  58.  *                Made many more debug printk's a compile time option.
  59.  * Revision 1.8:  Jul 1  1997
  60.  *                port to linux-2.1.43 kernel.
  61.  * Revision 1.9:  Oct 9  1998
  62.  *                Added stuff for the IO8+/PCI version.
  63.  * Revision 1.10: Oct 22  1999 / Jan 21 2000. 
  64.  *                Added stuff for setserial. 
  65.  *                Nicolas Mailhot (Nicolas.Mailhot@email.enst.fr)
  66.  * 
  67.  */
  68. #define VERSION "1.10"
  69. /*
  70.  * There is a bunch of documentation about the card, jumpers, config
  71.  * settings, restrictions, cables, device names and numbers in
  72.  * ../../Documentation/specialix.txt 
  73.  */
  74. #include <linux/config.h>
  75. #include <linux/module.h>
  76. #include <asm/io.h>
  77. #include <linux/kernel.h>
  78. #include <linux/sched.h>
  79. #include <linux/ioport.h>
  80. #include <linux/interrupt.h>
  81. #include <linux/errno.h>
  82. #include <linux/tty.h>
  83. #include <linux/mm.h>
  84. #include <linux/serial.h>
  85. #include <linux/fcntl.h>
  86. #include <linux/major.h>
  87. #include <linux/delay.h>
  88. #include <linux/tqueue.h>
  89. #include <linux/version.h>
  90. #include <linux/pci.h>
  91. /* ************************************************************** */
  92. /* * This section can be removed when 2.0 becomes outdated....  * */
  93. /* ************************************************************** */
  94. #if LINUX_VERSION_CODE < 131328    /* Less than 2.1.0 */
  95. #define TWO_ZERO
  96. #else
  97. #if LINUX_VERSION_CODE < 131371   /* less than 2.1.43 */
  98. /* This has not been extensively tested yet. Sorry. */
  99. #warning "You're on your own between 2.1.0 and 2.1.43.... "
  100. #warning "Please use a recent kernel."
  101. #endif
  102. #endif
  103. #ifdef TWO_ZERO
  104. #define Get_user(a,b)         a = get_user(b)
  105. #define copy_from_user(a,b,c) memcpy_fromfs(a,b,c)
  106. #define copy_to_user(a,b,c)   memcpy_tofs(a,b,c)
  107. #define queue_task            queue_task_irq_off
  108. #else
  109. #define Get_user(a,b)         get_user(a,b)
  110. #endif
  111. /* ************************************************************** */
  112. /* *                End of compatibility section..              * */
  113. /* ************************************************************** */
  114. #ifndef TWO_ZERO
  115. #include <asm/uaccess.h>
  116. #endif
  117. #include "specialix_io8.h"
  118. #include "cd1865.h"
  119. /* Configurable options: */
  120. /* Am I paranoid or not ? ;-) */
  121. #define SPECIALIX_PARANOIA_CHECK
  122. /* Do I trust the IRQ from the card? (enabeling it doesn't seem to help)
  123.    When the IRQ routine leaves the chip in a state that is keeps on
  124.    requiring attention, the timer doesn't help either. */
  125. #undef SPECIALIX_TIMER
  126. /* 
  127.  * The following defines are mostly for testing purposes. But if you need
  128.  * some nice reporting in your syslog, you can define them also.
  129.  */
  130. #undef SX_REPORT_FIFO
  131. #undef SX_REPORT_OVERRUN
  132. #ifdef CONFIG_SPECIALIX_RTSCTS
  133. #define SX_CRTSCTS(bla) 1
  134. #else
  135. #define SX_CRTSCTS(tty) C_CRTSCTS(tty)
  136. #endif
  137. /* Used to be outb (0xff, 0x80); */
  138. #define short_pause() udelay (1)
  139. #define SPECIALIX_LEGAL_FLAGS 
  140. (ASYNC_HUP_NOTIFY   | ASYNC_SAK          | ASYNC_SPLIT_TERMIOS   | 
  141.  ASYNC_SPD_HI       | ASYNC_SPEED_VHI    | ASYNC_SESSION_LOCKOUT | 
  142.  ASYNC_PGRP_LOCKOUT | ASYNC_CALLOUT_NOHUP)
  143. #ifndef MIN
  144. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  145. #endif
  146. DECLARE_TASK_QUEUE(tq_specialix);
  147. #undef RS_EVENT_WRITE_WAKEUP
  148. #define RS_EVENT_WRITE_WAKEUP 0
  149. #define SPECIALIX_TYPE_NORMAL 1
  150. #define SPECIALIX_TYPE_CALLOUT 2
  151. static struct tty_driver specialix_driver, specialix_callout_driver;
  152. static int    specialix_refcount;
  153. static struct tty_struct * specialix_table[SX_NBOARD * SX_NPORT];
  154. static struct termios * specialix_termios[SX_NBOARD * SX_NPORT];
  155. static struct termios * specialix_termios_locked[SX_NBOARD * SX_NPORT];
  156. static unsigned char * tmp_buf;
  157. static DECLARE_MUTEX(tmp_buf_sem);
  158. static unsigned long baud_table[] =  {
  159. 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
  160. 9600, 19200, 38400, 57600, 115200, 0, 
  161. };
  162. static struct specialix_board sx_board[SX_NBOARD] =  {
  163. { 0, SX_IOBASE1,  9, },
  164. { 0, SX_IOBASE2, 11, },
  165. { 0, SX_IOBASE3, 12, },
  166. { 0, SX_IOBASE4, 15, },
  167. };
  168. static struct specialix_port sx_port[SX_NBOARD * SX_NPORT];
  169. #ifdef SPECIALIX_TIMER
  170. static struct timer_list missed_irq_timer;
  171. static void sx_interrupt(int irq, void * dev_id, struct pt_regs * regs);
  172. #endif
  173. static inline int sx_paranoia_check(struct specialix_port const * port,
  174.     kdev_t device, const char *routine)
  175. {
  176. #ifdef SPECIALIX_PARANOIA_CHECK
  177. static const char *badmagic =
  178. KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %sn";
  179. static const char *badinfo =
  180. KERN_ERR "sx: Warning: null specialix port for device %s in %sn";
  181.  
  182. if (!port) {
  183. printk(badinfo, kdevname(device), routine);
  184. return 1;
  185. }
  186. if (port->magic != SPECIALIX_MAGIC) {
  187. printk(badmagic, kdevname(device), routine);
  188. return 1;
  189. }
  190. #endif
  191. return 0;
  192. }
  193. /*
  194.  * 
  195.  *  Service functions for specialix IO8+ driver.
  196.  * 
  197.  */
  198. /* Get board number from pointer */
  199. static inline int board_No (struct specialix_board * bp)
  200. {
  201. return bp - sx_board;
  202. }
  203. /* Get port number from pointer */
  204. static inline int port_No (struct specialix_port const * port)
  205. {
  206. return SX_PORT(port - sx_port); 
  207. }
  208. /* Get pointer to board from pointer to port */
  209. static inline struct specialix_board * port_Board(struct specialix_port const * port)
  210. {
  211. return &sx_board[SX_BOARD(port - sx_port)];
  212. }
  213. /* Input Byte from CL CD186x register */
  214. static inline unsigned char sx_in(struct specialix_board  * bp, unsigned short reg)
  215. {
  216. bp->reg = reg | 0x80;
  217. outb (reg | 0x80, bp->base + SX_ADDR_REG);
  218. return inb  (bp->base + SX_DATA_REG);
  219. }
  220. /* Output Byte to CL CD186x register */
  221. static inline void sx_out(struct specialix_board  * bp, unsigned short reg,
  222.   unsigned char val)
  223. {
  224. bp->reg = reg | 0x80;
  225. outb (reg | 0x80, bp->base + SX_ADDR_REG);
  226. outb (val, bp->base + SX_DATA_REG);
  227. }
  228. /* Input Byte from CL CD186x register */
  229. static inline unsigned char sx_in_off(struct specialix_board  * bp, unsigned short reg)
  230. {
  231. bp->reg = reg;
  232. outb (reg, bp->base + SX_ADDR_REG);
  233. return inb  (bp->base + SX_DATA_REG);
  234. }
  235. /* Output Byte to CL CD186x register */
  236. static inline void sx_out_off(struct specialix_board  * bp, unsigned short reg,
  237.   unsigned char val)
  238. {
  239. bp->reg = reg;
  240. outb (reg, bp->base + SX_ADDR_REG);
  241. outb (val, bp->base + SX_DATA_REG);
  242. }
  243. /* Wait for Channel Command Register ready */
  244. static inline void sx_wait_CCR(struct specialix_board  * bp)
  245. {
  246. unsigned long delay;
  247. for (delay = SX_CCR_TIMEOUT; delay; delay--) 
  248. if (!sx_in(bp, CD186x_CCR))
  249. return;
  250. printk(KERN_ERR "sx%d: Timeout waiting for CCR.n", board_No(bp));
  251. }
  252. /* Wait for Channel Command Register ready */
  253. static inline void sx_wait_CCR_off(struct specialix_board  * bp)
  254. {
  255. unsigned long delay;
  256. for (delay = SX_CCR_TIMEOUT; delay; delay--) 
  257. if (!sx_in_off(bp, CD186x_CCR))
  258. return;
  259. printk(KERN_ERR "sx%d: Timeout waiting for CCR.n", board_No(bp));
  260. }
  261. /*
  262.  *  specialix IO8+ IO range functions.
  263.  */
  264. static inline int sx_check_io_range(struct specialix_board * bp)
  265. {
  266. return check_region (bp->base, SX_IO_SPACE);
  267. }
  268. static inline void sx_request_io_range(struct specialix_board * bp)
  269. {
  270. request_region(bp->base, 
  271.                bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE,
  272.                "specialix IO8+" );
  273. }
  274. static inline void sx_release_io_range(struct specialix_board * bp)
  275. {
  276. release_region(bp->base, 
  277.                bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
  278. }
  279. /* Must be called with enabled interrupts */
  280. /* Ugly. Very ugly. Don't use this for anything else than initialization 
  281.    code */
  282. static inline void sx_long_delay(unsigned long delay)
  283. {
  284. unsigned long i;
  285. for (i = jiffies + delay; time_after(i, jiffies); ) ;
  286. }
  287. /* Set the IRQ using the RTS lines that run to the PAL on the board.... */
  288. int sx_set_irq ( struct specialix_board *bp)
  289. {
  290. int virq;
  291. int i;
  292. if (bp->flags & SX_BOARD_IS_PCI) 
  293. return 1;
  294. switch (bp->irq) {
  295. /* In the same order as in the docs... */
  296. case 15: virq = 0;break;
  297. case 12: virq = 1;break;
  298. case 11: virq = 2;break;
  299. case 9:  virq = 3;break;
  300. default: printk (KERN_ERR "Speclialix: cannot set irq to %d.n", bp->irq);
  301.          return 0;
  302. }
  303. for (i=0;i<2;i++) {
  304. sx_out(bp, CD186x_CAR, i);
  305. sx_out(bp, CD186x_MSVRTS, ((virq >> i) & 0x1)? MSVR_RTS:0);
  306. }
  307. return 1;
  308. }
  309. /* Reset and setup CD186x chip */
  310. static int sx_init_CD186x(struct specialix_board  * bp)
  311. {
  312. unsigned long flags;
  313. int scaler;
  314. int rv = 1;
  315. save_flags(flags); cli();
  316. sx_wait_CCR_off(bp);    /* Wait for CCR ready        */
  317. sx_out_off(bp, CD186x_CCR, CCR_HARDRESET);      /* Reset CD186x chip          */
  318. sti();
  319. sx_long_delay(HZ/20);                      /* Delay 0.05 sec            */
  320. cli();
  321. sx_out_off(bp, CD186x_GIVR, SX_ID);             /* Set ID for this chip      */
  322. sx_out_off(bp, CD186x_GICR, 0);                 /* Clear all bits            */
  323. sx_out_off(bp, CD186x_PILR1, SX_ACK_MINT);      /* Prio for modem intr       */
  324. sx_out_off(bp, CD186x_PILR2, SX_ACK_TINT);      /* Prio for transmitter intr */
  325. sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT);      /* Prio for receiver intr    */
  326. /* Set RegAckEn */
  327. sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
  328. /* Setting up prescaler. We need 4 ticks per 1 ms */
  329. scaler =  SX_OSCFREQ/SPECIALIX_TPS;
  330. sx_out_off(bp, CD186x_PPRH, scaler >> 8);
  331. sx_out_off(bp, CD186x_PPRL, scaler & 0xff);
  332. if (!sx_set_irq (bp)) {
  333. /* Figure out how to pass this along... */
  334. printk (KERN_ERR "Cannot set irq to %d.n", bp->irq);
  335. rv = 0;
  336. }
  337. restore_flags(flags);
  338. return rv;
  339. }
  340. int read_cross_byte (struct specialix_board *bp, int reg, int bit)
  341. {
  342. int i;
  343. int t;
  344. for (i=0, t=0;i<8;i++) {
  345. sx_out_off (bp, CD186x_CAR, i);
  346. if (sx_in_off (bp, reg) & bit) 
  347. t |= 1 << i;
  348. }
  349. return t;
  350. }
  351. #ifdef SPECIALIX_TIMER
  352. void missed_irq (unsigned long data)
  353. {
  354. if (sx_in ((struct specialix_board *)data, CD186x_SRSR) &  
  355.                                             (SRSR_RREQint |
  356.                                              SRSR_TREQint |
  357.                                              SRSR_MREQint)) {
  358. printk (KERN_INFO "Missed interrupt... Calling int from timer. n");
  359. sx_interrupt (((struct specialix_board *)data)->irq, 
  360.               NULL, NULL);
  361. }
  362. missed_irq_timer.expires = jiffies + HZ;
  363. add_timer (&missed_irq_timer);
  364. }
  365. #endif
  366. /* Main probing routine, also sets irq. */
  367. static int sx_probe(struct specialix_board *bp)
  368. {
  369. unsigned char val1, val2;
  370. #if 0
  371. int irqs = 0;
  372. int retries;
  373. #endif
  374. int rev;
  375. int chip;
  376. if (sx_check_io_range(bp)) 
  377. return 1;
  378. /* Are the I/O ports here ? */
  379. sx_out_off(bp, CD186x_PPRL, 0x5a);
  380. short_pause ();
  381. val1 = sx_in_off(bp, CD186x_PPRL);
  382. sx_out_off(bp, CD186x_PPRL, 0xa5);
  383. short_pause ();
  384. val2 = sx_in_off(bp, CD186x_PPRL);
  385. if ((val1 != 0x5a) || (val2 != 0xa5)) {
  386. printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.n",
  387.        board_No(bp), bp->base);
  388. return 1;
  389. }
  390. /* Check the DSR lines that Specialix uses as board 
  391.    identification */
  392. val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
  393. val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
  394. #ifdef SPECIALIX_DEBUG
  395. printk (KERN_DEBUG "sx%d: DSR lines are: %02x, rts lines are: %02xn", 
  396.         board_No(bp),  val1, val2);
  397. #endif
  398. /* They managed to switch the bit order between the docs and
  399.    the IO8+ card. The new PCI card now conforms to old docs.
  400.    They changed the PCI docs to reflect the situation on the
  401.    old card. */
  402. val2 = (bp->flags & SX_BOARD_IS_PCI)?0x4d : 0xb2;
  403. if (val1 != val2) {
  404. printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).n",
  405.        board_No(bp), val2, bp->base, val1);
  406. return 1;
  407. }
  408. #if 0
  409. /* It's time to find IRQ for this board */
  410. for (retries = 0; retries < 5 && irqs <= 0; retries++) {
  411. irqs = probe_irq_on();
  412. sx_init_CD186x(bp);         /* Reset CD186x chip       */
  413. sx_out(bp, CD186x_CAR, 2);               /* Select port 2          */
  414. sx_wait_CCR(bp);
  415. sx_out(bp, CD186x_CCR, CCR_TXEN);        /* Enable transmitter     */
  416. sx_out(bp, CD186x_IER, IER_TXRDY);       /* Enable tx empty intr   */
  417. sx_long_delay(HZ/20);        
  418. irqs = probe_irq_off(irqs);
  419. #if SPECIALIX_DEBUG > 2
  420. printk (KERN_DEBUG "SRSR = %02x, ",  sx_in(bp, CD186x_SRSR));
  421. printk (           "TRAR = %02x, ",  sx_in(bp, CD186x_TRAR));
  422. printk (           "GIVR = %02x, ",  sx_in(bp, CD186x_GIVR));
  423. printk (           "GICR = %02x, ",  sx_in(bp, CD186x_GICR));
  424. printk (           "n");
  425. #endif
  426. /* Reset CD186x again      */
  427. if (!sx_init_CD186x(bp)) {
  428. /* Hmmm. This is dead code anyway. */
  429. }
  430. #if SPECIALIX_DEBUG > 2
  431. printk (KERN_DEBUG "val1 = %02x, val2 = %02x, val3 = %02x.n", 
  432.         val1, val2, val3); 
  433. #endif
  434. }
  435. #if 0
  436. if (irqs <= 0) {
  437. printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.n",
  438.        board_No(bp), bp->base);
  439. return 1;
  440. }
  441. #endif
  442. printk (KERN_INFO "Started with irq=%d, but now have irq=%d.n", bp->irq, irqs);
  443. if (irqs > 0)
  444. bp->irq = irqs;
  445. #endif
  446. /* Reset CD186x again  */
  447. if (!sx_init_CD186x(bp)) {
  448. return -EIO;
  449. }
  450. sx_request_io_range(bp);
  451. bp->flags |= SX_BOARD_PRESENT;
  452. /* Chip           revcode   pkgtype
  453.                   GFRCR     SRCR bit 7
  454.    CD180 rev B    0x81      0
  455.    CD180 rev C    0x82      0
  456.    CD1864 rev A   0x82      1
  457.    CD1865 rev A   0x83      1  -- Do not use!!! Does not work. 
  458.    CD1865 rev B   0x84      1
  459.  -- Thanks to Gwen Wang, Cirrus Logic.
  460.  */
  461. switch (sx_in_off(bp, CD186x_GFRCR)) {
  462. case 0x82:chip = 1864;rev='A';break;
  463. case 0x83:chip = 1865;rev='A';break;
  464. case 0x84:chip = 1865;rev='B';break;
  465. case 0x85:chip = 1865;rev='C';break; /* Does not exist at this time */
  466. default:chip=-1;rev='x';
  467. }
  468. #if SPECIALIX_DEBUG > 2
  469. printk (KERN_DEBUG " GFCR = 0x%02xn", sx_in_off(bp, CD186x_GFRCR) );
  470. #endif
  471. #ifdef SPECIALIX_TIMER
  472. init_timer (&missed_irq_timer);
  473. missed_irq_timer.function = missed_irq;
  474. missed_irq_timer.data = (unsigned long) bp;
  475. missed_irq_timer.expires = jiffies + HZ;
  476. add_timer (&missed_irq_timer);
  477. #endif
  478. printk(KERN_INFO"sx%d: specialix IO8+ board detected at 0x%03x, IRQ %d, CD%d Rev. %c.n",
  479.        board_No(bp),
  480.        bp->base, bp->irq,
  481.        chip, rev);
  482. return 0;
  483. }
  484. /* 
  485.  * 
  486.  *  Interrupt processing routines.
  487.  * */
  488. static inline void sx_mark_event(struct specialix_port * port, int event)
  489. {
  490. /* 
  491.  * I'm not quite happy with current scheme all serial
  492.  * drivers use their own BH routine.
  493.  * It seems this easily can be done with one BH routine
  494.  * serving for all serial drivers.
  495.  * For now I must introduce another one - SPECIALIX_BH.
  496.  * Still hope this will be changed in near future.
  497.  * -- Dmitry.
  498.  */
  499. set_bit(event, &port->event);
  500. queue_task(&port->tqueue, &tq_specialix);
  501. mark_bh(SPECIALIX_BH);
  502. }
  503. static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
  504.        unsigned char const * what)
  505. {
  506. unsigned char channel;
  507. struct specialix_port * port;
  508. channel = sx_in(bp, CD186x_GICR) >> GICR_CHAN_OFF;
  509. if (channel < CD186x_NCH) {
  510. port = &sx_port[board_No(bp) * SX_NPORT + channel];
  511. if (port->flags & ASYNC_INITIALIZED) {
  512. return port;
  513. }
  514. }
  515. printk(KERN_INFO "sx%d: %s interrupt from invalid port %dn", 
  516.        board_No(bp), what, channel);
  517. return NULL;
  518. }
  519. static inline void sx_receive_exc(struct specialix_board * bp)
  520. {
  521. struct specialix_port *port;
  522. struct tty_struct *tty;
  523. unsigned char status;
  524. unsigned char ch;
  525. if (!(port = sx_get_port(bp, "Receive")))
  526. return;
  527. tty = port->tty;
  528. if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
  529. printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.n",
  530.        board_No(bp), port_No(port));
  531. return;
  532. }
  533. #ifdef SX_REPORT_OVERRUN
  534. status = sx_in(bp, CD186x_RCSR);
  535. if (status & RCSR_OE) {
  536. port->overrun++;
  537. #if SPECIALIX_DEBUG 
  538. printk(KERN_DEBUG "sx%d: port %d: Overrun. Total %ld overruns.n", 
  539.        board_No(bp), port_No(port), port->overrun);
  540. #endif
  541. }
  542. status &= port->mark_mask;
  543. #else
  544. status = sx_in(bp, CD186x_RCSR) & port->mark_mask;
  545. #endif
  546. ch = sx_in(bp, CD186x_RDR);
  547. if (!status) {
  548. return;
  549. }
  550. if (status & RCSR_TOUT) {
  551. printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?n", 
  552.        board_No(bp), port_No(port));
  553. return;
  554. } else if (status & RCSR_BREAK) {
  555. #ifdef SPECIALIX_DEBUG
  556. printk(KERN_DEBUG "sx%d: port %d: Handling break...n",
  557.        board_No(bp), port_No(port));
  558. #endif
  559. *tty->flip.flag_buf_ptr++ = TTY_BREAK;
  560. if (port->flags & ASYNC_SAK)
  561. do_SAK(tty);
  562. } else if (status & RCSR_PE) 
  563. *tty->flip.flag_buf_ptr++ = TTY_PARITY;
  564. else if (status & RCSR_FE) 
  565. *tty->flip.flag_buf_ptr++ = TTY_FRAME;
  566. else if (status & RCSR_OE)
  567. *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
  568. else
  569. *tty->flip.flag_buf_ptr++ = 0;
  570. *tty->flip.char_buf_ptr++ = ch;
  571. tty->flip.count++;
  572. queue_task(&tty->flip.tqueue, &tq_timer);
  573. }
  574. static inline void sx_receive(struct specialix_board * bp)
  575. {
  576. struct specialix_port *port;
  577. struct tty_struct *tty;
  578. unsigned char count;
  579. if (!(port = sx_get_port(bp, "Receive")))
  580. return;
  581. tty = port->tty;
  582. count = sx_in(bp, CD186x_RDCR);
  583. #ifdef SX_REPORT_FIFO
  584. port->hits[count > 8 ? 9 : count]++;
  585. #endif
  586. while (count--) {
  587. if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
  588. printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.n",
  589.        board_No(bp), port_No(port));
  590. break;
  591. }
  592. *tty->flip.char_buf_ptr++ = sx_in(bp, CD186x_RDR);
  593. *tty->flip.flag_buf_ptr++ = 0;
  594. tty->flip.count++;
  595. }
  596. queue_task(&tty->flip.tqueue, &tq_timer);
  597. }
  598. static inline void sx_transmit(struct specialix_board * bp)
  599. {
  600. struct specialix_port *port;
  601. struct tty_struct *tty;
  602. unsigned char count;
  603. if (!(port = sx_get_port(bp, "Transmit")))
  604. return;
  605. tty = port->tty;
  606. if (port->IER & IER_TXEMPTY) {
  607. /* FIFO drained */
  608. sx_out(bp, CD186x_CAR, port_No(port));
  609. port->IER &= ~IER_TXEMPTY;
  610. sx_out(bp, CD186x_IER, port->IER);
  611. return;
  612. }
  613. if ((port->xmit_cnt <= 0 && !port->break_length)
  614.     || tty->stopped || tty->hw_stopped) {
  615. sx_out(bp, CD186x_CAR, port_No(port));
  616. port->IER &= ~IER_TXRDY;
  617. sx_out(bp, CD186x_IER, port->IER);
  618. return;
  619. }
  620. if (port->break_length) {
  621. if (port->break_length > 0) {
  622. if (port->COR2 & COR2_ETC) {
  623. sx_out(bp, CD186x_TDR, CD186x_C_ESC);
  624. sx_out(bp, CD186x_TDR, CD186x_C_SBRK);
  625. port->COR2 &= ~COR2_ETC;
  626. }
  627. count = MIN(port->break_length, 0xff);
  628. sx_out(bp, CD186x_TDR, CD186x_C_ESC);
  629. sx_out(bp, CD186x_TDR, CD186x_C_DELAY);
  630. sx_out(bp, CD186x_TDR, count);
  631. if (!(port->break_length -= count))
  632. port->break_length--;
  633. } else {
  634. sx_out(bp, CD186x_TDR, CD186x_C_ESC);
  635. sx_out(bp, CD186x_TDR, CD186x_C_EBRK);
  636. sx_out(bp, CD186x_COR2, port->COR2);
  637. sx_wait_CCR(bp);
  638. sx_out(bp, CD186x_CCR, CCR_CORCHG2);
  639. port->break_length = 0;
  640. }
  641. return;
  642. }
  643. count = CD186x_NFIFO;
  644. do {
  645. sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
  646. port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
  647. if (--port->xmit_cnt <= 0)
  648. break;
  649. } while (--count > 0);
  650. if (port->xmit_cnt <= 0) {
  651. sx_out(bp, CD186x_CAR, port_No(port));
  652. port->IER &= ~IER_TXRDY;
  653. sx_out(bp, CD186x_IER, port->IER);
  654. }
  655. if (port->xmit_cnt <= port->wakeup_chars)
  656. sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
  657. }
  658. static inline void sx_check_modem(struct specialix_board * bp)
  659. {
  660. struct specialix_port *port;
  661. struct tty_struct *tty;
  662. unsigned char mcr;
  663. #ifdef SPECIALIX_DEBUG
  664. printk (KERN_DEBUG "Modem intr. ");
  665. #endif
  666. if (!(port = sx_get_port(bp, "Modem")))
  667. return;
  668. tty = port->tty;
  669. mcr = sx_in(bp, CD186x_MCR);
  670. printk ("mcr = %02x.n", mcr);
  671. if ((mcr & MCR_CDCHG)) {
  672. #ifdef SPECIALIX_DEBUG 
  673. printk (KERN_DEBUG "CD just changed... ");
  674. #endif
  675. if (sx_in(bp, CD186x_MSVR) & MSVR_CD) {
  676. #ifdef SPECIALIX_DEBUG
  677. printk ( "Waking up guys in open.n");
  678. #endif
  679. wake_up_interruptible(&port->open_wait);
  680. }
  681. else if (!((port->flags & ASYNC_CALLOUT_ACTIVE) &&
  682.            (port->flags & ASYNC_CALLOUT_NOHUP))) {
  683. #ifdef SPECIALIX_DEBUG
  684. printk ( "Sending HUP.n");
  685. #endif
  686. MOD_INC_USE_COUNT;
  687. if (schedule_task(&port->tqueue_hangup) == 0)
  688. MOD_DEC_USE_COUNT;
  689. } else {
  690. #ifdef SPECIALIX_DEBUG
  691. printk ( "Don't need to send HUP.n");
  692. #endif
  693. }
  694. }
  695. #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
  696. if (mcr & MCR_CTSCHG) {
  697. if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
  698. tty->hw_stopped = 0;
  699. port->IER |= IER_TXRDY;
  700. if (port->xmit_cnt <= port->wakeup_chars)
  701. sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
  702. } else {
  703. tty->hw_stopped = 1;
  704. port->IER &= ~IER_TXRDY;
  705. }
  706. sx_out(bp, CD186x_IER, port->IER);
  707. }
  708. if (mcr & MCR_DSSXHG) {
  709. if (sx_in(bp, CD186x_MSVR) & MSVR_DSR) {
  710. tty->hw_stopped = 0;
  711. port->IER |= IER_TXRDY;
  712. if (port->xmit_cnt <= port->wakeup_chars)
  713. sx_mark_event(port, RS_EVENT_WRITE_WAKEUP);
  714. } else {
  715. tty->hw_stopped = 1;
  716. port->IER &= ~IER_TXRDY;
  717. }
  718. sx_out(bp, CD186x_IER, port->IER);
  719. }
  720. #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
  721. /* Clear change bits */
  722. sx_out(bp, CD186x_MCR, 0);
  723. }
  724. /* The main interrupt processing routine */
  725. static void sx_interrupt(int irq, void * dev_id, struct pt_regs * regs)
  726. {
  727. unsigned char status;
  728. unsigned char ack;
  729. struct specialix_board *bp;
  730. unsigned long loop = 0;
  731. int saved_reg;
  732. bp = dev_id;
  733. if (!bp || !(bp->flags & SX_BOARD_ACTIVE)) {
  734. #ifdef SPECIALIX_DEBUG 
  735. printk (KERN_DEBUG "sx: False interrupt. irq %d.n", irq);
  736. #endif
  737. return;
  738. }
  739. saved_reg = bp->reg;
  740. while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
  741.                                    (SRSR_RREQint |
  742.                             SRSR_TREQint |
  743.                                     SRSR_MREQint)))) {
  744. if (status & SRSR_RREQint) {
  745. ack = sx_in(bp, CD186x_RRAR);
  746. if (ack == (SX_ID | GIVR_IT_RCV))
  747. sx_receive(bp);
  748. else if (ack == (SX_ID | GIVR_IT_REXC))
  749. sx_receive_exc(bp);
  750. else
  751. printk(KERN_ERR "sx%d: Bad receive ack 0x%02x.n",
  752.        board_No(bp), ack);
  753. } else if (status & SRSR_TREQint) {
  754. ack = sx_in(bp, CD186x_TRAR);
  755. if (ack == (SX_ID | GIVR_IT_TX))
  756. sx_transmit(bp);
  757. else
  758. printk(KERN_ERR "sx%d: Bad transmit ack 0x%02x.n",
  759.        board_No(bp), ack);
  760. } else if (status & SRSR_MREQint) {
  761. ack = sx_in(bp, CD186x_MRAR);
  762. if (ack == (SX_ID | GIVR_IT_MODEM)) 
  763. sx_check_modem(bp);
  764. else
  765. printk(KERN_ERR "sx%d: Bad modem ack 0x%02x.n",
  766.        board_No(bp), ack);
  767. sx_out(bp, CD186x_EOIR, 0);   /* Mark end of interrupt */
  768. }
  769. bp->reg = saved_reg;
  770. outb (bp->reg, bp->base + SX_ADDR_REG);
  771. }
  772. /*
  773.  *  Routines for open & close processing.
  774.  */
  775. void turn_ints_off (struct specialix_board *bp)
  776. {
  777. if (bp->flags & SX_BOARD_IS_PCI) {
  778. /* This was intended for enabeling the interrupt on the
  779.  * PCI card. However it seems that it's already enabled
  780.  * and as PCI interrupts can be shared, there is no real
  781.  * reason to have to turn it off. */
  782. }
  783. (void) sx_in_off (bp, 0); /* Turn off interrupts. */
  784. }
  785. void turn_ints_on (struct specialix_board *bp)
  786. {
  787. if (bp->flags & SX_BOARD_IS_PCI) {
  788. /* play with the PCI chip. See comment above. */
  789. }
  790. (void) sx_in (bp, 0); /* Turn ON interrupts. */
  791. }
  792. /* Called with disabled interrupts */
  793. static inline int sx_setup_board(struct specialix_board * bp)
  794. {
  795. int error;
  796. if (bp->flags & SX_BOARD_ACTIVE) 
  797. return 0;
  798. if (bp->flags & SX_BOARD_IS_PCI)
  799. error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT | SA_SHIRQ, "specialix IO8+", bp);
  800. else
  801. error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT, "specialix IO8+", bp);
  802. if (error) 
  803. return error;
  804. turn_ints_on (bp);
  805. bp->flags |= SX_BOARD_ACTIVE;
  806. MOD_INC_USE_COUNT;
  807. return 0;
  808. }
  809. /* Called with disabled interrupts */
  810. static inline void sx_shutdown_board(struct specialix_board *bp)
  811. {
  812. if (!(bp->flags & SX_BOARD_ACTIVE))
  813. return;
  814. bp->flags &= ~SX_BOARD_ACTIVE;
  815. #if SPECIALIX_DEBUG > 2
  816. printk ("Freeing IRQ%d for board %d.n", bp->irq, board_No (bp));
  817. #endif
  818. free_irq(bp->irq, bp);
  819. turn_ints_off (bp);
  820. MOD_DEC_USE_COUNT;
  821. }
  822. /*
  823.  * Setting up port characteristics. 
  824.  * Must be called with disabled interrupts
  825.  */
  826. static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
  827. {
  828. struct tty_struct *tty;
  829. unsigned long baud;
  830. long tmp;
  831. unsigned char cor1 = 0, cor3 = 0;
  832. unsigned char mcor1 = 0, mcor2 = 0;
  833. static int again;
  834. if (!(tty = port->tty) || !tty->termios)
  835. return;
  836. port->IER  = 0;
  837. port->COR2 = 0;
  838. /* Select port on the board */
  839. sx_out(bp, CD186x_CAR, port_No(port));
  840. /* The Specialix board doens't implement the RTS lines.
  841.    They are used to set the IRQ level. Don't touch them. */
  842. if (SX_CRTSCTS(tty))
  843. port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
  844. else
  845. port->MSVR =  (sx_in(bp, CD186x_MSVR) & MSVR_RTS);
  846. #ifdef DEBUG_SPECIALIX
  847. printk (KERN_DEBUG "sx: got MSVR=%02x.n", port->MSVR);
  848. #endif
  849. baud = C_BAUD(tty);
  850. if (baud & CBAUDEX) {
  851. baud &= ~CBAUDEX;
  852. if (baud < 1 || baud > 2) 
  853. port->tty->termios->c_cflag &= ~CBAUDEX;
  854. else
  855. baud += 15;
  856. }
  857. if (baud == 15) {
  858. if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
  859. baud ++;
  860. if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
  861. baud += 2;
  862. }
  863. if (!baud_table[baud]) {
  864. /* Drop DTR & exit */
  865. #ifdef SPECIALIX_DEBUG
  866. printk (KERN_DEBUG "Dropping DTR...  Hmm....n");
  867. #endif
  868. if (!SX_CRTSCTS (tty)) {
  869. port -> MSVR &= ~ MSVR_DTR;
  870. sx_out(bp, CD186x_MSVR, port->MSVR );
  871. #ifdef DEBUG_SPECIALIX
  872. else
  873. printk (KERN_DEBUG "Can't drop DTR: no DTR.n");
  874. #endif
  875. return;
  876. } else {
  877. /* Set DTR on */
  878. if (!SX_CRTSCTS (tty)) {
  879. port ->MSVR |= MSVR_DTR;
  880. }
  881. }
  882. /*
  883.  * Now we must calculate some speed depended things 
  884.  */
  885. /* Set baud rate for port */
  886. tmp = port->custom_divisor ;
  887. if ( tmp )
  888. printk (KERN_INFO "sx%d: Using custom baud rate divisor %ld. n"
  889.                   "This is an untested option, please be carefull.n",
  890.                   port_No (port), tmp);
  891. else
  892. tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
  893.          CD186x_TPC/2) / CD186x_TPC);
  894. if ((tmp < 0x10) && time_before(again, jiffies)) { 
  895. again = jiffies + HZ * 60;
  896. /* Page 48 of version 2.0 of the CL-CD1865 databook */
  897. if (tmp >= 12) {
  898. printk (KERN_INFO "sx%d: Baud rate divisor is %ld. n"
  899.         "Performance degradation is possible.n"
  900.         "Read specialix.txt for more info.n",
  901.         port_No (port), tmp);
  902. } else {
  903. printk (KERN_INFO "sx%d: Baud rate divisor is %ld. n"
  904.         "Warning: overstressing Cirrus chip. "
  905.         "This might not work.n"
  906.         "Read specialix.txt for more info.n", 
  907.         port_No (port), tmp);
  908. }
  909. }
  910. sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff); 
  911. sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff); 
  912. sx_out(bp, CD186x_RBPRL, tmp & 0xff); 
  913. sx_out(bp, CD186x_TBPRL, tmp & 0xff);
  914. if (port->custom_divisor) {
  915. baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
  916. baud = ( baud + 5 ) / 10;
  917. } else 
  918. baud = (baud_table[baud] + 5) / 10;   /* Estimated CPS */
  919. /* Two timer ticks seems enough to wakeup something like SLIP driver */
  920. tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
  921. port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
  922.       SERIAL_XMIT_SIZE - 1 : tmp);
  923. /* Receiver timeout will be transmission time for 1.5 chars */
  924. tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
  925. tmp = (tmp > 0xff) ? 0xff : tmp;
  926. sx_out(bp, CD186x_RTPR, tmp);
  927. switch (C_CSIZE(tty)) {
  928.  case CS5:
  929. cor1 |= COR1_5BITS;
  930. break;
  931.  case CS6:
  932. cor1 |= COR1_6BITS;
  933. break;
  934.  case CS7:
  935. cor1 |= COR1_7BITS;
  936. break;
  937.  case CS8:
  938. cor1 |= COR1_8BITS;
  939. break;
  940. }
  941. if (C_CSTOPB(tty)) 
  942. cor1 |= COR1_2SB;
  943. cor1 |= COR1_IGNORE;
  944. if (C_PARENB(tty)) {
  945. cor1 |= COR1_NORMPAR;
  946. if (C_PARODD(tty)) 
  947. cor1 |= COR1_ODDP;
  948. if (I_INPCK(tty)) 
  949. cor1 &= ~COR1_IGNORE;
  950. }
  951. /* Set marking of some errors */
  952. port->mark_mask = RCSR_OE | RCSR_TOUT;
  953. if (I_INPCK(tty)) 
  954. port->mark_mask |= RCSR_FE | RCSR_PE;
  955. if (I_BRKINT(tty) || I_PARMRK(tty)) 
  956. port->mark_mask |= RCSR_BREAK;
  957. if (I_IGNPAR(tty)) 
  958. port->mark_mask &= ~(RCSR_FE | RCSR_PE);
  959. if (I_IGNBRK(tty)) {
  960. port->mark_mask &= ~RCSR_BREAK;
  961. if (I_IGNPAR(tty)) 
  962. /* Real raw mode. Ignore all */
  963. port->mark_mask &= ~RCSR_OE;
  964. }
  965. /* Enable Hardware Flow Control */
  966. if (C_CRTSCTS(tty)) {
  967. #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
  968. port->IER |= IER_DSR | IER_CTS;
  969. mcor1 |= MCOR1_DSRZD | MCOR1_CTSZD;
  970. mcor2 |= MCOR2_DSROD | MCOR2_CTSOD;
  971. tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
  972. #else
  973. port->COR2 |= COR2_CTSAE; 
  974. #endif
  975. }
  976. /* Enable Software Flow Control. FIXME: I'm not sure about this */
  977. /* Some people reported that it works, but I still doubt it */
  978. if (I_IXON(tty)) {
  979. port->COR2 |= COR2_TXIBE;
  980. cor3 |= (COR3_FCT | COR3_SCDE);
  981. if (I_IXANY(tty))
  982. port->COR2 |= COR2_IXM;
  983. sx_out(bp, CD186x_SCHR1, START_CHAR(tty));
  984. sx_out(bp, CD186x_SCHR2, STOP_CHAR(tty));
  985. sx_out(bp, CD186x_SCHR3, START_CHAR(tty));
  986. sx_out(bp, CD186x_SCHR4, STOP_CHAR(tty));
  987. }
  988. if (!C_CLOCAL(tty)) {
  989. /* Enable CD check */
  990. port->IER |= IER_CD;
  991. mcor1 |= MCOR1_CDZD;
  992. mcor2 |= MCOR2_CDOD;
  993. }
  994. if (C_CREAD(tty)) 
  995. /* Enable receiver */
  996. port->IER |= IER_RXD;
  997. /* Set input FIFO size (1-8 bytes) */
  998. cor3 |= SPECIALIX_RXFIFO; 
  999. /* Setting up CD186x channel registers */
  1000. sx_out(bp, CD186x_COR1, cor1);
  1001. sx_out(bp, CD186x_COR2, port->COR2);
  1002. sx_out(bp, CD186x_COR3, cor3);
  1003. /* Make CD186x know about registers change */
  1004. sx_wait_CCR(bp);
  1005. sx_out(bp, CD186x_CCR, CCR_CORCHG1 | CCR_CORCHG2 | CCR_CORCHG3);
  1006. /* Setting up modem option registers */
  1007. #ifdef DEBUG_SPECIALIX
  1008. printk ("Mcor1 = %02x, mcor2 = %02x.n", mcor1, mcor2);
  1009. #endif
  1010. sx_out(bp, CD186x_MCOR1, mcor1);
  1011. sx_out(bp, CD186x_MCOR2, mcor2);
  1012. /* Enable CD186x transmitter & receiver */
  1013. sx_wait_CCR(bp);
  1014. sx_out(bp, CD186x_CCR, CCR_TXEN | CCR_RXEN);
  1015. /* Enable interrupts */
  1016. sx_out(bp, CD186x_IER, port->IER);
  1017. /* And finally set the modem lines... */
  1018. sx_out(bp, CD186x_MSVR, port->MSVR);
  1019. }
  1020. /* Must be called with interrupts enabled */
  1021. static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port)
  1022. {
  1023. unsigned long flags;
  1024. if (port->flags & ASYNC_INITIALIZED)
  1025. return 0;
  1026. if (!port->xmit_buf) {
  1027. /* We may sleep in get_free_page() */
  1028. unsigned long tmp;
  1029. if (!(tmp = get_free_page(GFP_KERNEL)))
  1030. return -ENOMEM;
  1031. if (port->xmit_buf) {
  1032. free_page(tmp);
  1033. return -ERESTARTSYS;
  1034. }
  1035. port->xmit_buf = (unsigned char *) tmp;
  1036. }
  1037. save_flags(flags); cli();
  1038. if (port->tty) 
  1039. clear_bit(TTY_IO_ERROR, &port->tty->flags);
  1040. if (port->count == 1) 
  1041. bp->count++;
  1042. port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
  1043. sx_change_speed(bp, port);
  1044. port->flags |= ASYNC_INITIALIZED;
  1045. restore_flags(flags);
  1046. return 0;
  1047. }
  1048. /* Must be called with interrupts disabled */
  1049. static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *port)
  1050. {
  1051. struct tty_struct *tty;
  1052. if (!(port->flags & ASYNC_INITIALIZED)) 
  1053. return;
  1054. #ifdef SX_REPORT_OVERRUN
  1055. printk(KERN_INFO "sx%d: port %d: Total %ld overruns were detected.n",
  1056.        board_No(bp), port_No(port), port->overrun);
  1057. #endif
  1058. #ifdef SX_REPORT_FIFO
  1059. {
  1060. int i;
  1061. printk(KERN_INFO "sx%d: port %d: FIFO hits [ ",
  1062.        board_No(bp), port_No(port));
  1063. for (i = 0; i < 10; i++) {
  1064. printk("%ld ", port->hits[i]);
  1065. }
  1066. printk("].n");
  1067. }
  1068. #endif
  1069. if (port->xmit_buf) {
  1070. free_page((unsigned long) port->xmit_buf);
  1071. port->xmit_buf = NULL;
  1072. }
  1073. /* Select port */
  1074. sx_out(bp, CD186x_CAR, port_No(port));
  1075. if (!(tty = port->tty) || C_HUPCL(tty)) {
  1076. /* Drop DTR */
  1077. sx_out(bp, CD186x_MSVDTR, 0);
  1078. }
  1079. /* Reset port */
  1080. sx_wait_CCR(bp);
  1081. sx_out(bp, CD186x_CCR, CCR_SOFTRESET);
  1082. /* Disable all interrupts from this port */
  1083. port->IER = 0;
  1084. sx_out(bp, CD186x_IER, port->IER);
  1085. if (tty)
  1086. set_bit(TTY_IO_ERROR, &tty->flags);
  1087. port->flags &= ~ASYNC_INITIALIZED;
  1088. if (--bp->count < 0) {
  1089. printk(KERN_ERR "sx%d: sx_shutdown_port: bad board count: %dn",
  1090.        board_No(bp), bp->count);
  1091. bp->count = 0;
  1092. }
  1093. /*
  1094.  * If this is the last opened port on the board
  1095.  * shutdown whole board
  1096.  */
  1097. if (!bp->count) 
  1098. sx_shutdown_board(bp);
  1099. }
  1100. static int block_til_ready(struct tty_struct *tty, struct file * filp,
  1101.                            struct specialix_port *port)
  1102. {
  1103. DECLARE_WAITQUEUE(wait,  current);
  1104. struct specialix_board *bp = port_Board(port);
  1105. int    retval;
  1106. int    do_clocal = 0;
  1107. int    CD;
  1108. /*
  1109.  * If the device is in the middle of being closed, then block
  1110.  * until it's done, and then try again.
  1111.  */
  1112. if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) {
  1113. interruptible_sleep_on(&port->close_wait);
  1114. if (port->flags & ASYNC_HUP_NOTIFY)
  1115. return -EAGAIN;
  1116. else
  1117. return -ERESTARTSYS;
  1118. }
  1119. /*
  1120.  * If this is a callout device, then just make sure the normal
  1121.  * device isn't being used.
  1122.  */
  1123. if (tty->driver.subtype == SPECIALIX_TYPE_CALLOUT) {
  1124. if (port->flags & ASYNC_NORMAL_ACTIVE)
  1125. return -EBUSY;
  1126. if ((port->flags & ASYNC_CALLOUT_ACTIVE) &&
  1127.     (port->flags & ASYNC_SESSION_LOCKOUT) &&
  1128.     (port->session != current->session))
  1129. return -EBUSY;
  1130. if ((port->flags & ASYNC_CALLOUT_ACTIVE) &&
  1131.     (port->flags & ASYNC_PGRP_LOCKOUT) &&
  1132.     (port->pgrp != current->pgrp))
  1133. return -EBUSY;
  1134. port->flags |= ASYNC_CALLOUT_ACTIVE;
  1135. return 0;
  1136. }
  1137. /*
  1138.  * If non-blocking mode is set, or the port is not enabled,
  1139.  * then make the check up front and then exit.
  1140.  */
  1141. if ((filp->f_flags & O_NONBLOCK) ||
  1142.     (tty->flags & (1 << TTY_IO_ERROR))) {
  1143. if (port->flags & ASYNC_CALLOUT_ACTIVE)
  1144. return -EBUSY;
  1145. port->flags |= ASYNC_NORMAL_ACTIVE;
  1146. return 0;
  1147. }
  1148. if (port->flags & ASYNC_CALLOUT_ACTIVE) {
  1149. if (port->normal_termios.c_cflag & CLOCAL) 
  1150. do_clocal = 1;
  1151. } else {
  1152. if (C_CLOCAL(tty))
  1153. do_clocal = 1;
  1154. }
  1155. /*
  1156.  * Block waiting for the carrier detect and the line to become
  1157.  * free (i.e., not in use by the callout).  While we are in
  1158.  * this loop, info->count is dropped by one, so that
  1159.  * rs_close() knows when to free things.  We restore it upon
  1160.  * exit, either normal or abnormal.
  1161.  */
  1162. retval = 0;
  1163. add_wait_queue(&port->open_wait, &wait);
  1164. cli();
  1165. if (!tty_hung_up_p(filp))
  1166. port->count--;
  1167. sti();
  1168. port->blocked_open++;
  1169. while (1) {
  1170. cli();
  1171. sx_out(bp, CD186x_CAR, port_No(port));
  1172. CD = sx_in(bp, CD186x_MSVR) & MSVR_CD;
  1173. if (!(port->flags & ASYNC_CALLOUT_ACTIVE)) {
  1174. if (SX_CRTSCTS (tty)) {
  1175. /* Activate RTS */
  1176. port->MSVR |= MSVR_DTR;
  1177. sx_out (bp, CD186x_MSVR, port->MSVR);
  1178. } else {
  1179. /* Activate DTR */
  1180. port->MSVR |= MSVR_DTR;
  1181. sx_out (bp, CD186x_MSVR, port->MSVR);
  1182. }
  1183. sti();
  1184. set_current_state(TASK_INTERRUPTIBLE);
  1185. if (tty_hung_up_p(filp) ||
  1186.     !(port->flags & ASYNC_INITIALIZED)) {
  1187. if (port->flags & ASYNC_HUP_NOTIFY)
  1188. retval = -EAGAIN;
  1189. else
  1190. retval = -ERESTARTSYS;
  1191. break;
  1192. }
  1193. if (!(port->flags & ASYNC_CALLOUT_ACTIVE) &&
  1194.     !(port->flags & ASYNC_CLOSING) &&
  1195.     (do_clocal || CD))
  1196. break;
  1197. if (signal_pending(current)) {
  1198. retval = -ERESTARTSYS;
  1199. break;
  1200. }
  1201. schedule();
  1202. }
  1203. current->state = TASK_RUNNING;
  1204. remove_wait_queue(&port->open_wait, &wait);
  1205. if (!tty_hung_up_p(filp))
  1206. port->count++;
  1207. port->blocked_open--;
  1208. if (retval)
  1209. return retval;
  1210. port->flags |= ASYNC_NORMAL_ACTIVE;
  1211. return 0;
  1212. }
  1213. static int sx_open(struct tty_struct * tty, struct file * filp)
  1214. {
  1215. int board;
  1216. int error;
  1217. struct specialix_port * port;
  1218. struct specialix_board * bp;
  1219. unsigned long flags;
  1220. board = SX_BOARD(MINOR(tty->device));
  1221. if (board > SX_NBOARD || !(sx_board[board].flags & SX_BOARD_PRESENT))
  1222. return -ENODEV;
  1223. bp = &sx_board[board];
  1224. port = sx_port + board * SX_NPORT + SX_PORT(MINOR(tty->device));
  1225. #ifdef DEBUG_SPECIALIX
  1226. printk (KERN_DEBUG "Board = %d, bp = %p, port = %p, portno = %d.n", 
  1227.         board, bp, port, SX_PORT(MINOR(tty->device)));
  1228. #endif
  1229. if (sx_paranoia_check(port, tty->device, "sx_open"))
  1230. return -ENODEV;
  1231. if ((error = sx_setup_board(bp)))
  1232. return error;
  1233. port->count++;
  1234. tty->driver_data = port;
  1235. port->tty = tty;
  1236. if ((error = sx_setup_port(bp, port))) 
  1237. return error;
  1238. if ((error = block_til_ready(tty, filp, port)))
  1239. return error;
  1240. if ((port->count == 1) && (port->flags & ASYNC_SPLIT_TERMIOS)) {
  1241. if (tty->driver.subtype == SPECIALIX_TYPE_NORMAL)
  1242. *tty->termios = port->normal_termios;
  1243. else
  1244. *tty->termios = port->callout_termios;
  1245. save_flags(flags); cli();
  1246. sx_change_speed(bp, port);
  1247. restore_flags(flags);
  1248. }
  1249. port->session = current->session;
  1250. port->pgrp = current->pgrp;
  1251. return 0;
  1252. }
  1253. static void sx_close(struct tty_struct * tty, struct file * filp)
  1254. {
  1255. struct specialix_port *port = (struct specialix_port *) tty->driver_data;
  1256. struct specialix_board *bp;
  1257. unsigned long flags;
  1258. unsigned long timeout;
  1259. if (!port || sx_paranoia_check(port, tty->device, "close"))
  1260. return;
  1261. save_flags(flags); cli();
  1262. if (tty_hung_up_p(filp)) {
  1263. restore_flags(flags);
  1264. return;
  1265. }
  1266. bp = port_Board(port);
  1267. if ((tty->count == 1) && (port->count != 1)) {
  1268. printk(KERN_ERR "sx%d: sx_close: bad port count;"
  1269.        " tty->count is 1, port count is %dn",
  1270.        board_No(bp), port->count);
  1271. port->count = 1;
  1272. }
  1273. if (--port->count < 0) {
  1274. printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %dn",
  1275.        board_No(bp), port_No(port), port->count);
  1276. port->count = 0;
  1277. }
  1278. if (port->count) {
  1279. restore_flags(flags);
  1280. return;
  1281. }
  1282. port->flags |= ASYNC_CLOSING;
  1283. /*
  1284.  * Save the termios structure, since this port may have
  1285.  * separate termios for callout and dialin.
  1286.  */
  1287. if (port->flags & ASYNC_NORMAL_ACTIVE)
  1288. port->normal_termios = *tty->termios;
  1289. if (port->flags & ASYNC_CALLOUT_ACTIVE)
  1290. port->callout_termios = *tty->termios;
  1291. /*
  1292.  * Now we wait for the transmit buffer to clear; and we notify 
  1293.  * the line discipline to only process XON/XOFF characters.
  1294.  */
  1295. tty->closing = 1;
  1296. if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
  1297. tty_wait_until_sent(tty, port->closing_wait);
  1298. /*
  1299.  * At this point we stop accepting input.  To do this, we
  1300.  * disable the receive line status interrupts, and tell the
  1301.  * interrupt driver to stop checking the data ready bit in the
  1302.  * line status register.
  1303.  */
  1304. port->IER &= ~IER_RXD;
  1305. if (port->flags & ASYNC_INITIALIZED) {
  1306. port->IER &= ~IER_TXRDY;
  1307. port->IER |= IER_TXEMPTY;
  1308. sx_out(bp, CD186x_CAR, port_No(port));
  1309. sx_out(bp, CD186x_IER, port->IER);
  1310. /*
  1311.  * Before we drop DTR, make sure the UART transmitter
  1312.  * has completely drained; this is especially
  1313.  * important if there is a transmit FIFO!
  1314.  */
  1315. timeout = jiffies+HZ;
  1316. while(port->IER & IER_TXEMPTY) {
  1317. current->state = TASK_INTERRUPTIBLE;
  1318.   schedule_timeout(port->timeout);
  1319. if (time_after(jiffies, timeout)) {
  1320. printk (KERN_INFO "Timeout waiting for closen");
  1321. break;
  1322. }
  1323. }
  1324. }
  1325. sx_shutdown_port(bp, port);
  1326. if (tty->driver.flush_buffer)
  1327. tty->driver.flush_buffer(tty);
  1328. if (tty->ldisc.flush_buffer)
  1329. tty->ldisc.flush_buffer(tty);
  1330. tty->closing = 0;
  1331. port->event = 0;
  1332. port->tty = 0;
  1333. if (port->blocked_open) {
  1334. if (port->close_delay) {
  1335. current->state = TASK_INTERRUPTIBLE;
  1336. schedule_timeout(port->close_delay);
  1337. }
  1338. wake_up_interruptible(&port->open_wait);
  1339. }
  1340. port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
  1341.  ASYNC_CLOSING);
  1342. wake_up_interruptible(&port->close_wait);
  1343. restore_flags(flags);
  1344. }
  1345. static int sx_write(struct tty_struct * tty, int from_user, 
  1346.                     const unsigned char *buf, int count)
  1347. {
  1348. struct specialix_port *port = (struct specialix_port *)tty->driver_data;
  1349. struct specialix_board *bp;
  1350. int c, total = 0;
  1351. unsigned long flags;
  1352. if (sx_paranoia_check(port, tty->device, "sx_write"))
  1353. return 0;
  1354. bp = port_Board(port);
  1355. if (!tty || !port->xmit_buf || !tmp_buf)
  1356. return 0;
  1357. save_flags(flags);
  1358. if (from_user) {
  1359. down(&tmp_buf_sem);
  1360. while (1) {
  1361. c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
  1362.    SERIAL_XMIT_SIZE - port->xmit_head));
  1363. if (c <= 0)
  1364. break;
  1365. c -= copy_from_user(tmp_buf, buf, c);
  1366. if (!c) {
  1367. if (!total)
  1368. total = -EFAULT;
  1369. break;
  1370. }
  1371. cli();
  1372. c = MIN(c, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
  1373.        SERIAL_XMIT_SIZE - port->xmit_head));
  1374. memcpy(port->xmit_buf + port->xmit_head, tmp_buf, c);
  1375. port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
  1376. port->xmit_cnt += c;
  1377. restore_flags(flags);
  1378. buf += c;
  1379. count -= c;
  1380. total += c;
  1381. }
  1382. up(&tmp_buf_sem);
  1383. } else {
  1384. while (1) {
  1385. cli();
  1386. c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
  1387.    SERIAL_XMIT_SIZE - port->xmit_head));
  1388. if (c <= 0) {
  1389. restore_flags(flags);
  1390. break;
  1391. }
  1392. memcpy(port->xmit_buf + port->xmit_head, buf, c);
  1393. port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
  1394. port->xmit_cnt += c;
  1395. restore_flags(flags);
  1396. buf += c;
  1397. count -= c;
  1398. total += c;
  1399. }
  1400. }
  1401. cli();
  1402. if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
  1403.     !(port->IER & IER_TXRDY)) {
  1404. port->IER |= IER_TXRDY;
  1405. sx_out(bp, CD186x_CAR, port_No(port));
  1406. sx_out(bp, CD186x_IER, port->IER);
  1407. }
  1408. restore_flags(flags);
  1409. return total;
  1410. }
  1411. static void sx_put_char(struct tty_struct * tty, unsigned char ch)
  1412. {
  1413. struct specialix_port *port = (struct specialix_port *)tty->driver_data;
  1414. unsigned long flags;
  1415. if (sx_paranoia_check(port, tty->device, "sx_put_char"))
  1416. return;
  1417. if (!tty || !port->xmit_buf)
  1418. return;
  1419. save_flags(flags); cli();
  1420. if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
  1421. restore_flags(flags);
  1422. return;
  1423. }
  1424. port->xmit_buf[port->xmit_head++] = ch;
  1425. port->xmit_head &= SERIAL_XMIT_SIZE - 1;
  1426. port->xmit_cnt++;
  1427. restore_flags(flags);
  1428. }
  1429. static void sx_flush_chars(struct tty_struct * tty)
  1430. {
  1431. struct specialix_port *port = (struct specialix_port *)tty->driver_data;
  1432. unsigned long flags;
  1433. if (sx_paranoia_check(port, tty->device, "sx_flush_chars"))
  1434. return;
  1435. if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
  1436.     !port->xmit_buf)
  1437. return;
  1438. save_flags(flags); cli();
  1439. port->IER |= IER_TXRDY;
  1440. sx_out(port_Board(port), CD186x_CAR, port_No(port));
  1441. sx_out(port_Board(port), CD186x_IER, port->IER);
  1442. restore_flags(flags);
  1443. }
  1444. static int sx_write_room(struct tty_struct * tty)
  1445. {
  1446. struct specialix_port *port = (struct specialix_port *)tty->driver_data;
  1447. int ret;
  1448. if (sx_paranoia_check(port, tty->device, "sx_write_room"))
  1449. return 0;
  1450. ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
  1451. if (ret < 0)
  1452. ret = 0;
  1453. return ret;
  1454. }
  1455. static int sx_chars_in_buffer(struct tty_struct *tty)
  1456. {
  1457. struct specialix_port *port = (struct specialix_port *)tty->driver_data;
  1458. if (sx_paranoia_check(port, tty->device, "sx_chars_in_buffer"))
  1459. return 0;
  1460. return port->xmit_cnt;
  1461. }
  1462. static void sx_flush_buffer(struct tty_struct *tty)
  1463. {
  1464. struct specialix_port *port = (struct specialix_port *)tty->driver_data;
  1465. unsigned long flags;
  1466. if (sx_paranoia_check(port, tty->device, "sx_flush_buffer"))
  1467. return;
  1468. save_flags(flags); cli();
  1469. port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
  1470. restore_flags(flags);
  1471. wake_up_interruptible(&tty->write_wait);
  1472. if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
  1473.     tty->ldisc.write_wakeup)
  1474. (tty->ldisc.write_wakeup)(tty);
  1475. }
  1476. static int sx_get_modem_info(struct specialix_port * port, unsigned int *value)
  1477. {
  1478. struct specialix_board * bp;
  1479. unsigned char status;
  1480. unsigned int result;
  1481. unsigned long flags;
  1482. bp = port_Board(port);
  1483. save_flags(flags); cli();
  1484. sx_out(bp, CD186x_CAR, port_No(port));
  1485. status = sx_in(bp, CD186x_MSVR);
  1486. restore_flags(flags);
  1487. #ifdef DEBUG_SPECIALIX
  1488. printk (KERN_DEBUG "Got msvr[%d] = %02x, car = %d.n", 
  1489. port_No(port), status, sx_in (bp, CD186x_CAR));
  1490. printk (KERN_DEBUG "sx_port = %p, port = %pn", sx_port, port);
  1491. #endif
  1492. if (SX_CRTSCTS(port->tty)) {
  1493. result  = /*   (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */ 
  1494.           |   ((status & MSVR_DTR) ? TIOCM_RTS : 0)
  1495.           |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
  1496.           |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
  1497.           |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
  1498. } else {
  1499. result  = /*   (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */ 
  1500.           |   ((status & MSVR_DTR) ? TIOCM_DTR : 0)
  1501.           |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
  1502.           |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
  1503.           |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
  1504. }
  1505. put_user(result,(unsigned int *) value);
  1506. return 0;
  1507. }
  1508. static int sx_set_modem_info(struct specialix_port * port, unsigned int cmd,
  1509.                              unsigned int *value)
  1510. {
  1511. int error;
  1512. unsigned int arg;
  1513. unsigned long flags;
  1514. struct specialix_board *bp = port_Board(port);
  1515. error = verify_area(VERIFY_READ, value, sizeof(int));
  1516. if (error) 
  1517. return error;
  1518. Get_user(arg, (unsigned long *) value);
  1519. switch (cmd) {
  1520. case TIOCMBIS: 
  1521.    /* if (arg & TIOCM_RTS) 
  1522. port->MSVR |= MSVR_RTS; */
  1523.    /*   if (arg & TIOCM_DTR)
  1524. port->MSVR |= MSVR_DTR; */
  1525. if (SX_CRTSCTS(port->tty)) {
  1526. if (arg & TIOCM_RTS)
  1527. port->MSVR |= MSVR_DTR; 
  1528. } else {
  1529. if (arg & TIOCM_DTR)
  1530. port->MSVR |= MSVR_DTR; 
  1531. }      
  1532. break;
  1533. case TIOCMBIC:
  1534.   /* if (arg & TIOCM_RTS)
  1535. port->MSVR &= ~MSVR_RTS; */
  1536.   /*    if (arg & TIOCM_DTR)
  1537. port->MSVR &= ~MSVR_DTR; */
  1538. if (SX_CRTSCTS(port->tty)) {
  1539. if (arg & TIOCM_RTS)
  1540. port->MSVR &= ~MSVR_DTR;
  1541. } else {
  1542. if (arg & TIOCM_DTR)
  1543. port->MSVR &= ~MSVR_DTR;
  1544. }
  1545. break;
  1546. case TIOCMSET:
  1547.   /* port->MSVR = (arg & TIOCM_RTS) ? (port->MSVR | MSVR_RTS) : 
  1548.  (port->MSVR & ~MSVR_RTS); */
  1549.   /* port->MSVR = (arg & TIOCM_DTR) ? (port->MSVR | MSVR_DTR) : 
  1550.  (port->MSVR & ~MSVR_DTR); */
  1551. if (SX_CRTSCTS(port->tty)) {
  1552.    port->MSVR = (arg & TIOCM_RTS) ? 
  1553.                          (port->MSVR |  MSVR_DTR) : 
  1554.                          (port->MSVR & ~MSVR_DTR);
  1555. } else {
  1556. port->MSVR = (arg & TIOCM_DTR) ?
  1557.                          (port->MSVR |  MSVR_DTR):
  1558.                          (port->MSVR & ~MSVR_DTR);
  1559. }
  1560. break;
  1561. default:
  1562. return -EINVAL;
  1563. }
  1564. save_flags(flags); cli();
  1565. sx_out(bp, CD186x_CAR, port_No(port));
  1566. sx_out(bp, CD186x_MSVR, port->MSVR);
  1567. restore_flags(flags);
  1568. return 0;
  1569. }
  1570. static inline void sx_send_break(struct specialix_port * port, unsigned long length)
  1571. {
  1572. struct specialix_board *bp = port_Board(port);
  1573. unsigned long flags;
  1574. save_flags(flags); cli();
  1575. port->break_length = SPECIALIX_TPS / HZ * length;
  1576. port->COR2 |= COR2_ETC;
  1577. port->IER  |= IER_TXRDY;
  1578. sx_out(bp, CD186x_CAR, port_No(port));
  1579. sx_out(bp, CD186x_COR2, port->COR2);
  1580. sx_out(bp, CD186x_IER, port->IER);
  1581. sx_wait_CCR(bp);
  1582. sx_out(bp, CD186x_CCR, CCR_CORCHG2);
  1583. sx_wait_CCR(bp);
  1584. restore_flags(flags);
  1585. }
  1586. static inline int sx_set_serial_info(struct specialix_port * port,
  1587.                                      struct serial_struct * newinfo)
  1588. {
  1589. struct serial_struct tmp;
  1590. struct specialix_board *bp = port_Board(port);
  1591. int change_speed;
  1592. unsigned long flags;
  1593. int error;
  1594. error = verify_area(VERIFY_READ, (void *) newinfo, sizeof(tmp));
  1595. if (error)
  1596. return error;
  1597. if (copy_from_user(&tmp, newinfo, sizeof(tmp)))
  1598. return -EFAULT;
  1599. #if 0
  1600. if ((tmp.irq != bp->irq) ||
  1601.     (tmp.port != bp->base) ||
  1602.     (tmp.type != PORT_CIRRUS) ||
  1603.     (tmp.baud_base != (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC) ||
  1604.     (tmp.custom_divisor != 0) ||
  1605.     (tmp.xmit_fifo_size != CD186x_NFIFO) ||
  1606.     (tmp.flags & ~SPECIALIX_LEGAL_FLAGS))
  1607. return -EINVAL;
  1608. #endif
  1609. change_speed = ((port->flags & ASYNC_SPD_MASK) !=
  1610. (tmp.flags & ASYNC_SPD_MASK));
  1611. change_speed |= (tmp.custom_divisor != port->custom_divisor);
  1612. if (!capable(CAP_SYS_ADMIN)) {
  1613. if ((tmp.close_delay != port->close_delay) ||
  1614.     (tmp.closing_wait != port->closing_wait) ||
  1615.     ((tmp.flags & ~ASYNC_USR_MASK) !=
  1616.      (port->flags & ~ASYNC_USR_MASK)))
  1617. return -EPERM;
  1618. port->flags = ((port->flags & ~ASYNC_USR_MASK) |
  1619.                   (tmp.flags & ASYNC_USR_MASK));
  1620. port->custom_divisor = tmp.custom_divisor;
  1621. } else {
  1622. port->flags = ((port->flags & ~ASYNC_FLAGS) |
  1623.                   (tmp.flags & ASYNC_FLAGS));
  1624. port->close_delay = tmp.close_delay;
  1625. port->closing_wait = tmp.closing_wait;
  1626. port->custom_divisor = tmp.custom_divisor;
  1627. }
  1628. if (change_speed) {
  1629. save_flags(flags); cli();
  1630. sx_change_speed(bp, port);
  1631. restore_flags(flags);
  1632. }
  1633. return 0;
  1634. }
  1635. static inline int sx_get_serial_info(struct specialix_port * port,
  1636.      struct serial_struct * retinfo)
  1637. {
  1638. struct serial_struct tmp;
  1639. struct specialix_board *bp = port_Board(port);
  1640. int error;
  1641. error = verify_area(VERIFY_WRITE, (void *) retinfo, sizeof(tmp));
  1642. if (error)
  1643. return error;
  1644. memset(&tmp, 0, sizeof(tmp));
  1645. tmp.type = PORT_CIRRUS;
  1646. tmp.line = port - sx_port;
  1647. tmp.port = bp->base;
  1648. tmp.irq  = bp->irq;
  1649. tmp.flags = port->flags;
  1650. tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
  1651. tmp.close_delay = port->close_delay * HZ/100;
  1652. tmp.closing_wait = port->closing_wait * HZ/100;
  1653. tmp.custom_divisor =  port->custom_divisor;
  1654. tmp.xmit_fifo_size = CD186x_NFIFO;
  1655. if (copy_to_user(retinfo, &tmp, sizeof(tmp)))
  1656. return -EFAULT;
  1657. return 0;
  1658. }
  1659. static int sx_ioctl(struct tty_struct * tty, struct file * filp, 
  1660.                     unsigned int cmd, unsigned long arg)
  1661. {
  1662. struct specialix_port *port = (struct specialix_port *)tty->driver_data;
  1663. int error;
  1664. int retval;
  1665. if (sx_paranoia_check(port, tty->device, "sx_ioctl"))
  1666. return -ENODEV;
  1667. switch (cmd) {
  1668.  case TCSBRK: /* SVID version: non-zero arg --> no break */
  1669. retval = tty_check_change(tty);
  1670. if (retval)
  1671. return retval;
  1672. tty_wait_until_sent(tty, 0);
  1673. if (!arg)
  1674. sx_send_break(port, HZ/4); /* 1/4 second */
  1675. return 0;
  1676.  case TCSBRKP: /* support for POSIX tcsendbreak() */
  1677. retval = tty_check_change(tty);
  1678. if (retval)
  1679. return retval;
  1680. tty_wait_until_sent(tty, 0);
  1681. sx_send_break(port, arg ? arg*(HZ/10) : HZ/4);
  1682. return 0;
  1683.  case TIOCGSOFTCAR:
  1684. error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(long));
  1685. if (error)
  1686. return error;
  1687. put_user(C_CLOCAL(tty) ? 1 : 0,
  1688.          (unsigned long *) arg);
  1689. return 0;
  1690.  case TIOCSSOFTCAR:
  1691. Get_user(arg, (unsigned long *) arg);
  1692. tty->termios->c_cflag =
  1693. ((tty->termios->c_cflag & ~CLOCAL) |
  1694. (arg ? CLOCAL : 0));
  1695. return 0;
  1696.  case TIOCMGET:
  1697. error = verify_area(VERIFY_WRITE, (void *) arg,
  1698.                     sizeof(unsigned int));
  1699. if (error)
  1700. return error;
  1701. return sx_get_modem_info(port, (unsigned int *) arg);
  1702.  case TIOCMBIS:
  1703.  case TIOCMBIC:
  1704.  case TIOCMSET:
  1705. return sx_set_modem_info(port, cmd, (unsigned int *) arg);
  1706.  case TIOCGSERIAL:
  1707. return sx_get_serial_info(port, (struct serial_struct *) arg);
  1708.  case TIOCSSERIAL:
  1709. return sx_set_serial_info(port, (struct serial_struct *) arg);
  1710.  default:
  1711. return -ENOIOCTLCMD;
  1712. }
  1713. return 0;
  1714. }
  1715. static void sx_throttle(struct tty_struct * tty)
  1716. {
  1717. struct specialix_port *port = (struct specialix_port *)tty->driver_data;
  1718. struct specialix_board *bp;
  1719. unsigned long flags;
  1720. if (sx_paranoia_check(port, tty->device, "sx_throttle"))
  1721. return;
  1722. bp = port_Board(port);
  1723. save_flags(flags); cli();
  1724. /* Use DTR instead of RTS ! */
  1725. if (SX_CRTSCTS (tty)) 
  1726. port->MSVR &= ~MSVR_DTR;
  1727. else {
  1728. /* Auch!!! I think the system shouldn't call this then. */
  1729. /* Or maybe we're supposed (allowed?) to do our side of hw
  1730.    handshake anyway, even when hardware handshake is off. 
  1731.    When you see this in your logs, please report.... */
  1732. printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)n",
  1733.                  port_No (port));
  1734. }
  1735. sx_out(bp, CD186x_CAR, port_No(port));
  1736. if (I_IXOFF(tty)) {
  1737. sx_wait_CCR(bp);
  1738. sx_out(bp, CD186x_CCR, CCR_SSCH2);
  1739. sx_wait_CCR(bp);
  1740. }
  1741. sx_out(bp, CD186x_MSVR, port->MSVR);
  1742. restore_flags(flags);
  1743. }
  1744. static void sx_unthrottle(struct tty_struct * tty)
  1745. {
  1746. struct specialix_port *port = (struct specialix_port *)tty->driver_data;
  1747. struct specialix_board *bp;
  1748. unsigned long flags;
  1749. if (sx_paranoia_check(port, tty->device, "sx_unthrottle"))
  1750. return;
  1751. bp = port_Board(port);
  1752. save_flags(flags); cli();
  1753. /* XXXX Use DTR INSTEAD???? */
  1754. if (SX_CRTSCTS(tty)) {
  1755. port->MSVR |= MSVR_DTR;
  1756. } /* Else clause: see remark in "sx_throttle"... */
  1757. sx_out(bp, CD186x_CAR, port_No(port));
  1758. if (I_IXOFF(tty)) {
  1759. sx_wait_CCR(bp);
  1760. sx_out(bp, CD186x_CCR, CCR_SSCH1);
  1761. sx_wait_CCR(bp);
  1762. }
  1763. sx_out(bp, CD186x_MSVR, port->MSVR);
  1764. restore_flags(flags);
  1765. }
  1766. static void sx_stop(struct tty_struct * tty)
  1767. {
  1768. struct specialix_port *port = (struct specialix_port *)tty->driver_data;
  1769. struct specialix_board *bp;
  1770. unsigned long flags;
  1771. if (sx_paranoia_check(port, tty->device, "sx_stop"))
  1772. return;
  1773. bp = port_Board(port);
  1774. save_flags(flags); cli();
  1775. port->IER &= ~IER_TXRDY;
  1776. sx_out(bp, CD186x_CAR, port_No(port));
  1777. sx_out(bp, CD186x_IER, port->IER);
  1778. restore_flags(flags);
  1779. }
  1780. static void sx_start(struct tty_struct * tty)
  1781. {
  1782. struct specialix_port *port = (struct specialix_port *)tty->driver_data;
  1783. struct specialix_board *bp;
  1784. unsigned long flags;
  1785. if (sx_paranoia_check(port, tty->device, "sx_start"))
  1786. return;
  1787. bp = port_Board(port);
  1788. save_flags(flags); cli();
  1789. if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
  1790. port->IER |= IER_TXRDY;
  1791. sx_out(bp, CD186x_CAR, port_No(port));
  1792. sx_out(bp, CD186x_IER, port->IER);
  1793. }
  1794. restore_flags(flags);
  1795. }
  1796. /*
  1797.  * This routine is called from the scheduler tqueue when the interrupt
  1798.  * routine has signalled that a hangup has occurred.  The path of
  1799.  * hangup processing is:
  1800.  *
  1801.  *  serial interrupt routine -> (scheduler tqueue) ->
  1802.  *  do_sx_hangup() -> tty->hangup() -> sx_hangup()
  1803.  * 
  1804.  */
  1805. static void do_sx_hangup(void *private_)
  1806. {
  1807. struct specialix_port *port = (struct specialix_port *) private_;
  1808. struct tty_struct *tty;
  1809. tty = port->tty;
  1810. if (tty)
  1811. tty_hangup(tty); /* FIXME: module removal race here */
  1812. MOD_DEC_USE_COUNT;
  1813. }
  1814. static void sx_hangup(struct tty_struct * tty)
  1815. {
  1816. struct specialix_port *port = (struct specialix_port *)tty->driver_data;
  1817. struct specialix_board *bp;
  1818. if (sx_paranoia_check(port, tty->device, "sx_hangup"))
  1819. return;
  1820. bp = port_Board(port);
  1821. sx_shutdown_port(bp, port);
  1822. port->event = 0;
  1823. port->count = 0;
  1824. port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
  1825. port->tty = 0;
  1826. wake_up_interruptible(&port->open_wait);
  1827. }
  1828. static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios)
  1829. {
  1830. struct specialix_port *port = (struct specialix_port *)tty->driver_data;
  1831. unsigned long flags;
  1832. if (sx_paranoia_check(port, tty->device, "sx_set_termios"))
  1833. return;
  1834. if (tty->termios->c_cflag == old_termios->c_cflag &&
  1835.     tty->termios->c_iflag == old_termios->c_iflag)
  1836. return;
  1837. save_flags(flags); cli();
  1838. sx_change_speed(port_Board(port), port);
  1839. restore_flags(flags);
  1840. if ((old_termios->c_cflag & CRTSCTS) &&
  1841.     !(tty->termios->c_cflag & CRTSCTS)) {
  1842. tty->hw_stopped = 0;
  1843. sx_start(tty);
  1844. }
  1845. }
  1846. static void do_specialix_bh(void)
  1847. {
  1848.  run_task_queue(&tq_specialix);
  1849. }
  1850. static void do_softint(void *private_)
  1851. {
  1852. struct specialix_port *port = (struct specialix_port *) private_;
  1853. struct tty_struct *tty;
  1854. if(!(tty = port->tty)) 
  1855. return;
  1856. if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
  1857. if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
  1858.     tty->ldisc.write_wakeup)
  1859. (tty->ldisc.write_wakeup)(tty);
  1860. wake_up_interruptible(&tty->write_wait);
  1861. }
  1862. }
  1863. static int sx_init_drivers(void)
  1864. {
  1865. int error;
  1866. int i;
  1867. if (!(tmp_buf = (unsigned char *) get_free_page(GFP_KERNEL))) {
  1868. printk(KERN_ERR "sx: Couldn't get free page.n");
  1869. return 1;
  1870. }
  1871. init_bh(SPECIALIX_BH, do_specialix_bh);
  1872. memset(&specialix_driver, 0, sizeof(specialix_driver));
  1873. specialix_driver.magic = TTY_DRIVER_MAGIC;
  1874. specialix_driver.name = "ttyW";
  1875. specialix_driver.major = SPECIALIX_NORMAL_MAJOR;
  1876. specialix_driver.num = SX_NBOARD * SX_NPORT;
  1877. specialix_driver.type = TTY_DRIVER_TYPE_SERIAL;
  1878. specialix_driver.subtype = SPECIALIX_TYPE_NORMAL;
  1879. specialix_driver.init_termios = tty_std_termios;
  1880. specialix_driver.init_termios.c_cflag =
  1881. B9600 | CS8 | CREAD | HUPCL | CLOCAL;
  1882. specialix_driver.flags = TTY_DRIVER_REAL_RAW;
  1883. specialix_driver.refcount = &specialix_refcount;
  1884. specialix_driver.table = specialix_table;
  1885. specialix_driver.termios = specialix_termios;
  1886. specialix_driver.termios_locked = specialix_termios_locked;
  1887. specialix_driver.open  = sx_open;
  1888. specialix_driver.close = sx_close;
  1889. specialix_driver.write = sx_write;
  1890. specialix_driver.put_char = sx_put_char;
  1891. specialix_driver.flush_chars = sx_flush_chars;
  1892. specialix_driver.write_room = sx_write_room;
  1893. specialix_driver.chars_in_buffer = sx_chars_in_buffer;
  1894. specialix_driver.flush_buffer = sx_flush_buffer;
  1895. specialix_driver.ioctl = sx_ioctl;
  1896. specialix_driver.throttle = sx_throttle;
  1897. specialix_driver.unthrottle = sx_unthrottle;
  1898. specialix_driver.set_termios = sx_set_termios;
  1899. specialix_driver.stop = sx_stop;
  1900. specialix_driver.start = sx_start;
  1901. specialix_driver.hangup = sx_hangup;
  1902. specialix_callout_driver = specialix_driver;
  1903. specialix_callout_driver.name = "cuw";
  1904. specialix_callout_driver.major = SPECIALIX_CALLOUT_MAJOR;
  1905. specialix_callout_driver.subtype = SPECIALIX_TYPE_CALLOUT;
  1906. if ((error = tty_register_driver(&specialix_driver))) {
  1907. free_page((unsigned long)tmp_buf);
  1908. printk(KERN_ERR "sx: Couldn't register specialix IO8+ driver, error = %dn",
  1909.        error);
  1910. return 1;
  1911. }
  1912. if ((error = tty_register_driver(&specialix_callout_driver))) {
  1913. free_page((unsigned long)tmp_buf);
  1914. tty_unregister_driver(&specialix_driver);
  1915. printk(KERN_ERR "sx: Couldn't register specialix IO8+ callout driver, error = %dn",
  1916.        error);
  1917. return 1;
  1918. }
  1919. memset(sx_port, 0, sizeof(sx_port));
  1920. for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
  1921. sx_port[i].callout_termios = specialix_callout_driver.init_termios;
  1922. sx_port[i].normal_termios  = specialix_driver.init_termios;
  1923. sx_port[i].magic = SPECIALIX_MAGIC;
  1924. sx_port[i].tqueue.routine = do_softint;
  1925. sx_port[i].tqueue.data = &sx_port[i];
  1926. sx_port[i].tqueue_hangup.routine = do_sx_hangup;
  1927. sx_port[i].tqueue_hangup.data = &sx_port[i];
  1928. sx_port[i].close_delay = 50 * HZ/100;
  1929. sx_port[i].closing_wait = 3000 * HZ/100;
  1930. init_waitqueue_head(&sx_port[i].open_wait);
  1931. init_waitqueue_head(&sx_port[i].close_wait);
  1932. }
  1933. return 0;
  1934. }
  1935. static void sx_release_drivers(void)
  1936. {
  1937. free_page((unsigned long)tmp_buf);
  1938. tty_unregister_driver(&specialix_driver);
  1939. tty_unregister_driver(&specialix_callout_driver);
  1940. }
  1941. #ifndef MODULE
  1942. /*
  1943.  * Called at boot time.
  1944.  * 
  1945.  * You can specify IO base for up to SX_NBOARD cards,
  1946.  * using line "specialix=0xiobase1,0xiobase2,.." at LILO prompt.
  1947.  * Note that there will be no probing at default
  1948.  * addresses in this case.
  1949.  *
  1950.  */ 
  1951. void specialix_setup(char *str, int * ints)
  1952. {
  1953. int i;
  1954.         
  1955. for (i=0;i<SX_NBOARD;i++) {
  1956. sx_board[i].base = 0;
  1957. }
  1958. for (i = 1; i <= ints[0]; i++) {
  1959. if (i&1)
  1960. sx_board[i/2].base = ints[i];
  1961. else
  1962. sx_board[i/2 -1].irq = ints[i];
  1963. }
  1964. }
  1965. #endif
  1966. /* 
  1967.  * This routine must be called by kernel at boot time 
  1968.  */
  1969. int specialix_init(void) 
  1970. {
  1971. int i;
  1972. int found = 0;
  1973. printk(KERN_INFO "sx: Specialix IO8+ driver v" VERSION ", (c) R.E.Wolff 1997/1998.n");
  1974. printk(KERN_INFO "sx: derived from work (c) D.Gorodchanin 1994-1996.n");
  1975. #ifdef CONFIG_SPECIALIX_RTSCTS
  1976. printk (KERN_INFO "sx: DTR/RTS pin is always RTS.n");
  1977. #else
  1978. printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.n");
  1979. #endif
  1980. if (sx_init_drivers()) 
  1981. return -EIO;
  1982. for (i = 0; i < SX_NBOARD; i++) 
  1983. if (sx_board[i].base && !sx_probe(&sx_board[i]))
  1984. found++;
  1985. #ifdef CONFIG_PCI
  1986. if (pci_present()) {
  1987. struct pci_dev *pdev = NULL;
  1988. i=0;
  1989. while (i <= SX_NBOARD) {
  1990. if (sx_board[i].flags & SX_BOARD_PRESENT) {
  1991. i++;
  1992. continue;
  1993. }
  1994. pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
  1995.                         PCI_DEVICE_ID_SPECIALIX_IO8, 
  1996.                         pdev);
  1997. if (!pdev) break;
  1998. if (pci_enable_device(pdev))
  1999. continue;
  2000. sx_board[i].irq = pdev->irq;
  2001. sx_board[i].base = pci_resource_start (pdev, 2);
  2002. sx_board[i].flags |= SX_BOARD_IS_PCI;
  2003. if (!sx_probe(&sx_board[i]))
  2004. found ++;
  2005. }
  2006. }
  2007. #endif
  2008. if (!found) {
  2009. sx_release_drivers();
  2010. printk(KERN_INFO "sx: No specialix IO8+ boards detected.n");
  2011. return -EIO;
  2012. }
  2013. return 0;
  2014. }
  2015. #ifdef MODULE
  2016. int iobase[SX_NBOARD]  = {0,};
  2017. int irq [SX_NBOARD] = {0,};
  2018. MODULE_PARM(iobase,"1-" __MODULE_STRING(SX_NBOARD) "i");
  2019. MODULE_PARM(irq,"1-" __MODULE_STRING(SX_NBOARD) "i");
  2020. /*
  2021.  * You can setup up to 4 boards.
  2022.  * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
  2023.  * You should specify the IRQs too in that case "irq=....,...". 
  2024.  * 
  2025.  * More than 4 boards in one computer is not possible, as the card can
  2026.  * only use 4 different interrupts. 
  2027.  *
  2028.  */
  2029. int init_module(void) 
  2030. {
  2031. int i;
  2032. if (iobase[0] || iobase[1] || iobase[2] || iobase[3]) {
  2033. for(i = 0; i < SX_NBOARD; i++) {
  2034. sx_board[i].base = iobase[i];
  2035. sx_board[i].irq = irq[i];
  2036. }
  2037. }
  2038. return specialix_init();
  2039. }
  2040. void cleanup_module(void)
  2041. {
  2042. int i;
  2043. sx_release_drivers();
  2044. for (i = 0; i < SX_NBOARD; i++)
  2045. if (sx_board[i].flags & SX_BOARD_PRESENT) 
  2046. sx_release_io_range(&sx_board[i]);
  2047. #ifdef SPECIALIX_TIMER
  2048. del_timer (&missed_irq_timer);
  2049. #endif
  2050. }
  2051. #endif /* MODULE */
  2052. MODULE_LICENSE("GPL");