diff options
author | hm <hm@FreeBSD.org> | 1999-05-20 10:14:57 +0000 |
---|---|---|
committer | hm <hm@FreeBSD.org> | 1999-05-20 10:14:57 +0000 |
commit | 2077acfca034178f39e3fa4e86cb8d371f44737c (patch) | |
tree | 730187a2063473cb0d2e7cac998a9a4307285426 /sys/i4b | |
parent | 5ea75aea8a2633cc0acf9dd870c1e1db1abd6a21 (diff) | |
download | FreeBSD-src-2077acfca034178f39e3fa4e86cb8d371f44737c.zip FreeBSD-src-2077acfca034178f39e3fa4e86cb8d371f44737c.tar.gz |
upgrade isdn4bsd from version 0.71 to the just released version 0.81
Diffstat (limited to 'sys/i4b')
44 files changed, 2602 insertions, 706 deletions
diff --git a/sys/i4b/driver/i4b_ctl.c b/sys/i4b/driver/i4b_ctl.c index 680217e..37a18a9 100644 --- a/sys/i4b/driver/i4b_ctl.c +++ b/sys/i4b/driver/i4b_ctl.c @@ -27,9 +27,9 @@ * i4b_ctl.c - i4b system control port driver * ------------------------------------------ * - * $Id: i4b_ctl.c,v 1.19 1999/02/14 19:51:01 hm Exp $ + * $Id: i4b_ctl.c,v 1.20 1999/04/26 10:16:54 hm Exp $ * - * last edit-date: [Sun Feb 14 10:02:29 1999] + * last edit-date: [Mon Apr 26 11:16:28 1999] * *---------------------------------------------------------------------------*/ @@ -90,7 +90,8 @@ static int openflag = 0; static d_open_t i4bctlopen; static d_close_t i4bctlclose; static d_ioctl_t i4bctlioctl; -#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 + +#ifdef OS_USES_POLL static d_poll_t i4bctlpoll; #endif @@ -98,7 +99,7 @@ static d_poll_t i4bctlpoll; static struct cdevsw i4bctl_cdevsw = { i4bctlopen, i4bctlclose, noread, nowrite, i4bctlioctl, nostop, nullreset, nodevtotty, -#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 +#ifdef OS_USES_POLL i4bctlpoll, nommap, NULL, "i4bctl", NULL, -1 }; #else noselect, nommap, NULL, "i4bctl", NULL, -1 }; @@ -326,15 +327,17 @@ i4bctlioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) #endif DO_I4B_DEBUG } +#if defined(__FreeBSD__) && defined(OS_USES_POLL) + /*---------------------------------------------------------------------------* * i4bctlpoll - device driver poll routine *---------------------------------------------------------------------------*/ -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 static int i4bctlpoll (dev_t dev, int events, struct proc *p) { return (ENODEV); } + #endif #endif /* NI4BCTL > 0 */ diff --git a/sys/i4b/driver/i4b_ipr.c b/sys/i4b/driver/i4b_ipr.c index 9182a54..a427605 100644 --- a/sys/i4b/driver/i4b_ipr.c +++ b/sys/i4b/driver/i4b_ipr.c @@ -27,9 +27,9 @@ * i4b_ipr.c - isdn4bsd IP over raw HDLC ISDN network driver * --------------------------------------------------------- * - * $Id: i4b_ipr.c,v 1.2 1999/03/07 16:08:13 hm Exp $ + * $Id: i4b_ipr.c,v 1.51 1999/05/06 08:24:45 hm Exp $ * - * last edit-date: [Sun Feb 14 10:02:36 1999] + * last edit-date: [Thu May 6 10:09:20 1999] * *---------------------------------------------------------------------------* * @@ -207,12 +207,22 @@ enum ipr_states { ST_CONNECTED_A, /* connected to remote */ }; +#if defined(__FreeBSD__) || defined(__bsdi__) +#define THE_UNIT sc->sc_if.if_unit +#else +#define THE_UNIT sc->sc_unit +#endif + #ifdef __FreeBSD__ #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 # define IOCTL_CMD_T u_long #else +#ifdef __NetBSD__ +# define IOCTL_CMD_T u_long +#else # define IOCTL_CMD_T int #endif +#endif PDEVSTATIC void i4biprattach(void *); PSEUDO_SET(i4biprattach, i4b_ipr); static int i4biprioctl(struct ifnet *ifp, IOCTL_CMD_T cmd, caddr_t data); @@ -571,7 +581,12 @@ i4biprioctl(struct ifnet *ifp, u_long cmd, caddr_t data) case IPRIOCSMAXCID: { struct proc *p = curproc; /* XXX */ + +#if defined(__FreeBSD_version) && __FreeBSD_version >= 400005 if((error = suser(p)) != 0) +#else + if((error = suser(p->p_ucred, &p->p_acflag)) != 0) +#endif return (error); sl_compress_setup(sc->sc_compr, *(int *)data); } @@ -686,15 +701,14 @@ iprwatchdog(struct ifnet *ifp) * start transmitting after connect *---------------------------------------------------------------------------*/ static void -i4bipr_connect_startio(int unit) +i4bipr_connect_startio(struct ipr_softc *sc) { - struct ipr_softc *sc = &ipr_softc[unit]; int s = SPLI4B(); if(sc->sc_state == ST_CONNECTED_W) { sc->sc_state = ST_CONNECTED_A; - ipr_tx_queue_empty(unit); + ipr_tx_queue_empty(THE_UNIT); } splx(s); @@ -748,7 +762,7 @@ ipr_connect(int unit, void *cdp) if(sc->sc_cdp->isdntxdelay > 0) { - timeout((TIMEOUT_FUNC_T)i4bipr_connect_startio, (void *)unit, sc->sc_cdp->isdntxdelay /* hz*1 */); + timeout((TIMEOUT_FUNC_T)i4bipr_connect_startio, (void *)sc, sc->sc_cdp->isdntxdelay /* hz*1 */); } else { @@ -803,13 +817,19 @@ ipr_disconnect(int unit, void *cdp) * in case of dial problems *---------------------------------------------------------------------------*/ static void -ipr_dialresponse(int unit, int status) +ipr_dialresponse(int unit, int status, cause_t cause) { struct ipr_softc *sc = &ipr_softc[unit]; sc->sc_dialresp = status; DBGL4(L4_IPRDBG, "ipr_dialresponse", ("ipr%d: last=%d, this=%d\n", unit, sc->sc_lastdialresp, sc->sc_dialresp)); + + if(status != DSTAT_NONE) + { + DBGL4(L4_IPRDBG, "ipr_dialresponse", ("ipr%d: clearing queues\n", unit)); + iprclearqueues(sc); + } } /*---------------------------------------------------------------------------* @@ -1076,12 +1096,20 @@ ipr_tx_queue_empty(int unit) } #endif x = 1; - - IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m); - sc->sc_if.if_obytes += m->m_pkthdr.len; + if(IF_QFULL(isdn_linktab[unit]->tx_queue)) + { + DBGL4(L4_IPRDBG, "ipr_rx_data_rdy", ("ipr%d: tx queue full!\n", unit)); + m_freem(m); + } + else + { + IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m); - sc->sc_if.if_opackets++; + sc->sc_if.if_obytes += m->m_pkthdr.len; + + sc->sc_if.if_opackets++; + } } if(x) diff --git a/sys/i4b/driver/i4b_isppp.c b/sys/i4b/driver/i4b_isppp.c index 0ea767f..9dc0eff 100644 --- a/sys/i4b/driver/i4b_isppp.c +++ b/sys/i4b/driver/i4b_isppp.c @@ -34,9 +34,9 @@ * the "cx" driver for Cronyx's HDLC-in-hardware device). This driver * is only the glue between sppp and i4b. * - * $Id: i4b_isppp.c,v 1.22 1999/02/14 09:44:55 hm Exp $ + * $Id: i4b_isppp.c,v 1.27 1999/05/03 08:48:25 hm Exp $ * - * last edit-date: [Sun Feb 14 10:02:43 1999] + * last edit-date: [Sun May 2 10:52:57 1999] * *---------------------------------------------------------------------------*/ @@ -63,7 +63,7 @@ #include <net/if_types.h> #include <net/netisr.h> #include <net/route.h> -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) #include <net/if_sppp.h> #else #include <i4b/sppp/if_sppp.h> @@ -83,9 +83,11 @@ #ifdef __FreeBSD__ #include <machine/i4b_ioctl.h> #include <machine/i4b_cause.h> +#include <machine/i4b_debug.h> #else #include <i4b/i4b_ioctl.h> #include <i4b/i4b_cause.h> +#include <i4b/i4b_debug.h> #endif #include <i4b/include/i4b_global.h> @@ -373,11 +375,19 @@ i4bisppp_start(struct ifnet *ifp) microtime(&ifp->if_lastchange); - IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m); + if(IF_QFULL(isdn_linktab[unit]->tx_queue)) + { + DBGL4(L4_ISPDBG, "i4bisppp_start", ("isp%d, tx queue full!\n", unit)); + m_freem(m); + } + else + { + IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m); - sc->sc_if.if_obytes += m->m_pkthdr.len; - sc->sc_outb += m->m_pkthdr.len; - sc->sc_if.if_opackets++; + sc->sc_if.if_obytes += m->m_pkthdr.len; + sc->sc_outb += m->m_pkthdr.len; + sc->sc_if.if_opackets++; + } } isdn_linktab[unit]->bch_tx_start(isdn_linktab[unit]->unit, isdn_linktab[unit]->channel); @@ -553,10 +563,7 @@ i4bisppp_disconnect(int unit, void *cdp) /* new stuff to check that the active channel is being closed */ if (cd != sc->sc_cdp) { -#ifdef I4BISPPPDISCDEBUG - printf("i4bisppp_disconnect: isppp%d channel%d not active\n", - cd->driver_unit, cd->channelid); -#endif + DBGL4(L4_ISPDBG, "i4bisppp_disconnect", ("isp%d, channel%d not active!\n", unit, cd->channelid)); splx(s); return; } @@ -587,9 +594,24 @@ i4bisppp_disconnect(int unit, void *cdp) * in case of dial problems *---------------------------------------------------------------------------*/ static void -i4bisppp_dialresponse(int unit, int status) +i4bisppp_dialresponse(int unit, int status, cause_t cause) { -/* struct i4bisppp_softc *sc = &i4bisppp_softc[unit]; */ + struct i4bisppp_softc *sc = &i4bisppp_softc[unit]; + + DBGL4(L4_ISPDBG, "i4bisppp_dialresponse", ("isp%d: status=%d, cause=%d\n", unit, status, cause)); + + if(status != DSTAT_NONE) + { + struct mbuf *m; + + DBGL4(L4_ISPDBG, "i4bisppp_dialresponse", ("isp%d: clearing queues\n", unit)); + + if(!(sppp_isempty(&sc->sc_if))) + { + while((m = sppp_dequeue(&sc->sc_if)) != NULL) + m_freem(m); + } + } } /*---------------------------------------------------------------------------* diff --git a/sys/i4b/driver/i4b_rbch.c b/sys/i4b/driver/i4b_rbch.c index 02f91fb..42a9f0c 100644 --- a/sys/i4b/driver/i4b_rbch.c +++ b/sys/i4b/driver/i4b_rbch.c @@ -27,9 +27,9 @@ * i4b_rbch.c - device driver for raw B channel data * --------------------------------------------------- * - * $Id: i4b_rbch.c,v 1.25 1999/02/14 19:51:01 hm Exp $ + * $Id: i4b_rbch.c,v 1.31 1999/05/06 13:07:59 hm Exp $ * - * last edit-date: [Sun Feb 14 10:02:49 1999] + * last edit-date: [Thu May 6 13:40:22 1999] * *---------------------------------------------------------------------------*/ @@ -40,18 +40,6 @@ #include <sys/param.h> #include <sys/systm.h> -#if (defined(__FreeBSD_version) && __FreeBSD_version >= 300001) || (!defined(__FreeBSD__) && !defined(__bsdi__)) -#include <sys/ioccom.h> -#include <sys/poll.h> -#else -#include <sys/fcntl.h> -#include <sys/ioctl.h> -#endif - -#if (defined(__FreeBSD_version) && __FreeBSD_version >= 300001) -#include <sys/filio.h> -#endif - #include <sys/conf.h> #include <sys/uio.h> #include <sys/kernel.h> @@ -100,6 +88,19 @@ extern cc_t ttydefchars; int bootverbose = 0; #endif +#ifdef OS_USES_POLL +#include <sys/ioccom.h> +#include <sys/poll.h> +#else +#include <sys/fcntl.h> +#include <sys/ioctl.h> +#endif + +#if (defined(__FreeBSD_version) && __FreeBSD_version >= 300001) +#include <sys/filio.h> +#endif + + static drvr_link_t rbch_drvr_linktab[NI4BRBCH]; static isdn_link_t *isdn_linktab[NI4BRBCH]; @@ -143,7 +144,12 @@ int i4brbchclose __P((dev_t dev, int flag, int fmt, struct proc *p)); int i4brbchread __P((dev_t dev, struct uio *uio, int ioflag)); int i4brbchwrite __P((dev_t dev, struct uio *uio, int ioflag)); int i4brbchioctl __P((dev_t dev, IOCTL_CMD_T cmd, caddr_t arg, int flag, struct proc* pr)); +#ifdef OS_USES_POLL int i4brbchpoll __P((dev_t dev, int events, struct proc *p)); +#else +/* XXX fix "static" to PDEVSTATIC */ +static int i4brbchselect __P((dev_t dev, int rw, struct proc *p)); +#endif #endif #if BSD > 199306 && defined(__FreeBSD__) @@ -160,7 +166,7 @@ PDEVSTATIC d_read_t i4brbchread; PDEVSTATIC d_read_t i4brbchwrite; PDEVSTATIC d_ioctl_t i4brbchioctl; -#if (defined(__FreeBSD_version) && __FreeBSD_version >= 300001) || !defined(__FreeBSD__) +#ifdef OS_USES_POLL PDEVSTATIC d_poll_t i4brbchpoll; #else PDEVSTATIC d_select_t i4brbchselect; @@ -170,7 +176,7 @@ PDEVSTATIC d_select_t i4brbchselect; static struct cdevsw i4brbch_cdevsw = { i4brbchopen, i4brbchclose, i4brbchread, i4brbchwrite, i4brbchioctl, nostop, noreset, nodevtotty, -#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 +#ifdef OS_USES_POLL i4brbchpoll, nommap, NULL, "i4brbch", NULL, -1 #else i4brbchselect, nommap, NULL, "i4brbch", NULL, -1 @@ -486,7 +492,14 @@ i4brbchwrite(dev_t dev, struct uio * uio, int ioflag) error = uiomove(m->m_data, m->m_len, uio); - IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m); + if(IF_QFULL(isdn_linktab[unit]->tx_queue)) + { + m_freem(m); + } + else + { + IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m); + } (*isdn_linktab[unit]->bch_tx_start)(isdn_linktab[unit]->unit, isdn_linktab[unit]->channel); } @@ -556,11 +569,11 @@ if(bootverbose)printf("EE-rbch%d: attempting dialout (DTR)\n", unit); return(error); } +#ifdef OS_USES_POLL + /*---------------------------------------------------------------------------* * device driver poll *---------------------------------------------------------------------------*/ -#if (defined(__FreeBSD_version) && __FreeBSD_version >= 300001) || (!defined(__FreeBSD__) && !defined(__bsdi__)) - PDEVSTATIC int i4brbchpoll(dev_t dev, int events, struct proc *p) { @@ -570,9 +583,6 @@ i4brbchpoll(dev_t dev, int events, struct proc *p) /* We can't check for anything but IN or OUT */ - if((events & (POLLIN|POLLOUT)) == 0) - return(POLLNVAL); - s = splhigh(); if(!(rbch_softc[unit].sc_devstate & ST_ISOPEN)) @@ -586,16 +596,16 @@ i4brbchpoll(dev_t dev, int events, struct proc *p) * transmit queue can take them */ - if((events & POLLOUT) && + if((events & (POLLOUT|POLLWRNORM)) && (rbch_softc[unit].sc_devstate & ST_CONNECTED) && !IF_QFULL(isdn_linktab[unit]->tx_queue)) { - revents |= POLLOUT; + revents |= (events & (POLLOUT|POLLWRNORM)); } /* ... while reads are OK if we have any data */ - if((events & POLLIN) && + if((events & (POLLIN|POLLRDNORM)) && (rbch_softc[unit].sc_devstate & ST_CONNECTED)) { struct ifqueue *iqp; @@ -606,7 +616,7 @@ i4brbchpoll(dev_t dev, int events, struct proc *p) iqp = isdn_linktab[unit]->rx_queue; if(!IF_QEMPTY(iqp)) - revents |= POLLIN; + revents |= (events & (POLLIN|POLLRDNORM)); } if(revents == 0) @@ -616,11 +626,12 @@ i4brbchpoll(dev_t dev, int events, struct proc *p) return(revents); } -#else +#else /* OS_USES_POLL */ /*---------------------------------------------------------------------------* * device driver select *---------------------------------------------------------------------------*/ +/* XXX fix "static" to PDEVSTATIC */ static int i4brbchselect(dev_t dev, int rw, struct proc *p) { @@ -649,23 +660,31 @@ i4brbchselect(dev_t dev, int rw, struct proc *p) iqp = isdn_linktab[unit]->rx_queue; if(!IF_QEMPTY(iqp)) + { + splx(s); return(1); + } break; case FWRITE: if(!IF_QFULL(isdn_linktab[unit]->rx_queue)) + { + splx(s); return(1); + } break; default: + splx(s); return 0; } } selrecord(p, &rbch_softc[unit].selp); + splx(s); return(0); } -#endif /* defined(__FreeBSD_version) && __FreeBSD_version >= 300001 */ +#endif /* OS_USES_POLL */ /*===========================================================================* * ISDN INTERFACE ROUTINES @@ -707,7 +726,7 @@ rbch_disconnect(int unit, void *cdp) * feedback from daemon in case of dial problems *---------------------------------------------------------------------------*/ static void -rbch_dialresponse(int unit, int status) +rbch_dialresponse(int unit, int status, cause_t cause) { } diff --git a/sys/i4b/driver/i4b_tel.c b/sys/i4b/driver/i4b_tel.c index f7cfd5f..a548338 100644 --- a/sys/i4b/driver/i4b_tel.c +++ b/sys/i4b/driver/i4b_tel.c @@ -27,9 +27,9 @@ * i4b_tel.c - device driver for ISDN telephony * -------------------------------------------- * - * $Id: i4b_tel.c,v 1.22 1999/02/16 10:40:18 hm Exp $ + * $Id: i4b_tel.c,v 1.40 1999/05/06 08:24:45 hm Exp $ * - * last edit-date: [Tue Feb 16 11:30:35 1999] + * last edit-date: [Thu May 6 09:30:13 1999] * *---------------------------------------------------------------------------*/ @@ -42,10 +42,12 @@ #include <sys/param.h> #include <sys/systm.h> -#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 +#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 || defined(__NetBSD__) #include <sys/ioccom.h> +#include <sys/poll.h> #else #include <sys/ioctl.h> +#include <sys/fcntl.h> #endif #include <sys/conf.h> @@ -65,37 +67,76 @@ #include <sys/devfsext.h> #endif +#ifdef __bsdi__ +#include <sys/device.h> +#endif + #ifdef __FreeBSD__ #include <machine/i4b_ioctl.h> #include <machine/i4b_tel_ioctl.h> +#include <machine/i4b_debug.h> #else #include <i4b/i4b_ioctl.h> #include <i4b/i4b_tel_ioctl.h> +#include <i4b/i4b_debug.h> #endif #include <i4b/include/i4b_global.h> #include <i4b/include/i4b_mbuf.h> #include <i4b/include/i4b_l3l4.h> +#include <i4b/layer4/i4b_l4.h> + +/* minor number: lower 6 bits = unit number */ + +#include <i4b/layer4/i4b_l4.h> + +#define UNITBITS 6 +#define UNITMASK 0x3f +#define UNIT(n) (minor(n) & UNITMASK) + +/* minor number: upper 2 bits = function number */ + +#define FUNCMASK 0x03 +#define FUNC(n) (((minor(n)) >> UNITBITS) & FUNCMASK) + +#define FUNCTEL 0 /* 0 = normal i4btel device */ +#define FUNCDIAL 1 /* 1 = i4bteld dialout device */ + +#define NOFUNCS 2 /* number of device classes */ + typedef struct { - drvr_link_t drvr_linktab; /* driver linktab */ - isdn_link_t *isdn_linktab; /* isdn linktab */ + + /* used only in func = FUNCTEL */ + + drvr_link_t drvr_linktab; /* driver linktab */ + isdn_link_t *isdn_linktab; /* isdn linktab */ + int audiofmt; /* audio format conversion */ + u_char *rcvttab; /* conversion table on read */ + u_char *wcvttab; /* conversion table on write */ + call_desc_t *cdp; /* call descriptor pointer */ + + /* used only in func = FUNCDIAL */ + + char result; /* result code for dial dev */ + + /* used in func = FUNCDIAL and func = FUNCTEL*/ + int devstate; /* state of this unit */ #define ST_IDLE 0x00 /* idle */ #define ST_CONNECTED 0x01 /* isdn connected state */ #define ST_ISOPEN 0x02 /* userland opened */ #define ST_RDWAITDATA 0x04 /* userland read waiting */ #define ST_WRWAITEMPTY 0x08 /* userland write waiting */ - int audiofmt; /* audio format conversion */ - u_char *rcvttab; /* conversion table on read */ - u_char *wcvttab; /* conversion table on write */ - call_desc_t *cdp; /* call descriptor pointer */ + + struct selinfo selp; /* select / poll */ + #ifdef DEVFS void *devfs_token; /* token for DEVFS */ #endif } tel_sc_t; -static tel_sc_t tel_sc[NI4BTEL]; +static tel_sc_t tel_sc[NI4BTEL][NOFUNCS]; /* forward decl */ @@ -106,48 +147,62 @@ static void tel_connect(int unit, void *cdp); static void tel_disconnect(int unit, void *cdp); /* audio format conversion tables */ -static unsigned char alaw_ulaw[]; -static unsigned char ulaw_alaw[]; +static unsigned char a2u_tab[]; +static unsigned char u2a_tab[]; static unsigned char bitreverse[]; #ifndef __FreeBSD__ #define PDEVSTATIC /* - not static - */ PDEVSTATIC void i4btelattach __P((void)); + #ifdef __bsdi__ PDEVSTATIC int i4btelioctl __P((dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)); #else PDEVSTATIC int i4btelioctl __P((dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)); #endif + int i4btelopen __P((dev_t dev, int flag, int fmt, struct proc *p)); int i4btelclose __P((dev_t dev, int flag, int fmt, struct proc *p)); int i4btelread __P((dev_t dev, struct uio *uio, int ioflag)); int i4btelwrite __P((dev_t dev, struct uio * uio, int ioflag)); + +#ifdef OS_USES_POLL +int i4btelpoll __P((dev_t dev, int events, struct proc *p)); +#else +int i4btelsel __P((dev_t dev, int rw, struct proc *p)); #endif + +#endif /* __FreeBSD__ */ + + #if BSD > 199306 && defined(__FreeBSD__) + #define PDEVSTATIC static PDEVSTATIC d_open_t i4btelopen; PDEVSTATIC d_close_t i4btelclose; PDEVSTATIC d_read_t i4btelread; PDEVSTATIC d_read_t i4btelwrite; PDEVSTATIC d_ioctl_t i4btelioctl; -#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 +#ifdef OS_USES_POLL PDEVSTATIC d_poll_t i4btelpoll; +#else +PDEVSTATIC d_select_t i4btelsel; #endif #define CDEV_MAJOR 56 static struct cdevsw i4btel_cdevsw = { i4btelopen, i4btelclose, i4btelread, i4btelwrite, i4btelioctl, nostop, noreset, nodevtotty, -#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 +#ifdef OS_USES_POLL i4btelpoll, nommap, NULL, "i4btel", NULL, -1 #else - noselect, nommap, NULL, "i4btel", NULL, -1 + i4btelsel, nommap, NULL, "i4btel", NULL, -1 #endif }; PDEVSTATIC void i4btelinit(void *unused); - PDEVSTATIC void i4btelattach(void *); + PSEUDO_SET(i4btelattach, i4b_tel); /*===========================================================================* @@ -173,7 +228,8 @@ SYSINIT(i4bteldev, SI_SUB_DRIVERS, #endif /* BSD > 199306 && defined(__FreeBSD__) */ #ifdef __bsdi__ -#include <sys/device.h> + +int i4btelsel(dev_t dev, int rw, struct proc *p); int i4btelmatch(struct device *parent, struct cfdata *cf, void *aux); void dummy_i4btelattach(struct device*, struct device *, void *); @@ -185,21 +241,23 @@ static struct cfdriver i4btelcd = struct devsw i4btelsw = { &i4btelcd, i4btelopen, i4btelclose, i4btelread, i4btelwrite, - i4btelioctl, seltrue, nommap, nostrat, + i4btelioctl, i4btelsel, nommap, nostrat, nodump, nopsize, 0, nostop }; int i4btelmatch(struct device *parent, struct cfdata *cf, void *aux) { - printf("i4btelmatch: aux=0x%x\n", aux); + DBGL4(L4_TELDBG, "i4btelmatch", ("aux=0x%x\n", aux)); return 1; } + void dummy_i4btelattach(struct device *parent, struct device *self, void *aux) { - printf("dummy_i4btelattach: aux=0x%x\n", aux); + DBGL4(L4_TELDBG, "dummy_i4btelattach", ("aux=0x%x\n", aux)); } + #endif /* __bsdi__ */ /*---------------------------------------------------------------------------* @@ -212,7 +270,7 @@ i4btelattach(void *dummy) i4btelattach() #endif { - int i; + int i, j; #ifndef HACK_NO_PSEUDO_ATTACH_MSG printf("i4btel: %d ISDN telephony interface device(s) attached\n", NI4BTEL); @@ -220,17 +278,22 @@ i4btelattach() for(i=0; i < NI4BTEL; i++) { - tel_sc[i].devstate = ST_IDLE; - tel_sc[i].audiofmt = CVT_NONE; - tel_sc[i].rcvttab = 0; - tel_sc[i].wcvttab = 0; - tel_init_linktab(i); + for(j=0; j < NOFUNCS; j++) + { + tel_sc[i][j].devstate = ST_IDLE; + tel_sc[i][j].audiofmt = CVT_NONE; + tel_sc[i][j].rcvttab = 0; + tel_sc[i][j].wcvttab = 0; + tel_sc[i][j].result = 0; + tel_init_linktab(i); #ifdef DEVFS - tel_sc[i].devfs_token - = devfs_add_devswf(&i4btel_cdevsw, i, DV_CHR, + +/* XXX */ tel_sc[i][j].devfs_token + = devfs_add_devswf(&i4btel_cdevsw, i, DV_CHR, UID_ROOT, GID_WHEEL, 0600, "i4btel%d", i); #endif + } } } @@ -240,19 +303,26 @@ i4btelattach() PDEVSTATIC int i4btelopen(dev_t dev, int flag, int fmt, struct proc *p) { - int unit = minor(dev); + int unit = UNIT(dev); + int func = FUNC(dev); + tel_sc_t *sc; if(unit > NI4BTEL) return(ENXIO); - sc = &tel_sc[unit]; + sc = &tel_sc[unit][func]; if(sc->devstate & ST_ISOPEN) return(EBUSY); sc->devstate |= ST_ISOPEN; + if(func == FUNCDIAL) + { + sc->result = 0; + } + return(0); } @@ -262,16 +332,18 @@ i4btelopen(dev_t dev, int flag, int fmt, struct proc *p) PDEVSTATIC int i4btelclose(dev_t dev, int flag, int fmt, struct proc *p) { - int unit = minor(dev); + int unit = UNIT(dev); + int func = FUNC(dev); tel_sc_t *sc; int error = 0; if(unit > NI4BTEL) return(ENXIO); - sc = &tel_sc[unit]; + sc = &tel_sc[unit][func]; - if(sc->isdn_linktab != NULL && sc->isdn_linktab->tx_queue != NULL) + if((func == FUNCTEL) && + (sc->isdn_linktab != NULL && sc->isdn_linktab->tx_queue != NULL)) { while(!(IF_QEMPTY(sc->isdn_linktab->tx_queue))) { @@ -285,7 +357,9 @@ i4btelclose(dev_t dev, int flag, int fmt, struct proc *p) } sc->devstate &= ~ST_WRWAITEMPTY; } + sc->devstate &= ~ST_ISOPEN; + return(error); } @@ -301,57 +375,76 @@ i4btelioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) i4btelioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) #endif { + int unit = UNIT(dev); + int func = FUNC(dev); int error = 0; struct mbuf *m; int s; - tel_sc_t *sc = &tel_sc[minor(dev)]; - switch(cmd) - { - case I4B_TEL_GETAUDIOFMT: - *(int *)data = sc->audiofmt; - break; - - case I4B_TEL_SETAUDIOFMT: - switch (*(int *)data) - { - case CVT_NONE: - sc->rcvttab = 0; - sc->wcvttab = 0; - break; - case CVT_ALAW2ULAW: - sc->rcvttab = alaw_ulaw; - sc->wcvttab = ulaw_alaw; - break; - case CVT_ALAW_CANON: - sc->rcvttab = bitreverse; - sc->wcvttab = bitreverse; - break; - default: - error = ENODEV; - break; - } - if(error == 0) - sc->audiofmt = *(int *)data; - break; - - case I4B_TEL_EMPTYINPUTQUEUE: - s = splimp(); - while((sc->devstate & ST_CONNECTED) && - (sc->devstate & ST_ISOPEN) && - !IF_QEMPTY(sc->isdn_linktab->rx_queue)) - { - IF_DEQUEUE(sc->isdn_linktab->rx_queue, m); - if(m) - i4b_Bfreembuf(m); - } - splx(s); - break; + tel_sc_t *sc = &tel_sc[unit][func]; - default: - error = ENOTTY; - break; + if(func == FUNCTEL) + { + switch(cmd) + { + case I4B_TEL_GETAUDIOFMT: + *(int *)data = sc->audiofmt; + break; + + case I4B_TEL_SETAUDIOFMT: + switch (*(int *)data) + { + case CVT_NONE: + sc->rcvttab = 0; + sc->wcvttab = 0; + break; + case CVT_ALAW2ULAW: + /* ISDN: a-law */ + /* user: u-law */ + sc->rcvttab = a2u_tab; + sc->wcvttab = u2a_tab; + break; + case CVT_ULAW2ALAW: + /* ISDN: u-law */ + /* user: a-law */ + sc->rcvttab = u2a_tab; + sc->wcvttab = a2u_tab; + break; + default: + error = ENODEV; + break; + } + if(error == 0) + sc->audiofmt = *(int *)data; + break; + + case I4B_TEL_EMPTYINPUTQUEUE: + s = splimp(); + while((sc->devstate & ST_CONNECTED) && + (sc->devstate & ST_ISOPEN) && + !IF_QEMPTY(sc->isdn_linktab->rx_queue)) + { + IF_DEQUEUE(sc->isdn_linktab->rx_queue, m); + if(m) + i4b_Bfreembuf(m); + } + splx(s); + break; + + default: + error = ENOTTY; + break; + } } + else if(func == FUNCDIAL) + { + switch(cmd) + { + default: + error = ENOTTY; + break; + } + } return(error); } @@ -361,187 +454,380 @@ i4btelioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) PDEVSTATIC int i4btelread(dev_t dev, struct uio *uio, int ioflag) { + int unit = UNIT(dev); + int func = FUNC(dev); + struct mbuf *m; int s; int error = 0; - tel_sc_t *sc = &tel_sc[minor(dev)]; - -#ifdef notdef -/* - * XXX - * With this code enabled, one cannot set or get the audio format - * while not connected. -*/ - if(!(sc->devstate & ST_CONNECTED)) - return(EIO); -#endif + tel_sc_t *sc = &tel_sc[unit][func]; + if(!(sc->devstate & ST_ISOPEN)) return(EIO); -#ifdef NOTDEF - while(!(sc->devstate & ST_CONNECTED)) + if(func == FUNCTEL) { - if((error = tsleep((caddr_t) &sc->devstate, - TTIPRI | PCATCH, - "rrtel", 0 )) != 0) + while(IF_QEMPTY(sc->isdn_linktab->rx_queue) && + (sc->devstate & ST_ISOPEN) && + (sc->devstate & ST_CONNECTED)) { - return(error); + sc->devstate |= ST_RDWAITDATA; + + DBGL4(L4_TELDBG, "i4btelread", ("i4btel%d, queue empty!\n", unit)); + + if((error = tsleep((caddr_t) &sc->isdn_linktab->rx_queue, + TTIPRI | PCATCH, + "rtel", 0 )) != 0) + { + sc->devstate &= ~ST_RDWAITDATA; + return(error); + } } - } -#endif + + if(!(sc->devstate & ST_ISOPEN)) + { + return(EIO); + } + + if(!(sc->devstate & ST_CONNECTED)) + { + return(EIO); + } + + s = splimp(); + + IF_DEQUEUE(sc->isdn_linktab->rx_queue, m); + + if(m && m->m_len > 0) + { + register int i; + + for(i = 0; i < m->m_len; i++) + { + /* always reverse bit order from line */ + mtod(m,u_char *)[i] = bitreverse[mtod(m,u_char *)[i]]; + + /* convert if necessary */ + if(sc->rcvttab) + mtod(m,u_char *)[i] = sc->rcvttab[mtod(m,u_char *)[i]]; + } + error = uiomove(m->m_data, m->m_len, uio); - while(IF_QEMPTY(sc->isdn_linktab->rx_queue) && - (sc->devstate & ST_ISOPEN) && - (sc->devstate & ST_CONNECTED)) + DBGL4(L4_TELDBG, "i4btelread", ("i4btel%d, mbuf (%d bytes), uiomove %d!\n", unit, m->m_len, error)); + } + else + { + DBGL4(L4_TELDBG, "i4btelread", ("i4btel%d, empty mbuf from queue!\n", unit)); + error = EIO; + } + + if(m) + i4b_Bfreembuf(m); + + splx(s); + } + else if(func == FUNCDIAL) { - sc->devstate |= ST_RDWAITDATA; + while((sc->result == 0) && (sc->devstate & ST_ISOPEN)) + { + sc->devstate |= ST_RDWAITDATA; + + if((error = tsleep((caddr_t) &sc->result, + TTIPRI | PCATCH, + "rtel1", 0 )) != 0) + { + sc->devstate &= ~ST_RDWAITDATA; + return(error); + } + } + + if(!(sc->devstate & ST_ISOPEN)) + { + return(EIO); + } + + s = splimp(); - if((error = tsleep((caddr_t) &sc->isdn_linktab->rx_queue, - TTIPRI | PCATCH, - "rtel", 0 )) != 0) + if(sc->result != 0) { - sc->devstate &= ~ST_RDWAITDATA; - return(error); + error = uiomove(&sc->result, 1, uio); + sc->result = 0; } + else + { + error = EIO; + } + + splx(s); } + return(error); +} +/*---------------------------------------------------------------------------* + * write to tel device + *---------------------------------------------------------------------------*/ +PDEVSTATIC int +i4btelwrite(dev_t dev, struct uio * uio, int ioflag) +{ + int unit = UNIT(dev); + int func = FUNC(dev); + struct mbuf *m; + int s; + int error = 0; + tel_sc_t *sc = &tel_sc[unit][func]; + if(!(sc->devstate & ST_ISOPEN)) { return(EIO); } - if(!(sc->devstate & ST_CONNECTED)) + if(func == FUNCTEL) { - return(EIO); - } + if(!(sc->devstate & ST_CONNECTED)) + return(EIO); + + while((IF_QFULL(sc->isdn_linktab->tx_queue)) && + (sc->devstate & ST_ISOPEN)) + { + sc->devstate |= ST_WRWAITEMPTY; + + if((error = tsleep((caddr_t) &sc->isdn_linktab->tx_queue, + TTIPRI | PCATCH, "wtel", 0)) != 0) + { + sc->devstate &= ~ST_WRWAITEMPTY; + return(error); + } + } - s = splimp(); + if(!(sc->devstate & ST_ISOPEN)) + { + return(EIO); + } + + if(!(sc->devstate & ST_CONNECTED)) + { + return(EIO); + } - IF_DEQUEUE(sc->isdn_linktab->rx_queue, m); + s = splimp(); + + if((m = i4b_Bgetmbuf(BCH_MAX_DATALEN)) != NULL) + { + register int i; + + m->m_len = min(BCH_MAX_DATALEN, uio->uio_resid); + + error = uiomove(m->m_data, m->m_len, uio); + + for(i = 0; i < m->m_len; i++) + { + /* convert if necessary */ + if(sc->wcvttab) + mtod(m,u_char *)[i] = sc->wcvttab[mtod(m,u_char *)[i]]; - if(m && m->m_len > 0) + /* always reverse bitorder to line */ + mtod(m,u_char *)[i] = bitreverse[mtod(m,u_char *)[i]]; + } + + if(IF_QFULL(sc->isdn_linktab->tx_queue)) + { + m_freem(m); + } + else + { + IF_ENQUEUE(sc->isdn_linktab->tx_queue, m); + } + + (*sc->isdn_linktab->bch_tx_start)(sc->isdn_linktab->unit, sc->isdn_linktab->channel); + } + + splx(s); + } + else if(func == FUNCDIAL) { - if(sc->rcvttab) +#define CMDBUFSIZ 80 + char cmdbuf[CMDBUFSIZ]; + int len = min(CMDBUFSIZ-1, uio->uio_resid); + + error = uiomove(cmdbuf, len, uio); + + if(cmdbuf[0] == CMD_DIAL) { - int i; - for(i = 0; i < m->m_len; i++) - mtod(m,u_char *)[i] = sc->rcvttab[mtod(m,u_char *)[i]]; - } - error = uiomove(m->m_data, m->m_len, uio); + i4b_l4_dialoutnumber(BDRV_TEL, unit, len-1, &cmdbuf[1]); + } + else if(cmdbuf[0] == CMD_HUP) + { + i4b_l4_drvrdisc(BDRV_TEL, unit); + } } else { error = EIO; - } - - if(m) - i4b_Bfreembuf(m); - - splx(s); - + } + return(error); } +#ifdef OS_USES_POLL /*---------------------------------------------------------------------------* - * write to tel device + * device driver poll *---------------------------------------------------------------------------*/ PDEVSTATIC int -i4btelwrite(dev_t dev, struct uio * uio, int ioflag) +i4btelpoll(dev_t dev, int events, struct proc *p) { - struct mbuf *m; + int revents = 0; /* Events we found */ int s; - int error = 0; - tel_sc_t *sc = &tel_sc[minor(dev)]; + int unit = UNIT(dev); + int func = FUNC(dev); + + tel_sc_t *sc = &tel_sc[unit][func]; - if(!(sc->devstate & ST_CONNECTED)) - return(EIO); + s = splhigh(); if(!(sc->devstate & ST_ISOPEN)) { - return(EIO); + DBGL4(L4_TELDBG, "i4btelpoll", ("i4btel%d, !ST_ISOPEN\n", unit)); + splx(s); + return(0); } -#ifdef NOTDEF - while(!(sc->devstate & ST_CONNECTED)) + if(func == FUNCTEL) { - if((error = tsleep((caddr_t) &sc->devstate, - TTIPRI | PCATCH, - "wrtel", 0 )) != 0) - { - return(error); - } - /* - * XXX the originations B channel gets much earlier - * switched thru than the destinations B channel, so - * if the origination starts to send at once, some - * 200 bytes (at my site) or so get lost, so i delay - * a bit before sending. (-hm) + * Writes are OK if we are connected and the + * transmit queue can take them */ + + if((events & (POLLOUT|POLLWRNORM)) && + (sc->devstate & ST_CONNECTED) && + (sc->isdn_linktab != NULL) && + (!IF_QFULL(sc->isdn_linktab->tx_queue))) + { + DBGL4(L4_TELDBG, "i4btelpoll", ("i4btel%d, POLLOUT\n", unit)); + revents |= (events & (POLLOUT|POLLWRNORM)); + } - tsleep((caddr_t) &sc->devstate, TTIPRI | PCATCH, "xtel", (hz*1)); + /* ... while reads are OK if we have any data */ + + if((events & (POLLIN|POLLRDNORM)) && + (sc->devstate & ST_CONNECTED) && + (sc->isdn_linktab != NULL) && + (!IF_QEMPTY(sc->isdn_linktab->rx_queue))) + { + DBGL4(L4_TELDBG, "i4btelpoll", ("i4btel%d, POLLIN\n", unit)); + revents |= (events & (POLLIN|POLLRDNORM)); + } + + if(revents == 0) + { + DBGL4(L4_TELDBG, "i4btelpoll", ("i4btel%d, selrecord\n", unit)); + selrecord(p, &sc->selp); + } } -#endif - - while((IF_QFULL(sc->isdn_linktab->tx_queue)) && - (sc->devstate & ST_ISOPEN)) + else if(func == FUNCDIAL) { - sc->devstate |= ST_WRWAITEMPTY; + if(events & (POLLOUT|POLLWRNORM)) + { + DBGL4(L4_TELDBG, "i4btelpoll", ("i4bteld%d, POLLOUT\n", unit)); + revents |= (events & (POLLOUT|POLLWRNORM)); + } - if((error = tsleep((caddr_t) &sc->isdn_linktab->tx_queue, - TTIPRI | PCATCH, "wtel", 0)) != 0) + if(events & (POLLIN|POLLRDNORM)) + { + DBGL4(L4_TELDBG, "i4btelpoll", ("i4bteld%d, POLLIN, result = %d\n", unit, sc->result)); + if(sc->result != 0) + revents |= (events & (POLLIN|POLLRDNORM)); + } + + if(revents == 0) { - sc->devstate &= ~ST_WRWAITEMPTY; - return(error); + DBGL4(L4_TELDBG, "i4btelpoll", ("i4bteld%d, selrecord\n", unit)); + selrecord(p, &sc->selp); } } + splx(s); + return(revents); +} - if(!(sc->devstate & ST_ISOPEN)) - { - return(EIO); - } +#else /* OS_USES_POLL */ - if(!(sc->devstate & ST_CONNECTED)) - { - return(EIO); - } +/*---------------------------------------------------------------------------* + * device driver select + *---------------------------------------------------------------------------*/ +PDEVSTATIC int +i4btelsel(dev_t dev, int rw, struct proc *p) +{ + int s; + int unit = UNIT(dev); + int func = FUNC(dev); - s = splimp(); + tel_sc_t *sc = &tel_sc[unit][func]; + + s = splhigh(); - if((m = i4b_Bgetmbuf(BCH_MAX_DATALEN)) != NULL) + if (!(sc->devstate & ST_ISOPEN)) { - m->m_len = min(BCH_MAX_DATALEN, uio->uio_resid); + DBGL4(L4_TELDBG, "i4btelsel", ("i4btel%d, !ST_ISOPEN\n", unit)); + splx(s); + return(0); + } - error = uiomove(m->m_data, m->m_len, uio); + if (func == FUNCTEL) + { + /* Don't even bother if we're not connected */ + if (!(sc->devstate & ST_CONNECTED) || sc->isdn_linktab == NULL) + { + splx(s); + return 0; + } - if(sc->wcvttab) + if (rw == FREAD) { - int i; - for(i = 0; i < m->m_len; i++) - mtod(m,u_char *)[i] = sc->wcvttab[mtod(m,u_char *)[i]]; - } - - IF_ENQUEUE(sc->isdn_linktab->tx_queue, m); + if (!IF_QEMPTY(sc->isdn_linktab->rx_queue)) + { + DBGL4(L4_TELDBG, "i4btelsel", ("i4btel%d, FREAD\n", unit)); + splx(s); + return 1; + } + } + else if (rw == FWRITE) + { + if (!IF_QFULL(sc->isdn_linktab->tx_queue)) + { + DBGL4(L4_TELDBG, "i4btelsel", ("i4btel%d, FWRITE\n", unit)); + splx(s); + return 1; + } + } + } + else if (func == FUNCDIAL) + { + if (rw == FWRITE) + { + DBGL4(L4_TELDBG, "i4btelsel", ("i4bteld%d, FWRITE\n", unit)); + splx(s); + return 1; + } - (*sc->isdn_linktab->bch_tx_start)(sc->isdn_linktab->unit, sc->isdn_linktab->channel); + if (rw == FREAD) + { + DBGL4(L4_TELDBG, "i4btelsel", ("i4bteld%d, FREAD, result = %d\n", unit, sc->result)); + if (sc->result != 0) + { + splx(s); + return 1; + } + } } + DBGL4(L4_TELDBG, "i4btelsel", ("i4bteld%d, selrecord\n", unit)); + selrecord(p, &sc->selp); splx(s); - - return(error); + return 0; } -/*---------------------------------------------------------------------------* - * poll - *---------------------------------------------------------------------------*/ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 -PDEVSTATIC int -i4btelpoll (dev_t dev, int events, struct proc *p) -{ - return (ENODEV); -} -#endif +#endif /* OS_USES_POLL */ /*===========================================================================* * ISDN INTERFACE ROUTINES @@ -553,19 +839,29 @@ i4btelpoll (dev_t dev, int events, struct proc *p) static void tel_connect(int unit, void *cdp) { - tel_sc_t *sc = &tel_sc[unit]; + tel_sc_t *sc = &tel_sc[unit][FUNCTEL]; + /* audio device */ + sc->cdp = (call_desc_t *)cdp; -#ifdef NOTDEF - if(!(sc->devstate & ST_CONNECTED)) + sc->devstate |= ST_CONNECTED; + + /* dialer device */ + + sc = &tel_sc[unit][FUNCDIAL]; + + if(sc->devstate == ST_ISOPEN) { - sc->devstate |= ST_CONNECTED; - wakeup((caddr_t) &sc->devstate); + sc->result = RSP_CONN; + + if(sc->devstate & ST_RDWAITDATA) + { + sc->devstate &= ~ST_RDWAITDATA; + wakeup((caddr_t) &sc->result); + } + selwakeup(&sc->selp); } -#else - sc->devstate |= ST_CONNECTED; -#endif } /*---------------------------------------------------------------------------* @@ -576,8 +872,10 @@ tel_disconnect(int unit, void *cdp) { /* call_desc_t *cd = (call_desc_t *)cdp; */ - tel_sc_t *sc = &tel_sc[unit]; - + tel_sc_t *sc = &tel_sc[unit][FUNCTEL]; + + /* audio device */ + sc->devstate &= ~ST_CONNECTED; if(sc->devstate & ST_RDWAITDATA) @@ -591,14 +889,45 @@ tel_disconnect(int unit, void *cdp) sc->devstate &= ~ST_WRWAITEMPTY; wakeup((caddr_t) &sc->isdn_linktab->tx_queue); } + + /* dialer device */ + + sc = &tel_sc[unit][FUNCDIAL]; + + if(sc->devstate == ST_ISOPEN) + { + sc->result = RSP_HUP; + + if(sc->devstate & ST_RDWAITDATA) + { + sc->devstate &= ~ST_RDWAITDATA; + wakeup((caddr_t) &sc->result); + } + selwakeup(&sc->selp); + } } /*---------------------------------------------------------------------------* * feedback from daemon in case of dial problems *---------------------------------------------------------------------------*/ static void -tel_dialresponse(int unit, int status) -{ +tel_dialresponse(int unit, int status, cause_t cause) +{ + tel_sc_t *sc = &tel_sc[unit][FUNCDIAL]; + + DBGL4(L4_TELDBG, "tel_dialresponse", ("i4btel%d, status=%d, cause=0x%4x\n", unit, status, cause)); + + if((sc->devstate == ST_ISOPEN) && status) + { + sc->result = RSP_NOA; + + if(sc->devstate & ST_RDWAITDATA) + { + sc->devstate &= ~ST_RDWAITDATA; + wakeup((caddr_t) &sc->result); + } + selwakeup(&sc->selp); + } } /*---------------------------------------------------------------------------* @@ -617,13 +946,14 @@ tel_updown(int unit, int updown) static void tel_rx_data_rdy(int unit) { - tel_sc_t *sc = &tel_sc[unit]; + tel_sc_t *sc = &tel_sc[unit][FUNCTEL]; if(sc->devstate & ST_RDWAITDATA) { sc->devstate &= ~ST_RDWAITDATA; wakeup((caddr_t) &sc->isdn_linktab->rx_queue); } + selwakeup(&sc->selp); } /*---------------------------------------------------------------------------* @@ -634,13 +964,14 @@ tel_rx_data_rdy(int unit) static void tel_tx_queue_empty(int unit) { - tel_sc_t *sc = &tel_sc[unit]; + tel_sc_t *sc = &tel_sc[unit][FUNCTEL]; if(sc->devstate & ST_WRWAITEMPTY) { sc->devstate &= ~ST_WRWAITEMPTY; wakeup((caddr_t) &sc->isdn_linktab->tx_queue); } + selwakeup(&sc->selp); } /*---------------------------------------------------------------------------* @@ -650,7 +981,8 @@ tel_tx_queue_empty(int unit) static void tel_activity(int unit, int rxtx) { - tel_sc[unit].cdp->last_active_time = SECOND; + if(tel_sc[unit][FUNCTEL].cdp) + tel_sc[unit][FUNCTEL].cdp->last_active_time = SECOND; } /*---------------------------------------------------------------------------* @@ -659,7 +991,7 @@ tel_activity(int unit, int rxtx) drvr_link_t * tel_ret_linktab(int unit) { - tel_sc_t *sc = &tel_sc[unit]; + tel_sc_t *sc = &tel_sc[unit][FUNCTEL]; tel_init_linktab(unit); return(&sc->drvr_linktab); @@ -671,7 +1003,7 @@ tel_ret_linktab(int unit) void tel_set_linktab(int unit, isdn_link_t *ilt) { - tel_sc_t *sc = &tel_sc[unit]; + tel_sc_t *sc = &tel_sc[unit][FUNCTEL]; sc->isdn_linktab = ilt; } @@ -681,7 +1013,7 @@ tel_set_linktab(int unit, isdn_link_t *ilt) static void tel_init_linktab(int unit) { - tel_sc_t *sc = &tel_sc[unit]; + tel_sc_t *sc = &tel_sc[unit][FUNCTEL]; sc->drvr_linktab.unit = unit; sc->drvr_linktab.bch_rx_data_ready = tel_rx_data_rdy; @@ -694,74 +1026,121 @@ tel_init_linktab(int unit) } /*===========================================================================* - * AUDIO FORMAT CONVERSION + * AUDIO FORMAT CONVERSION (produced by running g711conv) *===========================================================================*/ /*---------------------------------------------------------------------------* - * Line format to mu-law conversion + * A-law to u-law conversion *---------------------------------------------------------------------------*/ -static unsigned char alaw_ulaw[256] = { - 0x2a, 0xa9, 0x62, 0xe1, 0x0a, 0x8a, 0x48, 0xc8, 0x39, 0xb9, 0x75, 0xf3, 0x1a, 0x9a, 0x56, 0xd6, - 0x22, 0xa1, 0x5d, 0xdc, 0x02, 0x82, 0x40, 0xc0, 0x31, 0xb1, 0x6a, 0xe9, 0x12, 0x92, 0x4f, 0xcf, - 0x2e, 0xad, 0x66, 0xe5, 0x0e, 0x8e, 0x4c, 0xcc, 0x3d, 0xbd, 0x7d, 0xfb, 0x1e, 0x9e, 0x5a, 0xda, - 0x26, 0xa5, 0x5f, 0xde, 0x06, 0x86, 0x44, 0xc4, 0x35, 0xb5, 0x6e, 0xed, 0x16, 0x96, 0x52, 0xd2, - 0x28, 0xa7, 0x60, 0xdf, 0x08, 0x88, 0x46, 0xc6, 0x37, 0xb7, 0x71, 0xef, 0x18, 0x98, 0x54, 0xd4, - 0x20, 0x9f, 0x5c, 0xdb, 0x00, 0x80, 0x3f, 0xbf, 0x2f, 0xaf, 0x68, 0xe7, 0x10, 0x90, 0x4e, 0xce, - 0x2c, 0xab, 0x64, 0xe3, 0x0c, 0x8c, 0x4a, 0xca, 0x3b, 0xbb, 0x79, 0xf7, 0x1c, 0x9c, 0x58, 0xd8, - 0x24, 0xa3, 0x5e, 0xdd, 0x04, 0x84, 0x42, 0xc2, 0x33, 0xb3, 0x6c, 0xeb, 0x14, 0x94, 0x50, 0xd0, - 0x2b, 0xaa, 0x63, 0xe2, 0x0b, 0x8b, 0x49, 0xc9, 0x3a, 0xba, 0x77, 0xf5, 0x1b, 0x9b, 0x57, 0xd7, - 0x23, 0xa2, 0x5d, 0xdd, 0x03, 0x83, 0x41, 0xc1, 0x32, 0xb2, 0x6b, 0xea, 0x13, 0x93, 0x4f, 0xcf, - 0x2f, 0xae, 0x67, 0xe6, 0x0f, 0x8f, 0x4d, 0xcd, 0x3e, 0xbe, 0xff, 0xfd, 0x1f, 0x9f, 0x5b, 0xdb, - 0x27, 0xa6, 0x5f, 0xdf, 0x07, 0x87, 0x45, 0xc5, 0x36, 0xb6, 0x6f, 0xee, 0x17, 0x97, 0x53, 0xd3, - 0x29, 0xa8, 0x61, 0xe0, 0x09, 0x89, 0x47, 0xc7, 0x38, 0xb8, 0x73, 0xf1, 0x19, 0x99, 0x55, 0xd5, - 0x21, 0xa0, 0x5c, 0xdc, 0x01, 0x81, 0x3f, 0xbf, 0x30, 0xb0, 0x69, 0xe8, 0x11, 0x91, 0x4e, 0xce, - 0x2d, 0xac, 0x65, 0xe4, 0x0d, 0x8d, 0x4b, 0xcb, 0x3c, 0xbc, 0x7b, 0xf9, 0x1d, 0x9d, 0x59, 0xd9, - 0x25, 0xa4, 0x5e, 0xde, 0x05, 0x85, 0x43, 0xc3, 0x34, 0xb4, 0x6d, 0xec, 0x15, 0x95, 0x51, 0xd1 +static unsigned char a2u_tab[256] = { +/* 00 */ 0x2a, 0x2b, 0x28, 0x29, 0x2e, 0x2f, 0x2c, 0x2d, +/* 08 */ 0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25, +/* 10 */ 0x39, 0x3a, 0x37, 0x38, 0x3d, 0x3e, 0x3b, 0x3c, +/* 18 */ 0x31, 0x32, 0x30, 0x30, 0x35, 0x36, 0x33, 0x34, +/* 20 */ 0x0a, 0x0b, 0x08, 0x09, 0x0e, 0x0f, 0x0c, 0x0d, +/* 28 */ 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, +/* 30 */ 0x1a, 0x1b, 0x18, 0x19, 0x1e, 0x1f, 0x1c, 0x1d, +/* 38 */ 0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, +/* 40 */ 0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, +/* 48 */ 0x5d, 0x5d, 0x5c, 0x5c, 0x5f, 0x5f, 0x5e, 0x5e, +/* 50 */ 0x74, 0x76, 0x70, 0x72, 0x7c, 0x7e, 0x78, 0x7a, +/* 58 */ 0x6a, 0x6b, 0x68, 0x69, 0x6e, 0x6f, 0x6c, 0x6d, +/* 60 */ 0x48, 0x49, 0x46, 0x47, 0x4c, 0x4d, 0x4a, 0x4b, +/* 68 */ 0x40, 0x41, 0x3f, 0x3f, 0x44, 0x45, 0x42, 0x43, +/* 70 */ 0x56, 0x57, 0x54, 0x55, 0x5a, 0x5b, 0x58, 0x59, +/* 78 */ 0x4f, 0x4f, 0x4e, 0x4e, 0x52, 0x53, 0x50, 0x51, +/* 80 */ 0xaa, 0xab, 0xa8, 0xa9, 0xae, 0xaf, 0xac, 0xad, +/* 88 */ 0xa2, 0xa3, 0xa0, 0xa1, 0xa6, 0xa7, 0xa4, 0xa5, +/* 90 */ 0xb9, 0xba, 0xb7, 0xb8, 0xbd, 0xbe, 0xbb, 0xbc, +/* 98 */ 0xb1, 0xb2, 0xb0, 0xb0, 0xb5, 0xb6, 0xb3, 0xb4, +/* a0 */ 0x8a, 0x8b, 0x88, 0x89, 0x8e, 0x8f, 0x8c, 0x8d, +/* a8 */ 0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, +/* b0 */ 0x9a, 0x9b, 0x98, 0x99, 0x9e, 0x9f, 0x9c, 0x9d, +/* b8 */ 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, +/* c0 */ 0xe2, 0xe3, 0xe0, 0xe1, 0xe6, 0xe7, 0xe4, 0xe5, +/* c8 */ 0xdd, 0xdd, 0xdc, 0xdc, 0xdf, 0xdf, 0xde, 0xde, +/* d0 */ 0xf4, 0xf6, 0xf0, 0xf2, 0xfc, 0xfe, 0xf8, 0xfa, +/* d8 */ 0xea, 0xeb, 0xe8, 0xe9, 0xee, 0xef, 0xec, 0xed, +/* e0 */ 0xc8, 0xc9, 0xc6, 0xc7, 0xcc, 0xcd, 0xca, 0xcb, +/* e8 */ 0xc0, 0xc1, 0xbf, 0xbf, 0xc4, 0xc5, 0xc2, 0xc3, +/* f0 */ 0xd6, 0xd7, 0xd4, 0xd5, 0xda, 0xdb, 0xd8, 0xd9, +/* f8 */ 0xcf, 0xcf, 0xce, 0xce, 0xd2, 0xd3, 0xd0, 0xd1 }; - /*---------------------------------------------------------------------------* - * mu-law to line format conversion + * u-law to A-law conversion *---------------------------------------------------------------------------*/ -static unsigned char ulaw_alaw[256] = { - 0x54, 0xd4, 0x14, 0x94, 0x74, 0xf4, 0x34, 0xb4, 0x44, 0xc4, 0x04, 0x84, 0x64, 0xe4, 0x24, 0xa4, - 0x5c, 0xdc, 0x1c, 0x9c, 0x7c, 0xfc, 0x3c, 0xbc, 0x4c, 0xcc, 0x0c, 0x8c, 0x6c, 0xec, 0x2c, 0xac, - 0xd0, 0x10, 0x90, 0x70, 0xf0, 0x30, 0xb0, 0x40, 0xc0, 0x00, 0x80, 0x60, 0xe0, 0x20, 0xa0, 0x58, - 0xd8, 0x18, 0x98, 0x78, 0xf8, 0x38, 0xb8, 0x48, 0xc8, 0x08, 0x88, 0x68, 0xe8, 0x28, 0xa8, 0xd6, - 0x16, 0x96, 0x76, 0xf6, 0x36, 0xb6, 0x46, 0xc6, 0x06, 0x86, 0x66, 0xe6, 0x26, 0xa6, 0xde, 0x9e, - 0x7e, 0xfe, 0x3e, 0xbe, 0x4e, 0xce, 0x0e, 0x8e, 0x6e, 0xee, 0x2e, 0xae, 0xd2, 0x92, 0xf2, 0xb2, - 0xc2, 0x02, 0x82, 0x62, 0xe2, 0x22, 0xa2, 0x5a, 0xda, 0x1a, 0x9a, 0x7a, 0xfa, 0x3a, 0xba, 0x4a, - 0x4a, 0xca, 0xca, 0x0a, 0x0a, 0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a, 0xaa, 0xab, 0xab, - 0x55, 0xd5, 0x15, 0x95, 0x75, 0xf5, 0x35, 0xb5, 0x45, 0xc5, 0x05, 0x85, 0x65, 0xe5, 0x25, 0xa5, - 0x5d, 0xdd, 0x1d, 0x9d, 0x7d, 0xfd, 0x3d, 0xbd, 0x4d, 0xcd, 0x0d, 0x8d, 0x6d, 0xed, 0x2d, 0xad, - 0x51, 0xd1, 0x11, 0x91, 0x71, 0xf1, 0x31, 0xb1, 0x41, 0xc1, 0x01, 0x81, 0x61, 0xe1, 0x21, 0xa1, - 0xd9, 0x19, 0x99, 0x79, 0xf9, 0x39, 0xb9, 0x49, 0xc9, 0x09, 0x89, 0x69, 0xe9, 0x29, 0xa9, 0x57, - 0x17, 0x97, 0x77, 0xf7, 0x37, 0xb7, 0x47, 0xc7, 0x07, 0x87, 0x67, 0xe7, 0x27, 0xa7, 0x5f, 0x1f, - 0x7f, 0xff, 0x3f, 0xbf, 0x4f, 0xcf, 0x0f, 0x8f, 0x6f, 0xef, 0x2f, 0xaf, 0x53, 0x13, 0x73, 0x33, - 0x43, 0xc3, 0x03, 0x83, 0x63, 0xe3, 0x23, 0xa3, 0x5b, 0xdb, 0x1b, 0x9b, 0x7b, 0xfb, 0x3b, 0xbb, - 0xbb, 0x4b, 0x4b, 0xcb, 0xcb, 0x0b, 0x0b, 0x8b, 0x8b, 0x6b, 0x6b, 0xeb, 0xeb, 0x2b, 0x2b, 0xab +static unsigned char u2a_tab[256] = { +/* 00 */ 0x2a, 0x2b, 0x28, 0x29, 0x2e, 0x2f, 0x2c, 0x2d, +/* 08 */ 0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25, +/* 10 */ 0x3a, 0x3b, 0x38, 0x39, 0x3e, 0x3f, 0x3c, 0x3d, +/* 18 */ 0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35, +/* 20 */ 0x0a, 0x0b, 0x08, 0x09, 0x0e, 0x0f, 0x0c, 0x0d, +/* 28 */ 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, +/* 30 */ 0x1b, 0x18, 0x19, 0x1e, 0x1f, 0x1c, 0x1d, 0x12, +/* 38 */ 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6a, +/* 40 */ 0x68, 0x69, 0x6e, 0x6f, 0x6c, 0x6d, 0x62, 0x63, +/* 48 */ 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 0x7a, 0x78, +/* 50 */ 0x7e, 0x7f, 0x7c, 0x7d, 0x72, 0x73, 0x70, 0x71, +/* 58 */ 0x76, 0x77, 0x74, 0x75, 0x4b, 0x49, 0x4f, 0x4d, +/* 60 */ 0x42, 0x43, 0x40, 0x41, 0x46, 0x47, 0x44, 0x45, +/* 68 */ 0x5a, 0x5b, 0x58, 0x59, 0x5e, 0x5f, 0x5c, 0x5d, +/* 70 */ 0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, +/* 78 */ 0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0x55, +/* 80 */ 0xaa, 0xab, 0xa8, 0xa9, 0xae, 0xaf, 0xac, 0xad, +/* 88 */ 0xa2, 0xa3, 0xa0, 0xa1, 0xa6, 0xa7, 0xa4, 0xa5, +/* 90 */ 0xba, 0xbb, 0xb8, 0xb9, 0xbe, 0xbf, 0xbc, 0xbd, +/* 98 */ 0xb2, 0xb3, 0xb0, 0xb1, 0xb6, 0xb7, 0xb4, 0xb5, +/* a0 */ 0x8a, 0x8b, 0x88, 0x89, 0x8e, 0x8f, 0x8c, 0x8d, +/* a8 */ 0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, +/* b0 */ 0x9b, 0x98, 0x99, 0x9e, 0x9f, 0x9c, 0x9d, 0x92, +/* b8 */ 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 0xea, +/* c0 */ 0xe8, 0xe9, 0xee, 0xef, 0xec, 0xed, 0xe2, 0xe3, +/* c8 */ 0xe0, 0xe1, 0xe6, 0xe7, 0xe4, 0xe5, 0xfa, 0xf8, +/* d0 */ 0xfe, 0xff, 0xfc, 0xfd, 0xf2, 0xf3, 0xf0, 0xf1, +/* d8 */ 0xf6, 0xf7, 0xf4, 0xf5, 0xcb, 0xc9, 0xcf, 0xcd, +/* e0 */ 0xc2, 0xc3, 0xc0, 0xc1, 0xc6, 0xc7, 0xc4, 0xc5, +/* e8 */ 0xda, 0xdb, 0xd8, 0xd9, 0xde, 0xdf, 0xdc, 0xdd, +/* f0 */ 0xd2, 0xd2, 0xd3, 0xd3, 0xd0, 0xd0, 0xd1, 0xd1, +/* f8 */ 0xd6, 0xd6, 0xd7, 0xd7, 0xd4, 0xd4, 0xd5, 0xd5 }; /*---------------------------------------------------------------------------* - * bit-reverse the sample to convert from/to canonical A-law + * reverse bits in a byte *---------------------------------------------------------------------------*/ static unsigned char bitreverse[256] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +/* 00 */ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, +/* 08 */ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, +/* 10 */ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, +/* 18 */ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, +/* 20 */ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, +/* 28 */ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, +/* 30 */ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, +/* 38 */ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, +/* 40 */ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, +/* 48 */ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, +/* 50 */ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, +/* 58 */ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, +/* 60 */ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, +/* 68 */ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, +/* 70 */ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, +/* 78 */ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, +/* 80 */ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, +/* 88 */ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, +/* 90 */ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, +/* 98 */ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, +/* a0 */ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, +/* a8 */ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, +/* b0 */ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, +/* b8 */ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, +/* c0 */ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, +/* c8 */ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, +/* d0 */ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, +/* d8 */ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, +/* e0 */ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, +/* e8 */ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, +/* f0 */ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, +/* f8 */ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff }; /*===========================================================================*/ diff --git a/sys/i4b/driver/i4b_trace.c b/sys/i4b/driver/i4b_trace.c index f50a67a..fe94d14 100644 --- a/sys/i4b/driver/i4b_trace.c +++ b/sys/i4b/driver/i4b_trace.c @@ -27,9 +27,9 @@ * i4btrc - device driver for trace data read device * --------------------------------------------------- * - * $Id: i4b_trace.c,v 1.16 1999/02/14 19:51:01 hm Exp $ + * $Id: i4b_trace.c,v 1.18 1999/04/28 08:23:21 hm Exp $ * - * last edit-date: [Sun Feb 14 10:03:01 1999] + * last edit-date: [Wed Apr 28 10:21:09 1999] * * NOTE: the code assumes that SPLI4B >= splimp ! * @@ -125,7 +125,7 @@ static d_open_t i4btrcopen; static d_close_t i4btrcclose; static d_read_t i4btrcread; static d_ioctl_t i4btrcioctl; -#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 +#ifdef OS_USES_POLL static d_poll_t i4btrcpoll; #endif @@ -133,7 +133,7 @@ static d_poll_t i4btrcpoll; static struct cdevsw i4btrc_cdevsw = { i4btrcopen, i4btrcclose, i4btrcread, nowrite, i4btrcioctl, nostop, noreset, nodevtotty, -#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 +#ifdef OS_USES_POLL i4btrcpoll, nommap, NULL, "i4btrc", NULL, -1 #else noselect, nommap, NULL, "i4btrc", NULL, -1 @@ -441,10 +441,10 @@ i4btrcread(dev_t dev, struct uio * uio, int ioflag) return(error); } +#if defined(__FreeBSD__) && defined(OS_USES_POLL) /*---------------------------------------------------------------------------* * poll device *---------------------------------------------------------------------------*/ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 PDEVSTATIC int i4btrcpoll(dev_t dev, int events, struct proc *p) { diff --git a/sys/i4b/include/i4b_debug.h b/sys/i4b/include/i4b_debug.h index ad6cccf..628a65e 100644 --- a/sys/i4b/include/i4b_debug.h +++ b/sys/i4b/include/i4b_debug.h @@ -27,9 +27,9 @@ * i4b_debug.h - i4b debug header file * ----------------------------------- * - * $Id: i4b_debug.h,v 1.15 1999/02/14 09:45:02 hm Exp $ + * $Id: i4b_debug.h,v 1.18 1999/04/28 14:50:55 hm Exp $ * - * last edit-date: [Sun Feb 14 10:37:58 1999] + * last edit-date: [Wed Apr 28 16:50:36 1999] * *---------------------------------------------------------------------------*/ @@ -169,9 +169,14 @@ extern unsigned int i4b_l4_debug; #define L4_DIALST 0x0008 /* network driver dial states */ #define L4_IPRDBG 0x0010 /* ipr driver debug messages */ #define L4_RBCHDBG 0x0020 /* rbch driver debug messages */ - -#define L4_DEBUG_MAX 0x003f /* all messages on */ -#define L4_DEBUG_ERR (L4_ERR) +#define L4_ISPDBG 0x0040 /* isp driver debug messages */ +#define L4_TELDBG 0x0080 /* tel driver debug messages */ +#define L4_TINADBG 0x0100 /* tina driver debug messages */ +#define L4_TINAMSG 0x0200 /* tina driver messages */ +#define L4_TINAERR 0x0400 /* tina driver error messages */ + +#define L4_DEBUG_MAX 0x07ff /* all messages on */ +#define L4_DEBUG_ERR (L4_ERR | L4_TINADBG | L4_TINAMSG | L4_TINAERR) #ifndef L4_DEBUG_DEFAULT #ifdef DO_I4B_MAXDEBUG diff --git a/sys/i4b/include/i4b_global.h b/sys/i4b/include/i4b_global.h index e386b38..b13ac0e 100644 --- a/sys/i4b/include/i4b_global.h +++ b/sys/i4b/include/i4b_global.h @@ -27,19 +27,22 @@ * i4b_global.h - i4b global include file * -------------------------------------- * - * $Id: i4b_global.h,v 1.19 1999/02/27 11:08:01 hm Exp $ + * $Id: i4b_global.h,v 1.21 1999/04/26 10:16:54 hm Exp $ * - * last edit-date: [Sun Feb 14 10:03:55 1999] + * last edit-date: [Mon Apr 26 11:10:26 1999] * *---------------------------------------------------------------------------*/ #ifndef _I4B_GLOBAL_H_ #define _I4B_GLOBAL_H_ -#define SPLI4B() splimp() /* spl for i4b */ +/*---------------------------------------------------------------------------* + * hiding OS differences in the kernel + *---------------------------------------------------------------------------*/ -#define TIMER_IDLE 1 /* a timer is running */ -#define TIMER_ACTIVE 2 /* a timer is idle */ +/*---------------*/ +/* time handling */ +/*---------------*/ #ifdef __FreeBSD__ #include <sys/param.h> @@ -66,6 +69,37 @@ #endif /* __NetBSD__ */ +/*----------------------*/ +/* poll/select handling */ +/*----------------------*/ + +#if (defined(__FreeBSD__) && \ + (!defined(__FreeBSD_version) || (__FreeBSD_version < 300001))) \ + || defined (__OpenBSD__) || defined(__bsdi__) +#define OS_USES_SELECT +#else +#define OS_USES_POLL +#endif + +/*---------------------------------------------------------------------------* + * misc globally used things in the kernel + *---------------------------------------------------------------------------*/ + +/* timer states */ + +#define TIMER_IDLE 1 /* a timer is running */ +#define TIMER_ACTIVE 2 /* a timer is idle */ + +/* i4b's spl */ + +#define SPLI4B() splimp() /* spl for i4b */ + +/* critial code region handling macros */ + +#define CRIT_VAR int _svd_spl_ /* declare variable */ +#define CRIT_BEG _svd_spl_ = SPLI4B() /* save spl */ +#define CRIT_END splx(_svd_spl_) /* restore spl */ + /* definitions for the STATUS indications L1 -> L2 -> L3 */ #define STI_ATTACH 0 /* attach at boot time */ diff --git a/sys/i4b/include/i4b_ioctl.h b/sys/i4b/include/i4b_ioctl.h index 21560a8..b7289a8 100644 --- a/sys/i4b/include/i4b_ioctl.h +++ b/sys/i4b/include/i4b_ioctl.h @@ -27,9 +27,9 @@ * i4b_ioctl.h - messages kernel <--> userland * ------------------------------------------- * - * $Id: i4b_ioctl.h,v 1.69 1999/03/01 09:04:15 hm Exp $ + * $Id: i4b_ioctl.h,v 1.106 1999/05/19 08:51:14 hm Exp $ * - * last edit-date: [Mon Mar 1 10:01:15 1999] + * last edit-date: [Wed May 19 10:56:56 1999] * *---------------------------------------------------------------------------*/ @@ -46,7 +46,7 @@ * version and release number for isdn4bsd package *---------------------------------------------------------------------------*/ #define VERSION 0 /* version number */ -#define REL 71 /* release number */ +#define REL 81 /* release number */ #define STEP 0 /* release step */ /*---------------------------------------------------------------------------* @@ -74,7 +74,9 @@ #define CTRL_UNKNOWN 0 /* unknown controller type */ #define CTRL_PASSIVE 1 /* passive ISDN controller cards*/ #define CTRL_DAIC 2 /* Diehl active controller cards*/ -#define CTRL_NUMTYPES 3 /* number of controller types */ +#define CTRL_TINADD 3 /* Stollmann Tina-dd active card*/ +#define CTRL_AVMB1 4 /* AVM B1 active card */ +#define CTRL_NUMTYPES 5 /* number of controller types */ /*---------------------------------------------------------------------------* * card types for CTRL_PASSIVE @@ -100,6 +102,7 @@ #define CARD_TYPEP_ELSAMLMCALL 17 /* ELSA MicroLink MCall */ #define CARD_TYPEP_ITKIX1 18 /* ITK ix1 micro */ #define CARD_TYPEP_AVMA1PCI 19 /* AVM FRITZ!CARD PCI */ +#define CARD_TYPEP_PCC16 20 /* ELSA PCC-16 */ /* * in case you add support for more cards, please update: @@ -110,7 +113,7 @@ * and adjust CARD_TYPEP_MAX below. */ -#define CARD_TYPEP_MAX 19 /* max type */ +#define CARD_TYPEP_MAX 20 /* max type */ /*---------------------------------------------------------------------------* * card types for CTRL_DAIC @@ -170,19 +173,17 @@ typedef unsigned int cause_t; /* 32 bit unsigned int */ /*---------------------------------------------------------------------------* * The shorthold algorithm to use *---------------------------------------------------------------------------*/ -typedef enum msg_shorthold_algorithm { - msg_alg__fix_unit_size, /* timeout algorithm for fix unit charging */ - msg_alg__var_unit_size /* timeout algorithm for variable unit charging */ -} msg_shorthold_algorithm_t; +#define SHA_FIXU 0 /* timeout algorithm for fix unit charging */ +#define SHA_VARU 1 /* timeout algorithm for variable unit charging */ /*---------------------------------------------------------------------------* * The shorthold data struct *---------------------------------------------------------------------------*/ typedef struct { - msg_shorthold_algorithm_t shorthold_algorithm; /* shorthold algorithm to use */ - int unitlen_time; /* length of a charging unit */ - int idle_time; /* time without activity on b ch */ - int earlyhup_time; /* safety area at end of unit */ + int shorthold_algorithm; /* shorthold algorithm to use */ + int unitlen_time; /* length of a charging unit */ + int idle_time; /* time without activity on b ch*/ + int earlyhup_time; /* safety area at end of unit */ } msg_shorthold_t; @@ -274,6 +275,7 @@ typedef struct { #define MSG_PDEACT_IND 'm' #define MSG_NEGCOMP_IND 'n' #define MSG_IFSTATE_CHANGED_IND 'o' +#define MSG_DIALOUTNUMBER_IND 'p' int cdid; /* call descriptor id */ } msg_hdr_t; @@ -349,6 +351,17 @@ typedef struct { } msg_dialout_ind_t; /*---------------------------------------------------------------------------* + * dial a number + *---------------------------------------------------------------------------*/ +typedef struct { + msg_hdr_t header; /* common header */ + int driver; /* driver type */ + int driver_unit; /* driver unit number */ + int cmdlen; /* length of string */ + char cmd[TELNO_MAX]; /* the number to dial */ +} msg_dialoutnumber_ind_t; + +/*---------------------------------------------------------------------------* * idle timeout disconnect sent indication * kernel has sent disconnect request because of b-ch idle *---------------------------------------------------------------------------*/ @@ -541,6 +554,7 @@ typedef struct { #define DSTAT_TFAIL 1 /* transient failure */ #define DSTAT_PFAIL 2 /* permanent failure */ #define DSTAT_INONLY 3 /* no outgoing dials allowed */ + cause_t cause; /* exact i4b cause */ } msg_dialout_resp_t; #define I4B_DIALOUT_RESP _IOW('4', 5, msg_dialout_resp_t) diff --git a/sys/i4b/include/i4b_l3l4.h b/sys/i4b/include/i4b_l3l4.h index 0f7ac7d..3655bb1 100644 --- a/sys/i4b/include/i4b_l3l4.h +++ b/sys/i4b/include/i4b_l3l4.h @@ -27,9 +27,9 @@ * i4b_l3l4.h - layer 3 / layer 4 interface * ------------------------------------------ * - * $Id: i4b_l3l4.h,v 1.23 1999/02/15 09:55:47 hm Exp $ + * $Id: i4b_l3l4.h,v 1.24 1999/03/18 14:33:40 hm Exp $ * - * last edit-date: [Sun Feb 14 10:04:19 1999] + * last edit-date: [Wed Mar 17 16:16:40 1999] * *---------------------------------------------------------------------------*/ @@ -81,7 +81,7 @@ typedef struct i4l_driver_bchan_linktab { #define ACT_TX 1 void (*line_connected)(int unit, void *cde); void (*line_disconnected)(int unit, void *cde); - void (*dial_response)(int unit, int stat); + void (*dial_response)(int unit, int stat, cause_t cause); void (*updown_ind)(int unit, int updown); } drvr_link_t; diff --git a/sys/i4b/include/i4b_tel_ioctl.h b/sys/i4b/include/i4b_tel_ioctl.h index 52f08cc..3df673b 100644 --- a/sys/i4b/include/i4b_tel_ioctl.h +++ b/sys/i4b/include/i4b_tel_ioctl.h @@ -27,20 +27,24 @@ * i4b_tel_ioctl.h telephony interface ioctls * ------------------------------------------ * - * $Id: i4b_tel_ioctl.h,v 1.7 1999/02/16 10:40:18 hm Exp $ + * $Id: i4b_tel_ioctl.h,v 1.9 1999/04/21 10:06:32 hm Exp $ * - * last edit-date: [Sun Feb 14 10:39:19 1999] + * last edit-date: [Wed Apr 21 11:00:02 1999] * *---------------------------------------------------------------------------*/ #ifndef _I4B_TEL_IOCTL_H_ #define _I4B_TEL_IOCTL_H_ -/* supported audio format conversions for /dev/i4btelXX devices */ +/*===========================================================================* + * /dev/i4btel<n> devices (audio data) + *===========================================================================*/ + +/* supported audio format conversions */ -#define CVT_NONE 0 /* no format conversion */ -#define CVT_ALAW2ULAW 1 /* kernel A-law, userland mu-law */ -#define CVT_ALAW_CANON 2 /* kernel A-law, userland canonical A-law */ +#define CVT_NONE 0 /* no A-law/u-law conversion */ +#define CVT_ALAW2ULAW 1 /* ISDN line: A-law, user: u-law */ +#define CVT_ULAW2ALAW 2 /* ISDN line: u-law, user: A-law */ /*---------------------------------------------------------------------------* * get / set audio format @@ -50,4 +54,20 @@ #define I4B_TEL_SETAUDIOFMT _IOW('A', 1, int) #define I4B_TEL_EMPTYINPUTQUEUE _IOW('A', 2, int) +/*===========================================================================* + * /dev/i4bteld<n> devices (dialer interface) + *===========================================================================*/ + +/* dialer commands */ + +#define CMD_DIAL 'D' /* dial the following number string */ +#define CMD_HUP 'H' /* hangup */ + +/* dialer responses */ + +#define RSP_CONN '0' /* connect */ +#define RSP_BUSY '1' /* busy */ +#define RSP_HUP '2' /* hangup */ +#define RSP_NOA '3' /* no answer */ + #endif /* _I4B_TEL_IOCTL_H_ */ diff --git a/sys/i4b/layer1/i4b_avm_fritz_pci.c b/sys/i4b/layer1/i4b_avm_fritz_pci.c index da910b6..2da4f89 100644 --- a/sys/i4b/layer1/i4b_avm_fritz_pci.c +++ b/sys/i4b/layer1/i4b_avm_fritz_pci.c @@ -29,18 +29,24 @@ * SUCH DAMAGE. * *--------------------------------------------------------------------------- + * a lot of code was borrowed from i4b_bchan.c and i4b_hscx.c + *--------------------------------------------------------------------------- * * Fritz!Card PCI specific routines for isic driver * ------------------------------------------------ * - * $Id: i4b_avm_fritz_pci.c,v 1.1 1999/02/17 14:31:42 hm Exp $ + * $Id: i4b_avm_fritz_pci.c,v 1.5 1999/05/05 11:50:21 hm Exp $ * - * last edit-date: [Wed Feb 17 15:23:28 1999] + * last edit-date: [Tue Mar 16 16:18:35 1999] * *---------------------------------------------------------------------------*/ +#if defined(__FreeBSD__) #include "isic.h" #include "opt_i4b.h" +#else +#define NISIC 1 +#endif #if NISIC > 0 && defined(AVM_A1_PCI) @@ -54,15 +60,32 @@ #include <sys/systm.h> #include <sys/mbuf.h> +#ifdef __FreeBSD__ #include <machine/clock.h> #include <i386/isa/isa_device.h> #include <pci/pcivar.h> /* for pcici_t */ +#if __FreeBSD__ < 3 +#include <pci/pcireg.h> +#include <pci/pcibus.h> +#endif /* __FreeBSD__ < 3 */ +#else +#include <machine/bus.h> +#include <sys/device.h> +#endif #include <sys/socket.h> #include <net/if.h> +#ifdef __FreeBSD__ #include <machine/i4b_debug.h> #include <machine/i4b_ioctl.h> +#else +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> +#include <i4b/i4b_debug.h> +#include <i4b/i4b_ioctl.h> +#endif #include <i4b/include/i4b_global.h> #include <i4b/include/i4b_l1l2.h> @@ -72,7 +95,20 @@ #include <i4b/layer1/i4b_isac.h> #include <i4b/layer1/i4b_hscx.h> +#ifndef __FreeBSD__ + +#include <i4b/layer1/pci_isic.h> + +/* PCI config map to use (only one in this driver) */ +#define FRITZPCI_PORT0_MAPOFF PCI_MAPREG_START+4 + +#endif + /* prototypes */ +static void avma1pp_disable(struct isic_softc *); + +#ifdef __FreeBSD__ + static void avma1pp_intr(struct isic_softc *); static void avma1pp_disable(struct isic_softc *); void avma1pp_map_int(pcici_t , void *, unsigned *); @@ -88,11 +124,30 @@ static void avma1pp_bchannel_setup(int, int, int, int); static void avma1pp_bchannel_start(int, int); static void avma1pp_hscx_init(struct isic_softc *, int, int); static void avma1pp_bchannel_stat(int, int, bchan_statistics_t *); -static void avma1pp_fifo(isic_Bchan_t *, struct isic_softc *); static void avma1pp_set_linktab(int, int, drvr_link_t *); static isdn_link_t * avma1pp_ret_linktab(int, int); +int isic_attach_avma1pp(int, u_int, u_int); extern void isicintr_sc(struct isic_softc *); +#else + +static int avma1pp_intr(void*); +static void avma1pp_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size); +static void avma1pp_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size); +static void avma1pp_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data); +static u_int8_t avma1pp_read_reg(struct isic_softc *sc, int what, bus_size_t offs); +static void hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc); +static void hscx_read_fifo(int chan, void *buf, size_t len, struct isic_softc *sc); +static void hscx_write_reg(int chan, u_int off, u_int val, struct isic_softc *sc); +static u_char hscx_read_reg(int chan, u_int off, struct isic_softc *sc); +static u_int hscx_read_reg_int(int chan, u_int off, struct isic_softc *sc); +static void avma1pp_fifo(isic_Bchan_t *chan, struct isic_softc *sc); +static void avma1pp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp); +static void avma1pp_map_int(struct pci_isic_softc *sc, struct pci_attach_args *pa); +static void avma1pp_bchannel_setup(int unit, int h_chan, int bprot, int activate); +static void avma1pp_init_linktab(struct isic_softc *); +#endif + /*---------------------------------------------------------------------------* * AVM PCI Fritz!Card special registers *---------------------------------------------------------------------------*/ @@ -105,20 +160,27 @@ extern void isicintr_sc(struct isic_softc *); #define ADDR_REG_OFFSET 0x04 /*#define MODREG_OFFSET 0x06 #define VERREG_OFFSET 0x07*/ + /* these 2 are used to select an ISAC register set */ #define ISAC_LO_REG_OFFSET 0x04 #define ISAC_HI_REG_OFFSET 0x06 + /* offset higher than this goes to the HI register set */ #define MAX_LO_REG_OFFSET 0x2f + /* mask for the offset */ #define ISAC_REGSET_MASK 0x0f + /* the offset from the base to the ISAC registers */ #define ISAC_REG_OFFSET 0x10 + /* the offset from the base to the ISAC FIFO */ #define ISAC_FIFO 0x02 + /* not really the HSCX, but sort of */ #define HSCX_FIFO 0x00 #define HSCX_STAT 0x04 + /* * AVM PCI Status Latch 0 read only bits */ @@ -128,6 +190,7 @@ extern void isicintr_sc(struct isic_softc *); #define ASL_IRQ_BCHAN ASL_IRQ_HSCX /* actually active LOW */ #define ASL_IRQ_Pending (ASL_IRQ_ISAC | ASL_IRQ_HSCX | ASL_IRQ_TIMER) + /* * AVM Status Latch 0 write only bits */ @@ -136,6 +199,7 @@ extern void isicintr_sc(struct isic_softc *); #define ASL_TIMERRESET 0x04 /* active high */ #define ASL_ENABLE_INT 0x08 /* active high */ #define ASL_TESTBIT 0x10 /* active high */ + /* * AVM Status Latch 1 write only bits */ @@ -195,12 +259,16 @@ extern void isicintr_sc(struct isic_softc *); #define AVMA1PPSETCMDLONG(f) (f) = ((sc->avma1pp_cmd) | (sc->avma1pp_txl << 8) \ | (sc->avma1pp_prot << 16)) +#ifdef __FreeBSD__ + /* "fake" addresses for the non-existent HSCX */ /* note: the unit number is in the lower byte for both the ISAC and "HSCX" */ #define HSCX0FAKE 0xfa000 /* read: fake0 */ #define HSCX1FAKE 0xfa100 /* read: fake1 */ #define IS_HSCX_MASK 0xfff00 +#endif /* __FreeBSD__ */ + /* * to prevent deactivating the "HSCX" when both channels are active we * define an HSCX_ACTIVE flag which is or'd into the channel's state @@ -212,6 +280,8 @@ extern void isicintr_sc(struct isic_softc *); /*---------------------------------------------------------------------------* * AVM read fifo routines *---------------------------------------------------------------------------*/ + +#ifdef __FreeBSD__ static void avma1pp_read_fifo(void *buf, const void *base, size_t len) { @@ -255,9 +325,49 @@ hscx_read_fifo(int chan, void *buf, size_t len, struct isic_softc *sc) } } +#else + +static void +avma1pp_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size) +{ + switch (what) { + case ISIC_WHAT_ISAC: + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR_REG_OFFSET, ISAC_FIFO); + bus_space_read_multi_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET, buf, size); + break; + case ISIC_WHAT_HSCXA: + hscx_read_fifo(0, buf, size, sc); + break; + case ISIC_WHAT_HSCXB: + hscx_read_fifo(1, buf, size, sc); + break; + } +} + +static void +hscx_read_fifo(int chan, void *buf, size_t len, struct isic_softc *sc) +{ + u_int32_t *ip; + size_t cnt; + + bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR_REG_OFFSET, chan); + ip = (u_int32_t *)buf; + cnt = 0; + /* what if len isn't a multiple of sizeof(int) and buf is */ + /* too small ???? */ + while (cnt < len) + { + *ip++ = bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET); + cnt += 4; + } +} + +#endif + /*---------------------------------------------------------------------------* * AVM write fifo routines *---------------------------------------------------------------------------*/ +#ifdef __FreeBSD__ static void avma1pp_write_fifo(void *base, const void *buf, size_t len) { @@ -312,9 +422,60 @@ hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc) } } +#else + +static void +avma1pp_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size) +{ + switch (what) { + case ISIC_WHAT_ISAC: + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR_REG_OFFSET, ISAC_FIFO); + bus_space_write_multi_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET, (u_int8_t*)buf, size); + break; + case ISIC_WHAT_HSCXA: + hscx_write_fifo(0, buf, size, sc); + break; + case ISIC_WHAT_HSCXB: + hscx_write_fifo(1, buf, size, sc); + break; + } +} + +static void +hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc) +{ + u_int32_t *ip; + size_t cnt; + isic_Bchan_t *Bchan = &sc->sc_chan[chan]; + + sc->avma1pp_cmd &= ~HSCX_CMD_XME; + sc->avma1pp_txl = 0; + if (len != sc->sc_bfifolen) + { + if (Bchan->bprot != BPROT_NONE) + sc->avma1pp_cmd |= HSCX_CMD_XME; + sc->avma1pp_txl = len; + } + + cnt = 0; /* borrow cnt */ + AVMA1PPSETCMDLONG(cnt); + hscx_write_reg(chan, HSCX_STAT, cnt, sc); + + ip = (u_int32_t *)buf; + cnt = 0; + while (cnt < len) + { + bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET, *ip); + ip++; + cnt += 4; + } +} +#endif + /*---------------------------------------------------------------------------* * AVM write register routines *---------------------------------------------------------------------------*/ +#ifdef __FreeBSD__ static void avma1pp_write_reg(u_char *base, u_int offset, u_int v) { @@ -357,9 +518,49 @@ hscx_write_reg(int chan, u_int off, u_int val, struct isic_softc *sc) outl(sc->sc_port + ISAC_REG_OFFSET + off, val); } +#else + +static void +avma1pp_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data) +{ + u_char reg_bank; + switch (what) { + case ISIC_WHAT_ISAC: + reg_bank = (offs > MAX_LO_REG_OFFSET) ? ISAC_HI_REG_OFFSET:ISAC_LO_REG_OFFSET; +#ifdef AVMA1PCI_DEBUG + printf("write_reg bank %d off %ld.. ", (int)reg_bank, (long)offs); +#endif + /* set the register bank */ + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR_REG_OFFSET, reg_bank); + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET + (offs & ISAC_REGSET_MASK), data); + break; + case ISIC_WHAT_HSCXA: + hscx_write_reg(0, offs, data, sc); + break; + case ISIC_WHAT_HSCXB: + hscx_write_reg(1, offs, data, sc); + break; + } +} + +static void +hscx_write_reg(int chan, u_int off, u_int val, struct isic_softc *sc) +{ + /* HACK */ + if (off == H_MASK) + return; + /* point at the correct channel */ + bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR_REG_OFFSET, chan); + bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET + off, val); +} + +#endif + /*---------------------------------------------------------------------------* * AVM read register routines *---------------------------------------------------------------------------*/ +#ifdef __FreeBSD__ + static u_char avma1pp_read_reg(u_char *base, u_int offset) { @@ -385,6 +586,29 @@ avma1pp_read_reg(u_char *base, u_int offset) return(inb(sc->sc_port + ISAC_REG_OFFSET + (offset & ISAC_REGSET_MASK))); } +#else +static u_int8_t +avma1pp_read_reg(struct isic_softc *sc, int what, bus_size_t offs) +{ + u_char reg_bank; + switch (what) { + case ISIC_WHAT_ISAC: + reg_bank = (offs > MAX_LO_REG_OFFSET) ? ISAC_HI_REG_OFFSET:ISAC_LO_REG_OFFSET; +#ifdef AVMA1PCI_DEBUG + printf("read_reg bank %d off %ld.. ", (int)reg_bank, (long)offs); +#endif + /* set the register bank */ + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR_REG_OFFSET, reg_bank); + return(bus_space_read_1(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET + + (offs & ISAC_REGSET_MASK))); + case ISIC_WHAT_HSCXA: + return hscx_read_reg(0, offs, sc); + case ISIC_WHAT_HSCXB: + return hscx_read_reg(1, offs, sc); + } + return 0; +} +#endif static u_char hscx_read_reg(int chan, u_int off, struct isic_softc *sc) @@ -393,7 +617,7 @@ hscx_read_reg(int chan, u_int off, struct isic_softc *sc) } /* - * need to be able to reeturn an int because the RBCH is in the 2nd + * need to be able to return an int because the RBCH is in the 2nd * byte. */ static u_int @@ -403,13 +627,19 @@ hscx_read_reg_int(int chan, u_int off, struct isic_softc *sc) if (off == H_ISTA) return(0); /* point at the correct channel */ +#ifdef __FreeBSD__ outl(sc->sc_port + ADDR_REG_OFFSET, chan); return(inl(sc->sc_port + ISAC_REG_OFFSET + off)); +#else + bus_space_write_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ADDR_REG_OFFSET, chan); + return(bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h, ISAC_REG_OFFSET + off)); +#endif } /*---------------------------------------------------------------------------* * isic_attach_avma1pp - attach Fritz!Card PCI *---------------------------------------------------------------------------*/ +#ifdef __FreeBSD__ int isic_attach_avma1pp(int unit, u_int iobase1, u_int iobase2) { @@ -468,7 +698,6 @@ isic_attach_avma1pp(int unit, u_int iobase1, u_int iobase2) /* reset the card */ /* the Linux driver does this to clear any pending ISAC interrupts */ - /* see if it helps any - XXXX */ v = 0; v = ISAC_READ(I_STAR); #ifdef AVMA1PCI_DEBUG @@ -523,7 +752,6 @@ isic_attach_avma1pp(int unit, u_int iobase1, u_int iobase2) /* from here to the end would normally be done in isic_pciattach */ - /* sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03; */ printf("isic%d: ISAC %s (IOM-%c)\n", unit, "2085 Version A1/A2 or 2086/2186 Version 1.1", sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2'); @@ -536,10 +764,6 @@ isic_attach_avma1pp(int unit, u_int iobase1, u_int iobase2) avma1pp_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0); - /* XXXX - try it here too */ - /* outb(sc->sc_port + STAT1_OFFSET, ASL1_ENABLE_IOM|sc->sc_irq); - DELAY(SEC_DELAY/100); */ /* 10 ms */ - /* can't use the normal B-Channel stuff */ avma1pp_init_linktab(sc); @@ -573,6 +797,150 @@ isic_attach_avma1pp(int unit, u_int iobase1, u_int iobase2) return(1); } +#else + +void +isic_attach_fritzPci(struct pci_isic_softc *psc, struct pci_attach_args *pa) +{ + struct isic_softc *sc = &psc->sc_isic; + u_int v; + + isic_sc[sc->sc_unit] = sc; /* XXX - hack! */ + + /* setup io mappings */ + sc->sc_num_mappings = 1; + MALLOC_MAPS(sc); + sc->sc_maps[0].size = 0; + if (pci_mapreg_map(pa, FRITZPCI_PORT0_MAPOFF, PCI_MAPREG_TYPE_IO, 0, + &sc->sc_maps[0].t, &sc->sc_maps[0].h, NULL, NULL)) { + printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname); + return; + } + + /* setup access routines */ + + sc->clearirq = NULL; + sc->readreg = avma1pp_read_reg; + sc->writereg = avma1pp_write_reg; + + sc->readfifo = avma1pp_read_fifo; + sc->writefifo = avma1pp_write_fifo; + + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_AVMA1PCI; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + /* this is no IPAC based card */ + sc->sc_ipac = 0; + sc->sc_bfifolen = HSCX_FIFO_LEN; + + /* init the card */ + /* the Linux driver does this to clear any pending ISAC interrupts */ + /* see if it helps any - XXXX */ + v = 0; + v = ISAC_READ(I_STAR); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_STAR %x...", v); +#endif + v = ISAC_READ(I_MODE); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_MODE %x...", v); +#endif + v = ISAC_READ(I_ADF2); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_ADF2 %x...", v); +#endif + v = ISAC_READ(I_ISTA); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_ISTA %x...", v); +#endif + if (v & ISAC_ISTA_EXI) + { + v = ISAC_READ(I_EXIR); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_EXIR %x...", v); +#endif + } + v = ISAC_READ(I_CIRR); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: I_CIRR %x...", v); +#endif + ISAC_WRITE(I_MASK, 0xff); + /* the Linux driver does this to clear any pending HSCX interrupts */ + v = hscx_read_reg_int(0, HSCX_STAT, sc); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: 0 HSCX_STAT %x...", v); +#endif + v = hscx_read_reg_int(1, HSCX_STAT, sc); +#ifdef AVMA1PCI_DEBUG + printf("avma1pp_attach: 1 HSCX_STAT %x\n", v); +#endif + + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); + DELAY(SEC_DELAY/100); /* 10 ms */ + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, ASL_TIMERRESET|ASL_ENABLE_INT|ASL_TIMERDISABLE); + DELAY(SEC_DELAY/100); /* 10 ms */ +#ifdef AVMA1PCI_DEBUG + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT1_OFFSET, ASL1_ENABLE_IOM|sc->sc_irq); + DELAY(SEC_DELAY/100); /* 10 ms */ + v = bus_space_read_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT1_OFFSET); + printf("after reset: S1 %#x\n", v); + + v = bus_space_read_4(sc->sc_maps[0].t, sc->sc_maps[0].h, 0); + printf("isic_attach_avma1pp: v %#x\n", v); +#endif + + /* setup i4b infrastructure (have to roll our own here) */ + + /* sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03; */ + printf("%s: ISAC %s (IOM-%c)\n", sc->sc_dev.dv_xname, + "2085 Version A1/A2 or 2086/2186 Version 1.1", + sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2'); + + /* init the ISAC */ + isic_isac_init(sc); + + /* init the "HSCX" */ + avma1pp_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0); + + avma1pp_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0); + + /* can't use the normal B-Channel stuff */ + avma1pp_init_linktab(sc); + + /* set trace level */ + + sc->sc_trace = TRACE_OFF; + + sc->sc_state = ISAC_IDLE; + + sc->sc_ibuf = NULL; + sc->sc_ib = NULL; + sc->sc_ilen = 0; + + sc->sc_obuf = NULL; + sc->sc_op = NULL; + sc->sc_ol = 0; + sc->sc_freeflag = 0; + + sc->sc_obuf2 = NULL; + sc->sc_freeflag2 = 0; + + /* init higher protocol layers */ + + MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp); + + /* setup interrupt mapping */ + avma1pp_map_int(psc, pa); +} + +#endif + /* * this is the real interrupt routine */ @@ -606,8 +974,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct isic_softc *sc) } /* - * The following is based on examination of the Linux driver. Who - * knows whether it's entirely correct ? + * The following is based on examination of the Linux driver. * * The logic here is different than with a "real" HSCX; all kinds * of information (interrupt/status bits) are in stat. @@ -658,10 +1025,10 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct isic_softc *sc) if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN) { - /* OK to copy the data */ + /* OK to copy the data */ bcopy(scrbuf, chan->in_cbptr, fifo_data_len); chan->in_cbptr += fifo_data_len; - chan->in_len += fifo_data_len; + chan->in_len += fifo_data_len; /* setup mbuf data length */ @@ -762,7 +1129,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct isic_softc *sc) } /* if(error == 0) */ else { - /* land here for RDO */ + /* land here for RDO */ if (chan->in_mbuf != NULL) { i4b_Bfreembuf(chan->in_mbuf); @@ -789,9 +1156,6 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct isic_softc *sc) * for a description what is going on here, please have * a look at isic_bchannel_start() in i4b_bchan.c ! */ - - /* int len; - int nextlen; */ DBGL1(L1_H_IRQ, "avma1pp_hscx_intr", ("unit %d, chan %d - XPR, Tx Fifo Empty!\n", sc->sc_unit, h_chan)); @@ -834,7 +1198,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct isic_softc *sc) } } - avma1pp_fifo(chan, sc); + isic_hscx_fifo(chan, sc); } /* call timeout handling routine */ @@ -864,19 +1228,43 @@ avma1pp_hscx_int_handler(struct isic_softc *sc) static void avma1pp_disable(struct isic_softc *sc) { +#ifdef __FreeBSD__ outb(sc->sc_port + STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); +#else + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); +#endif } +#ifdef __FreeBSD__ static void avma1pp_intr(struct isic_softc *sc) { +#define OURS /* no return value accumulated */ +#define ISICINTR(sc) isicintr_sc(sc) +#else +static int +avma1pp_intr(void * parm) +{ + struct isic_softc *sc = parm; + int ret = 0; +#define OURS ret = 1 +#define ISICINTR(sc) isicintr(sc) +#endif u_char stat; +#ifdef __FreeBSD__ stat = inb(sc->sc_port + STAT0_OFFSET); +#else + stat = bus_space_read_1(sc->sc_maps[0].t, sc->sc_maps[0].h, STAT0_OFFSET); +#endif DBGL1(L1_H_IRQ, "avma1pp_intr", ("stat %x\n", stat)); /* was there an interrupt from this card ? */ if ((stat & ASL_IRQ_Pending) == ASL_IRQ_Pending) +#ifdef __FreeBSD__ return; /* no */ +#else + return 0; /* no */ +#endif /* interrupts are low active */ if (!(stat & ASL_IRQ_TIMER)) DBGL1(L1_H_IRQ, "avma1pp_intr", ("timer interrupt ???\n")); @@ -884,21 +1272,42 @@ avma1pp_intr(struct isic_softc *sc) { DBGL1(L1_H_IRQ, "avma1pp_intr", ("HSCX\n")); avma1pp_hscx_int_handler(sc); + OURS; } if (!(stat & ASL_IRQ_ISAC)) { DBGL1(L1_H_IRQ, "avma1pp_intr", ("ISAC\n")); - isicintr_sc(sc); + ISICINTR(sc); + OURS; } +#ifndef __FreeBSD__ + return ret; +#endif } +#ifdef __FreeBSD__ void avma1pp_map_int(pcici_t config_id, void *pisc, unsigned *net_imask) { struct isic_softc *sc = (struct isic_softc *)pisc; +#ifdef AVMA1PCI_DEBUG /* may need the irq later */ +#if __FreeBSD__ < 3 + /* I'd like to call getirq here, but it is static */ + sc->sc_irq = PCI_INTERRUPT_LINE_EXTRACT( + pci_conf_read (config_id, PCI_INTERRUPT_REG)); + + if (sc->sc_irq == 0 || sc->sc_irq == 0xff) + printf ("avma1pp_map_int:int line register not set by bios\n"); + + if (sc->sc_irq >= PCI_MAX_IRQ) + printf ("avma1pp_map_int:irq %d out of bounds (must be < %d)\n", + sc->sc_irq, PCI_MAX_IRQ); +#else sc->sc_irq = config_id->intline; +#endif +#endif /* AVMA1PCI_DEBUG */ if(!(pci_map_int(config_id, (void *)avma1pp_intr, sc, net_imask))) { @@ -907,6 +1316,36 @@ avma1pp_map_int(pcici_t config_id, void *pisc, unsigned *net_imask) avma1pp_disable(sc); } } +#else +static void +avma1pp_map_int(struct pci_isic_softc *psc, struct pci_attach_args *pa) +{ + struct isic_softc *sc = &psc->sc_isic; + pci_chipset_tag_t pc = pa->pa_pc; + pci_intr_handle_t ih; + const char *intrstr; + + /* Map and establish the interrupt. */ + if (pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin, + pa->pa_intrline, &ih)) { + printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); + avma1pp_disable(sc); + return; + } + intrstr = pci_intr_string(pc, ih); + psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, avma1pp_intr, sc); + if (psc->sc_ih == NULL) { + printf("%s: couldn't establish interrupt", + sc->sc_dev.dv_xname); + if (intrstr != NULL) + printf(" at %s", intrstr); + printf("\n"); + avma1pp_disable(sc); + return; + } + printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr); +} +#endif static void avma1pp_hscx_init(struct isic_softc *sc, int h_chan, int activate) @@ -986,7 +1425,7 @@ avma1pp_bchannel_setup(int unit, int h_chan, int bprot, int activate) /* general part */ chan->unit = sc->sc_unit; /* unit number */ - chan->channel = h_chan; /* B channel */ + chan->channel = h_chan; /* B channel */ chan->bprot = bprot; /* B channel protocol */ chan->state = HSCX_IDLE; /* B channel state */ @@ -1037,19 +1476,9 @@ avma1pp_bchannel_start(int unit, int h_chan) #else struct isic_softc *sc = isic_find_sc(unit); #endif - register isic_Bchan_t *chan = &sc->sc_chan[h_chan]; - int s; int activity = -1; -#if 0 /* moved to avma1pp_fifo */ - /* the "HSCX" probably only allows writing all bytes at once */ - /* so we need a scratch buffer to collect the bytes */ - u_char scrbuf[HSCX_FIFO_LEN]; - int i; - register int next_len; - register int len; -#endif s = SPLI4B(); /* enter critical section */ if(chan->state & HSCX_TX_ACTIVE) /* already running ? */ @@ -1099,7 +1528,7 @@ avma1pp_bchannel_start(int unit, int h_chan) MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); } - avma1pp_fifo(chan, sc); + isic_hscx_fifo(chan, sc); /* call timeout handling routine */ @@ -1215,21 +1644,31 @@ avma1pp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp) splx(s); } -/* - * moved here from avma1pp_bchan_start and avma1pp_hscx_intr - */ -static void -avma1pp_fifo(isic_Bchan_t *chan, struct isic_softc *sc) +/*---------------------------------------------------------------------------* + * fill HSCX fifo with data from the current mbuf + * Put this here until it can go into i4b_hscx.c + *---------------------------------------------------------------------------*/ +int +isic_hscx_fifo(isic_Bchan_t *chan, struct isic_softc *sc) { int len; int nextlen; int i; - /* the "HSCX" probably only allows writing all bytes at once */ - /* so we need a scratch buffer to collect the bytes */ + int cmd; + /* using a scratch buffer simplifies writing to the FIFO */ u_char scrbuf[HSCX_FIFO_LEN]; len = 0; + /* + * fill the HSCX tx fifo with data from the current mbuf. if + * current mbuf holds less data than HSCX fifo length, try to + * get the next mbuf from (a possible) mbuf chain. if there is + * not enough data in a single mbuf or in a chain, then this + * is the last mbuf and we tell the HSCX that it has to send + * CRC and closing flag + */ + while(chan->out_mbuf_cur && len != sc->sc_bfifolen) { nextlen = min(chan->out_mbuf_cur_len, sc->sc_bfifolen - len); @@ -1244,9 +1683,10 @@ avma1pp_fifo(isic_Bchan_t *chan, struct isic_softc *sc) nextlen); #endif + cmd |= HSCX_CMDR_XTF; /* collect the data in the scratch buffer */ for (i = 0; i < nextlen; i++) - scrbuf[i + len] = chan->out_mbuf_cur_ptr[i]; + scrbuf[i + len] = chan->out_mbuf_cur_ptr[i]; len += nextlen; chan->txcount += nextlen; @@ -1274,15 +1714,17 @@ avma1pp_fifo(isic_Bchan_t *chan, struct isic_softc *sc) } else { + if (chan->bprot != BPROT_NONE) + cmd |= HSCX_CMDR_XME; i4b_Bfreembuf(chan->out_mbuf_head); chan->out_mbuf_head = NULL; } } } - /* write what we have from the scratch buf to the "HSCX" fifo */ - - /* HSCX_WRFIFO also sets the XME */ - HSCX_WRFIFO(chan->channel, scrbuf, len); + /* write what we have from the scratch buf to the HSCX fifo */ + if (len != 0) + HSCX_WRFIFO(chan->channel, scrbuf, len); + return(cmd); } #endif /* NISIC > 0 && defined(AVM_A1_PCI) */ diff --git a/sys/i4b/layer1/i4b_avm_fritz_pcmcia.c b/sys/i4b/layer1/i4b_avm_fritz_pcmcia.c index 03029a0..a6f0ad8 100644 --- a/sys/i4b/layer1/i4b_avm_fritz_pcmcia.c +++ b/sys/i4b/layer1/i4b_avm_fritz_pcmcia.c @@ -33,9 +33,9 @@ * Fritz!Card pcmcia specific routines for isic driver * --------------------------------------------------- * - * $Id: i4b_avm_fritz_pcmcia.c,v 1.2 1999/03/07 16:08:15 hm Exp $ + * $Id: i4b_avm_fritz_pcmcia.c,v 1.12 1999/05/03 08:48:25 hm Exp $ * - * last edit-date: [Tue Mar 16 10:49:53 1999] + * last edit-date: [Sun May 2 12:01:16 1999] * * -ap added support for AVM PCMCIA Fritz!Card * -mh split into separate file @@ -80,7 +80,6 @@ #include <i4b/i4b_ioctl.h> #include <dev/pcmcia/pcmciareg.h> #include <dev/pcmcia/pcmciavar.h> -#include <i4b/layer1/pcmcia_isic.h> #endif #include <i4b/layer1/i4b_l1.h> @@ -88,6 +87,8 @@ #include <i4b/layer1/i4b_hscx.h> #ifndef __FreeBSD__ +#include <i4b/layer1/pcmcia_isic.h> + /* PCMCIA support routines */ static u_int8_t avma1_pcmcia_read_reg __P((struct isic_softc *sc, int what, bus_size_t offs)); static void avma1_pcmcia_write_reg __P((struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)); @@ -390,7 +391,7 @@ isic_probe_avma1_pcmcia(struct isa_device *dev) *---------------------------------------------------------------------------*/ #ifdef __FreeBSD__ int -isic_attach_fritz(struct isa_device *dev) +isic_attach_fritzpcmcia(struct isa_device *dev) { /* ResetController again just to make sure... */ diff --git a/sys/i4b/layer1/i4b_bchan.c b/sys/i4b/layer1/i4b_bchan.c index e047c93..bd9dfd0 100644 --- a/sys/i4b/layer1/i4b_bchan.c +++ b/sys/i4b/layer1/i4b_bchan.c @@ -27,7 +27,7 @@ * i4b_bchan.c - B channel handling L1 procedures * ---------------------------------------------- * - * $Id: i4b_bchan.c,v 1.30 1999/02/14 19:51:01 hm Exp $ + * $Id: i4b_bchan.c,v 1.32 1999/03/17 10:41:08 hm Exp $ * * last edit-date: [Sun Feb 14 10:25:27 1999] * diff --git a/sys/i4b/layer1/i4b_bsdi_ibc.c b/sys/i4b/layer1/i4b_bsdi_ibc.c new file mode 100644 index 0000000..9168815 --- /dev/null +++ b/sys/i4b/layer1/i4b_bsdi_ibc.c @@ -0,0 +1,559 @@ +/* + * Copyright (c) 1998, 1999 Bert Driehuis. All rights reserved. + * + * Copyright (c) 1997, 1998 Hellmuth Michaelis. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + *--------------------------------------------------------------------------- + * + * i4b_bsdi_ibc.c - isdn4bsd kernel BSD/OS point to point driver + * ------------------------------------------------------------- + * + * $Id: i4b_bsdi_ibc.c,v 1.1 1999/04/23 08:35:07 hm Exp $ + * + * last edit-date: [Fri Apr 23 10:27:57 1999] + * + *---------------------------------------------------------------------------*/ + +#include "ibc.h" + +#if NIBC > 0 + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> +#include <sys/errno.h> +#include <sys/ioccom.h> +#include <sys/ttycom.h> +#include <sys/sockio.h> +#include <sys/kernel.h> +#include <sys/protosw.h> + +#include <net/if.h> +#include <net/if_types.h> +#include <net/if_p2p.h> +#include <net/netisr.h> +#include <net/route.h> + +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/in_var.h> +#include <netinet/ip.h> + +#include <i4b/i4b_ioctl.h> +#include <i4b/i4b_cause.h> +#include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_mbuf.h> +#include <i4b/include/i4b_l3l4.h> +#include <i4b/layer4/i4b_l4.h> + +#define IFP2UNIT(ifp) (ifp)->if_unit + +#define IOCTL_CMD_T u_long + +void ibcattach(void *); + +#define IBCACCT 1 /* enable accounting messages */ +#define IBCACCTINTVL 2 /* accounting msg interval in secs */ + +#define PPP_HDRLEN 4 /* 4 octets PPP header length */ + +struct ibc_softc { + struct p2pcom sc_p2pcom; + + int sc_state; /* state of the interface */ + call_desc_t *sc_cdp; /* ptr to call descriptor */ + +#ifdef IBCACCT + int sc_iinb; /* isdn driver # of inbytes */ + int sc_ioutb; /* isdn driver # of outbytes */ + int sc_inb; /* # of bytes rx'd */ + int sc_outb; /* # of bytes tx'd */ + int sc_linb; /* last # of bytes rx'd */ + int sc_loutb; /* last # of bytes tx'd */ + int sc_fn; /* flag, first null acct */ +#endif +} ibc_softc[NIBC]; + +static void ibc_init_linktab(int unit); + +static int ibc_start(struct ifnet *ifp); + +static int ibc_watchdog(int unit); +static int ibc_mdmctl(struct p2pcom *pp, int flag); +static int ibc_getmdm(struct p2pcom *pp, caddr_t arg); + +/* initialized by L4 */ + +static drvr_link_t ibc_drvr_linktab[NIBC]; +static isdn_link_t *isdn_ibc_lt[NIBC]; + +enum ibc_states { + ST_IDLE, /* initialized, ready, idle */ + ST_DIALING, /* dialling out to remote */ + ST_CONNECTED, /* connected to remote */ +}; + +int ibcdebug = 0; /* Use bpatch to set this for debug printf's */ +#define DBG(x) if (ibcdebug) printf x + +/*===========================================================================* + * DEVICE DRIVER ROUTINES + *===========================================================================*/ + +/*---------------------------------------------------------------------------* + * interface attach routine at kernel boot time + *---------------------------------------------------------------------------*/ +void +ibcattach(void *dummy) +{ + struct ibc_softc *sc = ibc_softc; + struct ifnet *ifp; + int i; + +#ifndef HACK_NO_PSEUDO_ATTACH_MSG + printf("ibc: %d ISDN ibc device(s) attached\n", + NIBC); +#endif + + for(i = 0; i < NIBC; sc++, i++) { + ibc_init_linktab(i); + + sc->sc_p2pcom.p2p_mdmctl = ibc_mdmctl; + sc->sc_p2pcom.p2p_getmdm = ibc_getmdm; + sc->sc_state = ST_IDLE; + ifp = &sc->sc_p2pcom.p2p_if; + ifp->if_name = "ibc"; + ifp->if_next = NULL; + ifp->if_unit = i; + ifp->if_mtu = 1500 /*XXX*/; + ifp->if_baudrate = 64000; + ifp->if_flags = IFF_SIMPLEX | IFF_POINTOPOINT; + ifp->if_type = IFT_ISDNBASIC; + ifp->if_start = ibc_start; + ifp->if_output = 0; + ifp->if_ioctl = p2p_ioctl; + + ifp->if_hdrlen = 0; + ifp->if_addrlen = 0; + ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; + + ifp->if_ipackets = 0; + ifp->if_ierrors = 0; + ifp->if_opackets = 0; + ifp->if_oerrors = 0; + ifp->if_collisions = 0; + ifp->if_ibytes = 0; + ifp->if_obytes = 0; + ifp->if_imcasts = 0; + ifp->if_omcasts = 0; + ifp->if_iqdrops = 0; + ifp->if_noproto = 0; +#if IBCACCT + ifp->if_timer = 0; + ifp->if_watchdog = ibc_watchdog; + sc->sc_iinb = 0; + sc->sc_ioutb = 0; + sc->sc_inb = 0; + sc->sc_outb = 0; + sc->sc_linb = 0; + sc->sc_loutb = 0; + sc->sc_fn = 1; +#endif + if_attach(ifp); + p2p_attach(&sc->sc_p2pcom); + } +} + +static struct mbuf * +p2p_dequeue(struct p2pcom *pp) +{ + struct ifqueue *ifq; + struct mbuf *m; + + ifq = &pp->p2p_isnd; + m = ifq->ifq_head; + if (m == 0) { + ifq = &pp->p2p_if.if_snd; + m = ifq->ifq_head; + } + if (m == 0) + return 0; + IF_DEQUEUE(ifq, m); + return m; +} + +/*---------------------------------------------------------------------------* + * start output to ISDN B-channel + *---------------------------------------------------------------------------*/ +static int +ibc_start(struct ifnet *ifp) +{ + int unit = IFP2UNIT(ifp); + struct ibc_softc *sc = (struct ibc_softc *)&ibc_softc[unit]; + struct p2pcom *pp = &sc->sc_p2pcom; + struct mbuf *m; + int s; + + if(sc->sc_state != ST_CONNECTED) { + DBG(("ibc%d: ibc_start called with sc_state=%d\n", + unit, sc->sc_state)); + return 0; + } + + s = SPLI4B(); + + if (IF_QFULL(isdn_ibc_lt[unit]->tx_queue)) { + splx(s); + return 0; + } + + m = p2p_dequeue(pp); + if (m == NULL) { + splx(s); + return 0; + } + + do { + microtime(&ifp->if_lastchange); + + IF_ENQUEUE(isdn_ibc_lt[unit]->tx_queue, m); + + ifp->if_obytes += m->m_pkthdr.len; + sc->sc_outb += m->m_pkthdr.len; + ifp->if_opackets++; + } while (!IF_QFULL(isdn_ibc_lt[unit]->tx_queue) && + (m = p2p_dequeue(pp)) != NULL); + isdn_ibc_lt[unit]->bch_tx_start(isdn_ibc_lt[unit]->unit, + isdn_ibc_lt[unit]->channel); + splx(s); + return 0; +} + +#ifdef IBCACCT +/*---------------------------------------------------------------------------* + * watchdog routine + *---------------------------------------------------------------------------*/ +static int +ibc_watchdog(int unit) +{ + struct ibc_softc *sc = &ibc_softc[unit]; + struct ifnet *ifp = &sc->sc_p2pcom.p2p_if; + bchan_statistics_t bs; + + (*isdn_ibc_lt[unit]->bch_stat) + (isdn_ibc_lt[unit]->unit, isdn_ibc_lt[unit]->channel, &bs); + + sc->sc_ioutb += bs.outbytes; + sc->sc_iinb += bs.inbytes; + + if((sc->sc_iinb != sc->sc_linb) || (sc->sc_ioutb != sc->sc_loutb) || sc->sc_fn) + { + int ri = (sc->sc_iinb - sc->sc_linb)/IBCACCTINTVL; + int ro = (sc->sc_ioutb - sc->sc_loutb)/IBCACCTINTVL; + + if((sc->sc_iinb == sc->sc_linb) && (sc->sc_ioutb == sc->sc_loutb)) + sc->sc_fn = 0; + else + sc->sc_fn = 1; + + sc->sc_linb = sc->sc_iinb; + sc->sc_loutb = sc->sc_ioutb; + + i4b_l4_accounting(BDRV_IBC, unit, ACCT_DURING, + sc->sc_ioutb, sc->sc_iinb, ro, ri, sc->sc_outb, sc->sc_inb); + } + ifp->if_timer = IBCACCTINTVL; + return 0; +} +#endif /* IBCACCT */ + +/* + *===========================================================================* + * P2P layer interface routines + *===========================================================================* + */ + +#if 0 +/*---------------------------------------------------------------------------* + * PPP interface phase change + *---------------------------------------------------------------------------* + */ +static void +ibc_state_changed(struct sppp *sp, int new_state) +{ + struct ibc_softc *sc = (struct ibc_softc *)sp; + + i4b_l4_ifstate_changed(sc->sc_cdp, new_state); +} + +/*---------------------------------------------------------------------------* + * PPP control protocol negotiation complete (run ip-up script now) + *---------------------------------------------------------------------------* + */ +static void +ibc_negotiation_complete(struct sppp *sp) +{ + struct ibc_softc *sc = (struct ibc_softc *)sp; + + i4b_l4_negcomplete(sc->sc_cdp); +} +#endif + +/*===========================================================================* + * ISDN INTERFACE ROUTINES + *===========================================================================*/ + +/*---------------------------------------------------------------------------* + * this routine is called from L4 handler at connect time + *---------------------------------------------------------------------------*/ +static void +ibc_connect(int unit, void *cdp) +{ + struct ibc_softc *sc = &ibc_softc[unit]; + struct ifnet *ifp = &sc->sc_p2pcom.p2p_if; + int s; + + DBG(("ibc%d: ibc_connect\n", unit)); + + s = splimp(); + + sc->sc_cdp = (call_desc_t *)cdp; + sc->sc_state = ST_CONNECTED; + +#if IBCACCT + sc->sc_iinb = 0; + sc->sc_ioutb = 0; + sc->sc_inb = 0; + sc->sc_outb = 0; + sc->sc_linb = 0; + sc->sc_loutb = 0; + ifp->if_timer = IBCACCTINTVL; +#endif + + splx(s); + if (sc->sc_p2pcom.p2p_modem) + (*sc->sc_p2pcom.p2p_modem)(&sc->sc_p2pcom, 1); + + /* This is a lie... PPP is just starting to negociate :-) */ + i4b_l4_negcomplete(sc->sc_cdp); +} + +/*---------------------------------------------------------------------------* + * this routine is called from L4 handler at disconnect time + *---------------------------------------------------------------------------*/ +static void +ibc_disconnect(int unit, void *cdp) +{ + call_desc_t *cd = (call_desc_t *)cdp; + struct ibc_softc *sc = &ibc_softc[unit]; + struct ifnet *ifp = &sc->sc_p2pcom.p2p_if; + int s; + + DBG(("ibc%d: ibc_disconnect\n", unit)); + + s = splimp(); + + /* new stuff to check that the active channel is being closed */ + if (cd != sc->sc_cdp) + { + DBG(("ibc_disconnect: ibc%d channel%d not active\n", + cd->driver_unit, cd->channelid)); + splx(s); + return; + } + +#if IBCACCT + ifp->if_timer = 0; +#endif + + i4b_l4_accounting(BDRV_IBC, unit, ACCT_FINAL, + sc->sc_ioutb, sc->sc_iinb, 0, 0, sc->sc_outb, sc->sc_inb); + + if (sc->sc_state == ST_CONNECTED) + { + sc->sc_cdp = (call_desc_t *)0; + sc->sc_state = ST_IDLE; + if (sc->sc_p2pcom.p2p_modem) + (*sc->sc_p2pcom.p2p_modem)(&sc->sc_p2pcom, 0); + } + + splx(s); +} + +/*---------------------------------------------------------------------------* + * this routine is used to give a feedback from userland demon + * in case of dial problems + *---------------------------------------------------------------------------*/ +static void +ibc_dialresponse(int unit, int status) +{ + DBG(("ibc%d: ibc_dialresponse %d\n", unit, status)); +/* struct ibc_softc *sc = &ibc_softc[unit]; */ +} + +/*---------------------------------------------------------------------------* + * interface up/down + *---------------------------------------------------------------------------*/ +static void +ibc_updown(int unit, int updown) +{ + DBG(("ibc%d: ibc_updown %d\n", unit, updown)); + /* could probably do something useful here */ +} + +/*---------------------------------------------------------------------------* + * this routine is called from the HSCX interrupt handler + * when a new frame (mbuf) has been received and was put on + * the rx queue. + *---------------------------------------------------------------------------*/ +static void +ibc_rx_data_rdy(int unit) +{ + struct ibc_softc *sc = &ibc_softc[unit]; + struct ifnet *ifp = &sc->sc_p2pcom.p2p_if; + struct mbuf *m, *m0; + char *buf; + int s; + + if((m = *isdn_ibc_lt[unit]->rx_mbuf) == NULL) + return; + + microtime(&ifp->if_lastchange); + ifp->if_ipackets++; + + /* Walk the mbuf chain */ + s = splimp(); + for (m0 = m; m != 0; m = m->m_next) { + if (m->m_len == 0) + continue; + ifp->if_ibytes += m->m_len; +#if IBCACCT + sc->sc_inb += m->m_len; +#endif + buf = mtod(m, caddr_t); + if ((*sc->sc_p2pcom.p2p_hdrinput)( + &sc->sc_p2pcom, buf, m->m_len) >= 0) + (*sc->sc_p2pcom.p2p_input)(&sc->sc_p2pcom, 0); + } + splx(s); + m_freem(m0); +} + +/*---------------------------------------------------------------------------* + * this routine is called from the HSCX interrupt handler + * when the last frame has been sent out and there is no + * further frame (mbuf) in the tx queue. + *---------------------------------------------------------------------------*/ +static void +ibc_tx_queue_empty(int unit) +{ + ibc_start(&ibc_softc[unit].sc_p2pcom.p2p_if); +} + +/*---------------------------------------------------------------------------* + * this routine is called from the HSCX interrupt handler + * each time a packet is received or transmitted. It should + * be used to implement an activity timeout mechanism. + *---------------------------------------------------------------------------*/ +static void +ibc_activity(int unit, int rxtx) +{ + ibc_softc[unit].sc_cdp->last_active_time = SECOND; +} + +/*---------------------------------------------------------------------------* + * return this drivers linktab address + *---------------------------------------------------------------------------*/ +drvr_link_t * +ibc_ret_linktab(int unit) +{ + return(&ibc_drvr_linktab[unit]); +} + +/*---------------------------------------------------------------------------* + * setup the isdn_ibc_lt for this driver + *---------------------------------------------------------------------------*/ +void +ibc_set_linktab(int unit, isdn_link_t *ilt) +{ + isdn_ibc_lt[unit] = ilt; +} + +/*---------------------------------------------------------------------------* + * initialize this drivers linktab + *---------------------------------------------------------------------------*/ +static void +ibc_init_linktab(int unit) +{ + ibc_drvr_linktab[unit].unit = unit; + ibc_drvr_linktab[unit].bch_rx_data_ready = ibc_rx_data_rdy; + ibc_drvr_linktab[unit].bch_tx_queue_empty = ibc_tx_queue_empty; + ibc_drvr_linktab[unit].bch_activity = ibc_activity; + ibc_drvr_linktab[unit].line_connected = ibc_connect; + ibc_drvr_linktab[unit].line_disconnected = ibc_disconnect; + ibc_drvr_linktab[unit].dial_response = ibc_dialresponse; + ibc_drvr_linktab[unit].updown_ind = ibc_updown; +} + +/*===========================================================================*/ + +static int +ibc_mdmctl(pp, flag) + struct p2pcom *pp; + int flag; +{ + register struct ifnet *ifp = &pp->p2p_if; + struct ibc_softc *sc = (struct ibc_softc *)&ibc_softc[ifp->if_unit]; + + DBG(("ibc%d: ibc_mdmctl called flags=%d\n", IFP2UNIT(ifp), flag)); + + if (flag == 1 && sc->sc_state == ST_IDLE) { + sc->sc_state = ST_DIALING; + i4b_l4_dialout(BDRV_IBC, IFP2UNIT(ifp)); + } else if (flag == 0 && sc->sc_state != ST_IDLE) { + sc->sc_state = ST_IDLE; + i4b_l4_drvrdisc(BDRV_IBC, IFP2UNIT(ifp)); + } + return 0; +} + +static int +ibc_getmdm(pp, arg) + struct p2pcom *pp; + caddr_t arg; +{ + register struct ifnet *ifp = &pp->p2p_if; + struct ibc_softc *sc = (struct ibc_softc *)&ibc_softc[ifp->if_unit]; + + if (sc->sc_state == ST_CONNECTED) + *(int *)arg = TIOCM_CAR; + else + *(int *)arg = 0; + return 0; + + DBG(("ibc%d: ibc_getmdm called ret=%d\n", IFP2UNIT(ifp), *(int *)arg)); +} +#endif diff --git a/sys/i4b/layer1/i4b_elsa_qs1i.c b/sys/i4b/layer1/i4b_elsa_qs1i.c index d43a637..573bb86 100644 --- a/sys/i4b/layer1/i4b_elsa_qs1i.c +++ b/sys/i4b/layer1/i4b_elsa_qs1i.c @@ -27,9 +27,9 @@ * isic - I4B Siemens ISDN Chipset Driver for ELSA Quickstep 1000pro ISA * ===================================================================== * - * $Id: i4b_elsa_qs1i.c,v 1.14 1999/02/14 11:02:04 hm Exp $ + * $Id: i4b_elsa_qs1i.c,v 1.15 1999/03/16 14:57:53 hm Exp $ * - * last edit-date: [Sun Feb 14 11:59:45 1999] + * last edit-date: [Tue Mar 16 15:42:10 1999] * *---------------------------------------------------------------------------*/ @@ -46,7 +46,11 @@ #endif -#if (NISIC > 0) && (NPNP > 0) && defined(ELSA_QS1ISA) +/* + * this driver works for both the ELSA QuickStep 1000 PNP and the ELSA + * PCC-16 + */ +#if (NISIC > 0) && (((NPNP > 0) && defined(ELSA_QS1ISA)) || defined(ELSA_PCC16)) #include <sys/param.h> #include <sys/kernel.h> diff --git a/sys/i4b/layer1/i4b_elsa_qs1p.c b/sys/i4b/layer1/i4b_elsa_qs1p.c index 43dd343..0cc0a01 100644 --- a/sys/i4b/layer1/i4b_elsa_qs1p.c +++ b/sys/i4b/layer1/i4b_elsa_qs1p.c @@ -27,9 +27,9 @@ * isic - I4B Siemens ISDN Chipset Driver for ELSA Quickstep 1000pro PCI * ===================================================================== * - * $Id: i4b_elsa_qs1p.c,v 1.5 1999/02/14 09:44:59 hm Exp $ + * $Id: i4b_elsa_qs1p.c,v 1.6 1999/03/16 15:21:55 hm Exp $ * - * last edit-date: [Sun Feb 14 10:26:43 1999] + * last edit-date: [Wed Mar 10 07:24:32 1999] * *---------------------------------------------------------------------------*/ @@ -86,8 +86,7 @@ #include <i4b/layer1/i4b_ipac.h> #ifndef __FreeBSD__ -/* we don't have the function prototypes in the global i4b_l1.h any more */ -void isic_attach_Eqs1pp __P((struct isic_softc *sc, struct pci_attach_args *pa)); +#include <i4b/layer1/pci_isic.h> #endif /* masks for register encoded in base addr */ @@ -400,10 +399,12 @@ isic_attach_Eqs1pp(int unit, unsigned int iobase1, unsigned int iobase2) #else /* !FreeBSD */ void -isic_attach_Eqs1pp(sc, pa) - struct isic_softc *sc; +isic_attach_Eqs1pp(psc, pa) + struct pci_isic_softc *psc; struct pci_attach_args *pa; { + struct isic_softc *sc = &psc->sc_isic; + /* setup io mappings */ sc->sc_num_mappings = 2; MALLOC_MAPS(sc); diff --git a/sys/i4b/layer1/i4b_hscx.c b/sys/i4b/layer1/i4b_hscx.c index 29c2f40..4ddf779 100644 --- a/sys/i4b/layer1/i4b_hscx.c +++ b/sys/i4b/layer1/i4b_hscx.c @@ -27,9 +27,9 @@ * i4b - Siemens HSCX chip (B-channel) handling * -------------------------------------------- * - * $Id: i4b_hscx.c,v 1.39 1999/02/14 19:51:01 hm Exp $ + * $Id: i4b_hscx.c,v 1.42 1999/03/17 13:44:50 hm Exp $ * - * last edit-date: [Sun Feb 14 10:26:49 1999] + * last edit-date: [Wed Mar 17 11:59:05 1999] * *---------------------------------------------------------------------------*/ @@ -288,14 +288,23 @@ isic_hscx_irq(register struct isic_softc *sc, u_char ista, int h_chan, u_char ex MPH_Trace_Ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data); } - /* move rx'd data to rx queue */ - - IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf); + /* silence detection */ - (*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit); - if(!(isic_hscx_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len))) activity = ACT_RX; + + if(!(IF_QFULL(&chan->rx_queue))) + { + IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf); + } + else + { + i4b_Bfreembuf(chan->in_mbuf); + } + + /* signal upper driver that data is available */ + + (*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit); /* alloc new buffer */ diff --git a/sys/i4b/layer1/i4b_isic.c b/sys/i4b/layer1/i4b_isic.c index 127fae2..f403faf 100644 --- a/sys/i4b/layer1/i4b_isic.c +++ b/sys/i4b/layer1/i4b_isic.c @@ -27,7 +27,7 @@ * i4b_isic.c - global isic stuff * ============================== * - * $Id: i4b_isic.c,v 1.46 1999/02/14 19:51:02 hm Exp $ + * $Id: i4b_isic.c,v 1.47 1999/04/20 09:34:14 hm Exp $ * * last edit-date: [Sun Feb 14 10:27:20 1999] * @@ -209,7 +209,7 @@ isicintr(void *arg) was_isac_irq = 1; } } -#ifndef amiga /* XXX should be: #if INTERUPTS_ARE_SHARED */ +#if !defined(amiga) && !defined(atari) /* XXX should be: #if INTS_ARE_SHARED */ #ifdef ELSA_QS1ISA if(sc->sc_cardtyp != CARD_TYPEP_ELSAQS1ISA) { @@ -219,7 +219,7 @@ isicintr(void *arg) #ifdef ELSA_QS1ISA } #endif -#endif /* AMIGA */ +#endif /* !AMIGA && !ATARI */ HSCX_WRITE(0, H_MASK, 0xff); ISAC_WRITE(I_MASK, 0xff); diff --git a/sys/i4b/layer1/i4b_isic_isa.c b/sys/i4b/layer1/i4b_isic_isa.c index aa722c0..4147355 100644 --- a/sys/i4b/layer1/i4b_isic_isa.c +++ b/sys/i4b/layer1/i4b_isic_isa.c @@ -27,9 +27,9 @@ * i4b_isic_isa.c - ISA bus interface * ================================== * - * $Id: i4b_isic_isa.c,v 1.2 1999/03/07 16:08:15 hm Exp $ + * $Id: i4b_isic_isa.c,v 1.20 1999/05/10 09:37:35 hm Exp $ * - * last edit-date: [Tue Mar 16 10:35:38 1999] + * last edit-date: [Tue Apr 20 11:47:59 1999] * *---------------------------------------------------------------------------*/ @@ -98,7 +98,7 @@ void isicintr ( int unit ); void isicintr_sc(struct isic_softc *sc); static int isicprobe(struct isa_device *dev); -static int isicattach(struct isa_device *dev); +int isicattach(struct isa_device *dev); struct isa_driver isicdriver = { isicprobe, @@ -198,6 +198,12 @@ isicprobe(struct isa_device *dev) break; #endif +#ifdef ELSA_PCC16 + case FLAG_ELSA_PCC16: + ret = isic_probe_Eqs1pi(dev, 0); + break; +#endif + default: break; } @@ -250,6 +256,12 @@ isa_isicmatch(struct device *parent, struct cfdata *cf, struct isa_attach_args * break; #endif +#ifdef ELSA_PCC16 + case FLAG_ELSA_PCC16: + ret = isic_probe_Eqs1pi(dev, 0); + break; +#endif + default: break; } @@ -274,7 +286,7 @@ isicprobe(struct isic_attach_args *args) /*---------------------------------------------------------------------------* * isic - non-pnp device driver attach routine *---------------------------------------------------------------------------*/ -static int +int isicattach(struct isa_device *dev) { return(isic_realattach(dev, 0)); @@ -395,6 +407,12 @@ isicattach(int flags, struct isic_softc *sc) break; #endif +#ifdef ELSA_PCC16 + case FLAG_ELSA_PCC16: + ret = isic_attach_Eqs1pi(dev, 0); + break; +#endif + /* ====================================================================== * Only P&P cards follow below!!! */ @@ -404,7 +422,7 @@ isicattach(int flags, struct isic_softc *sc) #ifdef AVM_A1_PCMCIA case FLAG_AVM_A1_PCMCIA: - ret = isic_attach_fritz(PARM); + ret = isic_attach_fritzpcmcia(PARM); break; #endif @@ -592,6 +610,10 @@ isicattach(int flags, struct isic_softc *sc) drvid = "ITK ix1 micro"; break; + case FLAG_ELSA_PCC16: + drvid = "ELSA PCC-16"; + break; + default: drvid = "ERROR, unknown flag used"; break; diff --git a/sys/i4b/layer1/i4b_isic_pci.c b/sys/i4b/layer1/i4b_isic_pci.c index c17dfc6..f732dd1 100644 --- a/sys/i4b/layer1/i4b_isic_pci.c +++ b/sys/i4b/layer1/i4b_isic_pci.c @@ -27,9 +27,9 @@ * i4b_isic_pci.c - PCI bus interface * ================================== * - * $Id: i4b_isic_pci.c,v 1.4 1999/04/24 20:24:02 peter Exp $ + * $Id: i4b_isic_pci.c,v 1.14 1999/04/28 04:12:51 hm Exp $ * - * last edit-date: [Wed Feb 17 15:19:44 1999] + * last edit-date: [Wed Apr 21 09:57:37 1999] * *---------------------------------------------------------------------------*/ @@ -88,7 +88,7 @@ #define PORT0_MAPOFF 4 #define PORT1_MAPOFF 12 -static char* i4b_pci_probe(pcici_t tag, pcidi_t type); +static const char *i4b_pci_probe(pcici_t tag, pcidi_t type); static void i4b_pci_attach(pcici_t config_id, int unit); static int isic_pciattach(int unit, u_long type, u_int iobase1, u_int iobase2); @@ -102,7 +102,15 @@ static struct pci_device i4b_pci_driver = { NULL }; +#if defined(__FreeBSD_version) && __FreeBSD_version >= 400004 +#ifndef COMPAT_PCI_DRIVER +DATA_SET (pcidevice_set, i4b_pci_driver); +#else COMPAT_PCI_DRIVER (isic_pci, i4b_pci_driver); +#endif /* COMPAT_PCI_DRIVER */ +#else /* __FreeBSD_version >= 400004 */ +DATA_SET (pcidevice_set, i4b_pci_driver); +#endif /* __FreeBSD_version >= 400004 */ static void isic_pci_intr_sc(struct isic_softc *sc); @@ -114,7 +122,7 @@ extern void avma1pp_map_int(pcici_t, void *, unsigned *); /*---------------------------------------------------------------------------* * PCI probe routine *---------------------------------------------------------------------------*/ -static char * +static const char * i4b_pci_probe(pcici_t tag, pcidi_t type) { switch(type) @@ -151,7 +159,7 @@ i4b_pci_attach(pcici_t config_id, int unit) return; } - /* IMHO the all following should be done in the low-level driver - GJ */ + /* IMHO all the following should be done in the low-level driver - GJ */ type = pci_conf_read(config_id, PCI_ID_REG); /* not all cards have their ports at the same location !!! */ diff --git a/sys/i4b/layer1/i4b_isic_pcmcia.c b/sys/i4b/layer1/i4b_isic_pcmcia.c index 47f78e4..f6ceb5d 100644 --- a/sys/i4b/layer1/i4b_isic_pcmcia.c +++ b/sys/i4b/layer1/i4b_isic_pcmcia.c @@ -35,14 +35,13 @@ * i4b_isic_pcmcia.c - i4b FreeBSD PCMCIA support * ---------------------------------------------- * - * $Id: i4b_isic_pcmcia.c,v 1.5 1999/03/16 11:07:04 hm Exp $ + * $Id: i4b_isic_pcmcia.c,v 1.9 1999/04/27 09:49:49 hm Exp $ * - * last edit-date: [Tue Mar 16 10:36:56 1999] + * last edit-date: [Mon Apr 26 10:52:57 1999] * *---------------------------------------------------------------------------*/ #ifdef __FreeBSD__ - #include "isic.h" #include "opt_i4b.h" #include "card.h" @@ -53,9 +52,9 @@ #include <sys/types.h> #include <sys/select.h> #include <sys/param.h> +#include <i386/isa/isa_device.h> #if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include <sys/module.h> #include <sys/ioccom.h> #else #include <sys/ioctl.h> @@ -89,10 +88,14 @@ #if !(defined(__FreeBSD_version)) || (defined(__FreeBSD_version) && __FreeBSD_version >= 300006) void isicintr ( int unit ); +#else +extern void isicintr(int unit); #endif #endif +extern int isicattach(struct isa_device *dev); + /* * PC-Card (PCMCIA) specific code. */ @@ -100,9 +103,7 @@ static int isic_pccard_init __P((struct pccard_devinfo *)); static void isic_unload __P((struct pccard_devinfo *)); static int isic_card_intr __P((struct pccard_devinfo *)); -#ifdef PCCARD_MODULE -PCCARD_MODULE(isic_pcmcia, isic_pccard_init, isic_unload, isic_card_intr, 0, net_imask); -#else +#if defined(__FreeBSD__) && __FreeBSD__ < 3 static struct pccard_device isic_info = { "isic", isic_pccard_init, @@ -110,11 +111,14 @@ static struct pccard_device isic_info = { isic_card_intr, 0, /* Attributes - presently unused */ &net_imask -}; - +}; + DATA_SET(pccarddrv_set, isic_info); +#else +PCCARD_MODULE(isic, isic_pccard_init, isic_unload, isic_card_intr, 0,net_imask); #endif + /* * Initialize the device - called from Slot manager. */ @@ -124,6 +128,7 @@ static int opened = 0; /* our cards status */ static int isic_pccard_init(devi) struct pccard_devinfo *devi; { +#ifdef AVM_A1_PCMCIA struct isa_device *is = &devi->isahd; if ((1 << is->id_unit) & opened) @@ -149,6 +154,7 @@ struct pccard_devinfo *devi; isic_realattach(is, 0); +#endif return(0); } diff --git a/sys/i4b/layer1/i4b_isic_pnp.c b/sys/i4b/layer1/i4b_isic_pnp.c index eddfb9d..a9f056a 100644 --- a/sys/i4b/layer1/i4b_isic_pnp.c +++ b/sys/i4b/layer1/i4b_isic_pnp.c @@ -37,9 +37,9 @@ * i4b_isic_pnp.c - i4b pnp support * -------------------------------- * - * $Id: i4b_isic_pnp.c,v 1.2 1999/03/07 16:08:16 hm Exp $ + * $Id: i4b_isic_pnp.c,v 1.17 1999/04/20 14:28:46 hm Exp $ * - * last edit-date: [Sun Feb 14 10:27:52 1999] + * last edit-date: [Tue Apr 20 16:12:27 1999] * *---------------------------------------------------------------------------*/ @@ -219,7 +219,16 @@ i4b_pnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev) if(dev->id_driver == NULL) { dev->id_driver = &isicdriver; +#if(defined(__FreeBSD_version) && __FreeBSD_version >= 400004) dev->id_id = isa_compat_nextid(); +#else + isa_devp = find_isadev(isa_devtab_net, &isicdriver, 0); + + if(isa_devp != NULL) + { + dev->id_id = isa_devp->id_id; + } +#endif } if((dev->id_alive = isic_pnpprobe(dev, spci.port[1])) != 0) diff --git a/sys/i4b/layer1/i4b_l1.h b/sys/i4b/layer1/i4b_l1.h index f00598a..6b455fa 100644 --- a/sys/i4b/layer1/i4b_l1.h +++ b/sys/i4b/layer1/i4b_l1.h @@ -27,9 +27,9 @@ * i4b_l1.h - isdn4bsd layer 1 header file * --------------------------------------- * - * $Id: i4b_l1.h,v 1.2 1999/03/07 16:08:16 hm Exp $ + * $Id: i4b_l1.h,v 1.61 1999/04/21 07:50:31 hm Exp $ * - * last edit-date: [Tue Mar 16 10:38:03 1999] + * last edit-date: [Tue Mar 16 15:50:24 1999] * *---------------------------------------------------------------------------*/ @@ -76,6 +76,7 @@ #define FLAG_ELSA_MLIMC 16 /* XXX - not needed, remove! */ #define FLAG_ELSA_MLMCALL 17 /* XXX - not needed, remove! */ #define FLAG_ITK_IX1 18 +#define FLAG_ELSA_PCC16 19 #define SEC_DELAY 1000000 /* one second DELAY for DELAY*/ @@ -383,7 +384,7 @@ extern struct isic_softc isic_sc[]; extern void isic_recover(struct isic_softc *sc); extern int isic_realattach(struct isa_device *dev, unsigned int iobase2); extern int isic_attach_avma1 ( struct isa_device *dev ); -extern int isic_attach_fritz ( struct isa_device *dev ); +extern int isic_attach_fritzpcmcia ( struct isa_device *dev ); extern int isic_attach_Cs0P ( struct isa_device *dev, unsigned int iobase2); extern int isic_attach_Dyn ( struct isa_device *dev, unsigned int iobase2); extern int isic_attach_s016 ( struct isa_device *dev ); @@ -397,6 +398,7 @@ extern int isic_attach_sws ( struct isa_device *dev ); extern int isic_attach_Eqs1pi(struct isa_device *dev, unsigned int iobase2); extern int isic_attach_Eqs1pp(int unit, unsigned int iobase1, unsigned int iobase2); extern void isic_bchannel_setup (int unit, int hscx_channel, int bprot, int activate ); +extern int isic_hscx_fifo(isic_Bchan_t *, struct isic_softc *); extern void isic_hscx_init ( struct isic_softc *sc, int hscx_channel, int activate ); extern void isic_hscx_irq ( struct isic_softc *sc, u_char ista, int hscx_channel, u_char ex_irq ); extern int isic_hscx_silence ( unsigned char *data, int len ); diff --git a/sys/i4b/layer1/i4b_tel_s0P.c b/sys/i4b/layer1/i4b_tel_s0P.c index 7ee1d06..f0315b0 100644 --- a/sys/i4b/layer1/i4b_tel_s0P.c +++ b/sys/i4b/layer1/i4b_tel_s0P.c @@ -38,7 +38,7 @@ * EXPERIMENTAL !!! * ================ * - * $Id: i4b_tel_s0P.c,v 1.2 1999/03/07 16:08:16 hm Exp $ + * $Id: i4b_tel_s0P.c,v 1.14 1999/03/16 11:12:31 hm Exp $ * * last edit-date: [Tue Mar 16 10:39:14 1999] * diff --git a/sys/i4b/layer1/isapnp_isic.c b/sys/i4b/layer1/isapnp_isic.c index c340d8f..a902995 100644 --- a/sys/i4b/layer1/isapnp_isic.c +++ b/sys/i4b/layer1/isapnp_isic.c @@ -33,9 +33,9 @@ * isapnp_isic.c - ISA-P&P bus frontend for i4b_isic driver * -------------------------------------------------------- * - * $Id: isapnp_isic.c,v 1.10 1999/02/14 09:45:00 hm Exp $ + * $Id: isapnp_isic.c,v 1.11 1999/05/03 08:48:25 hm Exp $ * - * last edit-date: [Sun Feb 14 10:29:15 1999] + * last edit-date: [Sun May 2 11:57:08 1999] * * -mh original implementation * -hm NetBSD patches from Martin @@ -92,8 +92,12 @@ typedef void (*attach_func)(struct isic_softc *sc); /* map allocators */ static void generic_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc); +#ifdef DRN_NGO static void ngo_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc); +#endif +#if defined(CRTX_S0_P) || defined(TEL_S0_16_3_P) static void tls_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc); +#endif /* card attach functions */ extern void isic_attach_Cs0P __P((struct isic_softc *sc)); @@ -350,6 +354,7 @@ generic_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc) sc->sc_maps[0].size = 0; /* foreign mapping, leave it alone */ } +#ifdef DRN_NGO static void ngo_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc) { @@ -362,7 +367,9 @@ ngo_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc) sc->sc_maps[1].h = ipa->ipa_io[1].h; sc->sc_maps[1].size = 0; } +#endif +#if defined(CRTX_S0_P) || defined(TEL_S0_16_3_P) static void tls_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc) { @@ -384,3 +391,4 @@ tls_pnp_mapalloc(struct isapnp_attach_args *ipa, struct isic_softc *sc) sc->sc_maps[3].h = ipa->ipa_io[1].h; sc->sc_maps[3].size = 0; } +#endif diff --git a/sys/i4b/layer1/isic_supio.c b/sys/i4b/layer1/isic_supio.c index 24cc1de..0a80fbb 100644 --- a/sys/i4b/layer1/isic_supio.c +++ b/sys/i4b/layer1/isic_supio.c @@ -33,15 +33,17 @@ * isic_supio.c - Amiga supio pseudo bus frontend for i4b_isic driver * supports: * - ISDN Blaster 5001/1 + * - ISDN MasterII 5000/1 * - ISDN Master 2092/64 - * But we attach to the supio, so just see "isic". - * ----------------------------------------------- + * But we attach to the supio, so just see "isic" or "isicII". + * ----------------------------------------------------------- * - * $Id: isic_supio.c,v 1.6 1999/02/14 09:45:00 hm Exp $ + * $Id: isic_supio.c,v 1.7 1999/03/24 10:09:03 hm Exp $ * - * last edit-date: [Sun Feb 14 10:29:19 1999] + * last edit-date: [Mon Mar 22 22:49:20 MET 1999] * - * -is original implementation + * -is ISDN Master II support added. + * -is original implementation [Sun Feb 14 10:29:19 1999] * *---------------------------------------------------------------------------*/ @@ -105,7 +107,8 @@ isic_supio_match(parent, cf, aux) struct supio_attach_args *sap = aux; /* ARGSUSED */ - return (!strcmp("isic", sap->supio_name)); + return (!strcmp("isic", sap->supio_name) || + !strcmp("isicII", sap->supio_name)); } int isic_supio_ipl = 2; @@ -124,6 +127,8 @@ isic_supio_attach(parent, self, aux) bus_space_tag_t bst; bus_space_handle_t h; + int o1, o2; + /* setup parameters */ sc->sc_cardtyp = CARD_TYPEP_BLMASTER; sc->sc_num_mappings = 3; @@ -132,25 +137,32 @@ isic_supio_attach(parent, self, aux) /* create io mappings */ MALLOC_MAPS(sc); + if (!strcmp(sap->supio_name, "isic")) { + o1 = 0x300; + o2 = 0x100; + } else /* "isic-II" */ { + o1 = 0x100; + o2 = 0x300; + } bst = sap->supio_iot; bus_space_map(bst, sap->supio_iobase, 0x400, 0, &h); /* ISAC */ sc->sc_maps[0].t = bst; sc->sc_maps[0].h = h; - sc->sc_maps[0].offset = 0x300/2; + sc->sc_maps[0].offset = o1/2; sc->sc_maps[0].size = 0; /* foreign mapping, leave it alone */ /* HSCX A */ sc->sc_maps[1].t = bst; sc->sc_maps[1].h = h; - sc->sc_maps[1].offset = 0x100/2; + sc->sc_maps[1].offset = o2/2; sc->sc_maps[1].size = 0; /* foreign mapping, leave it alone */ /* HSCX B */ sc->sc_maps[2].t = bst; sc->sc_maps[2].h = h; - sc->sc_maps[2].offset = 0x180/2; + sc->sc_maps[2].offset = (o2 + 0x80)/2; sc->sc_maps[2].size = 0; /* foreign mapping, leave it alone */ sc->clearirq = NULL; diff --git a/sys/i4b/layer1/pci_isic.c b/sys/i4b/layer1/pci_isic.c index d577592..7e0a699 100644 --- a/sys/i4b/layer1/pci_isic.c +++ b/sys/i4b/layer1/pci_isic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998 Martin Husemann. All rights reserved. + * Copyright (c) 1998,1999 Martin Husemann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,11 +33,12 @@ * pci_isic.c - pcmcia bus frontend for i4b_isic driver * ------------------------------------------------------- * - * $Id: pci_isic.c,v 1.2 1999/02/14 09:45:00 hm Exp $ + * $Id: pci_isic.c,v 1.3 1999/03/16 15:21:55 hm Exp $ * - * last edit-date: [Sun Feb 14 10:29:25 1999] + * last edit-date: [Wed Mar 10 07:22:08 1999] * * -mh original implementation + * -mh added support for Fritz! PCI card * *---------------------------------------------------------------------------*/ @@ -72,6 +73,7 @@ #include <i4b/layer1/i4b_ipac.h> #include <i4b/layer1/i4b_isac.h> #include <i4b/layer1/i4b_hscx.h> +#include <i4b/layer1/pci_isic.h> #include <i4b/include/i4b_global.h> #include <i4b/include/i4b_l1l2.h> @@ -79,15 +81,7 @@ static int pci_isic_match __P((struct device *, struct cfdata *, void *)); static void pci_isic_attach __P((struct device *, struct device *, void *)); static const struct isic_pci_product * find_matching_card __P((struct pci_attach_args *pa)); -extern void isic_attach_Eqs1pp __P((struct isic_softc *sc, struct pci_attach_args *pa)); -static int isic_pciattach __P((struct isic_softc *sc)); - -struct pci_isic_softc { - struct isic_softc sc_isic; /* parent class */ - - /* PCI-specific goo */ - void *sc_ih; /* interrupt handler */ -}; +static void isic_pciattach __P((struct pci_isic_softc *psc, struct pci_attach_args *pa)); struct cfattach pci_isic_ca = { sizeof(struct pci_isic_softc), pci_isic_match, pci_isic_attach @@ -98,16 +92,37 @@ static const struct isic_pci_product { pci_vendor_id_t npp_vendor; pci_product_id_t npp_product; int cardtype; - int flag; const char * name; - void (*attach)(struct isic_softc *sc, struct pci_attach_args *pa); + void (*attach)(struct pci_isic_softc *psc, struct pci_attach_args *pa); + void (*pciattach)(struct pci_isic_softc *psc, struct pci_attach_args *pa); } isic_pci_products[] = { - { PCI_VENDOR_ELSA, 0x1000, - CARD_TYPEP_ELSAQS1PCI, FLAG_ELSA_QS1P_PCI, + +#ifdef ELSA_QS1PCI +#ifndef PCI_PRODUCT_ELSA_QS1PCI +#define PCI_PRODUCT_ELSA_QS1PCI 0x1000 /* added to pcidevs in 1.3K, earlier versions missing it */ +#endif + { PCI_VENDOR_ELSA, PCI_PRODUCT_ELSA_QS1PCI, + CARD_TYPEP_ELSAQS1PCI, "ELSA QuickStep 1000pro/PCI", - isic_attach_Eqs1pp }, + isic_attach_Eqs1pp, /* card specific initialization */ + isic_pciattach /* generic setup for ISAC/HSCX or IPAC boards */ + }, +#endif - { 0, 0, 0, 0, NULL, NULL }, +#ifdef AVM_A1_PCI +#ifndef PCI_VENDOR_AVM +#define PCI_VENDOR_AVM 0x1244 /* earlier versions missing this */ +#define PCI_PRODUCT_AVM_FRITZ_CARD 0x0a00 +#endif + { PCI_VENDOR_AVM, PCI_PRODUCT_AVM_FRITZ_CARD, + CARD_TYPEP_AVMA1PCI, + "Fritz!Card", + isic_attach_fritzPci, + NULL /* card rolls its own setup */ + }, +#endif + + { 0, 0, 0, NULL, NULL }, }; static const struct isic_pci_product * find_matching_card(pa) @@ -151,10 +166,7 @@ pci_isic_attach(parent, self, aux) struct pci_isic_softc *psc = (void*) self; struct isic_softc *sc = &psc->sc_isic; struct pci_attach_args *pa = aux; - pci_chipset_tag_t pc = pa->pa_pc; - pci_intr_handle_t ih; const struct isic_pci_product * prod; - const char *intrstr; /* Redo probe */ prod = find_matching_card(pa); @@ -164,38 +176,24 @@ pci_isic_attach(parent, self, aux) printf(": %s\n", prod->name); /* card initilization and sc setup */ - prod->attach(sc, pa); + prod->attach(psc, pa); - /* generic setup */ - isic_pciattach(sc); - - /* Map and establish the interrupt. */ - if (pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin, - pa->pa_intrline, &ih)) { - printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); - return; - } - intrstr = pci_intr_string(pc, ih); - psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, isicintr, sc); - if (psc->sc_ih == NULL) { - printf("%s: couldn't establish interrupt", - sc->sc_dev.dv_xname); - if (intrstr != NULL) - printf(" at %s", intrstr); - printf("\n"); - return; - } - printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr); + /* generic setup, if needed for this card */ + if (prod->pciattach) prod->pciattach(psc, pa); } /*---------------------------------------------------------------------------* * isic - pci device driver attach routine *---------------------------------------------------------------------------*/ -static int -isic_pciattach(sc) - struct isic_softc *sc; +static void +isic_pciattach(psc, pa) + struct pci_isic_softc *psc; + struct pci_attach_args *pa; { - int ret = 0; + struct isic_softc *sc = &psc->sc_isic; + pci_chipset_tag_t pc = pa->pa_pc; + pci_intr_handle_t ih; + const char *intrstr; static char *ISACversion[] = { "2085 Version A1/A2 or 2086/2186 Version 1.1", @@ -222,7 +220,7 @@ isic_pciattach(sc) if(sc->sc_ipac) { - ret = IPAC_READ(IPAC_ID); + u_int ret = IPAC_READ(IPAC_ID); switch(ret) { @@ -233,8 +231,7 @@ isic_pciattach(sc) default: printf("%s: Error, IPAC version %d unknown!\n", sc->sc_dev.dv_xname, ret); - return(0); - break; + return; } } else @@ -256,8 +253,7 @@ isic_pciattach(sc) default: printf("%s: Error, ISAC version %d unknown!\n", sc->sc_dev.dv_xname, sc->sc_isac_version); - return(0); - break; + return; } sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf; @@ -276,8 +272,7 @@ isic_pciattach(sc) default: printf("%s: Error, HSCX version %d unknown!\n", sc->sc_dev.dv_xname, sc->sc_hscx_version); - return(0); - break; + return; } } @@ -322,6 +317,23 @@ isic_pciattach(sc) MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp); - return(1); + + /* Map and establish the interrupt. */ + if (pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin, + pa->pa_intrline, &ih)) { + printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname); + return; + } + intrstr = pci_intr_string(pc, ih); + psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, isicintr, sc); + if (psc->sc_ih == NULL) { + printf("%s: couldn't establish interrupt", + sc->sc_dev.dv_xname); + if (intrstr != NULL) + printf(" at %s", intrstr); + printf("\n"); + return; + } + printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr); } diff --git a/sys/i4b/layer1/pci_isic.h b/sys/i4b/layer1/pci_isic.h new file mode 100644 index 0000000..0ac1918 --- /dev/null +++ b/sys/i4b/layer1/pci_isic.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 1999 Martin Husemann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * 4. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software and/or documentation. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + *--------------------------------------------------------------------------- + * + * pci_isic.h - pci bus frontend for i4b_isic driver + * ------------------------------------------------- + * + * $Id: pci_isic.h,v 1.1 1999/05/03 08:52:05 hm Exp $ + * + * last edit-date: [Wed Mar 10 07:22:08 1999] + * + * -mh original implementation + * + *---------------------------------------------------------------------------*/ + +struct pci_isic_softc { + struct isic_softc sc_isic; /* parent class */ + + /* PCI-specific goo */ + void *sc_ih; /* interrupt handler */ +}; + +extern void isic_attach_Eqs1pp __P((struct pci_isic_softc *psc, struct pci_attach_args *pa)); +extern void isic_attach_fritzPci __P((struct pci_isic_softc *psc, struct pci_attach_args *pa)); + diff --git a/sys/i4b/layer1/pcmcia_isic.c b/sys/i4b/layer1/pcmcia_isic.c index 20b5478..cb6ff4c 100644 --- a/sys/i4b/layer1/pcmcia_isic.c +++ b/sys/i4b/layer1/pcmcia_isic.c @@ -33,9 +33,9 @@ * pcmcia_isic.c - pcmcia bus frontend for i4b_isic driver * ------------------------------------------------------- * - * $Id: pcmcia_isic.c,v 1.4 1999/02/14 09:45:00 hm Exp $ + * $Id: pcmcia_isic.c,v 1.5 1999/04/20 12:19:57 hm Exp $ * - * last edit-date: [Sun Feb 14 10:29:29 1999] + * last edit-date: [Tue Apr 20 14:09:16 1999] * * -mh original implementation * @@ -98,7 +98,7 @@ struct isic_pcmcia_card_entry { static const struct isic_pcmcia_card_entry card_list[] = { -#ifdef AVM_PCMCIA +#ifdef AVM_A1_PCMCIA { PCMCIA_VENDOR_INVALID, PCMCIA_PRODUCT_INVALID, { "AVM", "ISDN A", NULL, NULL }, "AVM Fritz!Card", PCMCIA_FUNCTION_NETWORK, diff --git a/sys/i4b/layer2/i4b_iframe.c b/sys/i4b/layer2/i4b_iframe.c index 887f828..3a37d04 100644 --- a/sys/i4b/layer2/i4b_iframe.c +++ b/sys/i4b/layer2/i4b_iframe.c @@ -27,9 +27,9 @@ * i4b_iframe.c - i frame handling routines * ------------------------------------------ * - * $Id: i4b_iframe.c,v 1.16 1999/02/14 09:45:00 hm Exp $ + * $Id: i4b_iframe.c,v 1.19 1999/04/21 07:36:32 hm Exp $ * - * last edit-date: [Sun Feb 14 10:31:19 1999] + * last edit-date: [Wed Apr 21 09:24:34 1999] * *---------------------------------------------------------------------------*/ @@ -73,7 +73,7 @@ /*---------------------------------------------------------------------------* * process i frame - * implements the routine "I COMMAND" Q.921 03/93 pp 77 + * implements the routine "I COMMAND" Q.921 03/93 pp 68 and pp 77 *---------------------------------------------------------------------------*/ void i4b_rxd_i_frame(int unit, struct mbuf *m) @@ -83,7 +83,7 @@ i4b_rxd_i_frame(int unit, struct mbuf *m) int nr; int ns; int p; - int x; + CRIT_VAR; if(!((l2sc->tei_valid == TEI_VALID) && (l2sc->tei == GETTEI(*(ptr+OFF_TEI))))) @@ -99,7 +99,7 @@ i4b_rxd_i_frame(int unit, struct mbuf *m) return; } - x = SPLI4B(); + CRIT_BEG; nr = GETINR(*(ptr + OFF_INR)); ns = GETINS(*(ptr + OFF_INS)); @@ -165,7 +165,9 @@ i4b_rxd_i_frame(int unit, struct mbuf *m) if(l2sc->Q921_state == ST_TIMREC) { l2sc->va = nr; - splx(x); + + CRIT_END; + return; } @@ -196,7 +198,8 @@ i4b_rxd_i_frame(int unit, struct mbuf *m) i4b_nr_error_recovery(l2sc); /* sequence error */ l2sc->Q921_state = ST_AW_EST; } - splx(x); + + CRIT_END; } /*---------------------------------------------------------------------------* @@ -205,26 +208,39 @@ i4b_rxd_i_frame(int unit, struct mbuf *m) void i4b_i_frame_queued_up(l2_softc_t *l2sc) { - int x; struct mbuf *m; u_char *ptr; + CRIT_VAR; - x = SPLI4B(); - - if(l2sc->peer_busy) + CRIT_BEG; + + if((l2sc->peer_busy) || (l2sc->vs == ((l2sc->va + MAX_K_VALUE) & 127))) { - DBGL2(L2_I_MSG, "i4b_i_frame_queued_up", ("peer busy!\n")); - i4b_print_l2var(l2sc); - splx(x); - return; - } + if(l2sc->peer_busy) + { + DBGL2(L2_I_MSG, "i4b_i_frame_queued_up", ("regen IFQUP, cause: peer busy!\n")); + } - if(l2sc->vs == ((l2sc->va + MAX_K_VALUE) & 127)) - { - DBGL2(L2_I_ERR, "i4b_i_frame_queued_up", ("V(S) == ((V(A) + k) & 127)!\n")); - DBGL2(L2_I_ERR, "i4b_i_frame_queued_up", ("state = %s\n", i4b_print_l2state(l2sc))); - i4b_print_l2var(l2sc); - splx(x); + if(l2sc->vs == ((l2sc->va + MAX_K_VALUE) & 127)) + { + DBGL2(L2_I_MSG, "i4b_i_frame_queued_up", ("regen IFQUP, cause: vs=va+k!\n")); + } + + /* + * XXX see: Q.921, page 36, 5.6.1 ".. may retransmit an I + * frame ...", shall we retransmit the last i frame ? + */ + + if(!(IF_QEMPTY(&l2sc->i_queue))) + { + DBGL2(L2_I_MSG, "i4b_i_frame_queued_up", ("re-scheduling IFQU call!\n")); +#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 + l2sc->IFQU_callout = timeout((TIMEOUT_FUNC_T)i4b_i_frame_queued_up, (void *)l2sc, IFQU_DLY); +#else + timeout((TIMEOUT_FUNC_T)i4b_i_frame_queued_up, (void *)l2sc, IFQU_DLY); +#endif + } + CRIT_END; return; } @@ -233,7 +249,7 @@ i4b_i_frame_queued_up(l2_softc_t *l2sc) if(!m) { DBGL2(L2_I_ERR, "i4b_i_frame_queued_up", ("ERROR, mbuf NULL after IF_DEQUEUE\n")); - splx(x); + CRIT_END; return; } @@ -263,7 +279,7 @@ i4b_i_frame_queued_up(l2_softc_t *l2sc) l2sc->ack_pend = 0; - splx(x); + CRIT_END; if(l2sc->T200 == TIMER_IDLE) { diff --git a/sys/i4b/layer2/i4b_l2.c b/sys/i4b/layer2/i4b_l2.c index 875fabb..80072bb 100644 --- a/sys/i4b/layer2/i4b_l2.c +++ b/sys/i4b/layer2/i4b_l2.c @@ -27,9 +27,9 @@ * i4b_l2.c - ISDN layer 2 (Q.921) * ------------------------------- * - * $Id: i4b_l2.c,v 1.24 1999/02/14 09:45:00 hm Exp $ + * $Id: i4b_l2.c,v 1.26 1999/04/15 09:53:55 hm Exp $ * - * last edit-date: [Sun Feb 14 10:31:25 1999] + * last edit-date: [Thu Apr 15 11:32:11 1999] * *---------------------------------------------------------------------------*/ @@ -156,7 +156,7 @@ int i4b_dl_unit_data_req(int unit, struct mbuf *m) int i4b_dl_data_req(int unit, struct mbuf *m) { l2_softc_t *l2sc = &l2_softc[unit]; - int x; + #ifdef NOTDEF DBGL2(L2_PRIM, "DL-DATA-REQ", ("unit %d\n",unit)); #endif @@ -173,9 +173,12 @@ int i4b_dl_data_req(int unit, struct mbuf *m) } else { - x = splimp(); + CRIT_VAR; + + CRIT_BEG; IF_ENQUEUE(&l2sc->i_queue, m); - splx(x); + CRIT_END; + i4b_i_frame_queued_up(l2sc); } break; @@ -222,7 +225,9 @@ static void i4b_l2_unit_init(int unit) { l2_softc_t *l2sc = &l2_softc[unit]; + CRIT_VAR; + CRIT_BEG; l2sc->Q921_state = ST_TEI_UNAS; l2sc->tei_valid = TEI_INVALID; l2sc->vr = 0; @@ -251,7 +256,9 @@ i4b_l2_unit_init(int unit) i4b_T200_stop(l2sc); i4b_T202_stop(l2sc); - i4b_T203_stop(l2sc); + i4b_T203_stop(l2sc); + + CRIT_END; } /*---------------------------------------------------------------------------* @@ -261,9 +268,10 @@ int i4b_mph_status_ind(int unit, int status, int parm) { l2_softc_t *l2sc = &l2_softc[unit]; + CRIT_VAR; int sendup = 1; - - int x = SPLI4B(); + + CRIT_BEG; DBGL1(L1_PRIM, "MPH-STATUS-IND", ("unit %d, status=%d, parm=%d\n", unit, status, parm)); @@ -280,6 +288,7 @@ i4b_mph_status_ind(int unit, int status, int parm) callout_handle_init(&l2sc->T200_callout); callout_handle_init(&l2sc->T202_callout); callout_handle_init(&l2sc->T203_callout); + callout_handle_init(&l2sc->IFQU_callout); #endif break; @@ -312,7 +321,7 @@ i4b_mph_status_ind(int unit, int status, int parm) if(sendup) MDL_Status_Ind(unit, status, parm); /* send up to layer 3 */ - splx(x); + CRIT_END; return(0); } diff --git a/sys/i4b/layer2/i4b_l2.h b/sys/i4b/layer2/i4b_l2.h index dd63f43..c829a07 100644 --- a/sys/i4b/layer2/i4b_l2.h +++ b/sys/i4b/layer2/i4b_l2.h @@ -27,9 +27,9 @@ * i4b_l2.h - ISDN layer 2 (Q.921) definitions * --------------------------------------------- * - * $Id: i4b_l2.h,v 1.15 1999/02/14 09:45:00 hm Exp $ + * $Id: i4b_l2.h,v 1.17 1999/04/22 11:51:45 hm Exp $ * - * last edit-date: [Sun Feb 14 10:31:31 1999] + * last edit-date: [Thu Apr 22 13:50:55 1999] * *---------------------------------------------------------------------------*/ @@ -65,8 +65,17 @@ typedef struct { struct callout_handle T200_callout; struct callout_handle T202_callout; struct callout_handle T203_callout; + struct callout_handle IFQU_callout; #endif +/* + * i4b_iframe.c, i4b_i_frame_queued_up(): value of IFQU_DLY + * some experimentation Gary did showed a minimal value of (hz/20) was + * possible to let this work, Gary suggested using (hz/10) but i settled + * down to using (hz/5) for now (-hm). + */ +#define IFQU_DLY (hz/5) /* reschedule I-FRAME-QUEUED-UP 0.2 sec */ + int vr; /* receive sequence frame counter */ int vs; /* transmit sequence frame counter */ int va; /* acknowledge sequence frame counter */ diff --git a/sys/i4b/layer2/i4b_l2fsm.c b/sys/i4b/layer2/i4b_l2fsm.c index dbbe0ca..ea04662 100644 --- a/sys/i4b/layer2/i4b_l2fsm.c +++ b/sys/i4b/layer2/i4b_l2fsm.c @@ -27,9 +27,9 @@ * i4b_l2fsm.c - layer 2 FSM * ------------------------- * - * $Id: i4b_l2fsm.c,v 1.14 1999/02/14 09:45:00 hm Exp $ + * $Id: i4b_l2fsm.c,v 1.15 1999/03/16 15:29:06 hm Exp $ * - * last edit-date: [Sun Feb 14 10:31:37 1999] + * last edit-date: [Tue Mar 16 16:27:12 1999] * *---------------------------------------------------------------------------*/ @@ -242,6 +242,7 @@ struct l2state_tab { void i4b_next_l2state(l2_softc_t *l2sc, int event) { int currstate, newstate; + int (*savpostfsmfunc)(int) = NULL; /* check event number */ if(event > N_EVENTS) @@ -292,8 +293,10 @@ void i4b_next_l2state(l2_softc_t *l2sc, int event) if(l2sc->postfsmfunc != NULL) { DBGL2(L2_F_MSG, "i4b_next_l2state", ("FSM executing postfsmfunc!\n")); - (*l2sc->postfsmfunc)(l2sc->postfsmarg); + /* try to avoid an endless loop */ + savpostfsmfunc = l2sc->postfsmfunc; l2sc->postfsmfunc = NULL; + (*savpostfsmfunc)(l2sc->postfsmarg); } } diff --git a/sys/i4b/layer2/i4b_l2timer.c b/sys/i4b/layer2/i4b_l2timer.c index b9ae4a1..7a7db04 100644 --- a/sys/i4b/layer2/i4b_l2timer.c +++ b/sys/i4b/layer2/i4b_l2timer.c @@ -27,9 +27,9 @@ * i4b_l2timer.c - layer 2 timer handling * -------------------------------------- * - * $Id: i4b_l2timer.c,v 1.13 1999/02/14 09:45:00 hm Exp $ + * $Id: i4b_l2timer.c,v 1.15 1999/04/21 07:36:32 hm Exp $ * - * last edit-date: [Sun Feb 14 10:31:48 1999] + * last edit-date: [Wed Apr 21 09:17:58 1999] * *---------------------------------------------------------------------------*/ @@ -85,8 +85,12 @@ i4b_T200_timeout(l2_softc_t *l2sc) void i4b_T200_start(l2_softc_t *l2sc) { + if(l2sc->T200 == TIMER_ACTIVE) + return; + DBGL2(L2_T_MSG, "i4b_T200_start", ("unit %d\n", l2sc->unit)); l2sc->T200 = TIMER_ACTIVE; + #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 l2sc->T200_callout = timeout((TIMEOUT_FUNC_T)i4b_T200_timeout, (void *)l2sc, T200DEF); #else @@ -100,6 +104,8 @@ i4b_T200_start(l2_softc_t *l2sc) void i4b_T200_stop(l2_softc_t *l2sc) { + CRIT_VAR; + CRIT_BEG; if(l2sc->T200 != TIMER_IDLE) { #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 @@ -109,6 +115,7 @@ i4b_T200_stop(l2_softc_t *l2sc) #endif l2sc->T200 = TIMER_IDLE; } + CRIT_END; DBGL2(L2_T_MSG, "i4b_T200_stop", ("unit %d\n", l2sc->unit)); } @@ -118,21 +125,27 @@ i4b_T200_stop(l2_softc_t *l2sc) void i4b_T200_restart(l2_softc_t *l2sc) { + CRIT_VAR; + CRIT_BEG; if(l2sc->T200 != TIMER_IDLE) + { #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 untimeout((TIMEOUT_FUNC_T)i4b_T200_timeout, (void *)l2sc, l2sc->T200_callout); #else untimeout((TIMEOUT_FUNC_T)i4b_T200_timeout, (void *)l2sc); #endif + } else + { l2sc->T200 = TIMER_ACTIVE; - + } + #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 l2sc->T200_callout = timeout((TIMEOUT_FUNC_T)i4b_T200_timeout, (void *)l2sc, T200DEF); #else timeout((TIMEOUT_FUNC_T)i4b_T200_timeout, (void *)l2sc, T200DEF); #endif - + CRIT_END; DBGL2(L2_T_MSG, "i4b_T200_restart", ("unit %d\n", l2sc->unit)); } @@ -156,9 +169,13 @@ i4b_T202_timeout(l2_softc_t *l2sc) void i4b_T202_start(l2_softc_t *l2sc) { + if (l2sc->N202 == TIMER_ACTIVE) + return; + DBGL2(L2_T_MSG, "i4b_T202_start", ("unit %d\n", l2sc->unit)); l2sc->N202 = N202DEF; l2sc->T202 = TIMER_ACTIVE; + #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 l2sc->T202_callout = timeout((TIMEOUT_FUNC_T)i4b_T202_timeout, (void *)l2sc, T202DEF); #else @@ -172,6 +189,8 @@ i4b_T202_start(l2_softc_t *l2sc) void i4b_T202_stop(l2_softc_t *l2sc) { + CRIT_VAR; + CRIT_BEG; if(l2sc->T202 != TIMER_IDLE) { #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 @@ -181,6 +200,7 @@ i4b_T202_stop(l2_softc_t *l2sc) #endif l2sc->T202 = TIMER_IDLE; } + CRIT_END; DBGL2(L2_T_MSG, "i4b_T202_stop", ("unit %d\n", l2sc->unit)); } @@ -203,8 +223,12 @@ void i4b_T203_start(l2_softc_t *l2sc) { #if I4B_T203_ACTIVE + if (l2sc->T203 == TIMER_ACTIVE) + return; + DBGL2(L2_T_MSG, "i4b_T203_start", ("unit %d\n", l2sc->unit)); l2sc->T203 = TIMER_ACTIVE; + #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 l2sc->T203_callout = timeout((TIMEOUT_FUNC_T)i4b_T203_timeout, (void *)l2sc, T203DEF); #else @@ -220,6 +244,8 @@ void i4b_T203_stop(l2_softc_t *l2sc) { #if I4B_T203_ACTIVE + CRIT_VAR; + CRIT_BEG; if(l2sc->T203 != TIMER_IDLE) { #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 @@ -229,6 +255,7 @@ i4b_T203_stop(l2_softc_t *l2sc) #endif l2sc->T203 = TIMER_IDLE; } + CRIT_END; DBGL2(L2_T_MSG, "i4b_T203_stop", ("unit %d\n", l2sc->unit)); #endif } @@ -240,24 +267,30 @@ void i4b_T203_restart(l2_softc_t *l2sc) { #if I4B_T203_ACTIVE + CRIT_VAR; + CRIT_BEG; + if(l2sc->T203 != TIMER_IDLE) + { #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 untimeout((TIMEOUT_FUNC_T)i4b_T203_timeout, (void *)l2sc, l2sc->T203_callout); #else untimeout((TIMEOUT_FUNC_T)i4b_T203_timeout, (void *)l2sc); #endif + } else + { l2sc->T203 = TIMER_ACTIVE; + } #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 l2sc->T203_callout = timeout((TIMEOUT_FUNC_T)i4b_T203_timeout, (void *)l2sc, T203DEF); #else timeout((TIMEOUT_FUNC_T)i4b_T203_timeout, (void *)l2sc, T203DEF); #endif - + CRIT_END; DBGL2(L2_T_MSG, "i4b_T203_restart", ("unit %d\n", l2sc->unit)); #endif } #endif /* NI4BQ921 > 0 */ - diff --git a/sys/i4b/layer2/i4b_util.c b/sys/i4b/layer2/i4b_util.c index 047e438..141bef0 100644 --- a/sys/i4b/layer2/i4b_util.c +++ b/sys/i4b/layer2/i4b_util.c @@ -27,9 +27,9 @@ * i4b_util.c - layer 2 utility routines * ------------------------------------- * - * $Id: i4b_util.c,v 1.17 1999/02/14 09:45:01 hm Exp $ + * $Id: i4b_util.c,v 1.20 1999/04/15 09:53:55 hm Exp $ * - * last edit-date: [Sun Feb 14 10:32:23 1999] + * last edit-date: [Thu Apr 15 10:47:52 1999] * *---------------------------------------------------------------------------*/ @@ -94,12 +94,15 @@ i4b_establish_data_link(l2_softc_t *l2sc) void i4b_clear_exception_conditions(l2_softc_t *l2sc) { + CRIT_VAR; + CRIT_BEG; + /*XXX -------------------------------------------------------------- */ /*XXX is this really appropriate here or should it moved elsewhere ? */ i4b_Dcleanifq(&l2sc->i_queue); - + if(l2sc->ua_num != UA_EMPTY) { i4b_Dfreembuf(l2sc->ua_frame); @@ -114,6 +117,8 @@ i4b_clear_exception_conditions(l2_softc_t *l2sc) l2sc->own_busy = 0; l2sc->ack_pend = 0; + + CRIT_END; } /*---------------------------------------------------------------------------* @@ -165,13 +170,15 @@ i4b_enquiry_response(l2_softc_t *l2sc) void i4b_invoke_retransmission(l2_softc_t *l2sc, int nr) { - int x = SPLI4B(); + CRIT_VAR; + + CRIT_BEG; DBGL2(L2_ERROR, "i4b_invoke_retransmission", ("nr = %d\n", nr )); while(l2sc->vs != nr) { - DBGL2(L2_ERROR, "i4b_invoke_retransmission", ("nr != vs, nr = %d, vs = %d\n", nr, l2sc->vs)); + DBGL2(L2_ERROR, "i4b_invoke_retransmission", ("nr(%d) != vs(%d)\n", nr, l2sc->vs)); M128DEC(l2sc->vs); @@ -179,8 +186,15 @@ i4b_invoke_retransmission(l2_softc_t *l2sc, int nr) if((l2sc->ua_num != UA_EMPTY) && (l2sc->vs == l2sc->ua_num)) { - IF_ENQUEUE(&l2sc->i_queue, l2sc->ua_frame); - l2sc->ua_num = UA_EMPTY; + if(IF_QFULL(&l2sc->i_queue)) + { + DBGL2(L2_ERROR, "i4b_invoke_retransmission", ("ERROR, I-queue full!\n")); + } + else + { + IF_ENQUEUE(&l2sc->i_queue, l2sc->ua_frame); + l2sc->ua_num = UA_EMPTY; + } } else { @@ -192,7 +206,7 @@ i4b_invoke_retransmission(l2_softc_t *l2sc, int nr) i4b_i_frame_queued_up(l2sc); } - splx(x); + CRIT_END; } /*---------------------------------------------------------------------------* @@ -260,9 +274,9 @@ i4b_rxd_ack(l2_softc_t *l2sc, int nr) if(l2sc->ua_num != UA_EMPTY) { - int s; - - s = SPLI4B(); + CRIT_VAR; + + CRIT_BEG; M128DEC(nr); @@ -272,7 +286,7 @@ i4b_rxd_ack(l2_softc_t *l2sc, int nr) i4b_Dfreembuf(l2sc->ua_frame); l2sc->ua_num = UA_EMPTY; - splx(s); + CRIT_END; } } @@ -308,7 +322,6 @@ i4b_l2_nr_ok(int nr, int va, int vs) DBGL2(L2_ERROR, "i4b_l2_nr_ok", ("ERROR, va = %d, nr = %d, vs = %d [2]\n", va, nr, vs)); return 0; /* fail */ } - return 1; /* good */ } diff --git a/sys/i4b/layer3/i4b_l3fsm.c b/sys/i4b/layer3/i4b_l3fsm.c index 39c024c..a022bf8 100644 --- a/sys/i4b/layer3/i4b_l3fsm.c +++ b/sys/i4b/layer3/i4b_l3fsm.c @@ -27,9 +27,9 @@ * i4b_l3fsm.c - layer 3 FSM * ------------------------- * - * $Id: i4b_l3fsm.c,v 1.14 1999/02/14 09:45:01 hm Exp $ + * $Id: i4b_l3fsm.c,v 1.16 1999/04/21 07:50:31 hm Exp $ * - * last edit-date: [Sun Feb 14 10:33:25 1999] + * last edit-date: [Wed Apr 21 09:42:26 1999] * *---------------------------------------------------------------------------*/ @@ -889,6 +889,13 @@ static void F_DISC(call_desc_t *cd) static void F_DCRQ(call_desc_t *cd) { DBGL3(L3_F_MSG, "F_DCRQ", ("FSM function F_DCRQ executing\n")); + + /* stop T310 in case this is the result of an incoming call for a */ + /* calledback connection */ + + if(cd->T310 == TIMER_ACTIVE) + T310_stop(cd); + /* cause from L4 */ i4b_l3_tx_disconnect(cd); T305_start(cd); diff --git a/sys/i4b/layer3/i4b_l3timer.c b/sys/i4b/layer3/i4b_l3timer.c index dc20d4e..a4a01be 100644 --- a/sys/i4b/layer3/i4b_l3timer.c +++ b/sys/i4b/layer3/i4b_l3timer.c @@ -27,9 +27,9 @@ * i4b_l3timer.c - timer and timeout handling for layer 3 * ------------------------------------------------------ * - * $Id: i4b_l3timer.c,v 1.10 1999/02/14 09:45:01 hm Exp $ + * $Id: i4b_l3timer.c,v 1.12 1999/04/21 07:50:31 hm Exp $ * - * last edit-date: [Sun Feb 14 10:33:38 1999] + * last edit-date: [Wed Apr 21 09:46:59 1999] * *---------------------------------------------------------------------------*/ @@ -101,8 +101,12 @@ T303_timeout(call_desc_t *cd) void T303_start(call_desc_t *cd) { + if (cd->T303 == TIMER_ACTIVE) + return; + DBGL3(L3_T_MSG, "T303_start", ("cr = %d\n", cd->cr)); cd->T303 = TIMER_ACTIVE; + #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 cd->T303_callout = timeout((TIMEOUT_FUNC_T)T303_timeout, (void *)cd, T303VAL); #else @@ -116,6 +120,9 @@ T303_start(call_desc_t *cd) void T303_stop(call_desc_t *cd) { + CRIT_VAR; + CRIT_BEG; + if(cd->T303 != TIMER_IDLE) { #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 @@ -125,6 +132,7 @@ T303_stop(call_desc_t *cd) #endif cd->T303 = TIMER_IDLE; } + CRIT_END; DBGL3(L3_T_MSG, "T303_stop", ("cr = %d\n", cd->cr)); } @@ -144,8 +152,12 @@ T305_timeout(call_desc_t *cd) void T305_start(call_desc_t *cd) { + if (cd->T305 == TIMER_ACTIVE) + return; + DBGL3(L3_T_MSG, "T305_start", ("cr = %d\n", cd->cr)); cd->T305 = TIMER_ACTIVE; + #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 cd->T305_callout = timeout((TIMEOUT_FUNC_T)T305_timeout, (void *)cd, T305VAL); #else @@ -159,6 +171,9 @@ T305_start(call_desc_t *cd) void T305_stop(call_desc_t *cd) { + CRIT_VAR; + CRIT_BEG; + if(cd->T305 != TIMER_IDLE) { #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 @@ -168,6 +183,8 @@ T305_stop(call_desc_t *cd) #endif cd->T305 = TIMER_IDLE; } + CRIT_END; + DBGL3(L3_T_MSG, "T305_stop", ("cr = %d\n", cd->cr)); } @@ -187,8 +204,12 @@ T308_timeout(call_desc_t *cd) void T308_start(call_desc_t *cd) { + if(cd->T308 == TIMER_ACTIVE) + return; + DBGL3(L3_T_MSG, "T308_start", ("cr = %d\n", cd->cr)); cd->T308 = TIMER_ACTIVE; + #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 cd->T308_callout = timeout((TIMEOUT_FUNC_T)T308_timeout, (void *)cd, T308VAL); #else @@ -202,6 +223,9 @@ T308_start(call_desc_t *cd) void T308_stop(call_desc_t *cd) { + CRIT_VAR; + CRIT_BEG; + if(cd->T308 != TIMER_IDLE) { #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 @@ -211,6 +235,8 @@ T308_stop(call_desc_t *cd) #endif cd->T308 = TIMER_IDLE; } + CRIT_END; + DBGL3(L3_T_MSG, "T308_stop", ("cr = %d\n", cd->cr)); } @@ -230,8 +256,12 @@ T309_timeout(call_desc_t *cd) void T309_start(call_desc_t *cd) { + if (cd->T309 == TIMER_ACTIVE) + return; + DBGL3(L3_T_MSG, "T309_start", ("cr = %d\n", cd->cr)); cd->T309 = TIMER_ACTIVE; + #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 cd->T309_callout = timeout((TIMEOUT_FUNC_T)T309_timeout, (void *)cd, T309VAL); #else @@ -245,6 +275,9 @@ T309_start(call_desc_t *cd) void T309_stop(call_desc_t *cd) { + CRIT_VAR; + CRIT_BEG; + if(cd->T309 != TIMER_IDLE) { #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 @@ -254,6 +287,8 @@ T309_stop(call_desc_t *cd) #endif cd->T309 = TIMER_IDLE; } + CRIT_END; + DBGL3(L3_T_MSG, "T309_stop", ("cr = %d\n", cd->cr)); } @@ -273,8 +308,12 @@ T310_timeout(call_desc_t *cd) void T310_start(call_desc_t *cd) { + if (cd->T310 == TIMER_ACTIVE) + return; + DBGL3(L3_T_MSG, "T310_start", ("cr = %d\n", cd->cr)); cd->T310 = TIMER_ACTIVE; + #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 cd->T310_callout = timeout((TIMEOUT_FUNC_T)T310_timeout, (void *)cd, T310VAL); #else @@ -288,6 +327,9 @@ T310_start(call_desc_t *cd) void T310_stop(call_desc_t *cd) { + CRIT_VAR; + CRIT_BEG; + if(cd->T310 != TIMER_IDLE) { #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 @@ -297,6 +339,8 @@ T310_stop(call_desc_t *cd) #endif cd->T310 = TIMER_IDLE; } + CRIT_END; + DBGL3(L3_T_MSG, "T310_stop", ("cr = %d\n", cd->cr)); } @@ -316,8 +360,12 @@ T313_timeout(call_desc_t *cd) void T313_start(call_desc_t *cd) { + if (cd->T313 == TIMER_ACTIVE) + return; + DBGL3(L3_T_MSG, "T313_start", ("cr = %d\n", cd->cr)); cd->T313 = TIMER_ACTIVE; + #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 cd->T313_callout = timeout((TIMEOUT_FUNC_T)T313_timeout, (void *)cd, T313VAL); #else @@ -331,6 +379,9 @@ T313_start(call_desc_t *cd) void T313_stop(call_desc_t *cd) { + CRIT_VAR; + CRIT_BEG; + if(cd->T313 != TIMER_IDLE) { cd->T313 = TIMER_IDLE; @@ -340,6 +391,8 @@ T313_stop(call_desc_t *cd) untimeout((TIMEOUT_FUNC_T)T313_timeout, (void *)cd); #endif } + CRIT_END; + DBGL3(L3_T_MSG, "T313_stop", ("cr = %d\n", cd->cr)); } diff --git a/sys/i4b/layer3/i4b_l4if.c b/sys/i4b/layer3/i4b_l4if.c index 3f0c0cb..46210d6 100644 --- a/sys/i4b/layer3/i4b_l4if.c +++ b/sys/i4b/layer3/i4b_l4if.c @@ -27,9 +27,9 @@ * i4b_l4if.c - Layer 3 interface to Layer 4 * ------------------------------------------- * - * $Id: i4b_l4if.c,v 1.18 1999/02/14 09:45:01 hm Exp $ + * $Id: i4b_l4if.c,v 1.19 1999/04/27 14:47:58 hm Exp $ * - * last edit-date: [Sun Feb 14 10:33:44 1999] + * last edit-date: [Tue Apr 27 16:46:51 1999] * *---------------------------------------------------------------------------*/ @@ -304,7 +304,7 @@ n_connect_response(u_int cdid, int response, int cause) } else { - DBGL3(L3_ERR, "n_connect_response", ("ERROR, invalid channel %d\n", cd->channelid)); + DBGL3(L3_MSG, "n_connect_response", ("Warning, invalid channelid %d, response = %d\n", cd->channelid, response)); } } diff --git a/sys/i4b/layer3/i4b_q931.c b/sys/i4b/layer3/i4b_q931.c index 64ce766..6e02565 100644 --- a/sys/i4b/layer3/i4b_q931.c +++ b/sys/i4b/layer3/i4b_q931.c @@ -27,9 +27,9 @@ * i4b_q931.c - Q931 received messages handling * -------------------------------------------- * - * $Id: i4b_q931.c,v 1.19 1999/02/14 09:45:02 hm Exp $ + * $Id: i4b_q931.c,v 1.21 1999/04/27 10:08:13 hm Exp $ * - * last edit-date: [Sun Feb 14 10:33:50 1999] + * last edit-date: [Tue Apr 27 12:04:35 1999] * *---------------------------------------------------------------------------*/ @@ -270,7 +270,7 @@ i4b_decode_q931_cs0_ie(int unit, call_desc_t *cd, int msg_len, u_char *msg_ptr) /* single byte IE's */ case IEI_SENDCOMPL: - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_SENDCOMPL\n")); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_SENDCOMPL\n")); return(1); break; @@ -283,17 +283,17 @@ i4b_decode_q931_cs0_ie(int unit, call_desc_t *cd, int msg_len, u_char *msg_ptr) case 0x89: /* restricted digital info */ case 0x90: /* 3.1KHz audio */ /* XXX */ cd->bprot = BPROT_NONE; - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_BEARERCAP - Telephony\n")); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_BEARERCAP - Telephony\n")); break; case 0x88: /* unrestricted digital info */ /* XXX */ cd->bprot = BPROT_RHDLC; - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_BEARERCAP - Raw HDLC\n")); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_BEARERCAP - Raw HDLC\n")); break; default: /* XXX */ cd->bprot = BPROT_NONE; - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_BEARERCAP - No Protocol\n")); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_BEARERCAP - No Protocol\n")); break; } break; @@ -302,12 +302,12 @@ i4b_decode_q931_cs0_ie(int unit, call_desc_t *cd, int msg_len, u_char *msg_ptr) if(msg_ptr[2] & 0x80) { cd->cause_in = msg_ptr[3] & 0x7f; - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_CAUSE = %d\n", msg_ptr[3] & 0x7f)); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_CAUSE = %d\n", msg_ptr[3] & 0x7f)); } else { cd->cause_in = msg_ptr[4] & 0x7f; - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_CAUSE = %d\n", msg_ptr[4] & 0x7f)); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_CAUSE = %d\n", msg_ptr[4] & 0x7f)); } break; @@ -315,7 +315,7 @@ i4b_decode_q931_cs0_ie(int unit, call_desc_t *cd, int msg_len, u_char *msg_ptr) if((msg_ptr[2] & 0xf4) != 0x80) { cd->channelid = CHAN_NO; - DBGL3(L3_P_ERR, "i4b_decode_q931_codeset0", ("IEI_CHANNELID, unsupported value 0x%x\n", msg_ptr[2])); + DBGL3(L3_P_ERR, "i4b_decode_q931_cs0_ie", ("IEI_CHANNELID, unsupported value 0x%x\n", msg_ptr[2])); } else { @@ -336,7 +336,7 @@ i4b_decode_q931_cs0_ie(int unit, call_desc_t *cd, int msg_len, u_char *msg_ptr) } cd->channelexcl = (msg_ptr[2] & 0x08) >> 3; - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_CHANNELID - channel %d, exclusive = %d\n", cd->channelid, cd->channelexcl)); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_CHANNELID - channel %d, exclusive = %d\n", cd->channelid, cd->channelexcl)); /* if this is a setup message, reserve channel */ @@ -347,15 +347,15 @@ i4b_decode_q931_cs0_ie(int unit, call_desc_t *cd, int msg_len, u_char *msg_ptr) if(ctrl_desc[cd->controller].bch_state[cd->channelid] == BCH_ST_FREE) ctrl_desc[cd->controller].bch_state[cd->channelid] = BCH_ST_RSVD; else - DBGL3(L3_P_ERR, "i4b_decode_q931_codeset0", ("IE ChannelID, Channel NOT free!!\n")); + DBGL3(L3_P_ERR, "i4b_decode_q931_cs0_ie", ("IE ChannelID, Channel NOT free!!\n")); } else if(cd->channelid == CHAN_NO) { - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IE ChannelID, SETUP with channel = No channel (CW)\n")); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IE ChannelID, SETUP with channel = No channel (CW)\n")); } else /* cd->channelid == CHAN_ANY */ { - DBGL3(L3_P_ERR, "i4b_decode_q931_codeset0", ("ERROR: IE ChannelID, SETUP with channel = Any channel!\n")); + DBGL3(L3_P_ERR, "i4b_decode_q931_cs0_ie", ("ERROR: IE ChannelID, SETUP with channel = Any channel!\n")); } } } @@ -374,29 +374,29 @@ i4b_decode_q931_cs0_ie(int unit, call_desc_t *cd, int msg_len, u_char *msg_ptr) cd->src_telno[min(TELNO_MAX, msg_ptr[1] - 2)] = '\0'; cd->scr_ind = (msg_ptr[3] & 0x03) + SCR_USR_NOSC; } - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_CALLINGPN = %s\n", cd->src_telno)); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_CALLINGPN = %s\n", cd->src_telno)); break; case IEI_CALLEDPN: /* called party number */ memcpy(cd->dst_telno, &msg_ptr[3], min(TELNO_MAX, msg_ptr[1]-1)); cd->dst_telno[min(TELNO_MAX, msg_ptr [1] - 1)] = '\0'; - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_CALLED = %s\n", cd->dst_telno)); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_CALLED = %s\n", cd->dst_telno)); break; case IEI_CALLSTATE: /* call state */ cd->call_state = msg_ptr[2] & 0x3f; - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_CALLSTATE = %d\n", cd->call_state)); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_CALLSTATE = %d\n", cd->call_state)); break; case IEI_PROGRESSI: /* progress indicator */ - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_PROGRESSINDICATOR\n")); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_PROGRESSINDICATOR\n")); break; case IEI_DISPLAY: /* display */ /* CHANGED BY <chris@medis.de> */ memcpy(cd->display, &msg_ptr[2], min(DISPLAY_MAX, msg_ptr[1])); cd->display[min(DISPLAY_MAX, msg_ptr[1])] = '\0'; - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_DISPLAY = %s\n", cd->display)); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_DISPLAY = %s\n", cd->display)); break; case IEI_DATETIME: /* date/time */ @@ -408,33 +408,41 @@ i4b_decode_q931_cs0_ie(int unit, call_desc_t *cd, int msg_len, u_char *msg_ptr) for(j = msg_ptr[1]; j > 0; j--, i++) sprintf(p+strlen(p), "%02d", msg_ptr[i]); - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_DATETIME = %s\n", cd->datetime)); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_DATETIME = %s\n", cd->datetime)); break; case IEI_FACILITY: /* facility */ - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_FACILITY\n")); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_FACILITY\n")); if(i4b_aoc(msg_ptr, cd) > -1) i4b_l4_charging_ind(cd); break; case IEI_CONCTDNO: /* connected number */ - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_CONCTDNO\n")); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_CONCTDNO\n")); break; case IEI_NETSPCFAC: /* network specific fac */ - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_NETSPCFAC\n")); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_NETSPCFAC\n")); break; case IEI_LLCOMPAT: /* low layer compat */ - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_LLCOMPAT\n")); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_LLCOMPAT\n")); break; case IEI_HLCOMPAT: /* high layer compat */ - DBGL3(L3_P_MSG, "i4b_decode_q931_codeset0", ("IEI_HLCOMPAT\n")); + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_HLCOMPAT\n")); + break; + + case IEI_CALLINGPS: /* calling party subaddress */ + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_CALLINGPS\n")); + break; + + case IEI_CALLEDPS: /* called party subaddress */ + DBGL3(L3_P_MSG, "i4b_decode_q931_cs0_ie", ("IEI_CALLEDPS\n")); break; default: - DBGL3(L3_P_ERR, "i4b_decode_q931_codeset0", ("Unknown IE %d - ", *msg_ptr)); + DBGL3(L3_P_ERR, "i4b_decode_q931_cs0_ie", ("Unknown IE %d - ", *msg_ptr)); i4b_print_frame(msg_ptr[1]+2, msg_ptr); break; } diff --git a/sys/i4b/layer4/i4b_i4bdrv.c b/sys/i4b/layer4/i4b_i4bdrv.c index 173b5a4..a28dd67 100644 --- a/sys/i4b/layer4/i4b_i4bdrv.c +++ b/sys/i4b/layer4/i4b_i4bdrv.c @@ -27,14 +27,21 @@ * i4b_i4bdrv.c - i4b userland interface driver * -------------------------------------------- * - * $Id: i4b_i4bdrv.c,v 1.3 1999/03/07 16:08:20 hm Exp $ + * $Id: i4b_i4bdrv.c,v 1.44 1999/05/06 08:24:45 hm Exp $ * - * last edit-date: [Mon Feb 15 10:36:25 1999] + * last edit-date: [Thu May 6 10:05:01 1999] * *---------------------------------------------------------------------------*/ #include "i4b.h" #include "i4bipr.h" +#include "i4btel.h" + +#ifdef __bsdi__ +#include "ibc.h" +#else +#include "i4bisppp.h" +#endif #if NI4B > 1 #error "only 1 (one) i4b device possible!" @@ -86,9 +93,7 @@ #include <i4b/layer4/i4b_l4.h> -#if (defined(__FreeBSD__) && (!defined(__FreeBSD_version) || __FreeBSD_version < 300001)) || defined(__bsdi__) -/* do nothing */ -#else +#ifdef OS_USES_POLL #include <sys/poll.h> #endif @@ -103,32 +108,37 @@ static void *devfs_token; #endif #ifndef __FreeBSD__ + #define PDEVSTATIC /* - not static - */ PDEVSTATIC void i4battach __P((void)); PDEVSTATIC int i4bopen __P((dev_t dev, int flag, int fmt, struct proc *p)); PDEVSTATIC int i4bclose __P((dev_t dev, int flag, int fmt, struct proc *p)); PDEVSTATIC int i4bread __P((dev_t dev, struct uio *uio, int ioflag)); + #ifdef __bsdi__ PDEVSTATIC int i4bioctl __P((dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)); #else PDEVSTATIC int i4bioctl __P((dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)); #endif -PDEVSTATIC int i4bpoll __P((dev_t dev, int events, struct proc *p)); -#if defined (__OpenBSD__) || defined(__bsdi__) -PDEVSTATIC int i4bselect(dev_t dev, int rw, struct proc *p); +#ifdef OS_USES_POLL +PDEVSTATIC int i4bpoll __P((dev_t dev, int events, struct proc *p)); +#else +PDEVSTATIC int i4bselect __P((dev_t dev, int rw, struct proc *p)); #endif -#endif +#endif /* #ifndef __FreeBSD__ */ #if BSD > 199306 && defined(__FreeBSD__) + #define PDEVSTATIC static PDEVSTATIC d_open_t i4bopen; PDEVSTATIC d_close_t i4bclose; PDEVSTATIC d_read_t i4bread; PDEVSTATIC d_ioctl_t i4bioctl; -#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 + +#ifdef OS_USES_POLL PDEVSTATIC d_poll_t i4bpoll; #else PDEVSTATIC d_select_t i4bselect; @@ -138,7 +148,7 @@ PDEVSTATIC d_select_t i4bselect; static struct cdevsw i4b_cdevsw = { i4bopen, i4bclose, i4bread, nowrite, i4bioctl, nostop, nullreset, nodevtotty, -#if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 +#ifdef OS_USES_POLL i4bpoll, nommap, NULL, "i4b", NULL, -1 }; #else i4bselect, nommap, NULL, "i4b", NULL, -1 }; @@ -414,7 +424,7 @@ i4bioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) cd->driver_unit = mcrsp->driver_unit; cd->max_idle_time = mcrsp->max_idle_time; - cd->shorthold_data.shorthold_algorithm = msg_alg__fix_unit_size; + cd->shorthold_data.shorthold_algorithm = SHA_FIXU; cd->shorthold_data.unitlen_time = 0; /* this is incoming */ cd->shorthold_data.idle_time = 0; cd->shorthold_data.earlyhup_time = 0; @@ -482,18 +492,40 @@ i4bioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) case I4B_DIALOUT_RESP: { + drvr_link_t *dlt = NULL; msg_dialout_resp_t *mdrsp; mdrsp = (msg_dialout_resp_t *)data; -#if NI4BIPR > 0 - if(mdrsp->driver == BDRV_IPR) + switch(mdrsp->driver) { - drvr_link_t *dlt; - dlt = ipr_ret_linktab(mdrsp->driver_unit); - (*dlt->dial_response)(mdrsp->driver_unit, mdrsp->stat); - } +#if NI4BIPR > 0 + case BDRV_IPR: + dlt = ipr_ret_linktab(mdrsp->driver_unit); + break; +#endif + +#if NI4BISPPP > 0 + case BDRV_ISPPP: + dlt = i4bisppp_ret_linktab(mdrsp->driver_unit); + break; +#endif + +#if NI4BTEL > 0 + case BDRV_TEL: + dlt = tel_ret_linktab(mdrsp->driver_unit); + break; +#endif + +#if NIBC > 0 + case BDRV_IBC: + dlt = ibc_ret_linktab(mdrsp->driver_unit); + break; #endif + } + + if(dlt != NULL) + (*dlt->dial_response)(mdrsp->driver_unit, mdrsp->stat, mdrsp->cause); break; } @@ -509,6 +541,7 @@ i4bioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) DBGL4(L4_TIMO, "i4bioctl", ("I4B_TIMEOUT_UPD ioctl, alg %d, unit %d, idle %d, early %d!\n", mtu->shorthold_data.shorthold_algorithm, mtu->shorthold_data.unitlen_time, mtu->shorthold_data.idle_time, mtu->shorthold_data.earlyhup_time )); + if((cd = cd_by_cdid(mtu->cdid)) == NULL)/* get cd */ { DBGL4(L4_ERR, "i4bioctl", ("I4B_TIMEOUT_UPD ioctl, cdid not found!\n")); @@ -518,53 +551,49 @@ i4bioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) switch( mtu->shorthold_data.shorthold_algorithm ) { - - case msg_alg__fix_unit_size: - /* - * For this algorithm - * unitlen_time, idle_time and earlyhup_time - * are used. - */ - if( mtu->shorthold_data.unitlen_time >= 0 - && mtu->shorthold_data.idle_time > 0 - && mtu->shorthold_data.earlyhup_time >= 0 ) - { + case SHA_FIXU: + /* + * For this algorithm unitlen_time, + * idle_time and earlyhup_time are used. + */ + + if(!(mtu->shorthold_data.unitlen_time >= 0 && + mtu->shorthold_data.idle_time >= 0 && + mtu->shorthold_data.earlyhup_time >= 0)) + { + DBGL4(L4_ERR, "i4bioctl", ("I4B_TIMEOUT_UPD ioctl, invalid args for fix unit algorithm!\n")); + error = EINVAL; + } break; - } - - DBGL4(L4_ERR, "i4bioctl", ("I4B_TIMEOUT_UPD ioctl, invalid args for fix unit algorithm!\n")); - error = EINVAL; - break; - - case msg_alg__var_unit_size: - /* - * For this algorithm - * unitlen_time and idle_time are used - * both must be positive integers - * earlyhup_time is not used and must be 0. - */ - if( mtu->shorthold_data.unitlen_time > 0 - && mtu->shorthold_data.idle_time > 0 - && mtu->shorthold_data.earlyhup_time == 0 ) - { + + case SHA_VARU: + /* + * For this algorithm unitlen_time and + * idle_time are used. both must be + * positive integers. earlyhup_time is + * not used and must be 0. + */ + + if(!(mtu->shorthold_data.unitlen_time > 0 && + mtu->shorthold_data.idle_time >= 0 && + mtu->shorthold_data.earlyhup_time == 0)) + { + DBGL4(L4_ERR, "i4bioctl", ("I4B_TIMEOUT_UPD ioctl, invalid args for var unit algorithm!\n")); + error = EINVAL; + } + break; + + default: + DBGL4(L4_ERR, "i4bioctl", ("I4B_TIMEOUT_UPD ioctl, invalid algorithm!\n")); + error = EINVAL; break; - } - - DBGL4(L4_ERR, "i4bioctl", ("I4B_TIMEOUT_UPD ioctl, invalid args for var unit algorithm!\n")); - error = EINVAL; - break; - - default: - DBGL4(L4_ERR, "i4bioctl", ("I4B_TIMEOUT_UPD ioctl, invalid algorithm!\n")); - error = EINVAL; - break; } /* * any error set above requires us to break - * out of the outter switch + * out of the outer switch */ - if( error != 0 ) + if(error != 0) break; x = SPLI4B(); @@ -769,9 +798,7 @@ diag_done: return(error); } -#if (defined(__FreeBSD__) && \ - (!defined(__FreeBSD_version) || (__FreeBSD_version < 300001))) \ - || defined (__OpenBSD__) || defined(__bsdi__) +#ifdef OS_USES_SELECT /*---------------------------------------------------------------------------* * i4bselect - device driver select routine @@ -803,7 +830,7 @@ i4bselect(dev_t dev, int rw, struct proc *p) return(0); } -#else /* NetBSD and FreeBSD -current */ +#else /* OS_USES_SELECT */ /*---------------------------------------------------------------------------* * i4bpoll - device driver poll routine @@ -835,7 +862,7 @@ i4bpoll(dev_t dev, int events, struct proc *p) return(0); } -#endif /* defined(__FreeBSD__) && __FreeBSD__ < 3 */ +#endif /* OS_USES_SELECT */ /*---------------------------------------------------------------------------* * i4bputqueue - put message into queue to userland diff --git a/sys/i4b/layer4/i4b_l4.c b/sys/i4b/layer4/i4b_l4.c index 1f87461..3396085 100644 --- a/sys/i4b/layer4/i4b_l4.c +++ b/sys/i4b/layer4/i4b_l4.c @@ -27,9 +27,9 @@ * i4b_l4.c - kernel interface to userland * ----------------------------------------- * - * $Id: i4b_l4.c,v 1.36 1999/02/15 09:55:48 hm Exp $ + * $Id: i4b_l4.c,v 1.39 1999/04/08 16:37:56 hm Exp $ * - * last edit-date: [Mon Feb 15 10:42:37 1999] + * last edit-date: [Thu Apr 8 17:31:52 1999] * *---------------------------------------------------------------------------*/ @@ -84,6 +84,10 @@ struct ctrl_type_desc ctrl_types[CTRL_NUMTYPES] = { { NULL, NULL} }; static int i4b_link_bchandrvr(call_desc_t *cd); static void i4b_unlink_bchandrvr(call_desc_t *cd); static void i4b_l4_setup_timeout(call_desc_t *cd); +static void i4b_idle_check_fix_unit(call_desc_t *cd); +static void i4b_idle_check_var_unit(call_desc_t *cd); +static void i4b_l4_setup_timeout_fix_unit(call_desc_t *cd); +static void i4b_l4_setup_timeout_var_unit(call_desc_t *cd); /*---------------------------------------------------------------------------* * send MSG_PDEACT_IND message to userland @@ -209,6 +213,33 @@ i4b_l4_dialout(int driver, int driver_unit) } /*---------------------------------------------------------------------------* + * send MSG_DIALOUTNUMBER_IND message to userland + *---------------------------------------------------------------------------*/ +void +i4b_l4_dialoutnumber(int driver, int driver_unit, int cmdlen, char *cmd) +{ + struct mbuf *m; + + if((m = i4b_Dgetmbuf(sizeof(msg_dialoutnumber_ind_t))) != NULL) + { + msg_dialoutnumber_ind_t *md = (msg_dialoutnumber_ind_t *)m->m_data; + + md->header.type = MSG_DIALOUTNUMBER_IND; + md->header.cdid = -1; + + md->driver = driver; + md->driver_unit = driver_unit; + + if(cmdlen > TELNO_MAX) + cmdlen = TELNO_MAX; + + md->cmdlen = cmdlen; + bcopy(cmd, md->cmd, cmdlen); + i4bputqueue(m); + } +} + +/*---------------------------------------------------------------------------* * send MSG_NEGOTIATION_COMPL message to userland *---------------------------------------------------------------------------*/ void @@ -703,10 +734,7 @@ idletime_state: IST_NONCHK IST_CHECK IST_SAFE /*---------------------------------------------------------------------------* * B channel idle check timeout setup - *---------------------------------------------------------------------------*/ -static void i4b_l4_setup_timeout_fix_unit(call_desc_t *cd); -static void i4b_l4_setup_timeout_var_unit(call_desc_t *cd); - + *---------------------------------------------------------------------------*/ static void i4b_l4_setup_timeout(call_desc_t *cd) { @@ -731,13 +759,14 @@ i4b_l4_setup_timeout(call_desc_t *cd) { switch( cd->shorthold_data.shorthold_algorithm ) { - default: /* fall into the old fix algorithm */ - case msg_alg__fix_unit_size: - i4b_l4_setup_timeout_fix_unit( cd ); - break; - case msg_alg__var_unit_size: - i4b_l4_setup_timeout_var_unit( cd ); - break; + default: /* fall into the old fix algorithm */ + case SHA_FIXU: + i4b_l4_setup_timeout_fix_unit( cd ); + break; + + case SHA_VARU: + i4b_l4_setup_timeout_var_unit( cd ); + break; } } else @@ -746,6 +775,9 @@ i4b_l4_setup_timeout(call_desc_t *cd) } } +/*---------------------------------------------------------------------------* + * fixed unit algorithm B channel idle check timeout setup + *---------------------------------------------------------------------------*/ static void i4b_l4_setup_timeout_fix_unit(call_desc_t *cd) { @@ -792,6 +824,9 @@ i4b_l4_setup_timeout_fix_unit(call_desc_t *cd) } } +/*---------------------------------------------------------------------------* + * variable unit algorithm B channel idle check timeout setup + *---------------------------------------------------------------------------*/ static void i4b_l4_setup_timeout_var_unit(call_desc_t *cd) { @@ -816,10 +851,7 @@ i4b_l4_setup_timeout_var_unit(call_desc_t *cd) /*---------------------------------------------------------------------------* * B channel idle check timeout function - *---------------------------------------------------------------------------*/ -static void i4b_idle_check_fix_unit(call_desc_t *cd); -static void i4b_idle_check_var_unit(call_desc_t *cd); - + *---------------------------------------------------------------------------*/ void i4b_idle_check(call_desc_t *cd) { @@ -855,6 +887,7 @@ i4b_idle_check(call_desc_t *cd) else { DBGL4(L4_TIMO, "i4b_idle_check", ("%ld: incoming-call, activity, last_active=%ld, max_idle=%ld\n", (long)SECOND, (long)cd->last_active_time, (long)cd->max_idle_time)); + #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 cd->idle_timeout_handle = #endif @@ -869,22 +902,25 @@ i4b_idle_check(call_desc_t *cd) { switch( cd->shorthold_data.shorthold_algorithm ) { - case msg_alg__fix_unit_size: - i4b_idle_check_fix_unit( cd ); - break; - case msg_alg__var_unit_size: - i4b_idle_check_var_unit( cd ); - break; - default: - DBGL4(L4_TIMO, "i4b_idle_check", ("%ld: bad value for shorthold_algorithm of %d\n", - (long)SECOND, cd->shorthold_data.shorthold_algorithm )); - i4b_idle_check_fix_unit( cd ); - break; + case SHA_FIXU: + i4b_idle_check_fix_unit( cd ); + break; + case SHA_VARU: + i4b_idle_check_var_unit( cd ); + break; + default: + DBGL4(L4_TIMO, "i4b_idle_check", ("%ld: bad value for shorthold_algorithm of %d\n", + (long)SECOND, cd->shorthold_data.shorthold_algorithm )); + i4b_idle_check_fix_unit( cd ); + break; } } splx(s); } +/*---------------------------------------------------------------------------* + * fixed unit algorithm B channel idle check timeout function + *---------------------------------------------------------------------------*/ static void i4b_idle_check_fix_unit(call_desc_t *cd) { @@ -979,6 +1015,9 @@ i4b_idle_check_fix_unit(call_desc_t *cd) } } +/*---------------------------------------------------------------------------* + * variable unit algorithm B channel idle check timeout function + *---------------------------------------------------------------------------*/ static void i4b_idle_check_var_unit(call_desc_t *cd) { @@ -1011,7 +1050,7 @@ i4b_idle_check_var_unit(call_desc_t *cd) DBGL4(L4_ERR, "i4b_idle_check", ("outgoing-call: var idle timeout invalid idletime_state value!\n")); cd->idletime_state = IST_IDLE; break; - } + } } #endif /* NI4B > 0 */ diff --git a/sys/i4b/layer4/i4b_l4.h b/sys/i4b/layer4/i4b_l4.h index d88e64c..5d011b4 100644 --- a/sys/i4b/layer4/i4b_l4.h +++ b/sys/i4b/layer4/i4b_l4.h @@ -27,9 +27,9 @@ * i4b_l4.h - kernel interface to userland header file * --------------------------------------------------- * - * $Id: i4b_l4.h,v 1.14 1999/02/14 09:45:02 hm Exp $ + * $Id: i4b_l4.h,v 1.15 1999/03/18 14:33:41 hm Exp $ * - * last edit-date: [Sun Feb 14 10:35:08 1999] + * last edit-date: [Wed Mar 17 16:20:10 1999] * *---------------------------------------------------------------------------*/ @@ -46,6 +46,7 @@ extern void i4b_l4_connect_ind ( call_desc_t *cd ); extern void i4b_l4_daemon_attached(void); extern void i4b_l4_daemon_detached(void); extern void i4b_l4_dialout( int driver, int driver_unit ); +extern void i4b_l4_dialoutnumber(int driver, int driver_unit, int cmdlen, char *cmd); extern void i4b_l4_disconnect_ind ( call_desc_t *cd ); extern void i4b_l4_drvrdisc (int driver, int driver_unit ); extern void i4b_l4_negcomplete( call_desc_t *cd ); diff --git a/sys/i4b/layer4/i4b_l4timer.c b/sys/i4b/layer4/i4b_l4timer.c index ddc0256..02bd758 100644 --- a/sys/i4b/layer4/i4b_l4timer.c +++ b/sys/i4b/layer4/i4b_l4timer.c @@ -27,9 +27,9 @@ * i4b_l4timer.c - timer and timeout handling for layer 4 * -------------------------------------------------------- * - * $Id: i4b_l4timer.c,v 1.11 1999/02/14 09:45:02 hm Exp $ + * $Id: i4b_l4timer.c,v 1.13 1999/04/21 07:50:31 hm Exp $ * - * last edit-date: [Sun Feb 14 10:35:20 1999] + * last edit-date: [Wed Apr 21 09:49:08 1999] * *---------------------------------------------------------------------------*/ @@ -78,9 +78,12 @@ T400_timeout(call_desc_t *cd) void T400_start(call_desc_t *cd) { + if (cd->T400 == TIMER_ACTIVE) + return; + DBGL4(L4_MSG, "T400_start", ("cr = %d\n", cd->cr)); - cd->T400 = TIMER_ACTIVE; + #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 cd->T400_callout = timeout((TIMEOUT_FUNC_T)T400_timeout, (void *)cd, T400DEF); #else @@ -94,17 +97,20 @@ T400_start(call_desc_t *cd) void T400_stop(call_desc_t *cd) { - DBGL4(L4_MSG, "T400_stop", ("cr = %d\n", cd->cr)); + CRIT_VAR; + CRIT_BEG; if(cd->T400 == TIMER_ACTIVE) { - cd->T400 = TIMER_IDLE; #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 untimeout((TIMEOUT_FUNC_T)T400_timeout, (void *)cd, cd->T400_callout); #else untimeout((TIMEOUT_FUNC_T)T400_timeout, (void *)cd); #endif + cd->T400 = TIMER_IDLE; } + CRIT_END; + DBGL4(L4_MSG, "T400_stop", ("cr = %d\n", cd->cr)); } #endif /* NI4B > 0 */ |