svn commit: r188411 - head/sys/dev/usb2/core

Andrew Thompson thompsa at FreeBSD.org
Mon Feb 9 13:56:34 PST 2009


Author: thompsa
Date: Mon Feb  9 21:56:33 2009
New Revision: 188411
URL: http://svn.freebsd.org/changeset/base/188411

Log:
  MFp4 //depot/projects/usb; 157069, 157429, 157430
  
   - Change "usb2_pause_mtx" so that it takes the timeout value in ticks
   - Factor out USB ethernet and USB serial driver specific control request.
   - USB process naming cleanup.
  
  Submitted by:	Hans Petter Selasky

Modified:
  head/sys/dev/usb2/core/usb2_core.h
  head/sys/dev/usb2/core/usb2_device.c
  head/sys/dev/usb2/core/usb2_hub.c
  head/sys/dev/usb2/core/usb2_msctest.c
  head/sys/dev/usb2/core/usb2_process.c
  head/sys/dev/usb2/core/usb2_process.h
  head/sys/dev/usb2/core/usb2_request.c
  head/sys/dev/usb2/core/usb2_request.h
  head/sys/dev/usb2/core/usb2_transfer.c
  head/sys/dev/usb2/core/usb2_util.c
  head/sys/dev/usb2/core/usb2_util.h

Modified: head/sys/dev/usb2/core/usb2_core.h
==============================================================================
--- head/sys/dev/usb2/core/usb2_core.h	Mon Feb  9 21:50:04 2009	(r188410)
+++ head/sys/dev/usb2/core/usb2_core.h	Mon Feb  9 21:56:33 2009	(r188411)
@@ -434,6 +434,7 @@ uint8_t	usb2_clear_stall_callback(struct
 uint8_t	usb2_get_interface_altindex(struct usb2_interface *iface);
 usb2_error_t usb2_set_alt_interface_index(struct usb2_device *udev,
 	    uint8_t iface_index, uint8_t alt_index);
+uint8_t	usb2_get_mode(struct usb2_device *udev);
 uint8_t	usb2_get_speed(struct usb2_device *udev);
 uint32_t usb2_get_isoc_fps(struct usb2_device *udev);
 usb2_error_t usb2_transfer_setup(struct usb2_device *udev,

Modified: head/sys/dev/usb2/core/usb2_device.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_device.c	Mon Feb  9 21:50:04 2009	(r188410)
+++ head/sys/dev/usb2/core/usb2_device.c	Mon Feb  9 21:56:33 2009	(r188411)
@@ -1401,7 +1401,8 @@ usb2_alloc_device(device_t parent_dev, s
 			    "(ignored)\n", udev->address);
 		}
 		/* allow device time to set new address */
-		usb2_pause_mtx(&Giant, USB_SET_ADDRESS_SETTLE);
+		usb2_pause_mtx(&Giant, 
+		    USB_MS_TO_TICKS(USB_SET_ADDRESS_SETTLE));
 	} else {
 		/* We are not self powered */
 		udev->flags.self_powered = 0;
@@ -1951,6 +1952,20 @@ usb2_check_strings(struct usb2_device *u
 	}
 }
 
+/*
+ * Returns:
+ * See: USB_MODE_XXX
+ */
+uint8_t
+usb2_get_mode(struct usb2_device *udev)
+{
+	return (udev->flags.usb2_mode);
+}
+
+/*
+ * Returns:
+ * See: USB_SPEED_XXX
+ */
 uint8_t
 usb2_get_speed(struct usb2_device *udev)
 {

Modified: head/sys/dev/usb2/core/usb2_hub.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_hub.c	Mon Feb  9 21:50:04 2009	(r188410)
+++ head/sys/dev/usb2/core/usb2_hub.c	Mon Feb  9 21:56:33 2009	(r188411)
@@ -335,7 +335,8 @@ repeat:
 
 		/* wait for maximum device power up time */
 
-		usb2_pause_mtx(&Giant, USB_PORT_POWERUP_DELAY);
+		usb2_pause_mtx(&Giant, 
+		    USB_MS_TO_TICKS(USB_PORT_POWERUP_DELAY));
 
 		/* reset port, which implies enabling it */
 
@@ -736,7 +737,7 @@ uhub_attach(device_t dev)
 		goto error;
 	}
 	/* wait with power off for a while */
