[BACK]Return to if_upl.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / usb

Annotation of src/sys/dev/usb/if_upl.c, Revision 1.19.6.5

1.19.6.5! skrll       1: /*     $NetBSD: if_upl.c,v 1.19.6.4 2004/12/18 09:32:21 skrll Exp $    */
1.1       augustss    2: /*
                      3:  * Copyright (c) 2000 The NetBSD Foundation, Inc.
                      4:  * All rights reserved.
                      5:  *
                      6:  * This code is derived from software contributed to The NetBSD Foundation
1.3       augustss    7:  * by Lennart Augustsson (lennart@augustsson.net) at
1.1       augustss    8:  * Carlstedt Research & Technology.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *        This product includes software developed by the NetBSD
                     21:  *        Foundation, Inc. and its contributors.
                     22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
                     38:
                     39: /*
                     40:  * Prolific PL2301/PL2302 driver
                     41:  */
1.16      lukem      42:
                     43: #include <sys/cdefs.h>
1.19.6.5! skrll      44: __KERNEL_RCSID(0, "$NetBSD: if_upl.c,v 1.19.6.4 2004/12/18 09:32:21 skrll Exp $");
1.1       augustss   45:
                     46: #include "opt_inet.h"
                     47: #include "opt_ns.h"
                     48: #include "bpfilter.h"
                     49: #include "rnd.h"
                     50:
                     51: #include <sys/param.h>
                     52: #include <sys/systm.h>
                     53: #include <sys/callout.h>
                     54: #include <sys/sockio.h>
                     55: #include <sys/mbuf.h>
                     56: #include <sys/malloc.h>
                     57: #include <sys/kernel.h>
                     58: #include <sys/socket.h>
                     59:
                     60: #include <sys/device.h>
                     61: #if NRND > 0
                     62: #include <sys/rnd.h>
                     63: #endif
                     64:
                     65: #include <net/if.h>
                     66: #include <net/if_types.h>
                     67: #include <net/if_dl.h>
                     68: #include <net/netisr.h>
                     69:
                     70: #define BPF_MTAP(ifp, m) bpf_mtap((ifp)->if_bpf, (m))
                     71:
                     72: #if NBPFILTER > 0
                     73: #include <net/bpf.h>
                     74: #endif
                     75:
                     76: #ifdef INET
1.19      augustss   77: #include <netinet/in.h>
                     78: #include <netinet/in_var.h>
1.1       augustss   79: #include <netinet/if_inarp.h>
                     80: #endif
                     81:
                     82: #ifdef NS
                     83: #include <netns/ns.h>
                     84: #include <netns/ns_if.h>
                     85: #endif
                     86:
                     87: #include <dev/usb/usb.h>
                     88: #include <dev/usb/usbdi.h>
                     89: #include <dev/usb/usbdi_util.h>
                     90: #include <dev/usb/usbdevs.h>
                     91:
                     92: /*
                     93:  * 7  6  5  4  3  2  1  0
1.6       augustss   94:  * tx rx 1  0
1.1       augustss   95:  * 1110 0000 rxdata
                     96:  * 1010 0000 idle
                     97:  * 0010 0000 tx over
                     98:  * 0110      tx over + rxd
                     99:  */
                    100:
                    101: #define UPL_RXDATA             0x40
                    102: #define UPL_TXOK               0x80
                    103:
                    104: #define UPL_INTR_PKTLEN                1
                    105:
                    106: #define UPL_CONFIG_NO          1
                    107: #define UPL_IFACE_IDX          0
                    108:
                    109: /***/
                    110:
                    111: #define UPL_INTR_INTERVAL      20
                    112:
                    113: #define UPL_BUFSZ              1024
                    114:
                    115: #define UPL_RX_FRAMES          1
                    116: #define UPL_TX_FRAMES          1
                    117:
                    118: #define UPL_RX_LIST_CNT                1
                    119: #define UPL_TX_LIST_CNT                1
                    120:
                    121: #define UPL_ENDPT_RX           0x0
                    122: #define UPL_ENDPT_TX           0x1
                    123: #define UPL_ENDPT_INTR         0x2
                    124: #define UPL_ENDPT_MAX          0x3
                    125:
                    126: struct upl_type {
                    127:        u_int16_t               upl_vid;
                    128:        u_int16_t               upl_did;
                    129: };
                    130:
                    131: struct upl_softc;
                    132:
                    133: struct upl_chain {
                    134:        struct upl_softc        *upl_sc;
                    135:        usbd_xfer_handle        upl_xfer;
                    136:        char                    *upl_buf;
                    137:        struct mbuf             *upl_mbuf;
                    138:        int                     upl_idx;
                    139: };
                    140:
                    141: struct upl_cdata {
                    142:        struct upl_chain        upl_tx_chain[UPL_TX_LIST_CNT];
                    143:        struct upl_chain        upl_rx_chain[UPL_RX_LIST_CNT];
                    144:        int                     upl_tx_prod;
                    145:        int                     upl_tx_cons;
                    146:        int                     upl_tx_cnt;
                    147:        int                     upl_rx_prod;
                    148: };
                    149:
                    150: struct upl_softc {
                    151:        USBBASEDEVICE           sc_dev;
                    152:
                    153:        struct ifnet            sc_if;
                    154: #if NRND > 0
                    155:        rndsource_element_t     sc_rnd_source;
                    156: #endif
                    157:
                    158:        usb_callout_t           sc_stat_ch;
                    159:
                    160:        usbd_device_handle      sc_udev;
                    161:        usbd_interface_handle   sc_iface;
                    162:        u_int16_t               sc_vendor;
                    163:        u_int16_t               sc_product;
                    164:        int                     sc_ed[UPL_ENDPT_MAX];
                    165:        usbd_pipe_handle        sc_ep[UPL_ENDPT_MAX];
                    166:        struct upl_cdata        sc_cdata;
                    167:
                    168:        uByte                   sc_ibuf;
                    169:
                    170:        char                    sc_dying;
                    171:        char                    sc_attached;
                    172:        u_int                   sc_rx_errs;
                    173:        struct timeval          sc_rx_notice;
                    174:        u_int                   sc_intr_errs;
                    175: };
                    176:
                    177: #ifdef UPL_DEBUG
                    178: #define DPRINTF(x)     if (upldebug) logprintf x
                    179: #define DPRINTFN(n,x)  if (upldebug >= (n)) logprintf x
                    180: int    upldebug = 0;
                    181: #else
                    182: #define DPRINTF(x)
                    183: #define DPRINTFN(n,x)
                    184: #endif
                    185:
                    186: /*
                    187:  * Various supported device vendors/products.
                    188:  */
                    189: Static struct upl_type sc_devs[] = {
                    190:        { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2301 },
                    191:        { USB_VENDOR_PROLIFIC, USB_PRODUCT_PROLIFIC_PL2302 },
                    192:        { 0, 0 }
                    193: };
                    194:
                    195: USB_DECLARE_DRIVER(upl);
                    196:
