Commit 20d2ca95 authored by Krzysztof Opasiak's avatar Krzysztof Opasiak Committed by Felipe Balbi

usb: gadget: f_hid: fix: Free out requests

Requests for out endpoint are allocated in bind() function
but never released.

This commit ensures that all pending requests are released
when we disable out endpoint.

Fixes: 99c51500 ("usb: gadget: hidg: register OUT INT endpoint for SET_REPORT")
Cc: stable@vger.kernel.org
Tested-by: default avatarDavid Lechner <david@lechnology.com>
Signed-off-by: default avatarKrzysztof Opasiak <k.opasiak@samsung.com>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent 271d2d6d
...@@ -425,12 +425,17 @@ static inline struct usb_request *hidg_alloc_ep_req(struct usb_ep *ep, ...@@ -425,12 +425,17 @@ static inline struct usb_request *hidg_alloc_ep_req(struct usb_ep *ep,
static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req) static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req)
{ {
struct f_hidg *hidg = (struct f_hidg *) req->context; struct f_hidg *hidg = (struct f_hidg *) req->context;
struct usb_composite_dev *cdev = hidg->func.config->cdev;
struct f_hidg_req_list *req_list; struct f_hidg_req_list *req_list;
unsigned long flags; unsigned long flags;
switch (req->status) {
case 0:
req_list = kzalloc(sizeof(*req_list), GFP_ATOMIC); req_list = kzalloc(sizeof(*req_list), GFP_ATOMIC);
if (!req_list) if (!req_list) {
return; ERROR(cdev, "Unable to allocate mem for req_list\n");
goto free_req;
}
req_list->req = req; req_list->req = req;
...@@ -439,6 +444,17 @@ static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req) ...@@ -439,6 +444,17 @@ static void hidg_set_report_complete(struct usb_ep *ep, struct usb_request *req)
spin_unlock_irqrestore(&hidg->spinlock, flags); spin_unlock_irqrestore(&hidg->spinlock, flags);
wake_up(&hidg->read_queue); wake_up(&hidg->read_queue);
break;
default:
ERROR(cdev, "Set report failed %d\n", req->status);
/* FALLTHROUGH */
case -ECONNABORTED: /* hardware forced ep reset */
case -ECONNRESET: /* request dequeued */
case -ESHUTDOWN: /* disconnect from host */
free_req:
free_ep_req(ep, req);
return;
}
} }
static int hidg_setup(struct usb_function *f, static int hidg_setup(struct usb_function *f,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment