mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2025-12-10 07:44:53 +01:00
usb: ci_udc: fix emissions of ZLPs
Commit6a13241635"ci_udc: Update the ci_udc driver to support bulk transfers" caused the value of "len" to change without updating subsquent users of that variable in ci_ep_submit_next_request(). This caused the code that detects when to emit ZLPs (Zero Length Packets) never to trigger, which in turn caused host timeouts when a ZLP was required, which in turn broke tests/dfu/, even despite the assertion in that commit's description that "These changes are tested for both the DFU and lthor." Fix this by modifying the added dtd iteration code not to modify "len", but rather to keep state in a separate variable. Rename the variables while we're at it so they describe their purpose better. Fixes:6a13241635("ci_udc: Update the ci_udc driver to support bulk transfers") Cc: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com> Signed-off-by: Stephen Warren <swarren@nvidia.com>
This commit is contained in:
parent
70eaeb03c1
commit
b337b3b2a5
1 changed files with 8 additions and 10 deletions
|
|
@ -426,7 +426,7 @@ static void ci_ep_submit_next_request(struct ci_ep *ci_ep)
|
||||||
int bit, num, len, in;
|
int bit, num, len, in;
|
||||||
struct ci_req *ci_req;
|
struct ci_req *ci_req;
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
uint32_t length, actlen;
|
uint32_t len_left, len_this_dtd;
|
||||||
struct ept_queue_item *dtd, *qtd;
|
struct ept_queue_item *dtd, *qtd;
|
||||||
|
|
||||||
ci_ep->req_primed = true;
|
ci_ep->req_primed = true;
|
||||||
|
|
@ -444,25 +444,23 @@ static void ci_ep_submit_next_request(struct ci_ep *ci_ep)
|
||||||
|
|
||||||
ci_req->dtd_count = 0;
|
ci_req->dtd_count = 0;
|
||||||
buf = ci_req->hw_buf;
|
buf = ci_req->hw_buf;
|
||||||
actlen = 0;
|
len_left = len;
|
||||||
dtd = item;
|
dtd = item;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
length = min(ci_req->req.length - actlen,
|
len_this_dtd = min(len_left, (unsigned)EP_MAX_LENGTH_TRANSFER);
|
||||||
(unsigned)EP_MAX_LENGTH_TRANSFER);
|
|
||||||
|
|
||||||
dtd->info = INFO_BYTES(length) | INFO_ACTIVE;
|
dtd->info = INFO_BYTES(len_this_dtd) | INFO_ACTIVE;
|
||||||
dtd->page0 = (unsigned long)buf;
|
dtd->page0 = (unsigned long)buf;
|
||||||
dtd->page1 = ((unsigned long)buf & 0xfffff000) + 0x1000;
|
dtd->page1 = ((unsigned long)buf & 0xfffff000) + 0x1000;
|
||||||
dtd->page2 = ((unsigned long)buf & 0xfffff000) + 0x2000;
|
dtd->page2 = ((unsigned long)buf & 0xfffff000) + 0x2000;
|
||||||
dtd->page3 = ((unsigned long)buf & 0xfffff000) + 0x3000;
|
dtd->page3 = ((unsigned long)buf & 0xfffff000) + 0x3000;
|
||||||
dtd->page4 = ((unsigned long)buf & 0xfffff000) + 0x4000;
|
dtd->page4 = ((unsigned long)buf & 0xfffff000) + 0x4000;
|
||||||
|
|
||||||
len -= length;
|
len_left -= len_this_dtd;
|
||||||
actlen += length;
|
buf += len_this_dtd;
|
||||||
buf += length;
|
|
||||||
|
|
||||||
if (len) {
|
if (len_left) {
|
||||||
qtd = (struct ept_queue_item *)
|
qtd = (struct ept_queue_item *)
|
||||||
memalign(ILIST_ALIGN, ILIST_ENT_SZ);
|
memalign(ILIST_ALIGN, ILIST_ENT_SZ);
|
||||||
dtd->next = (unsigned long)qtd;
|
dtd->next = (unsigned long)qtd;
|
||||||
|
|
@ -471,7 +469,7 @@ static void ci_ep_submit_next_request(struct ci_ep *ci_ep)
|
||||||
}
|
}
|
||||||
|
|
||||||
ci_req->dtd_count++;
|
ci_req->dtd_count++;
|
||||||
} while (len);
|
} while (len_left);
|
||||||
|
|
||||||
item = dtd;
|
item = dtd;
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue