Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Jun 2011 22:06:42 +0000 (UTC)
From:      Attilio Rao <attilio@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r222791 - in projects/largeSMP: contrib/top share/mk sys/dev/usb sys/netinet
Message-ID:  <201106062206.p56M6gdc051097@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: attilio
Date: Mon Jun  6 22:06:42 2011
New Revision: 222791
URL: http://svn.freebsd.org/changeset/base/222791

Log:
  MFC

Modified:
  projects/largeSMP/sys/dev/usb/usb_device.h
  projects/largeSMP/sys/dev/usb/usb_freebsd.h
  projects/largeSMP/sys/dev/usb/usb_generic.c
  projects/largeSMP/sys/dev/usb/usb_hub.c
  projects/largeSMP/sys/dev/usb/usb_request.c
  projects/largeSMP/sys/dev/usb/usb_request.h
  projects/largeSMP/sys/dev/usb/usb_transfer.c
  projects/largeSMP/sys/dev/usb/usbdi.h
  projects/largeSMP/sys/netinet/in_pcb.h
Directory Properties:
  projects/largeSMP/   (props changed)
  projects/largeSMP/cddl/contrib/opensolaris/   (props changed)
  projects/largeSMP/contrib/bind9/   (props changed)
  projects/largeSMP/contrib/binutils/   (props changed)
  projects/largeSMP/contrib/bzip2/   (props changed)
  projects/largeSMP/contrib/compiler-rt/   (props changed)
  projects/largeSMP/contrib/dialog/   (props changed)
  projects/largeSMP/contrib/ee/   (props changed)
  projects/largeSMP/contrib/expat/   (props changed)
  projects/largeSMP/contrib/file/   (props changed)
  projects/largeSMP/contrib/gcc/   (props changed)
  projects/largeSMP/contrib/gdb/   (props changed)
  projects/largeSMP/contrib/gdtoa/   (props changed)
  projects/largeSMP/contrib/gnu-sort/   (props changed)
  projects/largeSMP/contrib/groff/   (props changed)
  projects/largeSMP/contrib/less/   (props changed)
  projects/largeSMP/contrib/libpcap/   (props changed)
  projects/largeSMP/contrib/libstdc++/   (props changed)
  projects/largeSMP/contrib/llvm/   (props changed)
  projects/largeSMP/contrib/llvm/tools/clang/   (props changed)
  projects/largeSMP/contrib/ncurses/   (props changed)
  projects/largeSMP/contrib/netcat/   (props changed)
  projects/largeSMP/contrib/ntp/   (props changed)
  projects/largeSMP/contrib/one-true-awk/   (props changed)
  projects/largeSMP/contrib/openbsm/   (props changed)
  projects/largeSMP/contrib/openpam/   (props changed)
  projects/largeSMP/contrib/pf/   (props changed)
  projects/largeSMP/contrib/sendmail/   (props changed)
  projects/largeSMP/contrib/tcpdump/   (props changed)
  projects/largeSMP/contrib/tcsh/   (props changed)
  projects/largeSMP/contrib/top/   (props changed)
  projects/largeSMP/contrib/top/install-sh   (props changed)
  projects/largeSMP/contrib/tzcode/stdtime/   (props changed)
  projects/largeSMP/contrib/tzcode/zic/   (props changed)
  projects/largeSMP/contrib/tzdata/   (props changed)
  projects/largeSMP/contrib/wpa/   (props changed)
  projects/largeSMP/contrib/xz/   (props changed)
  projects/largeSMP/crypto/openssh/   (props changed)
  projects/largeSMP/crypto/openssl/   (props changed)
  projects/largeSMP/gnu/lib/   (props changed)
  projects/largeSMP/gnu/usr.bin/binutils/   (props changed)
  projects/largeSMP/gnu/usr.bin/cc/cc_tools/   (props changed)
  projects/largeSMP/gnu/usr.bin/gdb/   (props changed)
  projects/largeSMP/lib/libc/   (props changed)
  projects/largeSMP/lib/libc/stdtime/   (props changed)
  projects/largeSMP/lib/libutil/   (props changed)
  projects/largeSMP/lib/libz/   (props changed)
  projects/largeSMP/sbin/   (props changed)
  projects/largeSMP/sbin/ipfw/   (props changed)
  projects/largeSMP/share/mk/bsd.arch.inc.mk   (props changed)
  projects/largeSMP/share/zoneinfo/   (props changed)
  projects/largeSMP/sys/   (props changed)
  projects/largeSMP/sys/amd64/include/xen/   (props changed)
  projects/largeSMP/sys/boot/   (props changed)
  projects/largeSMP/sys/boot/i386/efi/   (props changed)
  projects/largeSMP/sys/boot/ia64/efi/   (props changed)
  projects/largeSMP/sys/boot/ia64/ski/   (props changed)
  projects/largeSMP/sys/boot/powerpc/boot1.chrp/   (props changed)
  projects/largeSMP/sys/boot/powerpc/ofw/   (props changed)
  projects/largeSMP/sys/cddl/contrib/opensolaris/   (props changed)
  projects/largeSMP/sys/conf/   (props changed)
  projects/largeSMP/sys/contrib/dev/acpica/   (props changed)
  projects/largeSMP/sys/contrib/octeon-sdk/   (props changed)
  projects/largeSMP/sys/contrib/pf/   (props changed)
  projects/largeSMP/sys/contrib/x86emu/   (props changed)
  projects/largeSMP/usr.bin/calendar/   (props changed)
  projects/largeSMP/usr.bin/csup/   (props changed)
  projects/largeSMP/usr.bin/procstat/   (props changed)
  projects/largeSMP/usr.sbin/ndiscvt/   (props changed)
  projects/largeSMP/usr.sbin/zic/   (props changed)

