static void usbhsh_endpoint_detach(struct usbhsh_hpriv *hpriv, struct usb_host_endpoint *ep) { struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); struct device *dev = usbhs_priv_to_dev(priv); struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); unsigned long flags; if (!uep) return; dev_dbg(dev, "%s [%d-%d]\n", __func__, usbhsh_device_number(hpriv, usbhsh_uep_to_udev(uep)), usb_endpoint_num(&ep->desc)); if (usbhsh_uep_to_pipe(uep)) usbhsh_pipe_detach(hpriv, uep); /******************** spin lock ********************/ usbhs_lock(priv, flags); /* remove this endpoint from udev */ list_del_init(&uep->ep_list); usbhsh_uep_to_udev(uep) = NULL; usbhsh_uep_to_ep(uep) = NULL; usbhsh_ep_to_uep(ep) = NULL; usbhs_unlock(priv, flags); /******************** spin unlock ******************/ kfree(uep); }
static void usbhsh_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep) { struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); struct usbhsh_device *udev; struct usbhsh_hpriv *hpriv; /* * this function might be called manytimes by same hcd/ep * in-endpoint == out-endpoint if ep == dcp. */ if (!uep) return; udev = usbhsh_uep_to_udev(uep); hpriv = usbhsh_hcd_to_hpriv(hcd); usbhsh_endpoint_detach(hpriv, ep); /* * if there is no endpoint, * free device */ if (!usbhsh_device_has_endpoint(udev)) usbhsh_device_detach(hpriv, udev); }
static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv, struct usbhsh_ep *uep) { struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); struct usbhs_pipe *pipe; struct device *dev = usbhs_priv_to_dev(priv); unsigned long flags; /******************** spin lock ********************/ usbhs_lock(priv, flags); pipe = usbhsh_uep_to_pipe(uep); if (unlikely(!pipe)) { dev_err(dev, "uep doens't have pipe\n"); } else { struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep); struct usbhsh_device *udev = usbhsh_uep_to_udev(uep); /* detach pipe from uep */ usbhsh_uep_to_pipe(uep) = NULL; usbhsh_pipe_to_uep(pipe) = NULL; dev_dbg(dev, "%s [%d-%d(%s)]\n", __func__, usbhsh_device_number(hpriv, udev), usb_endpoint_num(&ep->desc), usbhs_pipe_name(pipe)); } usbhs_unlock(priv, flags); /******************** spin unlock ******************/ }
/* * endpoint control */ static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv, struct urb *urb, gfp_t mem_flags) { struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); struct usb_host_endpoint *ep = urb->ep; struct usbhsh_ep *uep; struct device *dev = usbhs_priv_to_dev(priv); struct usb_endpoint_descriptor *desc = &ep->desc; unsigned long flags; uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); if (!uep) { dev_err(dev, "usbhsh_ep alloc fail\n"); return -ENOMEM; } /******************** spin lock ********************/ usbhs_lock(priv, flags); /* * init endpoint */ uep->counter = 0; INIT_LIST_HEAD(&uep->ep_list); list_add_tail(&uep->ep_list, &udev->ep_list_head); usbhsh_uep_to_udev(uep) = udev; usbhsh_uep_to_ep(uep) = ep; usbhsh_ep_to_uep(ep) = uep; usbhs_unlock(priv, flags); /******************** spin unlock ******************/ dev_dbg(dev, "%s [%d-%d]\n", __func__, usbhsh_device_number(hpriv, udev), usb_endpoint_num(desc)); return 0; }