summaryrefslogtreecommitdiffstats
path: root/sys/i4b
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>2000-11-25 07:35:38 +0000
committerjlemon <jlemon@FreeBSD.org>2000-11-25 07:35:38 +0000
commit954e1d2ccdb661d5c8b7f69340d118fa7ba7fb85 (patch)
tree0a4e9f6dcd5fa64a78f5991ac425f3ca97aba154 /sys/i4b
parent2daca11cae375091daf49a7cd704e5e4e1be27db (diff)
downloadFreeBSD-src-954e1d2ccdb661d5c8b7f69340d118fa7ba7fb85.zip
FreeBSD-src-954e1d2ccdb661d5c8b7f69340d118fa7ba7fb85.tar.gz
Lock down the network interface queues. The queue mutex must be obtained
before adding/removing packets from the queue. Also, the if_obytes and if_omcasts fields should only be manipulated under protection of the mutex. IF_ENQUEUE, IF_PREPEND, and IF_DEQUEUE perform all necessary locking on the queue. An IF_LOCK macro is provided, as well as the old (mutex-less) versions of the macros in the form _IF_ENQUEUE, _IF_QFULL, for code which needs them, but their use is discouraged. Two new macros are introduced: IF_DRAIN() to drain a queue, and IF_HANDOFF, which takes care of locking/enqueue, and also statistics updating/start if necessary.
Diffstat (limited to 'sys/i4b')
-rw-r--r--sys/i4b/driver/i4b_bsdi_ibc.c23
-rw-r--r--sys/i4b/driver/i4b_ing.c36
-rw-r--r--sys/i4b/driver/i4b_ipr.c50
-rw-r--r--sys/i4b/driver/i4b_isppp.c7
-rw-r--r--sys/i4b/driver/i4b_ispppsubr.c63
-rw-r--r--sys/i4b/driver/i4b_rbch.c43
-rw-r--r--sys/i4b/driver/i4b_tel.c32
-rw-r--r--sys/i4b/driver/i4b_trace.c17
-rw-r--r--sys/i4b/layer1/ifpi/i4b_ifpi_pci.c19
-rw-r--r--sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c19
-rw-r--r--sys/i4b/layer1/ihfc/i4b_ihfc_drv.c9
-rw-r--r--sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c4
-rw-r--r--sys/i4b/layer1/isic/i4b_bchan.c10
-rw-r--r--sys/i4b/layer1/isic/i4b_hscx.c9
-rw-r--r--sys/i4b/layer1/iwic/i4b_iwic_bchan.c19
-rw-r--r--sys/i4b/layer2/i4b_l2.c3
-rw-r--r--sys/i4b/layer2/i4b_mbuf.c16
-rw-r--r--sys/i4b/layer2/i4b_util.c2
-rw-r--r--sys/i4b/layer4/i4b_i4bdrv.c27
19 files changed, 157 insertions, 251 deletions
diff --git a/sys/i4b/driver/i4b_bsdi_ibc.c b/sys/i4b/driver/i4b_bsdi_ibc.c
index 369d4aa..6fcfe4c 100644
--- a/sys/i4b/driver/i4b_bsdi_ibc.c
+++ b/sys/i4b/driver/i4b_bsdi_ibc.c
@@ -196,18 +196,11 @@ ibcattach(void *dummy)
static struct mbuf *
p2p_dequeue(struct p2pcom *pp)
{
- struct ifqueue *ifq;
struct mbuf *m;
- ifq = &pp->p2p_isnd;
- m = ifq->ifq_head;
- if (m == 0) {
- ifq = &pp->p2p_if.if_snd;
- m = ifq->ifq_head;
- }
+ IF_DEQUEUE(&pp->p2p_isnd, m);
if (m == 0)
- return 0;
- IF_DEQUEUE(ifq, m);
+ IF_DEQUEUE(&pp->p2p_if.if_snd, m);
return m;
}
@@ -231,13 +224,16 @@ ibc_start(struct ifnet *ifp)
s = SPLI4B();
- if (IF_QFULL(isdn_ibc_lt[unit]->tx_queue)) {
+ IF_LOCK(isdn_ibc_lt[unit]->tx_queue);
+ if (_IF_QFULL(isdn_ibc_lt[unit]->tx_queue)) {
+ IF_UNLOCK(isdn_ibc_lt[unit]->tx_queue);
splx(s);
return 0;
}
m = p2p_dequeue(pp);
if (m == NULL) {
+ IF_UNLOCK(isdn_ibc_lt[unit]->tx_queue);
splx(s);
return 0;
}
@@ -245,13 +241,14 @@ ibc_start(struct ifnet *ifp)
do {
microtime(&ifp->if_lastchange);
- IF_ENQUEUE(isdn_ibc_lt[unit]->tx_queue, m);
-
ifp->if_obytes += m->m_pkthdr.len;
sc->sc_outb += m->m_pkthdr.len;
+ _IF_ENQUEUE(isdn_ibc_lt[unit]->tx_queue, m);
+
ifp->if_opackets++;
- } while (!IF_QFULL(isdn_ibc_lt[unit]->tx_queue) &&
+ } while (!_IF_QFULL(isdn_ibc_lt[unit]->tx_queue) &&
(m = p2p_dequeue(pp)) != NULL);
+ IF_UNLOCK(isdn_ibc_lt[unit]->tx_queue);
isdn_ibc_lt[unit]->bch_tx_start(isdn_ibc_lt[unit]->unit,
isdn_ibc_lt[unit]->channel);
splx(s);
diff --git a/sys/i4b/driver/i4b_ing.c b/sys/i4b/driver/i4b_ing.c
index 26a5b3b..50e1c4b 100644
--- a/sys/i4b/driver/i4b_ing.c
+++ b/sys/i4b/driver/i4b_ing.c
@@ -247,6 +247,7 @@ i4bingattach(void *dummy)
sc->sc_state = ST_IDLE;
sc->sc_fastq.ifq_maxlen = I4BINGMAXQLEN;
+ mtx_init(&sc->sc_fastq.ifq_mtx, "i4b_ing_fastq", MTX_DEF);
#if I4BINGACCT
callout_handle_init(&sc->sc_callout);
@@ -278,6 +279,8 @@ i4bingattach(void *dummy)
sc->xmitq.ifq_maxlen = IFQ_MAXLEN;
sc->xmitq_hipri.ifq_maxlen = IFQ_MAXLEN;
+ mtx_init(&sc->xmitq.ifq_mtx, "i4b_ing_xmitq", MTX_DEF);
+ mtx_init(&sc->xmitq_hipri.ifq_mtx, "i4b_ing_hipri", MTX_DEF);
/* name the netgraph node */
@@ -339,20 +342,11 @@ static void
ingclearqueue(struct ifqueue *iq)
{
int x;
- struct mbuf *m;
- for(;;)
- {
- x = splimp();
- IF_DEQUEUE(iq, m);
- splx(x);
-
- if(m)
- m_freem(m);
- else
- break;
- }
-}
+ x = splimp();
+ IF_DRAIN(iq);
+ splx(x);
+}
#endif
/*===========================================================================*
@@ -517,14 +511,9 @@ ing_tx_queue_empty(int unit)
x = 1;
- if(IF_QFULL(isdn_linktab[unit]->tx_queue))
+ if(! IF_HANDOFF(isdn_linktab[unit]->tx_queue, m, NULL))
{
NDBGL4(L4_INGDBG, "ing%d: tx queue full!", unit);
- m_freem(m);
- }
- else
- {
- IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m);
}
}
@@ -794,15 +783,18 @@ ng_ing_rcvdata(hook_p hook, struct mbuf *m, meta_p meta)
s = splimp();
- if (IF_QFULL(xmitq_p))
+ IF_LOCK(xmitq_p);
+ if (_IF_QFULL(xmitq_p))
{
- IF_DROP(xmitq_p);
+ _IF_DROP(xmitq_p);
+ IF_UNLOCK(xmitq_p);
splx(s);
NG_FREE_DATA(m, meta);
return(ENOBUFS);
}
- IF_ENQUEUE(xmitq_p, m);
+ _IF_ENQUEUE(xmitq_p, m);
+ IF_UNLOCK(xmitq_p);
ing_tx_queue_empty(sc->sc_unit);
diff --git a/sys/i4b/driver/i4b_ipr.c b/sys/i4b/driver/i4b_ipr.c
index 4d76cb9..4aa074a 100644
--- a/sys/i4b/driver/i4b_ipr.c
+++ b/sys/i4b/driver/i4b_ipr.c
@@ -324,6 +324,7 @@ i4biprattach()
sc->sc_if.if_snd.ifq_maxlen = I4BIPRMAXQLEN;
sc->sc_fastq.ifq_maxlen = I4BIPRMAXQLEN;
+ mtx_init(&sc->sc_fastq.ifq_mtx, "i4b_ipr_fastq", MTX_DEF);
sc->sc_if.if_ipackets = 0;
sc->sc_if.if_ierrors = 0;
@@ -509,11 +510,9 @@ i4biproutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
/* check for space in choosen send queue */
- if(IF_QFULL(ifq))
+ if(! IF_HANDOFF(ifq, m, NULL))
{
NDBGL4(L4_IPRDBG, "ipr%d: send queue full!", unit);
- IF_DROP(ifq);
- m_freem(m);
splx(s);
sc->sc_if.if_oerrors++;
return(ENOBUFS);
@@ -521,8 +520,6 @@ i4biproutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
NDBGL4(L4_IPRDBG, "ipr%d: add packet to send queue!", unit);
- IF_ENQUEUE(ifq, m);
-
ipr_tx_queue_empty(unit);
splx(s);
@@ -648,31 +645,11 @@ static void
iprclearqueues(struct ipr_softc *sc)
{
int x;
- struct mbuf *m;
- for(;;)
- {
- x = splimp();
- IF_DEQUEUE(&sc->sc_fastq, m);
- splx(x);
-
- if(m)
- m_freem(m);
- else
- break;
- }
-
- for(;;)
- {
- x = splimp();
- IF_DEQUEUE(&sc->sc_if.if_snd, m);
- splx(x);
-
- if(m)
- m_freem(m);
- else
- break;
- }
+ x = splimp();
+ IF_DRAIN(&sc->sc_fastq);
+ IF_DRAIN(&sc->sc_if.if_snd);
+ splx(x);
}
#if I4BIPRACCT
@@ -1070,18 +1047,14 @@ error:
}
#endif /* NBPFILTER > 0 || NBPF > 0 */
- if(IF_QFULL(&ipintrq))
+ if(! IF_HANDOFF(&ipintrq, m, NULL))
{
NDBGL4(L4_IPRDBG, "ipr%d: ipintrq full!", unit);
-
- IF_DROP(&ipintrq);
sc->sc_if.if_ierrors++;
sc->sc_if.if_iqdrops++;
- m_freem(m);
}
else
{
- IF_ENQUEUE(&ipintrq, m);
schednetisr(NETISR_IP);
}
}
@@ -1155,19 +1128,22 @@ ipr_tx_queue_empty(int unit)
#endif
x = 1;
- if(IF_QFULL(isdn_linktab[unit]->tx_queue))
+ IF_LOCK(isdn_linktab[unit]->tx_queue);
+ if(_IF_QFULL(isdn_linktab[unit]->tx_queue))
{
NDBGL4(L4_IPRDBG, "ipr%d: tx queue full!", unit);
m_freem(m);
}
else
{
- IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m);
-
sc->sc_if.if_obytes += m->m_pkthdr.len;
sc->sc_if.if_opackets++;
+
+ _IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m);
+
}
+ IF_UNLOCK(isdn_linktab[unit]->tx_queue);
}
if(x)
diff --git a/sys/i4b/driver/i4b_isppp.c b/sys/i4b/driver/i4b_isppp.c
index f13c229..0be5efa 100644
--- a/sys/i4b/driver/i4b_isppp.c
+++ b/sys/i4b/driver/i4b_isppp.c
@@ -426,20 +426,23 @@ i4bisppp_start(struct ifnet *ifp)
microtime(&ifp->if_lastchange);
- if(IF_QFULL(isdn_linktab[unit]->tx_queue))
+ IF_LOCK(isdn_linktab[unit]->tx_queue);
+ if(_IF_QFULL(isdn_linktab[unit]->tx_queue))
{
NDBGL4(L4_ISPDBG, "isp%d, tx queue full!", unit);
m_freem(m);
}
else
{
- IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m);
#if 0
sc->sc_if.if_obytes += m->m_pkthdr.len;
#endif
sc->sc_outb += m->m_pkthdr.len;
sc->sc_if.if_opackets++;
+
+ _IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m);
}
+ IF_UNLOCK(isdn_linktab[unit]->tx_queue);
}
isdn_linktab[unit]->bch_tx_start(isdn_linktab[unit]->unit,
isdn_linktab[unit]->channel);
diff --git a/sys/i4b/driver/i4b_ispppsubr.c b/sys/i4b/driver/i4b_ispppsubr.c
index 7b3a1f9..cbe45b6 100644
--- a/sys/i4b/driver/i4b_ispppsubr.c
+++ b/sys/i4b/driver/i4b_ispppsubr.c
@@ -665,17 +665,15 @@ isppp_input(struct ifnet *ifp, struct mbuf *m)
/* Check queue. */
s = splimp();
- if (IF_QFULL (inq)) {
- /* Queue overflow. */
- IF_DROP(inq);
- splx(s);
+ if (! IF_HANDOFF(inq, m, NULL)) {
+ ++ifp->if_ierrors;
+ ++ifp->if_iqdrops;
if (debug)
log(LOG_DEBUG, SPP_FMT "protocol queue overflow\n",
SPP_ARGS(ifp));
- goto drop;
+ } else {
+ sp->pp_last_recv = time_second;
}
- IF_ENQUEUE(inq, m);
- sp->pp_last_recv = time_second;
splx(s);
}
@@ -748,7 +746,7 @@ sppp_output(struct ifnet *ifp, struct mbuf *m,
* Put low delay, telnet, rlogin and ftp control packets
* in front of the queue.
*/
- if (IF_QFULL (&sp->pp_fastq))
+ if (_IF_QFULL (&sp->pp_fastq))
;
else if (ip->ip_tos & IPTOS_LOWDELAY)
ifq = &sp->pp_fastq;
@@ -870,24 +868,17 @@ nosupport:
/*
* Queue message on interface, and start output if interface
* not yet active.
+ *
+ * Count output packets and bytes.
+ * The packet length includes header, FCS and 1 flag,
+ * according to RFC 1333.
*/
- if (IF_QFULL (ifq)) {
- IF_DROP (&ifp->if_snd);
- m_freem (m);
+ if (! IF_HANDOFF_ADJ(ifq, m, ifp, 3)) {
++ifp->if_oerrors;
splx (s);
return (rv? rv: ENOBUFS);
}
- IF_ENQUEUE (ifq, m);
- if (! (ifp->if_flags & IFF_OACTIVE))
- (*ifp->if_start) (ifp);
- /*
- * Count output packets and bytes.
- * The packet length includes header, FCS and 1 flag,
- * according to RFC 1333.
- */
- ifp->if_obytes += m->m_pkthdr.len + 3;
sp->pp_last_sent = time_second;
splx (s);
return (0);
@@ -921,6 +912,8 @@ isppp_attach(struct ifnet *ifp)
sp->pp_fastq.ifq_maxlen = 32;
sp->pp_cpq.ifq_maxlen = 20;
+ mtx_init(&sp->pp_fastq.ifq_mtx, "i4b_isppp_fastq", MTX_DEF);
+ mtx_init(&sp->pp_cpq.ifq_mtx, "i4b_isppp_cpq", MTX_DEF);
sp->pp_loopcnt = 0;
sp->pp_alivecnt = 0;
sp->pp_seq = 0;
@@ -1316,15 +1309,7 @@ sppp_cisco_send(struct sppp *sp, int type, long par1, long par2)
SPP_ARGS(ifp), (u_long)ntohl (ch->type), (u_long)ch->par1,
(u_long)ch->par2, (u_int)ch->rel, (u_int)ch->time0, (u_int)ch->time1);
- if (IF_QFULL (&sp->pp_cpq)) {
- IF_DROP (&sp->pp_fastq);
- IF_DROP (&ifp->if_snd);
- m_freem (m);
- } else
- IF_ENQUEUE (&sp->pp_cpq, m);
- if (! (ifp->if_flags & IFF_OACTIVE))
- (*ifp->if_start) (ifp);
- ifp->if_obytes += m->m_pkthdr.len + 3;
+ (void) IF_HANDOFF_ADJ(&sp->pp_cpq, m, ifp, 3);
}
/*
@@ -1372,16 +1357,8 @@ sppp_cp_send(struct sppp *sp, u_short proto, u_char type,
sppp_print_bytes ((u_char*) (lh+1), len);
addlog(">\n");
}
- if (IF_QFULL (&sp->pp_cpq)) {
- IF_DROP (&sp->pp_fastq);
- IF_DROP (&ifp->if_snd);
- m_freem (m);
+ if (! IF_HANDOFF_ADJ(&sp->pp_cpq, m, ifp, 3))
++ifp->if_oerrors;
- } else
- IF_ENQUEUE (&sp->pp_cpq, m);
- if (! (ifp->if_flags & IFF_OACTIVE))
- (*ifp->if_start) (ifp);
- ifp->if_obytes += m->m_pkthdr.len + 3;
}
/*
@@ -4035,16 +4012,8 @@ sppp_auth_send(const struct cp *cp, struct sppp *sp,
sppp_print_bytes((u_char*) (lh+1), len);
addlog(">\n");
}
- if (IF_QFULL (&sp->pp_cpq)) {
- IF_DROP (&sp->pp_fastq);
- IF_DROP (&ifp->if_snd);
- m_freem (m);
+ if (! IF_HANDOFF_ADJ(&sp->pp_cpq, m, NULL, 3))
++ifp->if_oerrors;
- } else
- IF_ENQUEUE (&sp->pp_cpq, m);
- if (! (ifp->if_flags & IFF_OACTIVE))
- (*ifp->if_start) (ifp);
- ifp->if_obytes += m->m_pkthdr.len + 3;
}
/*
diff --git a/sys/i4b/driver/i4b_rbch.c b/sys/i4b/driver/i4b_rbch.c
index 59247c2..9e7db6a 100644
--- a/sys/i4b/driver/i4b_rbch.c
+++ b/sys/i4b/driver/i4b_rbch.c
@@ -327,6 +327,7 @@ i4brbchattach()
rbch_softc[i].sc_unit = i;
rbch_softc[i].sc_devstate = ST_IDLE;
rbch_softc[i].sc_hdlcq.ifq_maxlen = I4BRBCHMAXQLEN;
+ mtx_init(&rbch_softc[i].sc_hdlcq.ifq_mtx, "i4b_rbch", MTX_DEF);
rbch_softc[i].it_in.c_ispeed = rbch_softc[i].it_in.c_ospeed = 64000;
termioschars(&rbch_softc[i].it_in);
rbch_init_linktab(i);
@@ -510,7 +511,7 @@ i4brbchwrite(dev_t dev, struct uio * uio, int ioflag)
CRIT_END;
return(EWOULDBLOCK);
}
- if(IF_QFULL(isdn_linktab[unit]->tx_queue) && (sc->sc_devstate & ST_ISOPEN)) {
+ if(_IF_QFULL(isdn_linktab[unit]->tx_queue) && (sc->sc_devstate & ST_ISOPEN)) {
CRIT_END;
return(EWOULDBLOCK);
}
@@ -543,7 +544,7 @@ i4brbchwrite(dev_t dev, struct uio * uio, int ioflag)
tsleep((caddr_t) &rbch_softc[unit], TTIPRI | PCATCH, "xrbch", (hz*1));
}
- while(IF_QFULL(isdn_linktab[unit]->tx_queue) && (sc->sc_devstate & ST_ISOPEN))
+ while(_IF_QFULL(isdn_linktab[unit]->tx_queue) && (sc->sc_devstate & ST_ISOPEN))
{
sc->sc_devstate |= ST_WRWAITEMPTY;
@@ -589,15 +590,7 @@ i4brbchwrite(dev_t dev, struct uio * uio, int ioflag)
error = uiomove(m->m_data, m->m_len, uio);
- if(IF_QFULL(isdn_linktab[unit]->tx_queue))
- {
- m_freem(m);
- }
- else
- {
- IF_ENQUEUE(isdn_linktab[unit]->tx_queue, m);
- }
-
+ (void) IF_HANDOFF(isdn_linktab[unit]->tx_queue, m, NULL);
(*isdn_linktab[unit]->bch_tx_start)(isdn_linktab[unit]->unit, isdn_linktab[unit]->channel);
}
@@ -733,7 +726,7 @@ i4brbchpoll(dev_t dev, int events, struct proc *p)
if((events & (POLLOUT|POLLWRNORM)) &&
(sc->sc_devstate & ST_CONNECTED) &&
- !IF_QFULL(isdn_linktab[unit]->tx_queue))
+ !_IF_QFULL(isdn_linktab[unit]->tx_queue))
{
revents |= (events & (POLLOUT|POLLWRNORM));
}
@@ -802,7 +795,7 @@ i4brbchselect(dev_t dev, int rw, struct proc *p)
break;
case FWRITE:
- if(!IF_QFULL(isdn_linktab[unit]->rx_queue))
+ if(!_IF_QFULL(isdn_linktab[unit]->rx_queue))
{
splx(s);
return(1);
@@ -962,16 +955,11 @@ rbch_rx_data_rdy(int unit)
m->m_pkthdr.len = m->m_len;
- if(IF_QFULL(&(rbch_softc[unit].sc_hdlcq)))
+ if (! IF_HANDOFF(&(rbch_softc[unit].sc_hdlcq), m, NULL))
{
NDBGL4(L4_RBCHDBG, "unit %d: hdlc rx queue full!", unit);
- m_freem(m);
}
- else
- {
- IF_ENQUEUE(&(rbch_softc[unit].sc_hdlcq), m);
- }
- }
+ }
if(rbch_softc[unit].sc_devstate & ST_RDWAITDATA)
{
@@ -1025,20 +1013,11 @@ rbch_activity(int unit, int rxtx)
static void
rbch_clrq(int unit)
{
- struct mbuf *m;
CRIT_VAR;
- for(;;)
- {
- CRIT_BEG;
- IF_DEQUEUE(&rbch_softc[unit].sc_hdlcq, m);
- CRIT_END;
-
- if(m)
- m_freem(m);
- else
- break;
- }
+ CRIT_BEG;
+ IF_DRAIN(&rbch_softc[unit].sc_hdlcq);
+ CRIT_END;
}
/*---------------------------------------------------------------------------*
diff --git a/sys/i4b/driver/i4b_tel.c b/sys/i4b/driver/i4b_tel.c
index 1652b20..b34ec16 100644
--- a/sys/i4b/driver/i4b_tel.c
+++ b/sys/i4b/driver/i4b_tel.c
@@ -573,6 +573,7 @@ i4btelread(dev_t dev, struct uio *uio, int ioflag)
if(func == FUNCTEL)
{
s = splimp();
+ IF_LOCK(sc->isdn_linktab->rx_queue);
while(IF_QEMPTY(sc->isdn_linktab->rx_queue) &&
(sc->devstate & ST_ISOPEN) &&
(sc->devstate & ST_CONNECTED))
@@ -581,11 +582,13 @@ i4btelread(dev_t dev, struct uio *uio, int ioflag)
NDBGL4(L4_TELDBG, "i4btel%d, queue empty!", unit);
- if((error = tsleep((caddr_t) &sc->isdn_linktab->rx_queue,
+ if((error = msleep((caddr_t) &sc->isdn_linktab->rx_queue,
+ &sc->isdn_linktab->rx_queue->ifq_mtx,
TTIPRI | PCATCH,
"rtel", 0 )) != 0)
{
sc->devstate &= ~ST_RDWAITDATA;
+ IF_UNLOCK(sc->isdn_linktab->rx_queue);
splx(s);
return(error);
}
@@ -593,18 +596,21 @@ i4btelread(dev_t dev, struct uio *uio, int ioflag)
if(!(sc->devstate & ST_ISOPEN))
{
+ IF_UNLOCK(sc->isdn_linktab->rx_queue);
splx(s);
return(EIO);
}
if(!(sc->devstate & ST_CONNECTED))
{
+ IF_UNLOCK(sc->isdn_linktab->rx_queue);
splx(s);
return(EIO);
}
- IF_DEQUEUE(sc->isdn_linktab->rx_queue, m);
+ _IF_DEQUEUE(sc->isdn_linktab->rx_queue, m);
+ IF_UNLOCK(sc->isdn_linktab->rx_queue);
if(m && m->m_len > 0)
{
@@ -700,19 +706,23 @@ i4btelwrite(dev_t dev, struct uio * uio, int ioflag)
}
sc->devstate &= ~ST_TONE;
- while((IF_QFULL(sc->isdn_linktab->tx_queue)) &&
+ IF_LOCK(sc->isdn_linktab->tx_queue);
+ while((_IF_QFULL(sc->isdn_linktab->tx_queue)) &&
(sc->devstate & ST_ISOPEN))
{
sc->devstate |= ST_WRWAITEMPTY;
- if((error = tsleep((caddr_t) &sc->isdn_linktab->tx_queue,
+ if((error = msleep((caddr_t) &sc->isdn_linktab->tx_queue,
+ &sc->isdn_linktab->tx_queue->ifq_mtx,
TTIPRI | PCATCH, "wtel", 0)) != 0)
{
sc->devstate &= ~ST_WRWAITEMPTY;
+ IF_UNLOCK(sc->isdn_linktab->tx_queue);
splx(s);
return(error);
}
}
+ IF_UNLOCK(sc->isdn_linktab->tx_queue);
if(!(sc->devstate & ST_ISOPEN))
{
@@ -744,15 +754,7 @@ i4btelwrite(dev_t dev, struct uio * uio, int ioflag)
mtod(m,u_char *)[i] = bitreverse[mtod(m,u_char *)[i]];
}
- if(IF_QFULL(sc->isdn_linktab->tx_queue))
- {
- m_freem(m);
- }
- else
- {
- IF_ENQUEUE(sc->isdn_linktab->tx_queue, m);
- }
-
+ (void) IF_HANDOFF(sc->isdn_linktab->tx_queue, m, NULL);
(*sc->isdn_linktab->bch_tx_start)(sc->isdn_linktab->unit, sc->isdn_linktab->channel);
}
@@ -867,7 +869,7 @@ i4btelpoll(dev_t dev, int events, struct proc *p)
if((events & (POLLOUT|POLLWRNORM)) &&
(sc->devstate & ST_CONNECTED) &&
(sc->isdn_linktab != NULL) &&
- (!IF_QFULL(sc->isdn_linktab->tx_queue)))
+ (!_IF_QFULL(sc->isdn_linktab->tx_queue)))
{
NDBGL4(L4_TELDBG, "i4btel%d, POLLOUT", unit);
revents |= (events & (POLLOUT|POLLWRNORM));
@@ -958,7 +960,7 @@ i4btelsel(dev_t dev, int rw, struct proc *p)
}
else if (rw == FWRITE)
{
- if (!IF_QFULL(sc->isdn_linktab->tx_queue))
+ if (!_IF_QFULL(sc->isdn_linktab->tx_queue))
{
NDBGL4(L4_TELDBG, "i4btel%d, FWRITE", unit);
splx(s);
diff --git a/sys/i4b/driver/i4b_trace.c b/sys/i4b/driver/i4b_trace.c
index 0d10771..ff29c01 100644
--- a/sys/i4b/driver/i4b_trace.c
+++ b/sys/i4b/driver/i4b_trace.c
@@ -245,6 +245,7 @@ i4btrcattach()
#endif
#endif
trace_queue[i].ifq_maxlen = IFQ_MAXLEN;
+ mtx_init(&trace_queue[i].ifq_mtx, "i4b_trace", MTX_DEF);
device_state[i] = ST_IDLE;
}
}
@@ -317,12 +318,13 @@ get_trace_data_from_l1(i4b_trace_hdr_t *hdr, int len, char *buf)
unit = outunit;
}
- if(IF_QFULL(&trace_queue[unit]))
+ IF_LOCK(&trace_queue[unit]);
+ if(_IF_QFULL(&trace_queue[unit]))
{
struct mbuf *m1;
x = SPLI4B();
- IF_DEQUEUE(&trace_queue[unit], m1);
+ _IF_DEQUEUE(&trace_queue[unit], m1);
splx(x);
i4b_Bfreembuf(m1);
@@ -339,7 +341,8 @@ get_trace_data_from_l1(i4b_trace_hdr_t *hdr, int len, char *buf)
x = SPLI4B();
- IF_ENQUEUE(&trace_queue[unit], m);
+ _IF_ENQUEUE(&trace_queue[unit], m);
+ IF_UNLOCK(&trace_queue[unit]);
if(device_state[unit] & ST_WAITDATA)
{
@@ -441,21 +444,25 @@ i4btrcread(dev_t dev, struct uio * uio, int ioflag)
x = SPLI4B();
+ IF_LOCK(&trace_queue[unit]);
while(IF_QEMPTY(&trace_queue[unit]) && (device_state[unit] & ST_ISOPEN))
{
device_state[unit] |= ST_WAITDATA;
- if((error = tsleep((caddr_t) &trace_queue[unit],
+ if((error = msleep((caddr_t) &trace_queue[unit],
+ &trace_queue[unit].ifq_mtx,
TTIPRI | PCATCH,
"bitrc", 0 )) != 0)
{
device_state[unit] &= ~ST_WAITDATA;
+ IF_UNLOCK(&trace_queue[unit]);
splx(x);
return(error);
}
}
- IF_DEQUEUE(&trace_queue[unit], m);
+ _IF_DEQUEUE(&trace_queue[unit], m);
+ IF_UNLOCK(&trace_queue[unit]);
if(m && m->m_len)
error = uiomove(m->m_data, m->m_len, uio);
diff --git a/sys/i4b/layer1/ifpi/i4b_ifpi_pci.c b/sys/i4b/layer1/ifpi/i4b_ifpi_pci.c
index a59e07d..6fb3c11 100644
--- a/sys/i4b/layer1/ifpi/i4b_ifpi_pci.c
+++ b/sys/i4b/layer1/ifpi/i4b_ifpi_pci.c
@@ -863,14 +863,7 @@ avma1pp_hscx_intr(int h_chan, u_int stat, struct l1_softc *sc)
/* move rx'd data to rx queue */
- if (!(IF_QFULL(&chan->rx_queue)))
- {
- IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf);
- }
- else
- {
- i4b_Bfreembuf(chan->in_mbuf);
- }
+ (void) IF_HANDOFF(&chan->rx_queue, chan->in_mbuf, NULL);
/* signal upper layer that data are available */
(*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit);
@@ -1124,9 +1117,10 @@ avma1pp_bchannel_setup(int unit, int h_chan, int bprot, int activate)
/* receiver part */
- i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */
-
chan->rx_queue.ifq_maxlen = IFQ_MAXLEN;
+ mtx_init(&chan->rx_queue.ifq_mtx, "i4b_avma1pp_rx", MTX_DEF);
+
+ i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */
chan->rxcount = 0; /* reset rx counter */
@@ -1138,10 +1132,11 @@ avma1pp_bchannel_setup(int unit, int h_chan, int bprot, int activate)
/* transmitter part */
- i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */
-
chan->tx_queue.ifq_maxlen = IFQ_MAXLEN;
+ mtx_init(&chan->tx_queue.ifq_mtx, "i4b_avma1pp_tx", MTX_DEF);
+ i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */
+
chan->txcount = 0; /* reset tx counter */
i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */
diff --git a/sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c b/sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c
index 401a19d..bc69399 100644
--- a/sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c
+++ b/sys/i4b/layer1/ifpnp/i4b_ifpnp_avm.c
@@ -799,14 +799,7 @@ avm_pnp_hscx_intr(int h_chan, u_int stat, u_int cnt, struct l1_softc *sc)
/* move rx'd data to rx queue */
- if (!(IF_QFULL(&chan->rx_queue)))
- {
- IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf);
- }
- else
- {
- i4b_Bfreembuf(chan->in_mbuf);
- }
+ (void) IF_HANDOFF(&chan->rx_queue, chan->in_mbuf, NULL);
/* signal upper layer that data are available */
(*chan->isic_drvr_linktab->bch_rx_data_ready)(chan->isic_drvr_linktab->unit);
@@ -1044,9 +1037,10 @@ avm_pnp_bchannel_setup(int unit, int h_chan, int bprot, int activate)
/* receiver part */
- i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */
-
chan->rx_queue.ifq_maxlen = IFQ_MAXLEN;
+ mtx_init(&chan->rx_queue.ifq_mtx, "i4b_avm_pnp_rx", MTX_DEF);
+
+ i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */
chan->rxcount = 0; /* reset rx counter */
@@ -1058,10 +1052,11 @@ avm_pnp_bchannel_setup(int unit, int h_chan, int bprot, int activate)
/* transmitter part */
+ chan->tx_queue.ifq_maxlen = IFQ_MAXLEN;
+ mtx_init(&chan->tx_queue.ifq_mtx, "i4b_avm_pnp_tx", MTX_DEF);
+
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 */
diff --git a/sys/i4b/layer1/ihfc/i4b_ihfc_drv.c b/sys/i4b/layer1/ihfc/i4b_ihfc_drv.c
index 814a40a..7a01014 100644
--- a/sys/i4b/layer1/ihfc/i4b_ihfc_drv.c
+++ b/sys/i4b/layer1/ihfc/i4b_ihfc_drv.c
@@ -351,13 +351,14 @@ ihfc_init (ihfc_sc_t *sc, u_char chan, int prot, int activate)
do
{ if (chan < 2) /* D-Channel */
{
+ S_IFQUEUE.ifq_maxlen = IFQ_MAXLEN;
+ mtx_init(&S_IFQUEUE.ifq_mtx, "i4b_ihfc", MTX_DEF);
+
i4b_Dfreembuf(S_MBUF);
i4b_Dcleanifq(&S_IFQUEUE);
RESET_SOFT_CHAN(sc, chan);
- S_IFQUEUE.ifq_maxlen = IFQ_MAXLEN;
-
if (!activate) continue;
if (S_HFC & HFC_1)
@@ -373,13 +374,15 @@ ihfc_init (ihfc_sc_t *sc, u_char chan, int prot, int activate)
}
else /* B-Channel */
{
+ S_IFQUEUE.ifq_maxlen = IFQ_MAXLEN;
+ mtx_init(&S_IFQUEUE.ifq_mtx, "i4b_ihfc", MTX_DEF);
+
i4b_Bfreembuf(S_MBUF);
i4b_Bcleanifq(&S_IFQUEUE);
RESET_SOFT_CHAN(sc, chan);
S_PROT = prot;
- S_IFQUEUE.ifq_maxlen = IFQ_MAXLEN;
if (!activate) continue;
diff --git a/sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c b/sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c
index 5b9e6cf..4bb59f0 100644
--- a/sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c
+++ b/sys/i4b/layer1/ihfc/i4b_ihfc_l1if.c
@@ -127,7 +127,7 @@ ihfc_ph_data_req(int unit, struct mbuf *m, int freeflag)
if (freeflag == MBUF_DONTFREE) m = m_copypacket(m, M_DONTWAIT);
- if (!IF_QFULL(&S_IFQUEUE) && m)
+ if (!_IF_QFULL(&S_IFQUEUE) && m)
{
IF_ENQUEUE(&S_IFQUEUE, m);
@@ -300,7 +300,7 @@ ihfc_putmbuf (ihfc_sc_t *sc, u_char chan, struct mbuf *m)
S_BDRVLINK->bch_activity(S_BDRVLINK->unit, ACT_RX);
}
- if (!IF_QFULL(&S_IFQUEUE))
+ if (!_IF_QFULL(&S_IFQUEUE))
{
S_BYTES += m->m_len;
IF_ENQUEUE(&S_IFQUEUE, m);
diff --git a/sys/i4b/layer1/isic/i4b_bchan.c b/sys/i4b/layer1/isic/i4b_bchan.c
index f1db0ea..c937790 100644
--- a/sys/i4b/layer1/isic/i4b_bchan.c
+++ b/sys/i4b/layer1/isic/i4b_bchan.c
@@ -91,9 +91,10 @@ isic_bchannel_setup(int unit, int h_chan, int bprot, int activate)
/* receiver part */
- i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */
-
chan->rx_queue.ifq_maxlen = IFQ_MAXLEN;
+ mtx_init(&chan->rx_queue.ifq_mtx, "i4b_isic_rx", MTX_DEF);
+
+ i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */
chan->rxcount = 0; /* reset rx counter */
@@ -105,10 +106,11 @@ isic_bchannel_setup(int unit, int h_chan, int bprot, int activate)
/* transmitter part */
- i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */
-
chan->tx_queue.ifq_maxlen = IFQ_MAXLEN;
+ mtx_init(&chan->tx_queue.ifq_mtx, "i4b_isic_tx", MTX_DEF);
+ i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */
+
chan->txcount = 0; /* reset tx counter */
i4b_Bfreembuf(chan->out_mbuf_head); /* clean tx mbuf */
diff --git a/sys/i4b/layer1/isic/i4b_hscx.c b/sys/i4b/layer1/isic/i4b_hscx.c
index 121b8c5..79e74b8 100644
--- a/sys/i4b/layer1/isic/i4b_hscx.c
+++ b/sys/i4b/layer1/isic/i4b_hscx.c
@@ -270,14 +270,7 @@ isic_hscx_irq(register struct l1_softc *sc, u_char ista, int h_chan, u_char ex_i
if(!(i4b_l1_bchan_tel_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len)))
activity = ACT_RX;
- if(!(IF_QFULL(&chan->rx_queue)))
- {
- IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf);
- }
- else
- {
- i4b_Bfreembuf(chan->in_mbuf);
- }
+ (void) IF_HANDOFF(&chan->rx_queue, chan->in_mbuf, NULL);
/* signal upper driver that data is available */
diff --git a/sys/i4b/layer1/iwic/i4b_iwic_bchan.c b/sys/i4b/layer1/iwic/i4b_iwic_bchan.c
index e836f78..0b8fa26 100644
--- a/sys/i4b/layer1/iwic/i4b_iwic_bchan.c
+++ b/sys/i4b/layer1/iwic/i4b_iwic_bchan.c
@@ -239,14 +239,7 @@ iwic_bchan_xirq(struct iwic_softc *sc, int chan_no)
if(!(i4b_l1_bchan_tel_silence(chan->in_mbuf->m_data, chan->in_mbuf->m_len)))
activity = ACT_RX;
- if(!(IF_QFULL(&chan->rx_queue)))
- {
- IF_ENQUEUE(&chan->rx_queue, chan->in_mbuf);
- }
- else
- {
- i4b_Bfreembuf(chan->in_mbuf);
- }
+ (void) IF_HANDOFF(&chan->rx_queue, chan->in_mbuf, NULL);
/* signal upper driver that data is available */
@@ -416,9 +409,10 @@ iwic_bchannel_setup(int unit, int chan_no, int bprot, int activate)
/* receiver part */
- i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */
-
chan->rx_queue.ifq_maxlen = IFQ_MAXLEN;
+ mtx_init(&chan->rx_queue.ifq_mtx, "i4b_iwic_rx", MTX_DEF);
+
+ i4b_Bcleanifq(&chan->rx_queue); /* clean rx queue */
chan->rxcount = 0; /* reset rx counter */
@@ -430,9 +424,10 @@ iwic_bchannel_setup(int unit, int chan_no, int bprot, int activate)
/* transmitter part */
- i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */
-
chan->tx_queue.ifq_maxlen = IFQ_MAXLEN;
+ mtx_init(&chan->tx_queue.ifq_mtx, "i4b_iwic_tx", MTX_DEF);
+
+ i4b_Bcleanifq(&chan->tx_queue); /* clean tx queue */
chan->txcount = 0; /* reset tx counter */
diff --git a/sys/i4b/layer2/i4b_l2.c b/sys/i4b/layer2/i4b_l2.c
index 59a09ba..b3f79a6 100644
--- a/sys/i4b/layer2/i4b_l2.c
+++ b/sys/i4b/layer2/i4b_l2.c
@@ -163,7 +163,7 @@ int i4b_dl_data_req(int unit, struct mbuf *m)
case ST_MULTIFR:
case ST_TIMREC:
- if(IF_QFULL(&l2sc->i_queue))
+ if(_IF_QFULL(&l2sc->i_queue))
{
NDBGL2(L2_ERROR, "i_queue full!!");
i4b_Dfreembuf(m);
@@ -277,6 +277,7 @@ i4b_mph_status_ind(int unit, int status, int parm)
case STI_ATTACH:
l2sc->unit = unit;
l2sc->i_queue.ifq_maxlen = IQUEUE_MAXLEN;
+ mtx_init(&l2sc->i_queue.ifq_mtx, "i4b_l2sc", MTX_DEF);
l2sc->ua_frame = NULL;
bzero(&l2sc->stat, sizeof(lapdstat_t));
i4b_l2_unit_init(unit);
diff --git a/sys/i4b/layer2/i4b_mbuf.c b/sys/i4b/layer2/i4b_mbuf.c
index a0f1013..0537a5e 100644
--- a/sys/i4b/layer2/i4b_mbuf.c
+++ b/sys/i4b/layer2/i4b_mbuf.c
@@ -140,15 +140,9 @@ i4b_Dfreembuf(struct mbuf *m)
void
i4b_Dcleanifq(struct ifqueue *ifq)
{
- struct mbuf *m;
int x = splimp();
- while(!IF_QEMPTY(ifq))
- {
- IF_DEQUEUE(ifq, m);
- i4b_Dfreembuf(m);
- }
-
+ IF_DRAIN(ifq);
splx(x);
}
@@ -222,15 +216,9 @@ i4b_Bfreembuf(struct mbuf *m)
void
i4b_Bcleanifq(struct ifqueue *ifq)
{
- struct mbuf *m;
int x = splimp();
- while(!IF_QEMPTY(ifq))
- {
- IF_DEQUEUE(ifq, m);
- i4b_Bfreembuf(m);
- }
-
+ IF_DRAIN(ifq);
splx(x);
}
diff --git a/sys/i4b/layer2/i4b_util.c b/sys/i4b/layer2/i4b_util.c
index 982760d..0569a84 100644
--- a/sys/i4b/layer2/i4b_util.c
+++ b/sys/i4b/layer2/i4b_util.c
@@ -182,7 +182,7 @@ i4b_invoke_retransmission(l2_softc_t *l2sc, int nr)
if((l2sc->ua_num != UA_EMPTY) && (l2sc->vs == l2sc->ua_num))
{
- if(IF_QFULL(&l2sc->i_queue))
+ if(_IF_QFULL(&l2sc->i_queue))
{
NDBGL2(L2_ERROR, "ERROR, I-queue full!");
}
diff --git a/sys/i4b/layer4/i4b_i4bdrv.c b/sys/i4b/layer4/i4b_i4bdrv.c
index d02a159..118926d 100644
--- a/sys/i4b/layer4/i4b_i4bdrv.c
+++ b/sys/i4b/layer4/i4b_i4bdrv.c
@@ -262,6 +262,7 @@ i4battach()
printf("i4b: ISDN call control device attached\n");
#endif
i4b_rdqueue.ifq_maxlen = IFQ_MAXLEN;
+ mtx_init(&i4b_rdqueue.ifq_mtx, "i4b_rdqueue", MTX_DEF);
#if defined(__FreeBSD__)
#if __FreeBSD__ == 3
@@ -328,17 +329,21 @@ i4bread(dev_t dev, struct uio *uio, int ioflag)
return(ENODEV);
x = splimp();
+ IF_LOCK(&i4b_rdqueue);
while(IF_QEMPTY(&i4b_rdqueue))
{
readflag = 1;
- error = tsleep((caddr_t) &i4b_rdqueue, (PZERO + 1) | PCATCH, "bird", 0);
+ error = msleep((caddr_t) &i4b_rdqueue, &i4b_rdqueue.ifq_mtx,
+ (PZERO + 1) | PCATCH, "bird", 0);
if (error != 0) {
- splx(x);
+ IF_UNLOCK(&i4b_rdqueue);
+ splx(x);
return error;
}
}
- IF_DEQUEUE(&i4b_rdqueue, m);
+ _IF_DEQUEUE(&i4b_rdqueue, m);
+ IF_UNLOCK(&i4b_rdqueue);
splx(x);
@@ -978,15 +983,17 @@ i4bputqueue(struct mbuf *m)
x = splimp();
- if(IF_QFULL(&i4b_rdqueue))
+ IF_LOCK(&i4b_rdqueue);
+ if(_IF_QFULL(&i4b_rdqueue))
{
struct mbuf *m1;
- IF_DEQUEUE(&i4b_rdqueue, m1);
+ _IF_DEQUEUE(&i4b_rdqueue, m1);
i4b_Dfreembuf(m1);
NDBGL4(L4_ERR, "ERROR, queue full, removing entry!");
}
- IF_ENQUEUE(&i4b_rdqueue, m);
+ _IF_ENQUEUE(&i4b_rdqueue, m);
+ IF_UNLOCK(&i4b_rdqueue);
splx(x);
@@ -1019,15 +1026,17 @@ i4bputqueue_hipri(struct mbuf *m)
x = splimp();
- if(IF_QFULL(&i4b_rdqueue))
+ IF_LOCK(&i4b_rdqueue);
+ if(_IF_QFULL(&i4b_rdqueue))
{
struct mbuf *m1;
- IF_DEQUEUE(&i4b_rdqueue, m1);
+ _IF_DEQUEUE(&i4b_rdqueue, m1);
i4b_Dfreembuf(m1);
NDBGL4(L4_ERR, "ERROR, queue full, removing entry!");
}
- IF_PREPEND(&i4b_rdqueue, m);
+ _IF_PREPEND(&i4b_rdqueue, m);
+ IF_UNLOCK(&i4b_rdqueue);
splx(x);
OpenPOWER on IntegriCloud