Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 151413
b: refs/heads/master
c: d0e96f5
h: refs/heads/master
i:
  151411: a522628
v: v3
  • Loading branch information
Sarah Sharp authored and Greg Kroah-Hartman committed Jun 16, 2009
1 parent 0dac05c commit bd49298
Show file tree
Hide file tree
Showing 6 changed files with 507 additions and 4 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6d65b78a093552fb42448480d4c66bf093a6d4cf
refs/heads/master: d0e96f5a71a032ced0c35f521c1cbd67e816922a
93 changes: 93 additions & 0 deletions trunk/drivers/usb/host/xhci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,99 @@ void xhci_shutdown(struct usb_hcd *hcd)

/*-------------------------------------------------------------------------*/

/**
* xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and
* HCDs. Find the index for an endpoint given its descriptor. Use the return
* value to right shift 1 for the bitmask.
*
* Index = (epnum * 2) + direction - 1,
* where direction = 0 for OUT, 1 for IN.
* For control endpoints, the IN index is used (OUT index is unused), so
* index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2)
*/
unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc)
{
unsigned int index;
if (usb_endpoint_xfer_control(desc))
index = (unsigned int) (usb_endpoint_num(desc)*2);
else
index = (unsigned int) (usb_endpoint_num(desc)*2) +
(usb_endpoint_dir_in(desc) ? 1 : 0) - 1;
return index;
}

/* Returns 1 if the arguments are OK;
* returns 0 this is a root hub; returns -EINVAL for NULL pointers.
*/
int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev,
struct usb_host_endpoint *ep, int check_ep, const char *func) {
if (!hcd || (check_ep && !ep) || !udev) {
printk(KERN_DEBUG "xHCI %s called with invalid args\n",
func);
return -EINVAL;
}
if (!udev->parent) {
printk(KERN_DEBUG "xHCI %s called for root hub\n",
func);
return 0;
}
if (!udev->slot_id) {
printk(KERN_DEBUG "xHCI %s called with unaddressed device\n",
func);
return -EINVAL;
}
return 1;
}

/*
* non-error returns are a promise to giveback() the urb later
* we drop ownership so next owner (or urb unlink) can get it
*/
int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
unsigned long flags;
int ret = 0;
unsigned int slot_id, ep_index;

if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0)
return -EINVAL;

slot_id = urb->dev->slot_id;
ep_index = xhci_get_endpoint_index(&urb->ep->desc);
/* Only support ep 0 control transfers for now */
if (ep_index != 0) {
xhci_dbg(xhci, "WARN: urb submitted to unsupported ep %x\n",
urb->ep->desc.bEndpointAddress);
return -ENOSYS;
}

spin_lock_irqsave(&xhci->lock, flags);
if (!xhci->devs || !xhci->devs[slot_id]) {
if (!in_interrupt())
dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n");
return -EINVAL;
}
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
if (!in_interrupt())
xhci_dbg(xhci, "urb submitted during PCI suspend\n");
ret = -ESHUTDOWN;
goto exit;
}
ret = queue_ctrl_tx(xhci, mem_flags, urb, slot_id, ep_index);
exit:
spin_unlock_irqrestore(&xhci->lock, flags);
return ret;
}

/* Remove from hardware lists
* completions normally happen asynchronously
*/
int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
{
return -ENOSYS;
}

/*
* At this point, the struct usb_device is about to go away, the device has
* disconnected, and all traffic has been stopped and the endpoints have been
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/usb/host/xhci-mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
if (!ring)
return 0;

INIT_LIST_HEAD(&ring->td_list);
if (num_segs == 0)
return ring;

Expand Down Expand Up @@ -188,6 +189,7 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
return 0;
}

/* All the xhci_tds in the ring's TD list should be freed at this point */
void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
{
struct xhci_virt_device *dev;
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/usb/host/xhci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ static const struct hc_driver xhci_pci_hc_driver = {
/*
* managing i/o requests and associated device resources
*/
.urb_enqueue = xhci_urb_enqueue,
.urb_dequeue = xhci_urb_dequeue,
.alloc_dev = xhci_alloc_dev,
.free_dev = xhci_free_dev,
.address_device = xhci_address_device,
Expand Down
Loading

0 comments on commit bd49298

Please sign in to comment.