pcxx.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:57k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/drivers/char/pcxx.c
  3.  * 
  4.  *  Written by Troy De Jongh, November, 1994
  5.  *
  6.  *  Copyright (C) 1994,1995 Troy De Jongh
  7.  *  This software may be used and distributed according to the terms 
  8.  *  of the GNU General Public License.
  9.  *
  10.  *  This driver is for the DigiBoard PC/Xe and PC/Xi line of products.
  11.  *
  12.  *  This driver does NOT support DigiBoard's fastcook FEP option and
  13.  *  does not support the transparent print (i.e. digiprint) option.
  14.  *
  15.  * This Driver is currently maintained by Christoph Lameter (christoph@lameter.com)
  16.  *
  17.  * Please contact digi for support issues at digilnux@dgii.com.
  18.  * Some more information can be found at
  19.  * http://lameter.com/digi.
  20.  *
  21.  *  1.5.2 Fall 1995 Bug fixes by David Nugent
  22.  *  1.5.3 March 9, 1996 Christoph Lameter: Fixed 115.2K Support. Memory
  23.  * allocation harmonized with 1.3.X Series.
  24.  *  1.5.4 March 30, 1996 Christoph Lameter: Fixup for 1.3.81. Use init_bh
  25.  * instead of direct assignment to kernel arrays.
  26.  *  1.5.5 April 5, 1996 Major device numbers corrected.
  27.  *              Mike McLagan<mike.mclagan@linux.org>: Add setup
  28.  *              variable handling, instead of using the old pcxxconfig.h
  29.  *  1.5.6 April 16, 1996 Christoph Lameter: Pointer cleanup, macro cleanup.
  30.  * Call out devices changed to /dev/cudxx.
  31.  *  1.5.7 July 22, 1996 Martin Mares: CLOCAL fix, pcxe_table clearing.
  32.  * David Nugent: Bug in pcxe_open.
  33.  * Brian J. Murrell: Modem Control fixes, Majors correctly assigned
  34.  *  1.6.1 April 6, 1997 Bernhard Kaindl: fixed virtual memory access for 2.1
  35.  *              i386-kernels and use on other archtitectures, Allowing use
  36.  *              as module, added module parameters, added switch to enable
  37.  *              verbose messages to assist user during card configuration.
  38.  *              Currently only tested on a PC/Xi card, but should work on Xe
  39.  *              and Xeve also.
  40.  *  1.6.2 August, 7, 2000: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  41.  *   get rid of panics, release previously allocated resources
  42.  *  1.6.3 August, 23, 2000: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  43.  *   cleaned up wrt verify_area.
  44.  *              Christoph Lameter: Update documentation, email addresses
  45.  *              and URLs. Remove some obsolete code.
  46.  *
  47.  */
  48. #include <linux/module.h>
  49. #include <linux/mm.h>
  50. #include <linux/ioport.h>
  51. #include <linux/errno.h>
  52. #include <linux/signal.h>
  53. #include <linux/sched.h>
  54. #include <linux/timer.h>
  55. #include <linux/interrupt.h>
  56. #include <linux/tty.h>
  57. #include <linux/tty_flip.h>
  58. #include <linux/major.h>
  59. #include <linux/string.h>
  60. #include <linux/fcntl.h>
  61. #include <linux/ptrace.h>
  62. #include <linux/delay.h>
  63. #include <linux/serial.h>
  64. #include <linux/tty_driver.h>
  65. #include <linux/slab.h>
  66. #include <linux/init.h>
  67. #include <linux/version.h>
  68. #ifndef MODULE
  69. #include <linux/ctype.h> /* We only need it for parsing the "digi="-line */
  70. #endif
  71. #include <asm/system.h>
  72. #include <asm/io.h>
  73. #include <asm/uaccess.h>
  74. #include <asm/bitops.h>
  75. #include <asm/semaphore.h>
  76. #define VERSION  "1.6.3"
  77. #include "digi.h"
  78. #include "fep.h"
  79. #include "pcxx.h"
  80. #include "digi_fep.h"
  81. #include "digi_bios.h"
  82. /*
  83.  * Define one default setting if no digi= config line is used.
  84.  * Default is altpin = disabled, 16 ports, I/O 200h, Memory 0D0000h
  85.  */
  86. static struct board_info boards[MAX_DIGI_BOARDS] = { {
  87. /* Board is enabled       */ ENABLED,
  88. /* Type is auto-detected  */ 0,
  89. /* altping is disabled    */    DISABLED,
  90. /* number of ports = 16   */ 16,
  91. /* io address is 0x200    */ 0x200,
  92. /* card memory at 0xd0000 */ 0xd0000,
  93. /* first minor device no. */ 0
  94. } };
  95.  
  96. static int verbose = 0;
  97. static int debug   = 0;
  98. #ifdef MODULE
  99. /* Variables for insmod */
  100. static int io[]           = {0, 0, 0, 0};
  101. static int membase[]      = {0, 0, 0, 0};
  102. static int memsize[]      = {0, 0, 0, 0};
  103. static int altpin[]       = {0, 0, 0, 0};
  104. static int numports[]     = {0, 0, 0, 0};
  105. # if (LINUX_VERSION_CODE > 0x020111)
  106. MODULE_AUTHOR("Bernhard Kaindl");
  107. MODULE_DESCRIPTION("Digiboard PC/X{i,e,eve} driver");
  108. MODULE_LICENSE("GPL");
  109. MODULE_PARM(verbose,     "i");
  110. MODULE_PARM(debug,       "i");
  111. MODULE_PARM(io,          "1-4i");
  112. MODULE_PARM(membase,     "1-4i");
  113. MODULE_PARM(memsize,     "1-4i");
  114. MODULE_PARM(altpin,      "1-4i");
  115. MODULE_PARM(numports,    "1-4i");
  116. # endif
  117. #endif MODULE
  118. static int numcards = 1;
  119. static int nbdevs = 0;
  120.  
  121. static struct channel    *digi_channels;
  122. static struct tty_struct **pcxe_table;
  123. static struct termios    **pcxe_termios;
  124. static struct termios    **pcxe_termios_locked;
  125.  
  126. int pcxx_ncook=sizeof(pcxx_cook);
  127. int pcxx_nbios=sizeof(pcxx_bios);
  128. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  129. #define pcxxassert(x, msg)  if(!(x)) pcxx_error(__LINE__, msg)
  130. #define FEPTIMEOUT 200000  
  131. #define SERIAL_TYPE_NORMAL 1
  132. #define SERIAL_TYPE_CALLOUT 2
  133. #define PCXE_EVENT_HANGUP   1
  134. struct tty_driver pcxe_driver;
  135. struct tty_driver pcxe_callout;
  136. static int pcxe_refcount;
  137. static struct timer_list pcxx_timer;
  138. DECLARE_TASK_QUEUE(tq_pcxx);
  139. static void pcxxpoll(unsigned long dummy);
  140. static void pcxxdelay(int);
  141. static void fepcmd(struct channel *, int, int, int, int, int);
  142. static void pcxe_put_char(struct tty_struct *, unsigned char);
  143. static void pcxe_flush_chars(struct tty_struct *);
  144. static void pcxx_error(int, char *);
  145. static void pcxe_close(struct tty_struct *, struct file *);
  146. static int pcxe_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long);
  147. static void pcxe_set_termios(struct tty_struct *, struct termios *);
  148. static int pcxe_write(struct tty_struct *, int, const unsigned char *, int);
  149. static int pcxe_write_room(struct tty_struct *);
  150. static int pcxe_chars_in_buffer(struct tty_struct *);
  151. static void pcxe_flush_buffer(struct tty_struct *);
  152. static void doevent(int);
  153. static void receive_data(struct channel *);
  154. static void pcxxparam(struct tty_struct *, struct channel *ch);
  155. static void do_softint(void *);
  156. static inline void pcxe_sched_event(struct channel *, int);
  157. static void do_pcxe_bh(void);
  158. static void pcxe_start(struct tty_struct *);
  159. static void pcxe_stop(struct tty_struct *);
  160. static void pcxe_throttle(struct tty_struct *);
  161. static void pcxe_unthrottle(struct tty_struct *);
  162. static void digi_send_break(struct channel *ch, int msec);
  163. static void shutdown(struct channel *);
  164. static void setup_empty_event(struct tty_struct *tty, struct channel *ch);
  165. static inline void memwinon(struct board_info *b, unsigned int win);
  166. static inline void memwinoff(struct board_info *b, unsigned int win);
  167. static inline void globalwinon(struct channel *ch);
  168. static inline void rxwinon(struct channel *ch);
  169. static inline void txwinon(struct channel *ch);
  170. static inline void memoff(struct channel *ch);
  171. static inline void assertgwinon(struct channel *ch);
  172. static inline void assertmemoff(struct channel *ch);
  173. #define TZ_BUFSZ 4096
  174. /* function definitions */
  175. /*****************************************************************************/
  176. static void cleanup_board_resources(void)
  177. {
  178. int crd, i;
  179. struct board_info *bd;
  180. struct channel *ch;
  181.         for(crd = 0; crd < numcards; crd++) {
  182.                 bd = &boards[crd];
  183. ch = digi_channels + bd->first_minor;
  184. if (bd->region)
  185. release_region(bd->port, 4);
  186. for(i = 0; i < bd->numports; i++, ch++)
  187. if (ch->tmp_buf)
  188. kfree(ch->tmp_buf);
  189. }
  190. }
  191. /*****************************************************************************/
  192. #ifdef MODULE
  193. /*
  194.  * pcxe_init() is our init_module():
  195.  */
  196. #define pcxe_init init_module
  197. void cleanup_module(void);
  198. /*****************************************************************************/
  199. void cleanup_module()
  200. {
  201. unsigned long flags;
  202. int e1, e2;
  203. printk(KERN_NOTICE "Unloading PC/Xx version %sn", VERSION);
  204. save_flags(flags);
  205. cli();
  206. del_timer_sync(&pcxx_timer);
  207. remove_bh(DIGI_BH);
  208. if ((e1 = tty_unregister_driver(&pcxe_driver)))
  209. printk("SERIAL: failed to unregister serial driver (%d)n", e1);
  210. if ((e2 = tty_unregister_driver(&pcxe_callout)))
  211. printk("SERIAL: failed to unregister callout driver (%d)n",e2);
  212. cleanup_board_resources();
  213. kfree(digi_channels);
  214. kfree(pcxe_termios_locked);
  215. kfree(pcxe_termios);
  216. kfree(pcxe_table);
  217. restore_flags(flags);
  218. }
  219. #endif
  220. static inline struct channel *chan(register struct tty_struct *tty)
  221. {
  222. if (tty) {
  223. register struct channel *ch=(struct channel *)tty->driver_data;
  224. if (ch >= digi_channels && ch < digi_channels+nbdevs) {
  225. if (ch->magic==PCXX_MAGIC)
  226. return ch;
  227. }
  228. }
  229. return NULL;
  230. }
  231. /* These inline routines are to turn board memory on and off */
  232. static inline void memwinon(struct board_info *b, unsigned int win)
  233. {
  234. if(b->type == PCXEVE)
  235. outb_p(FEPWIN|win, b->port+1);
  236. else
  237. outb_p(inb(b->port)|FEPMEM, b->port);
  238. }
  239. static inline void memwinoff(struct board_info *b, unsigned int win)
  240. {
  241. outb_p(inb(b->port)&~FEPMEM, b->port);
  242. if(b->type == PCXEVE)
  243. outb_p(0, b->port + 1);
  244. }
  245. static inline void globalwinon(struct channel *ch)
  246. {
  247. if(ch->board->type == PCXEVE)
  248. outb_p(FEPWIN, ch->board->port+1);
  249. else
  250. outb_p(FEPMEM, ch->board->port);
  251. }
  252. static inline void rxwinon(struct channel *ch)
  253. {
  254. if(ch->rxwin == 0)
  255. outb_p(FEPMEM, ch->board->port);
  256. else 
  257. outb_p(ch->rxwin, ch->board->port+1);
  258. }
  259. static inline void txwinon(struct channel *ch)
  260. {
  261. if(ch->txwin == 0)
  262. outb_p(FEPMEM, ch->board->port);
  263. else
  264. outb_p(ch->txwin, ch->board->port+1);
  265. }
  266. static inline void memoff(struct channel *ch)
  267. {
  268. outb_p(0, ch->board->port);
  269. if(ch->board->type == PCXEVE)
  270. outb_p(0, ch->board->port+1);
  271. }
  272. static inline void assertgwinon(struct channel *ch)
  273. {
  274. if(ch->board->type != PCXEVE)
  275. pcxxassert(inb(ch->board->port) & FEPMEM, "Global memory off");
  276. }
  277. static inline void assertmemoff(struct channel *ch)
  278. {
  279. if(ch->board->type != PCXEVE)
  280. pcxxassert(!(inb(ch->board->port) & FEPMEM), "Memory on");
  281. }
  282. static inline void pcxe_sched_event(struct channel *info, int event)
  283. {
  284. info->event |= 1 << event;
  285. queue_task(&info->tqueue, &tq_pcxx);
  286. mark_bh(DIGI_BH);
  287. }
  288. static void pcxx_error(int line, char *msg)
  289. {
  290. printk("pcxx_error (DigiBoard): line=%d %sn", line, msg);
  291. }
  292. static int pcxx_waitcarrier(struct tty_struct *tty,struct file *filp,struct channel *info)
  293. {
  294. DECLARE_WAITQUEUE(wait, current);
  295. int retval = 0;
  296. int do_clocal = 0;
  297. if (info->asyncflags & ASYNC_CALLOUT_ACTIVE) {
  298. if (info->normal_termios.c_cflag & CLOCAL)
  299. do_clocal = 1;
  300. } else {
  301. if (tty->termios->c_cflag & CLOCAL)
  302. do_clocal = 1;
  303. }
  304. /*
  305.  * Block waiting for the carrier detect and the line to become free
  306.  */
  307. retval = 0;
  308. add_wait_queue(&info->open_wait, &wait);
  309. info->count--;
  310. info->blocked_open++;
  311. for (;;) {
  312. cli();
  313. if ((info->asyncflags & ASYNC_CALLOUT_ACTIVE) == 0) {
  314. globalwinon(info);
  315. info->omodem |= DTR|RTS;
  316. fepcmd(info, SETMODEM, DTR|RTS, 0, 10, 1);
  317. memoff(info);
  318. }
  319. sti();
  320. set_current_state(TASK_INTERRUPTIBLE);
  321. if(tty_hung_up_p(filp) || (info->asyncflags & ASYNC_INITIALIZED) == 0) {
  322. if(info->asyncflags & ASYNC_HUP_NOTIFY)
  323. retval = -EAGAIN;
  324. else
  325. retval = -ERESTARTSYS;
  326. break;
  327. }
  328. if ((info->asyncflags & ASYNC_CALLOUT_ACTIVE) == 0 &&
  329.     (info->asyncflags & ASYNC_CLOSING) == 0 &&
  330. (do_clocal || (info->imodem & info->dcd)))
  331. break;
  332. if(signal_pending(current)) {
  333. retval = -ERESTARTSYS;
  334. break;
  335. }
  336. schedule();
  337. }
  338. current->state = TASK_RUNNING;
  339. remove_wait_queue(&info->open_wait, &wait);
  340. if(!tty_hung_up_p(filp))
  341. info->count++;
  342. info->blocked_open--;
  343. return retval;
  344. }
  345. int pcxe_open(struct tty_struct *tty, struct file * filp)
  346. {
  347. volatile struct board_chan *bc;
  348. struct channel *ch;
  349. unsigned long flags;
  350. int line;
  351. int boardnum;
  352. int retval;
  353. line = MINOR(tty->device) - tty->driver.minor_start;
  354. if(line < 0 || line >= nbdevs) {
  355. printk("line out of range in pcxe_openn");
  356. tty->driver_data = NULL;
  357. return(-ENODEV);
  358. }
  359. for(boardnum=0;boardnum<numcards;boardnum++)
  360. if ((line >= boards[boardnum].first_minor) && 
  361. (line < boards[boardnum].first_minor + boards[boardnum].numports))
  362. break;
  363. if(boardnum >= numcards || boards[boardnum].status == DISABLED ||
  364. (line - boards[boardnum].first_minor) >= boards[boardnum].numports) {
  365. tty->driver_data = NULL;   /* Mark this device as 'down' */
  366. return(-ENODEV);
  367. }
  368. ch = digi_channels+line;
  369. if(ch->brdchan == 0) {
  370. tty->driver_data = NULL;
  371. return(-ENODEV);
  372. }
  373. /* flag the kernel that there is somebody using this guy */
  374. MOD_INC_USE_COUNT;
  375. /*
  376.  * If the device is in the middle of being closed, then block
  377.  * until it's done, and then try again.
  378.  */
  379. if(ch->asyncflags & ASYNC_CLOSING) {
  380. interruptible_sleep_on(&ch->close_wait);
  381. if(ch->asyncflags & ASYNC_HUP_NOTIFY)
  382. return -EAGAIN;
  383. else
  384. return -ERESTARTSYS;
  385. }
  386. save_flags(flags);
  387. cli();
  388. ch->count++;
  389. tty->driver_data = ch;
  390. ch->tty = tty;
  391. if ((ch->asyncflags & ASYNC_INITIALIZED) == 0) {
  392. unsigned int head;
  393. globalwinon(ch);
  394. ch->statusflags = 0;
  395. bc=ch->brdchan;
  396. ch->imodem = bc->mstat;
  397. head = bc->rin;
  398. bc->rout = head;
  399. ch->tty = tty;
  400. pcxxparam(tty,ch);
  401. ch->imodem = bc->mstat;
  402. bc->idata = 1;
  403. ch->omodem = DTR|RTS;
  404. fepcmd(ch, SETMODEM, DTR|RTS, 0, 10, 1);
  405. memoff(ch);
  406. ch->asyncflags |= ASYNC_INITIALIZED;
  407. }
  408. restore_flags(flags);
  409. if(ch->asyncflags & ASYNC_CLOSING) {
  410. interruptible_sleep_on(&ch->close_wait);
  411. if(ch->asyncflags & ASYNC_HUP_NOTIFY)
  412. return -EAGAIN;
  413. else
  414. return -ERESTARTSYS;
  415. }
  416. /*
  417.  * If this is a callout device, then just make sure the normal
  418.  * device isn't being used.
  419.  */
  420. if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
  421. if (ch->asyncflags & ASYNC_NORMAL_ACTIVE)
  422. return -EBUSY;
  423. if (ch->asyncflags & ASYNC_CALLOUT_ACTIVE) {
  424. if ((ch->asyncflags & ASYNC_SESSION_LOCKOUT) &&
  425.      (ch->session != current->session))
  426.     return -EBUSY;
  427. if((ch->asyncflags & ASYNC_PGRP_LOCKOUT) &&
  428.     (ch->pgrp != current->pgrp))
  429.     return -EBUSY;
  430. }
  431. ch->asyncflags |= ASYNC_CALLOUT_ACTIVE;
  432. }
  433. else {
  434. if (filp->f_flags & O_NONBLOCK) {
  435. if(ch->asyncflags & ASYNC_CALLOUT_ACTIVE)
  436. return -EBUSY;
  437. }
  438. else {
  439. /* this has to be set in order for the "block until
  440.  * CD" code to work correctly.  i'm not sure under
  441.  * what circumstances asyncflags should be set to
  442.  * ASYNC_NORMAL_ACTIVE though
  443.  * brian@ilinx.com
  444.  */
  445. ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
  446. if ((retval = pcxx_waitcarrier(tty, filp, ch)) != 0)
  447. return retval;
  448. }
  449. ch->asyncflags |= ASYNC_NORMAL_ACTIVE;
  450. }
  451.  
  452. save_flags(flags);
  453. cli();
  454. if((ch->count == 1) && (ch->asyncflags & ASYNC_SPLIT_TERMIOS)) {
  455. if(tty->driver.subtype == SERIAL_TYPE_NORMAL)
  456. *tty->termios = ch->normal_termios;
  457. else 
  458. *tty->termios = ch->callout_termios;
  459. globalwinon(ch);
  460. pcxxparam(tty,ch);
  461. memoff(ch);
  462. }
  463. ch->session = current->session;
  464. ch->pgrp = current->pgrp;
  465. restore_flags(flags);
  466. return 0;
  467. static void shutdown(struct channel *info)
  468. {
  469. unsigned long flags;
  470. volatile struct board_chan *bc;
  471. struct tty_struct *tty;
  472. if (!(info->asyncflags & ASYNC_INITIALIZED)) 
  473. return;
  474. save_flags(flags);
  475. cli();
  476. globalwinon(info);
  477. bc = info->brdchan;
  478. if(bc)
  479. bc->idata = 0;
  480. tty = info->tty;
  481. /*
  482.  * If we're a modem control device and HUPCL is on, drop RTS & DTR.
  483.  */
  484. if(tty->termios->c_cflag & HUPCL) {
  485. info->omodem &= ~(RTS|DTR);
  486. fepcmd(info, SETMODEM, 0, DTR|RTS, 10, 1);
  487. }
  488. memoff(info);
  489. info->asyncflags &= ~ASYNC_INITIALIZED;
  490. restore_flags(flags);
  491. }
  492. static void pcxe_close(struct tty_struct * tty, struct file * filp)
  493. {
  494. struct channel *info;
  495. if ((info=chan(tty))!=NULL) {
  496. unsigned long flags;
  497. save_flags(flags);
  498. cli();
  499. if(tty_hung_up_p(filp)) {
  500. /* flag that somebody is done with this module */
  501. MOD_DEC_USE_COUNT;
  502. restore_flags(flags);
  503. return;
  504. }
  505. /* this check is in serial.c, it won't hurt to do it here too */
  506. if ((tty->count == 1) && (info->count != 1)) {
  507. /*
  508.  * Uh, oh.  tty->count is 1, which means that the tty
  509.  * structure will be freed.  Info->count should always
  510.  * be one in these conditions.  If it's greater than
  511.  * one, we've got real problems, since it means the
  512.  * serial port won't be shutdown.
  513.  */
  514. printk("pcxe_close: bad serial port count; tty->count is 1, info->count is %dn", info->count);
  515. info->count = 1;
  516. }
  517. if (info->count-- > 1) {
  518. restore_flags(flags);
  519. MOD_DEC_USE_COUNT;
  520. return;
  521. }
  522. if (info->count < 0) {
  523. info->count = 0;
  524. }
  525. info->asyncflags |= ASYNC_CLOSING;
  526. /*
  527. * Save the termios structure, since this port may have
  528. * separate termios for callout and dialin.
  529. */
  530. if(info->asyncflags & ASYNC_NORMAL_ACTIVE)
  531. info->normal_termios = *tty->termios;
  532. if(info->asyncflags & ASYNC_CALLOUT_ACTIVE)
  533. info->callout_termios = *tty->termios;
  534. tty->closing = 1;
  535. if(info->asyncflags & ASYNC_INITIALIZED) {
  536. setup_empty_event(tty,info);
  537. tty_wait_until_sent(tty, 3000); /* 30 seconds timeout */
  538. }
  539. if(tty->driver.flush_buffer)
  540. tty->driver.flush_buffer(tty);
  541. if(tty->ldisc.flush_buffer)
  542. tty->ldisc.flush_buffer(tty);
  543. shutdown(info);
  544. tty->closing = 0;
  545. info->event = 0;
  546. info->tty = NULL;
  547. #ifndef MODULE
  548. /* ldiscs[] is not available in a MODULE
  549. ** worth noting that while I'm not sure what this hunk of code is supposed
  550. ** to do, it is not present in the serial.c driver.  Hmmm.  If you know,
  551. ** please send me a note.  brian@ilinx.com
  552. ** Don't know either what this is supposed to do christoph@lameter.com.
  553. */
  554. if(tty->ldisc.num != ldiscs[N_TTY].num) {
  555. if(tty->ldisc.close)
  556. (tty->ldisc.close)(tty);
  557. tty->ldisc = ldiscs[N_TTY];
  558. tty->termios->c_line = N_TTY;
  559. if(tty->ldisc.open)
  560. (tty->ldisc.open)(tty);
  561. }
  562. #endif
  563. if(info->blocked_open) {
  564. if(info->close_delay) {
  565. current->state = TASK_INTERRUPTIBLE;
  566. schedule_timeout(info->close_delay);
  567. }
  568. wake_up_interruptible(&info->open_wait);
  569. }
  570. info->asyncflags &= ~(ASYNC_NORMAL_ACTIVE|
  571.   ASYNC_CALLOUT_ACTIVE|ASYNC_CLOSING);
  572. wake_up_interruptible(&info->close_wait);
  573. MOD_DEC_USE_COUNT;
  574. restore_flags(flags);
  575. }
  576. }
  577. void pcxe_hangup(struct tty_struct *tty)
  578. {
  579. struct channel *ch;
  580. if ((ch=chan(tty))!=NULL) {
  581. unsigned long flags;
  582. save_flags(flags);
  583. cli();
  584. shutdown(ch);
  585. ch->event = 0;
  586. ch->count = 0;
  587. ch->tty = NULL;
  588. ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
  589. wake_up_interruptible(&ch->open_wait);
  590. restore_flags(flags);
  591. }
  592. }
  593. static int pcxe_write(struct tty_struct * tty, int from_user, const unsigned char *buf, int count)
  594. {
  595. struct channel *ch;
  596. volatile struct board_chan *bc;
  597. int total, remain, size, stlen;
  598. unsigned int head, tail;
  599. unsigned long flags;
  600. /* printk("Entering pcxe_write()n"); */
  601. if ((ch=chan(tty))==NULL)
  602. return 0;
  603. bc = ch->brdchan;
  604. size = ch->txbufsize;
  605. if (from_user) {
  606. down(&ch->tmp_buf_sem);
  607. save_flags(flags);
  608. cli();
  609. globalwinon(ch);
  610. head = bc->tin & (size - 1);
  611. /* It seems to be necessary to make sure that the value is stable here somehow
  612.    This is a rather odd pice of code here. */
  613. do
  614. {
  615. tail = bc->tout;
  616. } while (tail != bc->tout);
  617. tail &= (size - 1);
  618. stlen = (head >= tail) ? (size - (head - tail) - 1) : (tail - head - 1);
  619. count = MIN(stlen, count);
  620. memoff(ch);
  621. restore_flags(flags);
  622. if (count)
  623. if (copy_from_user(ch->tmp_buf, buf, count))
  624. count = 0;
  625. buf = ch->tmp_buf;
  626. }
  627. /*
  628.  * All data is now local
  629.  */
  630. total = 0;
  631. save_flags(flags);
  632. cli();
  633. globalwinon(ch);
  634. head = bc->tin & (size - 1);
  635. tail = bc->tout;
  636. if (tail != bc->tout)
  637. tail = bc->tout;
  638. tail &= (size - 1);
  639. if (head >= tail) {
  640. remain = size - (head - tail) - 1;
  641. stlen = size - head;
  642. }
  643. else {
  644. remain = tail - head - 1;
  645. stlen = remain;
  646. }
  647. count = MIN(remain, count);
  648. txwinon(ch);
  649. while (count > 0) {
  650. stlen = MIN(count, stlen);
  651. memcpy(ch->txptr + head, buf, stlen);
  652. buf += stlen;
  653. count -= stlen;
  654. total += stlen;
  655. head += stlen;
  656. if (head >= size) {
  657. head = 0;
  658. stlen = tail;
  659. }
  660. }
  661. ch->statusflags |= TXBUSY;
  662. globalwinon(ch);
  663. bc->tin = head;
  664. if ((ch->statusflags & LOWWAIT) == 0) {
  665. ch->statusflags |= LOWWAIT;
  666. bc->ilow = 1;
  667. }
  668. memoff(ch);
  669. restore_flags(flags);
  670. if(from_user)
  671. up(&ch->tmp_buf_sem);
  672. return(total);
  673. }
  674. static void pcxe_put_char(struct tty_struct *tty, unsigned char c)
  675. {
  676. pcxe_write(tty, 0, &c, 1);
  677. return;
  678. }
  679. static int pcxe_write_room(struct tty_struct *tty)
  680. {
  681. struct channel *ch;
  682. int remain;
  683. remain = 0;
  684. if ((ch=chan(tty))!=NULL) {
  685. volatile struct board_chan *bc;
  686. unsigned int head, tail;
  687. unsigned long flags;
  688. save_flags(flags);
  689. cli();
  690. globalwinon(ch);
  691. bc = ch->brdchan;
  692. head = bc->tin & (ch->txbufsize - 1);
  693. tail = bc->tout;
  694. if (tail != bc->tout)
  695. tail = bc->tout;
  696. tail &= (ch->txbufsize - 1);
  697. if((remain = tail - head - 1) < 0 )
  698. remain += ch->txbufsize;
  699. if (remain && (ch->statusflags & LOWWAIT) == 0) {
  700. ch->statusflags |= LOWWAIT;
  701. bc->ilow = 1;
  702. }
  703. memoff(ch);
  704. restore_flags(flags);
  705. }
  706. return remain;
  707. }
  708. static int pcxe_chars_in_buffer(struct tty_struct *tty)
  709. {
  710. int chars;
  711. unsigned int ctail, head, tail;
  712. int remain;
  713. unsigned long flags;
  714. struct channel *ch;
  715. volatile struct board_chan *bc;
  716. if ((ch=chan(tty))==NULL)
  717. return(0);
  718. save_flags(flags);
  719. cli();
  720. globalwinon(ch);
  721. bc = ch->brdchan;
  722. tail = bc->tout;
  723. head = bc->tin;
  724. ctail = ch->mailbox->cout;
  725. if(tail == head && ch->mailbox->cin == ctail && bc->tbusy == 0)
  726. chars = 0;
  727. else {
  728. head = bc->tin & (ch->txbufsize - 1);
  729. tail &= (ch->txbufsize - 1);
  730. if((remain = tail - head - 1) < 0 )
  731. remain += ch->txbufsize;
  732. chars = (int)(ch->txbufsize - remain);
  733. /* 
  734.  * Make it possible to wakeup anything waiting for output
  735.  * in tty_ioctl.c, etc.
  736.  */
  737. if(!(ch->statusflags & EMPTYWAIT))
  738. setup_empty_event(tty,ch);
  739. }
  740. memoff(ch);
  741. restore_flags(flags);
  742. return(chars);
  743. }
  744. static void pcxe_flush_buffer(struct tty_struct *tty)
  745. {
  746. unsigned int tail;
  747. volatile struct board_chan *bc;
  748. struct channel *ch;
  749. unsigned long flags;
  750. if ((ch=chan(tty))==NULL)
  751. return;
  752. save_flags(flags);
  753. cli();
  754. globalwinon(ch);
  755. bc = ch->brdchan;
  756. tail = bc->tout;
  757. fepcmd(ch, STOUT, (unsigned) tail, 0, 0, 0);
  758. memoff(ch);
  759. restore_flags(flags);
  760. wake_up_interruptible(&tty->write_wait);
  761. if((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
  762. (tty->ldisc.write_wakeup)(tty);
  763. }
  764. static void pcxe_flush_chars(struct tty_struct *tty)
  765. {
  766. struct channel * ch;
  767. if ((ch=chan(tty))!=NULL) {
  768. unsigned long flags;
  769. save_flags(flags);
  770. cli();
  771. if ((ch->statusflags & TXBUSY) && !(ch->statusflags & EMPTYWAIT))
  772. setup_empty_event(tty,ch);
  773. restore_flags(flags);
  774. }
  775. }
  776. #ifndef MODULE
  777. /*
  778.  * Driver setup function when linked into the kernel to optionally parse multible
  779.  * "digi="-lines and initialize the driver at boot time. No probing.
  780.  */
  781. void __init pcxx_setup(char *str, int *ints)
  782. {
  783. struct board_info board;
  784. int               i, j, last;
  785. char              *temp, *t2;
  786. unsigned          len;
  787. numcards=0;
  788. memset(&board, 0, sizeof(board));
  789. for(last=0,i=1;i<=ints[0];i++)
  790. switch(i)
  791. {
  792. case 1:
  793. board.status = ints[i];
  794. last = i;
  795. break;
  796. case 2:
  797. board.type = ints[i];
  798. last = i;
  799. break;
  800. case 3:
  801. board.altpin = ints[i];
  802. last = i;
  803. break;
  804. case 4:
  805. board.numports = ints[i];
  806. last = i;
  807. break;
  808. case 5:
  809. board.port = ints[i];
  810. last = i;
  811. break;
  812. case 6:
  813. board.membase = ints[i];
  814. last = i;
  815. break;
  816. default:
  817. printk("PC/Xx: Too many integer parmsn");
  818. return;
  819. }
  820. while (str && *str) 
  821. {
  822. /* find the next comma or terminator */
  823. temp = str;
  824. while (*temp && (*temp != ','))
  825. temp++;
  826. if (!*temp)
  827. temp = NULL;
  828. else
  829. *temp++ = 0;
  830. i = last + 1;
  831. switch(i)
  832. {
  833. case 1:
  834. len = strlen(str);
  835. if (strncmp("Disable", str, len) == 0) 
  836. board.status = 0;
  837. else
  838. if (strncmp("Enable", str, len) == 0)
  839. board.status = 1;
  840. else
  841. {
  842. printk("PC/Xx: Invalid status %sn", str);
  843. return;
  844. }
  845. last = i;
  846. break;
  847. case 2:
  848. for(j=0;j<PCXX_NUM_TYPES;j++)
  849. if (strcmp(board_desc[j], str) == 0)
  850. break;
  851. if (i<PCXX_NUM_TYPES) 
  852. board.type = j;
  853. else
  854. {
  855. printk("PC/Xx: Invalid board name: %sn", str);
  856. return;
  857. }
  858. last = i;
  859. break;
  860. case 3:
  861. len = strlen(str);
  862. if (strncmp("Disable", str, len) == 0) 
  863. board.altpin = 0;
  864. else
  865. if (strncmp("Enable", str, len) == 0)
  866. board.altpin = 1;
  867. else
  868. {
  869. printk("PC/Xx: Invalid altpin %sn", str);
  870. return;
  871. }
  872. last = i;
  873. break;
  874. case 4:
  875. t2 = str;
  876. while (isdigit(*t2))
  877. t2++;
  878. if (*t2)
  879. {
  880. printk("PC/Xx: Invalid port count %sn", str);
  881. return;
  882. }
  883. board.numports = simple_strtoul(str, NULL, 0);
  884. last = i;
  885. break;
  886. case 5:
  887. t2 = str;
  888. while (isxdigit(*t2))
  889. t2++;
  890. if (*t2)
  891. {
  892. printk("PC/Xx: Invalid io port address %sn", str);
  893. return;
  894. }
  895. board.port = simple_strtoul(str, NULL, 16);
  896. last = i;
  897. break;
  898. case 6:
  899. t2 = str;
  900. while (isxdigit(*t2))
  901. t2++;
  902. if (*t2)
  903. {
  904. printk("PC/Xx: Invalid memory base %sn", str);
  905. return;
  906. }
  907. board.membase = simple_strtoul(str, NULL, 16);
  908. last = i;
  909. break;
  910. default:
  911. printk("PC/Xx: Too many string parmsn");
  912. return;
  913. }
  914. str = temp;
  915. }
  916. if (last < 6)  
  917. {
  918. printk("PC/Xx: Insufficient parms specifiedn");
  919. return;
  920. }
  921.  
  922.         /* I should REALLY validate the stuff here */
  923. memcpy(&boards[numcards],&board, sizeof(board));
  924. printk("PC/Xx: Added board %i, %s %s %i ports at 0x%4.4X base 0x%6.6Xn", 
  925. numcards, board_desc[board.type], board_mem[board.type], 
  926. board.numports, board.port, (unsigned int) board.membase);
  927. /* keep track of my initial minor number */
  928.         if (numcards)
  929. boards[numcards].first_minor = boards[numcards-1].first_minor + boards[numcards-1].numports;
  930. else
  931. boards[numcards].first_minor = 0;
  932. /* yeha!  string parameter was successful! */
  933. numcards++;
  934. }
  935. #endif
  936. /*
  937.  * function to initialize the driver with the given parameters, which are either
  938.  * the default values from this file or the parameters given at boot.
  939.  */
  940. int __init pcxe_init(void)
  941. {
  942. ulong memory_seg=0, memory_size=0;
  943. int lowwater, enabled_cards=0, i, crd, shrinkmem=0, topwin = 0xff00L, botwin=0x100L;
  944. int ret = -ENOMEM;
  945. unchar *fepos, *memaddr, *bios, v;
  946. volatile struct global_data *gd;
  947. volatile struct board_chan *bc;
  948. struct board_info *bd;
  949. struct channel *ch;
  950. printk(KERN_NOTICE "Digiboard PC/X{i,e,eve} driver v%sn", VERSION);
  951. #ifdef MODULE
  952. for (i = 0; i < MAX_DIGI_BOARDS; i++) {
  953. if (io[i]) {
  954. numcards = 0;
  955. break;
  956. }
  957. }
  958. if (numcards == 0) {
  959. int first_minor = 0;
  960. for (i = 0; i < MAX_DIGI_BOARDS; i++) {
  961. if (io[i] == 0) {
  962. boards[i].port    = 0;
  963. boards[i].status  = DISABLED;
  964. }
  965. else {
  966. boards[i].port         = (ushort)io[i];
  967. boards[i].status       = ENABLED;
  968. boards[i].first_minor  = first_minor;
  969. numcards=i+1;
  970. }
  971. if (membase[i])
  972. boards[i].membase = (ulong)membase[i];
  973. else
  974. boards[i].membase = 0xD0000;
  975. if (memsize[i])
  976. boards[i].memsize = (ulong)(memsize[i] * 1024);
  977. else
  978. boards[i].memsize = 0;
  979. if (altpin[i])
  980. boards[i].altpin  = ON;
  981. else
  982. boards[i].altpin  = OFF;
  983. if (numports[i])
  984. boards[i].numports  = (ushort)numports[i];
  985. else
  986. boards[i].numports  = 16;
  987. boards[i].region = NULL;
  988. first_minor += boards[i].numports;
  989. }
  990. }
  991. #endif
  992. if (numcards <= 0)
  993. {
  994. printk("PC/Xx: No cards configured, driver not active.n");
  995. return -EIO;
  996. }
  997. #if 1
  998. if (debug)
  999.     for (i = 0; i < numcards; i++) {
  1000.     printk("Card %d:status=%d, port=0x%x, membase=0x%lx, memsize=0x%lx, altpin=%d, numports=%d, first_minor=%dn",
  1001.     i+1,
  1002.     boards[i].status,
  1003.     boards[i].port,
  1004.     boards[i].membase,
  1005.     boards[i].memsize,
  1006.     boards[i].altpin,
  1007.     boards[i].numports,
  1008.     boards[i].first_minor);
  1009.     }
  1010. #endif
  1011. for (i=0;i<numcards;i++)
  1012. nbdevs += boards[i].numports;
  1013. if (nbdevs <= 0)
  1014. {
  1015. printk("PC/Xx: No devices activated, driver not active.n");
  1016. return -EIO;
  1017. }
  1018. /*
  1019.  * this turns out to be more memory efficient, as there are no 
  1020.  * unused spaces.
  1021.  */
  1022. digi_channels = kmalloc(sizeof(struct channel) * nbdevs, GFP_KERNEL);
  1023. if (!digi_channels) {
  1024. printk(KERN_ERR "Unable to allocate digi_channel structn");
  1025. return -ENOMEM;
  1026. }
  1027. memset(digi_channels, 0, sizeof(struct channel) * nbdevs);
  1028. pcxe_table =  kmalloc(sizeof(struct tty_struct *) * nbdevs, GFP_KERNEL);
  1029. if (!pcxe_table) {
  1030. printk(KERN_ERR "Unable to allocate pcxe_table structn");
  1031. goto cleanup_digi_channels;
  1032. }
  1033. memset(pcxe_table, 0, sizeof(struct tty_struct *) * nbdevs);
  1034. pcxe_termios = kmalloc(sizeof(struct termios *) * nbdevs, GFP_KERNEL);
  1035. if (!pcxe_termios) {
  1036. printk(KERN_ERR "Unable to allocate pcxe_termios structn");
  1037. goto cleanup_pcxe_table;
  1038. }
  1039. memset(pcxe_termios,0,sizeof(struct termios *)*nbdevs);
  1040. pcxe_termios_locked = kmalloc(sizeof(struct termios *) * nbdevs, GFP_KERNEL);
  1041. if (!pcxe_termios_locked) {
  1042. printk(KERN_ERR "Unable to allocate pcxe_termios_locked structn");
  1043. goto cleanup_pcxe_termios;
  1044. }
  1045. memset(pcxe_termios_locked,0,sizeof(struct termios *)*nbdevs);
  1046. init_bh(DIGI_BH,do_pcxe_bh);
  1047. init_timer(&pcxx_timer);
  1048. pcxx_timer.function = pcxxpoll;
  1049. memset(&pcxe_driver, 0, sizeof(struct tty_driver));
  1050. pcxe_driver.magic = TTY_DRIVER_MAGIC;
  1051. pcxe_driver.name = "ttyD";
  1052. pcxe_driver.major = DIGI_MAJOR; 
  1053. pcxe_driver.minor_start = 0;
  1054. pcxe_driver.num = nbdevs;
  1055. pcxe_driver.type = TTY_DRIVER_TYPE_SERIAL;
  1056. pcxe_driver.subtype = SERIAL_TYPE_NORMAL;
  1057. pcxe_driver.init_termios = tty_std_termios;
  1058. pcxe_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL;
  1059. pcxe_driver.flags = TTY_DRIVER_REAL_RAW;
  1060. pcxe_driver.refcount = &pcxe_refcount;
  1061. pcxe_driver.table = pcxe_table;
  1062. pcxe_driver.termios = pcxe_termios;
  1063. pcxe_driver.termios_locked = pcxe_termios_locked;
  1064. pcxe_driver.open = pcxe_open;
  1065. pcxe_driver.close = pcxe_close;
  1066. pcxe_driver.write = pcxe_write;
  1067. pcxe_driver.put_char = pcxe_put_char;
  1068. pcxe_driver.flush_chars = pcxe_flush_chars;
  1069. pcxe_driver.write_room = pcxe_write_room;
  1070. pcxe_driver.chars_in_buffer = pcxe_chars_in_buffer;
  1071. pcxe_driver.flush_buffer = pcxe_flush_buffer;
  1072. pcxe_driver.ioctl = pcxe_ioctl;
  1073. pcxe_driver.throttle = pcxe_throttle;
  1074. pcxe_driver.unthrottle = pcxe_unthrottle;
  1075. pcxe_driver.set_termios = pcxe_set_termios;
  1076. pcxe_driver.stop = pcxe_stop;
  1077. pcxe_driver.start = pcxe_start;
  1078. pcxe_driver.hangup = pcxe_hangup;
  1079. pcxe_callout = pcxe_driver;
  1080. pcxe_callout.name = "cud";
  1081. pcxe_callout.major = DIGICU_MAJOR;
  1082. pcxe_callout.subtype = SERIAL_TYPE_CALLOUT;
  1083. pcxe_callout.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
  1084. for(crd=0; crd < numcards; crd++) {
  1085. bd = &boards[crd];
  1086. outb(FEPRST, bd->port);
  1087. pcxxdelay(1);
  1088. for(i=0; (inb(bd->port) & FEPMASK) != FEPRST; i++) {
  1089. if(i > 100) {
  1090. printk("PC/Xx: Board not found at port 0x%x! Check switch settings.n",
  1091. bd->port);
  1092. bd->status = DISABLED;
  1093. break;
  1094. }
  1095. #ifdef MODULE
  1096. schedule();
  1097. #endif
  1098. pcxxdelay(10);
  1099. }
  1100. if(bd->status == DISABLED)
  1101. continue;
  1102. v = inb(bd->port);
  1103. if((v & 0x1) == 0x1) {
  1104. if((v & 0x30) == 0) {        /* PC/Xi 64K card */
  1105. memory_seg = 0xf000;
  1106. memory_size = 0x10000;
  1107. if((v & 0x30) == 0x10) {     /* PC/Xi 128K card */
  1108. memory_seg = 0xe000;
  1109. memory_size = 0x20000;
  1110. }
  1111. if((v & 0x30) == 0x20) {     /* PC/Xi 256K card */
  1112. memory_seg = 0xc000;
  1113. memory_size = 0x40000;
  1114. }
  1115. if((v & 0x30) == 0x30) {     /* PC/Xi 512K card */
  1116. memory_seg = 0x8000;
  1117. memory_size = 0x80000;
  1118. }
  1119. bd->type = PCXI;
  1120. } else {
  1121. if((v & 0x1) == 0x1) {
  1122. bd->status = DISABLED;   /* PC/Xm unsupported card */
  1123. printk("PC/Xx: PC/Xm at 0x%x not supported!!n", bd->port);
  1124. continue;
  1125. } else {
  1126. if(v & 0xC0) {    
  1127. topwin = 0x1f00L;
  1128. outb((((ulong)bd->membase>>8) & 0xe0) | 0x10, bd->port+2);
  1129. outb(((ulong)bd->membase>>16) & 0xff, bd->port+3);
  1130. bd->type = PCXEVE; /* PC/Xe 8K card */
  1131. } else { 
  1132. bd->type = PCXE;    /* PC/Xe 64K card */
  1133. }
  1134. memory_seg = 0xf000;
  1135. memory_size = 0x10000;
  1136. }
  1137. }
  1138. if (verbose)
  1139. printk("Configuring card %d as a %s %ldK card. io=0x%x, mem=%lx-%lxn",
  1140. crd+1, board_desc[bd->type], memory_size/1024,
  1141. bd->port,bd->membase,bd->membase+memory_size-1);
  1142. if (boards[crd].memsize == 0)
  1143. boards[crd].memsize = memory_size;
  1144. else
  1145. if (boards[crd].memsize != memory_size) {
  1146.     printk("PC/Xx: memory size mismatch:supplied=%lx(%ldK) probed=%ld(%ldK)n",
  1147.     boards[crd].memsize, boards[crd].memsize / 1024,
  1148.     memory_size, memory_size / 1024);
  1149.     continue;
  1150. }
  1151. memaddr = (unchar *)phys_to_virt(bd->membase);
  1152. if (verbose)
  1153. printk("Resetting board and testing memory access:");
  1154. outb(FEPRST|FEPMEM, bd->port);
  1155. for(i=0; (inb(bd->port) & FEPMASK) != (FEPRST|FEPMEM); i++) {
  1156. if(i > 1000) {
  1157. printk("nPC/Xx: %s not resetting at port 0x%x! Check switch settings.n",
  1158. board_desc[bd->type], bd->port);
  1159. bd->status = DISABLED;
  1160. break;
  1161. }
  1162. #ifdef MODULE
  1163. schedule();
  1164. #endif
  1165. pcxxdelay(1);
  1166. }
  1167. if(bd->status == DISABLED)
  1168. continue;
  1169. memwinon(bd,0);
  1170. *(ulong *)(memaddr + botwin) = 0xa55a3cc3;
  1171. *(ulong *)(memaddr + topwin) = 0x5aa5c33c;
  1172. if(*(ulong *)(memaddr + botwin) != 0xa55a3cc3 ||
  1173. *(ulong *)(memaddr + topwin) != 0x5aa5c33c) {
  1174. printk("PC/Xx: Failed memory test at %lx for %s at port %x, check switch settings.n",
  1175. bd->membase, board_desc[bd->type], bd->port);
  1176. bd->status = DISABLED;
  1177. continue;
  1178. }
  1179. if (verbose)
  1180. printk(" done.n");
  1181. for(i=0; i < 16; i++) {
  1182. memaddr[MISCGLOBAL+i] = 0;
  1183. }
  1184. if(bd->type == PCXI || bd->type == PCXE) {
  1185. bios = memaddr + BIOSCODE + ((0xf000 - memory_seg) << 4);
  1186. if (verbose)
  1187. printk("Downloading BIOS to 0x%lx:", virt_to_phys(bios));
  1188. memcpy(bios, pcxx_bios, pcxx_nbios);
  1189. if (verbose)
  1190. printk(" done.n");
  1191. outb(FEPMEM, bd->port);
  1192. if (verbose)
  1193. printk("Waiting for BIOS to become ready");
  1194. for(i=1; i <= 30; i++) {
  1195. if(*(ushort *)((ulong)memaddr + MISCGLOBAL) == *(ushort *)"GD" ) {
  1196. goto load_fep;
  1197. }
  1198. if (verbose) {
  1199. printk(".");
  1200. if (i % 50 == 0)
  1201. printk("n");
  1202. }
  1203. #ifdef MODULE
  1204. schedule();
  1205. #endif
  1206. pcxxdelay(50);
  1207. }
  1208. printk("nPC/Xx: BIOS download failed for board at 0x%x(addr=%lx-%lx)!n",
  1209. bd->port, bd->membase, bd->membase+bd->memsize);
  1210. bd->status = DISABLED;
  1211. continue;
  1212. }
  1213. if(bd->type == PCXEVE) {
  1214. bios = memaddr + (BIOSCODE & 0x1fff);
  1215. memwinon(bd,0xff);
  1216. memcpy(bios, pcxx_bios, pcxx_nbios);
  1217. outb(FEPCLR, bd->port);
  1218. memwinon(bd,0);
  1219. for(i=0; i <= 1000; i++) {
  1220. if(*(ushort *)((ulong)memaddr + MISCGLOBAL) == *(ushort *)"GD" ) {
  1221. goto load_fep;
  1222. }
  1223. if (verbose) {
  1224. printk(".");
  1225. if (i % 50 == 0)
  1226. printk("n");
  1227. }
  1228. #ifdef MODULE
  1229. schedule();
  1230. #endif
  1231. pcxxdelay(10);
  1232. }
  1233. printk("nPC/Xx: BIOS download failed on the %s at 0x%x!n",
  1234. board_desc[bd->type], bd->port);
  1235. bd->status = DISABLED;
  1236. continue;
  1237. }
  1238. load_fep:
  1239. fepos = memaddr + FEPCODE;
  1240. if(bd->type == PCXEVE)
  1241. fepos = memaddr + (FEPCODE & 0x1fff);
  1242. if (verbose)
  1243. printk(" ok.nDownloading FEP/OS to 0x%lx:", virt_to_phys(fepos));
  1244. memwinon(bd, (FEPCODE >> 13));
  1245. memcpy(fepos, pcxx_cook, pcxx_ncook);
  1246. memwinon(bd, 0);
  1247. if (verbose)
  1248. printk(" done.n");
  1249. *(ushort *)((ulong)memaddr + MBOX +  0) = 2;
  1250. *(ushort *)((ulong)memaddr + MBOX +  2) = memory_seg + FEPCODESEG;
  1251. *(ushort *)((ulong)memaddr + MBOX +  4) = 0;
  1252. *(ushort *)((ulong)memaddr + MBOX +  6) = FEPCODESEG;
  1253. *(ushort *)((ulong)memaddr + MBOX +  8) = 0;
  1254. *(ushort *)((ulong)memaddr + MBOX + 10) = pcxx_ncook;
  1255. outb(FEPMEM|FEPINT, bd->port);
  1256. outb(FEPMEM, bd->port);
  1257. for(i=0; *(ushort *)((ulong)memaddr + MBOX); i++) {
  1258. if(i > 2000) {
  1259. printk("PC/Xx: Command failed for the %s at 0x%x!n",
  1260. board_desc[bd->type], bd->port);
  1261. bd->status = DISABLED;
  1262. break;
  1263. }
  1264. #ifdef MODULE
  1265. schedule();
  1266. #endif
  1267. pcxxdelay(1);
  1268. }
  1269. if(bd->status == DISABLED)
  1270. continue;
  1271. if (verbose)
  1272. printk("Waiting for FEP/OS to become ready");
  1273. *(ushort *)(memaddr + FEPSTAT) = 0;
  1274. *(ushort *)(memaddr + MBOX + 0) = 1;
  1275. *(ushort *)(memaddr + MBOX + 2) = FEPCODESEG;
  1276. *(ushort *)(memaddr + MBOX + 4) = 0x4L;
  1277. outb(FEPINT, bd->port);
  1278. outb(FEPCLR, bd->port);
  1279. memwinon(bd, 0);
  1280. for(i=1; *(ushort *)((ulong)memaddr + FEPSTAT) != *(ushort *)"OS"; i++) {
  1281. if(i > 1000) {
  1282. printk("nPC/Xx: FEP/OS download failed on the %s at 0x%x!n",
  1283. board_desc[bd->type], bd->port);
  1284. bd->status = DISABLED;
  1285. break;
  1286. }
  1287. if (verbose) {
  1288. printk(".");
  1289. if (i % 50 == 0)
  1290. printk("n%5d",i/50);
  1291. }
  1292. #ifdef MODULE
  1293. schedule();
  1294. #endif
  1295. pcxxdelay(1);
  1296. }
  1297. if(bd->status == DISABLED)
  1298. continue;
  1299. if (verbose)
  1300. printk(" ok.n");
  1301. ch = digi_channels+bd->first_minor;
  1302. pcxxassert(ch < digi_channels+nbdevs, "ch out of range");
  1303. bc = (volatile struct board_chan *)((ulong)memaddr + CHANSTRUCT);
  1304. gd = (volatile struct global_data *)((ulong)memaddr + GLOBAL);
  1305. if((bd->type == PCXEVE) && (*(ushort *)((ulong)memaddr+NPORT) < 3))
  1306. shrinkmem = 1;
  1307. bd->region = request_region(bd->port, 4, "PC/Xx");
  1308. if (!bd->region) {
  1309. printk(KERN_ERR "I/O port 0x%x is already usedn", bd->port);
  1310. ret = -EBUSY;
  1311. goto cleanup_boards;
  1312. }
  1313. for(i=0; i < bd->numports; i++, ch++, bc++) {
  1314. if(((ushort *)((ulong)memaddr + PORTBASE))[i] == 0) {
  1315. ch->brdchan = 0;
  1316. continue;
  1317. }
  1318. ch->brdchan = bc;
  1319. ch->mailbox = gd;
  1320. ch->tqueue.routine = do_softint;
  1321. ch->tqueue.data = ch;
  1322. ch->board = &boards[crd];
  1323. #ifdef DEFAULT_HW_FLOW
  1324. ch->digiext.digi_flags = RTSPACE|CTSPACE;
  1325. #endif
  1326. if(boards[crd].altpin) {
  1327. ch->dsr = CD;
  1328. ch->dcd = DSR;
  1329. ch->digiext.digi_flags |= DIGI_ALTPIN;
  1330. } else { 
  1331. ch->dcd = CD;
  1332. ch->dsr = DSR;
  1333. }
  1334. ch->magic = PCXX_MAGIC;
  1335. ch->boardnum = crd;
  1336. ch->channelnum = i;
  1337. ch->dev = bd->first_minor + i;
  1338. ch->tty = 0;
  1339. if(shrinkmem) {
  1340. fepcmd(ch, SETBUFFER, 32, 0, 0, 0);
  1341. shrinkmem = 0;
  1342. }
  1343. if(bd->type != PCXEVE) {
  1344. ch->txptr = memaddr+((bc->tseg-memory_seg) << 4);
  1345. ch->rxptr = memaddr+((bc->rseg-memory_seg) << 4);
  1346. ch->txwin = ch->rxwin = 0;
  1347. } else {
  1348. ch->txptr = memaddr+(((bc->tseg-memory_seg) << 4) & 0x1fff);
  1349. ch->txwin = FEPWIN | ((bc->tseg-memory_seg) >> 9);
  1350. ch->rxptr = memaddr+(((bc->rseg-memory_seg) << 4) & 0x1fff);
  1351. ch->rxwin = FEPWIN | ((bc->rseg-memory_seg) >>9 );
  1352. }
  1353. ch->txbufsize = bc->tmax + 1;
  1354. ch->rxbufsize = bc->rmax + 1;
  1355. ch->tmp_buf = kmalloc(ch->txbufsize,GFP_KERNEL);
  1356. init_MUTEX(&ch->tmp_buf_sem);
  1357. if (!ch->tmp_buf) {
  1358. printk(KERN_ERR "Unable to allocate memory for temp buffersn");
  1359. goto cleanup_boards;
  1360. }
  1361. lowwater = ch->txbufsize >= 2000 ? 1024 : ch->txbufsize/2;
  1362. fepcmd(ch, STXLWATER, lowwater, 0, 10, 0);
  1363. fepcmd(ch, SRXLWATER, ch->rxbufsize/4, 0, 10, 0);
  1364. fepcmd(ch, SRXHWATER, 3 * ch->rxbufsize/4, 0, 10, 0);
  1365. bc->edelay = 100;
  1366. bc->idata = 1;
  1367. ch->startc = bc->startc;
  1368. ch->stopc = bc->stopc;
  1369. ch->startca = bc->startca;
  1370. ch->stopca = bc->stopca;
  1371. ch->fepcflag = 0;
  1372. ch->fepiflag = 0;
  1373. ch->fepoflag = 0;
  1374. ch->fepstartc = 0;
  1375. ch->fepstopc = 0;
  1376. ch->fepstartca = 0;
  1377. ch->fepstopca = 0;
  1378. ch->close_delay = 50;
  1379. ch->count = 0;
  1380. ch->blocked_open = 0;
  1381. ch->callout_termios = pcxe_callout.init_termios;
  1382. ch->normal_termios = pcxe_driver.init_termios;
  1383. init_waitqueue_head(&ch->open_wait);
  1384. init_waitqueue_head(&ch->close_wait);
  1385. ch->asyncflags = 0;
  1386. }
  1387. if (verbose)
  1388.     printk("Card No. %d ready: %s (%s) I/O=0x%x Mem=0x%lx Ports=%dn", 
  1389.     crd+1, board_desc[bd->type], board_mem[bd->type], bd->port, 
  1390.     bd->membase, bd->numports);
  1391. else
  1392.     printk("PC/Xx: %s (%s) I/O=0x%x Mem=0x%lx Ports=%dn", 
  1393.     board_desc[bd->type], board_mem[bd->type], bd->port, 
  1394.     bd->membase, bd->numports);
  1395. memwinoff(bd, 0);
  1396. enabled_cards++;
  1397. }
  1398. if (enabled_cards <= 0) {
  1399. printk(KERN_NOTICE "PC/Xx: No cards enabled, no driver.n");
  1400. ret = -EIO;
  1401. goto cleanup_boards;
  1402. }
  1403. ret = tty_register_driver(&pcxe_driver);
  1404. if(ret) {
  1405. printk(KERN_ERR "Couldn't register PC/Xe drivern");
  1406. goto cleanup_boards;
  1407. }
  1408. ret = tty_register_driver(&pcxe_callout);
  1409. if(ret) {
  1410. printk(KERN_ERR "Couldn't register PC/Xe calloutn");
  1411. goto cleanup_pcxe_driver;
  1412. }
  1413. /*
  1414.  * Start up the poller to check for events on all enabled boards
  1415.  */
  1416. mod_timer(&pcxx_timer, HZ/25);
  1417. if (verbose)
  1418. printk(KERN_NOTICE "PC/Xx: Driver with %d card(s) ready.n", enabled_cards);
  1419. return 0;
  1420. cleanup_pcxe_driver: tty_unregister_driver(&pcxe_driver);
  1421. cleanup_boards: cleanup_board_resources();
  1422. kfree(pcxe_termios_locked);
  1423. cleanup_pcxe_termios: kfree(pcxe_termios);
  1424. cleanup_pcxe_table: kfree(pcxe_table);
  1425. cleanup_digi_channels: kfree(digi_channels);
  1426. return ret;
  1427. }
  1428. static void pcxxpoll(unsigned long dummy)
  1429. {
  1430. unsigned long flags;
  1431. int crd;
  1432. volatile unsigned int head, tail;
  1433. struct channel *ch;
  1434. struct board_info *bd;
  1435. save_flags(flags);
  1436. cli();
  1437. for(crd=0; crd < numcards; crd++) {
  1438. bd = &boards[crd];
  1439. ch = digi_channels+bd->first_minor;
  1440. if(bd->status == DISABLED)
  1441. continue;
  1442. assertmemoff(ch);
  1443. globalwinon(ch);
  1444. head = ch->mailbox->ein;
  1445. tail = ch->mailbox->eout;
  1446. if(head != tail)
  1447. doevent(crd);
  1448. memoff(ch);
  1449. }
  1450. mod_timer(&pcxx_timer, jiffies + HZ/25);
  1451. restore_flags(flags);
  1452. }
  1453. static void doevent(int crd)
  1454. {
  1455. volatile struct board_info *bd;
  1456. static struct tty_struct *tty;
  1457. volatile struct board_chan *bc;
  1458. volatile unchar *eventbuf;
  1459. volatile unsigned int head;
  1460. volatile unsigned int tail;
  1461. struct channel *ch;
  1462. struct channel *chan0;
  1463. int channel, event, mstat, lstat;
  1464. bd = &boards[crd];
  1465. chan0 = digi_channels+bd->first_minor;
  1466. pcxxassert(chan0 < digi_channels+nbdevs, "ch out of range");
  1467. assertgwinon(chan0);
  1468. while ((tail = chan0->mailbox->eout) != (head = chan0->mailbox->ein)) {
  1469. assertgwinon(chan0);
  1470. eventbuf = (volatile unchar *)phys_to_virt(bd->membase + tail + ISTART);
  1471. channel = eventbuf[0];
  1472. event = eventbuf[1];
  1473. mstat = eventbuf[2];
  1474. lstat = eventbuf[3];
  1475. ch=chan0+channel;
  1476. if ((unsigned)channel >= bd->numports || !ch) { 
  1477. printk("physmem=%lx, tail=%x, head=%xn", bd->membase, tail, head);
  1478. printk("doevent(%x) channel %x, event %x, mstat %x, lstat %xn",
  1479. crd, (unsigned)channel, event, (unsigned)mstat, lstat);
  1480. if(channel >= bd->numports)
  1481. ch = chan0;
  1482. bc = ch->brdchan;
  1483. goto next;
  1484. }
  1485. if ((bc = ch->brdchan) == NULL)
  1486. goto next;
  1487. if (event & DATA_IND) {
  1488. receive_data(ch);
  1489. assertgwinon(ch);
  1490. }
  1491. if (event & MODEMCHG_IND) {
  1492. ch->imodem = mstat;
  1493. if (ch->asyncflags & (ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE)) {
  1494. if (ch->asyncflags & ASYNC_CHECK_CD) {
  1495. if (mstat & ch->dcd) {
  1496. wake_up_interruptible(&ch->open_wait);
  1497. } else {
  1498. pcxe_sched_event(ch, PCXE_EVENT_HANGUP);
  1499. }
  1500. }
  1501. }
  1502. }
  1503. tty = ch->tty;
  1504. if (tty) {
  1505. if (event & BREAK_IND) {
  1506. tty->flip.count++;
  1507. *tty->flip.flag_buf_ptr++ = TTY_BREAK;
  1508. *tty->flip.char_buf_ptr++ = 0;
  1509. #if 0
  1510. if (ch->asyncflags & ASYNC_SAK)
  1511. do_SAK(tty);
  1512. #endif
  1513. tty_schedule_flip(tty); 
  1514. }
  1515. if (event & LOWTX_IND) {
  1516. if (ch->statusflags & LOWWAIT) {
  1517. ch->statusflags &= ~LOWWAIT;
  1518. if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
  1519. tty->ldisc.write_wakeup)
  1520. (tty->ldisc.write_wakeup)(tty);
  1521. wake_up_interruptible(&tty->write_wait);
  1522. }
  1523. }
  1524. if (event & EMPTYTX_IND) {
  1525. ch->statusflags &= ~TXBUSY;
  1526. if (ch->statusflags & EMPTYWAIT) {
  1527. ch->statusflags &= ~EMPTYWAIT;
  1528. if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
  1529. tty->ldisc.write_wakeup)
  1530. (tty->ldisc.write_wakeup)(tty);
  1531. wake_up_interruptible(&tty->write_wait);
  1532. }
  1533. }
  1534. }
  1535. next:
  1536. globalwinon(ch);
  1537. if(!bc) printk("bc == NULL in doevent!n");
  1538. else bc->idata = 1;
  1539. chan0->mailbox->eout = (tail+4) & (IMAX-ISTART-4);
  1540. globalwinon(chan0);
  1541. }
  1542. }
  1543. /*
  1544.  * pcxxdelay - delays a specified number of milliseconds
  1545.  */
  1546. static void pcxxdelay(int msec)
  1547. {
  1548. mdelay(msec);
  1549. }
  1550. static void 
  1551. fepcmd(struct channel *ch, int cmd, int word_or_byte, int byte2, int ncmds,
  1552. int bytecmd)
  1553. {
  1554. unchar *memaddr;
  1555. unsigned int head, tail;
  1556. long count;
  1557. int n;
  1558. if(ch->board->status == DISABLED)
  1559. return;
  1560. assertgwinon(ch);
  1561. memaddr = (unchar *)phys_to_virt(ch->board->membase);
  1562. head = ch->mailbox->cin;
  1563. if(head >= (CMAX-CSTART) || (head & 03)) {
  1564. printk("line %d: Out of range, cmd=%x, head=%xn", __LINE__, cmd, head);
  1565. return;
  1566. }
  1567. if(bytecmd) {
  1568. *(unchar *)(memaddr+head+CSTART+0) = cmd;
  1569. *(unchar *)(memaddr+head+CSTART+1) = ch->dev - ch->board->first_minor;
  1570. *(unchar *)(memaddr+head+CSTART+2) = word_or_byte;
  1571. *(unchar *)(memaddr+head+CSTART+3) = byte2;
  1572. } else {
  1573. *(unchar *)(memaddr+head+CSTART+0) = cmd;
  1574. *(unchar *)(memaddr+head+CSTART+1) = ch->dev - ch->board->first_minor;
  1575. *(ushort*)(memaddr+head+CSTART+2) = word_or_byte;
  1576. }
  1577. head = (head+4) & (CMAX-CSTART-4);
  1578. ch->mailbox->cin = head;
  1579. count = FEPTIMEOUT;
  1580. while(1) {
  1581. count--;
  1582. if(count == 0) {
  1583. printk("Fep not responding in fepcmd()n");
  1584. return;
  1585. }
  1586. head = ch->mailbox->cin;
  1587. tail = ch->mailbox->cout;
  1588. n = (head-tail) & (CMAX-CSTART-4);
  1589. if(n <= ncmds * (sizeof(short)*4))
  1590. break;
  1591. /* Seems not to be good here: schedule(); */
  1592. }
  1593. }
  1594. static unsigned termios2digi_c(struct channel *ch, unsigned cflag)
  1595. {
  1596. unsigned res = 0;
  1597. if (cflag & CBAUDEX)
  1598. {
  1599. ch->digiext.digi_flags |= DIGI_FAST;
  1600. res |= FEP_HUPCL;
  1601. /* This gets strange but if we don't do this we will get 78600
  1602.  * instead of 115200. 57600 is mapped to 50 baud yielding 57600 in
  1603.  * FAST mode. 115200 is mapped to 75. We need to map it to 110 to
  1604.  * do 115K
  1605.  */
  1606. if (cflag & B115200) res|=1;
  1607. }
  1608. else ch->digiext.digi_flags &= ~DIGI_FAST;
  1609. res |= cflag & (CBAUD | PARODD | PARENB | CSTOPB | CSIZE | CLOCAL);
  1610. return res;
  1611. }
  1612. static unsigned termios2digi_i(struct channel *ch, unsigned iflag)
  1613. {
  1614. unsigned res = iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP|IXON|IXANY|IXOFF);
  1615. if(ch->digiext.digi_flags & DIGI_AIXON)
  1616. res |= IAIXON;
  1617. return res;
  1618. }
  1619. static unsigned termios2digi_h(struct channel *ch, unsigned cflag)
  1620. {
  1621. unsigned res = 0;
  1622. if(cflag & CRTSCTS) {
  1623. ch->digiext.digi_flags |= (RTSPACE|CTSPACE);
  1624. res |= (CTS | RTS);
  1625. }
  1626. if(ch->digiext.digi_flags & RTSPACE)
  1627. res |= RTS;
  1628. if(ch->digiext.digi_flags & DTRPACE)
  1629. res |= DTR;
  1630. if(ch->digiext.digi_flags & CTSPACE)
  1631. res |= CTS;
  1632. if(ch->digiext.digi_flags & DSRPACE)
  1633. res |= ch->dsr;
  1634. if(ch->digiext.digi_flags & DCDPACE)
  1635. res |= ch->dcd;
  1636. if (res & RTS)
  1637. ch->digiext.digi_flags |= RTSPACE;
  1638. if (res & CTS)
  1639. ch->digiext.digi_flags |= CTSPACE;
  1640. return res;
  1641. }
  1642. static void pcxxparam(struct tty_struct *tty, struct channel *ch)
  1643. {
  1644. volatile struct board_chan *bc;
  1645. unsigned int head;
  1646. unsigned mval, hflow, cflag, iflag;
  1647. struct termios *ts;
  1648. bc = ch->brdchan;
  1649. assertgwinon(ch);
  1650. ts = tty->termios;
  1651. if((ts->c_cflag & CBAUD) == 0) {
  1652. head = bc->rin;
  1653. bc->rout = head;
  1654. head = bc->tin;
  1655. fepcmd(ch, STOUT, (unsigned) head, 0, 0, 0);
  1656. mval = 0;
  1657. } else {
  1658. cflag = termios2digi_c(ch, ts->c_cflag);
  1659. if(cflag != ch->fepcflag) {
  1660. ch->fepcflag = cflag;
  1661. fepcmd(ch, SETCTRLFLAGS, (unsigned) cflag, 0, 0, 0);
  1662. }
  1663. if(cflag & CLOCAL)
  1664. ch->asyncflags &= ~ASYNC_CHECK_CD;
  1665. else {
  1666. ch->asyncflags |= ASYNC_CHECK_CD;
  1667. }
  1668. mval = DTR | RTS;
  1669. }
  1670. iflag = termios2digi_i(ch, ts->c_iflag);
  1671. if(iflag != ch->fepiflag) {
  1672. ch->fepiflag = iflag;
  1673. fepcmd(ch, SETIFLAGS, (unsigned int) ch->fepiflag, 0, 0, 0);
  1674. }
  1675. bc->mint = ch->dcd;
  1676. if((ts->c_cflag & CLOCAL) || (ch->digiext.digi_flags & DIGI_FORCEDCD))
  1677. if(ch->digiext.digi_flags & DIGI_FORCEDCD)
  1678. bc->mint = 0;
  1679. ch->imodem = bc->mstat;
  1680. hflow = termios2digi_h(ch, ts->c_cflag);
  1681. if(hflow != ch->hflow) {
  1682. ch->hflow = hflow;
  1683. fepcmd(ch, SETHFLOW, hflow, 0xff, 0, 1);
  1684. }
  1685. /* mval ^= ch->modemfake & (mval ^ ch->modem); */
  1686. if(ch->omodem != mval) {
  1687. ch->omodem = mval;
  1688. fepcmd(ch, SETMODEM, mval, RTS|DTR, 0, 1);
  1689. }
  1690. if(ch->startc != ch->fepstartc || ch->stopc != ch->fepstopc) {
  1691. ch->fepstartc = ch->startc;
  1692. ch->fepstopc = ch->stopc;
  1693. fepcmd(ch, SONOFFC, ch->fepstartc, ch->fepstopc, 0, 1);
  1694. }
  1695. if(ch->startca != ch->fepstartca || ch->stopca != ch->fepstopca) {
  1696. ch->fepstartca = ch->startca;
  1697. ch->fepstopca = ch->stopca;
  1698. fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1);
  1699. }
  1700. }
  1701. static void receive_data(struct channel *ch)
  1702. {
  1703. volatile struct board_chan *bc;
  1704. struct tty_struct *tty;
  1705. unsigned int tail, head, wrapmask;
  1706. int n;
  1707. int piece;
  1708. struct termios *ts=0;
  1709. unchar *rptr;
  1710. int rc;
  1711. int wrapgap;
  1712.     globalwinon(ch);
  1713. if (ch->statusflags & RXSTOPPED)
  1714. return;
  1715. tty = ch->tty;
  1716. if(tty)
  1717. ts = tty->termios;
  1718. bc = ch->brdchan;
  1719. if(!bc) {
  1720. printk("bc is NULL in receive_data!n");
  1721. return;
  1722. }
  1723. wrapmask = ch->rxbufsize - 1;
  1724. head = bc->rin;
  1725. head &= wrapmask;
  1726. tail = bc->rout & wrapmask;
  1727. n = (head-tail) & wrapmask;
  1728. if(n == 0)
  1729. return;
  1730. /*
  1731.  * If CREAD bit is off or device not open, set TX tail to head
  1732.  */
  1733. if(!tty || !ts || !(ts->c_cflag & CREAD)) {
  1734. bc->rout = head;
  1735. return;
  1736. }
  1737. if(tty->flip.count == TTY_FLIPBUF_SIZE) {
  1738. /* printk("tty->flip.count = TTY_FLIPBUF_SIZEn"); */
  1739. return;
  1740. }
  1741. if(bc->orun) {
  1742. bc->orun = 0;
  1743. printk("overrun! DigiBoard device minor=%dn",MINOR(tty->device));
  1744. }
  1745. rxwinon(ch);
  1746. rptr = tty->flip.char_buf_ptr;
  1747. rc = tty->flip.count;
  1748. while(n > 0) {
  1749. wrapgap = (head >= tail) ? head - tail : ch->rxbufsize - tail;
  1750. piece = (wrapgap < n) ? wrapgap : n;
  1751. /*
  1752.  * Make sure we don't overflow the buffer
  1753.  */
  1754. if ((rc + piece) > TTY_FLIPBUF_SIZE)
  1755. piece = TTY_FLIPBUF_SIZE - rc;
  1756. if (piece == 0)
  1757. break;
  1758. memcpy(rptr, ch->rxptr + tail, piece);
  1759. rptr += piece;
  1760. rc += piece;
  1761. tail = (tail + piece) & wrapmask;
  1762. n -= piece;
  1763. }
  1764. tty->flip.count = rc;
  1765. tty->flip.char_buf_ptr = rptr;
  1766.     globalwinon(ch);
  1767. bc->rout = tail;
  1768. /* Must be called with global data */
  1769. tty_schedule_flip(ch->tty); 
  1770. return;
  1771. }
  1772. static int pcxe_ioctl(struct tty_struct *tty, struct file * file,
  1773.     unsigned int cmd, unsigned long arg)
  1774. {
  1775. struct channel *ch = (struct channel *) tty->driver_data;
  1776. volatile struct board_chan *bc;
  1777. int retval;
  1778. unsigned int mflag, mstat;
  1779. unsigned char startc, stopc;
  1780. unsigned long flags;
  1781. digiflow_t dflow;
  1782. if(ch)
  1783. bc = ch->brdchan;
  1784. else {
  1785. printk("ch is NULL in pcxe_ioctl!n");
  1786. return(-EINVAL);
  1787. }
  1788. save_flags(flags);
  1789. switch(cmd) {
  1790. case TCSBRK: /* SVID version: non-zero arg --> no break */
  1791. retval = tty_check_change(tty);
  1792. if(retval)
  1793. return retval;
  1794. setup_empty_event(tty,ch);
  1795. tty_wait_until_sent(tty, 0);
  1796. if(!arg)
  1797. digi_send_break(ch, HZ/4);    /* 1/4 second */
  1798. return 0;
  1799. case TCSBRKP: /* support for POSIX tcsendbreak() */
  1800. retval = tty_check_change(tty);
  1801. if(retval)
  1802. return retval;
  1803. setup_empty_event(tty,ch);
  1804. tty_wait_until_sent(tty, 0);
  1805. digi_send_break(ch, arg ? arg*(HZ/10) : HZ/4);
  1806. return 0;
  1807. case TIOCGSOFTCAR:
  1808. return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned int *)arg);
  1809. case TIOCSSOFTCAR:
  1810. {
  1811.     unsigned int value;
  1812.     if (get_user(value, (unsigned int *) arg))
  1813.     return -EFAULT;
  1814.     tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (value ? CLOCAL : 0));
  1815. }
  1816. return 0;
  1817. case TIOCMODG:
  1818. case TIOCMGET:
  1819. mflag = 0;
  1820. cli();
  1821. globalwinon(ch);
  1822. mstat = bc->mstat;
  1823. memoff(ch);
  1824. restore_flags(flags);
  1825. if(mstat & DTR)
  1826. mflag |= TIOCM_DTR;
  1827. if(mstat & RTS)
  1828. mflag |= TIOCM_RTS;
  1829. if(mstat & CTS)
  1830. mflag |= TIOCM_CTS;
  1831. if(mstat & ch->dsr)
  1832. mflag |= TIOCM_DSR;
  1833. if(mstat & RI)
  1834. mflag |= TIOCM_RI;
  1835. if(mstat & ch->dcd)
  1836. mflag |= TIOCM_CD;
  1837. if (put_user(mflag, (unsigned int *) arg))
  1838. return -EFAULT;
  1839. break;
  1840. case TIOCMBIS:
  1841. case TIOCMBIC:
  1842. case TIOCMODS:
  1843. case TIOCMSET:
  1844. if (get_user(mstat, (unsigned int *) arg))
  1845. return -EFAULT;
  1846. mflag = 0;
  1847. if(mstat & TIOCM_DTR)
  1848. mflag |= DTR;
  1849. if(mstat & TIOCM_RTS)
  1850. mflag |= RTS;
  1851. switch(cmd) {
  1852. case TIOCMODS:
  1853. case TIOCMSET:
  1854. ch->modemfake = DTR|RTS;
  1855. ch->modem = mflag;
  1856. break;
  1857. case TIOCMBIS:
  1858. ch->modemfake |= mflag;
  1859. ch->modem |= mflag;
  1860. break;
  1861. case TIOCMBIC:
  1862. ch->modemfake &= ~mflag;
  1863. ch->modem &= ~mflag;
  1864. break;
  1865. }
  1866. cli();
  1867. globalwinon(ch);
  1868. pcxxparam(tty,ch);
  1869. memoff(ch);
  1870. restore_flags(flags);
  1871. break;
  1872. case TIOCSDTR:
  1873. cli();
  1874. ch->omodem |= DTR;
  1875. globalwinon(ch);
  1876. fepcmd(ch, SETMODEM, DTR, 0, 10, 1);
  1877. memoff(ch);
  1878. restore_flags(flags);
  1879. break;
  1880. case TIOCCDTR:
  1881. ch->omodem &= ~DTR;
  1882. cli();
  1883. globalwinon(ch);
  1884. fepcmd(ch, SETMODEM, 0, DTR, 10, 1);
  1885. memoff(ch);
  1886. restore_flags(flags);
  1887. break;
  1888. case DIGI_GETA:
  1889. if (copy_to_user((char*)arg, &ch->digiext, sizeof(digi_t)))
  1890. return -EFAULT;
  1891. break;
  1892. case DIGI_SETAW:
  1893. case DIGI_SETAF:
  1894. if(cmd == DIGI_SETAW) {
  1895. setup_empty_event(tty,ch);
  1896. tty_wait_until_sent(tty, 0);
  1897. }
  1898. else {
  1899. if(tty->ldisc.flush_buffer)
  1900. tty->ldisc.flush_buffer(tty);
  1901. }
  1902. /* Fall Thru */
  1903. case DIGI_SETA:
  1904. if (copy_from_user(&ch->digiext, (char*)arg, sizeof(digi_t)))
  1905. return -EFAULT;
  1906. #ifdef DEBUG_IOCTL
  1907. printk("ioctl(DIGI_SETA): flags = %xn", ch->digiext.digi_flags);
  1908. #endif
  1909. if(ch->digiext.digi_flags & DIGI_ALTPIN) {
  1910. ch->dcd = DSR;
  1911. ch->dsr = CD;
  1912. } else {
  1913. ch->dcd = CD;
  1914. ch->dsr = DSR;
  1915. }
  1916. cli();
  1917. globalwinon(ch);
  1918. pcxxparam(tty,ch);
  1919. memoff(ch);
  1920. restore_flags(flags);
  1921. break;
  1922. case DIGI_GETFLOW:
  1923. case DIGI_GETAFLOW:
  1924. cli();
  1925. globalwinon(ch);
  1926. if(cmd == DIGI_GETFLOW) {
  1927. dflow.startc = bc->startc;
  1928. dflow.stopc = bc->stopc;
  1929. } else {
  1930. dflow.startc = bc->startca;
  1931. dflow.stopc = bc->stopca;
  1932. }
  1933. memoff(ch);
  1934. restore_flags(flags);
  1935. if (copy_to_user((char*)arg, &dflow, sizeof(dflow)))
  1936. return -EFAULT;
  1937. break;
  1938. case DIGI_SETAFLOW:
  1939. case DIGI_SETFLOW:
  1940. if(cmd == DIGI_SETFLOW) {
  1941. startc = ch->startc;
  1942. stopc = ch->stopc;
  1943. } else {
  1944. startc = ch->startca;
  1945. stopc = ch->stopca;
  1946. }
  1947. if (copy_from_user(&dflow, (char*)arg, sizeof(dflow)))
  1948. return -EFAULT;
  1949. if(dflow.startc != startc || dflow.stopc != stopc) {
  1950. cli();
  1951. globalwinon(ch);
  1952. if(cmd == DIGI_SETFLOW) {
  1953. ch->fepstartc = ch->startc = dflow.startc;
  1954. ch->fepstopc = ch->stopc = dflow.stopc;
  1955. fepcmd(ch,SONOFFC,ch->fepstartc,ch->fepstopc,0, 1);
  1956. } else {
  1957. ch->fepstartca = ch->startca = dflow.startc;
  1958. ch->fepstopca  = ch->stopca = dflow.stopc;
  1959. fepcmd(ch, SAUXONOFFC, ch->fepstartca, ch->fepstopca, 0, 1);
  1960. }
  1961. if(ch->statusflags & TXSTOPPED)
  1962. pcxe_start(tty);
  1963. memoff(ch);
  1964. restore_flags(flags);
  1965. }
  1966. break;
  1967. default:
  1968. return -ENOIOCTLCMD;
  1969. }
  1970. return 0;
  1971. }
  1972. static void pcxe_set_termios(struct tty_struct *tty, struct termios *old_termios)
  1973. {
  1974. struct channel *info;
  1975. if ((info=chan(tty))!=NULL) {
  1976. unsigned long flags;
  1977. save_flags(flags);
  1978. cli();
  1979. globalwinon(info);
  1980. pcxxparam(tty,info);
  1981. memoff(info);
  1982. if ((old_termios->c_cflag & CRTSCTS) &&
  1983. ((tty->termios->c_cflag & CRTSCTS) == 0))
  1984. tty->hw_stopped = 0;
  1985. if(!(old_termios->c_cflag & CLOCAL) &&
  1986. (tty->termios->c_cflag & CLOCAL))
  1987. wake_up_interruptible(&info->open_wait);
  1988. restore_flags(flags);
  1989. }
  1990. }
  1991. static void do_pcxe_bh(void)
  1992. {
  1993. run_task_queue(&tq_pcxx);
  1994. }
  1995. static void do_softint(void *private_)
  1996. {
  1997. struct channel *info = (struct channel *) private_;
  1998. if(info && info->magic == PCXX_MAGIC) {
  1999. struct tty_struct *tty = info->tty;
  2000. if (tty && tty->driver_data) {
  2001. if(test_and_clear_bit(PCXE_EVENT_HANGUP, &info->event)) {
  2002. tty_hangup(tty);
  2003. wake_up_interruptible(&info->open_wait);
  2004. info->asyncflags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
  2005. }
  2006. }
  2007. }
  2008. }
  2009. static void pcxe_stop(struct tty_struct *tty)
  2010. {
  2011. struct channel *info;
  2012. if ((info=chan(tty))!=NULL) {
  2013. unsigned long flags;
  2014. save_flags(flags); 
  2015. cli();
  2016. if ((info->statusflags & TXSTOPPED) == 0) {
  2017. globalwinon(info);
  2018. fepcmd(info, PAUSETX, 0, 0, 0, 0);
  2019. info->statusflags |= TXSTOPPED;
  2020. memoff(info);
  2021. }
  2022. restore_flags(flags);
  2023. }
  2024. }
  2025. static void pcxe_throttle(struct tty_struct * tty)
  2026. {
  2027. struct channel *info;
  2028. if ((info=chan(tty))!=NULL) {
  2029. unsigned long flags;
  2030. save_flags(flags);
  2031. cli();
  2032. if ((info->statusflags & RXSTOPPED) == 0) {
  2033. globalwinon(info);
  2034. fepcmd(info, PAUSERX, 0, 0, 0, 0);
  2035. info->statusflags |= RXSTOPPED;
  2036. memoff(info);
  2037. }
  2038. restore_flags(flags);
  2039. }
  2040. }
  2041. static void pcxe_unthrottle(struct tty_struct *tty)
  2042. {
  2043. struct channel *info;
  2044. if ((info=chan(tty)) != NULL) {
  2045. unsigned long flags;
  2046. /* Just in case output was resumed because of a change in Digi-flow */
  2047. save_flags(flags);
  2048. cli();
  2049. if(info->statusflags & RXSTOPPED) {
  2050. volatile struct board_chan *bc;
  2051. globalwinon(info);
  2052. bc = info->brdchan;
  2053. fepcmd(info, RESUMERX, 0, 0, 0, 0);
  2054. info->statusflags &= ~RXSTOPPED;
  2055. memoff(info);
  2056. }
  2057. restore_flags(flags);
  2058. }
  2059. }
  2060. static void pcxe_start(struct tty_struct *tty)
  2061. {
  2062. struct channel *info;
  2063. if ((info=chan(tty))!=NULL) {
  2064. unsigned long flags;
  2065. save_flags(flags);
  2066. cli();
  2067. /* Just in case output was resumed because of a change in Digi-flow */
  2068. if(info->statusflags & TXSTOPPED) {
  2069. volatile struct board_chan *bc;
  2070. globalwinon(info);
  2071. bc = info->brdchan;
  2072. if(info->statusflags & LOWWAIT)
  2073. bc->ilow = 1;
  2074. fepcmd(info, RESUMETX, 0, 0, 0, 0);
  2075. info->statusflags &= ~TXSTOPPED;
  2076. memoff(info);
  2077. }
  2078. restore_flags(flags);
  2079. }
  2080. }
  2081. void digi_send_break(struct channel *ch, int msec)
  2082. {
  2083. unsigned long flags;
  2084. save_flags(flags);
  2085. cli();
  2086. globalwinon(ch);
  2087. /* 
  2088.  * Maybe I should send an infinite break here, schedule() for
  2089.  * msec amount of time, and then stop the break.  This way,
  2090.  * the user can't screw up the FEP by causing digi_send_break()
  2091.  * to be called (i.e. via an ioctl()) more than once in msec amount 
  2092.  * of time.  Try this for now...
  2093.  */
  2094. fepcmd(ch, SENDBREAK, msec, 0, 10, 0);
  2095. memoff(ch);
  2096. restore_flags(flags);
  2097. }
  2098. static void setup_empty_event(struct tty_struct *tty, struct channel *ch)
  2099. {
  2100. volatile struct board_chan *bc;
  2101. unsigned long flags;
  2102. save_flags(flags);
  2103. cli();
  2104. globalwinon(ch);
  2105. ch->statusflags |= EMPTYWAIT;
  2106. bc = ch->brdchan;
  2107. bc->iempty = 1;
  2108. memoff(ch);
  2109. restore_flags(flags);
  2110. }