-	usb2_pause_mtx(&Giant, USB_POWER_DOWN_TIME);
+	usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(USB_POWER_DOWN_TIME));
 
 	/*
 	 * To have the best chance of success we do things in the exact same
@@ -794,7 +795,7 @@ uhub_attach(device_t dev)
 		    portno);
 
 		/* wait for stable power */
-		usb2_pause_mtx(&Giant, pwrdly);
+		usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(pwrdly));
 	}
 
 	device_printf(dev, "%d port%s with %d "
@@ -1666,7 +1667,7 @@ usb2_dev_resume_peer(struct usb2_device 
 		return;
 	}
 	/* resume settle time */
-	usb2_pause_mtx(&Giant, USB_PORT_RESUME_DELAY);
+	usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(USB_PORT_RESUME_DELAY));
 
 	if (bus->methods->device_resume != NULL) {
 		/* resume USB device on the USB controller */
@@ -1802,7 +1803,7 @@ repeat:
 
 		/* do DMA delay */
 		temp = usb2_get_dma_delay(udev->bus);
-		usb2_pause_mtx(&Giant, temp);
+		usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(temp));
 
 	}
 	/* suspend current port */

Modified: head/sys/dev/usb2/core/usb2_msctest.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_msctest.c	Mon Feb  9 21:50:04 2009	(r188410)
+++ head/sys/dev/usb2/core/usb2_msctest.c	Mon Feb  9 21:56:33 2009	(r188411)
@@ -562,7 +562,7 @@ repeat_inquiry:
 			goto done;
 		}
 	} else if ((err != 2) && --timeout) {
-		usb2_pause_mtx(&sc->mtx, USB_MS_HZ);
+		usb2_pause_mtx(&sc->mtx, hz);
 		goto repeat_inquiry;
 	}
 	err = USB_ERR_INVAL;

Modified: head/sys/dev/usb2/core/usb2_process.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_process.c	Mon Feb  9 21:50:04 2009	(r188410)
+++ head/sys/dev/usb2/core/usb2_process.c	Mon Feb  9 21:56:33 2009	(r188411)
@@ -164,7 +164,7 @@ usb2_process(void *arg)
 }
 
 /*------------------------------------------------------------------------*
- *	usb2_proc_setup
+ *	usb2_proc_create
  *
  * This function will create a process using the given "prio" that can
  * execute callbacks. The mutex pointed to by "p_mtx" will be applied
@@ -176,8 +176,9 @@ usb2_process(void *arg)
  *    0: success
  * Else: failure
  *------------------------------------------------------------------------*/
