diff -drupN a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c --- a/drivers/usb/gadget/composite.c 2018-08-06 17:23:04.000000000 +0300 +++ b/drivers/usb/gadget/composite.c 2022-06-12 05:28:14.000000000 +0300 @@ -1900,6 +1900,19 @@ unknown: ctrl->bRequestType, ctrl->bRequest, w_value, w_index, w_length); +#if defined(CONFIG_USB_G_WEBCAM) || defined(CONFIG_USB_CONFIGFS_F_UVC) + /* getcur request about request error code of webcam. */ + if ((ctrl->bRequest == 0x81) && (ctrl->bRequestType == 0xa1) + && (ctrl->wLength == 0x1) && (ctrl->wValue == 0x200) + && (ctrl->wIndex == 0x0)) { + u8 ret_data = 0x06; + + value = min_t(u16, w_length, (u16) 1); + memcpy(req->buf, &ret_data, value); + break; + } +#endif + /* functions always handle their interfaces and endpoints... * punt other recipients (other, WUSB, ...) to the current * configuration code. @@ -1993,6 +2006,12 @@ void composite_disconnect(struct usb_gad struct usb_composite_dev *cdev = get_gadget_data(gadget); unsigned long flags; + if (cdev == NULL) { + WARN(1, "%s: Calling disconnect on a Gadget that is \ + not connected\n", __func__); + return; + } + /* REVISIT: should we have config and device level * disconnect callbacks? */ @@ -2154,6 +2173,7 @@ int composite_os_desc_req_prepare(struct if (!cdev->os_desc_req->buf) { ret = -ENOMEM; usb_ep_free_request(ep0, cdev->os_desc_req); + cdev->os_desc_req = NULL; goto end; } cdev->os_desc_req->context = cdev; @@ -2176,6 +2196,7 @@ void composite_dev_cleanup(struct usb_co kfree(cdev->os_desc_req->buf); usb_ep_free_request(cdev->gadget->ep0, cdev->os_desc_req); + cdev->os_desc_req = NULL; } if (cdev->req) { if (cdev->setup_pending) @@ -2183,6 +2204,7 @@ void composite_dev_cleanup(struct usb_co kfree(cdev->req->buf); usb_ep_free_request(cdev->gadget->ep0, cdev->req); + cdev->req = NULL; } cdev->next_string_id = 0; device_remove_file(&cdev->gadget->dev, &dev_attr_suspended);