/* * * usb_ep_ops * */ static int usbhsg_ep_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) { struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); struct usbhs_pipe *pipe; int ret = -EIO; unsigned long flags; usbhs_lock(priv, flags); /* * if it already have pipe, * nothing to do */ if (uep->pipe) { usbhs_pipe_clear(uep->pipe); usbhs_pipe_sequence_data0(uep->pipe); ret = 0; goto usbhsg_ep_enable_end; } pipe = usbhs_pipe_malloc(priv, usb_endpoint_type(desc), usb_endpoint_dir_in(desc)); if (pipe) { uep->pipe = pipe; pipe->mod_private = uep; /* set epnum / maxp */ usbhs_pipe_config_update(pipe, 0, usb_endpoint_num(desc), usb_endpoint_maxp(desc)); /* * usbhs_fifo_dma_push/pop_handler try to * use dmaengine if possible. * It will use pio handler if impossible. */ if (usb_endpoint_dir_in(desc)) { pipe->handler = &usbhs_fifo_dma_push_handler; } else { pipe->handler = &usbhs_fifo_dma_pop_handler; usbhs_xxxsts_clear(priv, BRDYSTS, usbhs_pipe_number(pipe)); } ret = 0; } usbhsg_ep_enable_end: usbhs_unlock(priv, flags); return ret; }
/* * module start/stop */ static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) { struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); struct usbhs_pipe *pipe; struct renesas_usbhs_driver_pipe_config *pipe_configs = usbhs_get_dparam(priv, pipe_configs); int pipe_size = usbhs_get_dparam(priv, pipe_size); int old_type, dir_in, i; /* init all pipe */ old_type = USB_ENDPOINT_XFER_CONTROL; for (i = 0; i < pipe_size; i++) { /* * data "output" will be finished as soon as possible, * but there is no guaranty at data "input" case. * * "input" needs "standby" pipe. * So, "input" direction pipe > "output" direction pipe * is good idea. * * 1st USB_ENDPOINT_XFER_xxx will be output direction, * and the other will be input direction here. * * ex) * ... * USB_ENDPOINT_XFER_ISOC -> dir out * USB_ENDPOINT_XFER_ISOC -> dir in * USB_ENDPOINT_XFER_BULK -> dir out * USB_ENDPOINT_XFER_BULK -> dir in * USB_ENDPOINT_XFER_BULK -> dir in * ... */ dir_in = (pipe_configs[i].type == old_type); old_type = pipe_configs[i].type; if (USB_ENDPOINT_XFER_CONTROL == pipe_configs[i].type) { pipe = usbhs_dcp_malloc(priv); usbhsh_hpriv_to_dcp(hpriv) = pipe; } else { pipe = usbhs_pipe_malloc(priv, pipe_configs[i].type, dir_in); } pipe->mod_private = NULL; } }
/* * * usb_ep_ops * */ static int usbhsg_ep_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) { struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); struct usbhs_pipe *pipe; spinlock_t *lock; unsigned long flags; int ret = -EIO; /* * if it already have pipe, * nothing to do */ if (uep->pipe) return 0; /******************** spin lock ********************/ lock = usbhsg_trylock(gpriv, &flags); pipe = usbhs_pipe_malloc(priv, desc); if (pipe) { uep->pipe = pipe; pipe->mod_private = uep; INIT_LIST_HEAD(&uep->list); if (usb_endpoint_dir_in(desc)) uep->handler = &usbhsg_handler_send_packet; else uep->handler = &usbhsg_handler_recv_packet; ret = 0; } usbhsg_unlock(lock, &flags); /******************** spin unlock ******************/ return ret; }
/* * * usb_ep_ops * */ static int usbhsg_ep_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) { struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); struct usbhs_pipe *pipe; int ret = -EIO; /* * if it already have pipe, * nothing to do */ if (uep->pipe) { usbhs_pipe_clear(uep->pipe); usbhs_pipe_clear_sequence(uep->pipe); return 0; } pipe = usbhs_pipe_malloc(priv, desc); if (pipe) { uep->pipe = pipe; pipe->mod_private = uep; /* * usbhs_fifo_dma_push/pop_handler try to * use dmaengine if possible. * It will use pio handler if impossible. */ if (usb_endpoint_dir_in(desc)) uep->handler = &usbhs_fifo_dma_push_handler; else uep->handler = &usbhs_fifo_dma_pop_handler; ret = 0; } return ret; }