Modified: projects/largeSMP/sys/dev/usb/usb_device.h
==============================================================================
--- projects/largeSMP/sys/dev/usb/usb_device.h	Mon Jun  6 22:03:09 2011	(r222790)
+++ projects/largeSMP/sys/dev/usb/usb_device.h	Mon Jun  6 22:06:42 2011	(r222791)
@@ -187,6 +187,8 @@ struct usb_device {
 	struct usb_host_endpoint *linux_endpoint_end;
 	uint16_t devnum;
 #endif
+
+	uint32_t clear_stall_errors;	/* number of clear-stall failures */
 };
 
 /* globals */

Modified: projects/largeSMP/sys/dev/usb/usb_freebsd.h
==============================================================================
--- projects/largeSMP/sys/dev/usb/usb_freebsd.h	Mon Jun  6 22:03:09 2011	(r222790)
+++ projects/largeSMP/sys/dev/usb/usb_freebsd.h	Mon Jun  6 22:06:42 2011	(r222791)
@@ -66,6 +66,7 @@
 
 #define	USB_HUB_MAX_DEPTH	5
 #define	USB_EP0_BUFSIZE		1024	/* bytes */
+#define	USB_CS_RESET_LIMIT	20	/* failures = 20 * 50 ms = 1sec */
 
 typedef uint32_t usb_timeout_t;		/* milliseconds */
 typedef uint32_t usb_frlength_t;	/* bytes */

Modified: projects/largeSMP/sys/dev/usb/usb_generic.c
==============================================================================
--- projects/largeSMP/sys/dev/usb/usb_generic.c	Mon Jun  6 22:03:09 2011	(r222790)
+++ projects/largeSMP/sys/dev/usb/usb_generic.c	Mon Jun  6 22:06:42 2011	(r222791)
@@ -966,10 +966,8 @@ ugen_re_enumerate(struct usb_fifo *f)
 		/* ignore any errors */
 		DPRINTFN(6, "no FIFOs\n");
 	}
-	if (udev->re_enumerate_wait == 0) {
-		udev->re_enumerate_wait = 1;
-		usb_needs_explore(udev->bus, 0);
-	}
+	/* start re-enumeration of device */
+	usbd_start_re_enumerate(udev);
 	return (0);
 }
 

