+ remaining_length = (tmptoken & TD_TOTAL_BYTES);
+ remaining_length >>= __ffs(TD_TOTAL_BYTES);
+ actual -= remaining_length;
+
+ mReq->req.status = tmptoken & TD_STATUS;
+ if ((TD_STATUS_HALTED & mReq->req.status)) {
+ mReq->req.status = -EPIPE;
+ break;
+ } else if ((TD_STATUS_DT_ERR & mReq->req.status)) {
+ mReq->req.status = -EPROTO;
+ break;
+ } else if ((TD_STATUS_TR_ERR & mReq->req.status)) {
+ mReq->req.status = -EILSEQ;
+ break;
+ }
+
+ if (remaining_length) {
+ if (mEp->dir) {
+ mReq->req.status = -EPROTO;
+ break;
+ }
+ }
+ /*
+ * As the hardware could still address the freed td
+ * which will run the udc unusable, the cleanup of the
+ * td has to be delayed by one.
+ */
+ if (mEp->pending_td)
+ free_pending_td(mEp);
+
+ mEp->pending_td = node;
+ list_del_init(&node->td);
+ }