1.4       augustss  197: Static int upl_openpipes(struct upl_softc *);
                    198: Static int upl_tx_list_init(struct upl_softc *);
                    199: Static int upl_rx_list_init(struct upl_softc *);
                    200: Static int upl_newbuf(struct upl_softc *, struct upl_chain *, struct mbuf *);
                    201: Static int upl_send(struct upl_softc *, struct mbuf *, int);
                    202: Static void upl_intr(usbd_xfer_handle, usbd_private_handle, usbd_status);
                    203: Static void upl_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
                    204: Static void upl_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
                    205: Static void upl_start(struct ifnet *);
                    206: Static int upl_ioctl(struct ifnet *, u_long, caddr_t);
                    207: Static void upl_init(void *);
                    208: Static void upl_stop(struct upl_softc *);
                    209: Static void upl_watchdog(struct ifnet *);
                    210:
                    211: Static int upl_output(struct ifnet *, struct mbuf *, struct sockaddr *,
                    212:                      struct rtentry *);
                    213: Static void upl_input(struct ifnet *, struct mbuf *);
1.1       augustss  214:
                    215: /*
                    216:  * Probe for a Prolific chip.
                    217:  */
                    218: USB_MATCH(upl)
                    219: {
                    220:        USB_MATCH_START(upl, uaa);
                    221:        struct upl_type                 *t;
                    222:
                    223:        if (uaa->iface != NULL)
                    224:                return (UMATCH_NONE);
                    225:
                    226:        for (t = sc_devs; t->upl_vid != 0; t++)
                    227:                if (uaa->vendor == t->upl_vid && uaa->product == t->upl_did)
                    228:                        return (UMATCH_VENDOR_PRODUCT);
                    229:
                    230:        return (UMATCH_NONE);
                    231: }
                    232:
                    233: USB_ATTACH(upl)
                    234: {
                    235:        USB_ATTACH_START(upl, sc, uaa);
1.19.6.5! skrll     236:        char                    *devinfop;
1.1       augustss  237:        int                     s;
                    238:        usbd_device_handle      dev = uaa->device;
                    239:        usbd_interface_handle   iface;
                    240:        usbd_status             err;
                    241:        struct ifnet            *ifp;
                    242:        usb_interface_descriptor_t      *id;
                    243:        usb_endpoint_descriptor_t       *ed;
                    244:        int                     i;
                    245:
                    246:        DPRINTFN(5,(" : upl_attach: sc=%p, dev=%p", sc, dev));
                    247:
1.19.6.5! skrll     248:        devinfop = usbd_devinfo_alloc(dev, 0);
1.1       augustss  249:        USB_ATTACH_SETUP;
1.19.6.5! skrll     250:        printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfop);
        !           251:        usbd_devinfo_free(devinfop);
1.1       augustss  252:
1.9       augustss  253:        err = usbd_set_config_no(dev, UPL_CONFIG_NO, 1);
1.1       augustss  254:        if (err) {
                    255:                printf("%s: setting config no failed\n",
                    256:                    USBDEVNAME(sc->sc_dev));
                    257:                USB_ATTACH_ERROR_RETURN;
                    258:        }
                    259:
                    260:        sc->sc_udev = dev;
                    261:        sc->sc_product = uaa->product;
                    262:        sc->sc_vendor = uaa->vendor;
                    263:
                    264:        err = usbd_device2interface_handle(dev, UPL_IFACE_IDX, &iface);
                    265:        if (err) {
                    266:                printf("%s: getting interface handle failed\n",
                    267:                    USBDEVNAME(sc->sc_dev));
                    268:                USB_ATTACH_ERROR_RETURN;
                    269:        }
                    270:
                    271:        sc->sc_iface = iface;
                    272:        id = usbd_get_interface_descriptor(iface);
                    273:
                    274:        /* Find endpoints. */
                    275:        for (i = 0; i < id->bNumEndpoints; i++) {
                    276:                ed = usbd_interface2endpoint_descriptor(iface, i);
                    277:                if (ed == NULL) {
                    278:                        printf("%s: couldn't get ep %d\n",
                    279:                            USBDEVNAME(sc->sc_dev), i);
                    280:                        USB_ATTACH_ERROR_RETURN;
                    281:                }
                    282:                if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
                    283:                    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
                    284:                        sc->sc_ed[UPL_ENDPT_RX] = ed->bEndpointAddress;
                    285:                } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
                    286:                           UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
                    287:                        sc->sc_ed[UPL_ENDPT_TX] = ed->bEndpointAddress;
                    288:                } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
                    289:                           UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) {
                    290:                        sc->sc_ed[UPL_ENDPT_INTR] = ed->bEndpointAddress;
                    291:                }
                    292:        }
                    293:
                    294:        if (sc->sc_ed[UPL_ENDPT_RX] == 0 || sc->sc_ed[UPL_ENDPT_TX] == 0 ||
                    295:            sc->sc_ed[UPL_ENDPT_INTR] == 0) {
                    296:                printf("%s: missing endpoint\n", USBDEVNAME(sc->sc_dev));
                    297:                USB_ATTACH_ERROR_RETURN;
                    298:        }
                    299:
