home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-10-16 | 59.8 KB | 2,205 lines |
- Newsgroups: comp.sources.unix
- From: fas@geminix.in-berlin.de (FAS Support Account)
- Subject: REPOST v27i073: FAS-2.11.0 - asynch serial driver for System V, Part06/08
- References: <1.750471074.20539@gw.home.vix.com>
- Sender: unix-sources-moderator@gw.home.vix.com
- Approved: vixie@gw.home.vix.com
-
- Submitted-By: fas@geminix.in-berlin.de (FAS Support Account)
- Posting-Number: Volume 27, Issue 73
- Archive-Name: fas-2.11.0/part06
-
- #!/bin/sh
- # this is fas211pl0.06 (part 6 of a multipart archive)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file fas.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 6; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping fas.c'
- else
- echo 'x - continuing file fas.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'fas.c' &&
- X else
- X#endif
- X {
- X if (cflag & CTSFLOW)
- X fip->flow_flags |= FF_HWO_HANDSHAKE;
- X if (cflag & RTSFLOW)
- X fip->flow_flags |= (fip->flow_flags
- X & FF_NEW_CTSRTS)
- X ? FF_HWI_HANDSHAKE
- X : FF_HDX_HANDSHAKE;
- X }
- X#endif
- X }
- X#endif
- X#endif
- X }
- X
- X /* Determine whether to enable MSI or not.
- X Set the interrupt enable port accordingly.
- X */
- X#if defined (HAVE_VPIX)
- X if ((cflag & CLOCAL) && !(fip->flow_flags & FF_HWO_HANDSHAKE)
- X && !(fip->iflag & DOSMODE))
- X#else
- X if ((cflag & CLOCAL) && !(fip->flow_flags & FF_HWO_HANDSHAKE))
- X#endif
- X {
- X if (fip->device_flags & DF_MSI_ENABLED)
- X {
- X FAS_FIRST_OUTB (fip, INT_ENABLE_PORT,
- X IER &= ~IE_MODEM_STATUS);
- X fip->device_flags &= ~DF_MSI_ENABLED;
- X }
- X fip->device_flags &= ~DF_MSI_NOISE;
- X }
- X else
- X {
- X if (!(fip->device_flags & (DF_MSI_ENABLED | DF_MSI_NOISE)))
- X {
- X /* read current modem status lines */
- X MSR = NEW_MSR = FAS_FIRST_INB (fip, MDM_STATUS_PORT)
- X & (MS_CTS_PRESENT
- X | MS_DSR_PRESENT
- X | MS_DCD_PRESENT);
- X FAS_OUTB (fip, INT_ENABLE_PORT, IER |= IE_MODEM_STATUS);
- X fip->device_flags |= DF_MSI_ENABLED;
- X }
- X }
- X
- X /* Fake the carrier detect state flag if CLOCAL mode or if
- X requested by open mode.
- X */
- X if ((cflag & CLOCAL)
- X || (fip->flow_flags & FF_CD_ENABLED
- X && !(~MSR & fip->modem.m.ca))
- X || ((fip->o_state & OS_FAKE_CARRIER_ON)
- X && ((fip->flow_flags & FF_CARRIER_ON)
- X || !(fip->o_state & OS_OPEN_STATES))))
- X {
- X fip->flow_flags |= FF_CD_ENABLED | FF_CARRIER_ON;
- X ttyp->t_state |= CARR_ON;
- X }
- X else
- X {
- X if (fip->flow_flags & FF_CARRIER_ON)
- X {
- X fip->flow_flags &= ((fip->device_flags
- X & DF_HUP_PROTECT)
- X && (fip->o_state
- X & OS_OPEN_STATES))
- X ? ~(FF_CD_ENABLED
- X | FF_CARRIER_ON)
- X : ~FF_CARRIER_ON;
- X /* flush buffers on carrier drop */
- X do_flush = TRUE;
- X }
- X ttyp->t_state &= ~CARR_ON;
- X }
- X
- X if ((fip->flow_flags & FF_CARRIER_ON) && (cflag & CREAD))
- X {
- X /* enable receiver data interrupts */
- X if (!(fip->device_flags & DF_RDI_ENABLED))
- X fas_rdi_enable (fip);
- X }
- X else
- X {
- X /* disable receiver data interrupts */
- X if (fip->device_flags & DF_RDI_ENABLED)
- X {
- X FAS_FIRST_OUTB (fip, INT_ENABLE_PORT,
- X IER &= ~IE_RECV_DATA_AVAILABLE);
- X fip->device_flags &= ~DF_RDI_ENABLED;
- X }
- X }
- X
- X fip->cflag = cflag;
- X }
- X
- X#if defined (XCLUDE) /* SYSV 3.2 Xenix compatibility */
- X /* Permit exclusive use of this device. */
- X if (ttyp->t_lflag & XCLUDE)
- X fip->o_state |= OS_EXCLUSIVE_OPEN_2;
- X else
- X fip->o_state &= ~OS_EXCLUSIVE_OPEN_2;
- X#endif
- X
- X /* re-link fas_internals structure */
- X fas_pos_by_speed (fip);
- X
- X /* flush buffers if necessary */
- X if (do_flush)
- X {
- X /* lock transmitter */
- X fip->device_flags |= DF_XMIT_LOCKED;
- X old_level = SPLWRK ();
- X (void) ttyflush (ttyp, FREAD | FWRITE);
- X (void) splx (old_level);
- X /* enable transmitter */
- X fip->device_flags &= ~DF_XMIT_LOCKED;
- X }
- X
- X /* setup handshake flags */
- X#if defined (HAVE_VPIX)
- X if ((fip->flow_flags & (FF_HWI_HANDSHAKE | FF_HDX_HANDSHAKE))
- X || !(fip->iflag & DOSMODE))
- X#endif
- X {
- X register n_unchar mcr REG_BX;
- X
- X /* clear flow control output bits */
- X mcr = MCR & ~(fip->flow.m.ic | fip->flow.m.hc);
- X fip->flow_flags &= ~(FF_HWI_STARTED | FF_HDX_STARTED);
- X
- X /* raise flow control bits if necessary */
- X if (fip->flow_flags & FF_HWI_HANDSHAKE)
- X {
- X if (fip->recv_ring_cnt < HW_LOW_WATER)
- X {
- X mcr |= fip->flow.m.ic;
- X fip->flow_flags |= FF_HWI_STARTED;
- X }
- X }
- X else if (fip->flow_flags & FF_HDX_HANDSHAKE)
- X {
- X if (fip->flow_flags & FF_OUTPUT_BUSY)
- X {
- X mcr |= fip->flow.m.hc;
- X fip->flow_flags |= FF_HDX_STARTED;
- X }
- X }
- X else if (!(fip->flow_flags & FF_DEF_HHO_LOW))
- X mcr |= fip->flow.m.hc;
- X
- X /* set modem enable bits */
- X#if defined (HAVE_VPIX)
- X if (!(fip->iflag & DOSMODE))
- X#endif
- X {
- X if ((ttyp->t_cflag & CBAUD) != B0
- X && (fip->flow_flags & FF_CD_ENABLED))
- X {
- X mcr |= (fip->o_state & OS_WAIT_OPEN)
- X ? fip->modem.m.ei
- X : fip->modem.m.eo;
- X }
- X else
- X {
- X mcr &= (fip->o_state & OS_WAIT_OPEN)
- X ? ~fip->modem.m.ei
- X : ~fip->modem.m.eo;
- X }
- X }
- X
- X if ((init_type != SOFT_INIT) || (mcr != MCR))
- X FAS_FIRST_OUTB (fip, MDM_CTL_PORT, MCR = mcr);
- X }
- X
- X /* set hardware output flow control flags */
- X if (!(~NEW_MSR & fip->flow.m.oc)
- X || (~NEW_MSR & fip->flow.m.oe)
- X || !(fip->flow_flags & FF_HWO_HANDSHAKE))
- X fip->flow_flags &= ~FF_HWO_STOPPED;
- X else
- X fip->flow_flags |= FF_HWO_STOPPED;
- X
- X /* check software input flow control */
- X if (fip->flow_flags & FF_SWI_STOPPED)
- X {
- X if (!(fip->iflag & IXOFF)
- X || (fip->recv_ring_cnt < SW_LOW_WATER))
- X fas_send_xon (fip);
- X }
- X else
- X {
- X if ((fip->iflag & IXOFF)
- X && (fip->recv_ring_cnt > SW_HIGH_WATER))
- X fas_send_xoff (fip);
- X }
- X
- X /* restart output */
- X fas_xproc (fip);
- X}
- X
- X/* Re-link fas_internals structure to interrupt users chain according
- X to the baud rate (fastes port comes first).
- X (called at SPLINT)
- X*/
- XSTATIC void
- Xfas_pos_by_speed (fipp)
- Xstruct fas_internals *fipp;
- X{
- X register struct fas_internals *fip REG_SI;
- X
- X {
- X register n_unchar my_prio REG_BX;
- X register n_unchar prio REG_CX;
- X ulong my_speed;
- X
- X fip = fipp;
- X
- X /* compute our own speed */
- X if (fip->flow_flags & FF_CARRIER_ON)
- X {
- X INT_PRIO = my_prio = (fip->device_flags & DF_NO_OVERRUN)
- X ? NUMBER_OF_TYPES
- X : DEVICE_TYPE;
- X my_speed = fas_baud_ptr [BT_SELECT] [fip->cflag & CBAUD];
- X }
- X else
- X {
- X my_prio = NUMBER_OF_TYPES + 1;
- X INT_PRIO = NUMBER_OF_TYPES + 1;
- X my_speed = 0L;
- X }
- X
- X /* unhook us from the interrupt users chain */
- X if (fip->prev_int_user)
- X fip->prev_int_user->next_int_user = fip->next_int_user;
- X else
- X fas_first_int_user = fip->next_int_user;
- X if (fip->next_int_user)
- X fip->next_int_user->prev_int_user = fip->prev_int_user;
- X else
- X fas_last_int_user = fip->prev_int_user;
- X
- X /* find a new position for us */
- X for (fip = fas_first_int_user; fip; fip = fip->next_int_user)
- X {
- Xfastloop4:
- X if (my_prio > (prio = INT_PRIO))
- X {
- X /* speed beats beauty */
- X fip = fip->next_int_user;
- X if (fip)
- X goto fastloop4;
- X break;
- X }
- X
- X if (my_prio < prio)
- X break; /* found a new position */
- X if (my_speed >= ((prio == NUMBER_OF_TYPES + 1)
- X ? 0L
- X : fas_baud_ptr [BT_SELECT]
- X [fip->cflag & CBAUD]))
- X break; /* found a new position */
- X }
- X }
- X
- X {
- X register struct fas_internals *my_fip REG_DI;
- X
- X my_fip = fipp;
- X
- X /* now hook us into the new position */
- X if (fip)
- X {
- X /* we are in front of another entry */
- X if ((my_fip->prev_int_user = fip->prev_int_user))
- X my_fip->prev_int_user->next_int_user = my_fip;
- X else
- X fas_first_int_user = my_fip;
- X fip->prev_int_user = my_fip;
- X my_fip->next_int_user = fip;
- X }
- X else
- X {
- X /* we are the last entry */
- X if ((my_fip->prev_int_user = fas_last_int_user))
- X my_fip->prev_int_user->next_int_user = my_fip;
- X else
- X fas_first_int_user = my_fip;
- X fas_last_int_user = my_fip;
- X my_fip->next_int_user = (struct fas_internals *) NULL;
- X }
- X }
- X}
- X
- X/* Asynchronous event handler. Scheduled by functions that can't do the
- X processing themselves because of execution time restrictions.
- X (called via timeout () at an OS dependent SPL)
- X*/
- XSTATIC void
- Xfas_event (dummy)
- Xvoid *dummy;
- X{
- X register struct fas_internals *fip REG_SI;
- X register struct tty *ttyp REG_DI;
- X register uint count REG_BX;
- X bool idle;
- X int old_level;
- X
- X /* allow pending tty interrupts */
- X old_level = SPLWRK ();
- X (void) SPLINT ();
- X
- X idle = TRUE;
- X
- X /* loop through all fas_internals structures */
- X for (fip = &fas_internals [0], count = fas_physical_units; count;
- X ++fip, --count)
- X {
- Xfastloop3:
- X /* process only structures that actually need service */
- X if (!fip->event_flags)
- X {
- X /* speed beats beauty */
- X ++fip;
- X if (--count)
- X goto fastloop3;
- X break;
- X }
- X
- X /* we have something to do */
- X idle = FALSE;
- X ttyp = fip->tty;
- X
- X /* check the modem signals */
- X if (fip->event_flags & (EF_DO_MPROC | EF_RESET_DELTA_BITS))
- X {
- X NEW_MSR &= ~MS_ANY_DELTA;
- X if (fip->event_flags & EF_DO_MPROC)
- X {
- X fip->event_flags &= ~(EF_DO_MPROC
- X | EF_RESET_DELTA_BITS);
- X fas_mproc (fip);
- X }
- X else
- X fip->event_flags &= ~EF_RESET_DELTA_BITS;
- X
- X /* re-enable modem status interrupts if appropriate */
- X if (fip->device_flags & DF_MSI_NOISE)
- X {
- X FAS_FIRST_OUTB (fip, INT_ENABLE_PORT,
- X IER |= IE_MODEM_STATUS);
- X fip->device_flags |= DF_MSI_ENABLED;
- X fip->device_flags &= ~DF_MSI_NOISE;
- X }
- X }
- X
- X /* do the break interrupt */
- X if (fip->event_flags & EF_DO_BRKINT)
- X {
- X fip->event_flags &= ~EF_DO_BRKINT;
- X if (fip->flow_flags & FF_CARRIER_ON)
- X {
- X (void) SPLWRK ();
- X (void) (*linesw [(unchar) ttyp->t_line].l_input)
- X (ttyp, L_BREAK);
- X (void) SPLINT ();
- X }
- X }
- X
- X /* transfer characters to the CLIST input buffer */
- X if (fip->event_flags & EF_DO_RXFER)
- X {
- X#if defined (HAVE_VPIX)
- X fip->event_flags &= ~(EF_DO_RXFER | EF_WAKEUP_VPIX);
- X#else
- X fip->event_flags &= ~EF_DO_RXFER;
- X#endif
- X if ((fip->flow_flags & (FF_CARRIER_ON
- X | FF_RXFER_STOPPED))
- X == FF_CARRIER_ON)
- X {
- X /* if not done, re-schedule this event */
- X if (!fas_rxfer (fip))
- X fip->event_flags |= EF_DO_RXFER;
- X /* check input buffer low water marks */
- X if ((fip->recv_ring_cnt < HW_LOW_WATER)
- X && (fip->flow_flags & (FF_HWI_HANDSHAKE
- X | FF_HWI_STARTED))
- X == FF_HWI_HANDSHAKE)
- X {
- X FAS_FIRST_OUTB (fip, MDM_CTL_PORT,
- X MCR |= fip->flow.m.ic);
- X fip->flow_flags |= FF_HWI_STARTED;
- X }
- X if ((fip->recv_ring_cnt < SW_LOW_WATER)
- X && (fip->iflag & IXOFF)
- X && (fip->flow_flags & FF_SWI_STOPPED))
- X fas_send_xon (fip);
- X }
- X#if defined (HAVE_VPIX)
- X /* send pseudorupt to VP/ix */
- X if ((fip->iflag & DOSMODE) && fip->v86_proc
- X && (ttyp->t_rawq.c_cc || ttyp->t_canq.c_cc))
- X {
- X (void) SPLWRK ();
- X (void) v86setint (fip->v86_proc,
- X fip->v86_intmask);
- X (void) SPLINT ();
- X fip->event_flags |= EF_WAKEUP_VPIX;
- X }
- X#endif
- X }
- X#if defined (HAVE_VPIX)
- X else if (fip->event_flags & EF_WAKEUP_VPIX)
- X {
- X /* send pseudorupt to VP/ix */
- X if ((fip->iflag & DOSMODE) && fip->v86_proc
- X && (ttyp->t_rawq.c_cc || ttyp->t_canq.c_cc))
- X {
- X (void) SPLWRK ();
- X (void) v86setint (fip->v86_proc,
- X fip->v86_intmask);
- X (void) SPLINT ();
- X }
- X else
- X fip->event_flags &= ~EF_WAKEUP_VPIX;
- X }
- X#endif
- X
- X /* transfer characters to the output ring buffer */
- X if (fip->event_flags & EF_DO_XXFER)
- X {
- X fip->event_flags &= ~EF_DO_XXFER;
- X if (fip->flow_flags & FF_CARRIER_ON)
- X {
- X fas_xxfer (fip);
- X if (fip->flow_flags & FF_OUTPUT_BUSY)
- X ttyp->t_state |= BUSY;
- X /* check half duplex output flow control */
- X if ((fip->flow_flags & (FF_HDX_HANDSHAKE
- X | FF_HDX_STARTED
- X | FF_OUTPUT_BUSY))
- X == (FF_HDX_HANDSHAKE
- X | FF_OUTPUT_BUSY))
- X {
- X FAS_FIRST_OUTB (fip, MDM_CTL_PORT,
- X MCR |= fip->flow.m.hc);
- X fip->flow_flags |= FF_HDX_STARTED;
- X }
- X /* output characters */
- X fas_xproc (fip);
- X }
- X else
- X {
- X /* throw away characters in output queue */
- X (void) SPLWRK ();
- X (void) ttyflush (ttyp, FWRITE);
- X (void) SPLINT ();
- X }
- X }
- X
- X /* allow pending tty interrupts */
- X (void) SPLWRK ();
- X (void) SPLINT ();
- X }
- X
- X event_scheduled = FALSE;
- X
- X /* check whether there was something to do */
- X if (!idle)
- X {
- X /* there was work to do, so it's likely that there
- X also will be something to do in a short time from
- X now, so we schedule the next event processing
- X */
- X event_scheduled = TRUE;
- X (void) timeout (fas_event, (caddr_t) NULL,
- X (EVENT_TIME) * (HZ) / 1000);
- X }
- X
- X (void) splx (old_level);
- X}
- X
- X/* Modem status handler.
- X (called at SPLINT)
- X*/
- XSTATIC void
- Xfas_mproc (fip)
- Xregister struct fas_internals *fip REG_SI;
- X{
- X register n_unchar mdm_status REG_BX;
- X int old_level;
- X
- X mdm_status = NEW_MSR;
- X NEW_MSR &= ~MS_RING_PRESENT;
- X
- X /* Check the carrier detect signal and set the state flags
- X accordingly. Also, if not in clocal mode, send SIGHUP on
- X carrier loss and flush the buffers.
- X */
- X if (!(fip->cflag & CLOCAL) && (fip->flow_flags & FF_CD_ENABLED))
- X {
- X register struct tty *ttyp REG_DI;
- X
- X ttyp = fip->tty;
- X if (!(~mdm_status & fip->modem.m.ca))
- X {
- X /* Wake up dialin process on carrier low->high. */
- X if (!(fip->flow_flags & FF_CARRIER_ON))
- X {
- X fip->flow_flags |= FF_CARRIER_ON;
- X if ((ttyp->t_state |= CARR_ON) & WOPEN)
- X (void) wakeup ((caddr_t) &ttyp->t_canq);
- X /* enable receiver data interrupts */
- X if ((fip->cflag & CREAD)
- X && !(fip->device_flags
- X & DF_RDI_ENABLED))
- X fas_rdi_enable (fip);
- X /* re-link fas_internals structure */
- X fas_pos_by_speed (fip);
- X }
- X }
- X else
- X {
- X if (!(~MSR & fip->modem.m.ca))
- X {
- X if ((fip->device_flags & DF_HUP_PROTECT)
- X && (fip->o_state & OS_OPEN_STATES))
- X {
- X FAS_FIRST_OUTB (fip, MDM_CTL_PORT,
- X MCR &= (fip->o_state
- X & OS_WAIT_OPEN)
- X ? ~fip->modem.m.ei
- X : ~fip->modem.m.eo);
- X fip->flow_flags &= ~(FF_CD_ENABLED
- X | FF_CARRIER_ON);
- X }
- X else
- X fip->flow_flags &= ~FF_CARRIER_ON;
- X ttyp->t_state &= ~CARR_ON;
- X /* disable receiver data interrupts */
- X if (fip->device_flags & DF_RDI_ENABLED)
- X {
- X FAS_FIRST_OUTB (fip, INT_ENABLE_PORT,
- X IER &= ~IE_RECV_DATA_AVAILABLE);
- X fip->device_flags &= ~DF_RDI_ENABLED;
- X }
- X /* re-link fas_internals structure */
- X fas_pos_by_speed (fip);
- X old_level = SPLWRK ();
- X if (ttyp->t_pgrp)
- X {
- X (void) signal (ttyp->t_pgrp, SIGHUP);
- X#if defined (SIGCONT)
- X /* make sure processes are awake */
- X (void) signal (ttyp->t_pgrp, SIGCONT);
- X#endif
- X }
- X (void) ttyflush (ttyp, FREAD | FWRITE);
- X (void) splx (old_level);
- X }
- X }
- X }
- X
- X#if defined (HAVE_VPIX)
- X if ((fip->iflag & (DOSMODE | PARMRK)) == (DOSMODE | PARMRK)
- X && (fip->flow_flags & FF_CARRIER_ON)
- X && fip->recv_ring_cnt < RECV_BUFF_SIZE - 2)
- X {
- X register n_unchar vpix_status REG_CX;
- X
- X /* prepare status bits for VP/ix */
- X vpix_status = (((mdm_status ^ MSR) >> 4) & MS_ANY_DELTA)
- X | (mdm_status & (MS_CTS_PRESENT
- X | MS_DSR_PRESENT
- X | MS_DCD_PRESENT));
- X if (fip->flow_flags & FF_HWO_HANDSHAKE)
- X {
- X vpix_status &= ~((n_unchar) (fip->flow.m.oc
- X | fip->flow.m.oe) >> 4);
- X vpix_status |= fip->flow.m.oc | fip->flow.m.oe;
- X }
- X if (!(fip->cflag & CLOCAL))
- X {
- X vpix_status &= ~((n_unchar) fip->modem.m.ca >> 4);
- X vpix_status |= fip->modem.m.ca;
- X }
- X /* send status bits to VP/ix */
- X if (vpix_status & MS_ANY_DELTA)
- X {
- X fip->recv_ring_cnt += 3;
- X PUT_RECV_BUFFER (fip, fip->recv_ring_put_ptr, 0xff);
- X PUT_RECV_BUFFER (fip, fip->recv_ring_put_ptr, 2);
- X PUT_RECV_BUFFER (fip, fip->recv_ring_put_ptr,
- X vpix_status);
- X EVENT_SCHED (fip, EF_DO_RXFER);
- X /* check input buffer high water marks */
- X if ((fip->recv_ring_cnt > HW_HIGH_WATER)
- X && (fip->flow_flags & (FF_HWI_HANDSHAKE
- X | FF_HWI_STARTED))
- X == (FF_HWI_HANDSHAKE | FF_HWI_STARTED))
- X {
- X FAS_FIRST_OUTB (fip, MDM_CTL_PORT,
- X MCR &= ~fip->flow.m.ic);
- X fip->flow_flags &= ~FF_HWI_STARTED;
- X }
- X if ((fip->recv_ring_cnt > SW_HIGH_WATER)
- X && (fip->iflag & IXOFF)
- X && !(fip->flow_flags & FF_SWI_STOPPED))
- X fas_send_xoff (fip);
- X }
- X }
- X#endif
- X MSR = mdm_status & ~MS_RING_PRESENT;
- X
- X /* re-enable transmitter if it was stopped by carrier detect */
- X if (fip->flow_flags & FF_CARR_STOPPED)
- X {
- X fip->flow_flags &= ~FF_CARR_STOPPED;
- X fas_xproc (fip);
- X }
- X}
- X
- X/* Receiver ring buffer -> CLIST buffer transfer function.
- X (called at SPLINT)
- X*/
- XSTATIC bool
- Xfas_rxfer (fipp)
- Xstruct fas_internals *fipp;
- X{
- X /* Defining register variables with function-wide scope would
- X break the FAS_MEM_COPY () macro below. So don't do that!
- X */
- X unchar *tmp_srcptr, *tmp_destptr;
- X uint num_save;
- X uint recv_ring_cnt;
- X int old_level;
- X
- X num_save = 0;
- X
- X for (;;)
- X {
- X /* determine how many characters we have to copy */
- X {
- X register struct fas_internals *fip REG_SI;
- X register struct tty *ttyp REG_DI;
- X register uint num_to_xfer REG_BX;
- X
- X old_level = SPLWRK ();
- X fip = fipp;
- X ttyp = fip->tty;
- X
- X /* if the target buffer is full, or if there is no
- X target buffer available, try to get a new one,
- X otherwise return
- X */
- X if (num_save || !ttyp->t_rbuf.c_ptr)
- X {
- X (void) (*linesw [(unchar) ttyp->t_line].l_input)
- X (ttyp, L_BUF);
- X if (!ttyp->t_rbuf.c_ptr)
- X {
- X (void) splx (old_level);
- X return (FALSE);
- X }
- X }
- X
- X /* return if there aren't any characters to transfer */
- X if (!(recv_ring_cnt = fip->recv_ring_cnt))
- X {
- X (void) splx (old_level);
- X return (TRUE);
- X }
- X
- X /* determine how many characters to transfer */
- X#if defined (XENIX)
- X if (ttyp->t_lflag & ICANON)
- X#else
- X if ((ttyp->t_lflag & ICANON) || ttyp->t_term)
- X#endif
- X {
- X num_to_xfer = recv_ring_cnt;
- X }
- X else
- X {
- X num_to_xfer = max_rawq_count - (uint) ttyp->t_rawq.c_cc;
- X if (!num_to_xfer)
- X {
- X (void) splx (old_level);
- X return (FALSE); /* input buffer full */
- X }
- X if (recv_ring_cnt < num_to_xfer)
- X num_to_xfer = recv_ring_cnt;
- X /* if there are too few remaining characters to
- X completely fill a CLIST buffer, postpone the
- X transfer of these characters for a number of
- X event cycles on the assumption that by then
- X more characters have arrived
- X */
- X if (ttyp->t_rbuf.c_count > num_to_xfer
- X && (num_save || --fip->rxfer_timeout))
- X {
- X (void) splx (old_level);
- X return (FALSE); /* input buffer full */
- X }
- X }
- X
- X /* reset timeout counter */
- X fip->rxfer_timeout = MAX_RXFER_DELAY / EVENT_TIME;
- X
- X /* determine how many characters are in one contiguous block */
- X if (ttyp->t_rbuf.c_count < num_to_xfer)
- X num_to_xfer = ttyp->t_rbuf.c_count;
- X if ((uint) (&fip->recv_buffer [RECV_BUFF_SIZE]
- X - fip->recv_ring_take_ptr)
- X < num_to_xfer)
- X num_to_xfer = &fip->recv_buffer [RECV_BUFF_SIZE]
- X - fip->recv_ring_take_ptr;
- X
- X if (!num_to_xfer)
- X {
- X /* invalid count, shouldn't happen */
- X (void) splx (old_level);
- X return (FALSE);
- X }
- X
- X tmp_srcptr = fip->recv_ring_take_ptr;
- X if ((fip->recv_ring_take_ptr += num_to_xfer)
- X == &fip->recv_buffer [RECV_BUFF_SIZE])
- X fip->recv_ring_take_ptr = &fip->recv_buffer [0];
- X tmp_destptr = (unchar *) ttyp->t_rbuf.c_ptr;
- X ttyp->t_rbuf.c_count -= num_to_xfer;
- X num_save = num_to_xfer;
- X }
- X
- X /* now copy from the ring buffer to the clist buffer */
- X FAS_MEM_COPY (tmp_destptr, tmp_srcptr, num_save);
- X
- X (void) splx (old_level);
- X fipp->recv_ring_cnt -= num_save;
- X }
- X}
- X
- X/* CLIST buffer -> transmitter ring buffer transfer function.
- X (called at SPLINT)
- X*/
- XSTATIC void
- Xfas_xxfer (fipp)
- Xstruct fas_internals *fipp;
- X{
- X /* Defining register variables with function-wide scope would
- X break the FAS_MEM_COPY () macro below. So don't do that!
- X */
- X unchar *tmp_srcptr, *tmp_destptr;
- X uint num_save;
- X uint xmit_ring_cnt;
- X int old_level;
- X
- X for (;;)
- X {
- X /* determine how many characters we have to copy */
- X {
- X register struct fas_internals *fip REG_SI;
- X register struct tty *ttyp REG_DI;
- X register uint num_to_xfer REG_BX;
- X
- X old_level = SPLWRK ();
- X fip = fipp;
- X ttyp = fip->tty;
- X
- X /* Check if tbuf is empty. If it is empty, reset buffer
- X pointer and counter and get the next chunk of output
- X characters.
- X */
- X if (!ttyp->t_tbuf.c_ptr || !ttyp->t_tbuf.c_count)
- X {
- X if (ttyp->t_tbuf.c_ptr)
- X ttyp->t_tbuf.c_ptr -= ttyp->t_tbuf.c_size;
- X if (!((*linesw [(unchar) ttyp->t_line].l_output) (ttyp)
- X & CPRES))
- X {
- X (void) splx (old_level);
- X return;
- X }
- X }
- X
- X /* Return if transmitter ring buffer is full. */
- X if (fip->xmit_ring_size <= (xmit_ring_cnt = fip->xmit_ring_cnt))
- X {
- X (void) splx (old_level);
- X return;
- X }
- X
- X /* set the maximum character limit */
- X num_to_xfer = fip->xmit_ring_size - xmit_ring_cnt;
- X
- X /* Determine how many chars to transfer this time. */
- X if (ttyp->t_tbuf.c_count < num_to_xfer)
- X num_to_xfer = ttyp->t_tbuf.c_count;
- X if ((uint) (&fip->xmit_buffer [XMIT_BUFF_SIZE]
- X - fip->xmit_ring_put_ptr)
- X < num_to_xfer)
- X num_to_xfer = &fip->xmit_buffer [XMIT_BUFF_SIZE]
- X - fip->xmit_ring_put_ptr;
- X if (!num_to_xfer)
- X {
- X /* invalid count, shouldn't happen */
- X (void) splx (old_level);
- X return;
- X }
- X
- X fip->flow_flags |= FF_OUTPUT_BUSY;
- X tmp_srcptr = (unchar *) ttyp->t_tbuf.c_ptr;
- X ttyp->t_tbuf.c_ptr += num_to_xfer;
- X ttyp->t_tbuf.c_count -= num_to_xfer;
- X tmp_destptr = fip->xmit_ring_put_ptr;
- X if ((fip->xmit_ring_put_ptr += num_to_xfer)
- X == &fip->xmit_buffer [XMIT_BUFF_SIZE])
- X fip->xmit_ring_put_ptr = &fip->xmit_buffer [0];
- X num_save = num_to_xfer;
- X }
- X
- X /* now copy from the clist buffer to the ring buffer */
- X FAS_MEM_COPY (tmp_destptr, tmp_srcptr, num_save);
- X
- X (void) splx (old_level);
- X fipp->xmit_ring_cnt += num_save;
- X }
- X}
- X
- X/* Handle hangup after last close.
- X (called via timeout () at an OS dependent SPL)
- X*/
- XSTATIC void
- Xfas_hangup (fip)
- Xregister struct fas_internals *fip REG_SI;
- X{
- X int old_level;
- X
- X old_level = SPLINT ();
- X
- X if (fip->device_flags & DF_DO_HANGUP)
- X {
- X /* do the hangup */
- X MCR &= ~(fip->modem.m.ei | fip->modem.m.eo);
- X FAS_FIRST_OUTB (fip, MDM_CTL_PORT, MCR |= fip->modem.m.di);
- X fip->device_flags &= ~DF_DO_HANGUP;
- X (void) timeout (fas_hangup, (caddr_t) fip,
- X (HANGUP_TIME) * (HZ) / 1000);
- X }
- X else
- X {
- X /* If there was a waiting dialin process on this
- X port, reopen the physical device.
- X */
- X if (fip->o_state & OS_WAIT_OPEN)
- X {
- X /* allow pending tty interrupts */
- X (void) SPLWRK ();
- X (void) SPLINT ();
- X
- X fas_open_device (fip);
- X
- X /* allow pending tty interrupts */
- X (void) SPLWRK ();
- X (void) SPLINT ();
- X }
- X RELEASE_DEVICE_LOCK (fip);
- X }
- X
- X (void) splx (old_level);
- X}
- X
- X/* Main timeout function.
- X (called via timeout () at an OS dependent SPL)
- X*/
- XSTATIC void
- Xfas_timeout (fip)
- Xregister struct fas_internals *fip REG_SI;
- X{
- X int old_level;
- X
- X old_level = SPLINT ();
- X
- X /* handle break request */
- X if (fip->device_flags & DF_DO_BREAK)
- X {
- X /* set up break request flags */
- X FAS_FIRST_OUTB (fip, LINE_CTL_PORT,
- X LCR |= LC_SET_BREAK_LEVEL);
- X fip->device_flags &= ~(DF_DO_BREAK | DF_GUARD_TIMEOUT);
- X (void) timeout (fas_timeout, (caddr_t) fip,
- X (BREAK_TIME) * (HZ) / 1000);
- X (void) splx (old_level);
- X return;
- X }
- X
- X /* reset break state */
- X if ((fip->device_flags & DF_XMIT_BREAK)
- X && (LCR & LC_SET_BREAK_LEVEL))
- X {
- X FAS_FIRST_OUTB (fip, LINE_CTL_PORT, LCR &= ~LC_SET_BREAK_LEVEL);
- X fip->device_flags |= DF_GUARD_TIMEOUT;
- X fip->timeout_idx = timeout (fas_timeout, (caddr_t) fip,
- X fas_speed_ptr [BT_SELECT]
- X [fip->cflag & CBAUD]
- X .i.ctime);
- X (void) splx (old_level);
- X return;
- X }
- X
- X fip->device_flags &= ~(DF_GUARD_TIMEOUT | DF_XMIT_BREAK);
- X
- X /* restart output */
- X fas_xproc (fip);
- X
- X if ((fip->flow_flags & FF_OUTPUT_BUSY)
- X && !fip->xmit_ring_cnt
- X && !(fip->device_flags & DF_XMIT_BUSY))
- X {
- X fip->flow_flags &= ~FF_OUTPUT_BUSY;
- X fip->tty->t_state &= ~BUSY;
- X /* check half duplex output flow control */
- X if ((fip->flow_flags & (FF_HDX_HANDSHAKE | FF_HDX_STARTED))
- X == (FF_HDX_HANDSHAKE | FF_HDX_STARTED))
- X {
- X FAS_FIRST_OUTB (fip, MDM_CTL_PORT,
- X MCR &= ~fip->flow.m.hc);
- X fip->flow_flags &= ~FF_HDX_STARTED;
- X }
- X EVENT_SCHED (fip, EF_DO_XXFER);
- X }
- X
- X (void) wakeup ((caddr_t) &(fip)->device_flags);
- X (void) splx (old_level);
- X}
- X
- X/* Re-enable receiver data interrupts.
- X (called at SPLINT)
- X*/
- XSTATIC void
- Xfas_rdi_enable (fip)
- Xregister struct fas_internals *fip REG_SI;
- X{
- X /* flush receiver register */
- X if (DEVICE_TYPE == TYPE_NS16550A)
- X FAS_FIRST_OUTB (fip, NS_FIFO_CTL_PORT, FCR | NS_FIFO_CLR_RECV);
- X else if (DEVICE_TYPE == TYPE_I82510)
- X {
- X FAS_FIRST_OUTB (fip, I_BANK_PORT, I_BANK_1);
- X FAS_OUTB (fip, I_RCM_PORT, I_FIFO_CLR_RECV);
- X FAS_OUTB (fip, I_BANK_PORT, I_BANK_0);
- X }
- X (void) FAS_FIRST_INB (fip, RCV_DATA_PORT);
- X if (FAS_INB (fip, LINE_STATUS_PORT) & LS_RCV_AVAIL)
- X (void) FAS_INB (fip, RCV_DATA_PORT);
- X
- X FAS_OUTB (fip, INT_ENABLE_PORT, IER |= IE_RECV_DATA_AVAILABLE);
- X fip->device_flags |= DF_RDI_ENABLED;
- X}
- X
- X/* Start software input flow control.
- X (called at SPLINT)
- X*/
- XSTATIC void
- Xfas_send_xon (fip)
- Xregister struct fas_internals *fip REG_SI;
- X{
- X fip->flow_flags &= ~FF_SWI_STOPPED;
- X fip->flow_flags ^= FF_SW_FC_REQ;
- X if (fip->flow_flags & FF_SW_FC_REQ)
- X {
- X if (fip->flow_flags & FF_CARRIER_ON)
- X {
- X /* start input */
- X fip->flow_flags |= FF_OUTPUT_BUSY;
- X fip->tty->t_state |= TTXON | BUSY;
- X /* check half duplex output flow control */
- X if ((fip->flow_flags & (FF_HDX_HANDSHAKE | FF_HDX_STARTED))
- X == FF_HDX_HANDSHAKE)
- X {
- X FAS_FIRST_OUTB (fip, MDM_CTL_PORT,
- X MCR |= fip->flow.m.hc);
- X fip->flow_flags |= FF_HDX_STARTED;
- X }
- X fas_xproc (fip);
- X }
- X else
- X fip->flow_flags &= ~FF_SW_FC_REQ;
- X }
- X else
- X {
- X /* there is a yet unprocessed request for XOFF, so
- X we just cancel it and don't need to send an XON
- X */
- X fip->tty->t_state &= ~TTXOFF;
- X if ((fip->flow_flags & FF_OUTPUT_BUSY)
- X && !fip->xmit_ring_cnt
- X && !(fip->device_flags
- X & (DF_XMIT_BUSY
- X | DF_GUARD_TIMEOUT
- X | DF_XMIT_BREAK)))
- X {
- X fip->flow_flags &= ~FF_OUTPUT_BUSY;
- X fip->tty->t_state &= ~BUSY;
- X /* check half duplex output flow control */
- X if ((fip->flow_flags & (FF_HDX_HANDSHAKE
- X | FF_HDX_STARTED))
- X == (FF_HDX_HANDSHAKE | FF_HDX_STARTED))
- X {
- X FAS_FIRST_OUTB (fip, MDM_CTL_PORT,
- X MCR &= ~fip->flow.m.hc);
- X fip->flow_flags &= ~FF_HDX_STARTED;
- X }
- X EVENT_SCHED (fip, EF_DO_XXFER);
- X }
- X }
- X}
- X
- X/* Stop software input flow control.
- X (called at SPLINT)
- X*/
- XSTATIC void
- Xfas_send_xoff (fip)
- Xregister struct fas_internals *fip REG_SI;
- X{
- X fip->flow_flags |= FF_SWI_STOPPED;
- X fip->flow_flags ^= FF_SW_FC_REQ;
- X if (fip->flow_flags & FF_SW_FC_REQ)
- X {
- X if (fip->flow_flags & FF_CARRIER_ON)
- X {
- X /* stop input */
- X fip->flow_flags |= FF_OUTPUT_BUSY;
- X fip->tty->t_state |= TTXOFF | BUSY;
- X /* check half duplex output flow control */
- X if ((fip->flow_flags & (FF_HDX_HANDSHAKE | FF_HDX_STARTED))
- X == FF_HDX_HANDSHAKE)
- X {
- X FAS_FIRST_OUTB (fip, MDM_CTL_PORT,
- X MCR |= fip->flow.m.hc);
- X fip->flow_flags |= FF_HDX_STARTED;
- X }
- X fas_xproc (fip);
- X }
- X else
- X fip->flow_flags &= ~FF_SW_FC_REQ;
- X }
- X else
- X {
- X /* there is a yet unprocessed request for XON, so
- X we just cancel it and don't need to send an XOFF
- X */
- X fip->tty->t_state &= ~TTXON;
- X if ((fip->flow_flags & FF_OUTPUT_BUSY)
- X && !fip->xmit_ring_cnt
- X && !(fip->device_flags
- X & (DF_XMIT_BUSY
- X | DF_GUARD_TIMEOUT
- X | DF_XMIT_BREAK)))
- X {
- X fip->flow_flags &= ~FF_OUTPUT_BUSY;
- X fip->tty->t_state &= ~BUSY;
- X /* check half duplex output flow control */
- X if ((fip->flow_flags & (FF_HDX_HANDSHAKE
- X | FF_HDX_STARTED))
- X == (FF_HDX_HANDSHAKE | FF_HDX_STARTED))
- X {
- X FAS_FIRST_OUTB (fip, MDM_CTL_PORT,
- X MCR &= ~fip->flow.m.hc);
- X fip->flow_flags &= ~FF_HDX_STARTED;
- X }
- X EVENT_SCHED (fip, EF_DO_XXFER);
- X }
- X }
- X}
- X
- X/* Compute the port access control value. */
- XSTATIC uint
- Xfas_make_ctl_val (fip, unit, num)
- Xregister struct fas_internals *fip REG_SI;
- Xuint unit;
- Xuint num;
- X{
- X register uint val REG_DI;
- X register uint mask REG_BX;
- X uint i;
- X
- X if (fip->device_flags & DF_CTL_FIRST)
- X return (fas_ctl_val [unit]);
- X
- X if (fip->device_flags & DF_CTL_EVERY)
- X {
- X for (i = 8, mask = fas_ctl_val [unit],
- X val = fas_ctl_val [unit] << 8; i; --i)
- X {
- X if (mask & 0x100)
- X {
- X if (num & 0x01)
- X val ^= 0x100;
- X num >>= 1;
- X }
- X mask >>= 1;
- X val >>= 1;
- X }
- X return (val);
- X }
- X return (0);
- X}
- X
- X/* Initialize memory with zeros. */
- XSTATIC void
- Xfas_mem_zero (ptr, size)
- Xregister unchar *ptr REG_SI;
- Xuint size;
- X{
- X register unchar *limptr REG_DI;
- X
- X for (limptr = ptr + size; ptr < limptr; ++ptr)
- X *ptr = 0;
- X}
- X
- X/* Test device thoroughly. */
- XSTATIC uint
- Xfas_test_device (fip)
- Xregister struct fas_internals *fip REG_SI;
- X{
- X register unchar *cptr REG_DI;
- X uint baud_rate, test_rate;
- X ulong max_rate;
- X uint errcode;
- X register uint delay_count REG_BX;
- X uint rep_count, i;
- X n_unchar lsr, msr;
- X static uint lcrval [3] =
- X {
- X LC_WORDLEN_8,
- X LC_WORDLEN_8 | LC_ENABLE_PARITY,
- X LC_WORDLEN_8 | LC_ENABLE_PARITY | LC_EVEN_PARITY
- X };
- X
- X /* find fastest baud rate for this port */
- X max_rate = 0L;
- X for (test_rate = baud_rate = B0 + 1; baud_rate <= CBAUD; ++baud_rate)
- X if (fas_baud_ptr [BT_SELECT] [baud_rate] > max_rate)
- X {
- X max_rate = fas_baud_ptr [BT_SELECT] [baud_rate];
- X test_rate = baud_rate;
- X }
- X
- X /* make sure FIFO is off */
- X FAS_FIRST_OUTB (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);
- X FAS_OUTB (fip, I_BANK_PORT, I_BANK_2);
- X FAS_OUTB (fip, I_IDM_PORT, I_FIFO_CLEAR_CMD);
- X FAS_OUTB (fip, I_BANK_PORT, I_BANK_0);
- X
- X /* set counter divisor */
- X FAS_OUTB (fip, LINE_CTL_PORT, LC_ENABLE_DIVISOR);
- X FAS_OUTB (fip, DIVISOR_LSB_PORT, fas_speed_ptr [BT_SELECT]
- X [test_rate].div.b.low);
- X FAS_OUTB (fip, DIVISOR_MSB_PORT, fas_speed_ptr [BT_SELECT]
- X [test_rate].div.b.high);
- X FAS_OUTB (fip, LINE_CTL_PORT, 0);
- X
- X /* switch to local loopback */
- X FAS_OUTB (fip, MDM_CTL_PORT, MC_SET_LOOPBACK);
- X
- X errcode = 0;
- X
- X /* wait until the transmitter register is empty */
- X FAS_EVERY_CTL (fip, LINE_STATUS_PORT);
- X for (delay_count = TEST_DELAY_LOOPS;
- X delay_count && (~FAS_SAME_INB (fip, LINE_STATUS_PORT)
- X & (LS_XMIT_AVAIL | LS_XMIT_COMPLETE));
- X --delay_count)
- X ;
- X
- X if (!delay_count)
- X errcode = 1;
- X
- X if (!errcode)
- X {
- X /* clear flags */
- X (void) FAS_INB (fip, RCV_DATA_PORT);
- X (void) FAS_SAME_INB (fip, RCV_DATA_PORT);
- X (void) FAS_INB (fip, LINE_STATUS_PORT);
- X
- X /* make sure there are no more characters in the
- X receiver register
- X */
- X FAS_EVERY_CTL (fip, LINE_STATUS_PORT);
- X for (delay_count = TEST_DELAY_LOOPS;
- X delay_count && !(FAS_SAME_INB (fip, LINE_STATUS_PORT)
- X & LS_RCV_AVAIL);
- X --delay_count)
- X ;
- X
- X if (delay_count)
- X (void) FAS_INB (fip, RCV_DATA_PORT);
- X
- X for (rep_count = TEST_CHAR_LOOPS; rep_count; --rep_count)
- X {
- X for (i = 0; i < 3; ++i)
- X {
- X /* test pattern */
- X cptr = (unchar *) "\377\125\252\045\244\0\0";
- X
- X /* check LSR flags */
- X if (FAS_INB (fip, LINE_STATUS_PORT)
- X != (LS_XMIT_AVAIL | LS_XMIT_COMPLETE))
- X {
- X errcode = 2;
- X break;
- X }
- X
- X /* test transmitter and receiver
- X with different line settings
- X */
- X FAS_OUTB (fip, LINE_CTL_PORT, lcrval [i]);
- X
- X /* send first test pattern */
- X FAS_OUTB (fip, XMT_DATA_PORT, *cptr);
- X
- X /* wait until the transmitter holding register
- X is empty
- X */
- X FAS_EVERY_CTL (fip, LINE_STATUS_PORT);
- X for (delay_count = TEST_DELAY_LOOPS;
- X delay_count
- X && !((lsr = FAS_SAME_INB (fip,
- X LINE_STATUS_PORT))
- X & LS_XMIT_AVAIL);
- X --delay_count)
- X ;
- X
- X if (!delay_count)
- X {
- X errcode = 3;
- X break;
- X }
- X
- X /* check LSR flags */
- X if (lsr != LS_XMIT_AVAIL)
- X {
- X errcode = 2;
- X break;
- X }
- X
- X do
- X {
- X if (*cptr)
- X {
- X /* send next test pattern */
- X FAS_OUTB (fip, XMT_DATA_PORT, *(cptr + 1));
- X
- X /* check LSR flags */
- X if (FAS_INB (fip, LINE_STATUS_PORT))
- X {
- X errcode = 2;
- X break;
- X }
- X }
- X
- X /* wait until the test pattern is received */
- X FAS_EVERY_CTL (fip, LINE_STATUS_PORT);
- X for (delay_count = TEST_DELAY_LOOPS;
- X delay_count
- X && !((lsr = FAS_SAME_INB (fip,
- X LINE_STATUS_PORT))
- X & LS_RCV_AVAIL);
- X --delay_count)
- X ;
- X
- X if (!delay_count)
- X {
- X errcode = 4;
- X break;
- X }
- X
- X /* check LSR flags */
- X if ((lsr & LS_RCV_INT) != LS_RCV_AVAIL)
- X {
- X errcode = 5;
- X break;
- X }
- X
- X /* check test pattern */
- X if (FAS_INB (fip, RCV_DATA_PORT) != *cptr)
- X {
- X errcode = 6;
- X break;
- X }
- X
- X /* check LSR flags */
- X if (FAS_INB (fip, LINE_STATUS_PORT)
- X & LS_RCV_INT)
- X {
- X errcode = 5;
- X break;
- X }
- X
- X /* wait until the transmitter register
- X is empty
- X */
- X if (*cptr)
- X {
- X FAS_EVERY_CTL (fip, LINE_STATUS_PORT);
- X for (delay_count = TEST_DELAY_LOOPS;
- X delay_count
- X && !((lsr = FAS_SAME_INB (fip,
- X LINE_STATUS_PORT))
- X & LS_XMIT_AVAIL);
- X --delay_count)
- X ;
- X
- X if (!delay_count)
- X {
- X errcode = 7;
- X break;
- X }
- X
- X /* check LSR flags */
- X if (lsr != LS_XMIT_AVAIL)
- X {
- X errcode = 8;
- X break;
- X }
- X }
- X else
- X {
- X FAS_EVERY_CTL (fip, LINE_STATUS_PORT);
- X for (delay_count = TEST_DELAY_LOOPS;
- X delay_count
- X && !((lsr = FAS_SAME_INB (fip,
- X LINE_STATUS_PORT))
- X & LS_XMIT_COMPLETE);
- X --delay_count)
- X ;
- X
- X if (!delay_count)
- X {
- X errcode = 7;
- X break;
- X }
- X
- X /* check LSR flags */
- X if (lsr != (LS_XMIT_AVAIL
- X | LS_XMIT_COMPLETE))
- X {
- X errcode = 8;
- X break;
- X }
- X }
- X } while (*((ushort *) (cptr++)));
- X
- X if (errcode)
- X break;
- X }
- X
- X if (errcode)
- X break;
- X }
- X }
- X
- X if (!errcode)
- X {
- X /* clear delta bits */
- X (void) FAS_INB (fip, MDM_STATUS_PORT);
- X
- X for (rep_count = TEST_CTL_LOOPS; rep_count; --rep_count)
- X {
- X /* test pattern */
- X cptr = (unchar *) "\005\142\012\237\006\130\011\257\017\361\0\017\0\0";
- X
- X for (; *((ushort *) cptr); cptr += 2)
- X {
- X /* test modem control and status lines */
- X FAS_OUTB (fip, MDM_CTL_PORT, *cptr | MC_SET_LOOPBACK);
- X
- X /* wait for delta flags */
- X FAS_EVERY_CTL (fip, MDM_STATUS_PORT);
- X for (delay_count = TEST_DELAY_LOOPS;
- X delay_count
- X && !((msr = FAS_SAME_INB (fip,
- X MDM_STATUS_PORT))
- X & MS_ANY_DELTA);
- X --delay_count)
- X ;
- X
- X if (!delay_count)
- X {
- X errcode = 9;
- X break;
- X }
- X
- X /* check MSR flags */
- X if (msr != *(cptr + 1))
- X {
- X errcode = 9;
- X break;
- X }
- X
- X /* check whether delta flags are cleared */
- X if (FAS_SAME_INB (fip, MDM_STATUS_PORT)
- X != (msr & ~MS_ANY_DELTA))
- X {
- X errcode = 9;
- X break;
- X }
- X }
- X
- X if (errcode)
- X break;
- X }
- X }
- X
- X /* switch back to normal operation */
- X FAS_OUTB (fip, MDM_CTL_PORT, 0);
- X
- X return (errcode);
- X}
- X
- X#if defined (NEED_PUT_GETCHAR)
- Xint
- XFASPUTCHAR (arg)
- Xunchar arg;
- X{
- X register struct fas_internals *fip REG_SI;
- X
- X if (!fas_is_initted)
- X fasinit ();
- X
- X fip = &fas_internals [0];
- X if (fip->device_flags & DF_DEVICE_CONFIGURED)
- X {
- X if (arg == '\n')
- X (void) FASPUTCHAR ('\r');
- X FAS_CTL (fip, LINE_STATUS_PORT);
- X while (!(FAS_SAME_INB (fip, LINE_STATUS_PORT) & LS_XMIT_AVAIL))
- X ;
- X FAS_OUTB (fip, XMT_DATA_PORT, arg);
- X }
- X return (0);
- X}
- X
- Xint
- XFASGETCHAR ()
- X{
- X register struct fas_internals *fip REG_SI;
- X
- X if (!fas_is_initted)
- X fasinit ();
- X
- X fip = &fas_internals [0];
- X if ((fip->device_flags & DF_DEVICE_CONFIGURED)
- X && (FAS_FIRST_INB (fip, LINE_STATUS_PORT) & LS_RCV_AVAIL))
- X return (FAS_INB (fip, RCV_DATA_PORT));
- X else
- X return (-1);
- X}
- X#endif
- X
- X#if defined (NEED_INIT8250)
- X/* Reset the requested port to be used directly by a DOS process.
- X (DosMerge only)
- X*/
- Xint
- Xinit8250 (port, ier)
- Xregister ushort port REG_BX;
- Xushort ier; /* ier not used in this stub */
- X{
- X register struct fas_internals *fip REG_SI;
- X register uint unit REG_DI;
- X int old_level;
- X
- X /* See if the port address matches a port that is used by
- X the FAS driver.
- X */
- X for (unit = 0; unit < fas_physical_units; ++unit)
- X if (port == fas_port [unit])
- X break;
- X
- X if (unit >= fas_physical_units)
- X return (-1); /* port didn't match */
- X
- X fip = fas_internals_ptr [unit];
- X
- X old_level = SPLINT ();
- X
- X FAS_FIRST_OUTB (fip, INT_ENABLE_PORT, IER = IE_NONE);
- X fip->device_flags &= ~(DF_RDI_ENABLED | DF_MSI_ENABLED | DF_MSI_NOISE);
- X
- X FAS_OUTB (fip, MDM_CTL_PORT, MCR &= ~(fip->flow.m.ic | fip->flow.m.hc));
- X
- X if (DEVICE_TYPE == TYPE_NS16550A)
- X FAS_OUTB (fip, NS_FIFO_CTL_PORT, NS_FIFO_CLEAR_CMD);
- X else if (DEVICE_TYPE == TYPE_I82510)
- X {
- X FAS_OUTB (fip, I_BANK_PORT, I_BANK_1);
- X FAS_OUTB (fip, I_TCM_PORT, I_FIFO_CLR_XMIT);
- X FAS_OUTB (fip, I_RCM_PORT, I_FIFO_CLR_RECV);
- X FAS_OUTB (fip, I_BANK_PORT, I_BANK_2);
- X FAS_OUTB (fip, I_IDM_PORT, I_FIFO_CLEAR_CMD);
- X FAS_OUTB (fip, I_BANK_PORT, I_BANK_0);
- X }
- X
- X (void) FAS_INB (fip, MDM_STATUS_PORT);
- X (void) FAS_INB (fip, RCV_DATA_PORT);
- X if (FAS_INB (fip, LINE_STATUS_PORT) & LS_RCV_AVAIL)
- X (void) FAS_INB (fip, RCV_DATA_PORT);
- X (void) FAS_INB (fip, INT_ID_PORT);
- X (void) splx (old_level);
- X return (0);
- X}
- X#endif
- SHAR_EOF
- echo 'File fas.c is complete' &&
- true || echo 'restore of fas.c failed'
- rm -f _shar_wnt_.tmp
- fi
- # ============= fas.h ==============
- if test -f 'fas.h' -a X"$1" != X"-c"; then
- echo 'x - skipping fas.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting fas.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'fas.h' &&
- X/* This file contains various defines for the FAS async driver.
- X If you change anything here you have to recompile the driver module.
- X*/
- X
- X#if !defined (M_I286)
- X#ident "@(#)fas.h 2.11"
- X#endif
- X
- X/* Uncomment the following line if you need (asy|sio)putchar and
- X (asy|sio)getchar. This is only required if you link the kernel
- X without the original asy or sio driver and these functions aren't
- X provided by any other kernel module.
- X*/
- X/* #define NEED_PUT_GETCHAR /* */
- X
- X/* Uncomment the following line if you have VP/ix support in the
- X kernel.
- X*/
- X#define HAVE_VPIX /* */
- X
- X/* Uncomment the following line if there is a tunable `ttyhog' variable
- X in the kernel.
- X*/
- X#define TUNABLE_TTYHOG /* */
- X
- X/* Uncomment the following line if you want FAS to make sure that the
- X thresholds in tthiwat [] and ttlowat [] are high enough to prevent
- X the CLIST buffer functions to become a bottleneck at high baud rates.
- X tthiwat [] and ttlowat [] are global resources and are used by other
- X tty drivers as well, so in case that fixing these values causes
- X problems with these drivers this feature is configurable.
- X*/
- X#define FIX_TTHILOWAT /* */
- X
- X/* Uncomment the following line if you need init8250. DosMerge needs
- X this function, but only if you link the kernel without the original
- X asy or sio driver.
- X*/
- X/* #define NEED_INIT8250 /* */
- X
- X/* Initial line control register. This value will only be meaningful if
- X NEED_PUT_GETCHAR is defined.
- X*/
- X#define INITIAL_LINE_CONTROL LC_WORDLEN_8
- X
- X/* Initial baud rate. This value will only be meaningful if
- X NEED_PUT_GETCHAR is defined.
- X*/
- X#define INITIAL_BAUD_RATE B9600
- X
- X/* Initial modem control register. This should probably not have to
- X be touched. It is here because some terminals used as the console
- X require one or more of the modem signals set. It is only meaningful
- X if NEED_PUT_GETCHAR is defined.
- X*/
- X#define INITIAL_MDM_CONTROL 0
- X
- X/****************************************************/
- X/* Nothing past this line should have to be changed */
- X/****************************************************/
- X
- X/* The following section is, if necessary, automatically updated with
- X OS dependent informations. Don't change it by hand!
- X*/
- X/* @@OS_DEP_BEGIN@@ */
- X/* @@OS_DEP_END@@ */
- X
- X#if defined (VPIX)
- X#undef VPIX
- X#endif
- X
- X#if defined (HAVE_VPIX)
- X#define VPIX
- X#endif
- X
- X#if defined (SCO) && !defined (_NO_PROTOTYPE)
- X#define _NO_PROTOTYPE 1
- X#endif
- X
- X#include <sys/param.h>
- X#include <sys/types.h>
- X#include <sys/signal.h>
- X#include <sys/buf.h>
- X#include <sys/dir.h>
- X#if defined (XENIX)
- X#include <sys/page.h>
- X#include <sys/seg.h>
- X#endif
- X#include <sys/user.h>
- X#include <sys/errno.h>
- X#include <sys/tty.h>
- X#include <sys/conf.h>
- X#include <sys/sysinfo.h>
- X#include <sys/file.h>
- X#if !defined (XENIX)
- X#include <sys/termio.h>
- X#endif
- X#if defined (SCO) || defined (XENIX)
- X#include <sys/select.h>
- X#endif
- X#include <sys/ioctl.h>
- X#if defined (HAVE_VPIX)
- X#if !defined (XENIX)
- X#include <sys/tss.h>
- X#include <sys/immu.h>
- X#include <sys/region.h>
- X#endif
- X#include <sys/proc.h>
- X#include <sys/v86.h>
- X#endif
- X
- X#if defined (XENIX)
- Xtypedef unsigned char unchar;
- Xtypedef unsigned long ulong;
- X/*
- X** Union for use by all device handler ioctl routines.
- X*/
- Xunion ioctl_arg {
- X struct termio *stparg; /* ptr to termio struct */
- X char *cparg; /* ptr to character */
- X char carg; /* character */
- X int *iparg; /* ptr to integer */
- X int iarg; /* integer */
- X long *lparg; /* ptr to long */
- X long larg; /* long */
- X};
- X#endif
- X
- X#if defined (__GNUC__)
- X/* in expressions GNU C is able to use operand sizes < native integer size */
- Xtypedef unchar n_unchar;
- X#else
- X/* in expressions AT&T C extends smaller types to the native integer size */
- Xtypedef uint n_unchar;
- X#endif
- X
- X/* allow function prototypes in ANSI C */
- X#if defined (__STDC__)
- X#define P(x) x
- X#else
- X#define P(x) ()
- X#endif
- X
- X#if defined (TRUE)
- X#undef TRUE
- X#endif
- X#define TRUE (1)
- X
- X#if defined (FALSE)
- X#undef FALSE
- X#endif
- X#define FALSE (0)
- X
- Xtypedef int bool;
- X
- X#define MAX_UNITS 16 /* max. number of physical units */
- X#define MAX_BAUD_TABLES 256 /* max. number of baud rate tables */
- X#define NUM_UART_REGS 7 /* number of UART registers */
- X
- X/* Miscellaneous Constants */
- X
- X#define HANGUP_DELAY 500 /* in milli-seconds */
- X#define HANGUP_TIME 1000 /* in milli-seconds */
- X#define BREAK_TIME 250 /* in milli-seconds */
- X#define MAX_EVENT_TIME 10 /* in milli-seconds */
- X#define MAX_RXFER_DELAY 20 /* in milli-seconds */
- X#if defined (M_I286)
- X#define RECV_BUFF_SIZE 1000 /* receiver ring buffer size (MAX) */
- X#define SW_LOW_WATER 500 /* 50% MAX sw flow control */
- X#define SW_HIGH_WATER 800 /* 80% MAX trigger levels */
- X#define HW_LOW_WATER 700 /* MAX - 300 hw flow control */
- X#define HW_HIGH_WATER 900 /* MAX - 100 trigger levels */
- X#define XMIT_BUFF_SIZE 500 /* transmitter ring buffer size */
- X#else
- X#define RECV_BUFF_SIZE 10000 /* receiver ring buffer size (MAX) */
- X#define SW_LOW_WATER 5000 /* 50% MAX sw flow control */
- X#define SW_HIGH_WATER 8000 /* 80% MAX trigger levels */
- X#define HW_LOW_WATER 8500 /* MAX - 1500 hw flow control */
- X#define HW_HIGH_WATER 9500 /* MAX - 500 trigger levels */
- X#define XMIT_BUFF_SIZE 10000 /* transmitter ring buffer size */
- X#endif
- X#define SOFT_INIT 0 /* init registers if cflag changed */
- X#define HARD_INIT 1 /* init registers w/o checking cflag */
- X#define TEST_CHAR_LOOPS 100 /* no. of character test loops */
- X#define TEST_CTL_LOOPS 1000 /* no. of control line test loops */
- X#define TEST_DELAY_LOOPS 60000 /* no. of delay loops */
- X#if defined (SCO) || defined (XENIX)
- X#define SPLWRK spl5 /* SPL for character processing */
- X#define SPLINT spl7 /* SPL to disable FAS interrupts */
- X#else
- X#define SPLWRK spl6 /* SPL for character processing */
- X#define SPLINT spltty /* SPL to disable FAS interrupts */
- X#endif
- X
- X/* calculate EVENT_TIME from MAX_EVENT_TIME with regard to the
- X clock tick granularity
- X*/
- X#define EVENT_TIME ((((MAX_EVENT_TIME) * (HZ) / 1000)\
- X * 1000 + (HZ) - 1) / (HZ))
- X#if EVENT_TIME == 0
- X#undef EVENT_TIME
- X#define EVENT_TIME ((1000 + (HZ) - 1) / (HZ))
- X#endif
- X
- X#if MAX_RXFER_DELAY < EVENT_TIME
- X#undef MAX_RXFER_DELAY
- X#define MAX_RXFER_DELAY EVENT_TIME
- X#endif
- X
- X#define MAX_INPUT_FIFO_SIZE INPUT_NS_FIFO_SIZE
- X#define MAX_OUTPUT_FIFO_SIZE OUTPUT_NS_FIFO_SIZE
- X
- X
- X/* Here are the modem control flags for the fas_modem array in space.c.
- X They are arranged in three 8-bit masks which are combined to a 32-bit
- X word. Each of these 32-bit words represents one entry in the fas_modem
- X array.
- X
- X The lowest byte is used as a mask to manipulate the modem control
- X register for modem disable. Use the MC_* macros to build the mask.
- X
- X The second lowest byte is used as a mask to manipulate the modem control
- X register for modem enable during dialout. Use the MC_* macros to build
- X the mask and shift them 8 bits to the left.
- X
- X The second highest byte is used as a mask to manipulate the modem control
- X register for modem enable during dialin. Use the MC_* macros to build
- X the mask and shift them 16 bits to the left.
- X
- X The highest byte is used to mask signals from the modem status
- X register that will be used as the carrier detect signal. Use the MS_*
- X macros to build the mask and shift them 24 bits to the left. If you use
- X more than one signal, carrier is considered on only when all signals
- X are on.
- X
- X Here are some useful macros for the space.c file. You may create your
- X own macros if you have some special requirements not met by the
- X predefined ones.
- X*/
- X
- X/* modem disable (choose one) */
- X#define DI_RTS ((ulong) MC_SET_RTS)
- X#define DI_DTR ((ulong) MC_SET_DTR)
- X#define DI_RTS_AND_DTR ((ulong) (MC_SET_RTS | MC_SET_DTR))
- X
- X/* modem enable for dialout (choose one) */
- X#define EO_RTS ((ulong) MC_SET_RTS << 8)
- X#define EO_DTR ((ulong) MC_SET_DTR << 8)
- X#define EO_RTS_AND_DTR ((ulong) (MC_SET_RTS | MC_SET_DTR) << 8)
- X
- X/* modem enable for dialin (choose one) */
- X#define EI_RTS ((ulong) MC_SET_RTS << 16)
- X#define EI_DTR ((ulong) MC_SET_DTR << 16)
- X#define EI_RTS_AND_DTR ((ulong) (MC_SET_RTS | MC_SET_DTR) << 16)
- X
- X/* carrier detect signal (choose one) */
- X#define CA_DCD ((ulong) MS_DCD_PRESENT << 24)
- X#define CA_CTS ((ulong) MS_CTS_PRESENT << 24)
- X#define CA_DSR ((ulong) MS_DSR_PRESENT << 24)
- X
- X
- X/* Here are the hardware handshake flags for the fas_flow array in space.c.
- X They are arranged in three 8-bit masks which are combined to a 32-bit
- X word. Each of these 32-bit words represents one entry in the fas_flow
- X array.
- X
- X The lowest byte is used as a mask to manipulate the modem control
- X register for input flow control. Use the MC_* macros to build the mask.
- X
- X The second lowest byte is used to mask signals from the modem status
- X register that will be used for output flow control. Use the MS_* macros
- X to build the mask and shift them 8 bits to the left. If you use more
- X than one signal, output is allowed only when all signals are on.
- X
- X The second highest byte is used to mask signals from the modem status
- X register that will be used to enable the output flow control selected
- X by the second lowest byte. Use the MS_* macros to build the mask and
- X shift them 16 bits to the left. If you use more than one signal, output
- X flow control is enabled only when all signals are on.
- X
- X The highest byte is used as a mask to manipulate the modem control
- X register for output half duplex flow control. Use the MC_* macros to
- X build the mask and shift them 24 bits to the left.
- X
- X Here are some useful macros for the space.c file. You may create your
- X own macros if you have some special requirements not met by the
- X predefined ones.
- X*/
- X
- X/* input flow control (choose one) */
- X#define HI_RTS ((ulong) MC_SET_RTS)
- X#define HI_DTR ((ulong) MC_SET_DTR)
- X#define HI_RTS_AND_DTR ((ulong) (MC_SET_RTS | MC_SET_DTR))
- X
- X/* output flow control (choose one) */
- X#define HO_CTS ((ulong) MS_CTS_PRESENT << 8)
- X#define HO_DSR ((ulong) MS_DSR_PRESENT << 8)
- X#define HO_CTS_AND_DSR ((ulong) (MS_CTS_PRESENT | MS_DSR_PRESENT) \
- X << 8)
- X#define HO_CTS_ON_DSR (((ulong) MS_CTS_PRESENT << 8) \
- X | ((ulong) MS_DSR_PRESENT << 16))
- X#define HO_CTS_ON_DSR_AND_DCD (((ulong) MS_CTS_PRESENT << 8) \
- X | ((ulong) (MS_DSR_PRESENT | MS_DCD_PRESENT) \
- X << 16))
- X
- X/* output hdx flow control (choose one) */
- X#define HX_RTS ((ulong) MC_SET_RTS << 24)
- X#define HX_DTR ((ulong) MC_SET_DTR << 24)
- X#define HX_RTS_AND_DTR ((ulong) (MC_SET_RTS | MC_SET_DTR) << 24)
- X
- X
- X/* define the local open flags */
- X
- X#define OS_DEVICE_CLOSED 0x0000
- X#define OS_OPEN_FOR_DIALOUT 0x0001
- X#define OS_OPEN_FOR_DIALIN 0x0002
- X#define OS_WAIT_OPEN 0x0004
- X#define OS_NO_DIALOUT 0x0008
- X#define OS_FAKE_CARRIER_ON 0x0010
- X#define OS_CLOCAL 0x0020
- X#define OS_HWO_HANDSHAKE 0x0040
- X#define OS_HWI_HANDSHAKE 0x0080
- X#define OS_HDX_HANDSHAKE 0x0100
- X#define OS_EXCLUSIVE_OPEN_1 0x0200
- X#define OS_EXCLUSIVE_OPEN_2 0x0400 /* SYSV 3.2 Xenix compatibility */
- X
- X#define OS_OPEN_STATES (OS_OPEN_FOR_DIALOUT | OS_OPEN_FOR_DIALIN)
- X#define OS_TEST_MASK (OS_OPEN_FOR_DIALOUT | OS_NO_DIALOUT \
- X | OS_FAKE_CARRIER_ON | OS_CLOCAL \
- X | OS_HWO_HANDSHAKE | OS_HWI_HANDSHAKE \
- X | OS_HDX_HANDSHAKE | OS_EXCLUSIVE_OPEN_1 \
- X | OS_EXCLUSIVE_OPEN_2)
- X#define OS_SU_TEST_MASK (OS_OPEN_FOR_DIALOUT | OS_NO_DIALOUT \
- X | OS_FAKE_CARRIER_ON | OS_CLOCAL \
- X | OS_HWO_HANDSHAKE | OS_HWI_HANDSHAKE \
- X | OS_HDX_HANDSHAKE | OS_EXCLUSIVE_OPEN_1)
- X
- X/* define the device status flags */
- X
- X#define DF_CTL_FIRST 0x0001 /* write ctl port at first access */
- X#define DF_CTL_EVERY 0x0002 /* write ctl port at every access */
- X#define DF_XMIT_BUSY 0x0004 /* transmitter busy */
- X#define DF_XMIT_BREAK 0x0008 /* transmitter sends break */
- X#define DF_XMIT_LOCKED 0x0010 /* transmitter locked against output */
- X#define DF_GUARD_TIMEOUT 0x0020 /* protect last char from corruption */
- X#define DF_MSI_NOISE 0x0040 /* modem status interrupts noise */
- X#define DF_MSI_ENABLED 0x0080 /* modem status interrupts enabled */
- X#define DF_RDI_ENABLED 0x0100 /* receiver data interrupts enabled */
- X#define DF_HUP_PROTECT 0x0200 /* protect device after hangup */
- X#define DF_NO_OVERRUN 0x0400 /* device is overrun protected */
- X#define DF_DEVICE_CONFIGURED 0x0800 /* device is configured */
- X#define DF_DEVICE_OPEN 0x1000 /* physical device is open */
- X#define DF_DEVICE_LOCKED 0x2000 /* physical device locked */
- X#define DF_DO_HANGUP 0x4000 /* delayed hangup request */
- X#define DF_DO_BREAK 0x8000 /* delayed break request */
- X
- X/* define the flow control status flags */
- X
- X#define FF_HWO_HANDSHAKE 0x0001 /* output hw handshake enabled */
- X#define FF_HWI_HANDSHAKE 0x0002 /* input hw handshake enabled */
- X#define FF_HDX_HANDSHAKE 0x0004 /* output hdx hw handshake enabled */
- X#define FF_HWO_STOPPED 0x0008 /* output stopped by hw handshake */
- X#define FF_HWI_STARTED 0x0010 /* input started by hw handshake */
- X#define FF_HDX_STARTED 0x0020 /* output buffer contains characters */
- X#define FF_CARR_STOPPED 0x0040 /* output stopped by carrier detect */
- X#define FF_SWO_STOPPED 0x0080 /* output stopped by sw flow control */
- X#define FF_SWI_STOPPED 0x0100 /* input stopped by sw flow control */
- X#define FF_SW_FC_REQ 0x0200 /* sw input flow control request */
- X#define FF_RXFER_STOPPED 0x0400 /* rxfer function stopped */
- X#define FF_NEW_CTSRTS 0x0800 /* CTS/RTSFLOW do fdx hw handshake */
- X#define FF_DEF_HHO_LOW 0x1000 /* hw handshake outp. is low by deflt */
- X#define FF_OUTPUT_BUSY 0x2000 /* output buffers/circuits are busy */
- X#define FF_CD_ENABLED 0x4000 /* carrier detect enabled */
- X#define FF_CARRIER_ON 0x8000 /* carrier detect */
- X
- X/* define the scheduled events flags */
- X
- X#define EF_DO_RXFER 0x0001 /* rxfer function request */
- X#define EF_DO_XXFER 0x0002 /* xxfer function request */
- X#define EF_DO_BRKINT 0x0004 /* break int request */
- X#define EF_DO_MPROC 0x0008 /* mproc function request */
- X#define EF_RESET_DELTA_BITS 0x0010 /* reset accumulated msr delta bits */
- X#define EF_WAKEUP_VPIX 0x0020 /* wakeup VP/ix until rawq is empty */
- X
- X/* define the device types
- X The symbolic constant for the device type that allows the lowest interrupt
- X latency (usually a 16450) has the lowest numerical value. Devices that
- X allow a higher interrupt latency have a higher numerical value. With this
- X ordering the device type can be used as a priority indicator during the
- X interrupt processing, that is, devices that can't hold the received
- X characters for very long are serviced first while devices with FIFOs
- X are serviced only after all devices with higher priority are done.
- X Usually, the following rule applies: The longer the FIFOs, the higher
- X the assigned device type value should be, and the lower the interrupt
- X priority will be.
- X*/
- X
- X#define NUMBER_OF_TYPES 3 /* adjust this to the highest */
- X /* device type + 1 */
- X#define TYPE_NS16450 0
- X#define TYPE_I82510 1
- X#define TYPE_NS16550A 2
- X
- X/* modifier flags that can be set in fas_modify [] (`space.c') */
- X
- X#define NO_TEST 0x0001 /* don't test the UART */
- X#define NO_HUP_PROTECT 0x0002 /* don't protect device after hangup */
- X#define NO_OVERRUN 0x0004 /* device is overrun protected */
- X#define NEW_CTSRTS 0x0008 /* CTS/RTSFLOW do fdx hw handshake */
- X
- X/* read from port rather than write to it (for fas_init_seq [] and
- X fas_int_ack_seq [] in `space.c')
- X*/
- X
- X#define READ_PORT 0x0100
- X
- X/* define the FIFO operating modes for the fas_fifo_ctl array in space.c
- X (FIFO_POINTER_DEV and FIFO_TRIGGER_* apply to NS16550A UART, only)
- X*/
- X
- X#define FIFO_DEFAULT 0 /* default mode (OS dependent) */
- X#define FIFO_OFF 1 /* 16450 compatible mode */
- X#define FIFO_EMUL_NS16450 2 /* emulate 16450 in FIFO mode */
- X#define FIFO_POINTER_DEV 3 /* pointer device (mouse etc.) */
- X#define FIFO_TRIGGER_1 4 /* set trigger level to 1 char */
- X#define FIFO_TRIGGER_4 5 /* set trigger level to 4 chars */
- X#define FIFO_TRIGGER_8 6 /* set trigger level to 8 chars */
- X#define FIFO_TRIGGER_14 7 /* set trigger level to 14 chars */
- X
- X/* define an easy way to reference the port structures */
- X
- X#define RCV_DATA_PORT (fip->port [0])
- X#define XMT_DATA_PORT (fip->port [0])
- X#define INT_ENABLE_PORT (fip->port [1])
- X#define INT_ID_PORT (fip->port [2])
- X#define NS_FIFO_CTL_PORT (fip->port [2])
- X#define I_BANK_PORT (fip->port [2])
- X#define LINE_CTL_PORT (fip->port [3])
- X#define MDM_CTL_PORT (fip->port [4])
- X#define I_IDM_PORT (fip->port [4])
- X#define LINE_STATUS_PORT (fip->port [5])
- X#define I_RCM_PORT (fip->port [5])
- X#define MDM_STATUS_PORT (fip->port [6])
- X#define I_TCM_PORT (fip->port [6])
- X#define DIVISOR_LSB_PORT (fip->port [0])
- X#define DIVISOR_MSB_PORT (fip->port [1])
- X#define CTL_PORT (fip->ctl_port)
- X
- X/* UART related variables */
- X
- X#define BT_SELECT (fip->port [0].p.val)
- X#define IER (fip->port [1].p.val)
- X#define FCR (fip->port [2].p.val)
- X#define LCR (fip->port [3].p.val)
- X#define MCR (fip->port [4].p.val)
- X#define NEW_MSR (fip->port [5].p.val)
- X#define MSR (fip->port [6].p.val)
- X#define DEVICE_TYPE (fip->ctl_port.p.val1)
- X#define INT_PRIO (fip->ctl_port.p.val2)
- X
- X/* modem control port */
- X
- X#define MC_SET_DTR 0x01
- X#define MC_SET_RTS 0x02
- X#define MC_SET_OUT1 0x04
- X#define MC_SET_OUT2 0x08
- X#define MC_SET_LOOPBACK 0x10
- X
- X#define MC_ANY_CONTROL (MC_SET_DTR | MC_SET_RTS | MC_SET_OUT1 | MC_SET_OUT2)
- X
- X/* modem status port */
- X
- X#define MS_CTS_DELTA 0x01
- X#define MS_DSR_DELTA 0x02
- X#define MS_RING_TEDGE 0x04
- X#define MS_DCD_DELTA 0x08
- X#define MS_CTS_PRESENT 0x10
- X#define MS_DSR_PRESENT 0x20
- X#define MS_RING_PRESENT 0x40
- X#define MS_DCD_PRESENT 0x80
- X
- X#define MS_ANY_DELTA (MS_CTS_DELTA | MS_DSR_DELTA | MS_RING_TEDGE \
- X | MS_DCD_DELTA)
- X#define MS_ANY_PRESENT (MS_CTS_PRESENT | MS_DSR_PRESENT | MS_RING_PRESENT \
- X | MS_DCD_PRESENT)
- X
- X/* interrupt enable port */
- X
- X#define IE_NONE 0x00
- X#define IE_RECV_DATA_AVAILABLE 0x01
- X#define IE_XMIT_HOLDING_BUFFER_EMPTY 0x02
- X#define IE_LINE_STATUS 0x04
- X#define IE_MODEM_STATUS 0x08
- X
- X/* interrupt id port */
- X
- X#define II_NO_INTS_PENDING 0x01
- X#define II_CODE_MASK 0x07
- X#define II_MODEM_STATE 0x00
- X#define II_XMTD_CHAR 0x02
- X#define II_RCVD_CHAR 0x04
- X#define II_RCV_ERROR 0x06
- X#define II_NS_FIFO_TIMEOUT 0x08
- X#define II_NS_FIFO_ENABLED 0xC0
- X
- X/* line control port */
- X
- X#define LC_WORDLEN_MASK 0x03
- X#define LC_WORDLEN_5 0x00
- X#define LC_WORDLEN_6 0x01
- X#define LC_WORDLEN_7 0x02
- X#define LC_WORDLEN_8 0x03
- X#define LC_STOPBITS_LONG 0x04
- X#define LC_ENABLE_PARITY 0x08
- X#define LC_EVEN_PARITY 0x10
- X#define LC_STICK_PARITY 0x20
- X#define LC_SET_BREAK_LEVEL 0x40
- X#define LC_ENABLE_DIVISOR 0x80
- X
- X/* line status port */
- X
- X#define LS_RCV_AVAIL 0x01
- X#define LS_OVERRUN 0x02
- X#define LS_PARITY_ERROR 0x04
- X#define LS_FRAMING_ERROR 0x08
- X#define LS_BREAK_DETECTED 0x10
- X#define LS_XMIT_AVAIL 0x20
- X#define LS_XMIT_COMPLETE 0x40
- X#define LS_ERROR_IN_NS_FIFO 0x80 /* NS16550A only */
- X
- X#define LS_RCV_INT (LS_RCV_AVAIL | LS_OVERRUN | LS_PARITY_ERROR \
- X | LS_FRAMING_ERROR | LS_BREAK_DETECTED)
- X
- X/* fifo control port (NS16550A only) */
- X
- X#define NS_FIFO_ENABLE 0x01
- X#define NS_FIFO_CLR_RECV 0x02
- X#define NS_FIFO_CLR_XMIT 0x04
- X#define NS_FIFO_START_DMA 0x08
- X#define NS_FIFO_SIZE_1 0x00
- X#define NS_FIFO_SIZE_4 0x40
- X#define NS_FIFO_SIZE_8 0x80
- X#define NS_FIFO_SIZE_14 0xC0
- X#define NS_FIFO_SIZE_MASK 0xC0
- X
- X#define NS_FIFO_CLEAR_CMD 0
- X#define NS_FIFO_INIT_CMD (NS_FIFO_SIZE_1 | NS_FIFO_ENABLE \
- X | NS_FIFO_CLR_RECV | NS_FIFO_CLR_XMIT)
- X
- X#define INPUT_NS_FIFO_SIZE 16
- X#define OUTPUT_NS_FIFO_SIZE 16
- X
- X/* fifo control ports (i82510 only) */
- X
- X#define I_BANK_0 0x00
- X#define I_BANK_1 0x20
- X#define I_BANK_2 0x40
- X#define I_BANK_3 0x60
- X#define I_FIFO_ENABLE 0x08
- X#define I_FIFO_CLR_RECV 0x30
- X#define I_FIFO_CLR_XMIT 0x0c
- X
- X#define I_FIFO_CLEAR_CMD 0
- X#define I_FIFO_SETUP_CMD I_FIFO_ENABLE
- X
- X#define INPUT_I_FIFO_SIZE 4
- X#define OUTPUT_I_FIFO_SIZE 4
- X
- X/* defines for ioctl calls (VP/ix) */
- X
- X#define AIOC ('A'<<8)
- X#define AIOCINTTYPE (AIOC|60) /* set interrupt type */
- X#define AIOCDOSMODE (AIOC|61) /* set DOS mode */
- X#define AIOCNONDOSMODE (AIOC|62) /* reset DOS mode */
- X#define AIOCSERIALOUT (AIOC|63) /* serial device data write */
- X#define AIOCSERIALIN (AIOC|64) /* serial device data read */
- X#define AIOCSETSS (AIOC|65) /* set start/stop chars */
- X#define AIOCINFO (AIOC|66) /* tell us what device we are */
- X
- X/* ioctl alternate names used by VP/ix */
- X
- X#define VPC_SERIAL_DOS AIOCDOSMODE
- X#define VPC_SERIAL_NONDOS AIOCNONDOSMODE
- X#define VPC_SERIAL_INFO AIOCINFO
- X#define VPC_SERIAL_OUT AIOCSERIALOUT
- X#define VPC_SERIAL_IN AIOCSERIALIN
- X
- X/* serial in/out requests */
- X
- X#define SO_DIVLLSB 1
- X#define SO_DIVLMSB 2
- X#define SO_LCR 3
- X#define SO_MCR 4
- X#define SI_MSR 1
- X#define SIO_MASK(x) (1<<((x)-1))
- X
- X
- X/* This structure contains baud rate dependent informations. */
- X
- Xstruct fas_speed
- X{
- X union {
- X uint ctime; /* kernel clock ticks until xmitter is empty */
- X bool valid; /* the baud rate table contains valid data */
- X } i;
- X union { /* UART counter divisor value */
- X struct {
- X unchar low; /* low byte */
- X unchar high; /* high byte */
- X } b;
- X ushort val;
- X } div;
- X ushort xbuf_size; /* xmit buffer size that fits the baud rate */
- X};
- X
- X
- X/* This structure contains everything one would like to know about
- X an open device. There is one of it for each physical unit.
- X
- X Take care that the size of the area that contains the various
- X structure fields (up to, but excluding the ring buffers)
- X is <= 128 bytes. Otherwise a 4-byte offset is used to access
- X some of the structure fields. For the first 128 bytes a 1-byte
- X offset is used, which is faster.
- X*/
- X
- Xstruct fas_internals
- X{
- X struct tty *tty; /* the tty structure */
- X struct fas_internals *next_int_user; /* link to next struct */
- X struct fas_internals *prev_int_user; /* link to previous struct */
- X uint device_flags; /* flags about the device state */
- SHAR_EOF
- true || echo 'restore of fas.h failed'
- fi
- echo 'End of part 6'
- echo 'File fas.h is continued in part 7'
- echo 7 > _shar_seq_.tmp
- exit 0
-