Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Feb 2009 03:41:53 +0000 (UTC)
From:      Andrew Thompson <thompsa@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r188986 - head/sys/dev/usb
Message-ID:  <200902240341.n1O3frNQ049764@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: thompsa
Date: Tue Feb 24 03:41:52 2009
New Revision: 188986
URL: http://svn.freebsd.org/changeset/base/188986

Log:
  MFp4 //depot/projects/usb@157958
  
  - We don't need to exit the Giant mutex when sleeping. This is done
    automatically. Replace Giant by NULL mutex for all control requests in the
    enumeration path.
  - Optimise away duplicate alternate interface selection requests in USB Host
    mode.
  
  Submitted by:	Hans Petter Selasky

Modified:
  head/sys/dev/usb/usb_device.c
  head/sys/dev/usb/usb_generic.c
  head/sys/dev/usb/usb_handle_request.c
  head/sys/dev/usb/usb_hub.c

Modified: head/sys/dev/usb/usb_device.c
==============================================================================
--- head/sys/dev/usb/usb_device.c	Tue Feb 24 03:40:48 2009	(r188985)
+++ head/sys/dev/usb/usb_device.c	Tue Feb 24 03:41:52 2009	(r188986)
@@ -551,12 +551,12 @@ usb2_set_config_index(struct usb2_device
 		 * device. "usb2_free_iface_data()" will also reset
 		 * the current config number and index.
 		 */
-		err = usb2_req_set_config(udev, &Giant, USB_UNCONFIG_NO);
+		err = usb2_req_set_config(udev, NULL, USB_UNCONFIG_NO);
 		goto done;
 	}
 	/* get the full config descriptor */
 	err = usb2_req_get_config_desc_full(udev,
-	    &Giant, &cdp, M_USB, index);
+	    NULL, &cdp, M_USB, index);
 	if (err) {
 		goto done;
 	}
