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