[PATCH v5 06/21] usb: dwc2: host: Always add to the tail of queues
Kever Yang
kever.yang at rock-chips.com
Wed Jan 27 02:23:54 PST 2016
Hi Doug,
This is obviously a bug in dwc2 driver which not meet the usb 2.0
spec, and this patch can fix it.
Reviewed-by: Kever Yang <kever.yang at rock-chips.com>
Thanks,
- Kever
On 01/23/2016 02:18 AM, Douglas Anderson wrote:
> The queues the the dwc2 host controller used are truly queues. That
> means FIFO or first in first out.
>
> Unfortunately though the code was iterating through these queues
> starting from the head, some places in the code was adding things to the
> queue by adding at the head instead of the tail. That means last in
> first out. Doh.
>
> Go through and just always add to the tail.
>
> Doing this makes things much happier when I've got:
> * 7-port USB 2.0 Single-TT hub
> * - Microsoft 2.4 GHz Transceiver v7.0 dongle
> * - Jabra speakerphone playing music
>
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> ---
> Changes in v5: None
> Changes in v4:
> - Always add to the tail of queues new for v4.
>
> Changes in v3: None
> Changes in v2: None
>
> drivers/usb/dwc2/hcd.c | 11 ++++++-----
> drivers/usb/dwc2/hcd_ddma.c | 4 ++--
> drivers/usb/dwc2/hcd_intr.c | 4 ++--
> drivers/usb/dwc2/hcd_queue.c | 6 ++++--
> 4 files changed, 14 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
> index 7783c8ba0173..d2daaea88d91 100644
> --- a/drivers/usb/dwc2/hcd.c
> +++ b/drivers/usb/dwc2/hcd.c
> @@ -969,7 +969,8 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
> * periodic assigned schedule
> */
> qh_ptr = qh_ptr->next;
> - list_move(&qh->qh_list_entry, &hsotg->periodic_sched_assigned);
> + list_move_tail(&qh->qh_list_entry,
> + &hsotg->periodic_sched_assigned);
> ret_val = DWC2_TRANSACTION_PERIODIC;
> }
>
> @@ -1002,8 +1003,8 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions(
> * non-periodic active schedule
> */
> qh_ptr = qh_ptr->next;
> - list_move(&qh->qh_list_entry,
> - &hsotg->non_periodic_sched_active);
> + list_move_tail(&qh->qh_list_entry,
> + &hsotg->non_periodic_sched_active);
>
> if (ret_val == DWC2_TRANSACTION_NONE)
> ret_val = DWC2_TRANSACTION_NON_PERIODIC;
> @@ -1176,8 +1177,8 @@ static void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg)
> * Move the QH from the periodic assigned schedule to
> * the periodic queued schedule
> */
> - list_move(&qh->qh_list_entry,
> - &hsotg->periodic_sched_queued);
> + list_move_tail(&qh->qh_list_entry,
> + &hsotg->periodic_sched_queued);
>
> /* done queuing high bandwidth */
> hsotg->queuing_high_bandwidth = 0;
> diff --git a/drivers/usb/dwc2/hcd_ddma.c b/drivers/usb/dwc2/hcd_ddma.c
> index 36606fc33c0d..16b261cfa92d 100644
> --- a/drivers/usb/dwc2/hcd_ddma.c
> +++ b/drivers/usb/dwc2/hcd_ddma.c
> @@ -1327,8 +1327,8 @@ void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg,
> dwc2_hcd_qh_unlink(hsotg, qh);
> } else {
> /* Keep in assigned schedule to continue transfer */
> - list_move(&qh->qh_list_entry,
> - &hsotg->periodic_sched_assigned);
> + list_move_tail(&qh->qh_list_entry,
> + &hsotg->periodic_sched_assigned);
> /*
> * If channel has been halted during giveback of urb
> * then prevent any new scheduling.
> diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
> index 99efc2bd1617..2c521c00e5e0 100644
> --- a/drivers/usb/dwc2/hcd_intr.c
> +++ b/drivers/usb/dwc2/hcd_intr.c
> @@ -143,7 +143,7 @@ static void dwc2_sof_intr(struct dwc2_hsotg *hsotg)
> * Move QH to the ready list to be executed next
> * (micro)frame
> */
> - list_move(&qh->qh_list_entry,
> + list_move_tail(&qh->qh_list_entry,
> &hsotg->periodic_sched_ready);
> }
> tr_type = dwc2_hcd_select_transactions(hsotg);
> @@ -794,7 +794,7 @@ static void dwc2_halt_channel(struct dwc2_hsotg *hsotg,
> * halt to be queued when the periodic schedule is
> * processed.
> */
> - list_move(&chan->qh->qh_list_entry,
> + list_move_tail(&chan->qh->qh_list_entry,
> &hsotg->periodic_sched_assigned);
>
> /*
> diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
> index e0933a9dfad7..bc632a72f611 100644
> --- a/drivers/usb/dwc2/hcd_queue.c
> +++ b/drivers/usb/dwc2/hcd_queue.c
> @@ -732,9 +732,11 @@ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
> dwc2_frame_num_le(qh->sched_frame, frame_number)) ||
> (hsotg->core_params->uframe_sched <= 0 &&
> qh->sched_frame == frame_number))
> - list_move(&qh->qh_list_entry, &hsotg->periodic_sched_ready);
> + list_move_tail(&qh->qh_list_entry,
> + &hsotg->periodic_sched_ready);
> else
> - list_move(&qh->qh_list_entry, &hsotg->periodic_sched_inactive);
> + list_move_tail(&qh->qh_list_entry,
> + &hsotg->periodic_sched_inactive);
> }
>
> /**
More information about the Linux-rockchip
mailing list