usb: wusbcore: add a convenience function for completing a transfer segment
This patch adds a convenience function for the commonly performed task of marking a transfer segment as done. It combines the 3 steps of setting the segment status, incrementing the segs_done field of the transfer and checking if the completed segment results in the transfer also being done. Signed-off-by: Thomas Pugliese <thomas.pugliese@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
5da43afc2b
commit
e500d526f9
@@ -391,6 +391,24 @@ out:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mark the given segment as done. Return true if this completes the xfer.
|
||||||
|
* This should only be called for segs that have been submitted to an RPIPE.
|
||||||
|
* Delayed segs are not marked as submitted so they do not need to be marked
|
||||||
|
* as done when cleaning up.
|
||||||
|
*
|
||||||
|
* xfer->lock has to be locked
|
||||||
|
*/
|
||||||
|
static unsigned __wa_xfer_mark_seg_as_done(struct wa_xfer *xfer,
|
||||||
|
struct wa_seg *seg, enum wa_seg_status status)
|
||||||
|
{
|
||||||
|
seg->status = status;
|
||||||
|
xfer->segs_done++;
|
||||||
|
|
||||||
|
/* check for done. */
|
||||||
|
return __wa_xfer_is_done(xfer);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Search for a transfer list ID on the HCD's URB list
|
* Search for a transfer list ID on the HCD's URB list
|
||||||
*
|
*
|
||||||
@@ -821,12 +839,10 @@ error_default:
|
|||||||
wa_reset_all(wa);
|
wa_reset_all(wa);
|
||||||
}
|
}
|
||||||
if (seg->status != WA_SEG_ERROR) {
|
if (seg->status != WA_SEG_ERROR) {
|
||||||
seg->status = WA_SEG_ERROR;
|
|
||||||
seg->result = urb->status;
|
seg->result = urb->status;
|
||||||
xfer->segs_done++;
|
|
||||||
__wa_xfer_abort(xfer);
|
__wa_xfer_abort(xfer);
|
||||||
rpipe_ready = rpipe_avail_inc(rpipe);
|
rpipe_ready = rpipe_avail_inc(rpipe);
|
||||||
done = __wa_xfer_is_done(xfer);
|
done = __wa_xfer_mark_seg_as_done(xfer, seg, WA_SEG_ERROR);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&xfer->lock, flags);
|
spin_unlock_irqrestore(&xfer->lock, flags);
|
||||||
if (holding_dto) {
|
if (holding_dto) {
|
||||||
@@ -892,12 +908,11 @@ static void wa_seg_iso_pack_desc_cb(struct urb *urb)
|
|||||||
}
|
}
|
||||||
if (seg->status != WA_SEG_ERROR) {
|
if (seg->status != WA_SEG_ERROR) {
|
||||||
usb_unlink_urb(seg->dto_urb);
|
usb_unlink_urb(seg->dto_urb);
|
||||||
seg->status = WA_SEG_ERROR;
|
|
||||||
seg->result = urb->status;
|
seg->result = urb->status;
|
||||||
xfer->segs_done++;
|
|
||||||
__wa_xfer_abort(xfer);
|
__wa_xfer_abort(xfer);
|
||||||
rpipe_ready = rpipe_avail_inc(rpipe);
|
rpipe_ready = rpipe_avail_inc(rpipe);
|
||||||
done = __wa_xfer_is_done(xfer);
|
done = __wa_xfer_mark_seg_as_done(xfer, seg,
|
||||||
|
WA_SEG_ERROR);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&xfer->lock, flags);
|
spin_unlock_irqrestore(&xfer->lock, flags);
|
||||||
if (done)
|
if (done)
|
||||||
@@ -971,12 +986,10 @@ static void wa_seg_tr_cb(struct urb *urb)
|
|||||||
}
|
}
|
||||||
usb_unlink_urb(seg->isoc_pack_desc_urb);
|
usb_unlink_urb(seg->isoc_pack_desc_urb);
|
||||||
usb_unlink_urb(seg->dto_urb);
|
usb_unlink_urb(seg->dto_urb);
|
||||||
seg->status = WA_SEG_ERROR;
|
|
||||||
seg->result = urb->status;
|
seg->result = urb->status;
|
||||||
xfer->segs_done++;
|
|
||||||
__wa_xfer_abort(xfer);
|
__wa_xfer_abort(xfer);
|
||||||
rpipe_ready = rpipe_avail_inc(rpipe);
|
rpipe_ready = rpipe_avail_inc(rpipe);
|
||||||
done = __wa_xfer_is_done(xfer);
|
done = __wa_xfer_mark_seg_as_done(xfer, seg, WA_SEG_ERROR);
|
||||||
spin_unlock_irqrestore(&xfer->lock, flags);
|
spin_unlock_irqrestore(&xfer->lock, flags);
|
||||||
if (done)
|
if (done)
|
||||||
wa_xfer_completion(xfer);
|
wa_xfer_completion(xfer);
|
||||||
@@ -2285,11 +2298,9 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer,
|
|||||||
goto error_submit_buf_in;
|
goto error_submit_buf_in;
|
||||||
} else {
|
} else {
|
||||||
/* OUT data phase or no data, complete it -- */
|
/* OUT data phase or no data, complete it -- */
|
||||||
seg->status = WA_SEG_DONE;
|
|
||||||
seg->result = bytes_transferred;
|
seg->result = bytes_transferred;
|
||||||
xfer->segs_done++;
|
|
||||||
rpipe_ready = rpipe_avail_inc(rpipe);
|
rpipe_ready = rpipe_avail_inc(rpipe);
|
||||||
done = __wa_xfer_is_done(xfer);
|
done = __wa_xfer_mark_seg_as_done(xfer, seg, WA_SEG_DONE);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&xfer->lock, flags);
|
spin_unlock_irqrestore(&xfer->lock, flags);
|
||||||
if (done)
|
if (done)
|
||||||
@@ -2453,10 +2464,8 @@ static int wa_process_iso_packet_status(struct wahc *wa, struct urb *urb)
|
|||||||
dti_busy = 1;
|
dti_busy = 1;
|
||||||
} else {
|
} else {
|
||||||
/* OUT transfer or no more IN data, complete it -- */
|
/* OUT transfer or no more IN data, complete it -- */
|
||||||
seg->status = WA_SEG_DONE;
|
|
||||||
xfer->segs_done++;
|
|
||||||
rpipe_ready = rpipe_avail_inc(rpipe);
|
rpipe_ready = rpipe_avail_inc(rpipe);
|
||||||
done = __wa_xfer_is_done(xfer);
|
done = __wa_xfer_mark_seg_as_done(xfer, seg, WA_SEG_DONE);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&xfer->lock, flags);
|
spin_unlock_irqrestore(&xfer->lock, flags);
|
||||||
wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING;
|
wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING;
|
||||||
@@ -2547,12 +2556,11 @@ static void wa_buf_in_cb(struct urb *urb)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rpipe = xfer->ep->hcpriv;
|
rpipe = xfer->ep->hcpriv;
|
||||||
seg->status = WA_SEG_DONE;
|
|
||||||
dev_dbg(dev, "xfer %p#%u: data in done (%zu bytes)\n",
|
dev_dbg(dev, "xfer %p#%u: data in done (%zu bytes)\n",
|
||||||
xfer, seg->index, seg->result);
|
xfer, seg->index, seg->result);
|
||||||
xfer->segs_done++;
|
|
||||||
rpipe_ready = rpipe_avail_inc(rpipe);
|
rpipe_ready = rpipe_avail_inc(rpipe);
|
||||||
done = __wa_xfer_is_done(xfer);
|
done = __wa_xfer_mark_seg_as_done(xfer, seg,
|
||||||
|
WA_SEG_DONE);
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&xfer->lock, flags);
|
spin_unlock_irqrestore(&xfer->lock, flags);
|
||||||
if (done)
|
if (done)
|
||||||
@@ -2575,12 +2583,10 @@ static void wa_buf_in_cb(struct urb *urb)
|
|||||||
"exceeded, resetting device\n");
|
"exceeded, resetting device\n");
|
||||||
wa_reset_all(wa);
|
wa_reset_all(wa);
|
||||||
}
|
}
|
||||||
seg->status = WA_SEG_ERROR;
|
|
||||||
seg->result = urb->status;
|
seg->result = urb->status;
|
||||||
xfer->segs_done++;
|
|
||||||
rpipe_ready = rpipe_avail_inc(rpipe);
|
rpipe_ready = rpipe_avail_inc(rpipe);
|
||||||
__wa_xfer_abort(xfer);
|
__wa_xfer_abort(xfer);
|
||||||
done = __wa_xfer_is_done(xfer);
|
done = __wa_xfer_mark_seg_as_done(xfer, seg, WA_SEG_ERROR);
|
||||||
spin_unlock_irqrestore(&xfer->lock, flags);
|
spin_unlock_irqrestore(&xfer->lock, flags);
|
||||||
if (done)
|
if (done)
|
||||||
wa_xfer_completion(xfer);
|
wa_xfer_completion(xfer);
|
||||||
|
|||||||
Reference in New Issue
Block a user