diff options
Diffstat (limited to 'drivers/usb/renesas_usbhs/mod_host.c')
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_host.c | 67 |
1 files changed, 49 insertions, 18 deletions
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index e6fd044adfa3..1816a3e11b78 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -228,9 +228,13 @@ static struct usbhsh_device *usbhsh_device_alloc(struct usbhsh_hpriv *hpriv, struct device *dev = usbhsh_hcd_to_dev(hcd); struct usb_device *usbv = usbhsh_urb_to_usbv(urb); struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); + unsigned long flags; u16 upphub, hubport; int i; + /******************** spin lock ********************/ + usbhs_lock(priv, flags); + /* * find device */ @@ -255,6 +259,19 @@ static struct usbhsh_device *usbhsh_device_alloc(struct usbhsh_hpriv *hpriv, } } + if (udev) { + /* + * usbhsh_usbv_to_udev() + * usbhsh_udev_to_usbv() + * will be enable + */ + dev_set_drvdata(&usbv->dev, udev); + udev->usbv = usbv; + } + + usbhs_unlock(priv, flags); + /******************** spin unlock ******************/ + if (!udev) { dev_err(dev, "no free usbhsh_device\n"); return NULL; @@ -266,14 +283,6 @@ static struct usbhsh_device *usbhsh_device_alloc(struct usbhsh_hpriv *hpriv, /* uep will be attached */ INIT_LIST_HEAD(&udev->ep_list_head); - /* - * usbhsh_usbv_to_udev() - * usbhsh_udev_to_usbv() - * will be enable - */ - dev_set_drvdata(&usbv->dev, udev); - udev->usbv = usbv; - upphub = 0; hubport = 0; if (!usbhsh_connected_to_rhdev(hcd, udev)) { @@ -302,8 +311,10 @@ static void usbhsh_device_free(struct usbhsh_hpriv *hpriv, struct usbhsh_device *udev) { struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); + struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); struct device *dev = usbhsh_hcd_to_dev(hcd); struct usb_device *usbv = usbhsh_udev_to_usbv(udev); + unsigned long flags; dev_dbg(dev, "%s [%d](%p)\n", __func__, usbhsh_device_number(hpriv, udev), udev); @@ -311,6 +322,9 @@ static void usbhsh_device_free(struct usbhsh_hpriv *hpriv, if (usbhsh_device_has_endpoint(udev)) dev_warn(dev, "udev still have endpoint\n"); + /******************** spin lock ********************/ + usbhs_lock(priv, flags); + /* * usbhsh_usbv_to_udev() * usbhsh_udev_to_usbv() @@ -318,6 +332,9 @@ static void usbhsh_device_free(struct usbhsh_hpriv *hpriv, */ dev_set_drvdata(&usbv->dev, NULL); udev->usbv = NULL; + + usbhs_unlock(priv, flags); + /******************** spin unlock ******************/ } /* @@ -338,6 +355,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, struct usb_endpoint_descriptor *desc = &ep->desc; int type, i, dir_in; unsigned int min_usr; + unsigned long flags; dir_in_req = !!dir_in_req; @@ -352,6 +370,9 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, goto usbhsh_endpoint_alloc_find_pipe; } + /******************** spin lock ********************/ + usbhs_lock(priv, flags); + /* * find best pipe for endpoint * see @@ -376,6 +397,19 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, } } + if (best_pipe) { + /* update pipe user count */ + info = usbhsh_pipe_info(best_pipe); + info->usr_cnt++; + + /* init this endpoint, and attach it to udev */ + INIT_LIST_HEAD(&uep->ep_list); + list_add_tail(&uep->ep_list, &udev->ep_list_head); + } + + usbhs_unlock(priv, flags); + /******************** spin unlock ******************/ + if (unlikely(!best_pipe)) { dev_err(dev, "couldn't find best pipe\n"); kfree(uep); @@ -391,16 +425,6 @@ usbhsh_endpoint_alloc_find_pipe: usbhsh_ep_to_uep(ep) = uep; /* - * update pipe user count - */ - info = usbhsh_pipe_info(best_pipe); - info->usr_cnt++; - - /* init this endpoint, and attach it to udev */ - INIT_LIST_HEAD(&uep->ep_list); - list_add_tail(&uep->ep_list, &udev->ep_list_head); - - /* * usbhs_pipe_config_update() should be called after * usbhs_set_device_config() * see @@ -426,6 +450,7 @@ void usbhsh_endpoint_free(struct usbhsh_hpriv *hpriv, struct device *dev = usbhs_priv_to_dev(priv); struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); struct usbhsh_pipe_info *info; + unsigned long flags; if (!uep) return; @@ -434,6 +459,9 @@ void usbhsh_endpoint_free(struct usbhsh_hpriv *hpriv, usbhsh_device_number(hpriv, usbhsh_uep_to_udev(uep)), usbhs_pipe_name(uep->pipe), uep); + /******************** spin lock ********************/ + usbhs_lock(priv, flags); + info = usbhsh_pipe_info(uep->pipe); info->usr_cnt--; @@ -443,6 +471,9 @@ void usbhsh_endpoint_free(struct usbhsh_hpriv *hpriv, usbhsh_uep_to_udev(uep) = NULL; usbhsh_ep_to_uep(ep) = NULL; + usbhs_unlock(priv, flags); + /******************** spin unlock ******************/ + kfree(uep); } |