-uint8_t
-usb2_proc_setup(struct usb2_process *up, struct mtx *p_mtx, uint8_t prio)
+int
+usb2_proc_create(struct usb2_process *up, struct mtx *p_mtx,
+    const char *pmesg, uint8_t prio)
 {
 	up->up_mtx = p_mtx;
 	up->up_prio = prio;
@@ -188,7 +189,7 @@ usb2_proc_setup(struct usb2_process *up,
 	usb2_cv_init(&up->up_drain, "dmsg");
 
 	if (USB_THREAD_CREATE(&usb2_process, up,
-	    &up->up_ptr, "usbproc")) {
+	    &up->up_ptr, pmesg)) {
 		DPRINTFN(0, "Unable to create USB process.");
 		up->up_ptr = NULL;
 		goto error;
@@ -196,12 +197,12 @@ usb2_proc_setup(struct usb2_process *up,
 	return (0);
 
 error:
-	usb2_proc_unsetup(up);
-	return (1);
+	usb2_proc_free(up);
+	return (ENOMEM);
 }
 
 /*------------------------------------------------------------------------*
- *	usb2_proc_unsetup
+ *	usb2_proc_free
  *
  * NOTE: If the structure pointed to by "up" is all zero, this
  * function does nothing.
@@ -210,7 +211,7 @@ error:
  * removed nor called.
  *------------------------------------------------------------------------*/
 void
-usb2_proc_unsetup(struct usb2_process *up)
+usb2_proc_free(struct usb2_process *up)
 {
 	if (!(up->up_mtx)) {
 		/* not initialised */

Modified: head/sys/dev/usb2/core/usb2_process.h
==============================================================================
--- head/sys/dev/usb2/core/usb2_process.h	Mon Feb  9 21:50:04 2009	(r188410)
+++ head/sys/dev/usb2/core/usb2_process.h	Mon Feb  9 21:56:33 2009	(r188411)
@@ -79,12 +79,12 @@ struct usb2_process {
 
 uint8_t	usb2_proc_cwait(struct usb2_process *up, int timeout);
 uint8_t	usb2_proc_is_gone(struct usb2_process *up);
-uint8_t	usb2_proc_setup(struct usb2_process *up, struct mtx *p_mtx,
-	    uint8_t prio);
+int	usb2_proc_create(struct usb2_process *up, struct mtx *p_mtx,
+	    const char *pmesg, uint8_t prio);
 void	usb2_proc_csignal(struct usb2_process *up);
 void	usb2_proc_drain(struct usb2_process *up);
 void	usb2_proc_mwait(struct usb2_process *up, void *pm0, void *pm1);
-void	usb2_proc_unsetup(struct usb2_process *up);
+void	usb2_proc_free(struct usb2_process *up);
 void   *usb2_proc_msignal(struct usb2_process *up, void *pm0, void *pm1);
 
 #endif					/* _USB2_PROCESS_H_ */

Modified: head/sys/dev/usb2/core/usb2_request.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_request.c	Mon Feb  9 21:50:04 2009	(r188410)
+++ head/sys/dev/usb2/core/usb2_request.c	Mon Feb  9 21:56:33 2009	(r188411)
@@ -371,7 +371,7 @@ usb2_do_request_flags(struct usb2_device
 					if (temp > 0) {
 						usb2_pause_mtx(
 						    xfer->xroot->xfer_mtx,
-						    temp);
+						    USB_MS_TO_TICKS(temp));
 					}
 #endif
 					xfer->flags.manual_status = 0;
@@ -477,6 +477,49 @@ done:
 }
 
 /*------------------------------------------------------------------------*
+ *	usb2_do_request_proc - factored out code
+ *
+ * This function is factored out code. It does basically the same like
+ * usb2_do_request_flags, except it will check the status of the
+ * passed process argument before doing the USB request. If the
+ * process is draining the USB_ERR_IOERROR code will be returned. It
+ * is assumed that the mutex associated with the process is locked
+ * when calling this function.
+ *------------------------------------------------------------------------*/
+usb2_error_t
+usb2_do_request_proc(struct usb2_device *udev, struct usb2_process *pproc,
+    struct usb2_device_request *req, void *data, uint32_t flags,
+    uint16_t *actlen, uint32_t timeout)
+{
+	usb2_error_t err;
+	uint16_t len;
+
+	/* get request data length */
+	len = UGETW(req->wLength);
+
+	/* check if the device is being detached */
+	if (usb2_proc_is_gone(pproc)) {
+		err = USB_ERR_IOERROR;
+		goto done;
+	}
+
+	/* forward the USB request */
+	err = usb2_do_request_flags(udev, pproc->up_mtx,
+	    req, data, flags, actlen, timeout);
+
+done:
+	/* on failure we zero the data */
+	/* on short packet we zero the unused data */
+	if ((len != 0) && (req->bmRequestType & UE_DIR_IN)) {
+		if (err)
+			memset(data, 0, len);
+		else if (actlen && *actlen != len)
+			memset(((uint8_t *)data) + *actlen, 0, len - *actlen);
+	}
+	return (err);
+}
+
+/*------------------------------------------------------------------------*
  *	usb2_req_reset_port
  *
  * This function will instruct an USB HUB to perform a reset sequence
@@ -520,11 +563,11 @@ usb2_req_reset_port(struct usb2_device *
 	while (1) {
 #if USB_DEBUG
 		/* wait for the device to recover from reset */
-		usb2_pause_mtx(mtx, pr_poll_delay);
+		usb2_pause_mtx(mtx, USB_MS_TO_TICKS(pr_poll_delay));
 		n += pr_poll_delay;
 #else
 		/* wait for the device to recover from reset */
-		usb2_pause_mtx(mtx, USB_PORT_RESET_DELAY);
+		usb2_pause_mtx(mtx, USB_MS_TO_TICKS(USB_PORT_RESET_DELAY));
 		n += USB_PORT_RESET_DELAY;
 #endif
 		err = usb2_req_get_port_status(udev, mtx, &ps, port);
@@ -559,10 +602,10 @@ usb2_req_reset_port(struct usb2_device *
 	}
 #if USB_DEBUG
 	/* wait for the device to recover from reset */
-	usb2_pause_mtx(mtx, pr_recovery_delay);
+	usb2_pause_mtx(mtx, USB_MS_TO_TICKS(pr_recovery_delay));
 #else
 	/* wait for the device to recover from reset */
-	usb2_pause_mtx(mtx, USB_PORT_RESET_RECOVERY);
+	usb2_pause_mtx(mtx, USB_MS_TO_TICKS(USB_PORT_RESET_RECOVERY));
 #endif
 
 done:
@@ -624,7 +667,7 @@ usb2_req_get_desc(struct usb2_device *ud
 			}
 			retries--;
 
-			usb2_pause_mtx(mtx, 200);
+			usb2_pause_mtx(mtx, hz / 5);
 
 			continue;
 		}
@@ -1369,7 +1412,7 @@ retry:
 	udev->address = old_addr;
 
 	/* allow device time to set new address */
-	usb2_pause_mtx(mtx, USB_SET_ADDRESS_SETTLE);
+	usb2_pause_mtx(mtx, USB_MS_TO_TICKS(USB_SET_ADDRESS_SETTLE));
 
 	/* get the device descriptor */
 	err = usb2_req_get_desc(udev, mtx, &udev->ddesc,
@@ -1389,7 +1432,7 @@ retry:
 done:
 	if (err && do_retry) {
 		/* give the USB firmware some time to load */
-		usb2_pause_mtx(mtx, 500);
+		usb2_pause_mtx(mtx, hz / 2);
 		/* no more retries after this retry */
 		do_retry = 0;
 		/* try again */

Modified: head/sys/dev/usb2/core/usb2_request.h
==============================================================================
--- head/sys/dev/usb2/core/usb2_request.h	Mon Feb  9 21:50:04 2009	(r188410)
+++ head/sys/dev/usb2/core/usb2_request.h	Mon Feb  9 21:56:33 2009	(r188411)
@@ -27,9 +27,14 @@
 #ifndef _USB2_REQUEST_H_
 #define	_USB2_REQUEST_H_
 
+struct usb2_process;
+
 usb2_error_t usb2_do_request_flags(struct usb2_device *udev, struct mtx *mtx,
 		    struct usb2_device_request *req, void *data, uint32_t flags,
 		    uint16_t *actlen, uint32_t timeout);
+usb2_error_t usb2_do_request_proc(struct usb2_device *udev, struct usb2_process *pproc,
+		    struct usb2_device_request *req, void *data, uint32_t flags,
+		    uint16_t *actlen, uint32_t timeout);
 usb2_error_t usb2_req_clear_hub_feature(struct usb2_device *udev,
 		    struct mtx *mtx, uint16_t sel);
 usb2_error_t usb2_req_clear_port_feature(struct usb2_device *udev,

Modified: head/sys/dev/usb2/core/usb2_transfer.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_transfer.c	Mon Feb  9 21:50:04 2009	(r188410)
+++ head/sys/dev/usb2/core/usb2_transfer.c	Mon Feb  9 21:56:33 2009	(r188411)
@@ -1066,7 +1066,8 @@ usb2_transfer_unsetup_sub(struct usb2_xf
 
 	if (needs_delay) {
 		temp = usb2_get_dma_delay(info->bus);
-		usb2_pause_mtx(&info->bus->bus_mtx, temp);
+		usb2_pause_mtx(&info->bus->bus_mtx,
+		    USB_MS_TO_TICKS(temp));
 	}
 
 	/* make sure that our done messages are not queued anywhere */

Modified: head/sys/dev/usb2/core/usb2_util.c
==============================================================================
--- head/sys/dev/usb2/core/usb2_util.c	Mon Feb  9 21:50:04 2009	(r188410)
+++ head/sys/dev/usb2/core/usb2_util.c	Mon Feb  9 21:56:33 2009	(r188411)
@@ -124,36 +124,37 @@ device_set_usb2_desc(device_t dev)
 /*------------------------------------------------------------------------*
  *	 usb2_pause_mtx - factored out code
  *
- * This function will delay the code by the passed number of
- * milliseconds. The passed mutex "mtx" will be dropped while waiting,
- * if "mtx" is not NULL. The number of milliseconds per second is 1024
- * for sake of optimisation.
+ * This function will delay the code by the passed number of system
+ * ticks. The passed mutex "mtx" will be dropped while waiting, if
+ * "mtx" is not NULL.
  *------------------------------------------------------------------------*/
 void
-usb2_pause_mtx(struct mtx *mtx, uint32_t ms)
+usb2_pause_mtx(struct mtx *mtx, int _ticks)
 {
+	if (mtx != NULL)
+		mtx_unlock(mtx);
+
 	if (cold) {
-		ms = (ms + 1) * 1024;
-		DELAY(ms);
+		/* convert to milliseconds */
+		_ticks = (_ticks * 1000) / hz;
+		/* convert to microseconds, rounded up */
+		_ticks = (_ticks + 1) * 1000;
+		DELAY(_ticks);
 
 	} else {
 
-		ms = USB_MS_TO_TICKS(ms);
 		/*
 		 * Add one to the number of ticks so that we don't return
 		 * too early!
 		 */
-		ms++;
-
-		if (mtx != NULL)
-			mtx_unlock(mtx);
+		_ticks++;
 
-		if (pause("USBWAIT", ms)) {
+		if (pause("USBWAIT", _ticks)) {
 			/* ignore */
 		}
-		if (mtx != NULL)
-			mtx_lock(mtx);
 	}
+	if (mtx != NULL)
+		mtx_lock(mtx);
 }
 
 /*------------------------------------------------------------------------*

Modified: head/sys/dev/usb2/core/usb2_util.h
==============================================================================
--- head/sys/dev/usb2/core/usb2_util.h	Mon Feb  9 21:50:04 2009	(r188410)
+++ head/sys/dev/usb2/core/usb2_util.h	Mon Feb  9 21:56:33 2009	(r188411)
@@ -31,7 +31,7 @@ int	device_delete_all_children(device_t 
 uint32_t usb2_get_devid(device_t dev);
 uint8_t	usb2_make_str_desc(void *ptr, uint16_t max_len, const char *s);
 void	device_set_usb2_desc(device_t dev);
-void	usb2_pause_mtx(struct mtx *mtx, uint32_t ms);
+void	usb2_pause_mtx(struct mtx *mtx, int _ticks);
 void	usb2_printBCD(char *p, uint16_t p_len, uint16_t bcd);
 void	usb2_trim_spaces(char *p);
 


More information about the svn-src-head mailing list