Date: Fri, 6 Feb 2009 20:41:30 +0000 (UTC) From: Andrew Thompson <thompsa@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r188246 - user/thompsa/usb/sys/dev/usb2/wlan Message-ID: <200902062041.n16KfUSP070987@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: thompsa Date: Fri Feb 6 20:41:30 2009 New Revision: 188246 URL: http://svn.freebsd.org/changeset/base/188246 Log: - Fix up the intrrupt read to copy the data from the right buffer. - Change rx handling slightly to make it a bit more robust. Modified: user/thompsa/usb/sys/dev/usb2/wlan/if_zyd2.c user/thompsa/usb/sys/dev/usb2/wlan/if_zydreg.h Modified: user/thompsa/usb/sys/dev/usb2/wlan/if_zyd2.c ============================================================================== --- user/thompsa/usb/sys/dev/usb2/wlan/if_zyd2.c Fri Feb 6 20:09:14 2009 (r188245) +++ user/thompsa/usb/sys/dev/usb2/wlan/if_zyd2.c Fri Feb 6 20:41:30 2009 (r188246) @@ -368,7 +368,7 @@ zyd_attach(device_t dev) sc->sc_dev = dev; sc->sc_udev = uaa->device; sc->sc_macrev = USB_GET_DRIVER_INFO(uaa); -#ifdef ZYD_DEBUG +#ifdef USB_DEBUG sc->sc_debug = zyd_debug; #endif mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), @@ -757,10 +757,16 @@ zyd_intr_read_callback(struct usb2_xfer } if (i != rqp->olen) continue; + /* copy answer into caller-supplied buffer */ + bcopy(cmd->data, rqp->odata, + sizeof(struct zyd_pair) * rqp->olen); wakeup(rqp); /* wakeup caller */ return; } - return; /* unexpected IORD notification */ + device_printf(sc->sc_dev, + "unexpected IORD notification %*D\n", + datalen, cmd->data, ":"); + break; } default: device_printf(sc->sc_dev, "unknown notification %x\n", @@ -846,8 +852,6 @@ zyd_intr_write_callback(struct usb2_xfer sc->sc_flags |= ZYD_FLAG_INTR_WRITE_STALL; usb2_transfer_start(sc->sc_xfer[ZYD_INTR_CS_WR]); } - rqp = xfer->priv_fifo; - wakeup(rqp); /* wakeup caller */ break; } } @@ -883,10 +887,12 @@ zyd_cmd(struct zyd_softc *sc, uint16_t c rq.cmd = &cmd; rq.idata = idata; + rq.odata = odata; rq.ilen = sizeof(uint16_t) + ilen; rq.olen = olen / sizeof(struct zyd_pair); rq.flags = flags; STAILQ_INSERT_TAIL(&sc->sc_rqh, &rq, rq); + usb2_transfer_start(sc->sc_xfer[ZYD_INTR_DT_RD]); usb2_transfer_start(sc->sc_xfer[ZYD_INTR_DT_WR]); /* wait at most one second for command reply */ @@ -894,7 +900,6 @@ zyd_cmd(struct zyd_softc *sc, uint16_t c if (error) device_printf(sc->sc_dev, "command timeout\n"); STAILQ_REMOVE(&sc->sc_rqh, &rq, zyd_rq, rq); - bcopy(cmd.data, odata, olen); /* copy answer into caller buffer */ return (error); } @@ -2246,7 +2251,12 @@ zyd_rx_data(struct usb2_xfer *xfer, int sizeof(struct zyd_rx_stat) - IEEE80211_CRC_LEN; /* allocate a mbuf to store the frame */ - if (rlen > MHLEN) + if (rlen > MCLBYTES) { + DPRINTF(sc, ZYD_DEBUG_RECV, "%s: frame too long (length=%d)\n", + device_get_nameunit(sc->sc_dev), rlen); + ifp->if_ierrors++; + return; + } else if (rlen > MHLEN) m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); else m = m_gethdr(M_DONTWAIT, MT_DATA); @@ -2258,7 +2268,8 @@ zyd_rx_data(struct usb2_xfer *xfer, int } m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = rlen; - usb2_copy_out(xfer->frbuffers, offset + sizeof(plcp), m->m_data, rlen); + usb2_copy_out(xfer->frbuffers, offset + sizeof(plcp), + mtod(m, uint8_t *), rlen); if (bpf_peers_present(ifp->if_bpf)) { struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap; @@ -2281,6 +2292,7 @@ zyd_rx_data(struct usb2_xfer *xfer, int sc->sc_rx_data[idx].rssi = rssi; sc->sc_rx_data[idx].m = m; + sc->sc_rx_count++; } static void @@ -2295,16 +2307,11 @@ zyd_bulk_read_callback(struct usb2_xfer uint32_t offset; uint8_t rssi; int8_t nf; - int i, rxcount; + int i; - rxcount = 0; + sc->sc_rx_count = 0; switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: - if (xfer->actlen < MAX(sizeof(desc), ZYD_MIN_FRAGSZ)) { - DPRINTF(sc, ZYD_DEBUG_ANY, "xfer too short, %d bytes\n", xfer->actlen); - ifp->if_ierrors++; - goto tr_setup; - } usb2_copy_out(xfer->frbuffers, xfer->actlen - sizeof(desc), &desc, sizeof(desc)); @@ -2320,7 +2327,6 @@ zyd_bulk_read_callback(struct usb2_xfer break; zyd_rx_data(xfer, i, offset, len16); - rxcount++; /* next frame is aligned on a 32-bit boundary */ len16 = (len16 + 3) & ~3; @@ -2334,11 +2340,9 @@ zyd_bulk_read_callback(struct usb2_xfer "%s: received single-frame transfer\n", __func__); zyd_rx_data(xfer, 0, 0, xfer->actlen); - rxcount++; } /* FALLTHROUGH */ case USB_ST_SETUP: -tr_setup: if (sc->sc_flags & ZYD_FLAG_BULK_READ_STALL) { usb2_transfer_start(sc->sc_xfer[ZYD_BULK_CS_RD]); } else { @@ -2352,9 +2356,10 @@ tr_setup: * "ieee80211_input" here, and not some lines up! */ ZYD_UNLOCK(sc); - for (i = 0;i < rxcount; i++) { + for (i = 0; i < sc->sc_rx_count; i++) { rssi = sc->sc_rx_data[i].rssi; m = sc->sc_rx_data[i].m; + sc->sc_rx_data[i].m = NULL; nf = -95; /* XXX */ @@ -2859,6 +2864,7 @@ zyd_init_locked(struct zyd_softc *sc) int error; struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; + struct usb2_config_descriptor *cd; uint32_t val; ZYD_LOCK_ASSERT(sc, MA_OWNED); @@ -2874,7 +2880,15 @@ zyd_init_locked(struct zyd_softc *sc) goto fail; } - if ((error = zyd_hw_init(sc)) != 0) { + /* reset device */ + cd = usb2_get_config_descriptor(sc->sc_udev); + error = usb2_req_set_config(sc->sc_udev, &sc->sc_mtx, + cd->bConfigurationValue); + if (error) + device_printf(sc->sc_dev, "reset failed, continuing\n"); + + error = zyd_hw_init(sc); + if (error) { device_printf(sc->sc_dev, "hardware initialization failed\n"); goto fail; @@ -2950,6 +2964,7 @@ zyd_init_locked(struct zyd_softc *sc) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ifp->if_drv_flags |= IFF_DRV_RUNNING; + usb2_transfer_start(sc->sc_xfer[ZYD_BULK_DT_RD]); usb2_transfer_start(sc->sc_xfer[ZYD_INTR_DT_RD]); return; @@ -2993,8 +3008,9 @@ zyd_stop(struct zyd_softc *sc) zyd_free_tx_list(sc); - /* Stop now if the device has vanished */ - if (sc->sc_flags & ZYD_FLAG_DETACHING) + /* Stop now if the device has vanished or was never set up */ + if (sc->sc_flags & ZYD_FLAG_DETACHING || + (sc->sc_flags & ZYD_FLAG_INITONCE) == 0) return; /* switch radio transmitter OFF */ @@ -3121,7 +3137,7 @@ zyd_scantask(void *arg, struct usb2_task struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; - ZYD_LOCK(sc); + ZYD_LOCK_ASSERT(sc, MA_OWNED); switch (sc->sc_scan_action) { case ZYD_SCAN_START: @@ -3140,8 +3156,6 @@ zyd_scantask(void *arg, struct usb2_task sc->sc_scan_action); break; } - - ZYD_UNLOCK(sc); } static void Modified: user/thompsa/usb/sys/dev/usb2/wlan/if_zydreg.h ============================================================================== --- user/thompsa/usb/sys/dev/usb2/wlan/if_zydreg.h Fri Feb 6 20:09:14 2009 (r188245) +++ user/thompsa/usb/sys/dev/usb2/wlan/if_zydreg.h Fri Feb 6 20:41:30 2009 (r188246) @@ -1231,6 +1231,7 @@ struct zyd_rf { struct zyd_rq { struct zyd_cmd *cmd; const uint16_t *idata; + struct zyd_pair *odata; int ilen; int olen; int flags; @@ -1325,6 +1326,7 @@ struct zyd_softc { int tx_nfree; struct zyd_rx_desc sc_rx_desc; struct zyd_rx_data sc_rx_data[ZYD_MAX_RXFRAMECNT]; + int sc_rx_count; struct zyd_cmd sc_ibuf;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902062041.n16KfUSP070987>