diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2009-05-14 14:44:22 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-16 00:44:51 -0400 |
commit | f88ba78d9ac0e1f583da4cada80b8816ca761a3f (patch) | |
tree | e02af0c83817517c2c5ba20c3cf9335b2f4ab9a9 /drivers/usb/host/xhci-mem.c | |
parent | a4d88302268d1e458f7c6eb7855f1ba4b3a7cffc (diff) |
USB: xhci: Respect critical sections.
Narrow down time spent holding the xHCI spinlock so that it's only used to
protect the xHCI rings, not as mutual exclusion. Stop allocating memory
while holding the spinlock and calling xhci_alloc_virt_device() and
xhci_endpoint_init().
The USB core should have locking in it to prevent device state to be
manipulated by more than one kernel thread. E.g. you can't free a device
while you're in the middle of setting a new configuration. So removing
the locks from the sections where xhci_alloc_dev() and
xhci_reset_bandwidth() touch xHCI's representation of the device should be
OK.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 37a83878a064..c8a72de1c508 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -460,7 +460,8 @@ static inline u32 xhci_get_endpoint_type(struct usb_device *udev, | |||
460 | int xhci_endpoint_init(struct xhci_hcd *xhci, | 460 | int xhci_endpoint_init(struct xhci_hcd *xhci, |
461 | struct xhci_virt_device *virt_dev, | 461 | struct xhci_virt_device *virt_dev, |
462 | struct usb_device *udev, | 462 | struct usb_device *udev, |
463 | struct usb_host_endpoint *ep) | 463 | struct usb_host_endpoint *ep, |
464 | gfp_t mem_flags) | ||
464 | { | 465 | { |
465 | unsigned int ep_index; | 466 | unsigned int ep_index; |
466 | struct xhci_ep_ctx *ep_ctx; | 467 | struct xhci_ep_ctx *ep_ctx; |
@@ -472,7 +473,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, | |||
472 | ep_ctx = &virt_dev->in_ctx->ep[ep_index]; | 473 | ep_ctx = &virt_dev->in_ctx->ep[ep_index]; |
473 | 474 | ||
474 | /* Set up the endpoint ring */ | 475 | /* Set up the endpoint ring */ |
475 | virt_dev->new_ep_rings[ep_index] = xhci_ring_alloc(xhci, 1, true, GFP_KERNEL); | 476 | virt_dev->new_ep_rings[ep_index] = xhci_ring_alloc(xhci, 1, true, mem_flags); |
476 | if (!virt_dev->new_ep_rings[ep_index]) | 477 | if (!virt_dev->new_ep_rings[ep_index]) |
477 | return -ENOMEM; | 478 | return -ENOMEM; |
478 | ep_ring = virt_dev->new_ep_rings[ep_index]; | 479 | ep_ring = virt_dev->new_ep_rings[ep_index]; |