diff options
Diffstat (limited to 'drivers/usb/host')
| -rw-r--r-- | drivers/usb/host/ohci-at91.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-hub.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/oxu210hp-hcd.c | 6 | ||||
| -rw-r--r-- | drivers/usb/host/sl811-hcd.c | 6 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-mem.c | 65 | ||||
| -rw-r--r-- | drivers/usb/host/xhci.h | 4 | 
6 files changed, 78 insertions, 7 deletions
| diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 68b83ab70719..944291e10f97 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -331,6 +331,8 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)  	 */  	if (at91_suspend_entering_slow_clock()) {  		ohci_usb_reset (ohci); +		/* flush the writes */ +		(void) ohci_readl (ohci, &ohci->regs->control);  		at91_stop_clock();  	} diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 32bbce9718f0..65cac8cc8921 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -697,7 +697,7 @@ static int ohci_hub_control (  	u16		wLength  ) {  	struct ohci_hcd	*ohci = hcd_to_ohci (hcd); -	int		ports = hcd_to_bus (hcd)->root_hub->maxchild; +	int		ports = ohci->num_ports;  	u32		temp;  	int		retval = 0; diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 50f57f468836..e62b30b3e429 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -660,13 +660,13 @@ static struct ehci_qh *oxu_qh_alloc(struct oxu_hcd *oxu)  		if (qh->dummy == NULL) {  			oxu_dbg(oxu, "no dummy td\n");  			oxu->qh_used[i] = 0; - -			return NULL; +			qh = NULL; +			goto unlock;  		}  		oxu->qh_used[i] = 1;  	} - +unlock:  	spin_unlock(&oxu->mem_lock);  	return qh; diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index e11cc3aa4b82..3b867a8af7b2 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -720,10 +720,10 @@ retry:  		/* port status seems weird until after reset, so  		 * force the reset and make khubd clean up later.  		 */ -		if (sl811->stat_insrmv & 1) -			sl811->port1 |= 1 << USB_PORT_FEAT_CONNECTION; -		else +		if (irqstat & SL11H_INTMASK_RD)  			sl811->port1 &= ~(1 << USB_PORT_FEAT_CONNECTION); +		else +			sl811->port1 |= 1 << USB_PORT_FEAT_CONNECTION;  		sl811->port1 |= 1 << USB_PORT_FEAT_C_CONNECTION; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index c09539bad1ee..d64f5724bfc4 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -582,6 +582,19 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev,  	return EP_INTERVAL(interval);  } +/* The "Mult" field in the endpoint context is only set for SuperSpeed devices. + * High speed endpoint descriptors can define "the number of additional + * transaction opportunities per microframe", but that goes in the Max Burst + * endpoint context field. + */ +static inline u32 xhci_get_endpoint_mult(struct usb_device *udev, +		struct usb_host_endpoint *ep) +{ +	if (udev->speed != USB_SPEED_SUPER || !ep->ss_ep_comp) +		return 0; +	return ep->ss_ep_comp->desc.bmAttributes; +} +  static inline u32 xhci_get_endpoint_type(struct usb_device *udev,  		struct usb_host_endpoint *ep)  { @@ -612,6 +625,36 @@ static inline u32 xhci_get_endpoint_type(struct usb_device *udev,  	return type;  } +/* Return the maximum endpoint service interval time (ESIT) payload. + * Basically, this is the maxpacket size, multiplied by the burst size + * and mult size. + */ +static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, +		struct usb_device *udev, +		struct usb_host_endpoint *ep) +{ +	int max_burst; +	int max_packet; + +	/* Only applies for interrupt or isochronous endpoints */ +	if (usb_endpoint_xfer_control(&ep->desc) || +			usb_endpoint_xfer_bulk(&ep->desc)) +		return 0; + +	if (udev->speed == USB_SPEED_SUPER) { +		if (ep->ss_ep_comp) +			return ep->ss_ep_comp->desc.wBytesPerInterval; +		xhci_warn(xhci, "WARN no SS endpoint companion descriptor.\n"); +		/* Assume no bursts, no multiple opportunities to send. */ +		return ep->desc.wMaxPacketSize; +	} + +	max_packet = ep->desc.wMaxPacketSize & 0x3ff; +	max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11; +	/* A 0 in max burst means 1 transfer per ESIT */ +	return max_packet * (max_burst + 1); +} +  int xhci_endpoint_init(struct xhci_hcd *xhci,  		struct xhci_virt_device *virt_dev,  		struct usb_device *udev, @@ -623,6 +666,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,  	struct xhci_ring *ep_ring;  	unsigned int max_packet;  	unsigned int max_burst; +	u32 max_esit_payload;  	ep_index = xhci_get_endpoint_index(&ep->desc);  	ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); @@ -644,6 +688,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,  	ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state;  	ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep); +	ep_ctx->ep_info |= EP_MULT(xhci_get_endpoint_mult(udev, ep));  	/* FIXME dig Mult and streams info out of ep companion desc */ @@ -689,6 +734,26 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,  	default:  		BUG();  	} +	max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep); +	ep_ctx->tx_info = MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload); + +	/* +	 * XXX no idea how to calculate the average TRB buffer length for bulk +	 * endpoints, as the driver gives us no clue how big each scatter gather +	 * list entry (or buffer) is going to be. +	 * +	 * For isochronous and interrupt endpoints, we set it to the max +	 * available, until we have new API in the USB core to allow drivers to +	 * declare how much bandwidth they actually need. +	 * +	 * Normally, it would be calculated by taking the total of the buffer +	 * lengths in the TD and then dividing by the number of TRBs in a TD, +	 * including link TRBs, No-op TRBs, and Event data TRBs.  Since we don't +	 * use Event Data TRBs, and we don't chain in a link TRB on short +	 * transfers, we're basically dividing by 1. +	 */ +	ep_ctx->tx_info |= AVG_TRB_LENGTH_FOR_EP(max_esit_payload); +  	/* FIXME Debug endpoint context */  	return 0;  } diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e5eb09b2f38e..ea389e9a4931 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -609,6 +609,10 @@ struct xhci_ep_ctx {  #define MAX_PACKET_MASK		(0xffff << 16)  #define MAX_PACKET_DECODED(p)	(((p) >> 16) & 0xffff) +/* tx_info bitmasks */ +#define AVG_TRB_LENGTH_FOR_EP(p)	((p) & 0xffff) +#define MAX_ESIT_PAYLOAD_FOR_EP(p)	(((p) & 0xffff) << 16) +  /**   * struct xhci_input_control_context | 