Modified: projects/largeSMP/sys/dev/usb/usb_hub.c
==============================================================================
--- projects/largeSMP/sys/dev/usb/usb_hub.c	Mon Jun  6 22:03:09 2011	(r222790)
+++ projects/largeSMP/sys/dev/usb/usb_hub.c	Mon Jun  6 22:06:42 2011	(r222791)
@@ -242,9 +242,14 @@ uhub_explore_sub(struct uhub_softc *sc, 
 	if (child->flags.usb_mode == USB_MODE_HOST) {
 		usbd_enum_lock(child);
 		if (child->re_enumerate_wait) {
-			err = usbd_set_config_index(child, USB_UNCONFIG_INDEX);
-			if (err == 0)
-				err = usbd_req_re_enumerate(child, NULL);
+			err = usbd_set_config_index(child,
+			    USB_UNCONFIG_INDEX);
+			if (err != 0) {
+				DPRINTF("Unconfigure failed: "
+				    "%s: Ignored.\n",
+				    usbd_errstr(err));
+			}
+			err = usbd_req_re_enumerate(child, NULL);
 			if (err == 0)
 				err = usbd_set_config_index(child, 0);
 			if (err == 0) {
@@ -2471,3 +2476,19 @@ usbd_filter_power_mode(struct usb_device
 	/* use fixed power mode given by hardware driver */
 	return (temp);
 }
+
+/*------------------------------------------------------------------------*
+ *	usbd_start_re_enumerate
+ *
+ * This function starts re-enumeration of the given USB device. This
+ * function does not need to be called BUS-locked. This function does
+ * not wait until the re-enumeration is completed.
+ *------------------------------------------------------------------------*/
+void
+usbd_start_re_enumerate(struct usb_device *udev)
+{
+	if (udev->re_enumerate_wait == 0) {
+		udev->re_enumerate_wait = 1;
+		usb_needs_explore(udev->bus, 0);
+	}
+}

Modified: projects/largeSMP/sys/dev/usb/usb_request.c
==============================================================================
--- projects/largeSMP/sys/dev/usb/usb_request.c	Mon Jun  6 22:03:09 2011	(r222790)
+++ projects/largeSMP/sys/dev/usb/usb_request.c	Mon Jun  6 22:06:42 2011	(r222791)
@@ -238,6 +238,10 @@ usb_do_clear_stall_callback(struct usb_x
 
 	switch (USB_GET_STATE(xfer)) {
 	case USB_ST_TRANSFERRED:
+
+		/* reset error counter */
+		udev->clear_stall_errors = 0;
+
 		if (ep == NULL)
 			goto tr_setup;		/* device was unconfigured */
 		if (ep->edesc &&
@@ -289,8 +293,23 @@ tr_setup:
 		goto tr_setup;
 
 	default:
-		if (xfer->error == USB_ERR_CANCELLED) {
+		if (error == USB_ERR_CANCELLED)
 			break;
+
+		DPRINTF("Clear stall failed.\n");
+		if (udev->clear_stall_errors == USB_CS_RESET_LIMIT)
+			goto tr_setup;
+
+		if (error == USB_ERR_TIMEOUT) {
+			udev->clear_stall_errors = USB_CS_RESET_LIMIT;
+			DPRINTF("Trying to re-enumerate.\n");
+			usbd_start_re_enumerate(udev);
+		} else {
+			udev->clear_stall_errors++;
+			if (udev->clear_stall_errors == USB_CS_RESET_LIMIT) {
+				DPRINTF("Trying to re-enumerate.\n");
+				usbd_start_re_enumerate(udev);
+			}
 		}
 		goto tr_setup;
 	}
@@ -1936,6 +1955,23 @@ usbd_req_re_enumerate(struct usb_device 
 		return (USB_ERR_INVAL);
 	}
 retry:
+	/*
+	 * Try to reset the High Speed parent HUB of a LOW- or FULL-
+	 * speed device, if any.
+	 */
+	if (udev->parent_hs_hub != NULL &&
+	    udev->speed != USB_SPEED_HIGH) {
+		DPRINTF("Trying to reset parent High Speed TT.\n");
+		err = usbd_req_reset_tt(udev->parent_hs_hub, NULL,
+		    udev->hs_port_no);
+		if (err) {
+			DPRINTF("Resetting parent High "
+			    "Speed TT failed (%s).\n",
+			    usbd_errstr(err));
+		}
+	}
+
+	/* Try to reset the parent HUB port. */
 	err = usbd_req_reset_port(parent_hub, mtx, udev->port_no);
 	if (err) {
 		DPRINTFN(0, "addr=%d, port reset failed, %s\n", 
@@ -2033,3 +2069,65 @@ usbd_req_set_device_feature(struct usb_d
 	USETW(req.wLength, 0);
 	return (usbd_do_request(udev, mtx, &req, 0));
 }
+
+/*------------------------------------------------------------------------*
+ *	usbd_req_reset_tt
+ *
+ * Returns:
+ *    0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+usb_error_t
+usbd_req_reset_tt(struct usb_device *udev, struct mtx *mtx,
+    uint8_t port)
+{
+	struct usb_device_request req;
+
+	/* For single TT HUBs the port should be 1 */
+
+	if (udev->ddesc.bDeviceClass == UDCLASS_HUB &&
+	    udev->ddesc.bDeviceProtocol == UDPROTO_HSHUBSTT)
+		port = 1;
+
+	req.bmRequestType = UT_WRITE_CLASS_OTHER;
+	req.bRequest = UR_RESET_TT;
+	USETW(req.wValue, 0);
+	req.wIndex[0] = port;
+	req.wIndex[1] = 0;
+	USETW(req.wLength, 0);
+	return (usbd_do_request(udev, mtx, &req, 0));
+}
+
+/*------------------------------------------------------------------------*
+ *	usbd_req_clear_tt_buffer
+ *
+ * For single TT HUBs the port should be 1.
+ *
+ * Returns:
+ *    0: Success
+ * Else: Failure
+ *------------------------------------------------------------------------*/
+usb_error_t
+usbd_req_clear_tt_buffer(struct usb_device *udev, struct mtx *mtx,
+    uint8_t port, uint8_t addr, uint8_t type, uint8_t endpoint)
+{
+	struct usb_device_request req;
+	uint16_t wValue;
+
+	/* For single TT HUBs the port should be 1 */
+
+	if (udev->ddesc.bDeviceClass == UDCLASS_HUB &&
+	    udev->ddesc.bDeviceProtocol == UDPROTO_HSHUBSTT)
+		port = 1;
+
+	wValue = (endpoint & 0xF) | ((addr & 0x7F) << 4) |
+	    ((endpoint & 0x80) << 8) | ((type & 3) << 12);
+
+	req.bmRequestType = UT_WRITE_CLASS_OTHER;
+	req.bRequest = UR_CLEAR_TT_BUFFER;
+	USETW(req.wValue, wValue);
+	req.wIndex[0] = port;
+	req.wIndex[1] = 0;
+	USETW(req.wLength, 0);
+	return (usbd_do_request(udev, mtx, &req, 0));
+}

Modified: projects/largeSMP/sys/dev/usb/usb_request.h
==============================================================================
--- projects/largeSMP/sys/dev/usb/usb_request.h	Mon Jun  6 22:03:09 2011	(r222790)
+++ projects/largeSMP/sys/dev/usb/usb_request.h	Mon Jun  6 22:06:42 2011	(r222791)
@@ -85,5 +85,9 @@ usb_error_t usbd_req_set_hub_u2_timeout(
 		    struct mtx *mtx, uint8_t port, uint8_t timeout);
 usb_error_t usbd_req_set_hub_depth(struct usb_device *udev,
 		    struct mtx *mtx, uint16_t depth);
+usb_error_t usbd_req_reset_tt(struct usb_device *udev, struct mtx *mtx,
+		    uint8_t port);
+usb_error_t usbd_req_clear_tt_buffer(struct usb_device *udev, struct mtx *mtx,
+		    uint8_t port, uint8_t addr, uint8_t type, uint8_t endpoint);
 
 #endif					/* _USB_REQUEST_H_ */

Modified: projects/largeSMP/sys/dev/usb/usb_transfer.c
==============================================================================
--- projects/largeSMP/sys/dev/usb/usb_transfer.c	Mon Jun  6 22:03:09 2011	(r222790)
+++ projects/largeSMP/sys/dev/usb/usb_transfer.c	Mon Jun  6 22:06:42 2011	(r222791)
@@ -2928,6 +2928,11 @@ repeat:
 	usbd_transfer_unsetup(udev->ctrl_xfer, USB_CTRL_XFER_MAX);
 
 	/*
+	 * Reset clear stall error counter.
+	 */
+	udev->clear_stall_errors = 0;
+
+	/*
 	 * Try to setup a new USB transfer for the
 	 * default control endpoint:
 	 */

Modified: projects/largeSMP/sys/dev/usb/usbdi.h
==============================================================================
--- projects/largeSMP/sys/dev/usb/usbdi.h	Mon Jun  6 22:03:09 2011	(r222790)
+++ projects/largeSMP/sys/dev/usb/usbdi.h	Mon Jun  6 22:06:42 2011	(r222791)
@@ -542,6 +542,7 @@ void	usbd_m_copy_in(struct usb_page_cach
 	    struct mbuf *m, usb_size_t src_offset, usb_frlength_t src_len);
 void	usbd_frame_zero(struct usb_page_cache *cache, usb_frlength_t offset,
 	    usb_frlength_t len);
+void	usbd_start_re_enumerate(struct usb_device *udev);
 
 int	usb_fifo_attach(struct usb_device *udev, void *priv_sc,
 	    struct mtx *priv_mtx, struct usb_fifo_methods *pm,

Modified: projects/largeSMP/sys/netinet/in_pcb.h
==============================================================================
--- projects/largeSMP/sys/netinet/in_pcb.h	Mon Jun  6 22:03:09 2011	(r222790)
+++ projects/largeSMP/sys/netinet/in_pcb.h	Mon Jun  6 22:06:42 2011	(r222791)
@@ -44,6 +44,7 @@
 #include <sys/_rwlock.h>
 
 #ifdef _KERNEL
+#include <sys/lock.h>
 #include <sys/rwlock.h>
 #include <net/vnet.h>
 #include <vm/uma.h>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106062206.p56M6gdc051097>