home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #20 / NN_1992_20.iso / spool / comp / sources / misc / 3960 < prev    next >
Encoding:
Text File  |  1992-09-15  |  57.2 KB  |  2,201 lines

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