home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume32 / ecu / part33 < prev    next >
Encoding:
Text File  |  1992-09-14  |  57.0 KB  |  2,195 lines

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