svn commit: r240969 - head/sys/dev/usb/controller
Hans Petter Selasky
hselasky at FreeBSD.org
Wed Sep 26 18:59:21 UTC 2012
Author: hselasky
Date: Wed Sep 26 18:59:20 2012
New Revision: 240969
URL: http://svn.freebsd.org/changeset/base/240969
Log:
Make sure the DWC OTG host mode channels are given enough time to disable.
Modified:
head/sys/dev/usb/controller/dwc_otg.c
head/sys/dev/usb/controller/dwc_otg.h
Modified: head/sys/dev/usb/controller/dwc_otg.c
==============================================================================
--- head/sys/dev/usb/controller/dwc_otg.c Wed Sep 26 18:11:43 2012 (r240968)
+++ head/sys/dev/usb/controller/dwc_otg.c Wed Sep 26 18:59:20 2012 (r240969)
@@ -507,6 +507,7 @@ static uint8_t
dwc_otg_host_channel_wait(struct dwc_otg_td *td)
{
struct dwc_otg_softc *sc;
+ uint16_t frame;
uint8_t x;
x = td->channel;
@@ -524,6 +525,8 @@ dwc_otg_host_channel_wait(struct dwc_otg
if (x == 0)
return (0); /* wait */
+ frame = DWC_OTG_READ_4(sc, DOTG_HFNUM) & HFNUM_FRNUM_MASK;
+
/* find new disabled channel */
for (x = 1; x != sc->sc_host_ch_max; x++) {
@@ -539,6 +542,9 @@ dwc_otg_host_channel_wait(struct dwc_otg
continue;
}
+ if (sc->sc_chan_state[x].last_frame == frame)
+ continue;
+
sc->sc_chan_state[td->channel].allocated = 0;
sc->sc_chan_state[x].allocated = 1;
@@ -577,6 +583,7 @@ static uint8_t
dwc_otg_host_channel_alloc(struct dwc_otg_td *td)
{
struct dwc_otg_softc *sc;
+ uint16_t frame;
uint8_t x;
uint8_t max_channel;
@@ -594,6 +601,8 @@ dwc_otg_host_channel_alloc(struct dwc_ot
x = 1;
}
+ frame = DWC_OTG_READ_4(sc, DOTG_HFNUM) & HFNUM_FRNUM_MASK;
+
for (; x != max_channel; x++) {
uint32_t hcchar;
@@ -608,6 +617,9 @@ dwc_otg_host_channel_alloc(struct dwc_ot
continue;
}
+ if (sc->sc_chan_state[x].last_frame == frame)
+ continue;
+
sc->sc_chan_state[x].allocated = 1;
/* clear interrupts */
@@ -633,8 +645,12 @@ dwc_otg_host_channel_disable(struct dwc_
{
uint32_t hcchar;
hcchar = DWC_OTG_READ_4(sc, DOTG_HCCHAR(x));
- if (hcchar & (HCCHAR_CHENA | HCCHAR_CHDIS))
+ if (hcchar & (HCCHAR_CHENA | HCCHAR_CHDIS)) {
+ /* don't re-use channel until next SOF is transmitted */
+ sc->sc_chan_state[x].last_frame =
+ DWC_OTG_READ_4(sc, DOTG_HFNUM) & HFNUM_FRNUM_MASK;
DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(x), HCCHAR_CHENA | HCCHAR_CHDIS);
+ }
}
static void
Modified: head/sys/dev/usb/controller/dwc_otg.h
==============================================================================
--- head/sys/dev/usb/controller/dwc_otg.h Wed Sep 26 18:11:43 2012 (r240968)
+++ head/sys/dev/usb/controller/dwc_otg.h Wed Sep 26 18:59:20 2012 (r240969)
@@ -140,6 +140,7 @@ struct dwc_otg_profile {
struct dwc_otg_chan_state {
uint32_t hcint;
+ uint16_t last_frame;
uint8_t allocated;
uint8_t suspended;
};
More information about the svn-src-all
mailing list