diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-05-11 14:44:27 +0200 | 
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-05-11 14:44:31 +0200 | 
| commit | 41fb454ebe6024f5c1e3b3cbc0abc0da762e7b51 (patch) | |
| tree | 51c50bcb67a5039448ddfa1869d7948cab1217e9 /drivers/usb/core | |
| parent | 19c1a6f5764d787113fa323ffb18be7991208f82 (diff) | |
| parent | 091bf7624d1c90cec9e578a18529f615213ff847 (diff) | |
Merge commit 'v2.6.30-rc5' into core/iommu
Merge reason: core/iommu was on an .30-rc1 base,
              update it to .30-rc5 to refresh.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/usb/core')
| -rw-r--r-- | drivers/usb/core/buffer.c | 2 | ||||
| -rw-r--r-- | drivers/usb/core/devio.c | 2 | ||||
| -rw-r--r-- | drivers/usb/core/hcd.c | 26 | ||||
| -rw-r--r-- | drivers/usb/core/hcd.h | 14 | ||||
| -rw-r--r-- | drivers/usb/core/message.c | 58 | ||||
| -rw-r--r-- | drivers/usb/core/usb.c | 2 | 
6 files changed, 80 insertions, 24 deletions
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index cadb2dc1d28..3ba2fff7149 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c @@ -119,7 +119,7 @@ void *hcd_buffer_alloc(  		if (size <= pool_max [i])  			return dma_pool_alloc(hcd->pool [i], mem_flags, dma);  	} -	return dma_alloc_coherent(hcd->self.controller, size, dma, 0); +	return dma_alloc_coherent(hcd->self.controller, size, dma, mem_flags);  }  void hcd_buffer_free( diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index df3c539f652..308609039c7 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -841,7 +841,7 @@ static int proc_resetep(struct dev_state *ps, void __user *arg)  	ret = checkintf(ps, ret);  	if (ret)  		return ret; -	usb_settoggle(ps->dev, ep & 0xf, !(ep & USB_DIR_IN), 0); +	usb_reset_endpoint(ps->dev, ep);  	return 0;  } diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 81fa8506825..42b93da1085 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1539,6 +1539,32 @@ void usb_hcd_disable_endpoint(struct usb_device *udev,  		hcd->driver->endpoint_disable(hcd, ep);  } +/** + * usb_hcd_reset_endpoint - reset host endpoint state + * @udev: USB device. + * @ep:   the endpoint to reset. + * + * Resets any host endpoint state such as the toggle bit, sequence + * number and current window. + */ +void usb_hcd_reset_endpoint(struct usb_device *udev, +			    struct usb_host_endpoint *ep) +{ +	struct usb_hcd *hcd = bus_to_hcd(udev->bus); + +	if (hcd->driver->endpoint_reset) +		hcd->driver->endpoint_reset(hcd, ep); +	else { +		int epnum = usb_endpoint_num(&ep->desc); +		int is_out = usb_endpoint_dir_out(&ep->desc); +		int is_control = usb_endpoint_xfer_control(&ep->desc); + +		usb_settoggle(udev, epnum, is_out, 0); +		if (is_control) +			usb_settoggle(udev, epnum, !is_out, 0); +	} +} +  /* Protect against drivers that try to unlink URBs after the device   * is gone, by waiting until all unlinks for @udev are finished.   * Since we don't currently track URBs by device, simply wait until diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index f750eb1ab59..e7d4479de41 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -206,6 +206,11 @@ struct hc_driver {  	void 	(*endpoint_disable)(struct usb_hcd *hcd,  			struct usb_host_endpoint *ep); +	/* (optional) reset any endpoint state such as sequence number +	   and current window */ +	void 	(*endpoint_reset)(struct usb_hcd *hcd, +			struct usb_host_endpoint *ep); +  	/* root hub support */  	int	(*hub_status_data) (struct usb_hcd *hcd, char *buf);  	int	(*hub_control) (struct usb_hcd *hcd, @@ -234,6 +239,8 @@ extern void usb_hcd_flush_endpoint(struct usb_device *udev,  		struct usb_host_endpoint *ep);  extern void usb_hcd_disable_endpoint(struct usb_device *udev,  		struct usb_host_endpoint *ep); +extern void usb_hcd_reset_endpoint(struct usb_device *udev, +		struct usb_host_endpoint *ep);  extern void usb_hcd_synchronize_unlinks(struct usb_device *udev);  extern int usb_hcd_get_frame_number(struct usb_device *udev); @@ -279,6 +286,13 @@ extern irqreturn_t usb_hcd_irq(int irq, void *__hcd);  extern void usb_hc_died(struct usb_hcd *hcd);  extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd); +/* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */ +#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1) +#define	usb_dotoggle(dev, ep, out)  ((dev)->toggle[out] ^= (1 << (ep))) +#define usb_settoggle(dev, ep, out, bit) \ +		((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << (ep))) | \ +		 ((bit) << (ep))) +  /* -------------------------------------------------------------------------- */  /* Enumeration is only for the hub driver, or HCD virtual root hubs */ diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 30a0690f368..b6262837765 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1002,8 +1002,7 @@ int usb_clear_halt(struct usb_device *dev, int pipe)  	 * the copy in usb-storage, for as long as we need two copies.  	 */ -	/* toggle was reset by the clear */ -	usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0); +	usb_reset_endpoint(dev, endp);  	return 0;  } @@ -1076,6 +1075,30 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,  }  /** + * usb_reset_endpoint - Reset an endpoint's state. + * @dev: the device whose endpoint is to be reset + * @epaddr: the endpoint's address.  Endpoint number for output, + *	endpoint number + USB_DIR_IN for input + * + * Resets any host-side endpoint state such as the toggle bit, + * sequence number or current window. + */ +void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr) +{ +	unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; +	struct usb_host_endpoint *ep; + +	if (usb_endpoint_out(epaddr)) +		ep = dev->ep_out[epnum]; +	else +		ep = dev->ep_in[epnum]; +	if (ep) +		usb_hcd_reset_endpoint(dev, ep); +} +EXPORT_SYMBOL_GPL(usb_reset_endpoint); + + +/**   * usb_disable_interface -- Disable all endpoints for an interface   * @dev: the device whose interface is being disabled   * @intf: pointer to the interface descriptor @@ -1117,7 +1140,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)  		usb_disable_endpoint(dev, i, true);  		usb_disable_endpoint(dev, i + USB_DIR_IN, true);  	} -	dev->toggle[0] = dev->toggle[1] = 0;  	/* getting rid of interfaces will disconnect  	 * any drivers bound to them (a key side effect) @@ -1154,28 +1176,24 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)   * usb_enable_endpoint - Enable an endpoint for USB communications   * @dev: the device whose interface is being enabled   * @ep: the endpoint - * @reset_toggle: flag to set the endpoint's toggle back to 0 + * @reset_ep: flag to reset the endpoint state   * - * Resets the endpoint toggle if asked, and sets dev->ep_{in,out} pointers. + * Resets the endpoint state if asked, and sets dev->ep_{in,out} pointers.   * For control endpoints, both the input and output sides are handled.   */  void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep, -		bool reset_toggle) +		bool reset_ep)  {  	int epnum = usb_endpoint_num(&ep->desc);  	int is_out = usb_endpoint_dir_out(&ep->desc);  	int is_control = usb_endpoint_xfer_control(&ep->desc); -	if (is_out || is_control) { -		if (reset_toggle) -			usb_settoggle(dev, epnum, 1, 0); +	if (reset_ep) +		usb_hcd_reset_endpoint(dev, ep); +	if (is_out || is_control)  		dev->ep_out[epnum] = ep; -	} -	if (!is_out || is_control) { -		if (reset_toggle) -			usb_settoggle(dev, epnum, 0, 0); +	if (!is_out || is_control)  		dev->ep_in[epnum] = ep; -	}  	ep->enabled = 1;  } @@ -1183,18 +1201,18 @@ void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep,   * usb_enable_interface - Enable all the endpoints for an interface   * @dev: the device whose interface is being enabled   * @intf: pointer to the interface descriptor - * @reset_toggles: flag to set the endpoints' toggles back to 0 + * @reset_eps: flag to reset the endpoints' state   *   * Enables all the endpoints for the interface's current altsetting.   */  void usb_enable_interface(struct usb_device *dev, -		struct usb_interface *intf, bool reset_toggles) +		struct usb_interface *intf, bool reset_eps)  {  	struct usb_host_interface *alt = intf->cur_altsetting;  	int i;  	for (i = 0; i < alt->desc.bNumEndpoints; ++i) -		usb_enable_endpoint(dev, &alt->endpoint[i], reset_toggles); +		usb_enable_endpoint(dev, &alt->endpoint[i], reset_eps);  }  /** @@ -1335,7 +1353,7 @@ EXPORT_SYMBOL_GPL(usb_set_interface);   * This issues a standard SET_CONFIGURATION request to the device using   * the current configuration.  The effect is to reset most USB-related   * state in the device, including interface altsettings (reset to zero), - * endpoint halts (cleared), and data toggle (only for bulk and interrupt + * endpoint halts (cleared), and endpoint state (only for bulk and interrupt   * endpoints).  Other usbcore state is unchanged, including bindings of   * usb device drivers to interfaces.   * @@ -1343,7 +1361,7 @@ EXPORT_SYMBOL_GPL(usb_set_interface);   * (multi-interface) devices.  Instead, the driver for each interface may   * use usb_set_interface() on the interfaces it claims.  Be careful though;   * some devices don't support the SET_INTERFACE request, and others won't - * reset all the interface state (notably data toggles).  Resetting the whole + * reset all the interface state (notably endpoint state).  Resetting the whole   * configuration would affect other drivers' interfaces.   *   * The caller must own the device lock. @@ -1376,8 +1394,6 @@ int usb_reset_configuration(struct usb_device *dev)  	if (retval < 0)  		return retval; -	dev->toggle[0] = dev->toggle[1] = 0; -  	/* re-init hc/hcd interface/endpoint state */  	for (i = 0; i < config->desc.bNumInterfaces; i++) {  		struct usb_interface *intf = config->interface[i]; diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index dcfc072630c..7eee400d3e3 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -362,7 +362,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent,  	dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;  	dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;  	/* ep0 maxpacket comes later, from device descriptor */ -	usb_enable_endpoint(dev, &dev->ep0, true); +	usb_enable_endpoint(dev, &dev->ep0, false);  	dev->can_submit = 1;  	/* Save readable and stable topology id, distinguishing devices  | 
