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>