static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) { struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); spinlock_t *lock; unsigned long flags; /* * see * CAUTION [*queue handler*] * CAUTION [*endpoint queue*] * CAUTION [*request complete*] */ /******************** spin lock ********************/ lock = usbhsg_trylock(gpriv, &flags); usbhsg_queue_pop(uep, ureq, -ECONNRESET); usbhsg_unlock(lock, &flags); /******************** spin unlock ******************/ return 0; }
static int usbhsg_pipe_disable(struct usbhsg_uep *uep) { struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); struct usbhsg_request *ureq; int disable = 0; /* ********* assume under spin lock ********* */ usbhs_fifo_disable(pipe); /* * disable pipe irq */ usbhsg_irq_empty_ctrl(uep, disable); usbhsg_irq_ready_ctrl(uep, disable); while (1) { ureq = usbhsg_queue_get(uep); if (!ureq) break; usbhsg_queue_pop(uep, ureq, -ECONNRESET); } return 0; }
static void usbhsg_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) { struct usbhs_pipe *pipe = pkt->pipe; struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); ureq->req.actual = pkt->actual; usbhsg_queue_pop(uep, ureq, 0); }
static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) { struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq)); usbhsg_queue_pop(uep, ureq, -ECONNRESET); return 0; }
static int usbhsg_try_run_receive_packet(struct usbhsg_uep *uep, struct usbhsg_request *ureq) { struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); struct usb_request *req = &ureq->req; struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); struct device *dev = usbhsg_gpriv_to_dev(gpriv); void *buf; int maxp; int remainder, recv; int is_done = 0; /* ********* assume under spin lock ********* */ maxp = usbhs_pipe_get_maxpacket(pipe); buf = req->buf + req->actual; remainder = req->length - req->actual; recv = usbhs_fifo_read(pipe, buf, remainder); /* * recv < 0 : pipe busy * recv >= 0 : receive data * * recv <= max_packet */ if (recv < 0) return -EBUSY; /* update parameters */ req->actual += recv; if ((recv == remainder) || /* receive all data */ (recv < maxp)) /* short packet */ is_done = 1; dev_dbg(dev, " recv %d (%d/ %d/ %d/ %d)\n", usbhs_pipe_number(pipe), remainder, recv, is_done, req->zero); /* read all data ? */ if (is_done) { int disable = 0; uep->handler->irq_mask(uep, disable); usbhs_fifo_disable(pipe); usbhsg_queue_pop(uep, ureq, 0); } return 0; }
/* * handler function */ static int usbhsg_try_run_ctrl_stage_end(struct usbhsg_uep *uep, struct usbhsg_request *ureq) { struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); /* ********* assume under spin lock ********* */ usbhs_dcp_control_transfer_done(pipe); usbhsg_queue_pop(uep, ureq, 0); return 0; }
/* * * usb_dcp_ops * */ static int usbhsg_pipe_disable(struct usbhsg_uep *uep) { struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); struct usbhs_pkt *pkt; while (1) { pkt = usbhs_pkt_pop(pipe, NULL); if (!pkt) break; usbhsg_queue_pop(uep, usbhsg_pkt_to_ureq(pkt), -ECONNRESET); } usbhs_pipe_disable(pipe); return 0; }
static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) { struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); if (pipe) usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq)); /* * To dequeue a request, this driver should call the usbhsg_queue_pop() * even if the pipe is NULL. */ usbhsg_queue_pop(uep, ureq, -ECONNRESET); return 0; }
static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) { struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); struct usbhs_pipe *pipe; unsigned long flags; spin_lock_irqsave(&uep->lock, flags); pipe = usbhsg_uep_to_pipe(uep); if (pipe) usbhs_pkt_pop(pipe, usbhsg_ureq_to_pkt(ureq)); /* * To dequeue a request, this driver should call the usbhsg_queue_pop() * even if the pipe is NULL. */ usbhsg_queue_pop(uep, ureq, -ECONNRESET); spin_unlock_irqrestore(&uep->lock, flags); return 0; }
static int usbhsg_try_run_send_packet(struct usbhsg_uep *uep, struct usbhsg_request *ureq) { struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); struct usb_request *req = &ureq->req; struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); struct device *dev = usbhsg_gpriv_to_dev(gpriv); void *buf; int remainder, send; int is_done = 0; int enable; int maxp; /* ********* assume under spin lock ********* */ maxp = usbhs_pipe_get_maxpacket(pipe); buf = req->buf + req->actual; remainder = req->length - req->actual; send = usbhs_fifo_write(pipe, buf, remainder); /* * send < 0 : pipe busy * send = 0 : send zero packet * send > 0 : send data * * send <= max_packet */ if (send > 0) req->actual += send; /* send all packet ? */ if (send < remainder) is_done = 0; /* there are remainder data */ else if (send < maxp) is_done = 1; /* short packet */ else is_done = !req->zero; /* send zero packet ? */ dev_dbg(dev, " send %d (%d/ %d/ %d/ %d)\n", usbhs_pipe_number(pipe), remainder, send, is_done, req->zero); /* * enable interrupt and send again in irq handler * if it still have remainder data which should be sent. */ enable = !is_done; uep->handler->irq_mask(uep, enable); /* * usbhs_fifo_enable execute * - after callback_update, * - before queue_pop / stage_end */ usbhs_fifo_enable(pipe); /* * all data were sent ? */ if (is_done) { /* it care below call in "function mode" */ if (usbhsg_is_dcp(uep)) usbhs_dcp_control_transfer_done(pipe); usbhsg_queue_pop(uep, ureq, 0); } return 0; }