USB: f_rndis: Check if cdev is NULL before accessing
RNDIS control path completion handlers are getting called after setting
cdev to NULL during disconnect as part of composition switch and this
is leading to a crash. Avoid this crash, by checking, if cdev is NULL
before accessing. Also don't queue request's to DCD, if composition switch
is in progress.
CRs-Fixed: 433534
Change-Id: Ic0790415ec3eaf866af2895370249e45adcbba5d
Signed-off-by: Chiranjeevi Velempati <cvelempa@codeaurora.org>
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index f004891..0c03e20 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -2942,6 +2942,9 @@
if (ep == NULL || req == NULL || mEp->desc == NULL)
return -EINVAL;
+ if (!udc->softconnect)
+ return -ENODEV;
+
spin_lock_irqsave(mEp->lock, flags);
if (!udc->configured && mEp->type !=
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 288611d..f3c6481 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -412,9 +412,14 @@
static void rndis_response_complete(struct usb_ep *ep, struct usb_request *req)
{
struct f_rndis *rndis = req->context;
- struct usb_composite_dev *cdev = rndis->port.func.config->cdev;
+ struct usb_composite_dev *cdev;
int status = req->status;
+ if (!rndis->port.func.config || !rndis->port.func.config->cdev)
+ return;
+ else
+ cdev = rndis->port.func.config->cdev;
+
/* after TX:
* - USB_CDC_GET_ENCAPSULATED_RESPONSE (ep0/control)
* - RNDIS_RESPONSE_AVAILABLE (status/irq)
@@ -451,10 +456,15 @@
static void rndis_command_complete(struct usb_ep *ep, struct usb_request *req)
{
struct f_rndis *rndis = req->context;
- struct usb_composite_dev *cdev = rndis->port.func.config->cdev;
+ struct usb_composite_dev *cdev;
int status;
rndis_init_msg_type *buf;
+ if (!rndis->port.func.config || !rndis->port.func.config->cdev)
+ return;
+ else
+ cdev = rndis->port.func.config->cdev;
+
/* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */
// spin_lock(&dev->lock);
status = rndis_msg_parser(rndis->config, (u8 *) req->buf);