lkml.org 
[lkml]   [2017]   [Mar]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 105/153] usb: gadget: f_hid: fix: Free out requests
    Date
    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,

    \
     
     \ /
      Last update: 2017-03-10 11:47    [W:4.184 / U:0.988 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site