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 ******************/ }
static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv, struct urb *urb) { struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); struct usbhs_pipe *pipe; struct usb_endpoint_descriptor *desc = &urb->ep->desc; struct device *dev = usbhs_priv_to_dev(priv); unsigned long flags; int dir_in_req = !!usb_pipein(urb->pipe); int is_dcp = usb_endpoint_xfer_control(desc); int i, dir_in; int ret = -EBUSY; /******************** spin lock ********************/ usbhs_lock(priv, flags); /* * if uep has been attached to pipe, * reuse it */ if (usbhsh_uep_to_pipe(uep)) { ret = 0; goto usbhsh_pipe_attach_done; } usbhs_for_each_pipe_with_dcp(pipe, priv, i) { /* check pipe type */ if (!usbhs_pipe_type_is(pipe, usb_endpoint_type(desc))) continue; /* check pipe direction if normal pipe */ if (!is_dcp) { dir_in = !!usbhs_pipe_is_dir_in(pipe); if (0 != (dir_in - dir_in_req)) continue; } /* check pipe is free */ if (usbhsh_pipe_to_uep(pipe)) continue; /* * attach pipe to uep * * usbhs_pipe_config_update() should be called after * usbhs_set_device_config() * see * DCPMAXP/PIPEMAXP */ usbhsh_uep_to_pipe(uep) = pipe; usbhsh_pipe_to_uep(pipe) = uep; usbhs_pipe_config_update(pipe, usbhsh_device_number(hpriv, udev), usb_endpoint_num(desc), usb_endpoint_maxp(desc)); dev_dbg(dev, "%s [%d-%d(%s:%s)]\n", __func__, usbhsh_device_number(hpriv, udev), usb_endpoint_num(desc), usbhs_pipe_name(pipe), dir_in_req ? "in" : "out"); ret = 0; break; } usbhsh_pipe_attach_done: if (0 == ret) uep->counter++; usbhs_unlock(priv, flags); /******************** spin unlock ******************/ return ret; }