/*---------------------------------------------------------------------------* * close tel device *---------------------------------------------------------------------------*/ PDEVSTATIC int i4btelclose(dev_t dev, int flag, int fmt, struct proc *p) { int unit = minor(dev); tel_sc_t *sc; int error = 0; if(unit > NI4BTEL) return(ENXIO); sc = &tel_sc[unit]; if(sc->isdn_linktab != NULL && sc->isdn_linktab->tx_queue != NULL) { while(!(IF_QEMPTY(sc->isdn_linktab->tx_queue))) { sc->devstate |= ST_WRWAITEMPTY; if((error = tsleep((caddr_t) &sc->isdn_linktab->tx_queue, TTIPRI | PCATCH, "wtcl", 0)) != 0) { break; } } sc->devstate &= ~ST_WRWAITEMPTY; } sc->devstate &= ~ST_ISOPEN; return(error); }
/*---------------------------------------------------------------------------* * i4bread - device driver read routine *---------------------------------------------------------------------------*/ PDEVSTATIC int i4bread(dev_t dev, struct uio *uio, int ioflag) { struct mbuf *m; int x; int error = 0; if(minor(dev)) return(ENODEV); while(IF_QEMPTY(&i4b_rdqueue)) { x = splimp(); readflag = 1; splx(x); tsleep((caddr_t) &i4b_rdqueue, (PZERO + 1) | PCATCH, "bird", 0); } x = splimp(); IF_DEQUEUE(&i4b_rdqueue, m); splx(x); if(m && m->m_len) error = uiomove(m->m_data, m->m_len, uio); else error = EIO; if(m) i4b_Dfreembuf(m); return(error); }
/*---------------------------------------------------------------------------* * i4bread - device driver read routine *---------------------------------------------------------------------------*/ PDEVSTATIC int isdnread(dev_t dev, struct uio *uio, int ioflag) { struct mbuf *m; int x; int error = 0; if(minor(dev)) return(ENODEV); x = splnet(); while(IF_QEMPTY(&i4b_rdqueue)) { readflag = 1; error = tsleep((void *) &i4b_rdqueue, (PZERO + 1) | PCATCH, "bird", 0); if (error != 0) { splx(x); return error; } } IF_DEQUEUE(&i4b_rdqueue, m); splx(x); if(m && m->m_len) error = uiomove(m->m_data, m->m_len, uio); else error = EIO; if(m) i4b_Dfreembuf(m); return(error); }
/*---------------------------------------------------------------------------* * i4bpoll - device driver poll routine *---------------------------------------------------------------------------*/ PDEVSTATIC int i4bpoll(dev_t dev, int events, struct proc *p) { int x; if(minor(dev)) return(ENODEV); if((events & POLLIN) || (events & POLLRDNORM)) { if(!IF_QEMPTY(&i4b_rdqueue)) return(1); x = splimp(); selrecord(p, &select_rd_info); selflag = 1; splx(x); return(0); } else if((events & POLLOUT) || (events & POLLWRNORM)) { return(1); } return(0); }
/* * Software interrupt routine, called at spl[soft]net. */ static void pppintr(netmsg_t msg) { struct mbuf *m; struct ppp_softc *sc; int i; /* * Packets are never sent to this netisr so the message must always * be replied. Interlock processing and notification by replying * the message first. */ lwkt_replymsg(&msg->lmsg, 0); get_mplock(); sc = ppp_softc; for (i = 0; i < NPPP; ++i, ++sc) { ifnet_serialize_all(&sc->sc_if); if (!(sc->sc_flags & SC_TBUSY) && (!ifq_is_empty(&sc->sc_if.if_snd) || !IF_QEMPTY(&sc->sc_fastq))) { sc->sc_flags |= SC_TBUSY; (*sc->sc_start)(sc); } for (;;) { IF_DEQUEUE(&sc->sc_rawq, m); if (m == NULL) break; ppp_inproc(sc, m); } ifnet_deserialize_all(&sc->sc_if); } rel_mplock(); }
/*---------------------------------------------------------------------------* * i4bread - device driver read routine *---------------------------------------------------------------------------*/ PDEVSTATIC int i4bread(struct dev_read_args *ap) { cdev_t dev = ap->a_head.a_dev; struct mbuf *m; int error = 0; if (minor(dev)) return(ENODEV); crit_enter(); while(IF_QEMPTY(&i4b_rdqueue)) { readflag = 1; error = tsleep((caddr_t) &i4b_rdqueue, PCATCH, "bird", 0); if (error != 0) { crit_exit(); return error; } } IF_DEQUEUE(&i4b_rdqueue, m); crit_exit(); if(m && m->m_len) error = uiomove(m->m_data, m->m_len, ap->a_uio); else error = EIO; if(m) i4b_Dfreembuf(m); return(error); }
int capi_start_tx(capi_softc_t *sc, int chan) { struct mbuf *m_b3; int sent = 0; _IF_DEQUEUE(&sc->sc_bchan[chan].tx_queue, m_b3); while (m_b3) { struct mbuf *m = m_b3->m_next; sc->sc_bchan[chan].txcount += m_b3->m_len; capi_data_b3_req(sc, chan, m_b3); sent++; m_b3 = m; } if (sc->sc_bchan[chan].capi_drvr_linktab) { /* Notify i4b driver of activity, and if the queue is drained. */ if (sent) (*sc->sc_bchan[chan].capi_drvr_linktab->bch_activity)( sc->sc_bchan[chan].capi_drvr_linktab->unit, ACT_TX); if (IF_QEMPTY(&sc->sc_bchan[chan].tx_queue)) (*sc->sc_bchan[chan].capi_drvr_linktab->bch_tx_queue_empty)( sc->sc_bchan[chan].capi_drvr_linktab->unit); } return sent; }
/*---------------------------------------------------------------------------* * i4bselect - device driver select routine *---------------------------------------------------------------------------*/ PDEVSTATIC int i4bselect(dev_t dev, int rw, struct proc *p) { int x; if(minor(dev)) return(ENODEV); switch(rw) { case FREAD: if(!IF_QEMPTY(&i4b_rdqueue)) return(1); x = splimp(); selrecord(p, &select_rd_info); selflag = 1; splx(x); return(0); break; case FWRITE: return(1); break; } return(0); }
void ubt_xmit_acl_start(struct ubt_softc *sc) { struct mbuf *m; usbd_status status; int len; if (sc->sc_dying) return; if (IF_QEMPTY(&sc->sc_aclwr_queue)) return; sc->sc_refcnt++; sc->sc_aclwr_busy = 1; IF_DEQUEUE(&sc->sc_aclwr_queue, m); KKASSERT(m != NULL); DPRINTFN(15, "%s: xmit ACL packet (%d bytes)\n", device_get_nameunit(sc->sc_dev), m->m_pkthdr.len); len = m->m_pkthdr.len - 1; if (len > UBT_BUFSIZ_ACL) { DPRINTF("%s: truncating ACL packet (%d => %d)!\n", device_get_nameunit(sc->sc_dev), len, UBT_BUFSIZ_ACL); len = UBT_BUFSIZ_ACL; } m_copydata(m, 1, len, sc->sc_aclwr_buf); m_freem(m); sc->sc_stats.acl_tx++; sc->sc_stats.byte_tx += len; usbd_setup_xfer(sc->sc_aclwr_xfer, sc->sc_aclwr_pipe, sc, sc->sc_aclwr_buf, len, USBD_NO_COPY | USBD_FORCE_SHORT_XFER, UBT_ACL_TIMEOUT, ubt_xmit_acl_complete); status = usbd_transfer(sc->sc_aclwr_xfer); KKASSERT(status != USBD_NORMAL_COMPLETION); if (status != USBD_IN_PROGRESS) { DPRINTF("usbd_transfer status=%s (%d)\n", usbd_errstr(status), status); sc->sc_refcnt--; sc->sc_aclwr_busy = 0; } }
void ubt_xmit_cmd_start(struct ubt_softc *sc) { usb_device_request_t req; usbd_status status; struct mbuf *m; int len; if (sc->sc_dying) return; if (IF_QEMPTY(&sc->sc_cmd_queue)) return; IF_DEQUEUE(&sc->sc_cmd_queue, m); KKASSERT(m != NULL); DPRINTFN(15, " %s: xmit CMD packet (%d bytes)\n", device_get_nameunit(sc->sc_dev), m->m_pkthdr.len); sc->sc_refcnt++; sc->sc_cmd_busy = 1; len = m->m_pkthdr.len - 1; m_copydata(m, 1, len, sc->sc_cmd_buf); m_freem(m); memset(&req, 0, sizeof(req)); req.bmRequestType = UT_WRITE_CLASS_DEVICE; USETW(req.wLength, len); usbd_setup_default_xfer(sc->sc_cmd_xfer, sc->sc_udev, sc, UBT_CMD_TIMEOUT, &req, sc->sc_cmd_buf, len, USBD_NO_COPY | USBD_FORCE_SHORT_XFER, ubt_xmit_cmd_complete); status = usbd_transfer(sc->sc_cmd_xfer); KKASSERT(status != USBD_NORMAL_COMPLETION); if (status != USBD_IN_PROGRESS) { DPRINTF("usbd_transfer status=%s (%d)\n", usbd_errstr(status), status); sc->sc_refcnt--; sc->sc_cmd_busy = 0; } }
PDEVSTATIC int i4bkqfilt_read(struct knote *kn, long hint) { int ready = 0; crit_enter(); if (!IF_QEMPTY(&i4b_rdqueue)) ready = 1; crit_exit(); return (ready); }
/*---------------------------------------------------------------------------* * device driver select *---------------------------------------------------------------------------*/ PDEVSTATIC int isdnbchanselect(dev_t dev, int rw, struct lwp *l) { int unit = minor(dev); struct rbch_softc *sc = &rbch_softc[unit]; int s; s = splhigh(); if(!(sc->sc_devstate & ST_ISOPEN)) { splx(s); NDBGL4(L4_RBCHDBG, "(minor=%d) not open anymore", unit); return(1); } if(sc->sc_devstate & ST_CONNECTED) { struct ifqueue *iqp; switch(rw) { case FREAD: if(sc->sc_bprot == BPROT_RHDLC) iqp = &sc->sc_hdlcq; else iqp = isdn_linktab[unit]->rx_queue; if(!IF_QEMPTY(iqp)) { splx(s); return(1); } break; case FWRITE: if(!IF_QFULL(isdn_linktab[unit]->rx_queue)) { splx(s); return(1); } break; default: splx(s); return 0; } } selrecord(l, &sc->selp); splx(s); return(0); }
/*---------------------------------------------------------------------------* * device driver poll *---------------------------------------------------------------------------*/ PDEVSTATIC int isdnbchanpoll(dev_t dev, int events, struct lwp *l) { int revents = 0; /* Events we found */ int s; int unit = minor(dev); struct rbch_softc *sc = &rbch_softc[unit]; /* We can't check for anything but IN or OUT */ s = splhigh(); if(!(sc->sc_devstate & ST_ISOPEN)) { splx(s); return(POLLNVAL); } /* * Writes are OK if we are connected and the * transmit queue can take them */ if((events & (POLLOUT|POLLWRNORM)) && (sc->sc_devstate & ST_CONNECTED) && !IF_QFULL(sc->sc_ilt->tx_queue)) { revents |= (events & (POLLOUT|POLLWRNORM)); } /* ... while reads are OK if we have any data */ if((events & (POLLIN|POLLRDNORM)) && (sc->sc_devstate & ST_CONNECTED)) { struct ifqueue *iqp; if(sc->sc_bprot == BPROT_RHDLC) iqp = &sc->sc_hdlcq; else iqp = sc->sc_ilt->rx_queue; if(!IF_QEMPTY(iqp)) revents |= (events & (POLLIN|POLLRDNORM)); } if(revents == 0) selrecord(l, &sc->selp); splx(s); return(revents); }
static int filt_i4bread(struct knote *kn, long hint) { struct mbuf *m; if (IF_QEMPTY(&i4b_rdqueue)) return (0); IF_POLL(&i4b_rdqueue, m); kn->kn_data = m->m_len; return (1); }
/*---------------------------------------------------------------------------* * read from trace device *---------------------------------------------------------------------------*/ static int i4btrcread(dev_t dev, struct uio * uio, int ioflag) { struct mbuf *m; int x; int error = 0; int unit = minor(dev); if(!(device_state[unit] & ST_ISOPEN)) return(EIO); 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 = 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_UNLOCK(&trace_queue[unit]); if(m && m->m_len) error = uiomove(m->m_data, m->m_len, uio); else error = EIO; if(m) i4b_Bfreembuf(m); splx(x); return(error); }
static int filt_i4brbchread(struct knote *kn, long hint) { struct rbch_softc *sc = kn->kn_hook; struct ifqueue *iqp; if ((sc->sc_devstate & ST_CONNECTED) == 0) return (0); if (sc->sc_bprot == BPROT_RHDLC) iqp = &sc->sc_hdlcq; else iqp = sc->sc_ilt->rx_queue; if (IF_QEMPTY(iqp)) return (0); kn->kn_data = 0; /* XXXLUKEM (thorpej): what to put here? */ return (1); }
/*---------------------------------------------------------------------------* * read from trace device *---------------------------------------------------------------------------*/ PDEVSTATIC int isdntrcread(dev_t dev, struct uio * uio, int ioflag) { struct mbuf *m; int x; int error = 0; int unit = minor(dev); if(!(device_state[unit] & ST_ISOPEN)) return(EIO); x = splnet(); while(IF_QEMPTY(&trace_queue[unit]) && (device_state[unit] & ST_ISOPEN)) { device_state[unit] |= ST_WAITDATA; if((error = tsleep((void *) &trace_queue[unit], TTIPRI | PCATCH, "bitrc", 0 )) != 0) { device_state[unit] &= ~ST_WAITDATA; splx(x); return(error); } } IF_DEQUEUE(&trace_queue[unit], m); if(m && m->m_len) error = uiomove(m->m_data, m->m_len, uio); else error = EIO; if(m) i4b_Bfreembuf(m); splx(x); return(error); }
i4btelioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) #endif { int error = 0; struct mbuf *m; int s; tel_sc_t *sc = &tel_sc[minor(dev)]; switch(cmd) { case I4B_TEL_GETAUDIOFMT: *(int *)data = sc->audiofmt; break; case I4B_TEL_SETAUDIOFMT: sc->audiofmt = *(int *)data; break; case I4B_TEL_EMPTYINPUTQUEUE: s = splimp(); while((sc->devstate & ST_CONNECTED) && (sc->devstate & ST_ISOPEN) && !IF_QEMPTY(sc->isdn_linktab->rx_queue)) { IF_DEQUEUE(sc->isdn_linktab->rx_queue, m); if(m) i4b_Bfreembuf(m); } splx(s); break; default: error = ENOTTY; break; } return(error); }
/*---------------------------------------------------------------------------* * read from tel device *---------------------------------------------------------------------------*/ PDEVSTATIC int i4btelread(dev_t dev, struct uio *uio, int ioflag) { struct mbuf *m; int s; int error = 0; tel_sc_t *sc = &tel_sc[minor(dev)]; if(!(sc->devstate & ST_CONNECTED)) return(EIO); if(!(sc->devstate & ST_ISOPEN)) return(EIO); #ifdef NOTDEF while(!(sc->devstate & ST_CONNECTED)) { if((error = tsleep((caddr_t) &sc->devstate, TTIPRI | PCATCH, "rrtel", 0 )) != 0) { return(error); } } #endif while(IF_QEMPTY(sc->isdn_linktab->rx_queue) && (sc->devstate & ST_ISOPEN) && (sc->devstate & ST_CONNECTED)) { sc->devstate |= ST_RDWAITDATA; if((error = tsleep((caddr_t) &sc->isdn_linktab->rx_queue, TTIPRI | PCATCH, "rtel", 0 )) != 0) { sc->devstate &= ~ST_RDWAITDATA; return(error); } } if(!(sc->devstate & ST_ISOPEN)) { return(EIO); } if(!(sc->devstate & ST_CONNECTED)) { return(EIO); } s = splimp(); IF_DEQUEUE(sc->isdn_linktab->rx_queue, m); if(m && m->m_len) { if(sc->audiofmt == CVT_ALAW2ULAW) { int i; for(i = 0; i < m->m_len; i++) m->m_data[i] = alaw_ulaw[(int)m->m_data[i]]; } error = uiomove(m->m_data, m->m_len, uio); } else { error = EIO; } if(m) i4b_Bfreembuf(m); splx(s); return(error); }
/*---------------------------------------------------------------------------* * read from rbch device *---------------------------------------------------------------------------*/ PDEVSTATIC int isdnbchanread(dev_t dev, struct uio *uio, int ioflag) { struct mbuf *m; int error = 0; int unit = minor(dev); struct ifqueue *iqp; struct rbch_softc *sc = &rbch_softc[unit]; int s; NDBGL4(L4_RBCHDBG, "unit %d, enter read", unit); s = splnet(); if(!(sc->sc_devstate & ST_ISOPEN)) { splx(s); NDBGL4(L4_RBCHDBG, "unit %d, read while not open", unit); return(EIO); } if((sc->sc_devstate & ST_NOBLOCK)) { if(!(sc->sc_devstate & ST_CONNECTED)) { splx(s); return(EWOULDBLOCK); } if(sc->sc_bprot == BPROT_RHDLC) iqp = &sc->sc_hdlcq; else iqp = sc->sc_ilt->rx_queue; if(IF_QEMPTY(iqp) && (sc->sc_devstate & ST_ISOPEN)) { splx(s); return(EWOULDBLOCK); } } else { while(!(sc->sc_devstate & ST_CONNECTED)) { NDBGL4(L4_RBCHDBG, "unit %d, wait read init", unit); if((error = tsleep((void *) &rbch_softc[unit], TTIPRI | PCATCH, "rrrbch", 0 )) != 0) { splx(s); NDBGL4(L4_RBCHDBG, "unit %d, error %d tsleep", unit, error); return(error); } } if(sc->sc_bprot == BPROT_RHDLC) iqp = &sc->sc_hdlcq; else iqp = sc->sc_ilt->rx_queue; while(IF_QEMPTY(iqp) && (sc->sc_devstate & ST_ISOPEN)) { sc->sc_devstate |= ST_RDWAITDATA; NDBGL4(L4_RBCHDBG, "unit %d, wait read data", unit); if((error = tsleep((void *) &sc->sc_ilt->rx_queue, TTIPRI | PCATCH, "rrbch", 0 )) != 0) { splx(s); NDBGL4(L4_RBCHDBG, "unit %d, error %d tsleep read", unit, error); sc->sc_devstate &= ~ST_RDWAITDATA; return(error); } else if (!(sc->sc_devstate & ST_CONNECTED)) { splx(s); return 0; } } } IF_DEQUEUE(iqp, m); NDBGL4(L4_RBCHDBG, "unit %d, read %d bytes", unit, m->m_len); if(m && m->m_len) { error = uiomove(m->m_data, m->m_len, uio); } else { NDBGL4(L4_RBCHDBG, "unit %d, error %d uiomove", unit, error); error = EIO; } if(m) i4b_Bfreembuf(m); splx(s); return(error); }