usb: renesas_usbhs: gadget: fix NULL pointer dereference in ep_disable()
[pandora-kernel.git] / drivers / usb / renesas_usbhs / mod_gadget.c
index ef82274..0b1fc07 100644 (file)
@@ -514,6 +514,10 @@ static int usbhsg_ep_enable(struct usb_ep *ep,
 static int usbhsg_ep_disable(struct usb_ep *ep)
 {
        struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
+       struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep);
+
+       if (!pipe)
+               return -EINVAL;
 
        return usbhsg_pipe_disable(uep);
 }
@@ -755,7 +759,7 @@ static int usbhsg_gadget_start(struct usb_gadget *gadget,
 
        if (!driver             ||
            !driver->setup      ||
-           driver->speed != USB_SPEED_HIGH)
+           driver->speed < USB_SPEED_FULL)
                return -EINVAL;
 
        /* first hook up the driver ... */
@@ -776,6 +780,7 @@ static int usbhsg_gadget_stop(struct usb_gadget *gadget,
                return -EINVAL;
 
        usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD);
+       gpriv->gadget.dev.driver = NULL;
        gpriv->driver = NULL;
 
        return 0;
@@ -805,9 +810,21 @@ static int usbhsg_start(struct usbhs_priv *priv)
 
 static int usbhsg_stop(struct usbhs_priv *priv)
 {
+       struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
+
+       /* cable disconnect */
+       if (gpriv->driver &&
+           gpriv->driver->disconnect)
+               gpriv->driver->disconnect(&gpriv->gadget);
+
        return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED);
 }
 
+static void usbhs_mod_gadget_release(struct device *pdev)
+{
+       /* do nothing */
+}
+
 int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
 {
        struct usbhsg_gpriv *gpriv;
@@ -856,6 +873,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
         */
        dev_set_name(&gpriv->gadget.dev, "gadget");
        gpriv->gadget.dev.parent        = dev;
+       gpriv->gadget.dev.release       = usbhs_mod_gadget_release;
        gpriv->gadget.name              = "renesas_usbhs_udc";
        gpriv->gadget.ops               = &usbhsg_gadget_ops;
        gpriv->gadget.is_dualspeed      = 1;