home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2658 < prev    next >
Encoding:
Internet Message Format  |  1991-02-05  |  59.8 KB

  1. From: gemini@geminix.in-berlin.de (Uwe Doering)
  2. Newsgroups: comp.unix.sysv386,comp.unix.xenix.sco,alt.sources
  3. Subject: FAS 2.08 async driver, part 3/4
  4. Message-ID: <80TN1GE@geminix.in-berlin.de>
  5. Date: 3 Feb 91 22:18:00 GMT
  6.  
  7. Submitted-by: gemini@geminix.in-berlin.de
  8. Archive-name: fas208/part03
  9.  
  10. #!/bin/sh
  11. # this is fas208.03 (part 3 of fas208)
  12. # do not concatenate these parts, unpack them in order with /bin/sh
  13. # file fas.c continued
  14. #
  15. if test ! -r _shar_seq_.tmp; then
  16.     echo 'Please unpack part 1 first!'
  17.     exit 1
  18. fi
  19. (read Scheck
  20.  if test "$Scheck" != 3; then
  21.     echo Please unpack part "$Scheck" next!
  22.     exit 1
  23.  else
  24.     exit 0
  25.  fi
  26. ) < _shar_seq_.tmp || exit 1
  27. if test ! -f _shar_wnt_.tmp; then
  28.     echo 'x - still skipping fas.c'
  29. else
  30. echo 'x - continuing file fas.c'
  31. sed 's/^X//' << 'SHAR_EOF' >> 'fas.c' &&
  32. X        goto setflags;
  33. X
  34. X    /* lock transmitter and wait until it is empty */
  35. X    fip->device_flags.s |= DF_XMIT_LOCKED;
  36. X    while (fip->device_flags.i & (DF_XMIT_BUSY | DF_XMIT_BREAK
  37. X                            | DF_GUARD_TIMEOUT))
  38. X        (void) sleep ((caddr_t) &fip->device_flags.i, PZERO - 1);
  39. X
  40. X    /* hangup line if it is baud rate 0, else enable line */
  41. X    if ((cflag & CBAUD) == B0)
  42. X    {
  43. X        fip->mcr &= (fip->o_state & OS_WAIT_OPEN)
  44. X                ? ~fip->modem.m.ei
  45. X                : ~fip->modem.m.eo;
  46. X        fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
  47. X        fip->device_flags.s &= ~DF_MODEM_ENABLED;
  48. X    }
  49. X    else
  50. X    {
  51. X        if (!(fip->device_flags.i & DF_MODEM_ENABLED))
  52. X        {
  53. X            fip->mcr |= (fip->o_state & OS_WAIT_OPEN)
  54. X                    ? fip->modem.m.ei
  55. X                    : fip->modem.m.eo;
  56. X            fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
  57. X            fip->device_flags.s |= DF_MODEM_ENABLED;
  58. X        }
  59. X    }
  60. X
  61. X    /* don't change break flag */
  62. X    fip->lcr &= LC_SET_BREAK_LEVEL;
  63. X
  64. X    /* set character size */
  65. X    switch (cflag & CSIZE)
  66. X    {
  67. X    case CS5:
  68. X        fip->lcr |= LC_WORDLEN_5;
  69. X        break;
  70. X
  71. X    case CS6:
  72. X        fip->lcr |= LC_WORDLEN_6;
  73. X        break;
  74. X
  75. X    case CS7:
  76. X        fip->lcr |= LC_WORDLEN_7;
  77. X        break;
  78. X
  79. X    default:
  80. X        fip->lcr |= LC_WORDLEN_8;
  81. X        break;
  82. X    }
  83. X
  84. X    /* set # of stop bits */
  85. X    if (cflag & CSTOPB)
  86. X        fip->lcr |= LC_STOPBITS_LONG;
  87. X
  88. X    /* set parity */
  89. X    if (cflag & PARENB)
  90. X    {
  91. X        fip->lcr |= LC_ENABLE_PARITY;
  92. X
  93. X        if (!(cflag & PARODD))
  94. X            fip->lcr |= LC_EVEN_PARITY;
  95. X    }
  96. X
  97. X    /* set divisor registers only if baud rate is valid */
  98. X    if ((cflag & CBAUD) != B0)
  99. X    {
  100. X        /* get counter divisor for selected baud rate */
  101. X        divisor = fas_speeds [cflag & CBAUD];
  102. X        /* set LCR and baud rate */
  103. X        fas_first_outb (fip, LINE_CTL_PORT, fip->lcr
  104. X                            | LC_ENABLE_DIVISOR);
  105. X        fas_outb (fip, DIVISOR_LSB_PORT, divisor);
  106. X        fas_outb (fip, DIVISOR_MSB_PORT, divisor >> 8);
  107. X    }
  108. X
  109. X    fas_first_outb (fip, LINE_CTL_PORT, fip->lcr);
  110. X
  111. Xsetflags:
  112. X    /* check dynamic xmit ring buffer size against boundaries,
  113. X       modify it if necessary and update the fas_info structure
  114. X    */
  115. X    if ((cflag & CBAUD) != B0)
  116. X    {
  117. X        xmit_ring_size = fas_xbuf_size [cflag & CBAUD]
  118. X                    - tthiwat [cflag & CBAUD];
  119. X        if (xmit_ring_size < MAX_OUTPUT_FIFO_SIZE * 2)
  120. X        {
  121. Xsetflags2:
  122. X            xmit_ring_size = MAX_OUTPUT_FIFO_SIZE * 2;
  123. X        }
  124. X        if (xmit_ring_size > XMIT_BUFF_SIZE)
  125. X            xmit_ring_size = XMIT_BUFF_SIZE;
  126. X        fip->xmit_ring_size = xmit_ring_size;
  127. X    }
  128. X
  129. X    /* setup character time for B0 mode */
  130. X    fas_ctimes [B0] = fas_ctimes [cflag & CBAUD];
  131. X
  132. X    /* disable modem control signals if required by open mode */
  133. X    if (fip->o_state & OS_CLOCAL)
  134. X        cflag |= CLOCAL;
  135. X
  136. X    /* Select hardware handshake depending on the minor device
  137. X       number and the CTSFLOW and RTSFLOW flags (if they are
  138. X       available).
  139. X    */
  140. X    fip->flow_flags.s &= ~(FF_HWO_HANDSHAKE
  141. X                | FF_HWI_HANDSHAKE
  142. X                | FF_HDX_HANDSHAKE);
  143. X    if (fip->o_state & (OS_HWO_HANDSHAKE | OS_HWI_HANDSHAKE
  144. X                    | OS_HDX_HANDSHAKE))
  145. X    {
  146. X        if (fip->o_state & OS_HWO_HANDSHAKE)
  147. X            fip->flow_flags.s |= FF_HWO_HANDSHAKE;
  148. X        if (fip->o_state & OS_HWI_HANDSHAKE)
  149. X            fip->flow_flags.s |= FF_HWI_HANDSHAKE;
  150. X        if (fip->o_state & OS_HDX_HANDSHAKE)
  151. X            fip->flow_flags.s |= FF_HDX_HANDSHAKE;
  152. X    }
  153. X    else
  154. X    {
  155. X#if defined (CTSFLOW)    /* SYSV 3.2 Xenix compatibility */
  156. X        if ((cflag & (CTSFLOW | CLOCAL)) == CTSFLOW)
  157. X            fip->flow_flags.s |= FF_HWO_HANDSHAKE;
  158. X#endif
  159. X#if defined (RTSFLOW)    /* SYSV 3.2 Xenix compatibility */
  160. X        if ((cflag & (RTSFLOW | CLOCAL)) == RTSFLOW)
  161. X            fip->flow_flags.s |= FF_HDX_HANDSHAKE;
  162. X#endif
  163. X    }
  164. X
  165. X    /* Fake the carrier detect state flag if CLOCAL mode or if
  166. X       requested by open mode.
  167. X    */
  168. X    if (!(~fip->msr & fip->modem.m.ca)
  169. X        || (fip->o_state & OS_FAKE_CARR_ON)
  170. X        || (cflag & CLOCAL))
  171. X        fip->tty->t_state |= CARR_ON;
  172. X    else
  173. X        fip->tty->t_state &= ~CARR_ON;
  174. X
  175. X#if defined (XCLUDE)    /* SYSV 3.2 Xenix compatibility */
  176. X    /* Permit exclusive use of this device. */
  177. X    if (cflag & XCLUDE)
  178. X        fip->o_state |= OS_EXCLUSIVE_OPEN_2;
  179. X    else
  180. X        fip->o_state &= ~OS_EXCLUSIVE_OPEN_2;
  181. X#endif
  182. X
  183. X    fip->cflag = cflag;
  184. X    fip->iflag = fip->tty->t_iflag;
  185. X
  186. X    /* enable transmitter */
  187. X    fip->device_flags.s &= ~DF_XMIT_LOCKED;
  188. X
  189. X    /* setup handshake flags */
  190. X    fas_hdx_check (fip);
  191. X    fas_ihlw_check (fip);
  192. X    fas_fproc (fip, fip->new_msr);
  193. X
  194. X    /* restart output */
  195. X    fas_xproc (fip);
  196. X}
  197. X
  198. X/* Main fas interrupt handler. Actual character processing is splitted
  199. X   into sub-functions.
  200. X*/
  201. Xint
  202. Xfasintr (vect)
  203. Xint    vect;
  204. X{
  205. X    register struct fas_info    *fip;
  206. X    register uint    status;
  207. X    struct fas_info    *old_fip;
  208. X    int    done, drop_mode;
  209. X    uint    port, old_recv_count;
  210. X    REGVAR;
  211. X
  212. X    drop_mode = FALSE;
  213. X
  214. X    /* The 8259 interrupt controller is set up for edge trigger.
  215. X       Therefor, we must loop until we make a complete pass without
  216. X       getting any UARTs that are interrupting.
  217. X    */
  218. X    do
  219. X    {
  220. X        done = TRUE;
  221. X        fip = fas_first_int_user [vect];
  222. X
  223. X        /* loop through all users of this interrupt vector */
  224. X        for (;; fip = fip->next_int_user)
  225. X        {
  226. X            if (!fip)
  227. X                break;    /* all users done */
  228. X
  229. X            /* process only ports that we expect ints from
  230. X               and that actually need to be serviced
  231. X            */
  232. Xfastloop:
  233. X            if (fas_first_inb (fip, INT_ID_PORT)
  234. X                    & II_NO_INTS_PENDING)
  235. X            {
  236. X                /* restore the normal receiver trigger level */
  237. X                if (fip->device_flags.i & DF_NS16550A_DROP_MODE)
  238. X                {
  239. X                    fip->device_flags.s &=
  240. X                            ~DF_NS16550A_DROP_MODE;
  241. X                    fas_outb (fip, NS_FIFO_CTL_PORT,
  242. X                            NS_FIFO_SETUP_CMD);
  243. X                }
  244. X                /* speed beats beauty */
  245. X                fip = fip->next_int_user;
  246. X                if (fip)
  247. X                    goto fastloop;
  248. X                break;
  249. X            }
  250. X
  251. X            /* restore the normal receiver trigger level */
  252. X            if (fip->device_flags.i & DF_NS16550A_DROP_MODE)
  253. X            {
  254. X                fip->device_flags.s &= ~DF_NS16550A_DROP_MODE;
  255. X                fas_outb (fip, NS_FIFO_CTL_PORT,
  256. X                            NS_FIFO_SETUP_CMD);
  257. X            }
  258. X
  259. X            done = FALSE;    /* not done if we got an int */
  260. X            old_recv_count = fip->recv_ring_cnt;
  261. X
  262. X            do
  263. X            {
  264. X                /* read in all the characters from the FIFO */
  265. X                if ((status = fas_inb (fip, LINE_STATUS_PORT))
  266. X                            & LS_RCV_INT)
  267. X                {
  268. X                    if (!drop_mode && (fip->device_flags.i
  269. X                        & DF_DEVICE_IS_NS16550A))
  270. X                    {
  271. X                    /* Drop receiver trigger levels to make
  272. X                       sure that we will see all received
  273. X                       characters in all NS16550A. This
  274. X                       prevents multiple interrupts if we
  275. X                       receive characters on more than one
  276. X                       unit.
  277. X                    */
  278. X                    old_fip = fip;
  279. X                    for (fip = fas_first_int_user [vect];
  280. X                        fip; fip = fip->next_int_user)
  281. X                    {
  282. X                        if ((fip->device_flags.i
  283. X                            & DF_DEVICE_IS_NS16550A)
  284. X                        && (fip != old_fip))
  285. X                        {
  286. X                        fip->device_flags.s |=
  287. X                            DF_NS16550A_DROP_MODE;
  288. X                        fas_first_outb (fip,
  289. X                            NS_FIFO_CTL_PORT,
  290. X                            NS_FIFO_DROP_CMD);
  291. X                        }
  292. X                    }
  293. X                    fip = old_fip;
  294. X                    drop_mode = TRUE;
  295. X                    }
  296. X                    status = fas_rproc (fip, status);
  297. X                    sysinfo.rcvint++;
  298. X                }
  299. X
  300. X                /* Is it a transmitter empty int ? */
  301. X                if ((status & LS_XMIT_AVAIL)
  302. X                    && (fip->device_flags.i & DF_XMIT_BUSY))
  303. X                {
  304. X                    fip->device_flags.s &= ~DF_XMIT_BUSY;
  305. X                    fas_xproc (fip);
  306. X                    if (!(fip->device_flags.i
  307. X                            & DF_XMIT_BUSY))
  308. X                    {
  309. X                        fip->device_flags.s |=
  310. X                            DF_GUARD_TIMEOUT;
  311. X                        fip->tty->t_state |=
  312. X                            TIMEOUT;
  313. X                        fip->timeout_idx =
  314. X                            timeout (
  315. X                            fas_timeout, fip,
  316. X                            fas_ctimes [fip->cflag
  317. X                                & CBAUD]);
  318. X                    }
  319. X                    sysinfo.xmtint++;
  320. X                }
  321. X
  322. X                /* Has there been a polarity change on
  323. X                   some of the modem lines ?
  324. X                */
  325. X                if ((status = fas_inb (fip, MDM_STATUS_PORT))
  326. X                        & MS_ANY_DELTA)
  327. X                {
  328. X                    /* Do special RING line handling.
  329. X                       RING generates an int only on the
  330. X                       trailing edge.
  331. X                    */
  332. X                    status = (status & ~MS_RING_PRESENT)
  333. X                        | (fip->new_msr
  334. X                            & MS_RING_PRESENT);
  335. X                    if (status & MS_RING_TEDGE)
  336. X                        status |= MS_RING_PRESENT;
  337. X                    if ((status ^ fip->new_msr)
  338. X                            & MS_ANY_PRESENT)
  339. X                    {
  340. X                        /* check for excessive modem
  341. X                           status interrupts
  342. X                        */
  343. X                        if (++fip->msi_cnt >
  344. X                            (MAX_MSI_CNT / HZ)
  345. X                              * (EVENT_TIME * HZ
  346. X                                / 1000))
  347. X                        {
  348. X                            fip->ier = IE_NONE;
  349. X                            fas_outb (fip,
  350. X                                INT_ENABLE_PORT,
  351. X                                fip->ier);
  352. X                        }
  353. X                        /* check hw flow flags */
  354. X                        fas_fproc (fip, status);
  355. X                        fip->new_msr = status;
  356. X                        event_sched (fip, EF_DO_MPROC);
  357. X                    }
  358. X                    sysinfo.mdmint++;
  359. X                }
  360. X            } while (!(fas_inb (fip, INT_ID_PORT)
  361. X                        & II_NO_INTS_PENDING));
  362. X
  363. X            /* schedule character transfer to UNIX buffer */
  364. X            if (fip->recv_ring_cnt
  365. X#if defined (HAVE_VPIX)
  366. X                && (((fip->iflag & DOSMODE)
  367. X                    ? MAX_VPIX_FILL - MIN_READ_CHUNK
  368. X                    : MAX_UNIX_FILL - MIN_READ_CHUNK)
  369. X                        >= fip->tty->t_rawq.c_cc)
  370. X#else
  371. X                && ((MAX_UNIX_FILL - MIN_READ_CHUNK)
  372. X                        >= fip->tty->t_rawq.c_cc)
  373. X#endif
  374. X                && !(fip->flow_flags.i & FF_RXFER_STOPPED))
  375. X            {
  376. X                event_sched (fip, EF_DO_RXFER);
  377. X            }
  378. X
  379. X            /* check input buffer high/low water marks */
  380. X            if (fip->recv_ring_cnt != old_recv_count)
  381. X                fas_ihlw_check (fip);
  382. X        }
  383. X    } while (!done);
  384. X
  385. X    /* clear the shared interrupt since we have scanned all
  386. X       of the ports that share this interrupt vector
  387. X    */    
  388. X    if (port = fas_int_ack_port [vect])
  389. X        (void) outb (port, fas_int_ack [vect]);
  390. X
  391. X    return (0);
  392. X}
  393. X
  394. X/* hardware flow control interrupt handler */
  395. Xstatic void
  396. Xfas_fproc (fip, mdm_status)
  397. Xregister struct fas_info    *fip;
  398. Xregister uint    mdm_status;
  399. X{
  400. X    /* Check the output flow control signals and set the state flag
  401. X       accordingly.
  402. X    */
  403. X    if (!(~mdm_status & fip->flow.m.oc)
  404. X        || (~mdm_status & fip->flow.m.oe)
  405. X        || !(fip->flow_flags.i & FF_HWO_HANDSHAKE))
  406. X    {
  407. X        if (fip->flow_flags.i & FF_HWO_STOPPED)
  408. X        {
  409. X            fip->flow_flags.s &= ~FF_HWO_STOPPED;
  410. X            fas_xproc (fip);
  411. X        }
  412. X    }
  413. X    else
  414. X        fip->flow_flags.s |= FF_HWO_STOPPED;
  415. X}
  416. X
  417. X/* modem status handler */
  418. Xstatic void
  419. Xfas_mproc (fip)
  420. Xregister struct fas_info    *fip;
  421. X{
  422. X    register struct tty    *ttyp;
  423. X    register uint    mdm_status;
  424. X    uint    vpix_status;
  425. X    int    old_level;
  426. X
  427. X    ttyp = fip->tty;
  428. X    mdm_status = fip->new_msr;
  429. X    fip->new_msr &= ~MS_RING_PRESENT;
  430. X
  431. X    /* Check the carrier detect signal and set the state flags
  432. X       accordingly. Also, if not in clocal mode, send SIGHUP on
  433. X       carrier loss and flush the buffers.
  434. X    */
  435. X    if (!(fip->cflag & CLOCAL))
  436. X    {
  437. X        if (!(~mdm_status & fip->modem.m.ca))
  438. X        {
  439. X            ttyp->t_state |= CARR_ON;
  440. X            /* Unblock getty open only if it is ready to run. */
  441. X            if ((ttyp->t_state & WOPEN)
  442. X                && (~fip->msr & fip->modem.m.ca))
  443. X                (void) wakeup ((caddr_t) &ttyp->t_canq);
  444. X        }
  445. X        else
  446. X        {
  447. X            if (!(~fip->msr & fip->modem.m.ca))
  448. X            {
  449. X                ttyp->t_state &= ~CARR_ON;
  450. X                old_level = SPLWRK ();
  451. X                if (ttyp->t_state & ISOPEN)
  452. X                    (void) signal (ttyp->t_pgrp, SIGHUP);
  453. X                (void) ttyflush (ttyp, FREAD | FWRITE);
  454. X                (void) splx (old_level);
  455. X            }
  456. X        }
  457. X    }
  458. X
  459. X#if defined (HAVE_VPIX)
  460. X    if (((fip->iflag & (DOSMODE | PARMRK))
  461. X            == (DOSMODE | PARMRK))
  462. X        && (fip->v86_intmask != V86VI_KBD))
  463. X    {
  464. X        /* prepare status bits for VP/ix */
  465. X        vpix_status = (((mdm_status ^ fip->msr) >> 4) & MS_ANY_DELTA)
  466. X                | (mdm_status & (MS_CTS_PRESENT
  467. X                            | MS_DSR_PRESENT
  468. X                            | MS_DCD_PRESENT));
  469. X        if (fip->flow_flags.i & FF_HWO_HANDSHAKE)
  470. X        {
  471. X            vpix_status &= ~((fip->flow.m.oc | fip->flow.m.oe)
  472. X                            >> 4);
  473. X            vpix_status |= fip->flow.m.oc | fip->flow.m.oe;
  474. X        }
  475. X        /* send status bits to VP/ix */
  476. X        if ((vpix_status & MS_ANY_DELTA)
  477. X            && fas_vpix_sr (fip, 2, vpix_status))
  478. X            event_sched (fip, EF_DO_RXFER);
  479. X    }
  480. X#endif
  481. X    fip->msr = mdm_status & ~MS_RING_PRESENT;
  482. X
  483. X    /* re-schedule if modem status flags have changed in the mean time */
  484. X    if ((fip->new_msr ^ fip->msr) & MS_ANY_PRESENT)
  485. X        event_sched (fip, EF_DO_MPROC);
  486. X}
  487. X
  488. X/* Receiver interrupt handler. Translates input characters to character
  489. X   sequences as described in TERMIO(7) man page.
  490. X*/
  491. Xstatic uint
  492. Xfas_rproc (fip, line_status)
  493. Xregister struct fas_info    *fip;
  494. Xuint    line_status;
  495. X{
  496. X    struct tty    *ttyp;
  497. X    uint    charac;
  498. X    register uint    csize;
  499. X    unchar    metta [4];
  500. X    REGVAR;
  501. X
  502. X    ttyp = fip->tty;
  503. X
  504. X    fas_first_ctl (fip, RCV_DATA_PORT);
  505. X
  506. X    /* Translate characters from FIFO according to the TERMIO(7)
  507. X       man page.
  508. X    */
  509. X    do
  510. X    {
  511. X        charac = (line_status & LS_RCV_AVAIL)
  512. X                ? fas_inb (fip, RCV_DATA_PORT)
  513. X                : 0;    /* was line status int only */
  514. X
  515. X        /* do we have to junk the character ? */
  516. X        if (!(fip->cflag & CREAD)
  517. X            || ((ttyp->t_state & (ISOPEN | CARR_ON)) !=
  518. X                        (ISOPEN | CARR_ON)))
  519. X        {
  520. X            /* if there are FIFOs we take a short cut */
  521. X            if (fip->device_flags.i & DF_DEVICE_IS_NS16550A)
  522. X                fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_SETUP_CMD
  523. X                            | NS_FIFO_CLR_RECV);
  524. X            else if (fip->device_flags.i & DF_DEVICE_IS_I82510)
  525. X            {
  526. X                fas_outb (fip, I_BANK_PORT, I_BANK_1);
  527. X                fas_outb (fip, I_RCM_PORT, I_FIFO_CLR_RECV);
  528. X                fas_outb (fip, I_BANK_PORT, I_BANK_0);
  529. X            }
  530. X            continue;
  531. X        }
  532. X
  533. X        csize = 0;
  534. X
  535. X        /* strip off 8th bit ? */
  536. X        if (fip->iflag & ISTRIP)
  537. X            charac &= 0x7f;
  538. X
  539. X        /* ignore parity errors ? */
  540. X        if ((line_status & LS_PARITY_ERROR)
  541. X            && !(fip->iflag & INPCK))
  542. X            line_status &= ~LS_PARITY_ERROR;
  543. X
  544. X        /* do we have some kind of character error ? */
  545. X        if (line_status & (LS_PARITY_ERROR
  546. X                    | LS_FRAMING_ERROR
  547. X                    | LS_BREAK_DETECTED))
  548. X        {
  549. X#if defined (HAVE_VPIX)
  550. X            if ((fip->iflag & (DOSMODE | PARMRK))
  551. X                    == (DOSMODE | PARMRK))
  552. X            {
  553. X                /* send status bits to VP/ix */
  554. X                (void) fas_vpix_sr (fip, 1,
  555. X                    (line_status & (LS_PARITY_ERROR
  556. X                            | LS_FRAMING_ERROR
  557. X                            | LS_BREAK_DETECTED))
  558. X                        | LS_RCV_AVAIL
  559. X                        | LS_XMIT_AVAIL
  560. X                        | LS_XMIT_COMPLETE);
  561. X                goto valid_char;
  562. X            }
  563. X#endif
  564. X            /* is it a BREAK ? */
  565. X            if (line_status & LS_BREAK_DETECTED)
  566. X            {
  567. X                if (!(fip->iflag & IGNBRK))
  568. X                    if (fip->iflag & BRKINT)
  569. X                    {
  570. X                        /* do BREAK interrupt */
  571. X                        event_sched (fip, EF_DO_BRKINT);
  572. X                    }
  573. X                    else
  574. X                    {
  575. X                        metta [csize] = 0;
  576. X                        csize++;
  577. X                        if (fip->iflag & PARMRK)
  578. X                        {
  579. X                            metta [csize] = 0;
  580. X                            csize++;
  581. X                            metta [csize] = 0xff;
  582. X                            csize++;
  583. X                        }
  584. X                    }
  585. X            }
  586. X            else if (!(fip->iflag & IGNPAR))
  587. X                if (fip->iflag & PARMRK)
  588. X                {
  589. X                    metta [csize] = charac;
  590. X                    csize++;
  591. X                    metta [csize] = 0;
  592. X                    csize++;
  593. X                    metta [csize] = 0xff;
  594. X                    csize++;
  595. X                }
  596. X                else
  597. X                {
  598. X                    metta [csize] = 0;
  599. X                    csize++;
  600. X                }
  601. X        }
  602. X        else
  603. X        /* is there a character to process ? */
  604. X        if (line_status & LS_RCV_AVAIL)
  605. X        {
  606. X            if (fip->iflag & IXON)
  607. X            {
  608. X                /* do output start/stop handling */
  609. X                if (fip->flow_flags.i & FF_SWO_STOPPED)
  610. X                {
  611. X#if defined (HAVE_VPIX)
  612. X                    if ((charac == fip->v86_ss.ss_start)
  613. X#else
  614. X                    if ((charac == CSTART)
  615. X#endif
  616. X                        || (fip->iflag & IXANY))
  617. X                    {
  618. X                        fip->flow_flags.s &=
  619. X                            ~FF_SWO_STOPPED;
  620. X                        ttyp->t_state &= ~TTSTOP;
  621. X                        /* restart output */
  622. X                        fas_xproc (fip);
  623. X                    }
  624. X                }
  625. X                else
  626. X                {
  627. X#if defined (HAVE_VPIX)
  628. X                    if (charac == fip->v86_ss.ss_stop)
  629. X#else
  630. X                    if (charac == CSTOP)
  631. X#endif
  632. X                    {
  633. X                        fip->flow_flags.s |=
  634. X                            FF_SWO_STOPPED;
  635. X                        ttyp->t_state |= TTSTOP;
  636. X                    }
  637. X                }
  638. X                /* we don't put start/stop characters
  639. X                   into the receiver buffer
  640. X                */
  641. X#if defined (HAVE_VPIX)
  642. X                if ((charac == fip->v86_ss.ss_start)
  643. X                    || (charac == fip->v86_ss.ss_stop))
  644. X#else
  645. X                if ((charac == CSTART)
  646. X                    || (charac == CSTOP))
  647. X#endif
  648. X                    continue;
  649. X            }
  650. Xvalid_char:
  651. X            if ((charac == 0xff) && (fip->iflag & PARMRK))
  652. X            {
  653. X                metta [csize] = 0xff;
  654. X                csize++;
  655. X                metta [csize] = 0xff;
  656. X                csize++;
  657. X            }
  658. X            else
  659. X            {
  660. X                /* we take a short-cut if only one character
  661. X                   has to be put into the receiver buffer
  662. X                */
  663. X                if (fip->recv_ring_cnt < RECV_BUFF_SIZE)
  664. X                {
  665. X                    fip->recv_ring_cnt++;
  666. X                    *fip->recv_ring_put_ptr = charac;
  667. X                    if (++fip->recv_ring_put_ptr
  668. X                        != &fip->recv_buffer
  669. X                            [RECV_BUFF_SIZE])
  670. X                        continue;
  671. X                    fip->recv_ring_put_ptr =
  672. X                            &fip->recv_buffer [0];
  673. X                }
  674. X                continue;
  675. X            }
  676. X        }
  677. X
  678. X        if (!(csize) || (fip->recv_ring_cnt + csize > RECV_BUFF_SIZE))
  679. X            continue;    /* nothing to put into recv buffer */
  680. X
  681. X        fip->recv_ring_cnt += csize;
  682. X
  683. X        /* store translation in ring buffer */
  684. X        do
  685. X        {
  686. X            do
  687. X            {
  688. X                *fip->recv_ring_put_ptr = (metta - 1) [csize];
  689. X                if (++fip->recv_ring_put_ptr
  690. X                    == &fip->recv_buffer [RECV_BUFF_SIZE])
  691. X                    break;
  692. X            } while (--csize);
  693. X            if (!csize)
  694. X                break;
  695. X            fip->recv_ring_put_ptr = &fip->recv_buffer [0];
  696. X        } while (--csize);
  697. X    } while ((line_status = fas_inb (fip, LINE_STATUS_PORT)) & LS_RCV_INT);
  698. X
  699. X    return (line_status);
  700. X}
  701. X
  702. X/* Output characters to the transmitter register. */
  703. Xstatic void
  704. Xfas_xproc (fip)
  705. Xregister struct fas_info    *fip;
  706. X{
  707. X    register uint    num_to_output;
  708. X    REGVAR;
  709. X
  710. X    /* proceed only if transmitter is available */
  711. X    if ((fip->device_flags.i & (DF_XMIT_BUSY | DF_XMIT_BREAK
  712. X                        | DF_XMIT_LOCKED))
  713. X        || (fip->flow_flags.i & FF_HWO_STOPPED))
  714. X        goto sched;
  715. X
  716. X    num_to_output = fip->xmit_fifo_size;
  717. X
  718. X    /* handle XON/XOFF input flow control requests */
  719. X    if (fip->flow_flags.i & FF_SW_FC_REQ)
  720. X    {
  721. X#if defined (HAVE_VPIX)
  722. X        fas_first_outb (fip, XMT_DATA_PORT, (fip->flow_flags.i & FF_SWI_STOPPED)
  723. X                    ? fip->v86_ss.ss_stop
  724. X                    : fip->v86_ss.ss_start);
  725. X#else
  726. X        fas_first_outb (fip, XMT_DATA_PORT, (fip->flow_flags.i & FF_SWI_STOPPED)
  727. X                    ? CSTOP
  728. X                    : CSTART);
  729. X#endif
  730. X        fip->tty->t_state &= ~(TTXON | TTXOFF);
  731. X        fip->device_flags.s |= DF_XMIT_BUSY;
  732. X        fip->flow_flags.s &= ~FF_SW_FC_REQ;
  733. X        /* disable guard timeout */
  734. X        if (fip->device_flags.i & DF_GUARD_TIMEOUT)
  735. X        {
  736. X            fip->device_flags.s &= ~DF_GUARD_TIMEOUT;
  737. X            fip->tty->t_state &= ~TIMEOUT;
  738. X            (void) untimeout (fip->timeout_idx);
  739. X        }
  740. X        num_to_output--;
  741. X    }
  742. X
  743. X    /* bail out if output is suspended by XOFF */
  744. X    if (fip->flow_flags.i & FF_SWO_STOPPED)
  745. X        goto sched;
  746. X
  747. X    /* Determine how many chars to put into the transmitter
  748. X       register.
  749. X    */
  750. X    if (fip->xmit_ring_cnt < num_to_output)
  751. X        num_to_output = fip->xmit_ring_cnt;
  752. X
  753. X    /* no characters available ? */
  754. X    if (!num_to_output)
  755. X        goto sched;
  756. X
  757. X    /* output characters */
  758. X    fip->xmit_ring_cnt -= num_to_output;
  759. X
  760. X    fas_ctl (fip, XMT_DATA_PORT);
  761. X
  762. X    do
  763. X    {
  764. X        do
  765. X        {
  766. X            (void) outb (XMT_DATA_PORT.addr,
  767. X                    *fip->xmit_ring_take_ptr);
  768. X            if (++fip->xmit_ring_take_ptr
  769. X                    == &fip->xmit_buffer [XMIT_BUFF_SIZE])
  770. X                break;
  771. X        } while (--num_to_output);
  772. X        if (!num_to_output)
  773. X            break;
  774. X        fip->xmit_ring_take_ptr = &fip->xmit_buffer [0];
  775. X    } while (--num_to_output);
  776. X
  777. X    /* signal that transmitter is busy now */
  778. X    fip->device_flags.s |= DF_XMIT_BUSY;
  779. X    /* disable guard timeout */
  780. X    if (fip->device_flags.i & DF_GUARD_TIMEOUT)
  781. X    {
  782. X        fip->device_flags.s &= ~DF_GUARD_TIMEOUT;
  783. X        fip->tty->t_state &= ~TIMEOUT;
  784. X        (void) untimeout (fip->timeout_idx);
  785. X    }
  786. X
  787. X    /* schedule fas_xxfer () if there are more characters to transfer
  788. X       into the transmitter ring buffer
  789. X    */
  790. Xsched:
  791. X    if ((fip->xmit_ring_size > fip->xmit_ring_cnt)
  792. X        && (fip->tty->t_outq.c_cc || fip->tty->t_tbuf.c_count))
  793. X    {
  794. X        event_sched (fip, EF_DO_XXFER);
  795. X    }
  796. X}
  797. X
  798. X/* Asynchronous event handler. Scheduled by functions that can't do the
  799. X   processing themselves because of execution time restrictions.
  800. X*/
  801. Xstatic void
  802. Xfas_event (dummy)
  803. Xvoid    *dummy;
  804. X{
  805. X    register struct fas_info    *fip;
  806. X    register uint    unit;
  807. X    int    old_level;
  808. X
  809. X    old_level = SPLINT ();
  810. X
  811. X    unit = 0;
  812. X    fip = &fas_info [0];
  813. X
  814. X    /* loop through all fas_info structures */
  815. X    for (;; fip++, unit++)
  816. X    {
  817. X        if (unit >= fas_physical_units)
  818. X        break;    /* all structures done */
  819. X
  820. X        /* process only structures that actually need to
  821. X           be serviced
  822. X        */
  823. Xfastloop2:
  824. X        if (!fip->event_flags.i)
  825. X        {
  826. X        /* speed beats beauty */
  827. X        fip++;
  828. X        if (++unit < fas_physical_units)
  829. X            goto fastloop2;
  830. X        break;
  831. X        }
  832. X
  833. X        do
  834. X        {
  835. X        /* check the modem signals */
  836. X        if (fip->event_flags.i & EF_DO_MPROC)
  837. X        {
  838. X            fip->event_flags.s &= ~EF_DO_MPROC;
  839. X            fas_mproc (fip);
  840. X            /* disable the device if there were too many modem
  841. X               status interrupts
  842. X            */
  843. X            if (fip->msi_cnt > (MAX_MSI_CNT / HZ)
  844. X                        * (EVENT_TIME * HZ / 1000))
  845. X            {
  846. X                fip->device_flags.s &= ~(DF_DEVICE_CONFIGURED
  847. X                            | DF_XMIT_BUSY
  848. X                            | DF_XMIT_BREAK);
  849. X                fip->device_flags.s |= DF_XMIT_LOCKED;
  850. X                if (fip->device_flags.i & DF_GUARD_TIMEOUT)
  851. X                {
  852. X                    fip->device_flags.s &=
  853. X                            ~DF_GUARD_TIMEOUT;
  854. X                    fip->tty->t_state &= ~TIMEOUT;
  855. X                    (void) untimeout (fip->timeout_idx);
  856. X                    (void) wakeup ((caddr_t) &(fip)->
  857. X                                device_flags.i);
  858. X                }
  859. X                fip->tty->t_state &= ~CARR_ON;
  860. X                (void) SPLWRK ();
  861. X                if (!(fip->cflag & CLOCAL)
  862. X                    && (fip->tty->t_state & ISOPEN))
  863. X                    (void) signal (fip->tty->t_pgrp,
  864. X                                SIGHUP);
  865. X                (void) ttyflush (fip->tty, FREAD | FWRITE);
  866. X                (void) printf ("\nWARNING: Excessive modem status interrupts on FAS unit %d (check the cabling).\n",
  867. X                            fip - &fas_info [0]);
  868. X                (void) SPLINT ();
  869. X            }
  870. X            fip->msi_cnt = 0;
  871. X        }
  872. X
  873. X        /* do the break interrupt */
  874. X        if (fip->event_flags.i & EF_DO_BRKINT)
  875. X        {
  876. X            fip->event_flags.s &= ~EF_DO_BRKINT;
  877. X            if (fip->tty->t_state & ISOPEN)
  878. X            {
  879. X                (void) SPLWRK ();
  880. X                (*linesw [fip->tty->t_line].l_input)
  881. X                            (fip->tty, L_BREAK);
  882. X                (void) SPLINT ();
  883. X            }
  884. X        }
  885. X
  886. X        /* transfer characters to the UNIX input buffer */
  887. X        if (fip->event_flags.i & EF_DO_RXFER)
  888. X        {
  889. X            fip->event_flags.s &= ~EF_DO_RXFER;
  890. X            if (!(fip->flow_flags.i & FF_RXFER_STOPPED))
  891. X            {
  892. X                (void) SPLWRK ();
  893. X                fas_rxfer (fip);
  894. X                (void) SPLINT ();
  895. X                /* check input buffer high/low water marks */
  896. X                fas_ihlw_check (fip);
  897. X            }
  898. X        }
  899. X
  900. X        /* transfer characters to the output ring buffer */
  901. X        if (fip->event_flags.i & EF_DO_XXFER)
  902. X        {
  903. X            fip->event_flags.s &= ~EF_DO_XXFER;
  904. X            (void) SPLWRK ();
  905. X            fas_xxfer (fip);
  906. X            (void) SPLINT ();
  907. X            fas_hdx_check (fip);
  908. X            /* output characters */
  909. X            fas_xproc (fip);
  910. X        }
  911. X
  912. X#if defined (HAVE_VPIX)
  913. X        /* send pseudorupt to VP/ix */
  914. X        if (fip->event_flags.i & EF_SIGNAL_VPIX)
  915. X        {
  916. X            fip->event_flags.s &= ~EF_SIGNAL_VPIX;
  917. X            if ((fip->iflag & DOSMODE) && fip->v86_proc)
  918. X            {
  919. X                (void) SPLWRK ();
  920. X                (void) v86setint (fip->v86_proc,
  921. X                            fip->v86_intmask);
  922. X                (void) SPLINT ();
  923. X            }
  924. X        }
  925. X#endif
  926. X        } while (fip->event_flags.i);
  927. X
  928. X        /* allow pending tty interrupts */
  929. X        (void) SPLWRK ();
  930. X        (void) SPLINT ();
  931. X    }
  932. X
  933. X    event_scheduled = FALSE;
  934. X
  935. X    /* check whether there have been new requests in the mean time */
  936. X    for (unit = 0, fip = &fas_info [0]; unit < fas_physical_units;
  937. X                            fip++, unit++)
  938. X        if (fip->event_flags.i)
  939. X        {
  940. X            /* there is at least one new request, so
  941. X               schedule the next event processing
  942. X            */
  943. X            event_scheduled = TRUE;
  944. X            (void) timeout (fas_event, (void *) NULL,
  945. X                    (EVENT_TIME) * (HZ) / 1000);
  946. X            break;
  947. X        }
  948. X
  949. X    (void) splx (old_level);
  950. X}
  951. X
  952. X#if defined (HAVE_VPIX)
  953. X/* Send port status register to VP/ix */
  954. Xstatic int
  955. Xfas_vpix_sr (fip, token, status)
  956. Xregister struct fas_info    *fip;
  957. Xuint    token;
  958. Xuint    status;
  959. X{
  960. X    if ((fip->recv_ring_cnt <= RECV_BUFF_SIZE - 3)
  961. X        && ((fip->tty->t_state & (ISOPEN | CARR_ON)) ==
  962. X                        (ISOPEN | CARR_ON)))
  963. X    {
  964. X        /* sent the character sequence 0xff, <token>, <status>
  965. X           to VP/ix
  966. X        */
  967. X        fip->recv_ring_cnt += 3;
  968. X
  969. X        *fip->recv_ring_put_ptr = 0xff;
  970. X        if (++fip->recv_ring_put_ptr
  971. X                == &fip->recv_buffer [RECV_BUFF_SIZE])
  972. X            fip->recv_ring_put_ptr
  973. X                = &fip->recv_buffer [0];
  974. X        *fip->recv_ring_put_ptr = token;
  975. X        if (++fip->recv_ring_put_ptr
  976. X                == &fip->recv_buffer [RECV_BUFF_SIZE])
  977. X            fip->recv_ring_put_ptr
  978. X                = &fip->recv_buffer [0];
  979. X        *fip->recv_ring_put_ptr = status;
  980. X        if (++fip->recv_ring_put_ptr
  981. X                == &fip->recv_buffer [RECV_BUFF_SIZE])
  982. X            fip->recv_ring_put_ptr
  983. X                = &fip->recv_buffer [0];
  984. X        return (TRUE);
  985. X    }
  986. X    return (FALSE);
  987. X}
  988. X#endif
  989. X
  990. X/* Receiver ring buffer -> UNIX buffer transfer function. */
  991. Xstatic void
  992. Xfas_rxfer (fip)
  993. Xregister struct fas_info    *fip;
  994. X{
  995. X    register struct tty    *ttyp;
  996. X    register int    num_to_xfer;
  997. X    int    num_save;
  998. X    int    old_level;
  999. X
  1000. X    ttyp = fip->tty;
  1001. X
  1002. X    for (;;)
  1003. X    {
  1004. X        if (!fip->recv_ring_cnt || !ttyp->t_rbuf.c_ptr)
  1005. X            break;    /* no characters to transfer */
  1006. X
  1007. X        /* determine how many characters to transfer */
  1008. X#if defined (HAVE_VPIX)
  1009. X        num_to_xfer = ((fip->iflag & DOSMODE)
  1010. X                ? MAX_VPIX_FILL
  1011. X                : MAX_UNIX_FILL) - ttyp->t_rawq.c_cc;
  1012. X#else
  1013. X        num_to_xfer = MAX_UNIX_FILL - ttyp->t_rawq.c_cc;
  1014. X#endif
  1015. X
  1016. X        if (num_to_xfer < MIN_READ_CHUNK)
  1017. X            break;    /* input buffer full */
  1018. X
  1019. X#if defined (HAVE_VPIX)
  1020. X        /* wakeup VP/ix */
  1021. X        if ((fip->iflag & DOSMODE) && !ttyp->t_rawq.c_cc)
  1022. X            event_sched (fip, EF_SIGNAL_VPIX);
  1023. X#endif
  1024. X
  1025. X        /* determine how many characters are in one contigous block */
  1026. X        if (fip->recv_ring_cnt < num_to_xfer)
  1027. X            num_to_xfer = fip->recv_ring_cnt;
  1028. X        if (&fip->recv_buffer [RECV_BUFF_SIZE] - fip->recv_ring_take_ptr
  1029. X            < num_to_xfer)
  1030. X            num_to_xfer = &fip->recv_buffer [RECV_BUFF_SIZE]
  1031. X                    - fip->recv_ring_take_ptr;
  1032. X        if (ttyp->t_rbuf.c_count < num_to_xfer)
  1033. X            num_to_xfer = ttyp->t_rbuf.c_count;
  1034. X
  1035. X        num_save = num_to_xfer;
  1036. X        ttyp->t_rbuf.c_count -= num_to_xfer;
  1037. X
  1038. X        /* do the transfer */
  1039. X        do
  1040. X        {
  1041. X            *ttyp->t_rbuf.c_ptr = *fip->recv_ring_take_ptr;
  1042. X            ttyp->t_rbuf.c_ptr++;
  1043. X            fip->recv_ring_take_ptr++;
  1044. X        } while (--num_to_xfer);
  1045. X
  1046. X        if (fip->recv_ring_take_ptr == &fip->recv_buffer [RECV_BUFF_SIZE])
  1047. X            fip->recv_ring_take_ptr = &fip->recv_buffer [0];
  1048. X
  1049. X        intr_disable ();
  1050. X        fip->recv_ring_cnt -= num_save;
  1051. X        intr_restore ();
  1052. X
  1053. X        ttyp->t_rbuf.c_ptr -= ttyp->t_rbuf.c_size
  1054. X                    - ttyp->t_rbuf.c_count;
  1055. X        (*linesw [ttyp->t_line].l_input) (ttyp, L_BUF);
  1056. X    }
  1057. X}
  1058. X
  1059. X/* UNIX buffer -> transmitter ring buffer transfer function. */
  1060. Xstatic void
  1061. Xfas_xxfer (fip)
  1062. Xregister struct fas_info    *fip;
  1063. X{
  1064. X    register struct tty    *ttyp;
  1065. X    register int    num_to_xfer;
  1066. X    int    num_save;
  1067. X    int    old_level;
  1068. X
  1069. X    ttyp = fip->tty;
  1070. X
  1071. X    for (;;)
  1072. X    {
  1073. X        /* Check if tbuf is empty. If it is empty, reset buffer
  1074. X           pointer and counter and get the next chunk of output
  1075. X           characters.
  1076. X        */
  1077. X        if (!ttyp->t_tbuf.c_ptr || !ttyp->t_tbuf.c_count)
  1078. X        {
  1079. X            if (ttyp->t_tbuf.c_ptr)
  1080. X                ttyp->t_tbuf.c_ptr -= ttyp->t_tbuf.c_size;
  1081. X            if (!((*linesw [ttyp->t_line].l_output) (ttyp)
  1082. X                    & CPRES))
  1083. X                break;
  1084. X        }
  1085. X
  1086. X        /* set the maximum character limit */
  1087. X        num_to_xfer = fip->xmit_ring_size - fip->xmit_ring_cnt;
  1088. X
  1089. X        /* Return if transmitter ring buffer is full. */
  1090. X        if (num_to_xfer < 1)
  1091. X            break;
  1092. X
  1093. X        /* Determine how many chars to transfer this time. */
  1094. X        if (&fip->xmit_buffer [XMIT_BUFF_SIZE] - fip->xmit_ring_put_ptr
  1095. X            < num_to_xfer)
  1096. X            num_to_xfer = &fip->xmit_buffer [XMIT_BUFF_SIZE]
  1097. X                    - fip->xmit_ring_put_ptr;
  1098. X        if (ttyp->t_tbuf.c_count < num_to_xfer)
  1099. X            num_to_xfer = ttyp->t_tbuf.c_count;
  1100. X
  1101. X        num_save = num_to_xfer;
  1102. X        ttyp->t_tbuf.c_count -= num_to_xfer;
  1103. X        ttyp->t_state |= BUSY;
  1104. X
  1105. X        /* do the transfer */
  1106. X        do
  1107. X        {
  1108. X            *fip->xmit_ring_put_ptr = *ttyp->t_tbuf.c_ptr;
  1109. X            ttyp->t_tbuf.c_ptr++;
  1110. X            fip->xmit_ring_put_ptr++;
  1111. X        } while (--num_to_xfer);
  1112. X
  1113. X        if (fip->xmit_ring_put_ptr == &fip->xmit_buffer [XMIT_BUFF_SIZE])
  1114. X            fip->xmit_ring_put_ptr = &fip->xmit_buffer [0];
  1115. X
  1116. X        intr_disable ();
  1117. X        fip->xmit_ring_cnt += num_save;
  1118. X        intr_restore ();
  1119. X    }
  1120. X}
  1121. X
  1122. X/* Input buffer high/low water mark check. */
  1123. Xstatic void
  1124. Xfas_ihlw_check (fip)
  1125. Xregister struct fas_info    *fip;
  1126. X{
  1127. X    REGVAR;
  1128. X
  1129. X    if (fip->flow_flags.i & FF_HWI_STOPPED)
  1130. X    {
  1131. X        /* If input buffer level has dropped below
  1132. X           the low water mark and input was stopped
  1133. X           by hardware handshake, restart input.
  1134. X        */
  1135. X        if (fip->recv_ring_cnt < HW_LOW_WATER)
  1136. X        {
  1137. X            fip->mcr |= fip->flow.m.ic;
  1138. X            fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
  1139. X            fip->flow_flags.s &= ~FF_HWI_STOPPED;
  1140. X        }
  1141. X    }
  1142. X    else
  1143. X    {
  1144. X        /* If input buffer level has risen above the
  1145. X           high water mark and input is not yet
  1146. X           stopped, stop input by hardware handshake.
  1147. X        */
  1148. X        if ((fip->flow_flags.i & FF_HWI_HANDSHAKE)
  1149. X            && (fip->recv_ring_cnt > HW_HIGH_WATER))
  1150. X        {
  1151. X            fip->mcr &= ~fip->flow.m.ic;
  1152. X            fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
  1153. X            fip->flow_flags.s |= FF_HWI_STOPPED;
  1154. X        }
  1155. X    }
  1156. X
  1157. X    if (fip->flow_flags.i & FF_SWI_STOPPED)
  1158. X    {
  1159. X        /* If input buffer level has dropped below
  1160. X           the low water mark and input was stopped
  1161. X           by XOFF, send XON to restart input.
  1162. X        */
  1163. X        if (!(fip->iflag & IXOFF)
  1164. X            || (fip->recv_ring_cnt < SW_LOW_WATER))
  1165. X        {
  1166. X            fip->flow_flags.s &= ~FF_SWI_STOPPED;
  1167. X            fip->flow_flags.s ^= FF_SW_FC_REQ;
  1168. X            if (fip->flow_flags.i & FF_SW_FC_REQ)
  1169. X            {
  1170. X                fip->tty->t_state |= TTXON;
  1171. X                fas_xproc (fip);
  1172. X            }
  1173. X            else
  1174. X                fip->tty->t_state &= ~TTXOFF;
  1175. X        }
  1176. X    }
  1177. X    else
  1178. X    {
  1179. X        /* If input buffer level has risen above the
  1180. X           high water mark and input is not yet
  1181. X           stopped, send XOFF to stop input.
  1182. X        */
  1183. X        if ((fip->iflag & IXOFF)
  1184. X            && (fip->recv_ring_cnt > SW_HIGH_WATER))
  1185. X        {
  1186. X            fip->flow_flags.s |= FF_SWI_STOPPED;
  1187. X            fip->flow_flags.s ^= FF_SW_FC_REQ;
  1188. X            if (fip->flow_flags.i & FF_SW_FC_REQ)
  1189. X            {
  1190. X                fip->tty->t_state |= TTXOFF;
  1191. X                fas_xproc (fip);
  1192. X            }
  1193. X            else
  1194. X                fip->tty->t_state &= ~TTXON;
  1195. X        }
  1196. X    }
  1197. X}
  1198. X
  1199. X/* Half-duplex hardware flow control check. */
  1200. Xstatic void
  1201. Xfas_hdx_check (fip)
  1202. Xregister struct fas_info    *fip;
  1203. X{
  1204. X    REGVAR;
  1205. X
  1206. X    /* don't interfere with hardware input handshake */
  1207. X    if (fip->flow_flags.i & FF_HWI_HANDSHAKE)
  1208. X        return;
  1209. X
  1210. X#if defined (HAVE_VPIX)
  1211. X    /* don't touch the mcr if we are in dos mode and hdx hardware
  1212. X       handshake is disabled (dos handles the handshake line(s)
  1213. X       on its own in this mode)
  1214. X    */
  1215. X    if ((fip->iflag & DOSMODE) && !(fip->flow_flags.i & FF_HDX_HANDSHAKE))
  1216. X        return;
  1217. X#endif
  1218. X    if (fip->flow_flags.i & FF_HDX_STARTED)
  1219. X    {
  1220. X        /* If output buffer is empty signal the connected
  1221. X           device that all output is done.
  1222. X        */
  1223. X        if ((fip->flow_flags.i & FF_HDX_HANDSHAKE)
  1224. X            && !(fip->tty->t_state & BUSY))
  1225. X        {
  1226. X            fip->mcr &= ~fip->flow.m.hc;
  1227. X            fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
  1228. X            fip->flow_flags.s &= ~FF_HDX_STARTED;
  1229. X        }
  1230. X    }
  1231. X    else
  1232. X    {
  1233. X        /* If the output ring buffer contains characters
  1234. X           and was previously empty signal the connected
  1235. X           device that output is resumed.
  1236. X        */
  1237. X        if (!(fip->flow_flags.i & FF_HDX_HANDSHAKE)
  1238. X            || (fip->tty->t_state & BUSY))
  1239. X        {
  1240. X            fip->mcr |= fip->flow.m.hc;
  1241. X            fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
  1242. X            fip->flow_flags.s |= FF_HDX_STARTED;
  1243. X        }
  1244. X    }
  1245. X}
  1246. X
  1247. X/* Handle hangup after last close */
  1248. Xstatic void
  1249. Xfas_hangup (fip)
  1250. Xregister struct fas_info    *fip;
  1251. X{
  1252. X    int    old_level;
  1253. X    REGVAR;
  1254. X
  1255. X    old_level = SPLINT ();
  1256. X
  1257. X    if (fip->device_flags.i & DF_DO_HANGUP)
  1258. X    {
  1259. X        /* do the hangup */
  1260. X        fip->mcr &= ~(fip->modem.m.ei
  1261. X                | fip->modem.m.eo);
  1262. X        fip->mcr |= fip->modem.m.di;
  1263. X        fas_first_outb (fip, MDM_CTL_PORT, fip->mcr);
  1264. X        fip->device_flags.s &= ~(DF_MODEM_ENABLED | DF_DO_HANGUP);
  1265. X        (void) timeout (fas_hangup, fip, (fip->device_flags.i
  1266. X                            & DF_DEVICE_CONFIGURED)
  1267. X                        ? (HANGUP_TIME) * (HZ) / 1000
  1268. X                        : (RECOVER_TIME) * (HZ));
  1269. X    }
  1270. X    else
  1271. X    {
  1272. X        /* unlock the device */
  1273. X        fip->device_flags.s |= DF_DEVICE_CONFIGURED;
  1274. X        /* If there was a waiting getty open on this
  1275. X           port, reopen the physical device.
  1276. X        */
  1277. X        if (fip->o_state & OS_WAIT_OPEN)
  1278. X        {
  1279. X            fas_open_device (fip);
  1280. X            fas_param (fip, HARD_INIT);    /* set up port regs */
  1281. X        }
  1282. X        release_device_lock (fip);
  1283. X    }
  1284. X    (void) splx (old_level);
  1285. X}
  1286. X
  1287. X/* main timeout function */
  1288. Xstatic void
  1289. Xfas_timeout (fip)
  1290. Xregister struct fas_info    *fip;
  1291. X{
  1292. X    int    old_level;
  1293. X    REGVAR;
  1294. X
  1295. X    old_level = SPLINT ();
  1296. X
  1297. X    /* handle break request */
  1298. X    if (fip->device_flags.i & DF_DO_BREAK)
  1299. X    {
  1300. X        /* set up break request flags */
  1301. X        fip->lcr |= LC_SET_BREAK_LEVEL;
  1302. X        fas_first_outb (fip, LINE_CTL_PORT, fip->lcr);
  1303. X        fip->device_flags.s &= ~(DF_DO_BREAK | DF_GUARD_TIMEOUT);
  1304. X        (void) timeout (fas_timeout, fip, (BREAK_TIME) * (HZ) / 1000);
  1305. X        (void) splx (old_level);
  1306. X        return;
  1307. X    }
  1308. X
  1309. X    /* reset break state */
  1310. X    if (fip->device_flags.i & DF_XMIT_BREAK)
  1311. X    {
  1312. X        if (fip->lcr & LC_SET_BREAK_LEVEL)
  1313. X        {
  1314. X            fip->lcr &= ~LC_SET_BREAK_LEVEL;
  1315. X            fas_first_outb (fip, LINE_CTL_PORT, fip->lcr);
  1316. X            fip->device_flags.s |= DF_GUARD_TIMEOUT;
  1317. X            fip->timeout_idx = timeout (fas_timeout, fip,
  1318. X                    fas_ctimes [fip->cflag & CBAUD]);
  1319. X            (void) splx (old_level);
  1320. X            return;
  1321. X        }
  1322. X        fip->device_flags.s &= ~DF_XMIT_BREAK;
  1323. X        /* restart output after BREAK */
  1324. X        fas_xproc (fip);
  1325. X    }
  1326. X
  1327. X    /* handle character guard timeout */
  1328. X    if (fip->device_flags.i & DF_GUARD_TIMEOUT)
  1329. X    {
  1330. X        fip->device_flags.s &= ~DF_GUARD_TIMEOUT;
  1331. X        if (!fip->xmit_ring_cnt)
  1332. X        {
  1333. X            fip->tty->t_state &= ~BUSY;
  1334. X            fas_hdx_check (fip);
  1335. X        }
  1336. X    }
  1337. X
  1338. X    fip->tty->t_state &= ~TIMEOUT;
  1339. X
  1340. X    event_sched (fip, EF_DO_XXFER);
  1341. X
  1342. X    (void) wakeup ((caddr_t) &(fip)->device_flags.i);
  1343. X    (void) splx (old_level);
  1344. X}
  1345. X
  1346. X/* Several functions for flow control, character output and special event
  1347. X   requests and handling.
  1348. X*/
  1349. Xstatic void
  1350. Xfas_cmd (fip, ttyp, arg2)
  1351. Xregister struct fas_info    *fip;
  1352. Xregister struct tty    *ttyp;
  1353. Xint    arg2;
  1354. X{
  1355. X    REGVAR;
  1356. X
  1357. X    switch (arg2)
  1358. X    {
  1359. X    case T_TIME:    /* timeout */
  1360. X        goto start_output;
  1361. X
  1362. X    case T_OUTPUT:    /* output characters to the transmitter */
  1363. X        if (fip->xmit_ring_size > fip->xmit_ring_cnt)
  1364. X        {
  1365. Xstart_output:
  1366. X            event_sched (fip, EF_DO_XXFER);
  1367. X        }
  1368. X        break;
  1369. X
  1370. X    case T_SUSPEND:    /* suspend character output */
  1371. X        fip->flow_flags.s |= FF_SWO_STOPPED;
  1372. X        ttyp->t_state |= TTSTOP;
  1373. X        break;
  1374. X
  1375. X    case T_RESUME:    /* restart character output */
  1376. X        fip->flow_flags.s &= ~FF_SWO_STOPPED;
  1377. X        ttyp->t_state &= ~TTSTOP;
  1378. X        fas_xproc (fip);
  1379. X        break;
  1380. X
  1381. X    case T_BLOCK:    /* stop character input, request XOFF */
  1382. X        ttyp->t_state |= TBLOCK;
  1383. X        break;    /* note: we do our own XON/XOFF */
  1384. X
  1385. X    case T_UNBLOCK:    /* restart character input, request XON */
  1386. X        ttyp->t_state &= ~TBLOCK;
  1387. X        break;    /* note: we do our own XON/XOFF */
  1388. X
  1389. X    case T_RFLUSH:    /* flush input buffers and restart input */
  1390. X        if (fip->device_flags.i & DF_DEVICE_IS_NS16550A)
  1391. X            fas_first_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_SETUP_CMD
  1392. X                        | NS_FIFO_CLR_RECV);
  1393. X        else if (fip->device_flags.i & DF_DEVICE_IS_I82510)
  1394. X        {
  1395. X            fas_first_outb (fip, I_BANK_PORT, I_BANK_1);
  1396. X            fas_outb (fip, I_RCM_PORT, I_FIFO_CLR_RECV);
  1397. X            fas_outb (fip, I_BANK_PORT, I_BANK_0);
  1398. X        }
  1399. X
  1400. X        fip->recv_ring_take_ptr = fip->recv_ring_put_ptr;
  1401. X        fip->recv_ring_cnt = 0;
  1402. X        ttyp->t_state &= ~TBLOCK;
  1403. X
  1404. X        fas_ihlw_check (fip);
  1405. X        break;
  1406. X
  1407. X    case T_WFLUSH:    /* flush output buffer and restart output */
  1408. X        if (fip->device_flags.i & DF_DEVICE_IS_NS16550A)
  1409. X            fas_first_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_SETUP_CMD
  1410. X                        | NS_FIFO_CLR_XMIT);
  1411. X        else if (fip->device_flags.i & DF_DEVICE_IS_I82510)
  1412. X        {
  1413. X            fas_first_outb (fip, I_BANK_PORT, I_BANK_1);
  1414. X            fas_outb (fip, I_TCM_PORT, I_FIFO_CLR_XMIT);
  1415. X            fas_outb (fip, I_BANK_PORT, I_BANK_0);
  1416. X        }
  1417. X
  1418. X        fip->xmit_ring_take_ptr = fip->xmit_ring_put_ptr;
  1419. X        fip->xmit_ring_cnt = 0;
  1420. X
  1421. X        fip->flow_flags.s &= ~FF_SWO_STOPPED;
  1422. X        ttyp->t_state &= ~TTSTOP;
  1423. X
  1424. X        if (ttyp->t_tbuf.c_ptr)
  1425. X            ttyp->t_tbuf.c_ptr += ttyp->t_tbuf.c_count;
  1426. X        ttyp->t_tbuf.c_count = 0;
  1427. X
  1428. X        if (!(fip->device_flags.i & (DF_XMIT_BUSY | DF_GUARD_TIMEOUT)))
  1429. X        {
  1430. X            ttyp->t_state &= ~BUSY;
  1431. X            fas_hdx_check (fip);
  1432. X            goto start_output;
  1433. X        }
  1434. X        break;
  1435. X
  1436. X    case T_BREAK:    /* do a break on the transmitter line */
  1437. X        fip->device_flags.s |= DF_XMIT_BREAK;
  1438. X        ttyp->t_state |= TIMEOUT;
  1439. X        if (fip->device_flags.i & (DF_XMIT_BUSY | DF_GUARD_TIMEOUT))
  1440. X        {
  1441. X            fip->device_flags.s |= DF_DO_BREAK;
  1442. X        }
  1443. X        else
  1444. X        {
  1445. X            /* set up break request flags */
  1446. X            fip->lcr |= LC_SET_BREAK_LEVEL;
  1447. X            fas_first_outb (fip, LINE_CTL_PORT, fip->lcr);
  1448. X            (void) timeout (fas_timeout, fip, (BREAK_TIME) * (HZ)
  1449. X                                / 1000);
  1450. X        }
  1451. X        break;
  1452. X
  1453. X    case T_PARM:    /* set up the port according to the termio structure */
  1454. X        fas_param (fip, SOFT_INIT);
  1455. X        break;
  1456. X
  1457. X    case T_SWTCH:    /* handle layer switch request */
  1458. X        break;
  1459. X    }
  1460. X}
  1461. X
  1462. X/* open device physically */
  1463. Xstatic void
  1464. Xfas_open_device (fip)
  1465. Xregister struct fas_info    *fip;
  1466. X{
  1467. X    REGVAR;
  1468. X
  1469. X    /* if already open, set up the mcr register only */
  1470. X    if (fip->device_flags.i & DF_DEVICE_OPEN)
  1471. X        goto setmcr;
  1472. X
  1473. X    /* init some variables */
  1474. X    fip->device_flags.s &= DF_DEVICE_CONFIGURED | DF_DEVICE_IS_NS16550A
  1475. X                | DF_DEVICE_IS_I82510 | DF_DEVICE_LOCKED
  1476. X                | DF_CTL_FIRST | DF_CTL_EVERY;
  1477. X    fip->flow_flags.s = 0;
  1478. X    fip->cflag = 0;
  1479. X    fip->iflag = 0;
  1480. X    fip->recv_ring_take_ptr = fip->recv_ring_put_ptr;
  1481. X    fip->recv_ring_cnt = 0;
  1482. X    fip->xmit_ring_take_ptr = fip->xmit_ring_put_ptr;
  1483. X    fip->xmit_ring_cnt = 0;
  1484. X
  1485. X    /* hook into the interrupt users chain */
  1486. X    fip->next_int_user = fas_first_int_user [fip->vec];
  1487. X    if (fip->next_int_user)
  1488. X        fip->next_int_user->prev_int_user = fip;
  1489. X    fas_first_int_user [fip->vec] = fip;
  1490. X    fip->prev_int_user = (struct fas_info *) NULL;
  1491. X
  1492. X    fip->lcr = 0;
  1493. X    fas_first_outb (fip, LINE_CTL_PORT, fip->lcr);
  1494. X
  1495. X    /* clear and disable FIFOs */
  1496. X    if (fip->device_flags.i & DF_DEVICE_IS_NS16550A)
  1497. X        fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);
  1498. X    else if (fip->device_flags.i & DF_DEVICE_IS_I82510)
  1499. X    {
  1500. X        fas_outb (fip, I_BANK_PORT, I_BANK_1);
  1501. X        fas_outb (fip, I_TCM_PORT, I_FIFO_CLR_XMIT);
  1502. X        fas_outb (fip, I_RCM_PORT, I_FIFO_CLR_RECV);
  1503. X        fas_outb (fip, I_BANK_PORT, I_BANK_2);
  1504. X        fas_outb (fip, I_IDM_PORT, I_FIFO_CLEAR_CMD);
  1505. X        fas_outb (fip, I_BANK_PORT, I_BANK_0);
  1506. X    }
  1507. X
  1508. X    /* clear interrupts */
  1509. X    (void) fas_inb (fip, MDM_STATUS_PORT);
  1510. X    (void) fas_inb (fip, RCV_DATA_PORT);
  1511. X    (void) fas_inb (fip, RCV_DATA_PORT);
  1512. X    (void) fas_inb (fip, LINE_STATUS_PORT);
  1513. X    (void) fas_inb (fip, INT_ID_PORT);
  1514. X
  1515. X    /* enable FIFOs */
  1516. X    if (fip->device_flags.i & DF_DEVICE_IS_NS16550A)
  1517. X        fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_SETUP_CMD);
  1518. X    else if (fip->device_flags.i & DF_DEVICE_IS_I82510)
  1519. X    {
  1520. X        fas_outb (fip, I_BANK_PORT, I_BANK_2);
  1521. X        fas_outb (fip, I_IDM_PORT, I_FIFO_SETUP_CMD);
  1522. X        fas_outb (fip, I_BANK_PORT, I_BANK_0);
  1523. X    }
  1524. X
  1525. X    fip->msi_cnt = 0;
  1526. X    fip->msr = fip->new_msr = fas_inb (fip, MDM_STATUS_PORT)
  1527. X                    & (MS_CTS_PRESENT
  1528. X                        | MS_DSR_PRESENT
  1529. X                        | MS_DCD_PRESENT);
  1530. X
  1531. X    fip->ier = IE_INIT_MODE;    /* enable UART interrupts */
  1532. X    fas_outb (fip, INT_ENABLE_PORT, fip->ier);
  1533. X
  1534. Xsetmcr:
  1535. X    /* set up modem and flow control lines */
  1536. X    fip->mcr &= ~(fip->modem.m.di
  1537. X            | fip->modem.m.ei
  1538. X            | fip->modem.m.eo
  1539. X            | fip->flow.m.ic
  1540. X            | fip->flow.m.hc);
  1541. X
  1542. X    fip->mcr |= (fip->o_state & OS_WAIT_OPEN)
  1543. X            ? fip->modem.m.ei
  1544. X            : fip->modem.m.eo;
  1545. X
  1546. X    if (fip->o_state & OS_HWI_HANDSHAKE)
  1547. X        fip->mcr |= fip->flow.m.ic;
  1548. X    else if (!(fip->o_state & OS_HDX_HANDSHAKE))
  1549. X    {
  1550. X        fip->flow_flags.s |= FF_HDX_STARTED;
  1551. X        fip->mcr |= fip->flow.m.hc;
  1552. X    }
  1553. X
  1554. X    fas_outb (fip, MDM_CTL_PORT, fip->mcr);
  1555. X
  1556. X    fip->device_flags.s |= DF_DEVICE_OPEN | DF_MODEM_ENABLED;
  1557. X}
  1558. X
  1559. X/* close device physically */
  1560. Xstatic void
  1561. Xfas_close_device (fip)
  1562. Xregister struct fas_info    *fip;
  1563. X{
  1564. X    REGVAR;
  1565. X
  1566. X    fip->device_flags.s &= ~DF_DEVICE_OPEN;
  1567. X
  1568. X    fip->ier = IE_NONE;    /* disable UART interrupts */
  1569. X    fas_first_outb (fip, INT_ENABLE_PORT, fip->ier);
  1570. X
  1571. X    /* drop flow control lines */
  1572. X    fip->mcr &= (fip->o_state & OS_HWI_HANDSHAKE)
  1573. X        ? ~fip->flow.m.ic
  1574. X        : ~fip->flow.m.hc;
  1575. X    fas_outb (fip, MDM_CTL_PORT, fip->mcr);
  1576. X
  1577. X    /* clear and disable FIFOs */
  1578. X    if (fip->device_flags.i & DF_DEVICE_IS_NS16550A)
  1579. X        fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);
  1580. X    else if (fip->device_flags.i & DF_DEVICE_IS_I82510)
  1581. X    {
  1582. X        fas_outb (fip, I_BANK_PORT, I_BANK_1);
  1583. X        fas_outb (fip, I_TCM_PORT, I_FIFO_CLR_XMIT);
  1584. X        fas_outb (fip, I_RCM_PORT, I_FIFO_CLR_RECV);
  1585. X        fas_outb (fip, I_BANK_PORT, I_BANK_2);
  1586. X        fas_outb (fip, I_IDM_PORT, I_FIFO_CLEAR_CMD);
  1587. X        fas_outb (fip, I_BANK_PORT, I_BANK_0);
  1588. X    }
  1589. X
  1590. X    /* reset break level */
  1591. X    fip->lcr &= ~LC_SET_BREAK_LEVEL;
  1592. X    fas_outb (fip, LINE_CTL_PORT, fip->lcr);
  1593. X
  1594. X    /* unhook from interrupt users chain */
  1595. X    if (fip->prev_int_user)
  1596. X        fip->prev_int_user->next_int_user = fip->next_int_user;
  1597. X    else
  1598. X        fas_first_int_user [fip->vec] = fip->next_int_user;
  1599. X    if (fip->next_int_user)
  1600. X        fip->next_int_user->prev_int_user = fip->prev_int_user;
  1601. X
  1602. X    if ((fip->cflag & HUPCL)
  1603. X        || !(fip->device_flags.i & DF_DEVICE_CONFIGURED))
  1604. X    {
  1605. X        /* request hangup */
  1606. X        fip->device_flags.s |= DF_DO_HANGUP;
  1607. X        (void) timeout (fas_hangup, fip, (HANGUP_DELAY) * (HZ) / 1000);
  1608. X    }
  1609. X}
  1610. X
  1611. X/* compute the port access control value */
  1612. Xstatic uint
  1613. Xfas_make_ctl_val (fip, unit, num)
  1614. Xregister struct fas_info    *fip;
  1615. Xuint    unit;
  1616. Xuint    num;
  1617. X{
  1618. X    register uint    mask, val;
  1619. X    uint    i;
  1620. X
  1621. X    if (fip->device_flags.i & DF_CTL_FIRST)
  1622. X        return (fas_ctl_val [unit]);
  1623. X
  1624. X    if (fip->device_flags.i & DF_CTL_EVERY)
  1625. X    {
  1626. X        for (i = 0, mask = fas_ctl_val [unit],
  1627. X                val = fas_ctl_val [unit] << 8; i < 8; i++)
  1628. X        {
  1629. X            if (mask & 0x100)
  1630. X            {
  1631. X                if (num & 0x01)
  1632. X                    val ^= 0x100;
  1633. X                num >>= 1;
  1634. X            }
  1635. X            mask >>= 1;
  1636. X            val >>= 1;
  1637. X        }
  1638. X        return (val);
  1639. X    }
  1640. X    return (0);
  1641. X}
  1642. X
  1643. X/* test device thoroughly */
  1644. Xstatic int
  1645. Xfas_test_device (fip)
  1646. Xregister struct fas_info    *fip;
  1647. X{
  1648. X    register unchar    *cptr;
  1649. X    int    done;
  1650. X    uint    delay_count, i;
  1651. X    static uint    lcrval [3] =
  1652. X    {
  1653. X        LC_WORDLEN_8,
  1654. X        LC_WORDLEN_8 | LC_ENABLE_PARITY,
  1655. X        LC_WORDLEN_8 | LC_ENABLE_PARITY | LC_EVEN_PARITY
  1656. X    };
  1657. X    REGVAR;
  1658. X
  1659. X    /* make sure FIFO is off */
  1660. X    fas_first_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);
  1661. X    fas_outb (fip, I_BANK_PORT, I_BANK_2);
  1662. X    fas_outb (fip, I_IDM_PORT, I_FIFO_CLEAR_CMD);
  1663. X    fas_outb (fip, I_BANK_PORT, I_BANK_0);
  1664. X
  1665. X    /* set counter divisor */
  1666. X    fas_outb (fip, LINE_CTL_PORT, LC_ENABLE_DIVISOR);
  1667. X    fas_outb (fip, DIVISOR_LSB_PORT, fas_speeds [B38400]);
  1668. X    fas_outb (fip, DIVISOR_MSB_PORT, fas_speeds [B38400] >> 8);
  1669. X    fas_outb (fip, LINE_CTL_PORT, 0);
  1670. X
  1671. X    /* switch to local loopback */
  1672. X    fas_outb (fip, MDM_CTL_PORT, MC_SET_LOOPBACK);
  1673. X
  1674. X    done = 0;
  1675. X
  1676. X    /* wait until the transmitter register is empty */
  1677. X    for (delay_count = 20000;
  1678. X        delay_count && (~fas_inb (fip, LINE_STATUS_PORT)
  1679. X                & (LS_XMIT_AVAIL | LS_XMIT_COMPLETE));
  1680. X        delay_count--)
  1681. X        ;
  1682. X
  1683. X    if (!delay_count)
  1684. X        done = 1;
  1685. X
  1686. X    if (!done)
  1687. X    {
  1688. X        /* clear flags */
  1689. X        (void) fas_inb (fip, RCV_DATA_PORT);
  1690. X        (void) fas_inb (fip, RCV_DATA_PORT);
  1691. X        (void) fas_inb (fip, LINE_STATUS_PORT);
  1692. X
  1693. X        /* make sure there are no more characters in the
  1694. X           receiver register
  1695. X        */
  1696. X        for (delay_count = 20000;
  1697. X            delay_count && !(fas_inb (fip, LINE_STATUS_PORT) & LS_RCV_AVAIL);
  1698. X            delay_count--)
  1699. X            ;
  1700. X
  1701. X        if (delay_count)
  1702. X            (void) fas_inb (fip, RCV_DATA_PORT);
  1703. X
  1704. X        /* test pattern */
  1705. X        cptr = (unchar *) "\
  1706. X\377\125\252\045\244\0\
  1707. X\377\125\252\045\244\0\
  1708. X\377\125\252\045\244\0\
  1709. X\377\125\252\045\244\0\
  1710. X\377\125\252\045\244\0\0";
  1711. X
  1712. X        do
  1713. X        {
  1714. X            for (i = 0; i < 3; i++)
  1715. X            {
  1716. X                /* test transmitter and receiver
  1717. X                   with different line settings
  1718. X                */
  1719. X                fas_outb (fip, LINE_CTL_PORT, lcrval [i]);
  1720. X
  1721. X                /* wait until the transmitter register
  1722. X                   is empty
  1723. X                */
  1724. X                for (delay_count = 20000;
  1725. X                    delay_count && (~fas_inb (fip, LINE_STATUS_PORT)
  1726. X                            & (LS_XMIT_AVAIL
  1727. X                              | LS_XMIT_COMPLETE));
  1728. X                    delay_count--)
  1729. X                    ;
  1730. X
  1731. X                if (!delay_count)
  1732. X                {
  1733. X                    done = 2;
  1734. X                    break;
  1735. X                }
  1736. X
  1737. X                /* send test pattern */
  1738. X                fas_outb (fip, XMT_DATA_PORT, *cptr);
  1739. X
  1740. X                /* wait until the test pattern is received */
  1741. X                for (delay_count = 20000;
  1742. X                    delay_count && ((fas_inb (fip, LINE_STATUS_PORT)
  1743. X                                & LS_RCV_INT)
  1744. X                            != LS_RCV_AVAIL);
  1745. X                    delay_count--)
  1746. X                    ;
  1747. X
  1748. X                if (!delay_count)
  1749. X                {
  1750. X                    done = 3;
  1751. X                    break;
  1752. X                }
  1753. X
  1754. X                /* check test pattern */
  1755. X                if (fas_inb (fip, RCV_DATA_PORT) != *cptr)
  1756. X                {
  1757. X                    done = 4;
  1758. X                    break;
  1759. X                }
  1760. X            }
  1761. X
  1762. X            if (done)
  1763. X                break;
  1764. X        } while (*((ushort *) cptr++));
  1765. X    }
  1766. X
  1767. X    if (!done)
  1768. X    {
  1769. X        /* wait until the transmitter register is empty */
  1770. X        for (delay_count = 20000;
  1771. X            delay_count && (~fas_inb (fip, LINE_STATUS_PORT)
  1772. X                    & (LS_XMIT_AVAIL | LS_XMIT_COMPLETE));
  1773. X            delay_count--)
  1774. X            ;
  1775. X
  1776. X        if (!delay_count)
  1777. X            done = 5;
  1778. X    }
  1779. X
  1780. X    if (!done)
  1781. X    {
  1782. X        /* test pattern */
  1783. X        cptr = (unchar *) "\
  1784. X\005\142\012\237\006\130\011\257\017\361\0\017\
  1785. X\005\142\012\237\006\130\011\257\017\361\0\017\
  1786. X\005\142\012\237\006\130\011\257\017\361\0\017\
  1787. X\005\142\012\237\006\130\011\257\017\361\0\017\
  1788. X\005\142\012\237\006\130\011\257\017\361\0\017\0\0";
  1789. X
  1790. X        /* clear delta bits */
  1791. X        (void) fas_inb (fip, MDM_STATUS_PORT);
  1792. X
  1793. X        do
  1794. X        {
  1795. X            /* test modem control and status lines */
  1796. X            fas_outb (fip, MDM_CTL_PORT, *cptr | MC_SET_LOOPBACK);
  1797. X            if (fas_inb (fip, MDM_STATUS_PORT) != *(cptr + 1))
  1798. X            {
  1799. X                done = 6;
  1800. X                break;
  1801. X            }
  1802. X        } while (*((ushort *) cptr)++);
  1803. X    }
  1804. X
  1805. X    /* switch back to normal operation */
  1806. X    fas_outb (fip, MDM_CTL_PORT, 0);
  1807. X
  1808. X    return (done);
  1809. X}
  1810. X
  1811. X#if defined (NEED_PUT_GETCHAR)
  1812. X
  1813. Xint
  1814. Xasyputchar (arg1)
  1815. Xunchar    arg1;
  1816. X{
  1817. X    register struct    fas_info    *fip;
  1818. X    REGVAR;
  1819. X
  1820. X    if (!fas_is_initted)
  1821. X        (void) fasinit ();
  1822. X
  1823. X    fip = &fas_info [0];
  1824. X    if (fip->device_flags.i & DF_DEVICE_CONFIGURED)
  1825. X    {
  1826. X        fas_ctl (fip, LINE_STATUS_PORT);
  1827. X        while (!(inb (LINE_STATUS_PORT.addr) & LS_XMIT_AVAIL))
  1828. X            ;
  1829. X        fas_outb (fip, XMT_DATA_PORT, arg1);
  1830. X        if (arg1 == 10)
  1831. X            (void) asyputchar (13);
  1832. X    }
  1833. X    return (0);
  1834. X}
  1835. X
  1836. Xint
  1837. Xasygetchar ()
  1838. X{
  1839. X    register struct    fas_info    *fip;
  1840. X    REGVAR;
  1841. X
  1842. X    if (!fas_is_initted)
  1843. X        (void) fasinit ();
  1844. X
  1845. X    fip = &fas_info [0];
  1846. X    if ((fip->device_flags.i & DF_DEVICE_CONFIGURED)
  1847. X        && (fas_first_inb (fip, LINE_STATUS_PORT) & LS_RCV_AVAIL))
  1848. X        return (fas_inb (fip, RCV_DATA_PORT));
  1849. X    else
  1850. X        return (-1);
  1851. X}
  1852. X#endif
  1853. X
  1854. X#if defined (NEED_INIT8250)
  1855. X
  1856. X/* reset the requested port to be used directly by a DOS process */
  1857. Xint
  1858. Xinit8250 (port, ier)
  1859. Xushort    port, ier;    /* ier not used in this stub */
  1860. X{
  1861. X    register struct fas_info    *fip;
  1862. X    register uint    physical_unit;
  1863. X    int    old_level;
  1864. X    REGVAR;
  1865. X
  1866. X    /* See if the port address matches a port that is used by
  1867. X       the fas driver.
  1868. X    */
  1869. X    for (physical_unit = 0; physical_unit < fas_physical_units;
  1870. X            physical_unit++)
  1871. X        if (port == (ushort) (fas_port [physical_unit]))
  1872. X            break;
  1873. X
  1874. X    if (physical_unit >= fas_physical_units)
  1875. X        return (-1);    /* port didn't match */
  1876. X
  1877. X    fip = fas_info_ptr [physical_unit];
  1878. X
  1879. X    old_level = SPLINT ();
  1880. X
  1881. X    fip->ier = IE_NONE;
  1882. X    fas_first_outb (fip, INT_ENABLE_PORT, fip->ier);
  1883. X
  1884. X    fip->mcr &= ~(fip->flow.m.ic | fip->flow.m.hc);
  1885. X    fas_outb (fip, MDM_CTL_PORT, fip->mcr);
  1886. X
  1887. X    if (fip->device_flags.i & DF_DEVICE_IS_NS16550A)
  1888. X        fas_outb (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);
  1889. X    else if (fip->device_flags.i & DF_DEVICE_IS_I82510)
  1890. X    {
  1891. X        fas_outb (fip, I_BANK_PORT, I_BANK_1);
  1892. X        fas_outb (fip, I_TCM_PORT, I_FIFO_CLR_XMIT);
  1893. X        fas_outb (fip, I_RCM_PORT, I_FIFO_CLR_RECV);
  1894. X        fas_outb (fip, I_BANK_PORT, I_BANK_2);
  1895. X        fas_outb (fip, I_IDM_PORT, I_FIFO_CLEAR_CMD);
  1896. X        fas_outb (fip, I_BANK_PORT, I_BANK_0);
  1897. X    }
  1898. X
  1899. X    (void) fas_inb (fip, MDM_STATUS_PORT);
  1900. X    (void) fas_inb (fip, RCV_DATA_PORT);
  1901. X    (void) fas_inb (fip, RCV_DATA_PORT);
  1902. X    (void) fas_inb (fip, LINE_STATUS_PORT);
  1903. X    (void) fas_inb (fip, INT_ID_PORT);
  1904. X    (void) splx (old_level);
  1905. X    return (0);
  1906. X}
  1907. X#endif
  1908. SHAR_EOF
  1909. echo 'File fas.c is complete' &&
  1910. true || echo 'restore of fas.c failed'
  1911. rm -f _shar_wnt_.tmp
  1912. fi
  1913. # ============= fas.h ==============
  1914. if test -f 'fas.h' -a X"$1" != X"-c"; then
  1915.     echo 'x - skipping fas.h (File already exists)'
  1916.     rm -f _shar_wnt_.tmp
  1917. else
  1918. > _shar_wnt_.tmp
  1919. echo 'x - extracting fas.h (Text)'
  1920. sed 's/^X//' << 'SHAR_EOF' > 'fas.h' &&
  1921. X/* This file contains various defines for the FAS async driver.
  1922. X   If you change anything here you have to recompile the driver module.
  1923. X*/
  1924. X
  1925. X#if !defined (M_I286)
  1926. X#ident    "@(#)fas.h    2.08"
  1927. X#endif
  1928. X
  1929. X/* Uncomment the following line if you need asyputchar and asygetchar.
  1930. X   This is only required if you link the kernel without the original
  1931. X   asy driver and these functions aren't provided by any other kernel
  1932. X   module.
  1933. X*/
  1934. X/* #define NEED_PUT_GETCHAR    /* */
  1935. X
  1936. X/* Uncomment the following line if you have VP/ix support in the
  1937. X   kernel.
  1938. X*/
  1939. X/* #define HAVE_VPIX    /* */
  1940. X
  1941. X/* Uncomment the following line if you need init8250. DosMerge needs
  1942. X   this function, but only if you link the kernel without the original
  1943. X   asy driver.
  1944. X*/
  1945. X/* #define NEED_INIT8250    /* */
  1946. X
  1947. X#if defined (VPIX)
  1948. X#undef VPIX
  1949. X#endif
  1950. X
  1951. X#if defined (HAVE_VPIX)
  1952. X#define VPIX
  1953. X#endif
  1954. X
  1955. X#include <sys/param.h>
  1956. X#include <sys/types.h>
  1957. X#include <sys/signal.h>
  1958. X#include <sys/buf.h>
  1959. X#include <sys/dir.h>
  1960. X#if defined (XENIX)
  1961. X#include <sys/page.h>
  1962. X#include <sys/seg.h>
  1963. X#endif
  1964. X#include <sys/user.h>
  1965. X#include <sys/errno.h>
  1966. X#include <sys/tty.h>
  1967. X#include <sys/conf.h>
  1968. X#include <sys/sysinfo.h>
  1969. X#include <sys/file.h>
  1970. X#if !defined (XENIX)
  1971. X#include <sys/termio.h>
  1972. X#endif
  1973. X#include <sys/ioctl.h>
  1974. X#include <macros.h>
  1975. X#if defined (HAVE_VPIX)
  1976. X#if !defined (XENIX)
  1977. X#include <sys/tss.h>
  1978. X#include <sys/immu.h>
  1979. X#include <sys/region.h>
  1980. X#endif
  1981. X#include <sys/proc.h>
  1982. X#include <sys/v86.h>
  1983. X#endif
  1984. X
  1985. X#if defined (XENIX)
  1986. Xtypedef unsigned char    unchar;
  1987. Xtypedef unsigned long    ulong;
  1988. X/*
  1989. X**    Union for use by all device handler ioctl routines.
  1990. X*/
  1991. Xunion ioctl_arg {
  1992. X    struct termio    *stparg;    /* ptr to termio struct */
  1993. X    char        *cparg;        /* ptr to character */
  1994. X    char        carg;        /* character */
  1995. X    int        *iparg;        /* ptr to integer */
  1996. X    int        iarg;        /* integer */
  1997. X    long            *lparg;         /* ptr to long */
  1998. X    long            larg;           /* long */
  1999. X};
  2000. X#endif
  2001. X
  2002. X#if defined (TRUE)
  2003. X#undef TRUE
  2004. X#endif
  2005. X#define    TRUE    (1)
  2006. X
  2007. X#if defined (FALSE)
  2008. X#undef FALSE
  2009. X#endif
  2010. X#define FALSE    (0)
  2011. X
  2012. X/* Initial line control register.  Value will only be meaningful for
  2013. X   asyputchar and asygetchar and they are only meaningful if
  2014. X   NEED_PUT_GETCHAR is defined.
  2015. X*/
  2016. X#define    INITIAL_LINE_CONTROL    LC_WORDLEN_8
  2017. X
  2018. X/* Initial baud rate.  Value will only be meaningful for
  2019. X   asyputchar and asygetchar and they are only meaningful if
  2020. X   NEED_PUT_GETCHAR is defined.
  2021. X*/
  2022. X#define INITIAL_BAUD_RATE    (BAUD_BASE/9600)
  2023. X
  2024. X/* Initial modem control register.  This should probably not have to
  2025. X   be touched.  It is here because some terminals used as the console
  2026. X   require one or more of the modem signals set. It is only meaningful
  2027. X   for asyputchar and asygetchar and they are only meaningful if
  2028. X   NEED_PUT_GETCHAR is defined.
  2029. X*/
  2030. X#define INITIAL_MDM_CONTROL    0
  2031. X
  2032. X/****************************************************/
  2033. X/* Nothing past this line should have to be changed */
  2034. X/****************************************************/
  2035. X
  2036. X#define NUM_INT_VECTORS    32    /* number of possible int vectors, but
  2037. X                   only the first eight are normally used
  2038. X                */
  2039. X
  2040. X#define MAX_UNITS    16    /* we will only use that many units */
  2041. X
  2042. X/* Miscellaneous Constants */
  2043. X
  2044. X#define BAUD_BASE    (1843200 / 16)    /* 115200 bps */
  2045. X#define HANGUP_DELAY    500        /* in milli-seconds */
  2046. X#define HANGUP_TIME    1000        /* in milli-seconds */
  2047. X#define RECOVER_TIME    30        /* in seconds */
  2048. X#define BREAK_TIME    250        /* in milli-seconds */
  2049. X#define EVENT_TIME    20        /* in milli-seconds */
  2050. X#if defined (M_I286)
  2051. X#define    RECV_BUFF_SIZE    1000        /* receiver ring buffer size (MAX) */
  2052. X#define SW_LOW_WATER    500    /* 50% MAX    sw flow control */
  2053. X#define SW_HIGH_WATER    800    /* 80% MAX     trigger levels */
  2054. X#define HW_LOW_WATER    700    /* MAX - 300    hw flow control */
  2055. X#define HW_HIGH_WATER    900    /* MAX - 100     trigger levels */
  2056. X#define XMIT_BUFF_SIZE    500        /* transmitter ring buffer size */
  2057. X#else
  2058. X#define    RECV_BUFF_SIZE    5000        /* receiver ring buffer size (MAX) */
  2059. X#define SW_LOW_WATER    2500    /* 50% MAX    sw flow control */
  2060. X#define SW_HIGH_WATER    4000    /* 80% MAX     trigger levels */
  2061. X#define HW_LOW_WATER    4200    /* MAX - 800    hw flow control */
  2062. X#define HW_HIGH_WATER    4700    /* MAX - 300     trigger levels */
  2063. X#define XMIT_BUFF_SIZE    2500        /* transmitter ring buffer size */
  2064. X#endif
  2065. X#define MAX_UNIX_FILL    (TTYHOG)    /* read buffer max UNIX fill level */
  2066. X#define MAX_VPIX_FILL    64        /* read buffer max VP/ix fill level */
  2067. X#define MIN_READ_CHUNK    32        /* must be <= MAX_????_FILL/2 */
  2068. X#define MAX_MSI_CNT    1000        /* max modem status ints per second */
  2069. X#define READ_PORT    0x0100        /* read command for fas_init_seq */
  2070. X#define NO_FIFO        0x10000        /* force FIFOs off */
  2071. X#define SOFT_INIT    0        /* init registers if cflag changed */
  2072. X#define HARD_INIT    1        /* init registers w/o checking cflag */
  2073. X#if defined (XENIX)
  2074. X#define SPLWRK        spl5        /* SPL for character processing */
  2075. X#define SPLINT        spl7        /* SPL to disable FAS interrupts */
  2076. X#else
  2077. X#define SPLWRK        spl6        /* SPL for character processing */
  2078. X#define SPLINT        spltty        /* SPL to disable FAS interrupts */
  2079. X#endif
  2080. X
  2081. X#if ((EVENT_TIME) * (HZ) / 1000) == 0
  2082. X#undef EVENT_TIME
  2083. X#define EVENT_TIME    (1000 / (HZ))
  2084. X#endif
  2085. X
  2086. X#if (MAX_UNIX_FILL) > (TTYHOG)
  2087. X#undef MAX_UNIX_FILL
  2088. X#define MAX_UNIX_FILL    (TTYHOG)
  2089. X#endif
  2090. X
  2091. X#if (MAX_VPIX_FILL) > (TTYHOG)
  2092. X#undef MAX_VPIX_FILL
  2093. X#define MAX_VPIX_FILL    (TTYHOG)
  2094. X#endif
  2095. X
  2096. X#if (MIN_READ_CHUNK) > ((MAX_UNIX_FILL) / 2)
  2097. X#undef MIN_READ_CHUNK
  2098. X#define MIN_READ_CHUNK    ((MAX_UNIX_FILL) / 2)
  2099. X#endif
  2100. X
  2101. X#if (MIN_READ_CHUNK) > ((MAX_VPIX_FILL) / 2)
  2102. X#undef MIN_READ_CHUNK
  2103. X#define MIN_READ_CHUNK    ((MAX_VPIX_FILL) / 2)
  2104. X#endif
  2105. X
  2106. X#define MAX_INPUT_FIFO_SIZE    INPUT_NS_FIFO_SIZE
  2107. X#define MAX_OUTPUT_FIFO_SIZE    OUTPUT_NS_FIFO_SIZE
  2108. X
  2109. X
  2110. X/* Here are the modem control flags for the fas_modem array in space.c.
  2111. X   They are arranged in three 8-bit masks which are combined to a 32-bit
  2112. X   word. Each of these 32-bit words represents one entry in the fas_modem
  2113. X   array.
  2114. X
  2115. X   The lowest byte is used as a mask to manipulate the modem control
  2116. X   register for modem disable. Use the MC_* macros to build the mask.
  2117. X
  2118. X   The second lowest byte is used as a mask to manipulate the modem control
  2119. X   register for modem enable during dialout. Use the MC_* macros to build
  2120. X   the mask and shift them 8 bits to the left.
  2121. X
  2122. X   The second highest byte is used as a mask to manipulate the modem control
  2123. X   register for modem enable during dialin. Use the MC_* macros to build
  2124. X   the mask and shift them 16 bits to the left.
  2125. X
  2126. X   The highest byte is used to mask signals from the modem status
  2127. X   register that will be used as the carrier detect signal. Use the MS_*
  2128. X   macros to build the mask and shift them 24 bits to the left. If you use
  2129. X   more than one signal, carrier is considered on only when all signals
  2130. X   are on.
  2131. X
  2132. X   Here are some useful macros for the space.c file. You may create your
  2133. X   own macros if you have some special requirements not met by the
  2134. X   predefined ones.
  2135. X*/
  2136. X
  2137. X/* modem disable (choose one) */
  2138. X#define DI_RTS            MC_SET_RTS    /* RTS disables modem */
  2139. X#define DI_DTR            MC_SET_DTR    /* DTR disables modem */
  2140. X#define DI_RTS_AND_DTR        (MC_SET_RTS | MC_SET_DTR)
  2141. X
  2142. X/* modem enable for dialout (choose one) */
  2143. X#define EO_RTS            (MC_SET_RTS << 8) /* RTS enables modem */
  2144. X#define EO_DTR            (MC_SET_DTR << 8) /* DTR enables modem */
  2145. X#define EO_RTS_AND_DTR        ((MC_SET_RTS | MC_SET_DTR) << 8)
  2146. X
  2147. X/* modem enable for dialin (choose one) */
  2148. X#define EI_RTS            (MC_SET_RTS << 16) /* RTS enables modem */
  2149. X#define EI_DTR            (MC_SET_DTR << 16) /* DTR enables modem */
  2150. X#define EI_RTS_AND_DTR        ((MC_SET_RTS | MC_SET_DTR) << 16)
  2151. X
  2152. X/* carrier detect signal (choose one) */
  2153. X#define CA_DCD            (MS_DCD_PRESENT << 24) /* DCD is carr. detect */
  2154. X#define CA_CTS            (MS_CTS_PRESENT << 24) /* CTS is carr. detect */
  2155. X#define CA_DSR            (MS_DSR_PRESENT << 24) /* DSR is carr. detect */
  2156. X
  2157. X
  2158. X/* Here are the hardware handshake flags for the fas_flow array in space.c.
  2159. X   They are arranged in three 8-bit masks which are combined to a 32-bit
  2160. X   word. Each of these 32-bit words represents one entry in the fas_flow
  2161. X   array.
  2162. X
  2163. X   The lowest byte is used as a mask to manipulate the modem control
  2164. X   register for input flow control. Use the MC_* macros to build the mask.
  2165. X
  2166. X   The second lowest byte is used to mask signals from the modem status
  2167. X   register that will be used for output flow control. Use the MS_* macros
  2168. X   to build the mask and shift them 8 bits to the left. If you use more
  2169. X   than one signal, output is allowed only when all signals are on.
  2170. X
  2171. X   The second highest byte is used to mask signals from the modem status
  2172. X   register that will be used to enable the output flow control selected
  2173. X   by the second lowest byte. Use the MS_* macros to build the mask and
  2174. X   shift them 16 bits to the left. If you use more than one signal, output
  2175. X   flow control is enabled only when all signals are on.
  2176. X
  2177. X   The highest byte is used as a mask to manipulate the modem control
  2178. X   register for output half duplex flow control. Use the MC_* macros to
  2179. X   build the mask and shift them 24 bits to the left.
  2180. X
  2181. X   Here are some useful macros for the space.c file. You may create your
  2182. X   own macros if you have some special requirements not met by the
  2183. X   predefined ones.
  2184. X*/
  2185. X
  2186. X/* input flow control (choose one) */
  2187. X#define HI_RTS            MC_SET_RTS    /* RTS input flow ctrl */
  2188. X#define HI_DTR            MC_SET_DTR    /* DTR input flow ctrl */
  2189. X#define HI_RTS_AND_DTR        (MC_SET_RTS | MC_SET_DTR)
  2190. X
  2191. X/* output flow control (choose one) */
  2192. X#define HO_CTS            (MS_CTS_PRESENT << 8) /* CTS output flow ctrl */
  2193. X#define HO_DSR            (MS_DSR_PRESENT << 8) /* DSR output flow ctrl */
  2194. X#define HO_CTS_AND_DSR        ((MS_CTS_PRESENT | MS_DSR_PRESENT) << 8)
  2195. X#define HO_CTS_ON_DSR        ((MS_CTS_PRESENT << 8) | (MS_DSR_PRESENT << 16))
  2196. X#define HO_CTS_ON_DSR_AND_DCD    ((MS_CTS_PRESENT << 8) \
  2197. X                | ((MS_DSR_PRESENT | MS_DCD_PRESENT) << 16))
  2198. X
  2199. X/* output hdx flow control (choose one) */
  2200. X#define HX_RTS            (MC_SET_RTS << 24) /* RTS hdx flow ctrl */
  2201. X#define HX_DTR            (MC_SET_DTR << 24) /* DTR hdx flow ctrl */
  2202. X#define HX_RTS_AND_DTR        ((MC_SET_RTS | MC_SET_DTR) << 24)
  2203. X
  2204. X
  2205. X/* define the local open flags */
  2206. X
  2207. X#define OS_DEVICE_CLOSED    0x0000
  2208. X#define OS_OPEN_FOR_DIALOUT    0x0001
  2209. X#define OS_OPEN_FOR_GETTY    0x0002
  2210. X#define OS_WAIT_OPEN        0x0004
  2211. X#define OS_NO_DIALOUT        0x0008
  2212. X#define OS_FAKE_CARR_ON        0x0010
  2213. X#define OS_CLOCAL        0x0020
  2214. X#define OS_HWO_HANDSHAKE    0x0040
  2215. X#define OS_HWI_HANDSHAKE    0x0080
  2216. X#define OS_HDX_HANDSHAKE    0x0100
  2217. X#define OS_EXCLUSIVE_OPEN_1    0x0200
  2218. X#define OS_EXCLUSIVE_OPEN_2    0x0400    /* SYSV 3.2 Xenix compatibility */
  2219. X
  2220. X#define OS_OPEN_STATES        (OS_OPEN_FOR_DIALOUT | OS_OPEN_FOR_GETTY)
  2221. X#define OS_TEST_MASK        (OS_OPEN_FOR_DIALOUT | OS_NO_DIALOUT \
  2222. X                | OS_FAKE_CARR_ON | OS_CLOCAL \
  2223. X                | OS_HWO_HANDSHAKE | OS_HWI_HANDSHAKE \
  2224. X                | OS_HDX_HANDSHAKE | OS_EXCLUSIVE_OPEN_1 \
  2225. X                | OS_EXCLUSIVE_OPEN_2)
  2226. X#define OS_SU_TEST_MASK        (OS_OPEN_FOR_DIALOUT | OS_NO_DIALOUT \
  2227. X                | OS_FAKE_CARR_ON | OS_CLOCAL \
  2228. X                | OS_HWO_HANDSHAKE | OS_HWI_HANDSHAKE \
  2229. X                | OS_HDX_HANDSHAKE | OS_EXCLUSIVE_OPEN_1)
  2230. X
  2231. X/* define the device status flags */
  2232. X
  2233. X#define DF_DEVICE_CONFIGURED    0x0001    /* device is configured */
  2234. X#define DF_DEVICE_IS_NS16550A    0x0002    /* it's an NS16550A */
  2235. X#define DF_DEVICE_IS_I82510    0x0004    /* it's an I82510 */
  2236. X#define DF_CTL_FIRST        0x0008    /* write ctl port at first access */
  2237. X#define DF_CTL_EVERY        0x0010    /* write ctl port at every access */
  2238. X#define DF_DEVICE_OPEN        0x0020    /* physical device is open */
  2239. X#define DF_DEVICE_LOCKED    0x0040    /* physical device locked */
  2240. X#define DF_MODEM_ENABLED    0x0080    /* modem enabled */
  2241. X#define DF_XMIT_BUSY        0x0100    /* transmitter busy */
  2242. X#define DF_XMIT_BREAK        0x0200    /* transmitter sends break */
  2243. X#define DF_XMIT_LOCKED        0x0400    /* transmitter locked against output */
  2244. X#define DF_DO_HANGUP        0x0800    /* delayed hangup request */
  2245. X#define DF_DO_BREAK        0x1000    /* delayed break request */
  2246. X#define DF_GUARD_TIMEOUT    0x2000    /* protect last char from corruption */
  2247. X#define DF_NS16550A_DROP_MODE    0x4000    /* receiver trigger level is dropped */
  2248. X
  2249. X/* define the flow control status flags */
  2250. X
  2251. X#define FF_HWO_HANDSHAKE    0x0001    /* output hw handshake enabled */
  2252. X#define FF_HWI_HANDSHAKE    0x0002    /* input hw handshake enabled */
  2253. X#define FF_HDX_HANDSHAKE    0x0004    /* output hdx hw handshake enabled */
  2254. X#define    FF_HWO_STOPPED        0x0008    /* output stopped by hw handshake */
  2255. X#define FF_HWI_STOPPED        0x0010    /* input stopped by hw handshake */
  2256. X#define FF_HDX_STARTED        0x0020    /* output buffer contains characters */
  2257. X#define FF_SWO_STOPPED        0x0040    /* output stopped by sw flow control */
  2258. X#define FF_SWI_STOPPED        0x0080    /* input stopped by sw flow control */
  2259. X#define FF_SW_FC_REQ        0x0100    /* sw input flow control request */
  2260. X#define FF_RXFER_STOPPED    0x0200    /* rxfer function stopped */
  2261. X
  2262. X/* define the scheduled events flags */
  2263. X
  2264. X#define EF_DO_RXFER        0x0001    /* rxfer function request */
  2265. X#define EF_DO_XXFER        0x0002    /* xxfer function request */
  2266. X#define EF_DO_BRKINT        0x0004    /* break int request */
  2267. X#define EF_DO_MPROC        0x0008    /* mproc function request */
  2268. X#define EF_SIGNAL_VPIX        0x0010    /* send pseudorupt to VP/ix */
  2269. SHAR_EOF
  2270. true || echo 'restore of fas.h failed'
  2271. fi
  2272. echo 'End of fas208 part 3'
  2273. echo 'File fas.h is continued in part 4'
  2274. echo 4 > _shar_seq_.tmp
  2275. exit 0
  2276. -- 
  2277. Uwe Doering  |  INET : gemini@geminix.in-berlin.de
  2278. Berlin       |----------------------------------------------------------------
  2279. Germany      |  UUCP : ...!unido!fub!geminix.in-berlin.de!gemini
  2280.