/* * dma map/unmap */ static int usbhsg_dma_map_ctrl(struct usbhs_pkt *pkt, int map) { struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt); struct usb_request *req = &ureq->req; struct usbhs_pipe *pipe = pkt->pipe; struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe); struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); enum dma_data_direction dir; int ret = 0; dir = usbhs_pipe_is_dir_host(pipe); if (map) { /* it can not use scatter/gather */ WARN_ON(req->num_sgs); ret = usb_gadget_map_request(&gpriv->gadget, req, dir); if (ret < 0) return ret; pkt->dma = req->dma; } else { usb_gadget_unmap_request(&gpriv->gadget, req, dir); } return ret; }
static void done(struct goku_ep *ep, struct goku_request *req, int status) { struct goku_udc *dev; unsigned stopped = ep->stopped; list_del_init(&req->queue); if (likely(req->req.status == -EINPROGRESS)) req->req.status = status; else status = req->req.status; dev = ep->dev; if (ep->dma) usb_gadget_unmap_request(&dev->gadget, &req->req, ep->is_in); #ifndef USB_TRACE if (status && status != -ESHUTDOWN) #endif VDBG(dev, "complete %s req %p stat %d len %u/%u\n", ep->ep.name, &req->req, status, req->req.actual, req->req.length); /* don't modify queue heads during completion callback */ ep->stopped = 1; spin_unlock(&dev->lock); req->req.complete(&ep->ep, &req->req); spin_lock(&dev->lock); ep->stopped = stopped; }
/** * _hardware_dequeue: handles a request at hardware level * @gadget: gadget * @mEp: endpoint * * This function returns an error code */ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) { if (mReq->req.status != -EALREADY) return -EINVAL; if ((TD_STATUS_ACTIVE & mReq->ptr->token) != 0) return -EBUSY; if (mReq->zptr) { if ((TD_STATUS_ACTIVE & mReq->zptr->token) != 0) return -EBUSY; dma_pool_free(mEp->td_pool, mReq->zptr, mReq->zdma); mReq->zptr = NULL; } mReq->req.status = 0; usb_gadget_unmap_request(&mEp->ci->gadget, &mReq->req, mEp->dir); mReq->req.status = mReq->ptr->token & TD_STATUS; if ((TD_STATUS_HALTED & mReq->req.status) != 0) mReq->req.status = -1; else if ((TD_STATUS_DT_ERR & mReq->req.status) != 0) mReq->req.status = -1; else if ((TD_STATUS_TR_ERR & mReq->req.status) != 0) mReq->req.status = -1; mReq->req.actual = mReq->ptr->token & TD_TOTAL_BYTES; mReq->req.actual >>= ffs_nr(TD_TOTAL_BYTES); mReq->req.actual = mReq->req.length - mReq->req.actual; mReq->req.actual = mReq->req.status ? 0 : mReq->req.actual; return mReq->req.actual; }