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: 99c5150058
("usb: gadget: hidg: register OUT INT endpoint for SET_REPORT")
Cc: stable@vger.kernel.org
Tested-by: David Lechner <david@lechnology.com>
Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
This commit is contained in:
parent
271d2d6d94
commit
20d2ca955b
|
@ -425,20 +425,36 @@ 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)
|
||||
{
|
||||
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;
|
||||
unsigned long flags;
|
||||
|
||||
req_list = kzalloc(sizeof(*req_list), GFP_ATOMIC);
|
||||
if (!req_list)
|
||||
switch (req->status) {
|
||||
case 0:
|
||||
req_list = kzalloc(sizeof(*req_list), GFP_ATOMIC);
|
||||
if (!req_list) {
|
||||
ERROR(cdev, "Unable to allocate mem for req_list\n");
|
||||
goto free_req;
|
||||
}
|
||||
|
||||
req_list->req = req;
|
||||
|
||||
spin_lock_irqsave(&hidg->spinlock, flags);
|
||||
list_add_tail(&req_list->list, &hidg->completed_out_req);
|
||||
spin_unlock_irqrestore(&hidg->spinlock, flags);
|
||||
|
||||
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;
|
||||
|
||||
req_list->req = req;
|
||||
|
||||
spin_lock_irqsave(&hidg->spinlock, flags);
|
||||
list_add_tail(&req_list->list, &hidg->completed_out_req);
|
||||
spin_unlock_irqrestore(&hidg->spinlock, flags);
|
||||
|
||||
wake_up(&hidg->read_queue);
|
||||
}
|
||||
}
|
||||
|
||||
static int hidg_setup(struct usb_function *f,
|
||||
|
|
Loading…
Reference in New Issue