/* * USB_TYPE_STANDARD / get status functions */ static void __usbhsg_recip_send_complete(struct usb_ep *ep, struct usb_request *req) { struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); /* free allocated recip-buffer/usb_request */ kfree(ureq->pkt.buf); usb_ep_free_request(ep, req); }
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_ep_queue(struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags) { struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); spinlock_t *lock; unsigned long flags; int ret = 0; /* * CAUTION [*endpoint queue*] * * This function will be called from usb_request :: complete * or usb driver timing. * If this function is called from usb_request :: complete, * it is already under spinlock on this driver. * but it is called frm usb driver, this function should call spinlock. * * This function is using usbshg_trylock to solve this issue. * if "is_locked" is 1, this mean this function lock it. * but if it is 0, this mean it is already under spin lock. * see also * CAUTION [*queue handler*] * CAUTION [*request complete*] */ /******************** spin lock ********************/ lock = usbhsg_trylock(gpriv, &flags); /* param check */ if (usbhsg_is_not_connected(gpriv) || unlikely(!gpriv->driver) || unlikely(!pipe)) ret = -ESHUTDOWN; else usbhsg_queue_push(uep, ureq); usbhsg_unlock(lock, &flags); /******************** spin unlock ******************/ usbhsg_queue_prepare(uep); return ret; }
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_queue(struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags) { struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); /* param check */ if (usbhsg_is_not_connected(gpriv) || unlikely(!gpriv->driver) || unlikely(!pipe)) return -ESHUTDOWN; usbhsg_queue_push(uep, ureq); 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 void __usbhsg_recip_send_status(struct usbhsg_gpriv *gpriv, unsigned short status) { struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); struct device *dev = usbhsg_gpriv_to_dev(gpriv); struct usb_request *req; unsigned short *buf; /* alloc new usb_request for recip */ req = usb_ep_alloc_request(&dcp->ep, GFP_ATOMIC); if (!req) { dev_err(dev, "recip request allocation fail\n"); return; } /* alloc recip data buffer */ buf = kmalloc(sizeof(*buf), GFP_ATOMIC); if (!buf) { usb_ep_free_request(&dcp->ep, req); dev_err(dev, "recip data allocation fail\n"); return; } /* recip data is status */ *buf = cpu_to_le16(status); /* allocated usb_request/buffer will be freed */ req->complete = __usbhsg_recip_send_complete; req->buf = buf; req->length = sizeof(*buf); req->zero = 0; /* push packet */ pipe->handler = &usbhs_fifo_pio_push_handler; usbhsg_queue_push(dcp, usbhsg_req_to_ureq(req)); }