PERFORCE change 145200 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Jul 14 07:24:55 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=145200
Change 145200 by hselasky at hselasky_laptop001 on 2008/07/14 07:24:41
There is a bug in the condition variable implementation
that makes cv_xxx and mtx_sleep panic with no apparent
reason when used together with the Giant mutex. I have
a fix for this in the tree. But to make my USB stack
work on older releases of FreeBSD, this patch is
needed.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_busdma.c#2 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_compat_linux.c#6 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_compat_linux.h#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#15 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#13 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_msctest.c#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_process.c#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_request.c#9 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_transfer.c#13 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_transfer.h#5 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_util.c#2 edit
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_util.h#2 edit
.. //depot/projects/usb/src/sys/dev/usb2/serial/ufoma2.c#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2.c#6 edit
.. //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2_reg.h#3 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_busdma.c#2 (text+ko) ====
@@ -27,6 +27,7 @@
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_process.h>
#include <dev/usb2/core/usb2_transfer.h>
+#include <dev/usb2/core/usb2_util.h>
#include <dev/usb2/include/usb2_mfunc.h>
#include <dev/usb2/include/usb2_error.h>
@@ -389,7 +390,7 @@
if (isload) {
(uptag->func) (uptag);
} else {
- cv_broadcast(uptag->cv);
+ usb2_cv_broadcast(uptag->cv);
}
if (!owned)
mtx_unlock(uptag->mtx);
@@ -476,7 +477,7 @@
pc, (BUS_DMA_WAITOK | BUS_DMA_COHERENT));
if (err == EINPROGRESS) {
- cv_wait(uptag->cv, uptag->mtx);
+ usb2_cv_wait(uptag->cv, uptag->mtx);
err = 0;
}
mtx_unlock(uptag->mtx);
@@ -553,7 +554,7 @@
pc->tag, pc->map, pc->buffer, size,
&usb2_pc_alloc_mem_cb, pc, BUS_DMA_WAITOK);
if (err == EINPROGRESS) {
- cv_wait(uptag->cv, uptag->mtx);
+ usb2_cv_wait(uptag->cv, uptag->mtx);
err = 0;
}
mtx_unlock(uptag->mtx);
@@ -1077,7 +1078,7 @@
}
#ifdef __FreeBSD__
/* initialise condition variable */
- cv_init(udpt->cv, "USB DMA CV");
+ usb2_cv_init(udpt->cv, "USB DMA CV");
#endif
/* store some information */
@@ -1122,7 +1123,7 @@
if (udpt->utag_max) {
#ifdef __FreeBSD__
/* destroy the condition variable */
- cv_destroy(udpt->cv);
+ usb2_cv_destroy(udpt->cv);
#endif
}
return;
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_compat_linux.c#6 (text+ko) ====
@@ -562,7 +562,7 @@
*/
while (urb->transfer_flags & URB_WAIT_WAKEUP) {
urb->transfer_flags |= URB_IS_SLEEPING;
- err = mtx_sleep(urb, &Giant, 0, "USB Linux Wait", 0);
+ usb2_cv_wait(&(urb->cv_wait), &Giant);
urb->transfer_flags &= ~URB_IS_SLEEPING;
if (err)
goto done;
@@ -1006,6 +1006,8 @@
urb = malloc(size, M_USBDEV, M_WAITOK | M_ZERO);
if (urb) {
+
+ usb2_cv_init(&(urb->cv_wait), "URBWAIT");
if (iso_packets == 0xFFFF) {
urb->setup_packet = (void *)(urb + 1);
urb->transfer_buffer = (void *)(urb->setup_packet +
@@ -1236,6 +1238,9 @@
/* make sure that the current URB is not active */
usb_kill_urb(urb);
+ /* destroy condition variable */
+ usb2_cv_destroy(&(urb->cv_wait));
+
/* just free it */
free(urb, M_USBDEV);
return;
@@ -1322,7 +1327,7 @@
usb_linux_wait_complete(struct urb *urb, struct pt_regs *pt_regs)
{
if (urb->transfer_flags & URB_IS_SLEEPING) {
- wakeup(urb);
+ usb2_cv_signal(&(urb->cv_wait));
}
urb->transfer_flags &= ~URB_WAIT_WAKEUP;
return;
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_compat_linux.h#3 (text+ko) ====
@@ -394,6 +394,7 @@
*/
struct urb {
TAILQ_ENTRY(urb) bsd_urb_list;
+ struct cv cv_wait;
struct usb_device *dev; /* (in) pointer to associated device */
struct usb_host_endpoint *pipe; /* (in) pipe pointer */
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#15 (text+ko) ====
@@ -43,6 +43,7 @@
#include <dev/usb2/core/usb2_busdma.h>
#include <dev/usb2/core/usb2_generic.h>
#include <dev/usb2/core/usb2_dynamic.h>
+#include <dev/usb2/core/usb2_util.h>
#include <dev/usb2/controller/usb2_controller.h>
#include <dev/usb2/controller/usb2_bus.h>
@@ -450,17 +451,17 @@
mtx_lock(&usb2_ref_lock);
if (ploc->is_read) {
if (--(ploc->rxfifo->refcount) == 0) {
- cv_signal(&(ploc->rxfifo->cv_drain));
+ usb2_cv_signal(&(ploc->rxfifo->cv_drain));
}
}
if (ploc->is_write) {
if (--(ploc->txfifo->refcount) == 0) {
- cv_signal(&(ploc->txfifo->cv_drain));
+ usb2_cv_signal(&(ploc->txfifo->cv_drain));
}
}
if (ploc->is_uref) {
if (--(ploc->udev->refcount) == 0) {
- cv_signal(ploc->udev->default_cv + 1);
+ usb2_cv_signal(ploc->udev->default_cv + 1);
}
}
mtx_unlock(&usb2_ref_lock);
@@ -474,8 +475,8 @@
f = malloc(sizeof(*f), M_USBDEV, M_WAITOK | M_ZERO);
if (f) {
- cv_init(&f->cv_io, "FIFO-IO");
- cv_init(&f->cv_drain, "FIFO-DRAIN");
+ usb2_cv_init(&f->cv_io, "FIFO-IO");
+ usb2_cv_init(&f->cv_drain, "FIFO-DRAIN");
f->refcount = 1;
}
return (f);
@@ -677,20 +678,20 @@
/* get I/O thread out of any sleep state */
if (f->flag_sleeping) {
f->flag_sleeping = 0;
- cv_broadcast(&f->cv_io);
+ usb2_cv_broadcast(&f->cv_io);
}
mtx_unlock(f->priv_mtx);
/* wait for sync */
- cv_wait(&f->cv_drain, &usb2_ref_lock);
+ usb2_cv_wait(&f->cv_drain, &usb2_ref_lock);
}
mtx_unlock(&usb2_ref_lock);
/* take care of closing the device here, if any */
usb2_fifo_close(f, curthread, 0);
- cv_destroy(&f->cv_io);
- cv_destroy(&f->cv_drain);
+ usb2_cv_destroy(&f->cv_io);
+ usb2_cv_destroy(&f->cv_drain);
free(f, M_USBDEV);
return;
@@ -885,7 +886,7 @@
(!f->flag_iserror)) {
/* wait until all data has been written */
f->flag_sleeping = 1;
- err = cv_wait_sig(&(f->cv_io), f->priv_mtx);
+ err = usb2_cv_wait_sig(&(f->cv_io), f->priv_mtx);
if (err) {
DPRINTF(0, "signal received\n");
break;
@@ -1694,7 +1695,7 @@
}
f->flag_sleeping = 1;
- err = cv_wait_sig(&(f->cv_io), f->priv_mtx);
+ err = usb2_cv_wait_sig(&(f->cv_io), f->priv_mtx);
if (f->flag_iserror) {
/* we are gone */
@@ -1708,7 +1709,7 @@
{
if (f->flag_sleeping) {
f->flag_sleeping = 0;
- cv_broadcast(&(f->cv_io));
+ usb2_cv_broadcast(&(f->cv_io));
}
return;
}
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#13 (text+ko) ====
@@ -1307,8 +1307,8 @@
/* initialise our SX-lock */
sx_init(udev->default_sx + 1, "USB config SX lock");
- cv_init(udev->default_cv, "WCTRL");
- cv_init(udev->default_cv + 1, "UGONE");
+ usb2_cv_init(udev->default_cv, "WCTRL");
+ usb2_cv_init(udev->default_cv + 1, "UGONE");
/* initialise our mutex */
mtx_init(udev->default_mtx, "USB device mutex", NULL, MTX_DEF);
@@ -1669,7 +1669,7 @@
mtx_lock(&usb2_ref_lock);
udev->refcount--;
while (udev->refcount != 0) {
- cv_wait(udev->default_cv + 1, &usb2_ref_lock);
+ usb2_cv_wait(udev->default_cv + 1, &usb2_ref_lock);
}
mtx_unlock(&usb2_ref_lock);
@@ -1692,8 +1692,8 @@
sx_destroy(udev->default_sx);
sx_destroy(udev->default_sx + 1);
- cv_destroy(udev->default_cv);
- cv_destroy(udev->default_cv + 1);
+ usb2_cv_destroy(udev->default_cv);
+ usb2_cv_destroy(udev->default_cv + 1);
mtx_destroy(udev->default_mtx);
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_msctest.c#3 (text+ko) ====
@@ -217,7 +217,7 @@
sc->error = error;
sc->state = ST_COMMAND;
sc->status_try = 1;
- cv_signal(&(sc->cv));
+ usb2_cv_signal(&(sc->cv));
return;
}
@@ -460,7 +460,7 @@
usb2_transfer_start(sc->xfer[sc->state]);
while (usb2_transfer_pending(sc->xfer[sc->state])) {
- cv_wait(&(sc->cv), &(sc->mtx));
+ usb2_cv_wait(&(sc->cv), &(sc->mtx));
}
return (sc->error);
}
@@ -517,7 +517,7 @@
return (USB_ERR_NOMEM);
}
mtx_init(&(sc->mtx), "USB autoinstall", NULL, MTX_DEF);
- cv_init(&(sc->cv), "WBBB");
+ usb2_cv_init(&(sc->cv), "WBBB");
err = usb2_transfer_setup(udev,
&iface_index, sc->xfer, bbb_config,
@@ -559,7 +559,7 @@
mtx_unlock(&(sc->mtx));
usb2_transfer_unsetup(sc->xfer, ST_MAX);
mtx_destroy(&(sc->mtx));
- cv_destroy(&(sc->cv));
+ usb2_cv_destroy(&(sc->cv));
free(sc, M_USB);
return (err);
}
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_process.c#3 (text+ko) ====
@@ -28,6 +28,7 @@
#include <dev/usb2/core/usb2_core.h>
#include <dev/usb2/core/usb2_process.h>
#include <dev/usb2/core/usb2_debug.h>
+#include <dev/usb2/core/usb2_util.h>
#include <sys/proc.h>
#include <sys/kthread.h>
@@ -147,14 +148,14 @@
}
if (up->up_dsleep) {
up->up_dsleep = 0;
- cv_broadcast(&(up->up_drain));
+ usb2_cv_broadcast(&(up->up_drain));
}
up->up_msleep = 1;
- cv_wait(&(up->up_cv), up->up_mtx);
+ usb2_cv_wait(&(up->up_cv), up->up_mtx);
}
up->up_ptr = NULL;
- cv_signal(&(up->up_cv));
+ usb2_cv_signal(&(up->up_cv));
mtx_unlock(up->up_mtx);
USB_THREAD_EXIT(0);
@@ -182,8 +183,8 @@
TAILQ_INIT(&(up->up_qhead));
- cv_init(&(up->up_cv), "WMSG");
- cv_init(&(up->up_drain), "DMSG");
+ usb2_cv_init(&(up->up_cv), "WMSG");
+ usb2_cv_init(&(up->up_drain), "DMSG");
if (USB_THREAD_CREATE(&usb2_process, up,
&(up->up_ptr), "USBPROC")) {
@@ -216,8 +217,8 @@
}
usb2_proc_drain(up);
- cv_destroy(&(up->up_cv));
- cv_destroy(&(up->up_drain));
+ usb2_cv_destroy(&(up->up_cv));
+ usb2_cv_destroy(&(up->up_drain));
/* make sure that we do not enter here again */
up->up_mtx = NULL;
@@ -302,7 +303,7 @@
if (up->up_msleep) {
up->up_msleep = 0; /* save "cv_signal()" calls */
- cv_signal(&(up->up_cv));
+ usb2_cv_signal(&(up->up_cv));
}
return (pm2);
}
@@ -348,7 +349,7 @@
} else if (pm0->pm_qentry.tqe_prev ||
pm1->pm_qentry.tqe_prev) {
up->up_dsleep = 1;
- cv_wait(&(up->up_drain), up->up_mtx);
+ usb2_cv_wait(&(up->up_drain), up->up_mtx);
}
mtx_unlock(up->up_mtx);
return;
@@ -385,7 +386,7 @@
if (up->up_msleep || up->up_csleep) {
up->up_msleep = 0;
up->up_csleep = 0;
- cv_signal(&(up->up_cv));
+ usb2_cv_signal(&(up->up_cv));
}
/* Check if someone is waiting - should not happen */
@@ -399,7 +400,7 @@
printf("WARNING: A USB process has been left suspended!\n");
break;
}
- cv_wait(&(up->up_cv), up->up_mtx);
+ usb2_cv_wait(&(up->up_cv), up->up_mtx);
}
mtx_unlock(up->up_mtx);
return;
@@ -433,10 +434,10 @@
up->up_csleep = 1;
if (timeout == 0) {
- cv_wait(&(up->up_cv), up->up_mtx);
+ usb2_cv_wait(&(up->up_cv), up->up_mtx);
error = 0;
} else {
- error = cv_timedwait(&(up->up_cv), up->up_mtx, timeout);
+ error = usb2_cv_timedwait(&(up->up_cv), up->up_mtx, timeout);
}
up->up_csleep = 0;
@@ -462,7 +463,7 @@
if (up->up_csleep) {
up->up_csleep = 0;
- cv_signal(&(up->up_cv));
+ usb2_cv_signal(&(up->up_cv));
}
return;
}
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_request.c#9 (text+ko) ====
@@ -77,7 +77,7 @@
usb2_start_hardware(xfer);
break;
default:
- cv_signal(xfer->udev->default_cv);
+ usb2_cv_signal(xfer->udev->default_cv);
break;
}
return;
@@ -371,7 +371,7 @@
if ((flags & USB_USE_POLLING) || cold) {
usb2_do_poll(udev->default_xfer, USB_DEFAULT_XFER_MAX);
} else {
- cv_wait(xfer->udev->default_cv, xfer->priv_mtx);
+ usb2_cv_wait(xfer->udev->default_cv, xfer->priv_mtx);
}
}
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_transfer.c#13 (text+ko) ====
@@ -721,6 +721,8 @@
info->xfer_page_cache_start = USB_ADD_BYTES(buf, parm.size[5]);
info->xfer_page_cache_end = USB_ADD_BYTES(buf, parm.size[2]);
+ usb2_cv_init(&(info->cv_drain), "WDRAIN");
+
info->usb2_mtx = &(udev->bus->mtx);
info->priv_mtx = priv_mtx;
@@ -990,6 +992,8 @@
/* free all DMA tags */
usb2_dma_tag_unsetup(&(info->dma_parent_tag));
+ usb2_cv_destroy(&(info->cv_drain));
+
/*
* free the "memory_base" last, hence the "info" structure is
* contained within the "memory_base"!
@@ -1618,10 +1622,7 @@
* Wait until the current outstanding USB
* transfer is complete !
*/
- if (mtx_sleep(&(xfer->flags_int), xfer->priv_mtx,
- 0, "usbdrain", 0)) {
- /* should not happen */
- }
+ usb2_cv_wait(&(xfer->usb2_root->cv_drain), xfer->priv_mtx);
}
mtx_unlock(xfer->priv_mtx);
@@ -1832,7 +1833,7 @@
(!xfer->flags_int.transferring)) {
/* "usb2_transfer_drain()" is waiting for end of transfer */
xfer->flags_int.draining = 0;
- wakeup(&(xfer->flags_int));
+ usb2_cv_broadcast(&(xfer->usb2_root->cv_drain));
}
done:
/* do the next callback, if any */
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_transfer.h#5 (text+ko) ====
@@ -44,6 +44,7 @@
struct usb2_xfer_queue dma_q;
struct usb2_xfer_queue done_q;
struct usb2_done_msg done_m[2];
+ struct cv cv_drain;
struct usb2_dma_parent_tag dma_parent_tag;
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_util.c#2 (text+ko) ====
@@ -38,6 +38,9 @@
#include <dev/usb2/controller/usb2_controller.h>
#include <dev/usb2/controller/usb2_bus.h>
+/* function prototypes */
+static int usb2_msleep(void *chan, struct mtx *mtx, int priority, const char *wmesg, int timo);
+
/*------------------------------------------------------------------------*
* device_delete_all_children - delete all children of a device
*------------------------------------------------------------------------*/
@@ -234,3 +237,102 @@
}
return (totlen);
}
+
+/*------------------------------------------------------------------------*
+ * usb2_cv_init - wrapper function
+ *------------------------------------------------------------------------*/
+void
+usb2_cv_init(struct cv *cv, const char *desc)
+{
+ cv_init(cv, desc);
+ return;
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_cv_destroy - wrapper function
+ *------------------------------------------------------------------------*/
+void
+usb2_cv_destroy(struct cv *cv)
+{
+ cv_destroy(cv);
+ return;
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_cv_wait - wrapper function
+ *------------------------------------------------------------------------*/
+void
+usb2_cv_wait(struct cv *cv, struct mtx *mtx)
+{
+ int err;
+
+ err = usb2_msleep(cv, mtx, 0, cv_wmesg(cv), 0);
+ return;
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_cv_wait_sig - wrapper function
+ *------------------------------------------------------------------------*/
+int
+usb2_cv_wait_sig(struct cv *cv, struct mtx *mtx)
+{
+ int err;
+
+ err = usb2_msleep(cv, mtx, PCATCH, cv_wmesg(cv), 0);
+ return (err);
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_cv_timedwait - wrapper function
+ *------------------------------------------------------------------------*/
+int
+usb2_cv_timedwait(struct cv *cv, struct mtx *mtx, int timo)
+{
+ int err;
+
+ if (timo == 0)
+ timo = 1; /* zero means no timeout */
+ err = usb2_msleep(cv, mtx, 0, cv_wmesg(cv), timo);
+ return (err);
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_cv_signal - wrapper function
+ *------------------------------------------------------------------------*/
+void
+usb2_cv_signal(struct cv *cv)
+{
+ wakeup_one(cv);
+ return;
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_cv_broadcast - wrapper function
+ *------------------------------------------------------------------------*/
+void
+usb2_cv_broadcast(struct cv *cv)
+{
+ wakeup(cv);
+ return;
+}
+
+/*------------------------------------------------------------------------*
+ * usb2_msleep - wrapper function
+ *------------------------------------------------------------------------*/
+static int
+usb2_msleep(void *chan, struct mtx *mtx, int priority, const char *wmesg,
+ int timo)
+{
+ int err;
+
+ if (mtx == &Giant) {
+ err = tsleep(chan, priority, wmesg, timo);
+ } else {
+#ifdef mtx_sleep
+ err = mtx_sleep(chan, mtx, priority, wmesg, timo);
+#else
+ err = msleep(chan, mtx, priority, wmesg, timo);
+#endif
+ }
+ return (err);
+}
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_util.h#2 (text+ko) ====
@@ -33,5 +33,12 @@
void usb2_pause_mtx(struct mtx *mtx, uint32_t ms);
void usb2_printBCD(char *p, uint16_t p_len, uint16_t bcd);
void usb2_trim_spaces(char *p);
+void usb2_cv_init(struct cv *cv, const char *desc);
+void usb2_cv_destroy(struct cv *cv);
+void usb2_cv_wait(struct cv *cv, struct mtx *mtx);
+int usb2_cv_wait_sig(struct cv *cv, struct mtx *mtx);
+int usb2_cv_timedwait(struct cv *cv, struct mtx *mtx, int timo);
+void usb2_cv_signal(struct cv *cv);
+void usb2_cv_broadcast(struct cv *cv);
#endif /* _USB2_UTIL_H_ */
==== //depot/projects/usb/src/sys/dev/usb2/serial/ufoma2.c#3 (text+ko) ====
@@ -148,6 +148,7 @@
struct ufoma_softc {
struct usb2_com_super_softc sc_super_ucom;
struct usb2_com_softc sc_ucom;
+ struct cv sc_cv;
struct usb2_xfer *sc_ctrl_xfer[UFOMA_CTRL_ENDPT_MAX];
struct usb2_xfer *sc_bulk_xfer[UFOMA_BULK_ENDPT_MAX];
@@ -385,6 +386,8 @@
sc->sc_dev = dev;
sc->sc_unit = device_get_unit(dev);
+ usb2_cv_init(&(sc->sc_cv), "CWAIT");
+
device_set_usb2_desc(dev);
snprintf(sc->sc_name, sizeof(sc->sc_name),
@@ -472,6 +475,8 @@
if (sc->sc_modetable) {
free(sc->sc_modetable, M_USBDEV);
}
+ usb2_cv_destroy(&(sc->sc_cv));
+
return (0);
}
@@ -536,7 +541,7 @@
ufoma_cfg_do_request(sc, &req, sc->sc_modetable);
- error = mtx_sleep(&(sc->sc_currentmode), &Giant, 0, "ufoma_link", hz);
+ error = usb2_cv_timedwait(&(sc->sc_cv), &Giant, hz);
if (error) {
DPRINTF(0, "NO response\n");
@@ -558,8 +563,8 @@
ufoma_cfg_do_request(sc, &req, NULL);
- error = mtx_sleep(&(sc->sc_currentmode), &Giant, 0,
- "fmaact", (UFOMA_MAX_TIMEOUT * hz));
+ error = usb2_cv_timedwait(&(sc->sc_cv), &Giant,
+ (UFOMA_MAX_TIMEOUT * hz));
if (error) {
DPRINTF(0, "No response\n");
}
@@ -709,7 +714,7 @@
if (!(temp & 0xff)) {
DPRINTF(0, "Mode change failed!\n");
}
- wakeup(&(sc->sc_currentmode));
+ usb2_cv_signal(&(sc->sc_cv));
}
if (pkt.bmRequestType != UCDC_NOTIFICATION) {
goto tr_setup;
==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2.c#6 (text+ko) ====
@@ -475,7 +475,7 @@
if (sc->sc_intr_iwakeup) {
sc->sc_intr_iwakeup = 0;
- wakeup(&(sc->sc_intr_iwakeup));
+ usb2_cv_signal(&(sc->sc_intr_cv));
} else {
sc->sc_intr_iwakeup = 1;
}
@@ -517,8 +517,8 @@
usb2_transfer_start(sc->sc_xfer[ZYD_TR_INTR_DT_RD]);
- if (mtx_sleep(&(sc->sc_intr_iwakeup), &(sc->sc_mtx), 0,
- "zyd-ird", hz / 2)) {
+ if (usb2_cv_timedwait(&(sc->sc_intr_cv),
+ &(sc->sc_mtx), hz / 2)) {
/* should not happen */
}
if (usb2_config_td_is_gone(&(sc->sc_config_td))) {
@@ -617,7 +617,7 @@
wakeup:
if (sc->sc_intr_owakeup) {
sc->sc_intr_owakeup = 0;
- wakeup(&(sc->sc_intr_owakeup));
+ usb2_cv_signal(&(sc->sc_intr_cv));
}
return;
}
@@ -625,7 +625,7 @@
/*
* Interrupt transfer, write.
*
- * Not always an "interrupt transfer", as if operating in
+ * Not always an "interrupt transfer". If operating in
* full speed mode, EP4 is bulk out, not interrupt out.
*/
static void
@@ -648,8 +648,9 @@
usb2_transfer_start(sc->sc_xfer[ZYD_TR_INTR_DT_WR]);
while (sc->sc_intr_owakeup) {
- if (mtx_sleep(&(sc->sc_intr_owakeup), &(sc->sc_mtx), 0,
- "zyd-iwr", hz / 2)) {
+ if (usb2_cv_timedwait(&(sc->sc_intr_cv),
+ &(sc->sc_mtx), hz / 2)) {
+ /* should not happen */
}
if (usb2_config_td_is_gone(&(sc->sc_config_td))) {
sc->sc_intr_owakeup = 0;
@@ -1076,6 +1077,8 @@
mtx_init(&sc->sc_mtx, "zyd lock", MTX_NETWORK_LOCK,
MTX_DEF | MTX_RECURSE);
+ usb2_cv_init(&(sc->sc_intr_cv), "IWAIT");
+
usb2_callout_init_mtx(&(sc->sc_watchdog),
&(sc->sc_mtx), CALLOUT_RETURNUNLOCKED);
@@ -2057,6 +2060,8 @@
usb2_callout_drain(&(sc->sc_watchdog));
+ usb2_cv_destroy(&(sc->sc_intr_cv));
+
mtx_destroy(&sc->sc_mtx);
return (0);
==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2_reg.h#3 (text+ko) ====
@@ -1228,6 +1228,7 @@
struct zyd_cmd sc_intr_obuf;
struct zyd_tx_desc sc_tx_desc;
struct zyd_ifq sc_tx_queue;
+ struct cv sc_intr_cv;
struct ifnet *sc_ifp;
struct usb2_device *sc_udev;
More information about the p4-projects
mailing list