@@ -583,7 +583,7 @@ usb2_set_config_index(struct usb2_device
 				 * determined by the HUB characteristics.
 				 */
 				err = usb2_req_get_hub_descriptor
-				    (udev, &Giant, &hd, 1);
+				    (udev, NULL, &hd, 1);
 				if (err) {
 					DPRINTFN(0, "could not read "
 					    "HUB descriptor: %s\n",
@@ -597,7 +597,7 @@ usb2_set_config_index(struct usb2_device
 				    UGETW(hd.wHubCharacteristics));
 			} else {
 				err = usb2_req_get_device_status
-				    (udev, &Giant, &ds);
+				    (udev, NULL, &ds);
 				if (err) {
 					DPRINTFN(0, "could not read "
 					    "device status: %s\n",
@@ -640,7 +640,7 @@ usb2_set_config_index(struct usb2_device
 	udev->curr_config_index = index;
 
 	/* Set the actual configuration value. */
-	err = usb2_req_set_config(udev, &Giant, cdp->bConfigurationValue);
+	err = usb2_req_set_config(udev, NULL, cdp->bConfigurationValue);
 	if (err) {
 		goto done;
 	}
@@ -669,8 +669,10 @@ done:
  *
  * This function will select an alternate interface index for the
  * given interface index. The interface should not be in use when this
- * function is called. That means there should be no open USB
- * transfers. Else an error is returned.
+ * function is called. That means there should not be any open USB
+ * transfers. Else an error is returned. If the alternate setting is
+ * already set this function will simply return success. This function
+ * is called in Host mode and Device mode!
  *
  * Returns:
  *    0: Success
@@ -697,6 +699,15 @@ usb2_set_alt_interface_index(struct usb2
 	}
 	if (udev->flags.usb2_mode == USB_MODE_DEVICE) {
 		usb2_detach_device(udev, iface_index, 1);
+	} else {
+		if (iface->alt_index == alt_index) {
+			/* 
+			 * Optimise away duplicate setting of
+			 * alternate setting in USB Host Mode!
+			 */
+			err = 0;
+			goto done;
+		}
 	}
 	/*
 	 * Free all generic FIFOs for this interface, except control
@@ -708,8 +719,7 @@ usb2_set_alt_interface_index(struct usb2
 	if (err) {
 		goto done;
 	}
-	err = usb2_req_set_alt_interface_no
-	    (udev, &Giant, iface_index,
+	err = usb2_req_set_alt_interface_no(udev, NULL, iface_index,
 	    iface->idesc->bAlternateSetting);
 
 done:
@@ -1415,7 +1425,7 @@ usb2_alloc_device(device_t parent_dev, s
 
 	if (udev->flags.usb2_mode == USB_MODE_HOST) {
 
-		err = usb2_req_set_address(udev, &Giant, device_index);
+		err = usb2_req_set_address(udev, NULL, device_index);
 
 		/* This is the new USB device address from now on */
 
@@ -1435,7 +1445,7 @@ usb2_alloc_device(device_t parent_dev, s
 			    "(ignored)\n", udev->address);
 		}
 		/* allow device time to set new address */
-		usb2_pause_mtx(&Giant, 
+		usb2_pause_mtx(NULL, 
 		    USB_MS_TO_TICKS(USB_SET_ADDRESS_SETTLE));
 	} else {
 		/* We are not self powered */
@@ -1464,13 +1474,13 @@ usb2_alloc_device(device_t parent_dev, s
 	 * 0. If this value is different from "USB_MAX_IPACKET" a new
 	 * USB control request will be setup!
 	 */
-	err = usb2_req_get_desc(udev, &Giant, NULL, &udev->ddesc,
+	err = usb2_req_get_desc(udev, NULL, NULL, &udev->ddesc,
 	    USB_MAX_IPACKET, USB_MAX_IPACKET, 0, UDESC_DEVICE, 0, 0);
 	if (err) {
 		DPRINTFN(0, "getting device descriptor "
 		    "at addr %d failed!\n", udev->address);
 		/* XXX try to re-enumerate the device */
-		err = usb2_req_re_enumerate(udev, &Giant);
+		err = usb2_req_re_enumerate(udev, NULL);
 		if (err) {
 			goto done;
 		}
@@ -1486,7 +1496,7 @@ usb2_alloc_device(device_t parent_dev, s
 	    udev->speed);
 
 	/* get the full device descriptor */
-	err = usb2_req_get_device_desc(udev, &Giant, &udev->ddesc);
+	err = usb2_req_get_device_desc(udev, NULL, &udev->ddesc);
 	if (err) {
 		DPRINTF("addr=%d, getting full desc failed\n",
 		    udev->address);
@@ -1525,7 +1535,7 @@ usb2_alloc_device(device_t parent_dev, s
 	    udev->ddesc.iProduct ||
 	    udev->ddesc.iSerialNumber) {
 		/* read out the language ID string */
-		err = usb2_req_get_string_desc(udev, &Giant,
+		err = usb2_req_get_string_desc(udev, NULL,
 		    (char *)scratch_ptr, 4, scratch_size,
 		    USB_LANGUAGE_TABLE);
 	} else {
@@ -1544,21 +1554,21 @@ usb2_alloc_device(device_t parent_dev, s
 
 	/* get serial number string */
 	err = usb2_req_get_string_any
-	    (udev, &Giant, (char *)scratch_ptr,
+	    (udev, NULL, (char *)scratch_ptr,
 	    scratch_size, udev->ddesc.iSerialNumber);
 
 	strlcpy(udev->serial, (char *)scratch_ptr, sizeof(udev->serial));
 
 	/* get manufacturer string */
 	err = usb2_req_get_string_any
-	    (udev, &Giant, (char *)scratch_ptr,
+	    (udev, NULL, (char *)scratch_ptr,
 	    scratch_size, udev->ddesc.iManufacturer);
 
 	strlcpy(udev->manufacturer, (char *)scratch_ptr, sizeof(udev->manufacturer));
 
 	/* get product string */
 	err = usb2_req_get_string_any
-	    (udev, &Giant, (char *)scratch_ptr,
+	    (udev, NULL, (char *)scratch_ptr,
 	    scratch_size, udev->ddesc.iProduct);
 
 	strlcpy(udev->product, (char *)scratch_ptr, sizeof(udev->product));
@@ -1609,7 +1619,7 @@ repeat_set_config:
 					set_config_failed = 1;
 					/* XXX try to re-enumerate the device */
 					err = usb2_req_re_enumerate(
-					    udev, &Giant);
+					    udev, NULL);
 					if (err == 0)
 					    goto repeat_set_config;
 				}

Modified: head/sys/dev/usb/usb_generic.c
==============================================================================
--- head/sys/dev/usb/usb_generic.c	Tue Feb 24 03:40:48 2009	(r188985)
+++ head/sys/dev/usb/usb_generic.c	Tue Feb 24 03:41:52 2009	(r188986)
@@ -664,7 +664,7 @@ ugen_get_cdesc(struct usb2_fifo *f, stru
 
 	} else {
 		if (usb2_req_get_config_desc_full(udev,
-		    &Giant, &cdesc, M_USBDEV,
+		    NULL, &cdesc, M_USBDEV,
 		    ugd->ugd_config_index)) {
 			return (ENXIO);
 		}
@@ -695,7 +695,7 @@ ugen_get_sdesc(struct usb2_fifo *f, stru
 	uint16_t size = sizeof(f->udev->bus->scratch[0].data);
 	int error;
 
-	if (usb2_req_get_string_desc(f->udev, &Giant, ptr,
+	if (usb2_req_get_string_desc(f->udev, NULL, ptr,
 	    size, ugd->ugd_lang_id, ugd->ugd_string_index)) {
 		error = EINVAL;
 	} else {

Modified: head/sys/dev/usb/usb_handle_request.c
==============================================================================
--- head/sys/dev/usb/usb_handle_request.c	Tue Feb 24 03:40:48 2009	(r188985)
+++ head/sys/dev/usb/usb_handle_request.c	Tue Feb 24 03:41:52 2009	(r188986)
@@ -277,6 +277,10 @@ tr_repeat:
 				}
 				break;
 			}
+			/* 
+			 * Doing the alternate setting will detach the
+			 * interface aswell:
+			 */
 			error = usb2_set_alt_interface_index(udev,
 			    iface_index, req.wValue[0]);
 			if (error) {

Modified: head/sys/dev/usb/usb_hub.c
==============================================================================
--- head/sys/dev/usb/usb_hub.c	Tue Feb 24 03:40:48 2009	(r188985)
+++ head/sys/dev/usb/usb_hub.c	Tue Feb 24 03:41:52 2009	(r188986)
@@ -244,7 +244,7 @@ uhub_read_port_status(struct uhub_softc 
 	usb2_error_t err;
 
 	err = usb2_req_get_port_status(
-	    sc->sc_udev, &Giant, &ps, portno);
+	    sc->sc_udev, NULL, &ps, portno);
 
 	/* update status regardless of error */
 
@@ -289,7 +289,7 @@ repeat:
 
 	/* first clear the port connection change bit */
 
-	err = usb2_req_clear_port_feature(udev, &Giant,
+	err = usb2_req_clear_port_feature(udev, NULL,
 	    portno, UHF_C_PORT_CONNECTION);
 
 	if (err) {
@@ -329,18 +329,18 @@ repeat:
 			DPRINTF("Port %d was still "
 			    "suspended, clearing.\n", portno);
 			err = usb2_req_clear_port_feature(sc->sc_udev,
-			    &Giant, portno, UHF_PORT_SUSPEND);
+			    NULL, portno, UHF_PORT_SUSPEND);
 		}
 		/* USB Host Mode */
 
 		/* wait for maximum device power up time */
 
-		usb2_pause_mtx(&Giant, 
+		usb2_pause_mtx(NULL, 
 		    USB_MS_TO_TICKS(USB_PORT_POWERUP_DELAY));
 
 		/* reset port, which implies enabling it */
 
-		err = usb2_req_reset_port(udev, &Giant, portno);
+		err = usb2_req_reset_port(udev, NULL, portno);
 
 		if (err) {
 			DPRINTFN(0, "port %d reset "
@@ -425,7 +425,7 @@ error:
 	if (err == 0) {
 		if (sc->sc_st.port_status & UPS_PORT_ENABLED) {
 			err = usb2_req_clear_port_feature(
-			    sc->sc_udev, &Giant,
+			    sc->sc_udev, NULL,
 			    portno, UHF_PORT_ENABLE);
 		}
 	}
@@ -459,7 +459,7 @@ uhub_suspend_resume_port(struct uhub_sof
 
 	/* first clear the port suspend change bit */
 
-	err = usb2_req_clear_port_feature(udev, &Giant,
+	err = usb2_req_clear_port_feature(udev, NULL,
 	    portno, UHF_C_PORT_SUSPEND);
 	if (err) {
 		DPRINTF("clearing suspend failed.\n");
@@ -542,7 +542,7 @@ uhub_explore(struct usb2_device *udev)
 		if (sc->sc_st.port_change & UPS_C_OVERCURRENT_INDICATOR) {
 			DPRINTF("Overcurrent on port %u.\n", portno);
 			err = usb2_req_clear_port_feature(
-			    udev, &Giant, portno, UHF_C_PORT_OVER_CURRENT);
+			    udev, NULL, portno, UHF_C_PORT_OVER_CURRENT);
 			if (err) {
 				/* most likely the HUB is gone */
 				break;
@@ -558,7 +558,7 @@ uhub_explore(struct usb2_device *udev)
 		}
 		if (sc->sc_st.port_change & UPS_C_PORT_ENABLED) {
 			err = usb2_req_clear_port_feature(
-			    udev, &Giant, portno, UHF_C_PORT_ENABLE);
+			    udev, NULL, portno, UHF_C_PORT_ENABLE);
 			if (err) {
 				/* most likely the HUB is gone */
 				break;
@@ -682,13 +682,13 @@ uhub_attach(device_t dev)
 	DPRINTFN(2, "getting HUB descriptor\n");
 
 	/* assuming that there is one port */
-	err = usb2_req_get_hub_descriptor(udev, &Giant, &hubdesc, 1);
+	err = usb2_req_get_hub_descriptor(udev, NULL, &hubdesc, 1);
 
 	nports = hubdesc.bNbrPorts;
 
 	if (!err && (nports >= 8)) {
 		/* get complete HUB descriptor */
-		err = usb2_req_get_hub_descriptor(udev, &Giant, &hubdesc, nports);
+		err = usb2_req_get_hub_descriptor(udev, NULL, &hubdesc, nports);
 	}
 	if (err) {
 		DPRINTFN(0, "getting hub descriptor failed,"
@@ -737,7 +737,7 @@ uhub_attach(device_t dev)
 		goto error;
 	}
 	/* wait with power off for a while */
-	usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(USB_POWER_DOWN_TIME));
+	usb2_pause_mtx(NULL, USB_MS_TO_TICKS(USB_POWER_DOWN_TIME));
 
 	/*
 	 * To have the best chance of success we do things in the exact same
@@ -784,7 +784,7 @@ uhub_attach(device_t dev)
 		}
 		if (!err) {
 			/* turn the power on */
-			err = usb2_req_set_port_feature(udev, &Giant,
+			err = usb2_req_set_port_feature(udev, NULL,
 			    portno, UHF_PORT_POWER);
 		}
 		if (err) {
@@ -795,7 +795,7 @@ uhub_attach(device_t dev)
 		    portno);
 
 		/* wait for stable power */
-		usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(pwrdly));
+		usb2_pause_mtx(NULL, USB_MS_TO_TICKS(pwrdly));
 	}
 
 	device_printf(dev, "%d port%s with %d "
@@ -1661,13 +1661,13 @@ usb2_dev_resume_peer(struct usb2_device 
 
 	/* resume current port (Valid in Host and Device Mode) */
 	err = usb2_req_clear_port_feature(udev->parent_hub,
-	    &Giant, udev->port_no, UHF_PORT_SUSPEND);
+	    NULL, udev->port_no, UHF_PORT_SUSPEND);
 	if (err) {
 		DPRINTFN(0, "Resuming port failed!\n");
 		return;
 	}
 	/* resume settle time */
-	usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(USB_PORT_RESUME_DELAY));
+	usb2_pause_mtx(NULL, USB_MS_TO_TICKS(USB_PORT_RESUME_DELAY));
 
 	if (bus->methods->device_resume != NULL) {
 		/* resume USB device on the USB controller */
@@ -1703,7 +1703,7 @@ usb2_dev_resume_peer(struct usb2_device 
 	if (usb2_peer_can_wakeup(udev)) {
 		/* clear remote wakeup */
 		err = usb2_req_clear_device_feature(udev,
-		    &Giant, UF_DEVICE_REMOTE_WAKEUP);
+		    NULL, UF_DEVICE_REMOTE_WAKEUP);
 		if (err) {
 			DPRINTFN(0, "Clearing device "
 			    "remote wakeup failed: %s!\n",
@@ -1782,7 +1782,7 @@ repeat:
 	if (usb2_peer_can_wakeup(udev)) {
 		/* allow device to do remote wakeup */
 		err = usb2_req_set_device_feature(udev,
-		    &Giant, UF_DEVICE_REMOTE_WAKEUP);
+		    NULL, UF_DEVICE_REMOTE_WAKEUP);
 		if (err) {
 			DPRINTFN(0, "Setting device "
 			    "remote wakeup failed!\n");
@@ -1803,12 +1803,12 @@ repeat:
 
 		/* do DMA delay */
 		temp = usb2_get_dma_delay(udev->bus);
-		usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(temp));
+		usb2_pause_mtx(NULL, USB_MS_TO_TICKS(temp));
 
 	}
 	/* suspend current port */
 	err = usb2_req_set_port_feature(udev->parent_hub,
-	    &Giant, udev->port_no, UHF_PORT_SUSPEND);
+	    NULL, udev->port_no, UHF_PORT_SUSPEND);
 	if (err) {
 		DPRINTFN(0, "Suspending port failed\n");
 		return;



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