diff options
author | Hellmuth Michaelis <hm@FreeBSD.org> | 1999-08-06 14:05:10 +0000 |
---|---|---|
committer | Hellmuth Michaelis <hm@FreeBSD.org> | 1999-08-06 14:05:10 +0000 |
commit | 0df6adec74627c0b4c08bef04859a8ea19f222ca (patch) | |
tree | bc925696900bdd2b986e04e1985b9bad68a841dc /sys/i4b | |
parent | aab3beeede3032eef69a9bf581707f4ea77affe3 (diff) | |
download | src-0df6adec74627c0b4c08bef04859a8ea19f222ca.tar.gz src-0df6adec74627c0b4c08bef04859a8ea19f222ca.zip |
updating isdn4bsd to beta version 0.83
Notes
Notes:
svn path=/head/; revision=49460
Diffstat (limited to 'sys/i4b')
31 files changed, 2992 insertions, 287 deletions
diff --git a/sys/i4b/layer1/i4b_bsdi_ibc.c b/sys/i4b/driver/i4b_bsdi_ibc.c index 91688154c196..91688154c196 100644 --- a/sys/i4b/layer1/i4b_bsdi_ibc.c +++ b/sys/i4b/driver/i4b_bsdi_ibc.c diff --git a/sys/i4b/driver/i4b_ctl.c b/sys/i4b/driver/i4b_ctl.c index aac6f504d293..3ad68a0063a2 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.4 1999/05/20 10:08:56 hm Exp $ + * $Id: i4b_ctl.c,v 1.25 1999/06/08 08:13:00 hm Exp $ * - * last edit-date: [Mon Apr 26 11:16:28 1999] + * last edit-date: [Tue Jun 8 09:27:15 1999] * *---------------------------------------------------------------------------*/ @@ -83,6 +83,7 @@ #include <i4b/include/i4b_global.h> #include <i4b/include/i4b_mbuf.h> #include <i4b/layer1/i4b_l1.h> +#include <i4b/layer2/i4b_l2.h> static int openflag = 0; @@ -99,6 +100,8 @@ static d_poll_t i4bctlpoll; #endif #define CDEV_MAJOR 55 + +#if defined (__FreeBSD_version) && __FreeBSD_version >= 400006 static struct cdevsw i4bctl_cdevsw = { /* open */ i4bctlopen, /* close */ i4bctlclose, @@ -120,6 +123,12 @@ static struct cdevsw i4bctl_cdevsw = { /* maxio */ 0, /* bmaj */ -1 }; +#else +static struct cdevsw i4bctl_cdevsw = + { i4bctlopen, i4bctlclose, noread, nowrite, + i4bctlioctl, nostop, nullreset, nodevtotty, + POLLFIELD, nommap, NULL, "i4bctl", NULL, -1 }; +#endif static void i4bctlattach(void *); PSEUDO_SET(i4bctlattach, i4b_i4bctldrv); @@ -150,8 +159,12 @@ int i4bctlioctl __P((dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) static void i4bctlinit(void *unused) { - - cdevsw_add(&i4bctl_cdevsw); +#if defined (__FreeBSD_version) && __FreeBSD_version >= 400006 + cdevsw_add(&i4bctl_cdevsw); +#else + dev_t dev = makedev(CDEV_MAJOR, 0); + cdevsw_add(&dev, &i4bctl_cdevsw, NULL); +#endif } SYSINIT(i4bctldev, SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR, &i4bctlinit, NULL); @@ -332,6 +345,42 @@ i4bctlioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) break; } + case I4B_CTL_GET_LAPDSTAT: + { + l2stat_t *l2s; + l2_softc_t *sc; + l2s = (l2stat_t *)data; + + if( l2s->unit < 0 || l2s->unit > ISIC_MAXUNIT) + { + error = EINVAL; + break; + } + + sc = &l2_softc[l2s->unit]; + + bcopy(&sc->stat, &l2s->lapdstat, sizeof(lapdstat_t)); + break; + } + + case I4B_CTL_CLR_LAPDSTAT: + { + int *up; + l2_softc_t *sc; + up = (int *)data; + + if( *up < 0 || *up > ISIC_MAXUNIT) + { + error = EINVAL; + break; + } + + sc = &l2_softc[*up]; + + bzero(&sc->stat, sizeof(lapdstat_t)); + break; + } + default: error = ENOTTY; break; diff --git a/sys/i4b/driver/i4b_ipr.c b/sys/i4b/driver/i4b_ipr.c index 5415dda929cf..b2ac7d01fc23 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.4 1999/05/20 10:08:58 hm Exp $ + * $Id: i4b_ipr.c,v 1.53 1999/07/22 18:30:15 hm Exp $ * - * last edit-date: [Thu May 6 10:09:20 1999] + * last edit-date: [Thu Jul 22 19:46:53 1999] * *---------------------------------------------------------------------------* * @@ -110,8 +110,12 @@ /* undef to uncompress in the mbuf itself */ #endif /* IPR_VJ */ +#if defined(__FreeBSD_version) && __FreeBSD_version >= 400008 #include "bpf.h" -#if NBPF > 0 +#else +#include "bpfilter.h" +#endif +#if NBPFILTER > 0 || NBPF > 0 #include <sys/time.h> #include <net/bpf.h> #endif @@ -350,7 +354,7 @@ i4biprattach() if_attach(&sc->sc_if); -#if NBPF > 0 +#if NBPFILTER > 0 || NBPF > 0 #ifdef __FreeBSD__ bpfattach(&sc->sc_if, DLT_NULL, sizeof(u_int)); #else @@ -994,7 +998,7 @@ error: sc->sc_inb += m->m_pkthdr.len; #endif -#if NBPF > 0 +#if NBPFILTER > 0 || NBPF > 0 if(sc->sc_if.if_bpf) { /* prepend the address family as a four byte field */ @@ -1010,7 +1014,7 @@ error: bpf_mtap(sc->sc_if.if_bpf, &mm); #endif } -#endif /* NBPF > 0 */ +#endif /* NBPFILTER > 0 || NBPF > 0 */ if(IF_QFULL(&ipintrq)) { @@ -1062,7 +1066,7 @@ ipr_tx_queue_empty(int unit) microtime(&sc->sc_if.if_lastchange); -#if NBPF > 0 +#if NBPFILTER > 0 || NBPF > 0 if(sc->sc_if.if_bpf) { /* prepend the address family as a four byte field */ @@ -1079,7 +1083,7 @@ ipr_tx_queue_empty(int unit) bpf_mtap(sc->sc_if.if_bpf, &mm); #endif } -#endif /* NBPF */ +#endif /* NBPFILTER */ #if I4BIPRACCT sc->sc_outb += m->m_pkthdr.len; /* size before compression */ diff --git a/sys/i4b/driver/i4b_isppp.c b/sys/i4b/driver/i4b_isppp.c index eef0997ebeec..a2911d8b8d32 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.3 1999/05/20 10:09:01 hm Exp $ + * $Id: i4b_isppp.c,v 1.34 1999/07/24 13:21:42 hm Exp $ * - * last edit-date: [Sun May 2 10:52:57 1999] + * last edit-date: [Sat Jul 24 15:23:04 1999] * *---------------------------------------------------------------------------*/ @@ -63,19 +63,27 @@ #include <net/if_types.h> #include <net/netisr.h> #include <net/route.h> -#if defined(__FreeBSD__) -#include <net/if_sppp.h> -#else -#include <i4b/sppp/if_sppp.h> -#endif #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/in_var.h> #include <netinet/ip.h> -#include "bpf.h" -#if NBPF > 0 +#include <net/slcompress.h> + +#if defined(__FreeBSD__) || defined(__OpenBSD__) +#include <net/if_sppp.h> +#else +#include <i4b/sppp/if_sppp.h> +#endif + + +#if defined(__FreeBSD_version) && __FreeBSD_version >= 400008 +#include "bpf.h" +#else +#include "bpfilter.h" +#endif +#if NBPFILTER > 0 || NBPF > 0 #include <sys/time.h> #include <net/bpf.h> #endif @@ -222,8 +230,11 @@ i4bispppattach(void) int i; #ifndef HACK_NO_PSEUDO_ATTACH_MSG - printf("i4bisppp: %d ISDN SyncPPP device(s) attached\n", - NI4BISPPP); +#ifdef SPPP_VJ + printf("i4bisppp: %d ISDN SyncPPP device(s) attached (VJ header compression)\n", NI4BISPPP); +#else + printf("i4bisppp: %d ISDN SyncPPP device(s) attached\n", NI4BISPPP); +#endif #endif for(i = 0; i < NI4BISPPP; sc++, i++) { @@ -290,7 +301,7 @@ i4bispppattach(void) sppp_attach(&sc->sc_if); if_attach(&sc->sc_if); -#if NBPF > 0 +#if NBPFILTER > 0 || NBPF > 0 #ifdef __FreeBSD__ bpfattach(&sc->sc_if, DLT_PPP, PPP_HDRLEN); CALLOUT_INIT(&sc->sc_ch); @@ -361,7 +372,7 @@ i4bisppp_start(struct ifnet *ifp) while ((m = sppp_dequeue(&sc->sc_if)) != NULL) { -#if NBPF > 0 +#if NBPFILTER > 0 || NBPF > 0 #ifdef __FreeBSD__ if (ifp->if_bpf) bpf_mtap(ifp, m); @@ -371,7 +382,7 @@ i4bisppp_start(struct ifnet *ifp) if (ifp->if_bpf) bpf_mtap(ifp->if_bpf, m); #endif -#endif /* NBPF > 0 */ +#endif /* NBPFILTER > 0 || NBPF > 0 */ microtime(&ifp->if_lastchange); @@ -654,7 +665,7 @@ i4bisppp_rx_data_rdy(int unit) printf("i4bisppp_rx_data_ready: received packet!\n"); #endif -#if NBPF > 0 +#if NBPFILTER > 0 || NBPF > 0 #ifdef __FreeBSD__ if(sc->sc_if.if_bpf) @@ -666,7 +677,7 @@ i4bisppp_rx_data_rdy(int unit) bpf_mtap(sc->sc_if.if_bpf, m); #endif -#endif /* NBPF > 0 */ +#endif /* NBPFILTER > 0 || NBPF > 0 */ s = splimp(); diff --git a/sys/i4b/driver/i4b_rbch.c b/sys/i4b/driver/i4b_rbch.c index e4a5e61caeae..1179b35c46c5 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.3 1999/05/20 10:09:02 hm Exp $ + * $Id: i4b_rbch.c,v 1.36 1999/07/19 14:03:33 hm Exp $ * - * last edit-date: [Thu May 6 13:40:22 1999] + * last edit-date: [Fri Jul 9 09:37:02 1999] * *---------------------------------------------------------------------------*/ @@ -49,7 +49,7 @@ #include <sys/proc.h> #include <sys/tty.h> -#ifdef __NetBSD__ +#if defined (__NetBSD__) || defined (__OpenBSD__) extern cc_t ttydefchars; #define termioschars(t) memcpy((t)->c_cc, &ttydefchars, sizeof((t)->c_cc)) #endif @@ -69,9 +69,11 @@ extern cc_t ttydefchars; #ifdef __FreeBSD__ #include <machine/i4b_ioctl.h> +#include <machine/i4b_rbch_ioctl.h> #include <machine/i4b_debug.h> #else #include <i4b/i4b_ioctl.h> +#include <i4b/i4b_rbch_ioctl.h> #include <i4b/i4b_debug.h> #endif @@ -147,8 +149,7 @@ int i4brbchioctl __P((dev_t dev, IOCTL_CMD_T cmd, caddr_t arg, int flag, struct #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)); +PDEVSTATIC int i4brbchselect __P((dev_t dev, int rw, struct proc *p)); #endif #endif @@ -175,6 +176,8 @@ PDEVSTATIC d_select_t i4brbchselect; #endif #define CDEV_MAJOR 57 + +#if defined (__FreeBSD_version) && __FreeBSD_version >= 400006 static struct cdevsw i4brbch_cdevsw = { /* open */ i4brbchopen, /* close */ i4brbchclose, @@ -196,6 +199,13 @@ static struct cdevsw i4brbch_cdevsw = { /* maxio */ 0, /* bmaj */ -1 }; +#else +static struct cdevsw i4brbch_cdevsw = { + i4brbchopen, i4brbchclose, i4brbchread, i4brbchwrite, + i4brbchioctl, nostop, noreset, nodevtotty, + POLLFIELD, nommap, NULL, "i4brbch", NULL, -1 +}; +#endif static void i4brbchattach(void *); PSEUDO_SET(i4brbchattach, i4b_rbch); @@ -210,8 +220,12 @@ PSEUDO_SET(i4brbchattach, i4b_rbch); static void i4brbchinit(void *unused) { - - cdevsw_add(&i4brbch_cdevsw); +#if defined (__FreeBSD_version) && __FreeBSD_version >= 400006 + cdevsw_add(&i4brbch_cdevsw); +#else + dev_t dev = makedev(CDEV_MAJOR, 0); + cdevsw_add(&dev, &i4brbch_cdevsw, NULL); +#endif } SYSINIT(i4brbchdev, SI_SUB_DRIVERS, @@ -247,6 +261,7 @@ dummy_i4brbchattach(struct device *parent, struct device *self, void *aux) printf("dummy_i4brbchattach: aux=0x%x\n", aux); } #endif /* __bsdi__ */ + /*---------------------------------------------------------------------------* * interface attach routine *---------------------------------------------------------------------------*/ @@ -282,7 +297,7 @@ i4brbchattach() /*---------------------------------------------------------------------------* * open rbch device *---------------------------------------------------------------------------*/ -int +PDEVSTATIC int i4brbchopen(dev_t dev, int flag, int fmt, struct proc *p) { int unit = minor(dev); @@ -305,7 +320,7 @@ i4brbchopen(dev_t dev, int flag, int fmt, struct proc *p) /*---------------------------------------------------------------------------* * close rbch device *---------------------------------------------------------------------------*/ -int +PDEVSTATIC int i4brbchclose(dev_t dev, int flag, int fmt, struct proc *p) { int unit = minor(dev); @@ -326,7 +341,7 @@ i4brbchclose(dev_t dev, int flag, int fmt, struct proc *p) /*---------------------------------------------------------------------------* * read from rbch device *---------------------------------------------------------------------------*/ -int +PDEVSTATIC int i4brbchread(dev_t dev, struct uio *uio, int ioflag) { struct mbuf *m; @@ -419,7 +434,7 @@ i4brbchread(dev_t dev, struct uio *uio, int ioflag) /*---------------------------------------------------------------------------* * write to rbch device *---------------------------------------------------------------------------*/ -int +PDEVSTATIC int i4brbchwrite(dev_t dev, struct uio * uio, int ioflag) { struct mbuf *m; @@ -520,60 +535,96 @@ i4brbchwrite(dev_t dev, struct uio * uio, int ioflag) return(error); } +/*---------------------------------------------------------------------------* + * rbch device ioctl handlibg + *---------------------------------------------------------------------------*/ PDEVSTATIC int -i4brbchioctl(dev_t dev, IOCTL_CMD_T cmd, caddr_t data, int flag, struct proc* p) { +i4brbchioctl(dev_t dev, IOCTL_CMD_T cmd, caddr_t data, int flag, struct proc* p) +{ int error = 0; int unit = minor(dev); switch(cmd) { -#if 0 - case I4B_RBCH_DIALOUT: -if(bootverbose)printf("EE-rbch%d: attempting dialout (ioctl)\n", unit); - i4b_l4_dialout(BDRV_RBCH, unit); - break; -#endif - case FIOASYNC: /* Set async mode */ - if (*(int *)data) { -if(bootverbose)printf("EE-rbch%d: setting async mode\n", unit); - } else { -if(bootverbose)printf("EE-rbch%d: clearing async mode\n", unit); + if (*(int *)data) + { + DBGL4(L4_RBCHDBG, "i4brbchioctl", ("unit %d, setting async mode\n", unit)); + } + else + { + DBGL4(L4_RBCHDBG, "i4brbchioctl", ("unit %d, clearing async mode\n", unit)); } break; + case FIONBIO: - if (*(int *)data) { -if(bootverbose)printf("EE-rbch%d: setting non-blocking mode\n", unit); + if (*(int *)data) + { + DBGL4(L4_RBCHDBG, "i4brbchioctl", ("unit %d, setting non-blocking mode\n", unit)); rbch_softc[unit].sc_devstate |= ST_NOBLOCK; - } else { -if(bootverbose)printf("EE-rbch%d: clearing non-blocking mode\n", unit); + } + else + { + DBGL4(L4_RBCHDBG, "i4brbchioctl", ("unit %d, clearing non-blocking mode\n", unit)); rbch_softc[unit].sc_devstate &= ~ST_NOBLOCK; } break; + case TIOCCDTR: /* Clear DTR */ - if(rbch_softc[unit].sc_devstate & ST_CONNECTED) { -if(bootverbose)printf("EE-rbch%d: disconnecting for DTR down\n", unit); + if(rbch_softc[unit].sc_devstate & ST_CONNECTED) + { + DBGL4(L4_RBCHDBG, "i4brbchioctl", ("unit %d, disconnecting for DTR down\n", unit)); i4b_l4_disconnect_ind(rbch_softc[unit].cd); } break; + + case I4B_RBCH_DIALOUT: + { + size_t l; + + for (l = 0; l < TELNO_MAX && ((char *)data)[l]; l++) + ; + if (l) + { + DBGL4(L4_RBCHDBG, "i4brbchioctl", ("unit %d, attempting dialout to %s\n", unit, (char *)data)); + i4b_l4_dialoutnumber(BDRV_RBCH, unit, l, (char *)data); + break; + } + /* fall through to SDTR */ + } + case TIOCSDTR: /* Set DTR */ -if(bootverbose)printf("EE-rbch%d: attempting dialout (DTR)\n", unit); + DBGL4(L4_RBCHDBG, "i4brbchioctl", ("unit %d, attempting dialout (DTR)\n", unit)); i4b_l4_dialout(BDRV_RBCH, unit); break; + case TIOCSETA: /* Set termios struct */ break; + case TIOCGETA: /* Get termios struct */ *(struct termios *)data = rbch_softc[unit].it_in; break; + case TIOCMGET: *(int *)data = TIOCM_LE|TIOCM_DTR|TIOCM_RTS|TIOCM_CTS|TIOCM_DSR; if (rbch_softc[unit].sc_devstate & ST_CONNECTED) *(int *)data |= TIOCM_CD; break; + + case I4B_RBCH_VR_REQ: + { + msg_vr_req_t *mvr; + + mvr = (msg_vr_req_t *)data; + + mvr->version = VERSION; + mvr->release = REL; + mvr->step = STEP; + break; + } + default: /* Unknown stuff */ - printf("\n ========= i4brbch%d - ioctl, unknown cmd %lx ==================== \n", - unit, - (u_long)cmd); + DBGL4(L4_RBCHDBG, "i4brbchioctl", ("unit %d, ioctl, unknown cmd %lx\n", unit, (u_long)cmd)); error = EINVAL; break; } @@ -642,8 +693,7 @@ i4brbchpoll(dev_t dev, int events, struct proc *p) /*---------------------------------------------------------------------------* * device driver select *---------------------------------------------------------------------------*/ -/* XXX fix "static" to PDEVSTATIC */ -static int +PDEVSTATIC int i4brbchselect(dev_t dev, int rw, struct proc *p) { int unit = minor(dev); diff --git a/sys/i4b/driver/i4b_tel.c b/sys/i4b/driver/i4b_tel.c index d681f3b58c41..a96a77f9b8a3 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.3 1999/05/20 10:09:03 hm Exp $ + * $Id: i4b_tel.c,v 1.43 1999/07/09 06:44:00 hm Exp $ * - * last edit-date: [Thu May 6 09:30:13 1999] + * last edit-date: [Fri Jul 9 08:35:30 1999] * *---------------------------------------------------------------------------*/ @@ -183,6 +183,7 @@ PDEVSTATIC d_close_t i4btelclose; PDEVSTATIC d_read_t i4btelread; PDEVSTATIC d_read_t i4btelwrite; PDEVSTATIC d_ioctl_t i4btelioctl; + #ifdef OS_USES_POLL PDEVSTATIC d_poll_t i4btelpoll; #define POLLFIELD i4btelpoll @@ -192,6 +193,8 @@ PDEVSTATIC d_select_t i4btelsel; #endif #define CDEV_MAJOR 56 + +#if defined (__FreeBSD_version) && __FreeBSD_version >= 400006 static struct cdevsw i4btel_cdevsw = { /* open */ i4btelopen, /* close */ i4btelclose, @@ -213,6 +216,13 @@ static struct cdevsw i4btel_cdevsw = { /* maxio */ 0, /* bmaj */ -1 }; +#else +static struct cdevsw i4btel_cdevsw = { + i4btelopen, i4btelclose, i4btelread, i4btelwrite, + i4btelioctl, nostop, noreset, nodevtotty, + POLLFIELD, nommap, NULL, "i4btel", NULL, -1 +}; +#endif PDEVSTATIC void i4btelinit(void *unused); PDEVSTATIC void i4btelattach(void *); @@ -229,8 +239,12 @@ PSEUDO_SET(i4btelattach, i4b_tel); PDEVSTATIC void i4btelinit(void *unused) { - - cdevsw_add(&i4btel_cdevsw); +#if defined (__FreeBSD_version) && __FreeBSD_version >= 400006 + cdevsw_add(&i4btel_cdevsw); +#else + dev_t dev = makedev(CDEV_MAJOR, 0); + cdevsw_add(&dev, &i4btel_cdevsw, NULL); +#endif } SYSINIT(i4bteldev, SI_SUB_DRIVERS, @@ -441,6 +455,18 @@ i4btelioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) } splx(s); break; + + case I4B_TEL_VR_REQ: + { + msg_vr_req_t *mvr; + + mvr = (msg_vr_req_t *)data; + + mvr->version = VERSION; + mvr->release = REL; + mvr->step = STEP; + break; + } default: error = ENOTTY; diff --git a/sys/i4b/driver/i4b_trace.c b/sys/i4b/driver/i4b_trace.c index b43ce24b5423..aacf53d9532b 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.3 1999/05/20 10:09:05 hm Exp $ + * $Id: i4b_trace.c,v 1.20 1999/06/01 10:23:58 hm Exp $ * - * last edit-date: [Wed Apr 28 10:21:09 1999] + * last edit-date: [Tue Jun 1 12:15:40 1999] * * NOTE: the code assumes that SPLI4B >= splimp ! * @@ -125,6 +125,7 @@ static d_open_t i4btrcopen; static d_close_t i4btrcclose; static d_read_t i4btrcread; static d_ioctl_t i4btrcioctl; + #ifdef OS_USES_POLL static d_poll_t i4btrcpoll; #define POLLFIELD i4btrcpoll @@ -133,6 +134,8 @@ static d_poll_t i4btrcpoll; #endif #define CDEV_MAJOR 59 + +#if defined (__FreeBSD_version) && __FreeBSD_version >= 400006 static struct cdevsw i4btrc_cdevsw = { /* open */ i4btrcopen, /* close */ i4btrcclose, @@ -154,6 +157,13 @@ static struct cdevsw i4btrc_cdevsw = { /* maxio */ 0, /* bmaj */ -1 }; +#else +static struct cdevsw i4btrc_cdevsw = { + i4btrcopen, i4btrcclose, i4btrcread, nowrite, + i4btrcioctl, nostop, noreset, nodevtotty, + POLLFIELD, nommap, NULL, "i4btrc", NULL, -1 +}; +#endif /*---------------------------------------------------------------------------* * interface init routine @@ -161,8 +171,12 @@ static struct cdevsw i4btrc_cdevsw = { static void i4btrcinit(void *unused) { - - cdevsw_add(&i4btrc_cdevsw); +#if defined (__FreeBSD_version) && __FreeBSD_version >= 400006 + cdevsw_add(&i4btrc_cdevsw); +#else + dev_t dev = makedev(CDEV_MAJOR, 0); + cdevsw_add(&dev, &i4btrc_cdevsw, NULL); +#endif } SYSINIT(i4btrcdev, SI_SUB_DRIVERS, diff --git a/sys/i4b/include/i4b_debug.h b/sys/i4b/include/i4b_debug.h index 628a65e42f2b..980bb0ae1d34 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.18 1999/04/28 14:50:55 hm Exp $ + * $Id: i4b_debug.h,v 1.19 1999/05/28 15:03:32 hm Exp $ * - * last edit-date: [Wed Apr 28 16:50:36 1999] + * last edit-date: [Fri May 28 16:27:07 1999] * *---------------------------------------------------------------------------*/ @@ -221,4 +221,54 @@ typedef struct { #define I4B_CTL_CLR_HSCXSTAT _IOW('C', 3, hscxstat_t) +/*---------------------------------------------------------------------------* + * get LAPD/Q.921 statistics + *---------------------------------------------------------------------------*/ +typedef struct { + /* transmit */ + + u_long tx_i; /* I */ + u_long tx_rr; /* RR */ + u_long tx_rnr; /* RNR */ + u_long tx_rej; /* REJ */ + u_long tx_sabme; /* SABME*/ + u_long tx_dm; /* DM */ + u_long tx_disc; /* DISC */ + u_long tx_ua; /* UA */ + u_long tx_frmr; /* FRMR */ + u_long tx_tei; /* TEI */ + + /* receive */ + + u_long rx_i; /* I */ + u_long rx_rr; /* RR */ + u_long rx_rnr; /* RNR */ + u_long rx_rej; /* REJ */ + u_long rx_sabme; /* SABME*/ + u_long rx_tei; /* TEI */ + u_long rx_ui; /* UI */ + u_long rx_disc; /* DISC */ + u_long rx_xid; /* XID */ + u_long rx_dm; /* DM */ + u_long rx_ua; /* UA */ + u_long rx_frmr; /* FRMR */ + + /* errors */ + + u_long err_rx_len; /* incorrect length */ + u_long err_rx_badf; /* bad frame type */ + u_long err_rx_bads; /* bad s frame */ + u_long err_rx_badu; /* bad u frame */ + u_long err_rx_badui; /* bad ui frame */ +} lapdstat_t; + +typedef struct { + int unit; + lapdstat_t lapdstat; +} l2stat_t; + +#define I4B_CTL_GET_LAPDSTAT _IOWR('C', 4, l2stat_t) + +#define I4B_CTL_CLR_LAPDSTAT _IOW('C', 5, int) + /* EOF */ diff --git a/sys/i4b/include/i4b_ioctl.h b/sys/i4b/include/i4b_ioctl.h index b7289a8c5fa4..2f6c7530990a 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.106 1999/05/19 08:51:14 hm Exp $ + * $Id: i4b_ioctl.h,v 1.125 1999/07/30 07:02:11 hm Exp $ * - * last edit-date: [Wed May 19 10:56:56 1999] + * last edit-date: [Fri Jul 30 08:53:47 1999] * *---------------------------------------------------------------------------*/ @@ -46,7 +46,7 @@ * version and release number for isdn4bsd package *---------------------------------------------------------------------------*/ #define VERSION 0 /* version number */ -#define REL 81 /* release number */ +#define REL 83 /* release number */ #define STEP 0 /* release step */ /*---------------------------------------------------------------------------* @@ -103,7 +103,9 @@ #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 */ - +#define CARD_TYPEP_AVM_PNP 21 /* AVM FRITZ!CARD PnP */ +#define CARD_TYPEP_SIE_ISURF2 22 /* Siemens I-Surf 2 PnP */ +#define CARD_TYPEP_ASUSCOMIPAC 23 /* Asuscom ISDNlink 128 K PnP */ /* * in case you add support for more cards, please update: * @@ -113,7 +115,7 @@ * and adjust CARD_TYPEP_MAX below. */ -#define CARD_TYPEP_MAX 20 /* max type */ +#define CARD_TYPEP_MAX 23 /* max type */ /*---------------------------------------------------------------------------* * card types for CTRL_DAIC @@ -175,7 +177,7 @@ typedef unsigned int cause_t; /* 32 bit unsigned int */ *---------------------------------------------------------------------------*/ #define SHA_FIXU 0 /* timeout algorithm for fix unit charging */ #define SHA_VARU 1 /* timeout algorithm for variable unit charging */ - + /*---------------------------------------------------------------------------* * The shorthold data struct *---------------------------------------------------------------------------*/ @@ -593,14 +595,15 @@ typedef struct { /*---------------------------------------------------------------------------* * request version and release info from kernel part + * (msg_vr_req_t is also used by tel & rbch drivers) *---------------------------------------------------------------------------*/ typedef struct { int version; /* version number */ int release; /* release number */ int step; /* release step number */ } msg_vr_req_t; - -#define I4B_VR_REQ _IOR('4', 9, msg_vr_req_t) + +#define I4B_VR_REQ _IOR('4', 9, msg_vr_req_t) /*---------------------------------------------------------------------------* * Protocol download to active cards diff --git a/sys/i4b/include/i4b_rbch_ioctl.h b/sys/i4b/include/i4b_rbch_ioctl.h new file mode 100644 index 000000000000..97bdb90f6844 --- /dev/null +++ b/sys/i4b/include/i4b_rbch_ioctl.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 1999 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_rbch_ioctl.h raw B-channel driver interface ioctls + * ------------------------------------------------------ + * + * $Id: i4b_rbch_ioctl.h,v 1.1 1999/07/09 06:44:00 hm Exp $ + * + * last edit-date: [Fri Jul 9 08:35:07 1999] + * + *---------------------------------------------------------------------------*/ + +#ifndef _I4B_RBCH_IOCTL_H_ +#define _I4B_RBCH_IOCTL_H_ + +/*---------------------------------------------------------------------------* + * instruct the rbch device to dial the given number + *---------------------------------------------------------------------------*/ + +typedef char telno_t[TELNO_MAX]; + +#define I4B_RBCH_DIALOUT _IOW('R', 1, telno_t) + +/*---------------------------------------------------------------------------* + * request version and release info from kernel part + *---------------------------------------------------------------------------*/ + +#define I4B_RBCH_VR_REQ _IOR('R', 2, msg_vr_req_t) + +#endif /* _I4B_RBCH_IOCTL_H_ */ diff --git a/sys/i4b/include/i4b_tel_ioctl.h b/sys/i4b/include/i4b_tel_ioctl.h index 3df673b4279d..07fcde86df63 100644 --- a/sys/i4b/include/i4b_tel_ioctl.h +++ b/sys/i4b/include/i4b_tel_ioctl.h @@ -27,9 +27,9 @@ * i4b_tel_ioctl.h telephony interface ioctls * ------------------------------------------ * - * $Id: i4b_tel_ioctl.h,v 1.9 1999/04/21 10:06:32 hm Exp $ + * $Id: i4b_tel_ioctl.h,v 1.10 1999/07/09 06:44:00 hm Exp $ * - * last edit-date: [Wed Apr 21 11:00:02 1999] + * last edit-date: [Fri Jul 9 08:34:28 1999] * *---------------------------------------------------------------------------*/ @@ -54,6 +54,12 @@ #define I4B_TEL_SETAUDIOFMT _IOW('A', 1, int) #define I4B_TEL_EMPTYINPUTQUEUE _IOW('A', 2, int) +/*---------------------------------------------------------------------------* + * request version and release info from kernel part + *---------------------------------------------------------------------------*/ + +#define I4B_TEL_VR_REQ _IOR('A', 3, msg_vr_req_t) + /*===========================================================================* * /dev/i4bteld<n> devices (dialer interface) *===========================================================================*/ diff --git a/sys/i4b/layer1/i4b_asuscom_ipac.c b/sys/i4b/layer1/i4b_asuscom_ipac.c new file mode 100644 index 000000000000..5018e0852912 --- /dev/null +++ b/sys/i4b/layer1/i4b_asuscom_ipac.c @@ -0,0 +1,510 @@ +/* + * Copyright (c) 1999 Ari Suutari. All rights reserved. + * Copyright (c) 1997, 1999 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. + * + *--------------------------------------------------------------------------- + * + * isic - I4B Siemens ISDN Chipset Driver for Asuscom ISDNlink 128K PnP + * ===================================================================== + * + * This driver works with Asuscom ISDNlink 128K PnP ISA adapter, + * which is based on Siemens IPAC chip (my card probes as ASU1690). + * Older Asuscom ISA cards are based on different chipset + * (containing two chips) - for those cards, one might want + * to try the Dynalink driver. + * + * This driver is heavily based on ELSA Quickstep 1000pro PCI + * driver written by Hellmuth Michaelis. Card initialization + * code is modeled after Linux i4l driver written by Karsten + * Keil. + * + * $Id: i4b_asuscom_ipac.c,v 1.1 1999/07/05 13:46:46 hm Exp $ + * + * last edit-date: [Mon May 31 20:53:17 EEST 1999] + * + *---------------------------------------------------------------------------*/ + +#if defined(__FreeBSD__) +#include "isic.h" +#include "opt_i4b.h" +#include "pnp.h" +#else +#define NISIC 1 +#define NPNP 1 +#endif + +#if (NISIC > 0) && (NPNP > 0) && defined(ASUSCOM_IPAC) + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/socket.h> +#include <net/if.h> + +#ifdef __FreeBSD__ +#if __FreeBSD__ >= 3 +#include <sys/ioccom.h> +#else +#include <sys/ioctl.h> +#endif +#include <machine/clock.h> +#include <i386/isa/isa_device.h> +#include <i386/isa/pnp.h> +#else +#include <machine/bus.h> +#include <sys/device.h> +#endif + +#ifdef __FreeBSD__ +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> +#else +#include <i4b/i4b_debug.h> +#include <i4b/i4b_ioctl.h> +#endif + +#include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_l1l2.h> +#include <i4b/include/i4b_mbuf.h> + +#include <i4b/layer1/i4b_l1.h> +#include <i4b/layer1/i4b_isac.h> +#include <i4b/layer1/i4b_hscx.h> +#include <i4b/layer1/i4b_ipac.h> + +#ifndef __FreeBSD__ +#include <i4b/layer1/pci_isic.h> +#endif + +/* masks for register encoded in base addr */ + +#define ASI_BASE_MASK 0x0ffff +#define ASI_OFF_MASK 0xf0000 + +/* register id's to be encoded in base addr */ + +#define ASI_IDISAC 0x00000 +#define ASI_IDHSCXA 0x10000 +#define ASI_IDHSCXB 0x20000 +#define ASI_IDIPAC 0x40000 + +/* offsets from base address */ + +#define ASI_OFF_ALE 0x00 +#define ASI_OFF_RW 0x01 + +/*---------------------------------------------------------------------------* + * Asuscom ISDNlink 128K PnP ISAC get fifo routine + *---------------------------------------------------------------------------*/ +#ifdef __FreeBSD__ + +static void +asi_read_fifo(void *buf, const void *base, size_t len) +{ + u_int asus_base; + + asus_base = ((u_int) base) & ASI_BASE_MASK; + switch (((u_int) base) & ASI_OFF_MASK) { + case ASI_IDHSCXB: + outb(asus_base + ASI_OFF_ALE, IPAC_HSCXB_OFF); + insb(asus_base + ASI_OFF_RW, (u_char *)buf, (u_int)len); + break; + case ASI_IDHSCXA: + outb(asus_base + ASI_OFF_ALE, IPAC_HSCXA_OFF); + insb(asus_base + ASI_OFF_RW, (u_char *)buf, (u_int)len); + break; + case ASI_IDISAC: + outb(asus_base + ASI_OFF_ALE, IPAC_ISAC_OFF); + insb(asus_base + ASI_OFF_RW, (u_char *)buf, (u_int)len); + break; + } +} + +#else + +static void +asi_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size) +{ + bus_space_tag_t t = sc->sc_maps[1].t; + bus_space_handle_t h = sc->sc_maps[1].h; + switch (what) { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_ISAC_OFF); + bus_space_read_multi_1(t, h, ASI_OFF_RW, buf, size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXA_OFF); + bus_space_read_multi_1(t, h, ASI_OFF_RW, buf, size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXB_OFF); + bus_space_read_multi_1(t, h, ASI_OFF_RW, buf, size); + break; + } +} + +#endif + +/*---------------------------------------------------------------------------* + * Asuscom ISDNlink 128K PnP ISAC put fifo routine + *---------------------------------------------------------------------------*/ +#ifdef __FreeBSD__ + +static void +asi_write_fifo(void *base, const void *buf, size_t len) +{ + u_int asus_base; + + asus_base = ((u_int) base) & ASI_BASE_MASK; + switch (((u_int) base) & ASI_OFF_MASK) { + case ASI_IDHSCXB: + outb(asus_base + ASI_OFF_ALE, IPAC_HSCXB_OFF); + outsb(asus_base + ASI_OFF_RW, (u_char *)buf, (u_int)len); + break; + case ASI_IDHSCXA: + outb(asus_base + ASI_OFF_ALE, IPAC_HSCXA_OFF); + outsb(asus_base + ASI_OFF_RW, (u_char *)buf, (u_int)len); + break; + case ASI_IDISAC: + outb(asus_base + ASI_OFF_ALE, IPAC_ISAC_OFF); + outsb(asus_base + ASI_OFF_RW, (u_char *)buf, (u_int)len); + break; + } +} + +#else + +static void +asi_write_fifo(struct isic_softc *sc, + int what, const void *buf, size_t size) +{ + bus_space_tag_t t = sc->sc_maps[1].t; + bus_space_handle_t h = sc->sc_maps[1].h; + switch (what) { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_ISAC_OFF); + bus_space_write_multi_1(t, h, ASI_OFF_RW, (u_int8_t*)buf,size); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXA_OFF); + bus_space_write_multi_1(t, h, ASI_OFF_RW, (u_int8_t*)buf,size); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXB_OFF); + bus_space_write_multi_1(t, h, ASI_OFF_RW, (u_int8_t*)buf,size); + break; + } +} +#endif + +/*---------------------------------------------------------------------------* + * Asuscom ISDNlink 128K PnP ISAC put register routine + *---------------------------------------------------------------------------*/ +#ifdef __FreeBSD__ + +static void +asi_write_reg(u_char *base, u_int offset, u_int v) +{ + u_int asus_base; + + asus_base = ((u_int) base) & ASI_BASE_MASK; + switch (((u_int) base) & ASI_OFF_MASK) { + case ASI_IDHSCXB: + outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_HSCXB_OFF)); + outb(asus_base + ASI_OFF_RW, (u_char)v); + break; + case ASI_IDHSCXA: + outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_HSCXA_OFF)); + outb(asus_base + ASI_OFF_RW, (u_char)v); + break; + case ASI_IDISAC: + outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_ISAC_OFF)); + outb(asus_base + ASI_OFF_RW, (u_char)v); + break; + case ASI_IDIPAC: + outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_IPAC_OFF)); + outb(asus_base + ASI_OFF_RW, (u_char)v); + break; + } +} + +#else + +static void +asi_write_reg(struct isic_softc *sc, + int what, bus_size_t offs, u_int8_t data) +{ + bus_space_tag_t t = sc->sc_maps[1].t; + bus_space_handle_t h = sc->sc_maps[1].h; + switch (what) { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_ISAC_OFF+offs); + bus_space_write_1(t, h, ASI_OFF_RW, data); + break; + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXA_OFF+offs); + bus_space_write_1(t, h, ASI_OFF_RW, data); + break; + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXB_OFF+offs); + bus_space_write_1(t, h, ASI_OFF_RW, data); + break; + case ISIC_WHAT_IPAC: + bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_IPAC_OFF+offs); + bus_space_write_1(t, h, ASI_OFF_RW, data); + break; + } +} +#endif + +/*---------------------------------------------------------------------------* + * Asuscom ISDNlink 128K PnP ISAC get register routine + *---------------------------------------------------------------------------*/ +#ifdef __FreeBSD__ + +static u_char +asi_read_reg(u_char *base, u_int offset) +{ + u_int asus_base; + + asus_base = ((u_int) base) & ASI_BASE_MASK; + switch (((u_int) base) & ASI_OFF_MASK) { + case ASI_IDHSCXB: + outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_HSCXB_OFF)); + return(inb(asus_base + ASI_OFF_RW)); + case ASI_IDHSCXA: + outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_HSCXA_OFF)); + return(inb(asus_base + ASI_OFF_RW)); + case ASI_IDISAC: + outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_ISAC_OFF)); + return(inb(asus_base + ASI_OFF_RW)); + case ASI_IDIPAC: + outb(asus_base + ASI_OFF_ALE, (u_char)(offset+IPAC_IPAC_OFF)); + return(inb(asus_base + ASI_OFF_RW)); + } + + return 0; /* NOTREACHED */ +} + +#else + +static u_int8_t +asi_read_reg(struct isic_softc *sc, int what, bus_size_t offs) +{ + bus_space_tag_t t = sc->sc_maps[1].t; + bus_space_handle_t h = sc->sc_maps[1].h; + switch (what) { + case ISIC_WHAT_ISAC: + bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_ISAC_OFF+offs); + return bus_space_read_1(t, h, ASI_OFF_RW); + case ISIC_WHAT_HSCXA: + bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXA_OFF+offs); + return bus_space_read_1(t, h, ASI_OFF_RW); + case ISIC_WHAT_HSCXB: + bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_HSCXB_OFF+offs); + return bus_space_read_1(t, h, ASI_OFF_RW); + case ISIC_WHAT_IPAC: + bus_space_write_1(t, h, ASI_OFF_ALE, IPAC_IPAC_OFF+offs); + return bus_space_read_1(t, h, ASI_OFF_RW); + } + + return 0; +} + +#endif + +/*---------------------------------------------------------------------------* + * isic_attach_asi - attach for Asuscom ISDNlink 128K PnP + *---------------------------------------------------------------------------*/ +#ifdef __FreeBSD__ +int +isic_probe_asi(struct isa_device *dev, unsigned int iobase2) +{ + struct isic_softc *sc = &isic_sc[dev->id_unit]; + + /* check max unit range */ + + if(dev->id_unit >= ISIC_MAXUNIT) + { + printf("isic%d: Error, unit %d >= ISIC_MAXUNIT " + "for Asuscom ISDNlink 128K PnP!\n", + dev->id_unit, dev->id_unit); + + return(0); + } + sc->sc_unit = dev->id_unit; + + /* setup iobase */ + + if((dev->id_iobase <= 0) || (dev->id_iobase > 0xffff)) + { + printf("isic%d: Error, invalid iobase 0x%x specified " + "for Asuscom ISDNlink 128K PnP\n", + dev->id_unit, iobase2); + + return(0); + } + + sc->sc_port = dev->id_iobase; + + /* setup access routines */ + + sc->clearirq = NULL; + sc->readreg = asi_read_reg; + sc->writereg = asi_write_reg; + + sc->readfifo = asi_read_fifo; + sc->writefifo = asi_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_ASUSCOMIPAC; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + /* setup chip type = IPAC ! */ + + sc->sc_ipac = 1; + sc->sc_bfifolen = IPAC_BFIFO_LEN; + + /* setup ISAC and HSCX base addr */ + + ISAC_BASE = (caddr_t) ((u_int)dev->id_iobase | ASI_IDISAC); + HSCX_A_BASE = (caddr_t) ((u_int)dev->id_iobase | ASI_IDHSCXA); + HSCX_B_BASE = (caddr_t) ((u_int)dev->id_iobase | ASI_IDHSCXB); + IPAC_BASE = (caddr_t) ((u_int)dev->id_iobase | ASI_IDIPAC); + + return (1); +} + +int +isic_attach_asi(struct isa_device *dev, unsigned int iobase2) +{ + struct isic_softc *sc = &isic_sc[dev->id_unit]; + /* enable hscx/isac irq's */ +#if 0 +/* + * This is for ELSA driver + */ + IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0)); + + IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */ + IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */ + (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2)); + IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */ + + outb(dev->id_iobase + 0x4c, 0x41); /* enable card interrupt */ +#endif +/* + * This has been taken from Linux driver. + * XXX Figure out bits to use defines as original driver did. + */ + IPAC_WRITE (IPAC_CONF, 0x0); + IPAC_WRITE (IPAC_ACFG, 0xff); + IPAC_WRITE (IPAC_AOE, 0x0); + IPAC_WRITE (IPAC_MASK, 0xc0); + IPAC_WRITE (IPAC_PCFG, 0x12); + + return (1); +} + +#else /* !FreeBSD */ + +void +isic_attach_asi(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); + sc->sc_maps[0].size = 0; + if (pci_mapreg_map(pa, ASI_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; + } + sc->sc_maps[1].size = 0; + if (pci_mapreg_map(pa, ASI_PORT1_MAPOFF, PCI_MAPREG_TYPE_IO, 0, + &sc->sc_maps[1].t, &sc->sc_maps[1].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 = asi_read_reg; + sc->writereg = asi_write_reg; + + sc->readfifo = asi_read_fifo; + sc->writefifo = asi_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_ASUSCOMIPAC; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + /* setup chip type = IPAC ! */ + + sc->sc_ipac = 1; + sc->sc_bfifolen = IPAC_BFIFO_LEN; + +#if 0 +/* + * This for ELSA card in original driver. + */ + /* enable hscx/isac irq's */ + IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0)); + + IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */ + IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */ + (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2)); + IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */ + + bus_space_write_1(sc->sc_maps[0].t, sc->sc_maps[0].h, 0x4c, 0x41); /* enable card interrupt */ +#endif +/* + * This has been taken from Linux driver. + * XXX Figure out bits to use defines as original driver did. + */ + IPAC_WRITE (IPAC_CONF, 0x0); + IPAC_WRITE (IPAC_ACFG, 0xff); + IPAC_WRITE (IPAC_AOE, 0x0); + IPAC_WRITE (IPAC_MASK, 0xc0); + IPAC_WRITE (IPAC_PCFG, 0x12); +} + + +#endif + +#endif /* (NISIC > 0) && defined(ASUSCOM_IPAC) */ diff --git a/sys/i4b/layer1/i4b_avm_fritz_pci.c b/sys/i4b/layer1/i4b_avm_fritz_pci.c index 2da4f8953be9..c5f2d8a917b2 100644 --- a/sys/i4b/layer1/i4b_avm_fritz_pci.c +++ b/sys/i4b/layer1/i4b_avm_fritz_pci.c @@ -35,9 +35,9 @@ * Fritz!Card PCI specific routines for isic driver * ------------------------------------------------ * - * $Id: i4b_avm_fritz_pci.c,v 1.5 1999/05/05 11:50:21 hm Exp $ + * $Id: i4b_avm_fritz_pci.c,v 1.6 1999/06/01 12:10:25 hm Exp $ * - * last edit-date: [Tue Mar 16 16:18:35 1999] + * last edit-date: [Tue Jun 1 14:08:01 1999] * *---------------------------------------------------------------------------*/ @@ -390,30 +390,31 @@ avma1pp_write_fifo(void *base, const void *buf, size_t len) } /* tell the board to use the ISAC fifo */ outb(sc->sc_port + ADDR_REG_OFFSET, ISAC_FIFO); - outsb(sc->sc_port + ISAC_REG_OFFSET, (u_char *)buf, len); + outsb(sc->sc_port + ISAC_REG_OFFSET, (const u_char *)buf, len); } static void hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc) { - register u_int *ip; + register const u_int *ip; register 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->out_mbuf_cur == NULL) { if (Bchan->bprot != BPROT_NONE) sc->avma1pp_cmd |= HSCX_CMD_XME; - sc->avma1pp_txl = len; } - + if (len != sc->sc_bfifolen) + sc->avma1pp_txl = len; + cnt = 0; /* borrow cnt */ AVMA1PPSETCMDLONG(cnt); hscx_write_reg(chan, HSCX_STAT, cnt, sc); - ip = (u_int *)buf; + ip = (const u_int *)buf; cnt = 0; while (cnt < len) { @@ -450,12 +451,13 @@ hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc) sc->avma1pp_cmd &= ~HSCX_CMD_XME; sc->avma1pp_txl = 0; - if (len != sc->sc_bfifolen) + if (Bchan->out_mbuf_cur == NULL) { if (Bchan->bprot != BPROT_NONE) sc->avma1pp_cmd |= HSCX_CMD_XME; - sc->avma1pp_txl = len; } + if (len != sc->sc_bfifolen) + sc->avma1pp_txl = len; cnt = 0; /* borrow cnt */ AVMA1PPSETCMDLONG(cnt); @@ -492,7 +494,7 @@ avma1pp_write_reg(u_char *base, u_int offset, u_int v) hscx_write_reg(0, offset, v, sc); return; } - if (((int)base & IS_HSCX_MASK) == HSCX0FAKE) + if (((int)base & IS_HSCX_MASK) == HSCX1FAKE) { hscx_write_reg(1, offset, v, sc); return; diff --git a/sys/i4b/layer1/i4b_avm_fritz_pnp.c b/sys/i4b/layer1/i4b_avm_fritz_pnp.c new file mode 100644 index 000000000000..6da4969e8829 --- /dev/null +++ b/sys/i4b/layer1/i4b_avm_fritz_pnp.c @@ -0,0 +1,1268 @@ +/* + * Copyright (c) 1999 Udo Schweigert. 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. + * + *--------------------------------------------------------------------------- + * A lot of code was borrowed from i4b_bchan.c and i4b_hscx.c + * Based on AVM Fritz!PCI driver by Gary Jennejohn + *--------------------------------------------------------------------------- + * In case of trouble please contact Udo Schweigert <ust@cert.siemens.de> + *--------------------------------------------------------------------------- + * + * Fritz!Card PnP specific routines for isic driver + * ------------------------------------------------ + * + * $Id: i4b_avm_fritz_pnp.c,v 1.3 1999/07/05 13:22:12 hm Exp $ + * + * last edit-date: [Thu 10 Jun 08:50:28 CEST 1999] + * + *---------------------------------------------------------------------------*/ + +#if defined(__FreeBSD__) +#include "isic.h" +#include "opt_i4b.h" + +#if NISIC > 0 && defined(AVM_PNP) + +#include <sys/param.h> +#if defined(__FreeBSD__) && __FreeBSD__ >= 3 +#include <sys/ioccom.h> +#else +#include <sys/ioctl.h> +#endif +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> + +#include <machine/clock.h> +#include <i386/isa/isa_device.h> + +#include <sys/socket.h> +#include <net/if.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> + +#include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_l1l2.h> +#include <i4b/include/i4b_mbuf.h> + +#include <i4b/layer1/i4b_l1.h> +#include <i4b/layer1/i4b_isac.h> +#include <i4b/layer1/i4b_hscx.h> + +static void hscx_write_reg(int, u_int, struct isic_softc *, int); +static void hscx_write_reg_val(int, u_int, u_char, struct isic_softc *); +static u_char hscx_read_reg(int, u_int, struct isic_softc *); +static void hscx_read_fifo(int, void *, size_t, struct isic_softc *); +static void hscx_write_fifo(int, const void *, size_t, struct isic_softc *); +static void avm_pnp_hscx_int_handler(struct isic_softc *); +static void avm_pnp_hscx_intr(int, int, int, struct isic_softc *); +static void avm_pnp_init_linktab(struct isic_softc *); +static void avm_pnp_bchannel_setup(int, int, int, int); +static void avm_pnp_bchannel_start(int, int); +static void avm_pnp_hscx_init(struct isic_softc *, int, int); +static void avm_pnp_bchannel_stat(int, int, bchan_statistics_t *); +static void avm_pnp_set_linktab(int, int, drvr_link_t *); +static void avm_pnp_intr(int); +static isdn_link_t * avm_pnp_ret_linktab(int, int); +extern void isicintr_sc(struct isic_softc *); + +/*---------------------------------------------------------------------------* + * AVM PnP Fritz!Card special registers + *---------------------------------------------------------------------------*/ + +/* + * register offsets from i/o base + */ +#define STAT0_OFFSET 0x02 +#define STAT1_OFFSET 0x03 +#define ADDR_REG_OFFSET 0x04 + +/* 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 PnP Status Latch 0 read only bits + */ +#define ASL_IRQ_ISAC 0x01 /* ISAC interrupt, active low */ +#define ASL_IRQ_HSCX 0x02 /* HSX interrupt, active low */ +#define ASL_IRQ_TIMER 0x04 /* Timer interrupt, active low */ +#define ASL_IRQ_BCHAN ASL_IRQ_HSCX +/* actually active LOW */ +#define ASL_IRQ_Pending 0x07 + +/* + * AVM Status Latch 0 write only bits + */ +#define ASL_RESET_ALL 0x01 /* reset siemens IC's, active 1 */ +#define ASL_TIMERDISABLE 0x02 /* active high */ +#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 + */ +#define ASL1_INTSEL 0x0f /* active high */ +#define ASL1_ENABLE_IOM 0x80 /* active high */ + +/* + * "HSCX" mode bits + */ +#define HSCX_MODE_ITF_FLG 0x01 +#define HSCX_MODE_TRANS 0x02 +#define HSCX_MODE_CCR_7 0x04 +#define HSCX_MODE_CCR_16 0x08 +#define HSCX_MODE_TESTLOOP 0x80 + +/* + * "HSCX" status bits + */ +#define HSCX_STAT_RME 0x01 +#define HSCX_STAT_RDO 0x10 +#define HSCX_STAT_CRCVFRRAB 0x0E +#define HSCX_STAT_CRCVFR 0x06 +#define HSCX_STAT_RML_MASK 0x3f00 + +/* + * "HSCX" interrupt bits + */ +#define HSCX_INT_XPR 0x80 +#define HSCX_INT_XDU 0x40 +#define HSCX_INT_RPR 0x20 +#define HSCX_INT_MASK 0xE0 + +/* + * "HSCX" command bits + */ +#define HSCX_CMD_XRS 0x80 +#define HSCX_CMD_XME 0x01 +#define HSCX_CMD_RRS 0x20 +#define HSCX_CMD_XML_MASK 0x3f00 + +/* "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 + +/* + * 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 + * flag in avm_pnp_bchannel_setup upon active and cleared upon deactivation. + * It is set high to allow room for new flags. + */ +#define HSCX_AVMPNP_ACTIVE 0x1000 + +/*---------------------------------------------------------------------------* + * AVM read fifo routines + *---------------------------------------------------------------------------*/ + +static void +avm_pnp_read_fifo(void *buf, const void *base, size_t len) +{ + int unit; + struct isic_softc *sc; + + unit = (int)base & 0xff; + sc = &isic_sc[unit]; + + /* check whether the target is an HSCX */ + if (((int)base & IS_HSCX_MASK) == HSCX0FAKE) + { + hscx_read_fifo(0, buf, len, sc); + return; + } + if (((int)base & IS_HSCX_MASK) == HSCX1FAKE) + { + hscx_read_fifo(1, buf, len, sc); + return; + } + /* tell the board to access the ISAC fifo */ + outb(sc->sc_port + ADDR_REG_OFFSET, ISAC_FIFO); + insb(sc->sc_port + ISAC_REG_OFFSET, (u_char *)buf, len); +} + +static void +hscx_read_fifo(int chan, void *buf, size_t len, struct isic_softc *sc) +{ + u_char *ip; + size_t cnt; + + outb(sc->sc_port + ADDR_REG_OFFSET, chan); + ip = (u_char *)buf; + cnt = 0; + + while (cnt < len) + { + *ip++ = inb(sc->sc_port + ISAC_REG_OFFSET); + cnt++; + } +} + +/*---------------------------------------------------------------------------* + * AVM write fifo routines + *---------------------------------------------------------------------------*/ +static void +avm_pnp_write_fifo(void *base, const void *buf, size_t len) +{ + int unit; + struct isic_softc *sc; + + unit = (int)base & 0xff; + sc = &isic_sc[unit]; + + /* check whether the target is an HSCX */ + if (((int)base & IS_HSCX_MASK) == HSCX0FAKE) + { + hscx_write_fifo(0, buf, len, sc); + return; + } + if (((int)base & IS_HSCX_MASK) == HSCX1FAKE) + { + hscx_write_fifo(1, buf, len, sc); + return; + } + /* tell the board to use the ISAC fifo */ + outb(sc->sc_port + ADDR_REG_OFFSET, ISAC_FIFO); + outsb(sc->sc_port + ISAC_REG_OFFSET, (const u_char *)buf, len); +} + +static void +hscx_write_fifo(int chan, const void *buf, size_t len, struct isic_softc *sc) +{ + register const u_char *ip; + register size_t cnt; + isic_Bchan_t *Bchan = &sc->sc_chan[chan]; + + sc->avma1pp_cmd &= ~HSCX_CMD_XME; + sc->avma1pp_txl = 0; + + if (Bchan->out_mbuf_cur == NULL && Bchan->bprot != BPROT_NONE) + sc->avma1pp_cmd |= HSCX_CMD_XME; + + if (len != sc->sc_bfifolen) + sc->avma1pp_txl = len; + + hscx_write_reg(chan, HSCX_STAT, sc, 3); + + ip = (const u_char *)buf; + cnt = 0; + while (cnt < len) + { + outb(sc->sc_port + ISAC_REG_OFFSET, *ip++); + cnt++; + } +} + +/*---------------------------------------------------------------------------* + * AVM write register routines + *---------------------------------------------------------------------------*/ +static void +avm_pnp_write_reg(u_char *base, u_int offset, u_int v) +{ + int unit; + struct isic_softc *sc; + u_char reg_bank; + + unit = (int)base & 0xff; + sc = &isic_sc[unit]; + + /* check whether the target is an HSCX */ + if (((int)base & IS_HSCX_MASK) == HSCX0FAKE) + { + hscx_write_reg_val(0, offset, v, sc); + return; + } + if (((int)base & IS_HSCX_MASK) == HSCX1FAKE) + { + hscx_write_reg_val(1, offset, v, sc); + return; + } + /* must be the ISAC */ + reg_bank = (offset > MAX_LO_REG_OFFSET) ? ISAC_HI_REG_OFFSET:ISAC_LO_REG_OFFSET; + /* set the register bank */ + outb(sc->sc_port + ADDR_REG_OFFSET, reg_bank); + outb(sc->sc_port + ISAC_REG_OFFSET + (offset & ISAC_REGSET_MASK), v); +} + +static void +hscx_write_reg(int chan, u_int off, struct isic_softc *sc, int which) +{ + /* HACK */ + if (off == H_MASK) + return; + /* point at the correct channel */ + outb(sc->sc_port + ADDR_REG_OFFSET, chan); + if (which & 4) + outb(sc->sc_port + ISAC_REG_OFFSET + off + 2, sc->avma1pp_prot); + if (which & 2) + outb(sc->sc_port + ISAC_REG_OFFSET + off + 1, sc->avma1pp_txl); + if (which & 1) + outb(sc->sc_port + ISAC_REG_OFFSET + off, sc->avma1pp_cmd); +} + +static void +hscx_write_reg_val(int chan, u_int off, u_char val, struct isic_softc *sc) +{ + /* HACK */ + if (off == H_MASK) + return; + /* point at the correct channel */ + outb(sc->sc_port + ADDR_REG_OFFSET, chan); + outb(sc->sc_port + ISAC_REG_OFFSET + off, val); +} + +/*---------------------------------------------------------------------------* + * AVM read register routines + *---------------------------------------------------------------------------*/ + +static u_char +avm_pnp_read_reg(u_char *base, u_int offset) +{ + int unit; + struct isic_softc *sc; + u_char reg_bank; + + unit = (int)base & 0xff; + sc = &isic_sc[unit]; + + /* check whether the target is an HSCX */ + if (((int)base & IS_HSCX_MASK) == HSCX0FAKE) + return(hscx_read_reg(0, offset, sc)); + if (((int)base & IS_HSCX_MASK) == HSCX1FAKE) + return(hscx_read_reg(1, offset, sc)); + /* must be the ISAC */ + reg_bank = (offset > MAX_LO_REG_OFFSET) ? ISAC_HI_REG_OFFSET:ISAC_LO_REG_OFFSET; + /* set the register bank */ + outb(sc->sc_port + ADDR_REG_OFFSET, reg_bank); + return(inb(sc->sc_port + ISAC_REG_OFFSET + + (offset & ISAC_REGSET_MASK))); +} + +static u_char +hscx_read_reg(int chan, u_int off, struct isic_softc *sc) +{ + /* HACK */ + if (off == H_ISTA) + return(0); + /* point at the correct channel */ + outb(sc->sc_port + ADDR_REG_OFFSET, chan); + return(inb(sc->sc_port + ISAC_REG_OFFSET + off)); +} + +/*---------------------------------------------------------------------------* + * isic_probe_avm_pnp - probe Fritz!Card PnP + *---------------------------------------------------------------------------*/ + +int +isic_probe_avm_pnp(struct isa_device *dev, unsigned int iobase2) +{ + struct isic_softc *sc = &isic_sc[dev->id_unit]; + + /* check max unit range */ + + if(dev->id_unit >= ISIC_MAXUNIT) + { + printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for AVM Fritz! PnP\n", + dev->id_unit, dev->id_unit); + return(0); + } + sc->sc_unit = dev->id_unit; + + /* check IRQ validity */ + + switch(ffs(dev->id_irq) - 1) + { + case 3: + case 4: + case 5: + case 7: + case 10: + case 11: + case 12: + case 15: + break; + + default: + printf("isic%d: Error, invalid IRQ [%d] specified for AVM Fritz! PnP!\n", + dev->id_unit, ffs(dev->id_irq)-1); + return(0); + break; + } + sc->sc_irq = dev->id_irq; + + dev->id_intr = (inthand2_t *) avm_pnp_intr; + + /* check if memory addr specified */ + + if(dev->id_maddr) + { + printf("isic%d: Error, mem addr 0x%lx specified for AVM Fritz! PnP!\n", + dev->id_unit, (u_long)dev->id_maddr); + return(0); + } + dev->id_msize = 0; + + /* check if we got an iobase */ + + if(!((dev->id_iobase >= 0x160) && (dev->id_iobase <= 0x360))) + { + printf("isic%d: Error, invalid iobase 0x%x specified for AVM Fritz! PnP!\n", + dev->id_unit, dev->id_iobase); + return(0); + } + sc->sc_port = dev->id_iobase; + + + /* setup access routines */ + + sc->clearirq = NULL; + sc->readreg = avm_pnp_read_reg; + sc->writereg = avm_pnp_write_reg; + + sc->readfifo = avm_pnp_read_fifo; + sc->writefifo = avm_pnp_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_AVM_PNP; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + sc->sc_ipac = 0; + sc->sc_bfifolen = HSCX_FIFO_LEN; + + /* the ISAC lives at offset 0x10, but we can't use that. */ + /* instead, put the unit number into the lower byte - HACK */ + ISAC_BASE = (caddr_t)((int)(dev->id_iobase & ~0xff) + dev->id_unit); + + outb(sc->sc_port + STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); + ISAC_WRITE(I_MASK, 0x0); + outb(sc->sc_port + STAT0_OFFSET, ASL_TIMERRESET|ASL_ENABLE_INT|ASL_TIMERDISABLE); + ISAC_WRITE(I_MASK, 0x41); + return (1); +} + +/*---------------------------------------------------------------------------* + * isic_attach_avm_pnp - attach Fritz!Card PnP + *---------------------------------------------------------------------------*/ +int +isic_attach_avm_pnp(struct isa_device *dev, unsigned int iobase2) +{ + struct isic_softc *sc; + u_int v; + int unit; + + unit = dev->id_unit; + sc = &isic_sc[unit]; + + /* this thing doesn't have an HSCX, so fake the base addresses */ + /* put the unit number into the lower byte - HACK */ + HSCX_A_BASE = (caddr_t)(HSCX0FAKE + unit); + HSCX_B_BASE = (caddr_t)(HSCX1FAKE + unit); + + + /* reset the card */ + + /* the Linux driver does this to clear any pending ISAC interrupts */ + v = 0; + v = ISAC_READ(I_STAR); + v = ISAC_READ(I_MODE); + v = ISAC_READ(I_ADF2); + v = ISAC_READ(I_ISTA); + if (v & ISAC_ISTA_EXI) + { + v = ISAC_READ(I_EXIR); + } + v = ISAC_READ(I_CIRR); + ISAC_WRITE(I_MASK, 0xff); + + /* the Linux driver does this to clear any pending HSCX interrupts */ + v = hscx_read_reg(0, HSCX_STAT, sc); + v = hscx_read_reg(0, HSCX_STAT+1, sc); + v = hscx_read_reg(0, HSCX_STAT+2, sc); + v = hscx_read_reg(0, HSCX_STAT+3, sc); + v = hscx_read_reg(1, HSCX_STAT, sc); + v = hscx_read_reg(1, HSCX_STAT+1, sc); + v = hscx_read_reg(1, HSCX_STAT+2, sc); + v = hscx_read_reg(1, HSCX_STAT+3, sc); + + outb(sc->sc_port + STAT0_OFFSET, ASL_RESET_ALL|ASL_TIMERDISABLE); + DELAY(SEC_DELAY/100); /* 10 ms */ + outb(sc->sc_port + STAT0_OFFSET, ASL_TIMERRESET|ASL_ENABLE_INT|ASL_TIMERDISABLE); + DELAY(SEC_DELAY/100); /* 10 ms */ + outb(sc->sc_port + STAT1_OFFSET, ASL1_ENABLE_IOM+(ffs(sc->sc_irq)-1)); + DELAY(SEC_DELAY/100); /* 10 ms */ + + 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'); + + /* init the ISAC */ + isic_isac_init(sc); + + /* init the "HSCX" */ + avm_pnp_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0); + + avm_pnp_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0); + + /* can't use the normal B-Channel stuff */ + avm_pnp_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; + +#if defined(__FreeBSD__) && __FreeBSD__ >=3 + callout_handle_init(&sc->sc_T3_callout); + callout_handle_init(&sc->sc_T4_callout); +#endif + + /* init higher protocol layers */ + + MPH_Status_Ind(sc->sc_unit, STI_ATTACH, sc->sc_cardtyp); + + return(0); +} + +/* + * this is the real interrupt routine + */ +static void +avm_pnp_hscx_intr(int h_chan, int stat, int cnt, struct isic_softc *sc) +{ + register isic_Bchan_t *chan = &sc->sc_chan[h_chan]; + int activity = -1; + + DBGL1(L1_H_IRQ, "avm_pnp_hscx_intr", ("%#x\n", stat)); + + if((stat & HSCX_INT_XDU) && (chan->bprot != BPROT_NONE))/* xmit data underrun */ + { + chan->stat_XDU++; + DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("xmit data underrun\n")); + /* abort the transmission */ + sc->avma1pp_txl = 0; + sc->avma1pp_cmd |= HSCX_CMD_XRS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 1); + sc->avma1pp_cmd &= ~HSCX_CMD_XRS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 1); + + if (chan->out_mbuf_head != NULL) /* don't continue to transmit this buffer */ + { + i4b_Bfreembuf(chan->out_mbuf_head); + chan->out_mbuf_cur = chan->out_mbuf_head = NULL; + } + } + + /* + * 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. + * HSCX_INT_RPR indicates a receive interrupt + * HSCX_STAT_RDO indicates an overrun condition, abort - + * otherwise read the bytes ((stat & HSCX_STZT_RML_MASK) >> 8) + * HSCX_STAT_RME indicates end-of-frame and apparently any + * CRC/framing errors are only reported in this state. + * if ((stat & HSCX_STAT_CRCVFRRAB) != HSCX_STAT_CRCVFR) + * CRC/framing error + */ + + if(stat & HSCX_INT_RPR) + { + register int fifo_data_len; + int error = 0; + /* always have to read the FIFO, so use a scratch buffer */ + u_char scrbuf[HSCX_FIFO_LEN]; + + if(stat & HSCX_STAT_RDO) + { + chan->stat_RDO++; + DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("receive data overflow\n")); + error++; + } + + fifo_data_len = cnt; + + if(fifo_data_len == 0) + fifo_data_len = sc->sc_bfifolen; + + /* ALWAYS read data from HSCX fifo */ + + HSCX_RDFIFO(h_chan, scrbuf, fifo_data_len); + chan->rxcount += fifo_data_len; + + /* all error conditions checked, now decide and take action */ + + if(error == 0) + { + if(chan->in_mbuf == NULL) + { + if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) + panic("L1 avm_pnp_hscx_intr: RME, cannot allocate mbuf!\n"); + chan->in_cbptr = chan->in_mbuf->m_data; + chan->in_len = 0; + } + + if((chan->in_len + fifo_data_len) <= BCH_MAX_DATALEN) + { + /* 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; + + /* setup mbuf data length */ + + chan->in_mbuf->m_len = chan->in_len; + chan->in_mbuf->m_pkthdr.len = chan->in_len; + + + if(sc->sc_trace & TRACE_B_RX) + { + i4b_trace_hdr_t hdr; + hdr.unit = sc->sc_unit; + hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); + hdr.dir = FROM_NT; + hdr.count = ++sc->sc_trace_bcount; + MICROTIME(hdr.time); + MPH_Trace_Ind(&hdr, chan->in_mbuf->m_len, chan->in_mbuf->m_data); + } + + if (stat & HSCX_STAT_RME) + { + if((stat & HSCX_STAT_CRCVFRRAB) == HSCX_STAT_CRCVFR) + { + (*chan->drvr_linktab->bch_rx_data_ready)(chan->drvr_linktab->unit); + activity = ACT_RX; + + /* mark buffer ptr as unused */ + + chan->in_mbuf = NULL; + chan->in_cbptr = NULL; + chan->in_len = 0; + } + else + { + chan->stat_CRC++; + DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("CRC/RAB\n")); + if (chan->in_mbuf != NULL) + { + i4b_Bfreembuf(chan->in_mbuf); + chan->in_mbuf = NULL; + chan->in_cbptr = NULL; + chan->in_len = 0; + } + } + } + } /* END enough space in mbuf */ + else + { + if(chan->bprot == BPROT_NONE) + { + /* setup mbuf data length */ + + chan->in_mbuf->m_len = chan->in_len; + chan->in_mbuf->m_pkthdr.len = chan->in_len; + + if(sc->sc_trace & TRACE_B_RX) + { + i4b_trace_hdr_t hdr; + hdr.unit = sc->sc_unit; + hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); + hdr.dir = FROM_NT; + hdr.count = ++sc->sc_trace_bcount; + MICROTIME(hdr.time); + 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); + + (*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; + + /* alloc new buffer */ + + if((chan->in_mbuf = i4b_Bgetmbuf(BCH_MAX_DATALEN)) == NULL) + panic("L1 avm_pnp_hscx_intr: RPF, cannot allocate new mbuf!\n"); + + /* setup new data ptr */ + + chan->in_cbptr = chan->in_mbuf->m_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->rxcount += fifo_data_len; + } + else + { + DBGL1(L1_H_XFRERR, "avm_pnp_hscx_intr", ("RAWHDLC rx buffer overflow in RPF, in_len=%d\n", chan->in_len)); + chan->in_cbptr = chan->in_mbuf->m_data; + chan->in_len = 0; + } + } + } /* if(error == 0) */ + else + { + /* land here for RDO */ + if (chan->in_mbuf != NULL) + { + i4b_Bfreembuf(chan->in_mbuf); + chan->in_mbuf = NULL; + chan->in_cbptr = NULL; + chan->in_len = 0; + } + sc->avma1pp_txl = 0; + sc->avma1pp_cmd |= HSCX_CMD_RRS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 1); + sc->avma1pp_cmd &= ~HSCX_CMD_RRS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 1); + } + } + + + /* transmit fifo empty, new data can be written to fifo */ + + if(stat & HSCX_INT_XPR) + { + /* + * for a description what is going on here, please have + * a look at isic_bchannel_start() in i4b_bchan.c ! + */ + + DBGL1(L1_H_IRQ, "avm_pnp_hscx_intr", ("unit %d, chan %d - XPR, Tx Fifo Empty!\n", sc->sc_unit, h_chan)); + + if(chan->out_mbuf_cur == NULL || chan->out_mbuf_head == NULL) /* last frame is transmitted */ + { + IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head); + + if(chan->out_mbuf_head == NULL) + { + chan->state &= ~HSCX_TX_ACTIVE; + (*chan->drvr_linktab->bch_tx_queue_empty)(chan->drvr_linktab->unit); + } + else + { + chan->state |= HSCX_TX_ACTIVE; + chan->out_mbuf_cur = chan->out_mbuf_head; + chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; + chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; + + if(sc->sc_trace & TRACE_B_TX) + { + i4b_trace_hdr_t hdr; + hdr.unit = sc->sc_unit; + hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); + hdr.dir = FROM_TE; + hdr.count = ++sc->sc_trace_bcount; + MICROTIME(hdr.time); + MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); + } + if(chan->bprot == BPROT_NONE) + { + if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) + activity = ACT_TX; + } + else + { + activity = ACT_TX; + } + } + } + + isic_hscx_fifo(chan, sc); + } + + /* call timeout handling routine */ + + if(activity == ACT_RX || activity == ACT_TX) + (*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity); +} + +/* + * this is the main routine which checks each channel and then calls + * the real interrupt routine as appropriate + */ +static void +avm_pnp_hscx_int_handler(struct isic_softc *sc) +{ + u_char stat = 0; + u_char cnt = 0; + + stat = hscx_read_reg(0, HSCX_STAT, sc); + if (stat & HSCX_INT_RPR) + cnt = hscx_read_reg(0, HSCX_STAT+1, sc); + if (stat & HSCX_INT_MASK) + avm_pnp_hscx_intr(0, stat, cnt, sc); + + cnt = 0; + stat = hscx_read_reg(1, HSCX_STAT, sc); + if (stat & HSCX_INT_RPR) + cnt = hscx_read_reg(1, HSCX_STAT+1, sc); + if (stat & HSCX_INT_MASK) + avm_pnp_hscx_intr(1, stat, cnt, sc); +} + +static void +avm_pnp_hscx_init(struct isic_softc *sc, int h_chan, int activate) +{ + isic_Bchan_t *chan = &sc->sc_chan[h_chan]; + + DBGL1(L1_BCHAN, "avm_pnp_hscx_init", ("unit=%d, channel=%d, %s\n", + sc->sc_unit, h_chan, activate ? "activate" : "deactivate")); + + if (activate == 0) + { + /* only deactivate if both channels are idle */ + if (sc->sc_chan[HSCX_CH_A].state != HSCX_IDLE || + sc->sc_chan[HSCX_CH_B].state != HSCX_IDLE) + { + return; + } + sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; + sc->avma1pp_prot = HSCX_MODE_TRANS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 5); + return; + } + if(chan->bprot == BPROT_RHDLC) + { + DBGL1(L1_BCHAN, "avm_pnp_hscx_init", ("BPROT_RHDLC\n")); + + /* HDLC Frames, transparent mode 0 */ + sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; + sc->avma1pp_prot = HSCX_MODE_ITF_FLG; + hscx_write_reg(h_chan, HSCX_STAT, sc, 5); + sc->avma1pp_cmd = HSCX_CMD_XRS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 1); + sc->avma1pp_cmd = 0; + } + else + { + DBGL1(L1_BCHAN, "avm_pnp_hscx_init", ("BPROT_NONE??\n")); + + /* Raw Telephony, extended transparent mode 1 */ + sc->avma1pp_cmd = HSCX_CMD_XRS|HSCX_CMD_RRS; + sc->avma1pp_prot = HSCX_MODE_TRANS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 5); + sc->avma1pp_cmd = HSCX_CMD_XRS; + hscx_write_reg(h_chan, HSCX_STAT, sc, 1); + sc->avma1pp_cmd = 0; + } +} + +static void +avm_pnp_bchannel_setup(int unit, int h_chan, int bprot, int activate) +{ + struct isic_softc *sc = &isic_sc[unit]; + isic_Bchan_t *chan = &sc->sc_chan[h_chan]; + + int s = SPLI4B(); + + if(activate == 0) + { + /* deactivation */ + chan->state &= ~HSCX_AVMPNP_ACTIVE; + avm_pnp_hscx_init(sc, h_chan, activate); + } + + DBGL1(L1_BCHAN, "avm_pnp_bchannel_setup", ("unit=%d, channel=%d, %s\n", + sc->sc_unit, h_chan, activate ? "activate" : "deactivate")); + + /* general part */ + + chan->unit = sc->sc_unit; /* unit number */ + chan->channel = h_chan; /* B channel */ + chan->bprot = bprot; /* B channel protocol */ + chan->state = HSCX_IDLE; /* B channel state */ + + /* receiver part */ + + i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */ + + chan->rx_queue.ifq_maxlen = IFQ_MAXLEN; + + chan->rxcount = 0; /* reset rx counter */ + + i4b_Bfreembuf(chan->in_mbuf); /* clean rx mbuf */ + + chan->in_mbuf = NULL; /* reset mbuf ptr */ + chan->in_cbptr = NULL; /* reset mbuf curr ptr */ + chan->in_len = 0; /* reset mbuf data len */ + + /* transmitter part */ + + i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */ + + chan->tx_queue.ifq_maxlen = IFQ_MAXLEN; + + chan->txcount = 0; /* reset tx counter */ + + i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */ + + chan->out_mbuf_head = NULL; /* reset head mbuf ptr */ + chan->out_mbuf_cur = NULL; /* reset current mbuf ptr */ + chan->out_mbuf_cur_ptr = NULL; /* reset current mbuf data ptr */ + chan->out_mbuf_cur_len = 0; /* reset current mbuf data cnt */ + + if(activate != 0) + { + /* activation */ + avm_pnp_hscx_init(sc, h_chan, activate); + chan->state |= HSCX_AVMPNP_ACTIVE; + } + + splx(s); +} + +static void +avm_pnp_bchannel_start(int unit, int h_chan) +{ + struct isic_softc *sc = &isic_sc[unit]; + register isic_Bchan_t *chan = &sc->sc_chan[h_chan]; + int s; + int activity = -1; + + s = SPLI4B(); /* enter critical section */ + if(chan->state & HSCX_TX_ACTIVE) /* already running ? */ + { + splx(s); + return; /* yes, leave */ + } + + /* get next mbuf from queue */ + + IF_DEQUEUE(&chan->tx_queue, chan->out_mbuf_head); + + if(chan->out_mbuf_head == NULL) /* queue empty ? */ + { + splx(s); /* leave critical section */ + return; /* yes, exit */ + } + + /* init current mbuf values */ + + chan->out_mbuf_cur = chan->out_mbuf_head; + chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; + chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; + + /* activity indicator for timeout handling */ + + if(chan->bprot == BPROT_NONE) + { + if(!(isic_hscx_silence(chan->out_mbuf_cur->m_data, chan->out_mbuf_cur->m_len))) + activity = ACT_TX; + } + else + { + activity = ACT_TX; + } + + chan->state |= HSCX_TX_ACTIVE; /* we start transmitting */ + + if(sc->sc_trace & TRACE_B_TX) /* if trace, send mbuf to trace dev */ + { + i4b_trace_hdr_t hdr; + hdr.unit = unit; + hdr.type = (h_chan == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); + hdr.dir = FROM_TE; + hdr.count = ++sc->sc_trace_bcount; + MICROTIME(hdr.time); + MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); + } + + isic_hscx_fifo(chan, sc); + + /* call timeout handling routine */ + + if(activity == ACT_RX || activity == ACT_TX) + (*chan->drvr_linktab->bch_activity)(chan->drvr_linktab->unit, activity); + + splx(s); +} + +/*---------------------------------------------------------------------------* + * return the address of isic drivers linktab + *---------------------------------------------------------------------------*/ +static isdn_link_t * +avm_pnp_ret_linktab(int unit, int channel) +{ + struct isic_softc *sc = &isic_sc[unit]; + isic_Bchan_t *chan = &sc->sc_chan[channel]; + + return(&chan->isdn_linktab); +} + +/*---------------------------------------------------------------------------* + * set the driver linktab in the b channel softc + *---------------------------------------------------------------------------*/ +static void +avm_pnp_set_linktab(int unit, int channel, drvr_link_t *dlt) +{ + struct isic_softc *sc = &isic_sc[unit]; + isic_Bchan_t *chan = &sc->sc_chan[channel]; + + chan->drvr_linktab = dlt; +} + + +/*---------------------------------------------------------------------------* + * initialize our local linktab + *---------------------------------------------------------------------------*/ +static void +avm_pnp_init_linktab(struct isic_softc *sc) +{ + isic_Bchan_t *chan = &sc->sc_chan[HSCX_CH_A]; + isdn_link_t *lt = &chan->isdn_linktab; + + /* make sure the hardware driver is known to layer 4 */ + /* avoid overwriting if already set */ + if (ctrl_types[CTRL_PASSIVE].set_linktab == NULL) + { + ctrl_types[CTRL_PASSIVE].set_linktab = avm_pnp_set_linktab; + ctrl_types[CTRL_PASSIVE].get_linktab = avm_pnp_ret_linktab; + } + + /* local setup */ + lt->unit = sc->sc_unit; + lt->channel = HSCX_CH_A; + lt->bch_config = avm_pnp_bchannel_setup; + lt->bch_tx_start = avm_pnp_bchannel_start; + lt->bch_stat = avm_pnp_bchannel_stat; + lt->tx_queue = &chan->tx_queue; + + /* used by non-HDLC data transfers, i.e. telephony drivers */ + lt->rx_queue = &chan->rx_queue; + + /* used by HDLC data transfers, i.e. ipr and isp drivers */ + lt->rx_mbuf = &chan->in_mbuf; + + chan = &sc->sc_chan[HSCX_CH_B]; + lt = &chan->isdn_linktab; + + lt->unit = sc->sc_unit; + lt->channel = HSCX_CH_B; + lt->bch_config = avm_pnp_bchannel_setup; + lt->bch_tx_start = avm_pnp_bchannel_start; + lt->bch_stat = avm_pnp_bchannel_stat; + lt->tx_queue = &chan->tx_queue; + + /* used by non-HDLC data transfers, i.e. telephony drivers */ + lt->rx_queue = &chan->rx_queue; + + /* used by HDLC data transfers, i.e. ipr and isp drivers */ + lt->rx_mbuf = &chan->in_mbuf; +} + +/* + * use this instead of isic_bchannel_stat in i4b_bchan.c because it's static + */ +static void +avm_pnp_bchannel_stat(int unit, int h_chan, bchan_statistics_t *bsp) +{ + struct isic_softc *sc = &isic_sc[unit]; + isic_Bchan_t *chan = &sc->sc_chan[h_chan]; + int s; + + s = SPLI4B(); + + bsp->outbytes = chan->txcount; + bsp->inbytes = chan->rxcount; + + chan->txcount = 0; + chan->rxcount = 0; + + splx(s); +} + +/*---------------------------------------------------------------------------* + * 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; + /* 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); + +#ifdef NOTDEF + printf("i:mh=%p, mc=%p, mcp=%p, mcl=%d l=%d nl=%d # ", + chan->out_mbuf_head, + chan->out_mbuf_cur, + chan->out_mbuf_cur_ptr, + chan->out_mbuf_cur_len, + len, + nextlen); +#endif + + /* collect the data in the scratch buffer */ + for (i = 0; i < nextlen; i++) + scrbuf[i + len] = chan->out_mbuf_cur_ptr[i]; + + len += nextlen; + chan->txcount += nextlen; + + chan->out_mbuf_cur_ptr += nextlen; + chan->out_mbuf_cur_len -= nextlen; + + if(chan->out_mbuf_cur_len == 0) + { + if((chan->out_mbuf_cur = chan->out_mbuf_cur->m_next) != NULL) + { + chan->out_mbuf_cur_ptr = chan->out_mbuf_cur->m_data; + chan->out_mbuf_cur_len = chan->out_mbuf_cur->m_len; + + if(sc->sc_trace & TRACE_B_TX) + { + i4b_trace_hdr_t hdr; + hdr.unit = sc->sc_unit; + hdr.type = (chan->channel == HSCX_CH_A ? TRC_CH_B1 : TRC_CH_B2); + hdr.dir = FROM_TE; + hdr.count = ++sc->sc_trace_bcount; + MICROTIME(hdr.time); + MPH_Trace_Ind(&hdr, chan->out_mbuf_cur->m_len, chan->out_mbuf_cur->m_data); + } + } + else + { + i4b_Bfreembuf(chan->out_mbuf_head); + chan->out_mbuf_head = NULL; + } + } + } + /* write what we have from the scratch buf to the HSCX fifo */ + if (len != 0) + HSCX_WRFIFO(chan->channel, scrbuf, len); + + return(0); +} + +void +avm_pnp_intr(int unit) +{ + struct isic_softc *sc; + u_char stat; + register u_char isac_irq_stat; + int was_isac = 0; + + sc = &isic_sc[unit]; + + for(;;) { + stat = inb(sc->sc_port + STAT0_OFFSET); + + DBGL1(L1_H_IRQ, "avm_pnp_intr", ("stat %x\n", stat)); + + /* was there an interrupt from this card ? */ + if ((stat & ASL_IRQ_Pending) == ASL_IRQ_Pending) + break; /* no */ + + /* interrupts are low active */ + if (!(stat & ASL_IRQ_TIMER)) + DBGL1(L1_H_IRQ, "avm_pnp_intr", ("timer interrupt ???\n")); + + if (!(stat & ASL_IRQ_ISAC)) + { + DBGL1(L1_H_IRQ, "avm_pnp_intr", ("ISAC\n")); + isac_irq_stat = ISAC_READ(I_ISTA); + isic_isac_irq(sc, isac_irq_stat); + was_isac = 1; + } + + if (!(stat & ASL_IRQ_HSCX)) + { + DBGL1(L1_H_IRQ, "avm_pnp_intr", ("HSCX\n")); + avm_pnp_hscx_int_handler(sc); + } + } + if (was_isac) { + ISAC_WRITE(0x20, 0xFF); + ISAC_WRITE(0x20, 0x0); + } +} +#endif /* NISIC > 0 && defined(AVM_PNP) */ +#endif /* FreeBSD */ diff --git a/sys/i4b/layer1/i4b_dynalink.c b/sys/i4b/layer1/i4b_dynalink.c index e3166828f8b9..1f75302db431 100644 --- a/sys/i4b/layer1/i4b_dynalink.c +++ b/sys/i4b/layer1/i4b_dynalink.c @@ -33,7 +33,7 @@ * isdn4bsd layer1 driver for Dynalink IS64PH isdn TA * ================================================== * - * $Id: i4b_dynalink.c,v 1.9 1999/02/14 09:44:58 hm Exp $ + * $Id: i4b_dynalink.c,v 1.10 1999/07/26 09:03:49 hm Exp $ * * last edit-date: [Sun Feb 14 10:26:21 1999] * @@ -108,6 +108,8 @@ #include <machine/clock.h> #include <i386/isa/isa_device.h> #include <i386/isa/pnp.h> +#elif defined(__bsdi__) +#include <i386/isa/pnp.h> #else #include <machine/bus.h> #include <sys/device.h> @@ -129,15 +131,21 @@ #include <i4b/layer1/i4b_isac.h> #include <i4b/layer1/i4b_hscx.h> -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__bsdi__) static void dynalink_read_fifo(void *buf, const void *base, size_t len); static void dynalink_write_fifo(void *base, const void *buf, size_t len); static void dynalink_write_reg(u_char *base, u_int offset, u_int v); static u_char dynalink_read_reg(u_char *base, u_int offset); +#endif +#ifdef __FreeBSD__ extern struct isa_driver isicdriver; +#endif +#ifdef __bsdi__ +extern struct cfdriver isiccd; +#endif -#else +#if !defined(__FreeBSD__) && !defined(__bsdi__) static void dynalink_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size); static void dynalink_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size); static void dynalink_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data); @@ -158,13 +166,15 @@ void isic_attach_Dyn(struct isic_softc *sc); #define HSCXA 0x00 #define HSCXB 0x40 -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__bsdi__) /* base address juggling */ #define HSCXB_HACK 0x400 #define IOBASE(addr) (((int)addr)&0x3FC) #define IOADDR(addr) (((int)addr)&0x3FF) #define IS_HSCXB_HACK(addr) ((((int)addr)&HSCXB_HACK)?HSCXB:HSCXA) +#endif +#ifdef __FreeBSD__ /* ISIC probe and attach */ @@ -271,6 +281,136 @@ isic_attach_Dyn(struct isa_device *dev, unsigned int iobase2) return(1); } +#elif defined(__bsdi__) + +/* ISIC probe and attach +*/ + +static int +set_softc(struct isic_softc *sc, struct isa_attach_args *ia, int unit) +{ + if (unit >= NISIC) + return 0; + sc->sc_unit = unit; + switch(ffs(ia->ia_irq) - 1) + { + case 3: + case 4: + case 5: + case 9: + case 10: + case 11: + case 12: + case 15: + break; + + default: + printf("isic%d: Error, invalid IRQ [%d] specified for Dynalink IS64PH.\n", + unit, ffs(ia->ia_irq)-1); + return(0); + break; + } + sc->sc_irq = ia->ia_irq; + + /* check if memory addr specified */ + + if(ia->ia_maddr) + { + printf("isic%d: Error, mem addr 0x%lx specified for Dynalink IS64PH.\n", + unit, (u_long)ia->ia_maddr); + return (0); + } + + /* check if we got an iobase */ + if ( (ia->ia_iobase < 0x100) || + (ia->ia_iobase > 0x3f8) || + (ia->ia_iobase & 3) ) + { + printf("isic%d: Error, invalid iobase 0x%x specified for Dynalink!\n", unit, ia->ia_iobase); + return(0); + } + sc->sc_port = ia->ia_iobase; + + /* setup access routines */ + sc->clearirq = NULL; + sc->readreg = dynalink_read_reg; + sc->writereg = dynalink_write_reg; + sc->readfifo = dynalink_read_fifo; + sc->writefifo = dynalink_write_fifo; + + /* setup card type */ + sc->sc_cardtyp = CARD_TYPEP_DYNALINK; + + /* setup IOM bus type */ + sc->sc_bustyp = BUS_TYPE_IOM2; + + sc->sc_ipac = 0; + sc->sc_bfifolen = HSCX_FIFO_LEN; + + /* setup ISAC and HSCX base addr */ + ISAC_BASE = (caddr_t) sc->sc_port; + HSCX_A_BASE = (caddr_t) sc->sc_port + 1; + HSCX_B_BASE = (caddr_t) sc->sc_port + 1 + HSCXB_HACK; + return 1; +} + +int +isapnp_match_dynalink(struct device *parent, struct cfdata *cf, + struct isa_attach_args *ia) +{ + struct isic_softc dummysc, *sc = &dummysc; + pnp_resource_t res; + char *ids[] = {"ASU1688", NULL}; + bzero(&res, sizeof res); + res.res_irq[0].irq_level = ia->ia_irq; + res.res_port[0].prt_base = ia->ia_iobase; + res.res_port[0].prt_length = 4; + + if (!pnp_assigndev(ids, isiccd.cd_name, &res)) + return (0); + + ia->ia_irq = res.res_irq[0].irq_level; + ia->ia_iobase = res.res_port[0].prt_base; + ia->ia_iosize = res.res_port[0].prt_length; + + if (set_softc(sc, ia, cf->cf_unit) == 0) + return 0; + + /* Read HSCX A/B VSTR. Expected value is 0x05 (V2.1). */ + if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) || + ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) ) + { + printf("isic%d: HSCX VSTR test failed for Dynalink\n", + cf->cf_unit); + printf("isic%d: HSC0: VSTR: %#x\n", + cf->cf_unit, HSCX_READ(0, H_VSTR)); + printf("isic%d: HSC1: VSTR: %#x\n", + cf->cf_unit, HSCX_READ(1, H_VSTR)); + return (0); + } + + cf->cf_flags = FLAG_DYNALINK; + return (1); +} + +int +isic_attach_Dyn(struct device *parent, struct device *self, + struct isa_attach_args *ia) +{ + struct isic_softc *sc = (struct isic_softc *)self; + int unit = sc->sc_dev.dv_unit; + + /* Commit the probed attachment values */ + if (set_softc(sc, ia, unit) == 0) + panic("isic_attach_Dyn: set_softc"); + + outb((ia->ia_iobase)+ADDR, RESET); + DELAY(SEC_DELAY / 10); + outb((ia->ia_iobase)+ADDR, 0); + DELAY(SEC_DELAY / 10); + return(1); +} + #else void isic_attach_Dyn(struct isic_softc *sc) @@ -320,7 +460,7 @@ void isic_attach_Dyn(struct isic_softc *sc) REM: this is only true for the FreeBSD version of I4B! */ -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__bsdi__) static void dynalink_read_fifo(void *buf, const void *base, size_t len) { @@ -350,7 +490,7 @@ dynalink_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size) } #endif -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__bsdi__) static void dynalink_write_fifo(void *base, const void *buf, size_t len) { @@ -379,7 +519,7 @@ static void dynalink_write_fifo(struct isic_softc *sc, int what, const void *buf } #endif -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__bsdi__) static void dynalink_write_reg(u_char *base, u_int offset, u_int v) { @@ -408,7 +548,7 @@ static void dynalink_write_reg(struct isic_softc *sc, int what, bus_size_t offs, } #endif -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__bsdi__) static u_char dynalink_read_reg(u_char *base, u_int offset) { diff --git a/sys/i4b/layer1/i4b_ipac.h b/sys/i4b/layer1/i4b_ipac.h index d820271b0d3f..e58c4b8bde0b 100644 --- a/sys/i4b/layer1/i4b_ipac.h +++ b/sys/i4b/layer1/i4b_ipac.h @@ -27,9 +27,9 @@ * i4b_ipac.h - definitions for the Siemens IPAC PSB2115 chip * ========================================================== * - * $Id: i4b_ipac.h,v 1.5 1999/02/14 09:44:59 hm Exp $ + * $Id: i4b_ipac.h,v 1.6 1999/06/08 08:13:00 hm Exp $ * - * last edit-date: [Sun Feb 14 10:27:03 1999] + * last edit-date: [Tue Jun 8 09:53:26 1999] * *--------------------------------------------------------------------------- */ @@ -44,6 +44,10 @@ #define IPAC_ISAC_OFF 0x80 #define IPAC_IPAC_OFF 0xc0 +/* chip version */ + +#define IPAC_V11 0x01 /* IPAC Version 1.1 */ + /* * definitions of registers and bits for the IPAC ISDN chip. */ diff --git a/sys/i4b/layer1/i4b_isic.c b/sys/i4b/layer1/i4b_isic.c index f403fafa076a..a2361b986656 100644 --- a/sys/i4b/layer1/i4b_isic.c +++ b/sys/i4b/layer1/i4b_isic.c @@ -27,9 +27,9 @@ * i4b_isic.c - global isic stuff * ============================== * - * $Id: i4b_isic.c,v 1.47 1999/04/20 09:34:14 hm Exp $ + * $Id: i4b_isic.c,v 1.51 1999/07/26 09:03:49 hm Exp $ * - * last edit-date: [Sun Feb 14 10:27:20 1999] + * last edit-date: [Mon Jul 26 10:59:56 1999] * *---------------------------------------------------------------------------*/ @@ -97,6 +97,7 @@ struct cfdriver isiccd = sizeof(struct isic_softc) }; int isa_isicmatch(struct device *parent, struct cfdata *cf, struct isa_attach_args *); +int isapnp_isicmatch(struct device *parent, struct cfdata *cf, struct isa_attach_args *); int isa_isicattach(struct device *parent, struct device *self, struct isa_attach_args *ia); static int @@ -109,8 +110,7 @@ isicmatch(struct device *parent, struct cfdata *cf, void *aux) return 0; /* for now */ } if (ia->ia_bustype == BUS_PNP) { - /* return isapnp_isicmatch(parent, cf, ia); */ - return 0; /* for now */ + return isapnp_isicmatch(parent, cf, ia); } return isa_isicmatch(parent, cf, ia); } @@ -209,6 +209,9 @@ isicintr(void *arg) was_isac_irq = 1; } } + +#ifdef NOTDEF + #if !defined(amiga) && !defined(atari) /* XXX should be: #if INTS_ARE_SHARED */ #ifdef ELSA_QS1ISA if(sc->sc_cardtyp != CARD_TYPEP_ELSAQS1ISA) @@ -220,6 +223,8 @@ isicintr(void *arg) } #endif #endif /* !AMIGA && !ATARI */ + +#endif /* NOTDEF */ HSCX_WRITE(0, H_MASK, 0xff); ISAC_WRITE(I_MASK, 0xff); @@ -273,21 +278,27 @@ isicintr(void *arg) ipac_irq_stat & IPAC_ISTA_EXB); was_ipac_irq = 1; } - if(ipac_irq_stat & (IPAC_ISTA_ICD | IPAC_ISTA_EXD)) + if(ipac_irq_stat & IPAC_ISTA_ICD) { /* ISAC interrupt */ isic_isac_irq(sc, ISAC_READ(I_ISTA)); was_ipac_irq = 1; } + if(ipac_irq_stat & IPAC_ISTA_EXD) + { + /* force ISAC interrupt handling */ + isic_isac_irq(sc, ISAC_ISTA_EXI); + was_ipac_irq = 1; + } /* do as long as there are pending irqs in the chip */ if(!ipac_irq_stat) break; } - +#ifdef NOTDEF if(was_ipac_irq == 0) DBGL1(L1_ERROR, "isicintr", ("WARNING: unit %d, No IRQ from IPAC!\n", sc->sc_unit)); - +#endif IPAC_WRITE(IPAC_MASK, 0xff); DELAY(50); IPAC_WRITE(IPAC_MASK, 0xc0); diff --git a/sys/i4b/layer1/i4b_isic_isa.c b/sys/i4b/layer1/i4b_isic_isa.c index 41473552fcf1..ba927c40ddd6 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.20 1999/05/10 09:37:35 hm Exp $ + * $Id: i4b_isic_isa.c,v 1.24 1999/07/26 09:03:49 hm Exp $ * - * last edit-date: [Tue Apr 20 11:47:59 1999] + * last edit-date: [Mon Jul 26 10:59:51 1999] * *---------------------------------------------------------------------------*/ @@ -211,6 +211,18 @@ isicprobe(struct isa_device *dev) } #elif defined(__bsdi__) /*---------------------------------------------------------------------------* + * isic - pnp device driver probe routine + *---------------------------------------------------------------------------*/ +int +isapnp_isicmatch(struct device *parent, struct cfdata *cf, struct isa_attach_args *ia) +{ +#ifdef DYNALINK + if (isapnp_match_dynalink(parent, cf, ia)) + return 1; +#endif + return 0; +} +/*---------------------------------------------------------------------------* * isic - non-pnp device driver probe routine *---------------------------------------------------------------------------*/ int @@ -305,6 +317,7 @@ isic_realattach(struct isa_device *dev, unsigned int iobase2) *---------------------------------------------------------------------------*/ int isa_isicattach(struct device *parent, struct device *self, struct isa_attach_args *ia) + #else /* ! __FreeBSD__ */ int @@ -316,19 +329,26 @@ isicattach(int flags, struct isic_softc *sc) char *drvid; #ifdef __FreeBSD__ + struct isic_softc *sc = &isic_sc[dev->id_unit]; #define PARM dev #define PARM2 dev, iobase2 #define FLAGS dev->id_flags + #elif defined(__bsdi__) + struct isic_softc *sc = (struct isic_softc *)self; #define PARM parent, self, ia +#define PARM2 parent, self, ia #define FLAGS sc->sc_flags + #else + #define PARM sc #define PARM2 sc #define FLAGS flags -#endif + +#endif /* __FreeBSD__ */ static char *ISACversion[] = { "2085 Version A1/A2 or 2086/2186 Version 1.1", @@ -353,7 +373,7 @@ isicattach(int flags, struct isic_softc *sc) #ifdef __FreeBSD__ if(dev->id_unit != next_isic_unit) { - printf("isicattach: Error: new unit (%d) != next_isic_unit (%d)!\n", dev->id_unit, next_isic_unit); +/*XXX*/ printf("isicattach: Error: new unit (%d) != next_isic_unit (%d)!\n", dev->id_unit, next_isic_unit); return(0); } @@ -413,9 +433,16 @@ isicattach(int flags, struct isic_softc *sc) break; #endif +#ifdef amiga + case FLAG_BLMASTER: + ret = 1; /* full detection was done in caller */ + break; +#endif + /* ====================================================================== * Only P&P cards follow below!!! */ + #ifdef __FreeBSD__ /* we've already splitted all non-ISA stuff out of this ISA specific part for the other OS */ @@ -456,15 +483,26 @@ isicattach(int flags, struct isic_softc *sc) break; #endif -#endif /* __FreeBSD__ / P&P specific part */ +#ifdef AVM_PNP + case FLAG_AVM_PNP: + ret = isic_attach_avm_pnp(PARM2); + ret = 0; + break; +#endif -/* --- XXX - don't know how to handle this - should be removed!!!! ---- */ -#ifdef amiga - case FLAG_BLMASTER: - ret = 1; /* full detection was done in caller */ +#ifdef SIEMENS_ISURF2 + case FLAG_SIEMENS_ISURF2: + ret = isic_attach_siemens_isurf(PARM2); + break; +#endif + +#ifdef ASUSCOM_IPAC + case FLAG_ASUSCOM_IPAC: + ret = isic_attach_asi(PARM2); break; #endif -/* ------------------------------------------------------------------- */ + +#endif /* __FreeBSD__ / P&P specific part */ default: break; @@ -473,40 +511,78 @@ isicattach(int flags, struct isic_softc *sc) if(ret == 0) return(0); - sc->sc_isac_version = 0; - sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03; - - switch(sc->sc_isac_version) + if(sc->sc_ipac) { - case ISAC_VA: - case ISAC_VB1: - case ISAC_VB2: - case ISAC_VB3: - break; + ret = IPAC_READ(IPAC_ID); - default: - printf(ISIC_FMT "Error, ISAC version %d unknown!\n", - ISIC_PARM, sc->sc_isac_version); + if(ret != IPAC_V11) + { + printf("isic%d: Error, IPAC version %d unknown!\n", + sc->sc_unit, ret); return(0); - break; + } } + else + { - sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf; + sc->sc_isac_version = 0; + sc->sc_hscx_version = 0; - switch(sc->sc_hscx_version) + if(sc->sc_ipac) + { + ret = IPAC_READ(IPAC_ID); + + switch(ret) + { + case 0x01: + printf("isic%d: IPAC PSB2115 Version 1.1\n", sc->sc_unit); + break; + + default: + printf("isic%d: Error, IPAC version %d unknown!\n", + sc->sc_unit, ret); + return(0); + break; + } + } + else { - case HSCX_VA1: - case HSCX_VA2: - case HSCX_VA3: - case HSCX_V21: - break; - - default: - printf(ISIC_FMT "Error, HSCX version %d unknown!\n", - ISIC_PARM, sc->sc_hscx_version); - return(0); - break; - }; + sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03; + + switch(sc->sc_isac_version) + { + case ISAC_VA: + case ISAC_VB1: + case ISAC_VB2: + case ISAC_VB3: + break; + + default: + printf(ISIC_FMT "Error, ISAC version %d unknown!\n", + ISIC_PARM, sc->sc_isac_version); + return(0); + break; + } + + sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf; + + switch(sc->sc_hscx_version) + { + case HSCX_VA1: + case HSCX_VA2: + case HSCX_VA3: + case HSCX_V21: + break; + + default: + printf(ISIC_FMT "Error, HSCX version %d unknown!\n", + ISIC_PARM, sc->sc_hscx_version); + return(0); + break; + } + } + + } /* ISAC setup */ @@ -614,6 +690,14 @@ isicattach(int flags, struct isic_softc *sc) drvid = "ELSA PCC-16"; break; + case FLAG_ASUSCOM_IPAC: + drvid = "Asuscom ISDNlink 128K PnP"; + break; + + case FLAG_SIEMENS_ISURF2: + drvid = "Siemens I-Surf 2.0"; + break; + default: drvid = "ERROR, unknown flag used"; break; @@ -626,42 +710,52 @@ isicattach(int flags, struct isic_softc *sc) /* announce chip versions */ - if(sc->sc_isac_version >= ISAC_UNKN) + if(sc->sc_ipac) { - printf(ISIC_FMT "ISAC Version UNKNOWN (VN=0x%x)" TERMFMT, - ISIC_PARM, - sc->sc_isac_version); - sc->sc_isac_version = ISAC_UNKN; + printf(ISIC_FMT "IPAC PSB2115 Version 1.1\n", ISIC_PARM); } else { - printf(ISIC_FMT "ISAC %s (IOM-%c)" TERMFMT, - ISIC_PARM, - ISACversion[sc->sc_isac_version], - sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2'); - } - + if(sc->sc_isac_version >= ISAC_UNKN) + { + printf(ISIC_FMT "ISAC Version UNKNOWN (VN=0x%x)" TERMFMT, + ISIC_PARM, + sc->sc_isac_version); + sc->sc_isac_version = ISAC_UNKN; + } + else + { + printf(ISIC_FMT "ISAC %s (IOM-%c)" TERMFMT, + ISIC_PARM, + ISACversion[sc->sc_isac_version], + sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2'); + } + #ifdef __FreeBSD__ - printf("(Addr=0x%lx)\n", (u_long)ISAC_BASE); + printf("(Addr=0x%lx)\n", (u_long)ISAC_BASE); #endif - if(sc->sc_hscx_version >= HSCX_UNKN) - { - printf(ISIC_FMT "HSCX Version UNKNOWN (VN=0x%x)" TERMFMT, - ISIC_PARM, - sc->sc_hscx_version); - sc->sc_hscx_version = HSCX_UNKN; - } - else - { - printf(ISIC_FMT "HSCX %s" TERMFMT, - ISIC_PARM, - HSCXversion[sc->sc_hscx_version]); + if(sc->sc_hscx_version >= HSCX_UNKN) + { + printf(ISIC_FMT "HSCX Version UNKNOWN (VN=0x%x)" TERMFMT, + ISIC_PARM, + sc->sc_hscx_version); + sc->sc_hscx_version = HSCX_UNKN; + } + else + { + printf(ISIC_FMT "HSCX %s" TERMFMT, + ISIC_PARM, + HSCXversion[sc->sc_hscx_version]); + } + +#ifdef __FreeBSD__ + printf("(AddrA=0x%lx, AddrB=0x%lx)\n", (u_long)HSCX_A_BASE, (u_long)HSCX_B_BASE); + +#endif /* __FreeBSD__ */ } #ifdef __FreeBSD__ - printf("(AddrA=0x%lx, AddrB=0x%lx)\n", (u_long)HSCX_A_BASE, (u_long)HSCX_B_BASE); - next_isic_unit++; #if defined(__FreeBSD_version) && __FreeBSD_version >= 300003 diff --git a/sys/i4b/layer1/i4b_isic_pnp.c b/sys/i4b/layer1/i4b_isic_pnp.c index a9f056a3631c..0e534eb58ff6 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.17 1999/04/20 14:28:46 hm Exp $ + * $Id: i4b_isic_pnp.c,v 1.23 1999/07/05 14:00:04 hm Exp $ * - * last edit-date: [Tue Apr 20 16:12:27 1999] + * last edit-date: [Mon Jul 5 15:57:01 1999] * *---------------------------------------------------------------------------*/ @@ -76,23 +76,31 @@ extern void isicintr(int unit); #include <machine/i4b_ioctl.h> #include <i4b/layer1/i4b_l1.h> -#define VID_TEL163PNP 0x10212750 /* Teles 16.3 PnP */ -#define VID_CREATIXPP 0x0000980e /* Creatix S0/16 P+P */ -#define VID_DYNALINK 0x88167506 /* Dynalink */ -#define VID_SEDLBAUER 0x0100274c /* Sedlbauer WinSpeed */ -#define VID_NICCYGO 0x5001814c /* Neuhaus Niccy GO@ */ -#define VID_ELSAQS1P 0x33019315 /* ELSA Quickstep1000pro*/ +#define VID_TEL163PNP 0x10212750 /* Teles 16.3 PnP */ +#define VID_CREATIXPP 0x0000980e /* Creatix S0/16 P+P */ +#define VID_DYNALINK 0x88167506 /* Dynalink */ +#define VID_SEDLBAUER 0x0100274c /* Sedlbauer WinSpeed */ +#define VID_NICCYGO 0x5001814c /* Neuhaus Niccy GO@ */ +#define VID_ELSAQS1P 0x33019315 /* ELSA Quickstep1000pro*/ +#define VID_ITK0025 0x25008b26 /* ITK Ix1 Micro V3 */ +#define VID_AVMPNP 0x0009cd06 /* AVM Fritz! PnP */ +#define VID_SIESURF2 0x2000254d /* Siemens I-Surf 2.0 PnP*/ +#define VID_ASUSCOM_IPAC 0x90167506 /* Asuscom (with IPAC) */ static struct i4b_pnp_ids { u_long vend_id; char *id_str; } i4b_pnp_ids[] = { - { VID_TEL163PNP, "Teles 16.3 PnP" }, - { VID_CREATIXPP, "Creatix S0/16 P+P" }, - { VID_DYNALINK, "Dynalink IS64PH" }, - { VID_SEDLBAUER, "Sedlbauer WinSpeed" }, - { VID_NICCYGO, "Dr.Neuhaus Niccy Go@" }, - { VID_ELSAQS1P, "ELSA QuickStep 1000pro"}, + { VID_TEL163PNP, "Teles 16.3 PnP" }, + { VID_CREATIXPP, "Creatix S0/16 P+P" }, + { VID_DYNALINK, "Dynalink IS64PH" }, + { VID_SEDLBAUER, "Sedlbauer WinSpeed" }, + { VID_NICCYGO, "Dr.Neuhaus Niccy Go@" }, + { VID_ELSAQS1P, "ELSA QuickStep 1000pro" }, + { VID_ITK0025, "ITK ix1 Micro V3.0" }, + { VID_AVMPNP, "AVM Fritz!Card PnP" }, + { VID_SIESURF2, "Siemens I-Surf 2.0 PnP" }, + { VID_ASUSCOM_IPAC, "Asuscom ISDNLink 128 PnP" }, { 0 } }; @@ -156,7 +164,9 @@ static void i4b_pnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev) { struct pnp_cinfo spci; +#if !((defined(__FreeBSD_version) && __FreeBSD_version >= 400004)) struct isa_device *isa_devp; +#endif if(dev->id_unit != next_isic_unit) { @@ -211,6 +221,18 @@ i4b_pnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev) case VID_ELSAQS1P: dev->id_flags = FLAG_ELSA_QS1P_ISA; break; + case VID_ITK0025: + dev->id_flags = FLAG_ITK_IX1; + break; + case VID_AVMPNP: + dev->id_flags = FLAG_AVM_PNP; + break; + case VID_SIESURF2: + dev->id_flags = FLAG_SIEMENS_ISURF2; + break; + case VID_ASUSCOM_IPAC: + dev->id_flags = FLAG_ASUSCOM_IPAC; + break; } write_pnp_parms(&spci, 0); @@ -287,6 +309,31 @@ isic_pnpprobe(struct isa_device *dev, unsigned int iobase2) ret = isic_probe_Eqs1pi(dev, iobase2); break; #endif + +#ifdef ITKIX1 + case FLAG_ITK_IX1: + ret = isic_probe_itkix1(dev); + break; +#endif + +#ifdef AVM_PNP + case FLAG_AVM_PNP: + ret = isic_probe_avm_pnp(dev, iobase2); + break; +#endif + +#ifdef SIEMENS_ISURF2 + case FLAG_SIEMENS_ISURF2: + ret = isic_probe_siemens_isurf(dev, iobase2); + break; +#endif + +#ifdef ASUSCOM_IPAC + case FLAG_ASUSCOM_IPAC: + ret = isic_probe_asi(dev, iobase2); + break; +#endif + default: break; } diff --git a/sys/i4b/layer1/i4b_l1.h b/sys/i4b/layer1/i4b_l1.h index 6b455fa7989f..f013bbbea3d3 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.61 1999/04/21 07:50:31 hm Exp $ + * $Id: i4b_l1.h,v 1.64 1999/07/05 13:46:46 hm Exp $ * - * last edit-date: [Tue Mar 16 15:50:24 1999] + * last edit-date: [Mon Jul 5 15:32:02 1999] * *---------------------------------------------------------------------------*/ @@ -48,42 +48,36 @@ /*--------------------------------------------------------------------------- * kernel config file flags definition *---------------------------------------------------------------------------*/ - /* XXX: we do need these only for real ISA (not even ISAPNP cards), and only - * because we are not confident enough in the general ISA probe routine (as - * practiced by the NetBSD variant). *And* it is completely redundant to the - * various options enabling only a few card's support routines to be compiled - * in. Probably the current truth is: this is usefull for anybody with more - * than one supported real ISA card. It is not usefull in generic configs, - * nor in typical one-controller-only configurations. - * Further - it is identical to the CARD_TYPEP_xxx definitions in - * ../machine/i4b_ioctl.h. - */ #define FLAG_TELES_S0_8 1 #define FLAG_TELES_S0_16 2 #define FLAG_TELES_S0_163 3 #define FLAG_AVM_A1 4 -#define FLAG_TELES_S0_163_PnP 5 /* XXX - not needed, remove! */ -#define FLAG_CREATIX_S0_PnP 6 /* XXX - not needed, remove! */ +#define FLAG_TELES_S0_163_PnP 5 +#define FLAG_CREATIX_S0_PnP 6 #define FLAG_USR_ISDN_TA_INT 7 -#define FLAG_DRN_NGO 8 /* XXX - not needed, remove! */ -#define FLAG_SWS 9 /* XXX - not needed, remove! */ -#define FLAG_AVM_A1_PCMCIA 10 /* XXX - not needed, remove! */ -#define FLAG_DYNALINK 11 /* XXX - not needed, remove! */ +#define FLAG_DRN_NGO 8 +#define FLAG_SWS 9 +#define FLAG_AVM_A1_PCMCIA 10 +#define FLAG_DYNALINK 11 #define FLAG_BLMASTER 12 -#define FLAG_ELSA_QS1P_ISA 13 /* XXX - not needed, remove! */ -#define FLAG_ELSA_QS1P_PCI 14 /* XXX - not needed, remove! */ +#define FLAG_ELSA_QS1P_ISA 13 +#define FLAG_ELSA_QS1P_PCI 14 #define FLAG_SIEMENS_ITALK 15 -#define FLAG_ELSA_MLIMC 16 /* XXX - not needed, remove! */ -#define FLAG_ELSA_MLMCALL 17 /* XXX - not needed, remove! */ +#define FLAG_ELSA_MLIMC 16 +#define FLAG_ELSA_MLMCALL 17 #define FLAG_ITK_IX1 18 -#define FLAG_ELSA_PCC16 19 +#define FLAG_AVMA1PCI 19 +#define FLAG_ELSA_PCC16 20 +#define FLAG_AVM_PNP 21 +#define FLAG_SIEMENS_ISURF2 22 +#define FLAG_ASUSCOM_IPAC 23 -#define SEC_DELAY 1000000 /* one second DELAY for DELAY*/ +#define SEC_DELAY 1000000 /* one second DELAY for DELAY*/ -#define MAX_DFRAME_LEN 264 /* max length of a D frame */ +#define MAX_DFRAME_LEN 264 /* max length of a D frame */ #ifndef __bsdi__ -#define min(a,b) ((a)<(b)?(a):(b)) +#define min(a,b) ((a)<(b)?(a):(b)) #endif #if !defined(__FreeBSD__) && !defined(__bsdi__) @@ -190,7 +184,7 @@ struct isic_softc #endif int sc_unit; /* unit number */ - int sc_irq; /* interrupt vector */ + int sc_irq; /* interrupt vector */ #ifdef __FreeBSD__ int sc_port; /* port base address */ @@ -205,6 +199,7 @@ struct isic_softc u_int sc_maddr; /* "memory address" for card config register */ int sc_num_mappings; /* number of io mappings provided */ struct isic_io_map *sc_maps; + #define MALLOC_MAPS(sc) \ (sc)->sc_maps = (struct isic_io_map*)malloc(sizeof((sc)->sc_maps[0])*(sc)->sc_num_mappings, M_DEVBUF, 0) #endif @@ -266,6 +261,7 @@ struct isic_softc #endif int sc_I430T4; /* Timer T4 running */ + #if defined(__FreeBSD__) && __FreeBSD__ >=3 struct callout_handle sc_T4_callout; #endif @@ -396,7 +392,10 @@ extern int isic_attach_itkix1 ( struct isa_device *dev ); extern int isic_attach_drnngo ( struct isa_device *dev, unsigned int iobase2); 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_avm_pnp(struct isa_device *dev, unsigned int iobase2); +extern int isic_attach_siemens_isurf(struct isa_device *dev, unsigned int iobase2); extern int isic_attach_Eqs1pp(int unit, unsigned int iobase1, unsigned int iobase2); +extern int isic_attach_asi(struct isa_device *dev, 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 ); @@ -412,6 +411,8 @@ extern void isic_next_state ( struct isic_softc *sc, int event ); extern char *isic_printstate ( struct isic_softc *sc ); extern int isic_probe_avma1 ( struct isa_device *dev ); extern int isic_probe_avma1_pcmcia ( struct isa_device *dev ); +extern int isic_probe_avm_pnp ( struct isa_device *dev, unsigned int iobase2); +extern int isic_probe_siemens_isurf ( struct isa_device *dev, unsigned int iobase2); extern int isic_probe_Cs0P ( struct isa_device *dev, unsigned int iobase2); extern int isic_probe_Dyn ( struct isa_device *dev, unsigned int iobase2); extern int isic_probe_s016 ( struct isa_device *dev ); @@ -423,6 +424,7 @@ extern int isic_probe_itkix1 ( struct isa_device *dev ); extern int isic_probe_drnngo ( struct isa_device *dev, unsigned int iobase2); extern int isic_probe_sws ( struct isa_device *dev ); extern int isic_probe_Eqs1pi(struct isa_device *dev, unsigned int iobase2); +extern int isic_probe_asi(struct isa_device *dev, unsigned int iobase2); #elif defined(__bsdi__) diff --git a/sys/i4b/layer1/i4b_siemens_isurf.c b/sys/i4b/layer1/i4b_siemens_isurf.c new file mode 100644 index 000000000000..09e6f471d46c --- /dev/null +++ b/sys/i4b/layer1/i4b_siemens_isurf.c @@ -0,0 +1,317 @@ +/* + * Copyright (c) 1999 Udo Schweigert. 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. + * + *--------------------------------------------------------------------------- + * Based on ELSA Quickstep 1000pro PCI driver (i4b_elsa_qs1p.c) + *--------------------------------------------------------------------------- + * In case of trouble please contact Udo Schweigert <ust@cert.siemens.de> + *--------------------------------------------------------------------------- + * + * Siemens I-Surf 2.0 PnP specific routines for isic driver + * -------------------------------------------------------- + * + * $Id: i4b_siemens_isurf.c,v 1.2 1999/07/05 13:22:12 hm Exp $ + * + * last edit-date: [Mon 14 Jun 16:46:27 CEST 1999] + * + *---------------------------------------------------------------------------*/ + +#if defined(__FreeBSD__) +#include "isic.h" +#include "opt_i4b.h" + +#if NISIC > 0 && defined(SIEMENS_ISURF2) + +#include <sys/param.h> +#if defined(__FreeBSD__) && __FreeBSD__ >= 3 +#include <sys/ioccom.h> +#else +#include <sys/ioctl.h> +#endif +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/mbuf.h> + +#include <machine/clock.h> +#include <i386/isa/isa_device.h> + +#include <sys/socket.h> +#include <net/if.h> + +#include <machine/i4b_debug.h> +#include <machine/i4b_ioctl.h> + +#include <i4b/include/i4b_global.h> +#include <i4b/include/i4b_l1l2.h> +#include <i4b/include/i4b_mbuf.h> + +#include <i4b/layer1/i4b_l1.h> +#include <i4b/layer1/i4b_ipac.h> +#include <i4b/layer1/i4b_isac.h> +#include <i4b/layer1/i4b_hscx.h> + +/* masks for register encoded in base addr */ + +#define SIE_ISURF_BASE_MASK 0x0ffff +#define SIE_ISURF_OFF_MASK 0xf0000 + +/* register id's to be encoded in base addr */ + +#define SIE_ISURF_IDISAC 0x00000 +#define SIE_ISURF_IDHSCXA 0x10000 +#define SIE_ISURF_IDHSCXB 0x20000 +#define SIE_ISURF_IDIPAC 0x40000 + +/* offsets from base address */ + +#define SIE_ISURF_OFF_ALE 0x00 +#define SIE_ISURF_OFF_RW 0x01 + +/*---------------------------------------------------------------------------* + * Siemens I-Surf 2.0 PnP ISAC get fifo routine + *---------------------------------------------------------------------------*/ + +static void +siemens_isurf_read_fifo(void *buf, const void *base, size_t len) +{ + if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXB) + { + outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_HSCXB_OFF); + insb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (u_char *)buf, (u_int)len); + } + else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXA) + { + outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_HSCXA_OFF); + insb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (u_char *)buf, (u_int)len); + } + else /* if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDISAC) */ + { + outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_ISAC_OFF); + insb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (u_char *)buf, (u_int)len); + } +} + +/*---------------------------------------------------------------------------* + * Siemens I-Surf 2.0 PnP ISAC put fifo routine + *---------------------------------------------------------------------------*/ + +static void +siemens_isurf_write_fifo(void *base, const void *buf, size_t len) +{ + if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXB) + { + outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_HSCXB_OFF); + outsb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (const u_char *)buf, (u_int)len); + } + else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXA) + { + outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_HSCXA_OFF); + outsb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (const u_char *)buf, (u_int)len); + } + else /* if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDISAC) */ + { + outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_ISAC_OFF); + outsb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (const u_char *)buf, (u_int)len); + } +} + +/*---------------------------------------------------------------------------* + * Siemens I-Surf 2.0 PnP ISAC put register routine + *---------------------------------------------------------------------------*/ + +static void +siemens_isurf_write_reg(u_char *base, u_int offset, u_int v) +{ + if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXB) + { + outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_HSCXB_OFF)); + outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW, (u_char)v); + } + else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXA) + { + outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_HSCXA_OFF)); + outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW, (u_char)v); + } + else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDISAC) + { + outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_ISAC_OFF)); + outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW, (u_char)v); + } + else /* IPAC */ + { + outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_IPAC_OFF)); + outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW, (u_char)v); + } +} + +/*---------------------------------------------------------------------------* + * Siemens I-Surf 2.0 PnP ISAC get register routine + *---------------------------------------------------------------------------*/ + +static u_char +siemens_isurf_read_reg(u_char *base, u_int offset) +{ + if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXB) + { + outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_HSCXB_OFF)); + return(inb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW)); + } + else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXA) + { + outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_HSCXA_OFF)); + return(inb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW)); + } + else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDISAC) + { + outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_ISAC_OFF)); + return(inb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW)); + } + else /* IPAC */ + { + outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_IPAC_OFF)); + return(inb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW)); + } +} + +/*---------------------------------------------------------------------------* + * isic_probe_siemens_isurf - probe for Siemens I-Surf 2.0 PnP + *---------------------------------------------------------------------------*/ + +int +isic_probe_siemens_isurf(struct isa_device *dev, unsigned int iobase2) +{ + struct isic_softc *sc = &isic_sc[dev->id_unit]; + + /* check max unit range */ + + if(dev->id_unit >= ISIC_MAXUNIT) + { + printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Siemens I-Surf 2.0 PnP\n", + dev->id_unit, dev->id_unit); + return(0); + } + sc->sc_unit = dev->id_unit; + + /* check IRQ validity */ + + switch(ffs(dev->id_irq) - 1) + { + case 3: + case 4: + case 5: + case 7: + case 10: + case 11: + case 12: + case 15: + break; + + default: + printf("isic%d: Error, invalid IRQ [%d] specified for Siemens I-Surf 2.0 PnP!\n", + dev->id_unit, ffs(dev->id_irq)-1); + return(0); + break; + } + sc->sc_irq = dev->id_irq; + + /* check if memory addr specified */ + + if(dev->id_maddr) + { + printf("isic%d: Error, mem addr 0x%lx specified for Siemens I-Surf 2.0 PnP!\n", + dev->id_unit, (u_long)dev->id_maddr); + return(0); + } + dev->id_msize = 0; + + /* check if we got an iobase */ + + if(!((dev->id_iobase >= 0x100) && (dev->id_iobase <= 0xff0))) + { + printf("isic%d: Error, invalid iobase 0x%x specified for Siemens I-Surf 2.0 PnP!\n", + dev->id_unit, dev->id_iobase); + return(0); + } + sc->sc_port = dev->id_iobase; + + + /* setup access routines */ + + sc->clearirq = NULL; + sc->readreg = siemens_isurf_read_reg; + sc->writereg = siemens_isurf_write_reg; + + sc->readfifo = siemens_isurf_read_fifo; + sc->writefifo = siemens_isurf_write_fifo; + + /* setup card type */ + + sc->sc_cardtyp = CARD_TYPEP_SIE_ISURF2; + + /* setup IOM bus type */ + + sc->sc_bustyp = BUS_TYPE_IOM2; + + /* setup chip type = IPAC ! */ + + sc->sc_ipac = 1; + sc->sc_bfifolen = IPAC_BFIFO_LEN; + + + return (1); +} + +/*---------------------------------------------------------------------------* + * isic_attach_siemens_isurf - attach for Siemens I-Surf 2.0 PnP + *---------------------------------------------------------------------------*/ +int +isic_attach_siemens_isurf(struct isa_device *dev, unsigned int iobase2) +{ + struct isic_softc *sc = &isic_sc[dev->id_unit]; + + /* setup ISAC and HSCX base addr */ + + ISAC_BASE = (caddr_t) ((u_int)sc->sc_port | SIE_ISURF_IDISAC); + HSCX_A_BASE = (caddr_t) ((u_int)sc->sc_port | SIE_ISURF_IDHSCXA); + HSCX_B_BASE = (caddr_t) ((u_int)sc->sc_port | SIE_ISURF_IDHSCXB); + IPAC_BASE = (caddr_t) ((u_int)sc->sc_port | SIE_ISURF_IDIPAC); + + /* enable hscx/isac irq's */ + IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0)); + + IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */ + IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */ + (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2)); + IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */ + + return(1); +} +#endif /* NISIC > 0 && defined(SIEMENS_ISURF2) */ +#endif /* FreeBSD */ diff --git a/sys/i4b/layer1/i4b_tel_s0163.c b/sys/i4b/layer1/i4b_tel_s0163.c index efe9f34d5a3c..4b6f1b532caa 100644 --- a/sys/i4b/layer1/i4b_tel_s0163.c +++ b/sys/i4b/layer1/i4b_tel_s0163.c @@ -37,9 +37,9 @@ * isic - I4B Siemens ISDN Chipset Driver for Teles S0/16.3 * ======================================================== * - * $Id: i4b_tel_s0163.c,v 1.18 1999/02/14 19:51:02 hm Exp $ + * $Id: i4b_tel_s0163.c,v 1.19 1999/07/26 09:03:25 hm Exp $ * - * last edit-date: [Sun Feb 14 10:28:45 1999] + * last edit-date: [Mon Jul 26 10:59:38 1999] * * -hm clean up * -hm more cleanup @@ -212,7 +212,7 @@ isic_probe_s0163(struct isa_device *dev) if(dev->id_unit >= ISIC_MAXUNIT) { - printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles S0/16.3!", + printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles S0/16.3!\n", dev->id_unit, dev->id_unit); return(0); } @@ -232,7 +232,7 @@ isic_probe_s0163(struct isa_device *dev) if(dev->id_maddr) { - printf("isic%d: Error, mem addr 0x%lx specified for Teles S0/16.3!", + printf("isic%d: Error, mem addr 0x%lx specified for Teles S0/16.3!\n", dev->id_unit, (u_long)dev->id_maddr); return(0); } @@ -249,7 +249,7 @@ isic_probe_s0163(struct isa_device *dev) break; default: - printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!", + printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!\n", dev->id_unit, dev->id_iobase); return(0); break; @@ -258,21 +258,21 @@ isic_probe_s0163(struct isa_device *dev) if(((byte = inb(sc->sc_port)) != 0x51) && (byte != 0x10)) { - printf("isic%d: Error, signature 1 0x%x != 0x51 or 0x10 for Teles S0/16.3!", + printf("isic%d: Error, signature 1 0x%x != 0x51 or 0x10 for Teles S0/16.3!\n", dev->id_unit, byte); return(0); } if((byte = inb(sc->sc_port + 1)) != 0x93) { - printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16.3!", + printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16.3!\n", dev->id_unit, byte); return(0); } if((byte = inb(sc->sc_port + 2)) != 0x1c) { - printf("isic%d: Error, signature 3 0x%x != 0x1c for Teles S0/16.3!", + printf("isic%d: Error, signature 3 0x%x != 0x1c for Teles S0/16.3!\n", dev->id_unit, byte); return(0); } @@ -359,7 +359,7 @@ set_softc(struct isic_softc *sc, struct isa_attach_args *ia, int unit) break; default: - printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!", + printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!\n", unit, ia->ia_iobase); return(0); break; @@ -429,7 +429,7 @@ isic_probe_s0163(struct device *dev, struct cfdata *cf, if(ia->ia_maddr) { - printf("isic%d: Error, mem addr 0x%lx specified for Teles S0/16.3!", + printf("isic%d: Error, mem addr 0x%lx specified for Teles S0/16.3!\n", cf->cf_unit, (u_long)ia->ia_maddr); return 0; } @@ -441,21 +441,21 @@ isic_probe_s0163(struct device *dev, struct cfdata *cf, if((byte = inb(sc->sc_port)) != 0x51) { - printf("isic%d: Error, signature 1 0x%x != 0x51 for Teles S0/16.3!", + printf("isic%d: Error, signature 1 0x%x != 0x51 for Teles S0/16.3!\n", cf->cf_unit, byte); return(0); } if((byte = inb(sc->sc_port + 1)) != 0x93) { - printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16.3!", + printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16.3!\n", cf->cf_unit, byte); return(0); } if((byte = inb(sc->sc_port + 2)) != 0x1c) { - printf("isic%d: Error, signature 3 0x%x != 0x1c for Teles S0/16.3!", + printf("isic%d: Error, signature 3 0x%x != 0x1c for Teles S0/16.3!\n", cf->cf_unit, byte); return(0); } diff --git a/sys/i4b/layer1/isa_isic.c b/sys/i4b/layer1/isa_isic.c index 7165e2425b88..bd6b8c53ba86 100644 --- a/sys/i4b/layer1/isa_isic.c +++ b/sys/i4b/layer1/isa_isic.c @@ -33,9 +33,9 @@ * isa_isic.c - ISA bus frontend for i4b_isic driver * -------------------------------------------------- * - * $Id: isa_isic.c,v 1.21 1999/02/23 14:51:18 hm Exp $ + * $Id: isa_isic.c,v 1.23 1999/07/19 14:40:47 hm Exp $ * - * last edit-date: [Sun Feb 14 10:29:11 1999] + * last edit-date: [Mon Jul 19 16:39:02 1999] * * -mh original implementation * -hm NetBSD patches from Martin @@ -115,6 +115,10 @@ isa_isic_probe(parent, cf, aux) struct isic_attach_args args; int ret = 0; +#if 0 + printf("isic%d: enter isa_isic_probe\n", cf->cf_unit); +#endif + /* check irq */ if (ia->ia_irq == IRQUNK) { printf("isic%d: config error: no IRQ specified\n", cf->cf_unit); @@ -314,6 +318,10 @@ done: /* unmap resources */ args_unmap(&args.ia_num_mappings, &args.ia_maps[0]); +#if 0 + printf("isic%d: exit isa_isic_probe, return = %d\n", cf->cf_unit, ret); +#endif + return ret; } diff --git a/sys/i4b/layer2/i4b_iframe.c b/sys/i4b/layer2/i4b_iframe.c index 3a37d045b71e..3b3686cf4a4c 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.19 1999/04/21 07:36:32 hm Exp $ + * $Id: i4b_iframe.c,v 1.20 1999/05/28 15:03:32 hm Exp $ * - * last edit-date: [Wed Apr 21 09:24:34 1999] + * last edit-date: [Fri May 28 15:52:41 1999] * *---------------------------------------------------------------------------*/ @@ -100,6 +100,8 @@ i4b_rxd_i_frame(int unit, struct mbuf *m) } CRIT_BEG; + + l2sc->stat.rx_i++; /* update frame count */ nr = GETINR(*(ptr + OFF_INR)); ns = GETINS(*(ptr + OFF_INS)); @@ -261,6 +263,8 @@ i4b_i_frame_queued_up(l2_softc_t *l2sc) *(ptr + OFF_INS) = (l2sc->vs << 1) & 0xfe; /* bit 0 = 0 */ *(ptr + OFF_INR) = (l2sc->vr << 1) & 0xfe; /* P bit = 0 */ + l2sc->stat.tx_i++; /* update frame counter */ + PH_Data_Req(l2sc->unit, m, MBUF_DONTFREE); /* free'd when ack'd ! */ l2sc->iframe_sent = 1; /* in case we ack an I frame with another I frame */ diff --git a/sys/i4b/layer2/i4b_l2.c b/sys/i4b/layer2/i4b_l2.c index 80072bb1b192..f282dd45c5e2 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.26 1999/04/15 09:53:55 hm Exp $ + * $Id: i4b_l2.c,v 1.27 1999/05/28 15:03:32 hm Exp $ * - * last edit-date: [Thu Apr 15 11:32:11 1999] + * last edit-date: [Fri May 28 16:15:39 1999] * *---------------------------------------------------------------------------*/ @@ -281,6 +281,7 @@ i4b_mph_status_ind(int unit, int status, int parm) l2sc->unit = unit; l2sc->i_queue.ifq_maxlen = IQUEUE_MAXLEN; l2sc->ua_frame = NULL; + bzero(&l2sc->stat, sizeof(lapdstat_t)); i4b_l2_unit_init(unit); #if defined(__FreeBSD_version) && __FreeBSD_version >= 300001 @@ -351,6 +352,7 @@ int i4b_mdl_command_req(int unit, int command, int parm) int i4b_ph_data_ind(int unit, struct mbuf *m) { + l2_softc_t *l2sc = &l2_softc[unit]; #ifdef NOTDEF DBGL1(L1_PRIM, "PH-DATA-IND", ("unit %d\n", unit)); #endif @@ -360,6 +362,7 @@ i4b_ph_data_ind(int unit, struct mbuf *m) { if(m->m_len < 4) /* 6 oct - 2 chksum oct */ { + l2sc->stat.err_rx_len++; DBGL2(L2_ERROR, "i4b_ph_data_ind", ("ERROR, I-frame < 6 octetts!\n")); i4b_Dfreembuf(m); return(0); @@ -370,6 +373,7 @@ i4b_ph_data_ind(int unit, struct mbuf *m) { if(m->m_len < 4) /* 6 oct - 2 chksum oct */ { + l2sc->stat.err_rx_len++; DBGL2(L2_ERROR, "i4b_ph_data_ind", ("ERROR, S-frame < 6 octetts!\n")); i4b_Dfreembuf(m); return(0); @@ -380,6 +384,7 @@ i4b_ph_data_ind(int unit, struct mbuf *m) { if(m->m_len < 3) /* 5 oct - 2 chksum oct */ { + l2sc->stat.err_rx_len++; DBGL2(L2_ERROR, "i4b_ph_data_ind", ("ERROR, U-frame < 5 octetts!\n")); i4b_Dfreembuf(m); return(0); @@ -388,6 +393,7 @@ i4b_ph_data_ind(int unit, struct mbuf *m) } else { + l2sc->stat.err_rx_badf++; DBGL2(L2_ERROR, "i4b_ph_data_ind", ("ERROR, bad frame rx'd - ")); i4b_print_frame(m->m_len, m->m_data); i4b_Dfreembuf(m); @@ -396,4 +402,3 @@ i4b_ph_data_ind(int unit, struct mbuf *m) } #endif /* NI4BQ921 > 0 */ - diff --git a/sys/i4b/layer2/i4b_l2.h b/sys/i4b/layer2/i4b_l2.h index c829a07dc832..af0809f0c657 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.17 1999/04/22 11:51:45 hm Exp $ + * $Id: i4b_l2.h,v 1.18 1999/05/28 15:03:32 hm Exp $ * - * last edit-date: [Thu Apr 22 13:50:55 1999] + * last edit-date: [Fri May 28 15:51:17 1999] * *---------------------------------------------------------------------------*/ @@ -103,6 +103,11 @@ typedef struct { int (*postfsmfunc)(int);/* function to be called at fsm exit */ int postfsmarg; /* argument for above function */ + + /* statistics */ + + lapdstat_t stat; /* lapd protocol statistics */ + } l2_softc_t; extern l2_softc_t l2_softc[]; diff --git a/sys/i4b/layer2/i4b_sframe.c b/sys/i4b/layer2/i4b_sframe.c index 220be26bc4c7..59afdf69dfb1 100644 --- a/sys/i4b/layer2/i4b_sframe.c +++ b/sys/i4b/layer2/i4b_sframe.c @@ -27,9 +27,9 @@ * i4b_sframe.c - s frame handling routines * ---------------------------------------- * - * $Id: i4b_sframe.c,v 1.9 1999/02/14 09:45:00 hm Exp $ + * $Id: i4b_sframe.c,v 1.10 1999/05/28 15:03:32 hm Exp $ * - * last edit-date: [Sun Feb 14 10:32:06 1999] + * last edit-date: [Fri May 28 16:14:04 1999] * *---------------------------------------------------------------------------*/ @@ -93,21 +93,25 @@ i4b_rxd_s_frame(int unit, struct mbuf *m) switch(*(ptr + OFF_SRCR)) { case RR: + l2sc->stat.rx_rr++; /* update statistics */ DBGL2(L2_S_MSG, "i4b_rxd_s_frame", ("rx'd RR, N(R) = %d\n", l2sc->rxd_NR)); i4b_next_l2state(l2sc, EV_RXRR); break; case RNR: + l2sc->stat.rx_rnr++; /* update statistics */ DBGL2(L2_S_MSG, "i4b_rxd_s_frame", ("rx'd RNR, N(R) = %d\n", l2sc->rxd_NR)); i4b_next_l2state(l2sc, EV_RXRNR); break; case REJ: + l2sc->stat.rx_rej++; /* update statistics */ DBGL2(L2_S_MSG, "i4b_rxd_s_frame", ("rx'd REJ, N(R) = %d\n", l2sc->rxd_NR)); i4b_next_l2state(l2sc, EV_RXREJ); break; default: + l2sc->stat.err_rx_bads++; /* update statistics */ DBGL2(L2_S_ERR, "i4b_rxd_s_frame", ("ERROR, unknown code, frame = \n")); i4b_print_frame(m->m_len, m->m_data); break; @@ -128,6 +132,8 @@ i4b_tx_rr_command(l2_softc_t *l2sc, pbit_t pbit) m = i4b_build_s_frame(l2sc, CR_CMD_TO_NT, pbit, RR); PH_Data_Req(l2sc->unit, m, MBUF_FREE); + + l2sc->stat.tx_rr++; /* update statistics */ } /*---------------------------------------------------------------------------* @@ -143,6 +149,8 @@ i4b_tx_rr_response(l2_softc_t *l2sc, fbit_t fbit) m = i4b_build_s_frame(l2sc, CR_RSP_TO_NT, fbit, RR); PH_Data_Req(l2sc->unit, m, MBUF_FREE); + + l2sc->stat.tx_rr++; /* update statistics */ } /*---------------------------------------------------------------------------* @@ -158,6 +166,8 @@ i4b_tx_rnr_command(l2_softc_t *l2sc, pbit_t pbit) m = i4b_build_s_frame(l2sc, CR_CMD_TO_NT, pbit, RNR); PH_Data_Req(l2sc->unit, m, MBUF_FREE); + + l2sc->stat.tx_rnr++; /* update statistics */ } /*---------------------------------------------------------------------------* @@ -173,6 +183,8 @@ i4b_tx_rnr_response(l2_softc_t *l2sc, fbit_t fbit) m = i4b_build_s_frame(l2sc, CR_RSP_TO_NT, fbit, RNR); PH_Data_Req(l2sc->unit, m, MBUF_FREE); + + l2sc->stat.tx_rnr++; /* update statistics */ } /*---------------------------------------------------------------------------* @@ -188,6 +200,8 @@ i4b_tx_rej_response(l2_softc_t *l2sc, fbit_t fbit) m = i4b_build_s_frame(l2sc, CR_RSP_TO_NT, fbit, REJ); PH_Data_Req(l2sc->unit, m, MBUF_FREE); + + l2sc->stat.tx_rej++; /* update statistics */ } /*---------------------------------------------------------------------------* diff --git a/sys/i4b/layer2/i4b_tei.c b/sys/i4b/layer2/i4b_tei.c index 3742dfd2b540..b0299186f348 100644 --- a/sys/i4b/layer2/i4b_tei.c +++ b/sys/i4b/layer2/i4b_tei.c @@ -27,9 +27,9 @@ * i4b_tei.c - tei handling procedures * ----------------------------------- * - * $Id: i4b_tei.c,v 1.14 1999/02/14 09:45:00 hm Exp $ + * $Id: i4b_tei.c,v 1.15 1999/05/28 15:03:32 hm Exp $ * - * last edit-date: [Sun Feb 14 10:32:12 1999] + * last edit-date: [Fri May 28 16:14:14 1999] * *---------------------------------------------------------------------------*/ @@ -213,6 +213,7 @@ build_tei_mgmt_frame(l2_softc_t *l2sc, unsigned char type) panic("build_tei_mgmt_frame: invalid type"); break; } + l2sc->stat.tx_tei++; return(m); } diff --git a/sys/i4b/layer2/i4b_uframe.c b/sys/i4b/layer2/i4b_uframe.c index 1e8619ddae66..c27cfb8b256c 100644 --- a/sys/i4b/layer2/i4b_uframe.c +++ b/sys/i4b/layer2/i4b_uframe.c @@ -27,9 +27,9 @@ * i4b_uframe.c - routines for handling U-frames * ----------------------------------------------- * - * $Id: i4b_uframe.c,v 1.7 1999/02/14 09:45:00 hm Exp $ + * $Id: i4b_uframe.c,v 1.8 1999/05/28 15:03:32 hm Exp $ * - * last edit-date: [Sun Feb 14 10:32:17 1999] + * last edit-date: [Fri May 28 16:14:32 1999] * *---------------------------------------------------------------------------*/ @@ -89,10 +89,9 @@ i4b_rxd_u_frame(int unit, struct mbuf *m) if((l2sc->tei_valid == TEI_VALID) && (l2sc->tei == GETTEI(*(ptr+OFF_TEI)))) { + l2sc->stat.rx_sabme++; DBGL2(L2_U_MSG, "i4b_rxd_u_frame", ("SABME, sapi = %d, tei = %d\n", sapi, tei)); - l2sc->rxd_PF = pfbit; - i4b_next_l2state(l2sc, EV_RXSABME); } i4b_Dfreembuf(m); @@ -104,13 +103,13 @@ i4b_rxd_u_frame(int unit, struct mbuf *m) *(ptr + OFF_MEI) == MEI) { /* layer 2 management (SAPI = 63) */ - + l2sc->stat.rx_tei++; i4b_tei_rxframe(unit, m); } else if(sapi == SAPI_CCP && tei == GROUP_TEI) { /* call control (SAPI = 0) */ - + l2sc->stat.rx_ui++; /* strip ui header */ m_adj(m, UI_HDR_LEN); /* to upper layer */ @@ -118,8 +117,8 @@ i4b_rxd_u_frame(int unit, struct mbuf *m) } else { + l2sc->stat.err_rx_badui++; DBGL2(L2_U_ERR, "i4b_rxd_u_frame", ("unknown UI frame!\n")); - i4b_Dfreembuf(m); } break; @@ -128,10 +127,9 @@ i4b_rxd_u_frame(int unit, struct mbuf *m) if((l2sc->tei_valid == TEI_VALID) && (l2sc->tei == GETTEI(*(ptr+OFF_TEI)))) { + l2sc->stat.rx_disc++; DBGL2(L2_U_MSG, "i4b_rxd_u_frame", ("DISC, sapi = %d, tei = %d\n", sapi, tei)); - l2sc->rxd_PF = pfbit; - i4b_next_l2state(l2sc, EV_RXDISC); } i4b_Dfreembuf(m); @@ -141,6 +139,7 @@ i4b_rxd_u_frame(int unit, struct mbuf *m) if((l2sc->tei_valid == TEI_VALID) && (l2sc->tei == GETTEI(*(ptr+OFF_TEI)))) { + l2sc->stat.rx_xid++; DBGL2(L2_U_MSG, "i4b_rxd_u_frame", ("XID, sapi = %d, tei = %d\n", sapi, tei)); } i4b_Dfreembuf(m); @@ -152,12 +151,10 @@ i4b_rxd_u_frame(int unit, struct mbuf *m) if((l2sc->tei_valid == TEI_VALID) && (l2sc->tei == GETTEI(*(ptr+OFF_TEI)))) { + l2sc->stat.rx_dm++; DBGL2(L2_U_MSG, "i4b_rxd_u_frame", ("DM, sapi = %d, tei = %d\n", sapi, tei)); - i4b_print_frame(m->m_len, m->m_data); - l2sc->rxd_PF = pfbit; - i4b_next_l2state(l2sc, EV_RXDM); } i4b_Dfreembuf(m); @@ -167,10 +164,9 @@ i4b_rxd_u_frame(int unit, struct mbuf *m) if((l2sc->tei_valid == TEI_VALID) && (l2sc->tei == GETTEI(*(ptr+OFF_TEI)))) { + l2sc->stat.rx_ua++; DBGL2(L2_U_MSG, "i4b_rxd_u_frame", ("UA, sapi = %d, tei = %d\n", sapi, tei)); - l2sc->rxd_PF = pfbit; - i4b_next_l2state(l2sc, EV_RXUA); } i4b_Dfreembuf(m); @@ -180,10 +176,9 @@ i4b_rxd_u_frame(int unit, struct mbuf *m) if((l2sc->tei_valid == TEI_VALID) && (l2sc->tei == GETTEI(*(ptr+OFF_TEI)))) { + l2sc->stat.rx_frmr++; DBGL2(L2_U_MSG, "i4b_rxd_u_frame", ("FRMR, sapi = %d, tei = %d\n", sapi, tei)); - l2sc->rxd_PF = pfbit; - i4b_next_l2state(l2sc, EV_RXFRMR); } i4b_Dfreembuf(m); @@ -201,6 +196,7 @@ i4b_rxd_u_frame(int unit, struct mbuf *m) DBGL2(L2_U_ERR, "i4b_rxd_u_frame", ("not mine - UNKNOWN TYPE ERROR, sapi = %d, tei = %d, frame = ", sapi, tei)); i4b_print_frame(m->m_len, m->m_data); } + l2sc->stat.err_rx_badui++; i4b_Dfreembuf(m); break; } @@ -237,10 +233,9 @@ i4b_tx_sabme(l2_softc_t *l2sc, pbit_t pbit) { struct mbuf *m; + l2sc->stat.tx_sabme++; DBGL2(L2_U_MSG, "i4b_tx_sabme", ("tx SABME, tei = %d\n", l2sc->tei)); - m = i4b_build_u_frame(l2sc, CR_CMD_TO_NT, pbit, SABME); - PH_Data_Req(l2sc->unit, m, MBUF_FREE); } @@ -251,11 +246,10 @@ void i4b_tx_dm(l2_softc_t *l2sc, fbit_t fbit) { struct mbuf *m; - + + l2sc->stat.tx_dm++; DBGL2(L2_U_MSG, "i4b_tx_dm", ("tx DM, tei = %d\n", l2sc->tei)); - m = i4b_build_u_frame(l2sc, CR_RSP_TO_NT, fbit, DM); - PH_Data_Req(l2sc->unit, m, MBUF_FREE); } @@ -267,10 +261,9 @@ i4b_tx_disc(l2_softc_t *l2sc, pbit_t pbit) { struct mbuf *m; + l2sc->stat.tx_disc++; DBGL2(L2_U_MSG, "i4b_tx_disc", ("tx DISC, tei = %d\n", l2sc->tei)); - m = i4b_build_u_frame(l2sc, CR_CMD_TO_NT, pbit, DISC); - PH_Data_Req(l2sc->unit, m, MBUF_FREE); } @@ -282,10 +275,9 @@ i4b_tx_ua(l2_softc_t *l2sc, fbit_t fbit) { struct mbuf *m; + l2sc->stat.tx_ua++; DBGL2(L2_U_MSG, "i4b_tx_ua", ("tx UA, tei = %d\n", l2sc->tei)); - m = i4b_build_u_frame(l2sc, CR_RSP_TO_NT, fbit, UA); - PH_Data_Req(l2sc->unit, m, MBUF_FREE); } @@ -297,12 +289,10 @@ i4b_tx_frmr(l2_softc_t *l2sc, fbit_t fbit) { struct mbuf *m; + l2sc->stat.tx_frmr++; DBGL2(L2_U_MSG, "i4b_tx_frmr", ("tx FRMR, tei = %d\n", l2sc->tei)); - m = i4b_build_u_frame(l2sc, CR_RSP_TO_NT, fbit, FRMR); - PH_Data_Req(l2sc->unit, m, MBUF_FREE); } - #endif /* NI4BQ921 > 0 */ diff --git a/sys/i4b/layer3/i4b_l2if.c b/sys/i4b/layer3/i4b_l2if.c index 26338399294f..36ca34c04f0c 100644 --- a/sys/i4b/layer3/i4b_l2if.c +++ b/sys/i4b/layer3/i4b_l2if.c @@ -27,9 +27,9 @@ * i4b_l2if.c - Layer 3 interface to Layer 2 * ------------------------------------------- * - * $Id: i4b_l2if.c,v 1.15 1999/02/14 09:45:01 hm Exp $ + * $Id: i4b_l2if.c,v 1.16 1999/05/25 10:05:40 hm Exp $ * - * last edit-date: [Sun Feb 14 10:33:13 1999] + * last edit-date: [Tue May 25 11:55:15 1999] * *---------------------------------------------------------------------------*/ @@ -570,7 +570,7 @@ i4b_l3_tx_status(call_desc_t *cd, u_char q850cause) *ptr++ = IEI_CAUSE; /* cause ie */ *ptr++ = CAUSE_LEN; *ptr++ = CAUSE_STD_LOC_OUT; - *ptr++ = q850cause; + *ptr++ = q850cause | EXT_LAST; *ptr++ = IEI_CALLSTATE; /* call state ie */ *ptr++ = CALLSTATE_LEN; diff --git a/sys/i4b/layer4/i4b_i4bdrv.c b/sys/i4b/layer4/i4b_i4bdrv.c index 4ea26e7fb4ae..d15255502f57 100644 --- a/sys/i4b/layer4/i4b_i4bdrv.c +++ b/sys/i4b/layer4/i4b_i4bdrv.c @@ -27,9 +27,9 @@ * i4b_i4bdrv.c - i4b userland interface driver * -------------------------------------------- * - * $Id: i4b_i4bdrv.c,v 1.5 1999/05/20 10:11:20 hm Exp $ + * $Id: i4b_i4bdrv.c,v 1.47 1999/06/08 17:49:44 hm Exp $ * - * last edit-date: [Thu May 6 10:05:01 1999] + * last edit-date: [Tue Jun 8 19:48:16 1999] * *---------------------------------------------------------------------------*/ @@ -147,6 +147,8 @@ PDEVSTATIC d_select_t i4bselect; #endif #define CDEV_MAJOR 60 + +#if defined (__FreeBSD_version) && __FreeBSD_version >= 400006 static struct cdevsw i4b_cdevsw = { /* open */ i4bopen, /* close */ i4bclose, @@ -168,11 +170,38 @@ static struct cdevsw i4b_cdevsw = { /* maxio */ 0, /* bmaj */ -1 }; +#else +static struct cdevsw i4b_cdevsw = { + i4bopen, i4bclose, i4bread, nowrite, + i4bioctl, nostop, nullreset, nodevtotty, + POLLFIELD, nommap, NULL, "i4b", NULL, -1 +}; +#endif PDEVSTATIC void i4battach(void *); PSEUDO_SET(i4battach, i4b_i4bdrv); -#endif /* __FreeBSD__ */ +static void +i4b_drvinit(void *unused) +{ +#if defined (__FreeBSD_version) && __FreeBSD_version >= 400006 + cdevsw_add(&i4b_cdevsw); +#else + static int i4b_devsw_installed = 0; + dev_t dev; + + if( ! i4b_devsw_installed ) + { + dev = makedev(CDEV_MAJOR,0); + cdevsw_add(&dev,&i4b_cdevsw,NULL); + i4b_devsw_installed = 1; + } +#endif +} + +SYSINIT(i4bdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,i4b_drvinit,NULL) + +#endif /* BSD > 199306 && defined(__FreeBSD__) */ #ifdef __bsdi__ #include <sys/device.h> @@ -961,16 +990,4 @@ i4bputqueue_hipri(struct mbuf *m) } } -#if BSD > 199306 && defined(__FreeBSD__) -static int i4b_devsw_installed = 0; - -static void -i4b_drvinit(void *unused) -{ - - cdevsw_add(&i4b_cdevsw); -} - -SYSINIT(i4bdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,i4b_drvinit,NULL) -#endif /* __FreeBSD__ */ #endif /* NI4B > 0 */ |