usb: dwc2: gadget: Add endpoint wedge support
Add enpoint wedge support. Tested by USBCV MSC tests. Signed-off-by: Argishti Aleksanyan <Argishti.Aleksanyan@synopsys.com> Signed-off-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com> Link: https://lore.kernel.org/r/3143ea6b8eee08761709a6c2788216292be46a34.1626087390.git.Minas.Harutyunyan@synopsys.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
bcacbf06c8
commit
b833ce15ce
@ -122,6 +122,7 @@ struct dwc2_hsotg_req;
|
||||
* @periodic: Set if this is a periodic ep, such as Interrupt
|
||||
* @isochronous: Set if this is a isochronous ep
|
||||
* @send_zlp: Set if we need to send a zero-length packet.
|
||||
* @wedged: Set if ep is wedged.
|
||||
* @desc_list_dma: The DMA address of descriptor chain currently in use.
|
||||
* @desc_list: Pointer to descriptor DMA chain head currently in use.
|
||||
* @desc_count: Count of entries within the DMA descriptor chain of EP.
|
||||
@ -172,6 +173,7 @@ struct dwc2_hsotg_ep {
|
||||
unsigned int periodic:1;
|
||||
unsigned int isochronous:1;
|
||||
unsigned int send_zlp:1;
|
||||
unsigned int wedged:1;
|
||||
unsigned int target_frame;
|
||||
#define TARGET_FRAME_INITIAL 0xFFFFFFFF
|
||||
bool frame_overrun;
|
||||
|
@ -1806,7 +1806,8 @@ static int dwc2_hsotg_process_req_feature(struct dwc2_hsotg *hsotg,
|
||||
case USB_ENDPOINT_HALT:
|
||||
halted = ep->halted;
|
||||
|
||||
dwc2_hsotg_ep_sethalt(&ep->ep, set, true);
|
||||
if (!ep->wedged)
|
||||
dwc2_hsotg_ep_sethalt(&ep->ep, set, true);
|
||||
|
||||
ret = dwc2_hsotg_send_reply(hsotg, ep0, NULL, 0);
|
||||
if (ret) {
|
||||
@ -4046,6 +4047,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
|
||||
hs_ep->isochronous = 0;
|
||||
hs_ep->periodic = 0;
|
||||
hs_ep->halted = 0;
|
||||
hs_ep->wedged = 0;
|
||||
hs_ep->interval = desc->bInterval;
|
||||
|
||||
switch (ep_type) {
|
||||
@ -4286,6 +4288,27 @@ static int dwc2_hsotg_ep_dequeue(struct usb_ep *ep, struct usb_request *req)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc2_gadget_ep_set_wedge - set wedge on a given endpoint
|
||||
* @ep: The endpoint to be wedged.
|
||||
*
|
||||
*/
|
||||
static int dwc2_gadget_ep_set_wedge(struct usb_ep *ep)
|
||||
{
|
||||
struct dwc2_hsotg_ep *hs_ep = our_ep(ep);
|
||||
struct dwc2_hsotg *hs = hs_ep->parent;
|
||||
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&hs->lock, flags);
|
||||
hs_ep->wedged = 1;
|
||||
ret = dwc2_hsotg_ep_sethalt(ep, 1, false);
|
||||
spin_unlock_irqrestore(&hs->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* dwc2_hsotg_ep_sethalt - set halt on a given endpoint
|
||||
* @ep: The endpoint to set halt.
|
||||
@ -4337,6 +4360,7 @@ static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value, bool now)
|
||||
epctl |= DXEPCTL_EPDIS;
|
||||
} else {
|
||||
epctl &= ~DXEPCTL_STALL;
|
||||
hs_ep->wedged = 0;
|
||||
xfertype = epctl & DXEPCTL_EPTYPE_MASK;
|
||||
if (xfertype == DXEPCTL_EPTYPE_BULK ||
|
||||
xfertype == DXEPCTL_EPTYPE_INTERRUPT)
|
||||
@ -4353,6 +4377,7 @@ static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value, bool now)
|
||||
// STALL bit will be set in GOUTNAKEFF interrupt handler
|
||||
} else {
|
||||
epctl &= ~DXEPCTL_STALL;
|
||||
hs_ep->wedged = 0;
|
||||
xfertype = epctl & DXEPCTL_EPTYPE_MASK;
|
||||
if (xfertype == DXEPCTL_EPTYPE_BULK ||
|
||||
xfertype == DXEPCTL_EPTYPE_INTERRUPT)
|
||||
@ -4392,6 +4417,7 @@ static const struct usb_ep_ops dwc2_hsotg_ep_ops = {
|
||||
.queue = dwc2_hsotg_ep_queue_lock,
|
||||
.dequeue = dwc2_hsotg_ep_dequeue,
|
||||
.set_halt = dwc2_hsotg_ep_sethalt_lock,
|
||||
.set_wedge = dwc2_gadget_ep_set_wedge,
|
||||
/* note, don't believe we have any call for the fifo routines */
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user