From f286d487e9283a42a8844659bb5552b3f1bf6a7d Mon Sep 17 00:00:00 2001 From: Krzysztof Opasiak Date: Fri, 27 Mar 2015 09:35:44 +0100 Subject: [PATCH] usb: gadget: hid: Fix static variable usage If we have multiple instances of hid function, each of them may have different report descriptor, also their length may be different. Currently we are using static hidg_desc varable which is being filled in hidg_bind(). Then we send its content to host in hidg_setup() function. This content may have been already overwriten if another instance has executed hidg_bind(). Signed-off-by: Krzysztof Opasiak Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_hid.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 13dfc9915b1d..f7f35a36c09a 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -437,12 +437,20 @@ static int hidg_setup(struct usb_function *f, | USB_REQ_GET_DESCRIPTOR): switch (value >> 8) { case HID_DT_HID: + { + struct hid_descriptor hidg_desc_copy = hidg_desc; + VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: HID\n"); + hidg_desc_copy.desc[0].bDescriptorType = HID_DT_REPORT; + hidg_desc_copy.desc[0].wDescriptorLength = + cpu_to_le16(hidg->report_desc_length); + length = min_t(unsigned short, length, - hidg_desc.bLength); - memcpy(req->buf, &hidg_desc, length); + hidg_desc_copy.bLength); + memcpy(req->buf, &hidg_desc_copy, length); goto respond; break; + } case HID_DT_REPORT: VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: REPORT\n"); length = min_t(unsigned short, length, @@ -632,6 +640,10 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) hidg_fs_in_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); hidg_hs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); hidg_fs_out_ep_desc.wMaxPacketSize = cpu_to_le16(hidg->report_length); + /* + * We can use hidg_desc struct here but we should not relay + * that its content won't change after returning from this function. + */ hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT; hidg_desc.desc[0].wDescriptorLength = cpu_to_le16(hidg->report_desc_length); -- 2.20.1