Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 280936
b: refs/heads/master
c: c71fc37
h: refs/heads/master
v: v3
  • Loading branch information
Felipe Balbi committed Dec 21, 2011
1 parent d89a1f4 commit 84aa547
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 69 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: 898c60867827796f0f6f84e5de446098d776c866
refs/heads/master: c71fc37c191747ea1f00424e84f96c1f88e52bfc
146 changes: 78 additions & 68 deletions trunk/drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,78 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep,
kfree(req);
}

/**
* dwc3_prepare_one_trb - setup one TRB from one request
* @dep: endpoint for which this request is prepared
* @req: dwc3_request pointer
*/
static int dwc3_prepare_one_trb(struct dwc3_ep *dep,
struct dwc3_request *req, unsigned last)
{
struct dwc3_trb_hw *trb_hw;
struct dwc3_trb trb;

unsigned int cur_slot;

trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
cur_slot = dep->free_slot;
dep->free_slot++;

/* Skip the LINK-TRB on ISOC */
if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
usb_endpoint_xfer_isoc(dep->desc))
return 0;

dwc3_gadget_move_request_queued(req);
memset(&trb, 0, sizeof(trb));

req->trb = trb_hw;

if (usb_endpoint_xfer_isoc(dep->desc)) {
trb.isp_imi = true;
trb.csp = true;
} else {
trb.lst = last;
}

if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
trb.sid_sofn = req->request.stream_id;

switch (usb_endpoint_type(dep->desc)) {
case USB_ENDPOINT_XFER_CONTROL:
trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP;
break;

case USB_ENDPOINT_XFER_ISOC:
trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;

/* IOC every DWC3_TRB_NUM / 4 so we can refill */
if (!(cur_slot % (DWC3_TRB_NUM / 4)))
trb.ioc = last;
break;

case USB_ENDPOINT_XFER_BULK:
case USB_ENDPOINT_XFER_INT:
trb.trbctl = DWC3_TRBCTL_NORMAL;
break;
default:
/*
* This is only possible with faulty memory because we
* checked it already :)
*/
BUG();
}

trb.length = req->request.length;
trb.bplh = req->request.dma;
trb.hwo = true;

dwc3_trb_to_hw(&trb, trb_hw);
req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw);

return 0;
}

/*
* dwc3_prepare_trbs - setup TRBs from requests
* @dep: endpoint for which requests are being prepared
Expand All @@ -552,14 +624,14 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep,
bool starting)
{
struct dwc3_request *req, *n, *ret = NULL;
struct dwc3_trb_hw *trb_hw;
struct dwc3_trb trb;
u32 trbs_left;
unsigned int last_one = 0;

BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);

/* the first request must not be queued */
trbs_left = (dep->busy_slot - dep->free_slot) & DWC3_TRB_MASK;

/*
* if busy & slot are equal than it is either full or empty. If we are
* starting to proceed requests then we are empty. Otherwise we ar
Expand Down Expand Up @@ -594,25 +666,11 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep,
return NULL;

list_for_each_entry_safe(req, n, &dep->request_list, list) {
unsigned int last_one = 0;
unsigned int cur_slot;

trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
cur_slot = dep->free_slot;
dep->free_slot++;

/* Skip the LINK-TRB on ISOC */
if (((cur_slot & DWC3_TRB_MASK) == DWC3_TRB_NUM - 1) &&
usb_endpoint_xfer_isoc(dep->desc))
continue;

dwc3_gadget_move_request_queued(req);
memset(&trb, 0, sizeof(trb));
trbs_left--;

/* Is our TRB pool empty? */
if (!trbs_left)
last_one = 1;

/* Is this the last request? */
if (list_empty(&dep->request_list))
last_one = 1;
Expand All @@ -625,57 +683,9 @@ static struct dwc3_request *dwc3_prepare_trbs(struct dwc3_ep *dep,
* While we're debugging the problem, as a workaround to
* multiple TRBs handling, use only one TRB at a time.
*/
last_one = 1;

req->trb = trb_hw;
if (!ret)
ret = req;

trb.bplh = req->request.dma;

if (usb_endpoint_xfer_isoc(dep->desc)) {
trb.isp_imi = true;
trb.csp = true;
} else {
trb.lst = last_one;
}

if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
trb.sid_sofn = req->request.stream_id;

switch (usb_endpoint_type(dep->desc)) {
case USB_ENDPOINT_XFER_CONTROL:
trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP;
break;

case USB_ENDPOINT_XFER_ISOC:
trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;

/* IOC every DWC3_TRB_NUM / 4 so we can refill */
if (!(cur_slot % (DWC3_TRB_NUM / 4)))
trb.ioc = last_one;
break;

case USB_ENDPOINT_XFER_BULK:
case USB_ENDPOINT_XFER_INT:
trb.trbctl = DWC3_TRBCTL_NORMAL;
break;
default:
/*
* This is only possible with faulty memory because we
* checked it already :)
*/
BUG();
}

trb.length = req->request.length;
trb.hwo = true;

dwc3_trb_to_hw(&trb, trb_hw);
req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw);

if (last_one)
break;
dwc3_prepare_one_trb(dep, req, true);
ret = req;
break;
}

return ret;
Expand Down

0 comments on commit 84aa547

Please sign in to comment.