1.14      thorpej   300:        s = splnet();
1.1       augustss  301:
                    302:        /* Initialize interface info.*/
                    303:        ifp = &sc->sc_if;
                    304:        ifp->if_softc = sc;
                    305:        ifp->if_mtu = UPL_BUFSZ;
                    306:        ifp->if_flags = IFF_POINTOPOINT | IFF_NOARP | IFF_SIMPLEX;
                    307:        ifp->if_ioctl = upl_ioctl;
                    308:        ifp->if_start = upl_start;
                    309:        ifp->if_watchdog = upl_watchdog;
                    310:        strncpy(ifp->if_xname, USBDEVNAME(sc->sc_dev), IFNAMSIZ);
                    311:
                    312:        ifp->if_type = IFT_OTHER;
                    313:        ifp->if_addrlen = 0;
                    314:        ifp->if_hdrlen = 0;
                    315:        ifp->if_output = upl_output;
                    316:        ifp->if_input = upl_input;
                    317:        ifp->if_baudrate = 12000000;
1.12      augustss  318:        ifp->if_dlt = DLT_RAW;
1.17      itojun    319:        IFQ_SET_READY(&ifp->if_snd);
1.1       augustss  320:
                    321:        /* Attach the interface. */
                    322:        if_attach(ifp);
1.12      augustss  323:        if_alloc_sadl(ifp);
1.1       augustss  324:
                    325: #if NBPFILTER > 0
1.12      augustss  326:        bpfattach(ifp, DLT_RAW, 0);
1.1       augustss  327: #endif
                    328: #if NRND > 0
                    329:        rnd_attach_source(&sc->sc_rnd_source, USBDEVNAME(sc->sc_dev),
                    330:            RND_TYPE_NET, 0);
                    331: #endif
                    332:
                    333:        sc->sc_attached = 1;
                    334:        splx(s);
                    335:
                    336:        usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
                    337:            USBDEV(sc->sc_dev));
                    338:
                    339:        USB_ATTACH_SUCCESS_RETURN;
                    340: }
                    341:
                    342: USB_DETACH(upl)
                    343: {
                    344:        USB_DETACH_START(upl, sc);
                    345:        struct ifnet            *ifp = &sc->sc_if;
                    346:        int                     s;
                    347:
1.18      augustss  348:        DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1.1       augustss  349:
                    350:        s = splusb();
                    351:
                    352:        if (!sc->sc_attached) {
                    353:                /* Detached before attached finished, so just bail out. */
                    354:                splx(s);
                    355:                return (0);
                    356:        }
                    357:
                    358:        if (ifp->if_flags & IFF_RUNNING)
                    359:                upl_stop(sc);
                    360:
                    361: #if NRND > 0
                    362:        rnd_detach_source(&sc->sc_rnd_source);
                    363: #endif
                    364: #if NBPFILTER > 0
                    365:        bpfdetach(ifp);
                    366: #endif
                    367:
                    368:        if_detach(ifp);
                    369:
                    370: #ifdef DIAGNOSTIC
                    371:        if (sc->sc_ep[UPL_ENDPT_TX] != NULL ||
                    372:            sc->sc_ep[UPL_ENDPT_RX] != NULL ||
                    373:            sc->sc_ep[UPL_ENDPT_INTR] != NULL)
                    374:                printf("%s: detach has active endpoints\n",
                    375:                       USBDEVNAME(sc->sc_dev));
                    376: #endif
                    377:
                    378:        sc->sc_attached = 0;
                    379:        splx(s);
                    380:
                    381:        usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
                    382:            USBDEV(sc->sc_dev));
                    383:
                    384:        return (0);
                    385: }
                    386:
                    387: int
