svn commit: r188246 - user/thompsa/usb/sys/dev/usb2/wlan
Andrew Thompson
thompsa at FreeBSD.org
Fri Feb 6 12:41:30 PST 2009
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;
More information about the svn-src-user
mailing list