summaryrefslogtreecommitdiff
path: root/sys/dev/usb/dwc2
diff options
context:
space:
mode:
authorJonathan Matthew <jmatthew@cvs.openbsd.org>2015-06-28 11:48:19 +0000
committerJonathan Matthew <jmatthew@cvs.openbsd.org>2015-06-28 11:48:19 +0000
commita1e08a308f333afc17c5adda8075a25d65e423b8 (patch)
tree502e20d02c51cd2dd20a1dc738997ce2a738ab08 /sys/dev/usb/dwc2
parente68bbaebbd4c651e7d13c22f491ffca8b3e1f935 (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.c4
-rw-r--r--sys/dev/usb/dwc2/dwc2.h4
-rw-r--r--sys/dev/usb/dwc2/dwc2_core.c6
-rw-r--r--sys/dev/usb/dwc2/dwc2_core.h22
-rw-r--r--sys/dev/usb/dwc2/dwc2_coreintr.c8
-rw-r--r--sys/dev/usb/dwc2/dwc2_hcd.c166
-rw-r--r--sys/dev/usb/dwc2/dwc2_hcd.h14
-rw-r--r--sys/dev/usb/dwc2/dwc2_hcdddma.c40
-rw-r--r--sys/dev/usb/dwc2/dwc2_hcdintr.c45
-rw-r--r--sys/dev/usb/dwc2/dwc2_hcdqueue.c64
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);
}