1.4       augustss  388: upl_activate(device_ptr_t self, enum devact act)
1.1       augustss  389: {
                    390:        struct upl_softc *sc = (struct upl_softc *)self;
                    391:
1.18      augustss  392:        DPRINTFN(2,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1.1       augustss  393:
                    394:        switch (act) {
                    395:        case DVACT_ACTIVATE:
                    396:                return (EOPNOTSUPP);
                    397:                break;
                    398:
                    399:        case DVACT_DEACTIVATE:
                    400:                /* Deactivate the interface. */
                    401:                if_deactivate(&sc->sc_if);
                    402:                sc->sc_dying = 1;
                    403:                break;
                    404:        }
                    405:        return (0);
                    406: }
                    407:
                    408: /*
                    409:  * Initialize an RX descriptor and attach an MBUF cluster.
                    410:  */
                    411: Static int
1.4       augustss  412: upl_newbuf(struct upl_softc *sc, struct upl_chain *c, struct mbuf *m)
1.1       augustss  413: {
                    414:        struct mbuf             *m_new = NULL;
                    415:
1.18      augustss  416:        DPRINTFN(8,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1.1       augustss  417:
                    418:        if (m == NULL) {
                    419:                MGETHDR(m_new, M_DONTWAIT, MT_DATA);
                    420:                if (m_new == NULL) {
                    421:                        printf("%s: no memory for rx list "
                    422:                            "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
                    423:                        return (ENOBUFS);
                    424:                }
                    425:
                    426:                MCLGET(m_new, M_DONTWAIT);
                    427:                if (!(m_new->m_flags & M_EXT)) {
                    428:                        printf("%s: no memory for rx list "
                    429:                            "-- packet dropped!\n", USBDEVNAME(sc->sc_dev));
                    430:                        m_freem(m_new);
                    431:                        return (ENOBUFS);
                    432:                }
                    433:                m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
                    434:        } else {
                    435:                m_new = m;
                    436:                m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
                    437:                m_new->m_data = m_new->m_ext.ext_buf;
                    438:        }
                    439:
                    440:        c->upl_mbuf = m_new;
                    441:
                    442:        return (0);
                    443: }
                    444:
                    445: Static int
1.4       augustss  446: upl_rx_list_init(struct upl_softc *sc)
1.1       augustss  447: {
                    448:        struct upl_cdata        *cd;
                    449:        struct upl_chain        *c;
                    450:        int                     i;
                    451:
1.18      augustss  452:        DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1.1       augustss  453:
                    454:        cd = &sc->sc_cdata;
                    455:        for (i = 0; i < UPL_RX_LIST_CNT; i++) {
                    456:                c = &cd->upl_rx_chain[i];
                    457:                c->upl_sc = sc;
                    458:                c->upl_idx = i;
                    459:                if (upl_newbuf(sc, c, NULL) == ENOBUFS)
                    460:                        return (ENOBUFS);
                    461:                if (c->upl_xfer == NULL) {
                    462:                        c->upl_xfer = usbd_alloc_xfer(sc->sc_udev);
                    463:                        if (c->upl_xfer == NULL)
                    464:                                return (ENOBUFS);
                    465:                        c->upl_buf = usbd_alloc_buffer(c->upl_xfer, UPL_BUFSZ);
                    466:                        if (c->upl_buf == NULL) {
                    467:                                usbd_free_xfer(c->upl_xfer);
                    468:                                return (ENOBUFS);
                    469:                        }
                    470:                }
                    471:        }
                    472:
                    473:        return (0);
                    474: }
                    475:
                    476: Static int
1.4       augustss  477: upl_tx_list_init(struct upl_softc *sc)
1.1       augustss  478: {
                    479:        struct upl_cdata        *cd;
                    480:        struct upl_chain        *c;
                    481:        int                     i;
                    482:
1.18      augustss  483:        DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev), __func__));
1.1       augustss  484:
                    485:        cd = &sc->sc_cdata;
                    486:        for (i = 0; i < UPL_TX_LIST_CNT; i++) {
                    487:                c = &cd->upl_tx_chain[i];
                    488:                c->upl_sc = sc;
                    489:                c->upl_idx = i;
                    490:                c->upl_mbuf = NULL;
                    491:                if (c->upl_xfer == NULL) {
                    492:                        c->upl_xfer = usbd_alloc_xfer(sc->sc_udev);
                    493:                        if (c->upl_xfer == NULL)
                    494:                                return (ENOBUFS);
                    495:                        c->upl_buf = usbd_alloc_buffer(c->upl_xfer, UPL_BUFSZ);
                    496:                        if (c->upl_buf == NULL) {
                    497:                                usbd_free_xfer(c->upl_xfer);
                    498:                                return (ENOBUFS);
                    499:                        }
                    500:                }
                    501:        }
                    502:
                    503:        return (0);
                    504: }
                    505:
                    506: /*
                    507:  * A frame has been uploaded: pass the resulting mbuf chain up to
                    508:  * the higher level protocols.
                    509:  */
                    510: Static void
1.4       augustss  511: upl_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1.1       augustss  512: {
                    513:        struct upl_chain        *c = priv;
                    514:        struct upl_softc        *sc = c->upl_sc;
                    515:        struct ifnet            *ifp = &sc->sc_if;
                    516:        struct mbuf             *m;
                    517:        int                     total_len = 0;
                    518:        int                     s;
                    519:
                    520:        if (sc->sc_dying)
                    521:                return;
                    522:
                    523:        if (!(ifp->if_flags & IFF_RUNNING))
                    524:                return;
                    525:
                    526:        if (status != USBD_NORMAL_COMPLETION) {
                    527:                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
                    528:                        return;
                    529:                sc->sc_rx_errs++;
                    530:                if (usbd_ratecheck(&sc->sc_rx_notice)) {
                    531:                        printf("%s: %u usb errors on rx: %s\n",
                    532:                            USBDEVNAME(sc->sc_dev), sc->sc_rx_errs,
                    533:                            usbd_errstr(status));
                    534:                        sc->sc_rx_errs = 0;
                    535:                }
                    536:                if (status == USBD_STALLED)
                    537:                        usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_RX]);
                    538:                goto done;
                    539:        }
                    540:
                    541:        usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
                    542:
                    543:        DPRINTFN(9,("%s: %s: enter status=%d length=%d\n",
1.18      augustss  544:                    USBDEVNAME(sc->sc_dev), __func__, status, total_len));
1.1       augustss  545:
                    546:        m = c->upl_mbuf;
                    547:        memcpy(mtod(c->upl_mbuf, char *), c->upl_buf, total_len);
                    548:
                    549:        ifp->if_ipackets++;
                    550:        m->m_pkthdr.len = m->m_len = total_len;
                    551:
                    552:        m->m_pkthdr.rcvif = ifp;
                    553:
