Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 364511
b: refs/heads/master
c: dd064e9
h: refs/heads/master
i:
  364509: 86d3de7
  364507: 447e007
  364503: f371f97
  364495: 5b9b5dc
  364479: 9a6bb75
v: v3
  • Loading branch information
Michael Grzeschik authored and Greg Kroah-Hartman committed Mar 30, 2013
1 parent 0df152d commit c67b125
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 49 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: 24dcade163753259ddcbf77018b1244d7d90ed6b
refs/heads/master: dd064e9d36b32616e72dc9c1871d7e667cd970ce
104 changes: 56 additions & 48 deletions trunk/drivers/usb/chipidea/udc.c
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,59 @@ static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req)
usb_ep_free_request(ep, req);
}

/**
* _ep_queue: queues (submits) an I/O request to an endpoint
*
* Caller must hold lock
*/
static int _ep_queue(struct usb_ep *ep, struct usb_request *req,
gfp_t __maybe_unused gfp_flags)
{
struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
struct ci13xxx *ci = mEp->ci;
int retval = 0;

if (ep == NULL || req == NULL || mEp->ep.desc == NULL)
return -EINVAL;

if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
if (req->length)
mEp = (ci->ep0_dir == RX) ?
ci->ep0out : ci->ep0in;
if (!list_empty(&mEp->qh.queue)) {
_ep_nuke(mEp);
retval = -EOVERFLOW;
dev_warn(mEp->ci->dev, "endpoint ctrl %X nuked\n",
_usb_addr(mEp));
}
}

/* first nuke then test link, e.g. previous status has not sent */
if (!list_empty(&mReq->queue)) {
dev_err(mEp->ci->dev, "request already in queue\n");
return -EBUSY;
}

if (req->length > 4 * CI13XXX_PAGE_SIZE) {
dev_err(mEp->ci->dev, "request bigger than one td\n");
return -EMSGSIZE;
}

/* push request */
mReq->req.status = -EINPROGRESS;
mReq->req.actual = 0;

retval = _hardware_enqueue(mEp, mReq);

if (retval == -EALREADY)
retval = 0;
if (!retval)
list_add_tail(&mReq->queue, &mEp->qh.queue);

return retval;
}

/**
* isr_get_status_response: get_status request response
* @ci: ci struct
Expand Down Expand Up @@ -689,9 +742,7 @@ __acquires(mEp->lock)
}
/* else do nothing; reserved for future use */

spin_unlock(mEp->lock);
retval = usb_ep_queue(&mEp->ep, req, gfp_flags);
spin_lock(mEp->lock);
retval = _ep_queue(&mEp->ep, req, gfp_flags);
if (retval)
goto err_free_buf;

Expand Down Expand Up @@ -738,8 +789,6 @@ isr_setup_status_complete(struct usb_ep *ep, struct usb_request *req)
* This function returns an error code
*/
static int isr_setup_status_phase(struct ci13xxx *ci)
__releases(mEp->lock)
__acquires(mEp->lock)
{
int retval;
struct ci13xxx_ep *mEp;
Expand All @@ -748,9 +797,7 @@ __acquires(mEp->lock)
ci->status->context = ci;
ci->status->complete = isr_setup_status_complete;

spin_unlock(mEp->lock);
retval = usb_ep_queue(&mEp->ep, ci->status, GFP_ATOMIC);
spin_lock(mEp->lock);
retval = _ep_queue(&mEp->ep, ci->status, GFP_ATOMIC);

return retval;
}
Expand Down Expand Up @@ -1128,53 +1175,14 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req,
gfp_t __maybe_unused gfp_flags)
{
struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
struct ci13xxx *ci = mEp->ci;
int retval = 0;
unsigned long flags;

if (ep == NULL || req == NULL || mEp->ep.desc == NULL)
return -EINVAL;

spin_lock_irqsave(mEp->lock, flags);

if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
if (req->length)
mEp = (ci->ep0_dir == RX) ?
ci->ep0out : ci->ep0in;
if (!list_empty(&mEp->qh.queue)) {
_ep_nuke(mEp);
retval = -EOVERFLOW;
dev_warn(mEp->ci->dev, "endpoint ctrl %X nuked\n",
_usb_addr(mEp));
}
}

/* first nuke then test link, e.g. previous status has not sent */
if (!list_empty(&mReq->queue)) {
retval = -EBUSY;
dev_err(mEp->ci->dev, "request already in queue\n");
goto done;
}

if (req->length > 4 * CI13XXX_PAGE_SIZE) {
retval = -EMSGSIZE;
dev_err(mEp->ci->dev, "request bigger than one td\n");
goto done;
}

/* push request */
mReq->req.status = -EINPROGRESS;
mReq->req.actual = 0;

retval = _hardware_enqueue(mEp, mReq);

if (retval == -EALREADY)
retval = 0;
if (!retval)
list_add_tail(&mReq->queue, &mEp->qh.queue);

done:
retval = _ep_queue(ep, req, gfp_flags);
spin_unlock_irqrestore(mEp->lock, flags);
return retval;
}
Expand Down

0 comments on commit c67b125

Please sign in to comment.