From owner-p4-projects@FreeBSD.ORG Mon Jul 14 07:24:55 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 718EA1065682; Mon, 14 Jul 2008 07:24:55 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1C8A21065671 for ; Mon, 14 Jul 2008 07:24:55 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 0D14C8FC1B for ; Mon, 14 Jul 2008 07:24:55 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m6E7OslB053430 for ; Mon, 14 Jul 2008 07:24:54 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.2/8.14.1/Submit) id m6E7OsDT053428 for perforce@freebsd.org; Mon, 14 Jul 2008 07:24:54 GMT (envelope-from hselasky@FreeBSD.org) Date: Mon, 14 Jul 2008 07:24:54 GMT Message-Id: <200807140724.m6E7OsDT053428@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 145200 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 Jul 2008 07:24:55 -0000 http://perforce.freebsd.org/chv.cgi?CH=145200 Change 145200 by hselasky@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 #include #include +#include #include #include @@ -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 #include #include +#include #include #include @@ -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 #include #include +#include #include #include @@ -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 #include +/* 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;