1.14      thorpej   554:        s = splnet();
1.1       augustss  555:
                    556:        /* XXX ugly */
                    557:        if (upl_newbuf(sc, c, NULL) == ENOBUFS) {
                    558:                ifp->if_ierrors++;
                    559:                goto done1;
                    560:        }
                    561:
                    562: #if NBPFILTER > 0
                    563:        /*
                    564:         * Handle BPF listeners. Let the BPF user see the packet, but
                    565:         * don't pass it up to the ether_input() layer unless it's
                    566:         * a broadcast packet, multicast packet, matches our ethernet
                    567:         * address or the interface is in promiscuous mode.
                    568:         */
                    569:        if (ifp->if_bpf) {
                    570:                BPF_MTAP(ifp, m);
                    571:        }
                    572: #endif
                    573:
                    574:        DPRINTFN(10,("%s: %s: deliver %d\n", USBDEVNAME(sc->sc_dev),
1.18      augustss  575:                    __func__, m->m_len));
1.1       augustss  576:
                    577:        IF_INPUT(ifp, m);
                    578:
                    579:  done1:
                    580:        splx(s);
                    581:
                    582:  done:
                    583: #if 1
                    584:        /* Setup new transfer. */
                    585:        usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX],
                    586:            c, c->upl_buf, UPL_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
                    587:            USBD_NO_TIMEOUT, upl_rxeof);
                    588:        usbd_transfer(c->upl_xfer);
                    589:
                    590:        DPRINTFN(10,("%s: %s: start rx\n", USBDEVNAME(sc->sc_dev),
1.18      augustss  591:                    __func__));
1.1       augustss  592: #endif
                    593: }
                    594:
                    595: /*
                    596:  * A frame was downloaded to the chip. It's safe for us to clean up
                    597:  * the list buffers.
                    598:  */
                    599: Static void
1.4       augustss  600: upl_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1.1       augustss  601: {
                    602:        struct upl_chain        *c = priv;
                    603:        struct upl_softc        *sc = c->upl_sc;
                    604:        struct ifnet            *ifp = &sc->sc_if;
                    605:        int                     s;
                    606:
                    607:        if (sc->sc_dying)
                    608:                return;
                    609:
1.14      thorpej   610:        s = splnet();
1.1       augustss  611:
                    612:        DPRINTFN(10,("%s: %s: enter status=%d\n", USBDEVNAME(sc->sc_dev),
1.18      augustss  613:                    __func__, status));
1.1       augustss  614:
                    615:        ifp->if_timer = 0;
                    616:        ifp->if_flags &= ~IFF_OACTIVE;
                    617:
                    618:        if (status != USBD_NORMAL_COMPLETION) {
                    619:                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
                    620:                        splx(s);
                    621:                        return;
                    622:                }
                    623:                ifp->if_oerrors++;
                    624:                printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->sc_dev),
                    625:                    usbd_errstr(status));
                    626:                if (status == USBD_STALLED)
                    627:                        usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_TX]);
                    628:                splx(s);
                    629:                return;
                    630:        }
                    631:
                    632:        ifp->if_opackets++;
                    633:
                    634:        m_freem(c->upl_mbuf);
                    635:        c->upl_mbuf = NULL;
                    636:
1.17      itojun    637:        if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1.1       augustss  638:                upl_start(ifp);
                    639:
                    640:        splx(s);
                    641: }
                    642:
                    643: Static int
1.4       augustss  644: upl_send(struct upl_softc *sc, struct mbuf *m, int idx)
1.1       augustss  645: {
                    646:        int                     total_len;
                    647:        struct upl_chain        *c;
                    648:        usbd_status             err;
                    649:
                    650:        c = &sc->sc_cdata.upl_tx_chain[idx];
                    651:
                    652:        /*
                    653:         * Copy the mbuf data into a contiguous buffer, leaving two
                    654:         * bytes at the beginning to hold the frame length.
                    655:         */
                    656:        m_copydata(m, 0, m->m_pkthdr.len, c->upl_buf);
                    657:        c->upl_mbuf = m;
                    658:
                    659:        total_len = m->m_pkthdr.len;
                    660:
                    661:        DPRINTFN(10,("%s: %s: total_len=%d\n",
1.18      augustss  662:                     USBDEVNAME(sc->sc_dev), __func__, total_len));
1.1       augustss  663:
                    664:        usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_TX],
                    665:            c, c->upl_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT,
                    666:            upl_txeof);
                    667:
                    668:        /* Transmit */
                    669:        err = usbd_transfer(c->upl_xfer);
                    670:        if (err != USBD_IN_PROGRESS) {
                    671:                printf("%s: upl_send error=%s\n", USBDEVNAME(sc->sc_dev),
                    672:                       usbd_errstr(err));
                    673:                upl_stop(sc);
                    674:                return (EIO);
                    675:        }
                    676:
                    677:        sc->sc_cdata.upl_tx_cnt++;
                    678:
                    679:        return (0);
                    680: }
                    681:
                    682: Static void
1.4       augustss  683: upl_start(struct ifnet *ifp)
1.1       augustss  684: {
                    685:        struct upl_softc        *sc = ifp->if_softc;
                    686:        struct mbuf             *m_head = NULL;
                    687:
                    688:        if (sc->sc_dying)
                    689:                return;
                    690:
1.18      augustss  691:        DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
1.1       augustss  692:
                    693:        if (ifp->if_flags & IFF_OACTIVE)
                    694:                return;
                    695:
1.17      itojun    696:        IFQ_POLL(&ifp->if_snd, m_head);
1.1       augustss  697:        if (m_head == NULL)
                    698:                return;
                    699:
                    700:        if (upl_send(sc, m_head, 0)) {
                    701:                ifp->if_flags |= IFF_OACTIVE;
                    702:                return;
                    703:        }
                    704:
1.17      itojun    705:        IFQ_DEQUEUE(&ifp->if_snd, m_head);
                    706:
1.1       augustss  707: #if NBPFILTER > 0
                    708:        /*
                    709:         * If there's a BPF listener, bounce a copy of this frame
                    710:         * to him.
                    711:         */
                    712:        if (ifp->if_bpf)
                    713:                BPF_MTAP(ifp, m_head);
                    714: #endif
                    715:
                    716:        ifp->if_flags |= IFF_OACTIVE;
                    717:
                    718:        /*
                    719:         * Set a timeout in case the chip goes out to lunch.
                    720:         */
                    721:        ifp->if_timer = 5;
                    722: }
                    723:
                    724: Static void
1.4       augustss  725: upl_init(void *xsc)
1.1       augustss  726: {
                    727:        struct upl_softc        *sc = xsc;
                    728:        struct ifnet            *ifp = &sc->sc_if;
                    729:        int                     s;
                    730:
                    731:        if (sc->sc_dying)
                    732:                return;
                    733:
1.18      augustss  734:        DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
1.1       augustss  735:
                    736:        if (ifp->if_flags & IFF_RUNNING)
                    737:                return;
                    738:
1.14      thorpej   739:        s = splnet();
1.1       augustss  740:
                    741:        /* Init TX ring. */
                    742:        if (upl_tx_list_init(sc) == ENOBUFS) {
                    743:                printf("%s: tx list init failed\n", USBDEVNAME(sc->sc_dev));
                    744:                splx(s);
                    745:                return;
                    746:        }
                    747:
                    748:        /* Init RX ring. */
                    749:        if (upl_rx_list_init(sc) == ENOBUFS) {
                    750:                printf("%s: rx list init failed\n", USBDEVNAME(sc->sc_dev));
                    751:                splx(s);
                    752:                return;
                    753:        }
                    754:
                    755:        if (sc->sc_ep[UPL_ENDPT_RX] == NULL) {
                    756:                if (upl_openpipes(sc)) {
                    757:                        splx(s);
                    758:                        return;
                    759:                }
                    760:        }
                    761:
                    762:        ifp->if_flags |= IFF_RUNNING;
                    763:        ifp->if_flags &= ~IFF_OACTIVE;
                    764:
                    765:        splx(s);
                    766: }
                    767:
                    768: Static int
1.4       augustss  769: upl_openpipes(struct upl_softc *sc)
1.1       augustss  770: {
                    771:        struct upl_chain        *c;
                    772:        usbd_status             err;
                    773:        int                     i;
                    774:
                    775:        /* Open RX and TX pipes. */
                    776:        err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_RX],
                    777:            USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_RX]);
                    778:        if (err) {
                    779:                printf("%s: open rx pipe failed: %s\n",
                    780:                    USBDEVNAME(sc->sc_dev), usbd_errstr(err));
                    781:                return (EIO);
                    782:        }
                    783:        err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_TX],
                    784:            USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_TX]);
                    785:        if (err) {
                    786:                printf("%s: open tx pipe failed: %s\n",
                    787:                    USBDEVNAME(sc->sc_dev), usbd_errstr(err));
                    788:                return (EIO);
                    789:        }
                    790:        err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UPL_ENDPT_INTR],
                    791:            USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_INTR], sc,
1.19      augustss  792:            &sc->sc_ibuf, UPL_INTR_PKTLEN, upl_intr,
1.1       augustss  793:            UPL_INTR_INTERVAL);
                    794:        if (err) {
                    795:                printf("%s: open intr pipe failed: %s\n",
                    796:                    USBDEVNAME(sc->sc_dev), usbd_errstr(err));
                    797:                return (EIO);
                    798:        }
                    799:
                    800:
                    801: #if 1
                    802:        /* Start up the receive pipe. */
                    803:        for (i = 0; i < UPL_RX_LIST_CNT; i++) {
                    804:                c = &sc->sc_cdata.upl_rx_chain[i];
                    805:                usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX],
                    806:                    c, c->upl_buf, UPL_BUFSZ,
                    807:                    USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT,
                    808:                    upl_rxeof);
                    809:                usbd_transfer(c->upl_xfer);
                    810:        }
                    811: #endif
                    812:
                    813:        return (0);
                    814: }
                    815:
                    816: Static void
1.4       augustss  817: upl_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
1.1       augustss  818: {
                    819:        struct upl_softc        *sc = priv;
                    820:        struct ifnet            *ifp = &sc->sc_if;
                    821:        uByte                   stat;
                    822:
1.18      augustss  823:        DPRINTFN(15,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
1.1       augustss  824:
                    825:        if (sc->sc_dying)
                    826:                return;
                    827:
                    828:        if (!(ifp->if_flags & IFF_RUNNING))
                    829:                return;
                    830:
                    831:        if (status != USBD_NORMAL_COMPLETION) {
                    832:                if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
                    833:                        return;
                    834:                }
                    835:                sc->sc_intr_errs++;
                    836:                if (usbd_ratecheck(&sc->sc_rx_notice)) {
                    837:                        printf("%s: %u usb errors on intr: %s\n",
                    838:                            USBDEVNAME(sc->sc_dev), sc->sc_rx_errs,
                    839:                            usbd_errstr(status));
                    840:                        sc->sc_intr_errs = 0;
                    841:                }
                    842:                if (status == USBD_STALLED)
                    843:                        usbd_clear_endpoint_stall(sc->sc_ep[UPL_ENDPT_RX]);
                    844:                return;
                    845:        }
                    846:
                    847:        stat = sc->sc_ibuf;
                    848:
                    849:        if (stat == 0)
                    850:                return;
                    851:
                    852:        DPRINTFN(10,("%s: %s: stat=0x%02x\n", USBDEVNAME(sc->sc_dev),
1.18      augustss  853:                     __func__, stat));
1.1       augustss  854:
                    855: }
                    856:
                    857: Static int
1.4       augustss  858: upl_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
1.1       augustss  859: {
                    860:        struct upl_softc        *sc = ifp->if_softc;
                    861:        struct ifaddr           *ifa = (struct ifaddr *)data;
                    862:        struct ifreq            *ifr = (struct ifreq *)data;
                    863:        int                     s, error = 0;
                    864:
                    865:        if (sc->sc_dying)
                    866:                return (EIO);
                    867:
                    868:        DPRINTFN(5,("%s: %s: cmd=0x%08lx\n",
1.18      augustss  869:                    USBDEVNAME(sc->sc_dev), __func__, command));
1.1       augustss  870:
1.14      thorpej   871:        s = splnet();
1.1       augustss  872:
                    873:        switch(command) {
                    874:        case SIOCSIFADDR:
                    875:                ifp->if_flags |= IFF_UP;
                    876:                upl_init(sc);
                    877:
                    878:                switch (ifa->ifa_addr->sa_family) {
                    879: #ifdef INET
                    880:                case AF_INET:
                    881:                        break;
                    882: #endif /* INET */
                    883: #ifdef NS
                    884:                case AF_NS:
                    885:                    {
                    886:                        struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
                    887:
                    888:                        if (ns_nullhost(*ina))
                    889:                                ina->x_host = *(union ns_host *)
                    890:                                        LLADDR(ifp->if_sadl);
                    891:                        else
                    892:                                memcpy(LLADDR(ifp->if_sadl),
                    893:                                       ina->x_host.c_host,
                    894:                                       ifp->if_addrlen);
                    895:                        break;
                    896:                    }
                    897: #endif /* NS */
                    898:                }
                    899:                break;
                    900:
                    901:        case SIOCSIFMTU:
                    902:                if (ifr->ifr_mtu > UPL_BUFSZ)
                    903:                        error = EINVAL;
                    904:                else
                    905:                        ifp->if_mtu = ifr->ifr_mtu;
                    906:                break;
                    907:
                    908:        case SIOCSIFFLAGS:
                    909:                if (ifp->if_flags & IFF_UP) {
                    910:                        if (!(ifp->if_flags & IFF_RUNNING))
                    911:                                upl_init(sc);
                    912:                } else {
                    913:                        if (ifp->if_flags & IFF_RUNNING)
                    914:                                upl_stop(sc);
                    915:                }
                    916:                error = 0;
                    917:                break;
                    918:        default:
                    919:                error = EINVAL;
                    920:                break;
                    921:        }
                    922:
                    923:        splx(s);
                    924:
                    925:        return (error);
                    926: }
                    927:
                    928: Static void
