Commit 335053fe authored by Thomas Pugliese's avatar Thomas Pugliese Committed by Greg Kroah-Hartman

usb: wusbcore: use multiple urbs for HWA iso transfer result frame reads

Submit multiple concurrent urbs for HWA isochronous transfer result data
frame reads.  This keeps the read pipeline full and significantly
improves performance in cases where the frame reads cannot be combined
because they are not contiguous or multiples of the max packet size.
Signed-off-by: default avatarThomas Pugliese <thomas.pugliese@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 04a378f3
...@@ -75,8 +75,6 @@ void __wa_destroy(struct wahc *wa) ...@@ -75,8 +75,6 @@ void __wa_destroy(struct wahc *wa)
if (wa->dti_urb) { if (wa->dti_urb) {
usb_kill_urb(wa->dti_urb); usb_kill_urb(wa->dti_urb);
usb_put_urb(wa->dti_urb); usb_put_urb(wa->dti_urb);
usb_kill_urb(wa->buf_in_urb);
usb_put_urb(wa->buf_in_urb);
} }
kfree(wa->dti_buf); kfree(wa->dti_buf);
wa_nep_destroy(wa); wa_nep_destroy(wa);
......
...@@ -125,7 +125,8 @@ struct wa_rpipe { ...@@ -125,7 +125,8 @@ struct wa_rpipe {
enum wa_dti_state { enum wa_dti_state {
WA_DTI_TRANSFER_RESULT_PENDING, WA_DTI_TRANSFER_RESULT_PENDING,
WA_DTI_ISOC_PACKET_STATUS_PENDING WA_DTI_ISOC_PACKET_STATUS_PENDING,
WA_DTI_BUF_IN_DATA_PENDING
}; };
enum wa_quirks { enum wa_quirks {
...@@ -146,6 +147,8 @@ enum wa_vendor_specific_requests { ...@@ -146,6 +147,8 @@ enum wa_vendor_specific_requests {
WA_REQ_ALEREON_FEATURE_SET = 0x01, WA_REQ_ALEREON_FEATURE_SET = 0x01,
WA_REQ_ALEREON_FEATURE_CLEAR = 0x00, WA_REQ_ALEREON_FEATURE_CLEAR = 0x00,
}; };
#define WA_MAX_BUF_IN_URBS 4
/** /**
* Instance of a HWA Host Controller * Instance of a HWA Host Controller
* *
...@@ -216,7 +219,9 @@ struct wahc { ...@@ -216,7 +219,9 @@ struct wahc {
u32 dti_isoc_xfer_in_progress; u32 dti_isoc_xfer_in_progress;
u8 dti_isoc_xfer_seg; u8 dti_isoc_xfer_seg;
struct urb *dti_urb; /* URB for reading xfer results */ struct urb *dti_urb; /* URB for reading xfer results */
struct urb *buf_in_urb; /* URB for reading data in */ /* URBs for reading data in */
struct urb buf_in_urbs[WA_MAX_BUF_IN_URBS];
int active_buf_in_urbs; /* number of buf_in_urbs active. */
struct edc dti_edc; /* DTI error density counter */ struct edc dti_edc; /* DTI error density counter */
void *dti_buf; void *dti_buf;
size_t dti_buf_size; size_t dti_buf_size;
...@@ -286,6 +291,8 @@ static inline void wa_rpipe_init(struct wahc *wa) ...@@ -286,6 +291,8 @@ static inline void wa_rpipe_init(struct wahc *wa)
static inline void wa_init(struct wahc *wa) static inline void wa_init(struct wahc *wa)
{ {
int index;
edc_init(&wa->nep_edc); edc_init(&wa->nep_edc);
atomic_set(&wa->notifs_queued, 0); atomic_set(&wa->notifs_queued, 0);
wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING; wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING;
...@@ -299,6 +306,10 @@ static inline void wa_init(struct wahc *wa) ...@@ -299,6 +306,10 @@ static inline void wa_init(struct wahc *wa)
INIT_WORK(&wa->xfer_error_work, wa_process_errored_transfers_run); INIT_WORK(&wa->xfer_error_work, wa_process_errored_transfers_run);
wa->dto_in_use = 0; wa->dto_in_use = 0;
atomic_set(&wa->xfer_id_count, 1); atomic_set(&wa->xfer_id_count, 1);
/* init the buf in URBs */
for (index = 0; index < WA_MAX_BUF_IN_URBS; ++index)
usb_init_urb(&(wa->buf_in_urbs[index]));
wa->active_buf_in_urbs = 0;
} }
/** /**
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment