diff options
author | Jonathan Matthew <jmatthew@cvs.openbsd.org> | 2015-06-28 11:48:19 +0000 |
---|---|---|
committer | Jonathan Matthew <jmatthew@cvs.openbsd.org> | 2015-06-28 11:48:19 +0000 |
commit | a1e08a308f333afc17c5adda8075a25d65e423b8 (patch) | |
tree | 502e20d02c51cd2dd20a1dc738997ce2a738ab08 /sys/dev/usb/dwc2 | |
parent | e68bbaebbd4c651e7d13c22f491ffca8b3e1f935 (diff) |
Convert list_head lists into TAILQs and LISTs and fix up header includes
so we can build dwc2 without extra stuff.
tested by several edgerouter lite owners, ok jasper@
Diffstat (limited to 'sys/dev/usb/dwc2')
-rw-r--r-- | sys/dev/usb/dwc2/dwc2.c | 4 | ||||
-rw-r--r-- | sys/dev/usb/dwc2/dwc2.h | 4 | ||||
-rw-r--r-- | sys/dev/usb/dwc2/dwc2_core.c | 6 | ||||
-rw-r--r-- | sys/dev/usb/dwc2/dwc2_core.h | 22 | ||||
-rw-r--r-- | sys/dev/usb/dwc2/dwc2_coreintr.c | 8 | ||||
-rw-r--r-- | sys/dev/usb/dwc2/dwc2_hcd.c | 166 | ||||
-rw-r--r-- | sys/dev/usb/dwc2/dwc2_hcd.h | 14 | ||||
-rw-r--r-- | sys/dev/usb/dwc2/dwc2_hcdddma.c | 40 | ||||
-rw-r--r-- | sys/dev/usb/dwc2/dwc2_hcdintr.c | 45 | ||||
-rw-r--r-- | sys/dev/usb/dwc2/dwc2_hcdqueue.c | 64 |
10 files changed, 189 insertions, 184 deletions
diff --git a/sys/dev/usb/dwc2/dwc2.c b/sys/dev/usb/dwc2/dwc2.c index 3414b2d6220..d1e3319da32 100644 --- a/sys/dev/usb/dwc2/dwc2.c +++ b/sys/dev/usb/dwc2/dwc2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dwc2.c,v 1.30 2015/06/26 11:17:34 mpi Exp $ */ +/* $OpenBSD: dwc2.c,v 1.31 2015/06/28 11:48:18 jmatthew Exp $ */ /* $NetBSD: dwc2.c,v 1.32 2014/09/02 23:26:20 macallan Exp $ */ /*- @@ -1466,7 +1466,7 @@ dwc2_worker(struct task *wk, void *priv) struct dwc2_softc *sc = priv; struct dwc2_hsotg *hsotg = sc->sc_hsotg; -Debugger(); +/* Debugger(); */ #if 0 struct usbd_xfer *xfer = dwork->xfer; struct dwc2_xfer *dxfer = DWC2_XFER2DXFER(xfer); diff --git a/sys/dev/usb/dwc2/dwc2.h b/sys/dev/usb/dwc2/dwc2.h index b3dc6479acd..31fb1875671 100644 --- a/sys/dev/usb/dwc2/dwc2.h +++ b/sys/dev/usb/dwc2/dwc2.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dwc2.h,v 1.12 2015/06/08 08:47:38 jmatthew Exp $ */ +/* $OpenBSD: dwc2.h,v 1.13 2015/06/28 11:48:18 jmatthew Exp $ */ /* $NetBSD: dwc2.h,v 1.4 2014/12/23 16:20:06 macallan Exp $ */ /*- @@ -39,7 +39,7 @@ #include <sys/task.h> #include <sys/timeout.h> -#include <dev/usb/dwc2/linux/list.h> +#include <lib/libkern/libkern.h> #if 0 #include "opt_usb.h" diff --git a/sys/dev/usb/dwc2/dwc2_core.c b/sys/dev/usb/dwc2/dwc2_core.c index 3b17b256e38..d1912d02791 100644 --- a/sys/dev/usb/dwc2/dwc2_core.c +++ b/sys/dev/usb/dwc2/dwc2_core.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dwc2_core.c,v 1.5 2015/02/12 11:38:42 uebayasi Exp $ */ +/* $OpenBSD: dwc2_core.c,v 1.6 2015/06/28 11:48:18 jmatthew Exp $ */ /* $NetBSD: dwc2_core.c,v 1.6 2014/04/03 06:34:58 skrll Exp $ */ /* @@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: dwc2_core.c,v 1.6 2014/04/03 06:34:58 skrll Exp $"); #endif #include <sys/param.h> +#include <sys/systm.h> #include <sys/types.h> #include <sys/signal.h> #include <sys/proc.h> @@ -64,9 +65,6 @@ __KERNEL_RCSID(0, "$NetBSD: dwc2_core.c,v 1.6 2014/04/03 06:34:58 skrll Exp $"); #include <dev/usb/usbdivar.h> #include <dev/usb/usb_mem.h> -#include <dev/usb/dwc2/linux/kernel.h> -#include <dev/usb/dwc2/linux/list.h> - #include <dev/usb/dwc2/dwc2.h> #include <dev/usb/dwc2/dwc2var.h> diff --git a/sys/dev/usb/dwc2/dwc2_core.h b/sys/dev/usb/dwc2/dwc2_core.h index d6e25dc9ec1..c12e91af21e 100644 --- a/sys/dev/usb/dwc2/dwc2_core.h +++ b/sys/dev/usb/dwc2/dwc2_core.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dwc2_core.h,v 1.8 2015/02/12 11:38:42 uebayasi Exp $ */ +/* $OpenBSD: dwc2_core.h,v 1.9 2015/06/28 11:48:18 jmatthew Exp $ */ /* $NetBSD: dwc2_core.h,v 1.5 2014/04/03 06:34:58 skrll Exp $ */ /* @@ -49,8 +49,6 @@ #include <machine/intr.h> #include <machine/bus.h> -#include <dev/usb/dwc2/linux/list.h> - #include <dev/usb/dwc2/dwc2_hw.h> /* Maximum number of Endpoints/HostChannels */ @@ -313,6 +311,8 @@ struct dwc2_core_dma_config { void *set_dma_addr_data; }; +TAILQ_HEAD(dwc2_qh_list, dwc2_qh); + /** * struct dwc2_hsotg - Holds the state of the driver, including the non-periodic * and periodic schedules @@ -441,13 +441,13 @@ struct dwc2_hsotg { } b; } flags; - struct list_head non_periodic_sched_inactive; - struct list_head non_periodic_sched_active; - struct list_head *non_periodic_qh_ptr; - struct list_head periodic_sched_inactive; - struct list_head periodic_sched_ready; - struct list_head periodic_sched_assigned; - struct list_head periodic_sched_queued; + struct dwc2_qh_list non_periodic_sched_inactive; + struct dwc2_qh_list non_periodic_sched_active; + struct dwc2_qh *non_periodic_qh_ptr; + struct dwc2_qh_list periodic_sched_inactive; + struct dwc2_qh_list periodic_sched_ready; + struct dwc2_qh_list periodic_sched_assigned; + struct dwc2_qh_list periodic_sched_queued; u16 periodic_usecs; u16 frame_usecs[8]; u16 frame_number; @@ -462,7 +462,7 @@ struct dwc2_hsotg { int dumped_frame_num_array; #endif - struct list_head free_hc_list; + LIST_HEAD(, dwc2_host_chan) free_hc_list; int periodic_channels; int non_periodic_channels; int available_host_channels; diff --git a/sys/dev/usb/dwc2/dwc2_coreintr.c b/sys/dev/usb/dwc2/dwc2_coreintr.c index 4febcc3c472..03f276af57e 100644 --- a/sys/dev/usb/dwc2/dwc2_coreintr.c +++ b/sys/dev/usb/dwc2/dwc2_coreintr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dwc2_coreintr.c,v 1.7 2015/06/08 08:47:38 jmatthew Exp $ */ +/* $OpenBSD: dwc2_coreintr.c,v 1.8 2015/06/28 11:48:18 jmatthew Exp $ */ /* $NetBSD: dwc2_coreintr.c,v 1.8 2014/04/04 05:40:57 skrll Exp $ */ /* @@ -47,11 +47,14 @@ __KERNEL_RCSID(0, "$NetBSD: dwc2_coreintr.c,v 1.8 2014/04/04 05:40:57 skrll Exp #endif #include <sys/param.h> +#include <sys/systm.h> #include <sys/kernel.h> #include <sys/mutex.h> #include <sys/pool.h> #include <sys/timeout.h> +#include <lib/libkern/libkern.h> + #include <machine/bus.h> #include <dev/usb/usb.h> @@ -59,9 +62,6 @@ __KERNEL_RCSID(0, "$NetBSD: dwc2_coreintr.c,v 1.8 2014/04/04 05:40:57 skrll Exp #include <dev/usb/usbdivar.h> #include <dev/usb/usb_mem.h> -#include <dev/usb/dwc2/linux/kernel.h> -#include <dev/usb/dwc2/linux/list.h> - #include <dev/usb/dwc2/dwc2.h> #include <dev/usb/dwc2/dwc2var.h> diff --git a/sys/dev/usb/dwc2/dwc2_hcd.c b/sys/dev/usb/dwc2/dwc2_hcd.c index a7f6d753e7e..8e7ebf63d37 100644 --- a/sys/dev/usb/dwc2/dwc2_hcd.c +++ b/sys/dev/usb/dwc2/dwc2_hcd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dwc2_hcd.c,v 1.15 2015/06/08 08:47:38 jmatthew Exp $ */ +/* $OpenBSD: dwc2_hcd.c,v 1.16 2015/06/28 11:48:18 jmatthew Exp $ */ /* $NetBSD: dwc2_hcd.c,v 1.15 2014/11/24 10:14:14 skrll Exp $ */ /* @@ -48,6 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: dwc2_hcd.c,v 1.15 2014/11/24 10:14:14 skrll Exp $"); #endif #include <sys/param.h> +#include <sys/systm.h> #include <sys/types.h> #include <sys/malloc.h> #include <sys/signal.h> @@ -62,9 +63,6 @@ __KERNEL_RCSID(0, "$NetBSD: dwc2_hcd.c,v 1.15 2014/11/24 10:14:14 skrll Exp $"); #include <dev/usb/usbdivar.h> #include <dev/usb/usb_mem.h> -#include <dev/usb/dwc2/linux/kernel.h> -#include <dev/usb/dwc2/linux/list.h> - #include <dev/usb/dwc2/dwc2.h> #include <dev/usb/dwc2/dwc2var.h> @@ -120,12 +118,10 @@ STATIC void dwc2_dump_channel_info(struct dwc2_hsotg *hsotg, dev_dbg(hsotg->dev, " xfer_len: %d\n", chan->xfer_len); dev_dbg(hsotg->dev, " qh: %p\n", chan->qh); dev_dbg(hsotg->dev, " NP inactive sched:\n"); - list_for_each_entry(qh, &hsotg->non_periodic_sched_inactive, - qh_list_entry) + TAILQ_FOREACH(qh, &hsotg->non_periodic_sched_inactive, qh_list_entry) dev_dbg(hsotg->dev, " %p\n", qh); dev_dbg(hsotg->dev, " NP active sched:\n"); - list_for_each_entry(qh, &hsotg->non_periodic_sched_active, - qh_list_entry) + TAILQ_FOREACH(qh, &hsotg->non_periodic_sched_active, qh_list_entry) dev_dbg(hsotg->dev, " %p\n", qh); dev_dbg(hsotg->dev, " Channels:\n"); for (i = 0; i < num_channels; i++) { @@ -143,14 +139,13 @@ STATIC void dwc2_dump_channel_info(struct dwc2_hsotg *hsotg, * Must be called with interrupt disabled and spinlock held */ STATIC void dwc2_kill_urbs_in_qh_list(struct dwc2_hsotg *hsotg, - struct list_head *qh_list) + struct dwc2_qh_list *qh_list) { struct dwc2_qh *qh, *qh_tmp; struct dwc2_qtd *qtd, *qtd_tmp; - list_for_each_entry_safe(qh, qh_tmp, qh_list, qh_list_entry) { - list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, - qtd_list_entry) { + TAILQ_FOREACH_SAFE(qh, qh_list, qh_list_entry, qh_tmp) { + TAILQ_FOREACH_SAFE(qtd, &qh->qtd_list, qtd_list_entry, qtd_tmp) { dwc2_host_complete(hsotg, qtd, -ETIMEDOUT); dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); } @@ -158,28 +153,29 @@ STATIC void dwc2_kill_urbs_in_qh_list(struct dwc2_hsotg *hsotg, } STATIC void dwc2_qh_list_free(struct dwc2_hsotg *hsotg, - struct list_head *qh_list) + struct dwc2_qh_list *qh_list) { struct dwc2_qtd *qtd, *qtd_tmp; struct dwc2_qh *qh, *qh_tmp; unsigned long flags; - if (!qh_list->next) + if (TAILQ_EMPTY(qh_list)) { /* The list hasn't been initialized yet */ return; + } spin_lock_irqsave(&hsotg->lock, flags); /* Ensure there are no QTDs or URBs left */ dwc2_kill_urbs_in_qh_list(hsotg, qh_list); - list_for_each_entry_safe(qh, qh_tmp, qh_list, qh_list_entry) { + TAILQ_FOREACH_SAFE(qh, qh_list, qh_list_entry, qh_tmp) { dwc2_hcd_qh_unlink(hsotg, qh); /* Free each QTD in the QH's QTD list */ - list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, - qtd_list_entry) + TAILQ_FOREACH_SAFE(qtd, &qh->qtd_list, qtd_list_entry, qtd_tmp) { dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh); + } spin_unlock_irqrestore(&hsotg->lock, flags); dwc2_hcd_qh_free(hsotg, qh); @@ -243,7 +239,7 @@ STATIC void dwc2_hcd_cleanup_channels(struct dwc2_hsotg *hsotg) /* Flush out any channel requests in slave mode */ for (i = 0; i < num_channels; i++) { channel = hsotg->hc_ptr_array[i]; - if (!list_empty(&channel->hc_list_entry)) + if (channel->in_freelist == 0) continue; hcchar = DWC2_READ_4(hsotg, HCCHAR(i)); if (hcchar & HCCHAR_CHENA) { @@ -256,7 +252,7 @@ STATIC void dwc2_hcd_cleanup_channels(struct dwc2_hsotg *hsotg) for (i = 0; i < num_channels; i++) { channel = hsotg->hc_ptr_array[i]; - if (!list_empty(&channel->hc_list_entry)) + if (channel->in_freelist != 0) continue; hcchar = DWC2_READ_4(hsotg, HCCHAR(i)); if (hcchar & HCCHAR_CHENA) { @@ -266,7 +262,8 @@ STATIC void dwc2_hcd_cleanup_channels(struct dwc2_hsotg *hsotg) } dwc2_hc_cleanup(hsotg, channel); - list_add_tail(&channel->hc_list_entry, &hsotg->free_hc_list); + LIST_INSERT_HEAD(&hsotg->free_hc_list, channel, hc_list_entry); + channel->in_freelist = 1; /* * Added for Descriptor DMA to prevent channel double cleanup in * release_channel_ddma(), which is called from ep_disable when @@ -485,7 +482,7 @@ dwc2_hcd_urb_dequeue(struct dwc2_hsotg *hsotg, if (in_process) { dwc2_hcd_qh_deactivate(hsotg, qh, 0); qh->channel = NULL; - } else if (list_empty(&qh->qtd_list)) { + } else if (TAILQ_EMPTY(&qh->qtd_list)) { dwc2_hcd_qh_unlink(hsotg, qh); } } else { @@ -509,7 +506,7 @@ dwc2_hcd_reinit(struct dwc2_hsotg *hsotg) int i; hsotg->flags.d32 = 0; - hsotg->non_periodic_qh_ptr = &hsotg->non_periodic_sched_active; + hsotg->non_periodic_qh_ptr = NULL; if (hsotg->core_params->uframe_sched > 0) { hsotg->available_host_channels = @@ -523,14 +520,16 @@ dwc2_hcd_reinit(struct dwc2_hsotg *hsotg) * Put all channels in the free channel list and clean up channel * states */ - list_for_each_entry_safe(chan, chan_tmp, &hsotg->free_hc_list, - hc_list_entry) - list_del_init(&chan->hc_list_entry); + LIST_FOREACH_SAFE(chan, &hsotg->free_hc_list, hc_list_entry, chan_tmp) { + LIST_REMOVE(chan, hc_list_entry); + chan->in_freelist = 0; + } num_channels = hsotg->core_params->host_channels; for (i = 0; i < num_channels; i++) { chan = hsotg->hc_ptr_array[i]; - list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list); + LIST_INSERT_HEAD(&hsotg->free_hc_list, chan, hc_list_entry); + chan->in_freelist = 1; dwc2_hc_cleanup(hsotg, chan); } @@ -729,23 +728,23 @@ STATIC int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) if (dbg_qh(qh)) dev_vdbg(hsotg->dev, "%s(%p,%p)\n", __func__, hsotg, qh); - if (list_empty(&qh->qtd_list)) { + if (TAILQ_EMPTY(&qh->qtd_list)) { dev_dbg(hsotg->dev, "No QTDs in QH list\n"); return -ENOMEM; } - if (list_empty(&hsotg->free_hc_list)) { + if (LIST_EMPTY(&hsotg->free_hc_list)) { dev_dbg(hsotg->dev, "No free channel to assign\n"); return -ENOMEM; } - chan = list_first_entry(&hsotg->free_hc_list, struct dwc2_host_chan, - hc_list_entry); + chan = LIST_FIRST(&hsotg->free_hc_list); /* Remove host channel from free list */ - list_del_init(&chan->hc_list_entry); + LIST_REMOVE(chan, hc_list_entry); + chan->in_freelist = 0; - qtd = list_first_entry(&qh->qtd_list, struct dwc2_qtd, qtd_list_entry); + qtd = TAILQ_FIRST(&qh->qtd_list); urb = qtd->urb; qh->channel = chan; qtd->in_process = 1; @@ -808,8 +807,8 @@ STATIC int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) /* Add channel back to free list */ chan->align_buf = 0; chan->multi_count = 0; - list_add_tail(&chan->hc_list_entry, - &hsotg->free_hc_list); + LIST_INSERT_HEAD(&hsotg->free_hc_list, chan, hc_list_entry); + chan->in_freelist = 1; qtd->in_process = 0; qh->channel = NULL; return -ENOMEM; @@ -848,8 +847,7 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions( struct dwc2_hsotg *hsotg) { enum dwc2_transaction_type ret_val = DWC2_TRANSACTION_NONE; - struct list_head *qh_ptr; - struct dwc2_qh *qh; + struct dwc2_qh *qh, *qhn; int num_channels; #ifdef DWC2_DEBUG @@ -857,16 +855,16 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions( #endif /* Process entries in the periodic ready list */ - qh_ptr = hsotg->periodic_sched_ready.next; - while (qh_ptr != &hsotg->periodic_sched_ready) { - if (list_empty(&hsotg->free_hc_list)) + /* TAILQ_FOREACH_SAFE? */ + qh = TAILQ_FIRST(&hsotg->periodic_sched_ready); + while (qh != NULL) { + if (LIST_EMPTY(&hsotg->free_hc_list)) break; if (hsotg->core_params->uframe_sched > 0) { if (hsotg->available_host_channels <= 1) break; hsotg->available_host_channels--; } - qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry); if (dwc2_assign_and_init_hc(hsotg, qh)) break; @@ -874,9 +872,11 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions( * Move the QH from the periodic ready schedule to the * periodic assigned schedule */ - qh_ptr = qh_ptr->next; - list_move(&qh->qh_list_entry, &hsotg->periodic_sched_assigned); + qhn = TAILQ_NEXT(qh, qh_list_entry); + TAILQ_REMOVE(&hsotg->periodic_sched_ready, qh, qh_list_entry); + TAILQ_INSERT_TAIL(&hsotg->periodic_sched_assigned, qh, qh_list_entry); ret_val = DWC2_TRANSACTION_PERIODIC; + qh = qhn; } /* @@ -885,15 +885,14 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions( * reserved for periodic transfers. */ num_channels = hsotg->core_params->host_channels; - qh_ptr = hsotg->non_periodic_sched_inactive.next; - while (qh_ptr != &hsotg->non_periodic_sched_inactive) { + qh = TAILQ_FIRST(&hsotg->non_periodic_sched_inactive); + while (qh != NULL) { if (hsotg->core_params->uframe_sched <= 0 && hsotg->non_periodic_channels >= num_channels - hsotg->periodic_channels) break; - if (list_empty(&hsotg->free_hc_list)) + if (LIST_EMPTY(&hsotg->free_hc_list)) break; - qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry); /* * Check to see if this is a NAK'd retransmit, in which case @@ -904,7 +903,7 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions( if (qh->nak_frame != 0xffff && dwc2_full_frame_num(qh->nak_frame) == dwc2_full_frame_num(dwc2_hcd_get_frame_number(hsotg))) { - qh_ptr = qh_ptr->next; + qh = TAILQ_NEXT(qh, qh_list_entry); continue; } else { qh->nak_frame = 0xffff; @@ -923,9 +922,10 @@ enum dwc2_transaction_type dwc2_hcd_select_transactions( * Move the QH from the non-periodic inactive schedule to the * non-periodic active schedule */ - qh_ptr = qh_ptr->next; - list_move(&qh->qh_list_entry, - &hsotg->non_periodic_sched_active); + qhn = TAILQ_NEXT(qh, qh_list_entry); + TAILQ_REMOVE(&hsotg->non_periodic_sched_inactive, qh, qh_list_entry); + TAILQ_INSERT_TAIL(&hsotg->non_periodic_sched_active, qh, qh_list_entry); + qh = qhn; if (ret_val == DWC2_TRANSACTION_NONE) ret_val = DWC2_TRANSACTION_NON_PERIODIC; @@ -1019,8 +1019,7 @@ STATIC int dwc2_queue_transaction(struct dwc2_hsotg *hsotg, */ STATIC void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) { - struct list_head *qh_ptr; - struct dwc2_qh *qh; + struct dwc2_qh *qh, *qhn; u32 tx_status; u32 fspcavail; u32 gintmsk; @@ -1045,8 +1044,8 @@ STATIC void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) fspcavail); } - qh_ptr = hsotg->periodic_sched_assigned.next; - while (qh_ptr != &hsotg->periodic_sched_assigned) { + qh = TAILQ_FIRST(&hsotg->periodic_sched_assigned); + while (qh != NULL) { tx_status = DWC2_READ_4(hsotg, HPTXSTS); qspcavail = (tx_status & TXSTS_QSPCAVAIL_MASK) >> TXSTS_QSPCAVAIL_SHIFT; @@ -1055,15 +1054,14 @@ STATIC void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) break; } - qh = list_entry(qh_ptr, struct dwc2_qh, qh_list_entry); if (!qh->channel) { - qh_ptr = qh_ptr->next; + qh = TAILQ_NEXT(qh, qh_list_entry); continue; } /* Make sure EP's TT buffer is clean before queueing qtds */ if (qh->tt_buffer_dirty) { - qh_ptr = qh_ptr->next; + qh = TAILQ_NEXT(qh, qh_list_entry); continue; } @@ -1093,16 +1091,18 @@ STATIC void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) */ if (hsotg->core_params->dma_enable > 0 || status == 0 || qh->channel->requests == qh->channel->multi_count) { - qh_ptr = qh_ptr->next; + qhn = TAILQ_NEXT(qh, qh_list_entry); /* * Move the QH from the periodic assigned schedule to * the periodic queued schedule */ - list_move(&qh->qh_list_entry, - &hsotg->periodic_sched_queued); + TAILQ_REMOVE(&hsotg->periodic_sched_assigned, qh, qh_list_entry); + TAILQ_INSERT_TAIL(&hsotg->periodic_sched_queued, qh, qh_list_entry); /* done queuing high bandwidth */ hsotg->queuing_high_bandwidth = 0; + + qh = qhn; } } @@ -1121,7 +1121,7 @@ STATIC void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) fspcavail); } - if (!list_empty(&hsotg->periodic_sched_assigned) || + if (!TAILQ_EMPTY(&hsotg->periodic_sched_assigned) || no_queue_space || no_fifo_space) { /* * May need to queue more transactions as the request @@ -1159,7 +1159,6 @@ STATIC void dwc2_process_periodic_channels(struct dwc2_hsotg *hsotg) */ STATIC void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg) { - struct list_head *orig_qh_ptr; struct dwc2_qh *qh; u32 tx_status; u32 qspcavail; @@ -1186,9 +1185,10 @@ STATIC void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg) * Keep track of the starting point. Skip over the start-of-list * entry. */ - if (hsotg->non_periodic_qh_ptr == &hsotg->non_periodic_sched_active) - hsotg->non_periodic_qh_ptr = hsotg->non_periodic_qh_ptr->next; - orig_qh_ptr = hsotg->non_periodic_qh_ptr; + if (hsotg->non_periodic_qh_ptr == NULL) { + hsotg->non_periodic_qh_ptr = TAILQ_FIRST(&hsotg->non_periodic_sched_active); + } + qh = hsotg->non_periodic_qh_ptr; /* * Process once through the active list or until no more space is @@ -1203,8 +1203,6 @@ STATIC void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg) break; } - qh = list_entry(hsotg->non_periodic_qh_ptr, struct dwc2_qh, - qh_list_entry); if (!qh->channel) goto next; @@ -1223,13 +1221,12 @@ STATIC void dwc2_process_non_periodic_channels(struct dwc2_hsotg *hsotg) break; } next: - /* Advance to next QH, skipping start-of-list entry */ - hsotg->non_periodic_qh_ptr = hsotg->non_periodic_qh_ptr->next; - if (hsotg->non_periodic_qh_ptr == - &hsotg->non_periodic_sched_active) - hsotg->non_periodic_qh_ptr = - hsotg->non_periodic_qh_ptr->next; - } while (hsotg->non_periodic_qh_ptr != orig_qh_ptr); + /* Advance to next QH, wrapping to the start if we hit the end */ + qh = TAILQ_NEXT(qh, qh_list_entry); + if (qh == NULL) + qh = TAILQ_FIRST(&hsotg->non_periodic_sched_active); + } while ((qh != hsotg->non_periodic_qh_ptr) && (hsotg->non_periodic_qh_ptr != NULL)); + hsotg->non_periodic_qh_ptr = qh; if (hsotg->core_params->dma_enable <= 0) { tx_status = DWC2_READ_4(hsotg, GNPTXSTS); @@ -1290,13 +1287,13 @@ void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg, /* Process host channels associated with periodic transfers */ if ((tr_type == DWC2_TRANSACTION_PERIODIC || tr_type == DWC2_TRANSACTION_ALL) && - !list_empty(&hsotg->periodic_sched_assigned)) + !TAILQ_EMPTY(&hsotg->periodic_sched_assigned)) dwc2_process_periodic_channels(hsotg); /* Process host channels associated with non-periodic transfers */ if (tr_type == DWC2_TRANSACTION_NON_PERIODIC || tr_type == DWC2_TRANSACTION_ALL) { - if (!list_empty(&hsotg->non_periodic_sched_active)) { + if (!TAILQ_EMPTY(&hsotg->non_periodic_sched_active)) { dwc2_process_non_periodic_channels(hsotg); } else { /* @@ -1311,6 +1308,7 @@ void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg, } } + void dwc2_conn_id_status_change(void *data) { @@ -1882,7 +1880,7 @@ void dwc2_hcd_dump_state(struct dwc2_hsotg *hsotg) if (!(chan->xfer_started && chan->qh)) continue; - list_for_each_entry(qtd, &chan->qh->qtd_list, qtd_list_entry) { + TAILQ_FOREACH(qtd, &chan->qh->qtd_list, qtd_list_entry) { if (!qtd->in_process) break; urb = qtd->urb; @@ -2233,20 +2231,20 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg, timeout_set(&hsotg->wkp_timer, dwc2_wakeup_detected, hsotg); /* Initialize the non-periodic schedule */ - INIT_LIST_HEAD(&hsotg->non_periodic_sched_inactive); - INIT_LIST_HEAD(&hsotg->non_periodic_sched_active); + TAILQ_INIT(&hsotg->non_periodic_sched_inactive); + TAILQ_INIT(&hsotg->non_periodic_sched_active); /* Initialize the periodic schedule */ - INIT_LIST_HEAD(&hsotg->periodic_sched_inactive); - INIT_LIST_HEAD(&hsotg->periodic_sched_ready); - INIT_LIST_HEAD(&hsotg->periodic_sched_assigned); - INIT_LIST_HEAD(&hsotg->periodic_sched_queued); + TAILQ_INIT(&hsotg->periodic_sched_inactive); + TAILQ_INIT(&hsotg->periodic_sched_ready); + TAILQ_INIT(&hsotg->periodic_sched_assigned); + TAILQ_INIT(&hsotg->periodic_sched_queued); /* * Create a host channel descriptor for each host channel implemented * in the controller. Initialize the channel descriptor array. */ - INIT_LIST_HEAD(&hsotg->free_hc_list); + LIST_INIT(&hsotg->free_hc_list); num_channels = hsotg->core_params->host_channels; memset(&hsotg->hc_ptr_array[0], 0, sizeof(hsotg->hc_ptr_array)); diff --git a/sys/dev/usb/dwc2/dwc2_hcd.h b/sys/dev/usb/dwc2/dwc2_hcd.h index a68e02ebbdf..fe744278350 100644 --- a/sys/dev/usb/dwc2/dwc2_hcd.h +++ b/sys/dev/usb/dwc2/dwc2_hcd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dwc2_hcd.h,v 1.12 2015/06/08 08:47:38 jmatthew Exp $ */ +/* $OpenBSD: dwc2_hcd.h,v 1.13 2015/06/28 11:48:18 jmatthew Exp $ */ /* $NetBSD: dwc2_hcd.h,v 1.9 2014/09/03 10:00:08 skrll Exp $ */ /* @@ -161,8 +161,9 @@ struct dwc2_host_chan { enum dwc2_halt_status halt_status; u32 hcint; struct dwc2_qh *qh; - struct list_head hc_list_entry; + LIST_ENTRY(dwc2_host_chan) hc_list_entry; dma_addr_t desc_list_addr; + int in_freelist; }; struct dwc2_hcd_pipe_info { @@ -286,14 +287,15 @@ struct dwc2_qh { struct usb_dma dw_align_buf_usbdma; u8 *dw_align_buf; dma_addr_t dw_align_buf_dma; - struct list_head qtd_list; + TAILQ_HEAD(, dwc2_qtd) qtd_list; struct dwc2_host_chan *channel; - struct list_head qh_list_entry; + TAILQ_ENTRY(dwc2_qh) qh_list_entry; struct usb_dma desc_list_usbdma; struct dwc2_hcd_dma_desc *desc_list; dma_addr_t desc_list_dma; u32 *n_bytes; unsigned tt_buffer_dirty:1; + unsigned linked:1; }; /** @@ -354,7 +356,7 @@ struct dwc2_qtd { u16 isoc_frame_index_last; struct dwc2_hcd_urb *urb; struct dwc2_qh *qh; - struct list_head qtd_list_entry; + TAILQ_ENTRY(dwc2_qtd) qtd_list_entry; }; #ifdef DEBUG @@ -628,7 +630,7 @@ STATIC_INLINE int dwc2_hcd_is_bandwidth_allocated(struct dwc2_hsotg *hsotg, struct dwc2_pipe *dpipe = DWC2_XFER2DPIPE(xfer); struct dwc2_qh *qh = dpipe->priv; - if (qh && !list_empty(&qh->qh_list_entry)) + if (qh && qh->linked) return 1; return 0; diff --git a/sys/dev/usb/dwc2/dwc2_hcdddma.c b/sys/dev/usb/dwc2/dwc2_hcdddma.c index 1805f3869fc..ec071309ad7 100644 --- a/sys/dev/usb/dwc2/dwc2_hcdddma.c +++ b/sys/dev/usb/dwc2/dwc2_hcdddma.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dwc2_hcdddma.c,v 1.9 2015/02/12 06:46:23 uebayasi Exp $ */ +/* $OpenBSD: dwc2_hcdddma.c,v 1.10 2015/06/28 11:48:18 jmatthew Exp $ */ /* $NetBSD: dwc2_hcdddma.c,v 1.6 2014/04/03 06:34:58 skrll Exp $ */ /* @@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: dwc2_hcdddma.c,v 1.6 2014/04/03 06:34:58 skrll Exp $ #endif #include <sys/param.h> +#include <sys/systm.h> #include <sys/types.h> #include <sys/kernel.h> #include <sys/malloc.h> @@ -60,9 +61,6 @@ __KERNEL_RCSID(0, "$NetBSD: dwc2_hcdddma.c,v 1.6 2014/04/03 06:34:58 skrll Exp $ #include <dev/usb/usbdivar.h> #include <dev/usb/usb_mem.h> -#include <dev/usb/dwc2/linux/kernel.h> -#include <dev/usb/dwc2/linux/list.h> - #include <dev/usb/dwc2/dwc2.h> #include <dev/usb/dwc2/dwc2var.h> @@ -313,11 +311,12 @@ STATIC void dwc2_release_channel_ddma(struct dwc2_hsotg *hsotg, * device disconnect. See channel cleanup in dwc2_hcd_disconnect(). */ if (chan->qh) { - if (!list_empty(&chan->hc_list_entry)) - list_del(&chan->hc_list_entry); + if (chan->in_freelist != 0) + LIST_REMOVE(chan, hc_list_entry); dwc2_hc_cleanup(hsotg, chan); - list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list); + LIST_INSERT_HEAD(&hsotg->free_hc_list, chan, hc_list_entry); chan->qh = NULL; + chan->in_freelist = 1; } qh->channel = NULL; @@ -583,7 +582,7 @@ STATIC void dwc2_init_isoc_dma_desc(struct dwc2_hsotg *hsotg, max_xfer_size = qh->dev_speed == USB_SPEED_HIGH ? MAX_ISOC_XFER_SIZE_HS : MAX_ISOC_XFER_SIZE_FS; - list_for_each_entry(qtd, &qh->qtd_list, qtd_list_entry) { + TAILQ_FOREACH(qtd, &qh->qtd_list, qtd_list_entry) { while (qh->ntd < ntd_max && qtd->isoc_frame_index_last < qtd->urb->packet_count) { if (n_desc > 1) @@ -704,7 +703,7 @@ STATIC void dwc2_init_non_isoc_dma_desc(struct dwc2_hsotg *hsotg, * there is always one QTD active. */ - list_for_each_entry(qtd, &qh->qtd_list, qtd_list_entry) { + TAILQ_FOREACH(qtd, &qh->qtd_list, qtd_list_entry) { dev_vdbg(hsotg->dev, "qtd=%p\n", qtd); if (n_desc) { @@ -899,7 +898,7 @@ STATIC void dwc2_complete_isoc_xfer_ddma(struct dwc2_hsotg *hsotg, idx = qh->td_first; if (chan->halt_status == DWC2_HC_XFER_URB_DEQUEUE) { - list_for_each_entry(qtd, &qh->qtd_list, qtd_list_entry) + TAILQ_FOREACH(qtd, &qh->qtd_list, qtd_list_entry) qtd->in_process = 0; return; } @@ -918,8 +917,7 @@ STATIC void dwc2_complete_isoc_xfer_ddma(struct dwc2_hsotg *hsotg, int err = halt_status == DWC2_HC_XFER_AHB_ERR ? -EIO : -EOVERFLOW; - list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, - qtd_list_entry) { + TAILQ_FOREACH_SAFE(qtd, &qh->qtd_list, qtd_list_entry, qtd_tmp) { if (qtd->urb) { for (idx = 0; idx < qtd->urb->packet_count; idx++) { @@ -936,7 +934,7 @@ STATIC void dwc2_complete_isoc_xfer_ddma(struct dwc2_hsotg *hsotg, return; } - list_for_each_entry_safe(qtd, qtd_tmp, &qh->qtd_list, qtd_list_entry) { + TAILQ_FOREACH_SAFE(qtd, &qh->qtd_list, qtd_list_entry, qtd_tmp) { if (!qtd->in_process) break; do { @@ -1110,22 +1108,20 @@ STATIC void dwc2_complete_non_isoc_xfer_ddma(struct dwc2_hsotg *hsotg, int chnum, enum dwc2_halt_status halt_status) { - struct list_head *qtd_item, *qtd_tmp; struct dwc2_qh *qh = chan->qh; - struct dwc2_qtd *qtd = NULL; + struct dwc2_qtd *qtd = NULL, *qtd_tmp; int xfer_done; int desc_num = 0; if (chan->halt_status == DWC2_HC_XFER_URB_DEQUEUE) { - list_for_each_entry(qtd, &qh->qtd_list, qtd_list_entry) + TAILQ_FOREACH(qtd, &qh->qtd_list, qtd_list_entry) qtd->in_process = 0; return; } - list_for_each_safe(qtd_item, qtd_tmp, &qh->qtd_list) { + TAILQ_FOREACH_SAFE(qtd, &qh->qtd_list, qtd_list_entry, qtd_tmp) { int i; - qtd = list_entry(qtd_item, struct dwc2_qtd, qtd_list_entry); xfer_done = 0; for (i = 0; i < qtd->n_desc; i++) { @@ -1192,7 +1188,7 @@ void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg, /* Release the channel if halted or session completed */ if (halt_status != DWC2_HC_XFER_COMPLETE || - list_empty(&qh->qtd_list)) { + TAILQ_EMPTY(&qh->qtd_list)) { /* Halt the channel if session completed */ if (halt_status == DWC2_HC_XFER_COMPLETE) dwc2_hc_halt(hsotg, chan, halt_status); @@ -1200,8 +1196,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); + TAILQ_REMOVE(&hsotg->periodic_sched_queued, qh, qh_list_entry); + TAILQ_INSERT_TAIL(&hsotg->periodic_sched_assigned, qh, qh_list_entry); continue_isoc_xfer = 1; } /* @@ -1218,7 +1214,7 @@ void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg, dwc2_release_channel_ddma(hsotg, qh); dwc2_hcd_qh_unlink(hsotg, qh); - if (!list_empty(&qh->qtd_list)) { + if (!TAILQ_EMPTY(&qh->qtd_list)) { /* * Add back to inactive non-periodic schedule on normal * completion diff --git a/sys/dev/usb/dwc2/dwc2_hcdintr.c b/sys/dev/usb/dwc2/dwc2_hcdintr.c index 094a87f363d..33f5b211900 100644 --- a/sys/dev/usb/dwc2/dwc2_hcdintr.c +++ b/sys/dev/usb/dwc2/dwc2_hcdintr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dwc2_hcdintr.c,v 1.5 2015/02/12 06:46:23 uebayasi Exp $ */ +/* $OpenBSD: dwc2_hcdintr.c,v 1.6 2015/06/28 11:48:18 jmatthew Exp $ */ /* $NetBSD: dwc2_hcdintr.c,v 1.11 2014/11/24 10:14:14 skrll Exp $ */ /* @@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: dwc2_hcdintr.c,v 1.11 2014/11/24 10:14:14 skrll Exp #endif #include <sys/param.h> +#include <sys/systm.h> #include <sys/types.h> #include <sys/pool.h> @@ -56,8 +57,6 @@ __KERNEL_RCSID(0, "$NetBSD: dwc2_hcdintr.c,v 1.11 2014/11/24 10:14:14 skrll Exp #include <dev/usb/usbdivar.h> #include <dev/usb/usb_mem.h> -#include <dev/usb/dwc2/linux/kernel.h> - #include <dev/usb/dwc2/dwc2.h> #include <dev/usb/dwc2/dwc2var.h> @@ -125,8 +124,7 @@ STATIC void dwc2_hc_handle_tt_clear(struct dwc2_hsotg *hsotg, */ STATIC void dwc2_sof_intr(struct dwc2_hsotg *hsotg) { - struct list_head *qh_entry; - struct dwc2_qh *qh; + struct dwc2_qh *qh, *qhn; enum dwc2_transaction_type tr_type; #ifdef DEBUG_SOF @@ -138,17 +136,18 @@ STATIC void dwc2_sof_intr(struct dwc2_hsotg *hsotg) dwc2_track_missed_sofs(hsotg); /* Determine whether any periodic QHs should be executed */ - qh_entry = hsotg->periodic_sched_inactive.next; - while (qh_entry != &hsotg->periodic_sched_inactive) { - qh = list_entry(qh_entry, struct dwc2_qh, qh_list_entry); - qh_entry = qh_entry->next; - if (dwc2_frame_num_le(qh->sched_frame, hsotg->frame_number)) + qh = TAILQ_FIRST(&hsotg->periodic_sched_inactive); + while (qh != NULL) { + qhn = TAILQ_NEXT(qh, qh_list_entry); + if (dwc2_frame_num_le(qh->sched_frame, hsotg->frame_number)) { /* * Move QH to the ready list to be executed next * (micro)frame */ - list_move(&qh->qh_list_entry, - &hsotg->periodic_sched_ready); + TAILQ_REMOVE(&hsotg->periodic_sched_inactive, qh, qh_list_entry); + TAILQ_INSERT_TAIL(&hsotg->periodic_sched_ready, qh, qh_list_entry); + } + qh = qhn; } tr_type = dwc2_hcd_select_transactions(hsotg); if (tr_type != DWC2_TRANSACTION_NONE) @@ -660,12 +659,12 @@ STATIC void dwc2_deactivate_qh(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, dev_vdbg(hsotg->dev, " %s(%p,%p,%d)\n", __func__, hsotg, qh, free_qtd); - if (list_empty(&qh->qtd_list)) { + if (TAILQ_EMPTY(&qh->qtd_list)) { dev_dbg(hsotg->dev, "## QTD list empty ##\n"); goto no_qtd; } - qtd = list_first_entry(&qh->qtd_list, struct dwc2_qtd, qtd_list_entry); + qtd = TAILQ_FIRST(&qh->qtd_list); if (qtd->complete_split) continue_split = 1; @@ -681,8 +680,8 @@ STATIC void dwc2_deactivate_qh(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, no_qtd: if (qh->channel) qh->channel->align_buf = 0; - qh->channel = NULL; dwc2_hcd_qh_deactivate(hsotg, qh, continue_split); + qh->channel = NULL; } /** @@ -753,10 +752,11 @@ cleanup: * function clears the channel interrupt enables and conditions, so * there's no need to clear the Channel Halted interrupt separately. */ - if (!list_empty(&chan->hc_list_entry)) - list_del(&chan->hc_list_entry); + if (chan->in_freelist != 0) + LIST_REMOVE(chan, hc_list_entry); dwc2_hc_cleanup(hsotg, chan); - list_add_tail(&chan->hc_list_entry, &hsotg->free_hc_list); + LIST_INSERT_HEAD(&hsotg->free_hc_list, chan, hc_list_entry); + chan->in_freelist = 1; if (hsotg->core_params->uframe_sched > 0) { hsotg->available_host_channels++; @@ -837,8 +837,8 @@ 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, - &hsotg->periodic_sched_assigned); + TAILQ_REMOVE(&hsotg->periodic_sched_queued, chan->qh, qh_list_entry); + TAILQ_INSERT_TAIL(&hsotg->periodic_sched_assigned, chan->qh, qh_list_entry); /* * Make sure the Periodic Tx FIFO Empty interrupt is @@ -2000,7 +2000,7 @@ STATIC void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum) return; } - if (list_empty(&chan->qh->qtd_list)) { + if (TAILQ_EMPTY(&chan->qh->qtd_list)) { /* * TODO: Will this ever happen with the * DWC2_HC_XFER_URB_DEQUEUE handling above? @@ -2016,8 +2016,7 @@ STATIC void dwc2_hc_n_intr(struct dwc2_hsotg *hsotg, int chnum) return; } - qtd = list_first_entry(&chan->qh->qtd_list, struct dwc2_qtd, - qtd_list_entry); + qtd = TAILQ_FIRST(&chan->qh->qtd_list); if (hsotg->core_params->dma_enable <= 0) { if ((hcint & HCINTMSK_CHHLTD) && hcint != HCINTMSK_CHHLTD) diff --git a/sys/dev/usb/dwc2/dwc2_hcdqueue.c b/sys/dev/usb/dwc2/dwc2_hcdqueue.c index 7eb8162cba1..31bd3826254 100644 --- a/sys/dev/usb/dwc2/dwc2_hcdqueue.c +++ b/sys/dev/usb/dwc2/dwc2_hcdqueue.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dwc2_hcdqueue.c,v 1.6 2015/02/12 06:46:23 uebayasi Exp $ */ +/* $OpenBSD: dwc2_hcdqueue.c,v 1.7 2015/06/28 11:48:18 jmatthew Exp $ */ /* $NetBSD: dwc2_hcdqueue.c,v 1.11 2014/09/03 10:00:08 skrll Exp $ */ /* @@ -48,6 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: dwc2_hcdqueue.c,v 1.11 2014/09/03 10:00:08 skrll Exp #endif #include <sys/param.h> +#include <sys/systm.h> #include <sys/types.h> #include <sys/malloc.h> #include <sys/pool.h> @@ -59,8 +60,6 @@ __KERNEL_RCSID(0, "$NetBSD: dwc2_hcdqueue.c,v 1.11 2014/09/03 10:00:08 skrll Exp #include <dev/usb/usbdivar.h> #include <dev/usb/usb_mem.h> -#include <dev/usb/dwc2/linux/kernel.h> - #include <dev/usb/dwc2/dwc2.h> #include <dev/usb/dwc2/dwc2var.h> @@ -91,8 +90,8 @@ STATIC void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, qh->data_toggle = DWC2_HC_PID_DATA0; qh->maxp = dwc2_hcd_get_mps(&urb->pipe_info); - INIT_LIST_HEAD(&qh->qtd_list); - INIT_LIST_HEAD(&qh->qh_list_entry); + TAILQ_INIT(&qh->qtd_list); + qh->linked = 0; /* FS/LS Endpoint on HS Hub, NOT virtual root hub */ dev_speed = dwc2_host_get_speed(hsotg, urb->priv); @@ -540,11 +539,11 @@ STATIC int dwc2_schedule_periodic(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) if (hsotg->core_params->dma_desc_enable > 0) /* Don't rely on SOF and start in ready schedule */ - list_add_tail(&qh->qh_list_entry, &hsotg->periodic_sched_ready); + TAILQ_INSERT_TAIL(&hsotg->periodic_sched_ready, qh, qh_list_entry); else /* Always start in inactive schedule */ - list_add_tail(&qh->qh_list_entry, - &hsotg->periodic_sched_inactive); + TAILQ_INSERT_TAIL(&hsotg->periodic_sched_inactive, qh, qh_list_entry); + qh->linked = 1; if (hsotg->core_params->uframe_sched <= 0) /* Reserve periodic channel */ @@ -568,7 +567,7 @@ STATIC void dwc2_deschedule_periodic(struct dwc2_hsotg *hsotg, { int i; - list_del_init(&qh->qh_list_entry); + qh->linked = 0; /* Update claimed usecs per (micro)frame */ hsotg->periodic_usecs -= qh->usecs; @@ -602,15 +601,16 @@ int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) if (dbg_qh(qh)) dev_vdbg(hsotg->dev, "%s()\n", __func__); - if (!list_empty(&qh->qh_list_entry)) + if (qh->linked != 0) { /* QH already in a schedule */ return 0; + } /* Add the new QH to the appropriate schedule */ if (dwc2_qh_is_non_per(qh)) { /* Always start in inactive schedule */ - list_add_tail(&qh->qh_list_entry, - &hsotg->non_periodic_sched_inactive); + TAILQ_INSERT_TAIL(&hsotg->non_periodic_sched_inactive, qh, qh_list_entry); + qh->linked = 1; return 0; } status = dwc2_schedule_periodic(hsotg, qh); @@ -639,15 +639,26 @@ void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) dev_vdbg(hsotg->dev, "%s()\n", __func__); - if (list_empty(&qh->qh_list_entry)) + if (qh->linked == 0) { /* QH is not in a schedule */ return; + } if (dwc2_qh_is_non_per(qh)) { - if (hsotg->non_periodic_qh_ptr == &qh->qh_list_entry) + if (hsotg->non_periodic_qh_ptr == qh) { hsotg->non_periodic_qh_ptr = - hsotg->non_periodic_qh_ptr->next; - list_del_init(&qh->qh_list_entry); + TAILQ_NEXT(qh, qh_list_entry); + } + + if (qh->channel) { + TAILQ_REMOVE(&hsotg->non_periodic_sched_active, qh, qh_list_entry); + } else { + TAILQ_REMOVE(&hsotg->non_periodic_sched_inactive, qh, qh_list_entry); + } + qh->linked = 0; + + if (hsotg->non_periodic_qh_ptr == NULL) + hsotg->non_periodic_qh_ptr = TAILQ_FIRST(&hsotg->non_periodic_sched_active); return; } dwc2_deschedule_periodic(hsotg, qh); @@ -717,7 +728,7 @@ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, if (dwc2_qh_is_non_per(qh)) { dwc2_hcd_qh_unlink(hsotg, qh); - if (!list_empty(&qh->qtd_list)) + if (!TAILQ_EMPTY(&qh->qtd_list)) /* Add back to inactive non-periodic schedule */ dwc2_hcd_qh_add(hsotg, qh); return; @@ -735,7 +746,7 @@ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, qh->sched_frame = frame_number; } - if (list_empty(&qh->qtd_list)) { + if (TAILQ_EMPTY(&qh->qtd_list)) { dwc2_hcd_qh_unlink(hsotg, qh); return; } @@ -743,13 +754,15 @@ void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, * Remove from periodic_sched_queued and move to * appropriate queue */ + TAILQ_REMOVE(&hsotg->periodic_sched_queued, qh, qh_list_entry); if ((hsotg->core_params->uframe_sched > 0 && 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); - else - list_move(&qh->qh_list_entry, &hsotg->periodic_sched_inactive); + qh->sched_frame == frame_number)) { + TAILQ_INSERT_TAIL(&hsotg->periodic_sched_ready, qh, qh_list_entry); + } else { + TAILQ_INSERT_TAIL(&hsotg->periodic_sched_inactive, qh, qh_list_entry); + } } /** @@ -821,7 +834,7 @@ int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, goto fail; qtd->qh = *qh; - list_add_tail(&qtd->qtd_list_entry, &(*qh)->qtd_list); + TAILQ_INSERT_TAIL(&(*qh)->qtd_list, qtd, qtd_list_entry); return 0; @@ -834,8 +847,7 @@ fail: dwc2_hcd_qh_unlink(hsotg, qh_tmp); /* Free each QTD in the QH's QTD list */ - list_for_each_entry_safe(qtd2, qtd2_tmp, &qh_tmp->qtd_list, - qtd_list_entry) + TAILQ_FOREACH_SAFE(qtd2, &qh_tmp->qtd_list, qtd_list_entry, qtd2_tmp) dwc2_hcd_qtd_unlink_and_free(hsotg, qtd2, qh_tmp); dwc2_hcd_qh_free(hsotg, qh_tmp); @@ -850,7 +862,7 @@ void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg, { struct dwc2_softc *sc = hsotg->hsotg_sc; - list_del_init(&qtd->qtd_list_entry); + TAILQ_REMOVE(&qh->qtd_list, qtd, qtd_list_entry); pool_put(&sc->sc_qtdpool, qtd); } |