Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1597048 > unrolled thread
| Started by | Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
|---|---|
| First post | 2017-03-10 11:40 +0100 |
| Last post | 2017-03-10 11:40 +0100 |
| Articles | 1 — 1 participant |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH 4.9 105/153] usb: gadget: f_hid: fix: Free out requests Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-03-10 11:40 +0100
| From | Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
|---|---|
| Date | 2017-03-10 11:40 +0100 |
| Subject | [PATCH 4.9 105/153] usb: gadget: f_hid: fix: Free out requests |
| Message-ID | <tjq7N-2G5-41@gated-at.bofh.it> |
4.9-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Opasiak <kopasiak90@gmail.com>
commit 20d2ca955bd09639c7b01db5761d157c297aea0a upstream.
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: 99c515005857 ("usb: gadget: hidg: register OUT INT endpoint for SET_REPORT")
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/gadget/function/f_hid.c | 32 ++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)
--- a/drivers/usb/gadget/function/f_hid.c
+++ b/drivers/usb/gadget/function/f_hid.c
@@ -371,20 +371,36 @@ static inline struct usb_request *hidg_a
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)
- return;
+ 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;
+ 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);
+ 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);
+ 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,
Back to top | Article view | linux.kernel
csiph-web