1.4       augustss  929: upl_watchdog(struct ifnet *ifp)
1.1       augustss  930: {
                    931:        struct upl_softc        *sc = ifp->if_softc;
                    932:
1.18      augustss  933:        DPRINTFN(5,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
1.1       augustss  934:
                    935:        if (sc->sc_dying)
                    936:                return;
                    937:
                    938:        ifp->if_oerrors++;
                    939:        printf("%s: watchdog timeout\n", USBDEVNAME(sc->sc_dev));
                    940:
                    941:        upl_stop(sc);
                    942:        upl_init(sc);
                    943:
1.17      itojun    944:        if (IFQ_IS_EMPTY(&ifp->if_snd) == 0)
1.1       augustss  945:                upl_start(ifp);
                    946: }
                    947:
                    948: /*
                    949:  * Stop the adapter and free any mbufs allocated to the
                    950:  * RX and TX lists.
                    951:  */
                    952: Static void
1.4       augustss  953: upl_stop(struct upl_softc *sc)
1.1       augustss  954: {
                    955:        usbd_status             err;
                    956:        struct ifnet            *ifp;
                    957:        int                     i;
                    958:
1.18      augustss  959:        DPRINTFN(10,("%s: %s: enter\n", USBDEVNAME(sc->sc_dev),__func__));
1.1       augustss  960:
                    961:        ifp = &sc->sc_if;
                    962:        ifp->if_timer = 0;
                    963:
                    964:        /* Stop transfers. */
                    965:        if (sc->sc_ep[UPL_ENDPT_RX] != NULL) {
                    966:                err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_RX]);
                    967:                if (err) {
                    968:                        printf("%s: abort rx pipe failed: %s\n",
                    969:                        USBDEVNAME(sc->sc_dev), usbd_errstr(err));
                    970:                }
                    971:                err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_RX]);
                    972:                if (err) {
                    973:                        printf("%s: close rx pipe failed: %s\n",
                    974:                        USBDEVNAME(sc->sc_dev), usbd_errstr(err));
                    975:                }
                    976:                sc->sc_ep[UPL_ENDPT_RX] = NULL;
                    977:        }
                    978:
                    979:        if (sc->sc_ep[UPL_ENDPT_TX] != NULL) {
                    980:                err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_TX]);
                    981:                if (err) {
                    982:                        printf("%s: abort tx pipe failed: %s\n",
                    983:                        USBDEVNAME(sc->sc_dev), usbd_errstr(err));
                    984:                }
                    985:                err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_TX]);
                    986:                if (err) {
                    987:                        printf("%s: close tx pipe failed: %s\n",
                    988:                            USBDEVNAME(sc->sc_dev), usbd_errstr(err));
                    989:                }
                    990:                sc->sc_ep[UPL_ENDPT_TX] = NULL;
                    991:        }
                    992:
                    993:        if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) {
                    994:                err = usbd_abort_pipe(sc->sc_ep[UPL_ENDPT_INTR]);
                    995:                if (err) {
                    996:                        printf("%s: abort intr pipe failed: %s\n",
                    997:                        USBDEVNAME(sc->sc_dev), usbd_errstr(err));
                    998:                }
                    999:                err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_INTR]);
                   1000:                if (err) {
                   1001:                        printf("%s: close intr pipe failed: %s\n",
                   1002:                            USBDEVNAME(sc->sc_dev), usbd_errstr(err));
                   1003:                }
                   1004:                sc->sc_ep[UPL_ENDPT_INTR] = NULL;
                   1005:        }
                   1006:
                   1007:        /* Free RX resources. */
                   1008:        for (i = 0; i < UPL_RX_LIST_CNT; i++) {
                   1009:                if (sc->sc_cdata.upl_rx_chain[i].upl_mbuf != NULL) {
                   1010:                        m_freem(sc->sc_cdata.upl_rx_chain[i].upl_mbuf);
                   1011:                        sc->sc_cdata.upl_rx_chain[i].upl_mbuf = NULL;
                   1012:                }
                   1013:                if (sc->sc_cdata.upl_rx_chain[i].upl_xfer != NULL) {
                   1014:                        usbd_free_xfer(sc->sc_cdata.upl_rx_chain[i].upl_xfer);
                   1015:                        sc->sc_cdata.upl_rx_chain[i].upl_xfer = NULL;
                   1016:                }
                   1017:        }
                   1018:
                   1019:        /* Free TX resources. */
                   1020:        for (i = 0; i < UPL_TX_LIST_CNT; i++) {
                   1021:                if (sc->sc_cdata.upl_tx_chain[i].upl_mbuf != NULL) {
                   1022:                        m_freem(sc->sc_cdata.upl_tx_chain[i].upl_mbuf);
                   1023:                        sc->sc_cdata.upl_tx_chain[i].upl_mbuf = NULL;
                   1024:                }
                   1025:                if (sc->sc_cdata.upl_tx_chain[i].upl_xfer != NULL) {
                   1026:                        usbd_free_xfer(sc->sc_cdata.upl_tx_chain[i].upl_xfer);
                   1027:                        sc->sc_cdata.upl_tx_chain[i].upl_xfer = NULL;
                   1028:                }
                   1029:        }
                   1030:
                   1031:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   1032: }
                   1033:
                   1034: Static int
1.4       augustss 1035: upl_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
                   1036:           struct rtentry *rt0)
1.1       augustss 1037: {
1.17      itojun   1038:        int s, len, error;
                   1039:        ALTQ_DECL(struct altq_pktattr pktattr;)
1.1       augustss 1040:
                   1041:        DPRINTFN(10,("%s: %s: enter\n",
                   1042:                     USBDEVNAME(((struct upl_softc *)ifp->if_softc)->sc_dev),
1.18      augustss 1043:                     __func__));
1.1       augustss 1044:
1.17      itojun   1045:        /*
                   1046:         * if the queueing discipline needs packet classification,
                   1047:         * do it now.
                   1048:         */
                   1049:        IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family, &pktattr);
                   1050:
                   1051:        len = m->m_pkthdr.len;
1.14      thorpej  1052:        s = splnet();
1.1       augustss 1053:        /*
                   1054:         * Queue message on interface, and start output if interface
                   1055:         * not yet active.
                   1056:         */
1.17      itojun   1057:        IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error);
                   1058:        if (error) {
                   1059:                /* mbuf is already freed */
1.1       augustss 1060:                splx(s);
1.17      itojun   1061:                return (error);
1.1       augustss 1062:        }
1.17      itojun   1063:        ifp->if_obytes += len;
1.1       augustss 1064:        if ((ifp->if_flags & IFF_OACTIVE) == 0)
                   1065:                (*ifp->if_start)(ifp);
                   1066:        splx(s);
                   1067:
                   1068:        return (0);
                   1069: }
                   1070:
                   1071: Static void
1.4       augustss 1072: upl_input(struct ifnet *ifp, struct mbuf *m)
1.1       augustss 1073: {
1.19.6.4  skrll    1074: #ifdef INET
1.1       augustss 1075:        struct ifqueue *inq;
                   1076:        int s;
                   1077:
                   1078:        /* XXX Assume all traffic is IP */
                   1079:
                   1080:        schednetisr(NETISR_IP);
                   1081:        inq = &ipintrq;
                   1082:
1.14      thorpej  1083:        s = splnet();
1.1       augustss 1084:        if (IF_QFULL(inq)) {
                   1085:                IF_DROP(inq);
                   1086:                splx(s);
1.7       augustss 1087: #if 0
                   1088:                if (sc->sc_flags & SC_DEBUG)
                   1089:                        printf("%s: input queue full\n", ifp->if_xname);
                   1090: #endif
1.1       augustss 1091:                ifp->if_iqdrops++;
                   1092:                return;
                   1093:        }
                   1094:        IF_ENQUEUE(inq, m);
                   1095:        splx(s);
1.19.6.4  skrll    1096: #endif
1.1       augustss 1097:        ifp->if_ipackets++;
                   1098:        ifp->if_ibytes += m->m_len;
                   1099: }

CVSweb <webmaster@jp.NetBSD.org>