aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorAndrew Thompson <thompsa@FreeBSD.org>2009-02-24 03:41:52 +0000
committerAndrew Thompson <thompsa@FreeBSD.org>2009-02-24 03:41:52 +0000
commite280503373883f7625ce6eb06e511c9174c1d7e0 (patch)
tree13d47a7128085f71816e3d34526404331e4d64fa /sys/dev
parent16589bea5b93d4f319d8d22a7ac5806931d2b75b (diff)
downloadsrc-e280503373883f7625ce6eb06e511c9174c1d7e0.tar.gz
src-e280503373883f7625ce6eb06e511c9174c1d7e0.zip
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
Notes
Notes: svn path=/head/; revision=188986
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/usb_device.c48
-rw-r--r--sys/dev/usb/usb_generic.c4
-rw-r--r--sys/dev/usb/usb_handle_request.c4
-rw-r--r--sys/dev/usb/usb_hub.c40
4 files changed, 55 insertions, 41 deletions
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index 61f63dbc6f86..7746c010d0a8 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -551,12 +551,12 @@ usb2_set_config_index(struct usb2_device *udev, uint8_t index)
* 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 *udev, uint8_t index)
* 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 *udev, uint8_t index)
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, uint8_t index)
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_device *udev,
}
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_device *udev,
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, struct usb2_bus *bus,
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, struct usb2_bus *bus,
"(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, struct usb2_bus *bus,
* 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, struct usb2_bus *bus,
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, struct usb2_bus *bus,
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, struct usb2_bus *bus,
/* 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;
}
diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c
index 15ca909bfa1f..75b985c2c52a 100644
--- a/sys/dev/usb/usb_generic.c
+++ b/sys/dev/usb/usb_generic.c
@@ -664,7 +664,7 @@ ugen_get_cdesc(struct usb2_fifo *f, struct usb2_gen_descriptor *ugd)
} 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, struct usb2_gen_descriptor *ugd)
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 {
diff --git a/sys/dev/usb/usb_handle_request.c b/sys/dev/usb/usb_handle_request.c
index 05a739ae4dd8..3d2425a323ea 100644
--- a/sys/dev/usb/usb_handle_request.c
+++ b/sys/dev/usb/usb_handle_request.c
@@ -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) {
diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c
index a0b4e8516f13..dc6df8ddfdc3 100644
--- a/sys/dev/usb/usb_hub.c
+++ b/sys/dev/usb/usb_hub.c
@@ -244,7 +244,7 @@ uhub_read_port_status(struct uhub_softc *sc, uint8_t portno)
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_softc *sc, uint8_t portno)
/* 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 *udev)
/* 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 *udev)
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;