summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-mem.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-05-14 20:44:22 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 06:44:51 +0200
commitf88ba78d9ac0e1f583da4cada80b8816ca761a3f (patch)
treee02af0c83817517c2c5ba20c3cf9335b2f4ab9a9 /drivers/usb/host/xhci-mem.c
parentUSB: xHCI: Fix interrupt moderation. (diff)
downloadlinux-f88ba78d9ac0e1f583da4cada80b8816ca761a3f.tar.xz
linux-f88ba78d9ac0e1f583da4cada80b8816ca761a3f.zip
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.c5
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,
int xhci_endpoint_init(struct xhci_hcd *xhci,
struct xhci_virt_device *virt_dev,
struct usb_device *udev,
- struct usb_host_endpoint *ep)
+ struct usb_host_endpoint *ep,
+ gfp_t mem_flags)
{
unsigned int ep_index;
struct xhci_ep_ctx *ep_ctx;
@@ -472,7 +473,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
ep_ctx = &virt_dev->in_ctx->ep[ep_index];
/* Set up the endpoint ring */
- virt_dev->new_ep_rings[ep_index] = xhci_ring_alloc(xhci, 1, true, GFP_KERNEL);
+ virt_dev->new_ep_rings[ep_index] = xhci_ring_alloc(xhci, 1, true, mem_flags);
if (!virt_dev->new_ep_rings[ep_index])
return -ENOMEM;
ep_ring = virt_dev->new_ep_rings[ep_index];