[Zrouter-src-freebsd] ZRouter.org: push to FreeBSD HEAD tree
zrouter-src-freebsd at zrouter.org
zrouter-src-freebsd at zrouter.org
Sun Sep 2 20:12:20 UTC 2012
details: http://zrouter.org/hg/FreeBSD/head//rev/e2394547cbfe
changeset: 530:e2394547cbfe
user: Aleksandr Rybalko <ray at ddteam.net>
date: Sat Sep 01 00:32:47 2012 +0300
description:
Save.
diffstat:
head/sys/dev/usb/controller/dotg.c | 162 ++++++++++++++++++---------------
head/sys/dev/usb/controller/dotg.h | 4 +-
head/sys/dev/usb/controller/dotgreg.h | 22 ++--
3 files changed, 102 insertions(+), 86 deletions(-)
diffs (389 lines):
diff -r 96cfccfdf2c4 -r e2394547cbfe head/sys/dev/usb/controller/dotg.c
--- a/head/sys/dev/usb/controller/dotg.c Fri Aug 31 00:26:22 2012 +0300
+++ b/head/sys/dev/usb/controller/dotg.c Sat Sep 01 00:32:47 2012 +0300
@@ -64,6 +64,7 @@
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
+#undef USB_DEBUG
#define USB_DEBUG_VAR dotgdebug
#include <dev/usb/usb_core.h>
@@ -143,23 +144,61 @@
#define WRITE4(sc, offset, val) \
bus_space_write_4(sc->sc_bst, sc->sc_bsh, (offset), (val))
-// bus_space_write_4(sc->sc_bst, sc->sc_bsh, (offset), htole32(val))
#define READ4(sc, offset) \
(bus_space_read_4(sc->sc_bst, sc->sc_bsh, (offset)))
-// le32toh(bus_space_read_4(sc->sc_bst, sc->sc_bsh, (offset)))
-
-//static uint32_t
-//READ4(struct dotg_softc * sc, uint32_t offset)
-//{
-// uint32_t val = le32toh(bus_space_read_4(sc->sc_bst, sc->sc_bsh, (offset)));
-// printf("READ4(sc, 0x%08x, 0x%08x)\n", (offset), (val));
-// return (val);
-//}
+
+
+static inline int
+dotg_allocate_channel(struct dotg_softc *sc)
+{
+ uint32_t old, new;
+ int channel;
+
+ do {
+ cpu_dcache_inv_range((vm_offset_t)sc, sizeof(sc));
+ old = sc->idle_hardware_channels;
+// printf("%s: old=%08x\n", __func__, old);
+ new = 0;
+ for (channel = 0; channel < sc->channels; channel++)
+ if (old & (1 << channel)) {
+ new = old ^ (1 << channel);
+ break;
+ }
+ if (channel == sc->channels) {
+ device_printf(sc->sc_dev, "All channels busy\n");
+ return (-1);
+ }
+ } while (!atomic_cmpset_32(&sc->idle_hardware_channels, old, new));
+// printf("%s: updated=%08x\n", __func__, sc->idle_hardware_channels);
+
+ cpu_dcache_wb_range((vm_offset_t)sc, sizeof(sc));
+
+ return (channel);
+}
+
+static inline void
+dotg_free_channel(struct dotg_softc *sc, int channel)
+{
+ uint32_t old, new;
+
+ do {
+ cpu_dcache_inv_range((vm_offset_t)sc, sizeof(sc));
+ old = sc->idle_hardware_channels;
+// printf("%s: old=%08x\n", __func__, old);
+ if (old & (1 << channel))
+ /* Already idle */
+ return;
+ new = sc->idle_hardware_channels | (1 << channel);
+ } while (!atomic_cmpset_32(&sc->idle_hardware_channels, old, new));
+
+// printf("%s: updated=%08x\n", __func__, sc->idle_hardware_channels);
+ cpu_dcache_wb_range((vm_offset_t)sc, sizeof(sc));
+}
static inline int
needs_split(struct dotg_softc * sc, struct dotg_td *td)
{
- return ((td->qh->dev_speed != USB_SPEED_HIGH) &&
+ return ((td->qh->dev_speed != USB_SPEED_HIGH) &&
(GETFLD(sc->dotg_hprt, HPRT_PRTSPD) == HPRT_PRTSPD_HIGH));
}
@@ -390,6 +429,11 @@
struct dotg_td *td;
hcint = READ4(sc, DOTG_HCINT(channel));
+ WRITE4(sc, DOTG_HCINT(channel), hcint);
+ if (sc->idle_hardware_channels & (1 << channel)) {
+ printf("Channel %d not allocated\n", channel);
+ return (0);
+ }
#ifdef USB_DEBUG
if (hcint & HCINT_AHBERR) {
@@ -398,8 +442,6 @@
}
#endif
- WRITE4(sc, DOTG_HCINT(channel), hcint);
-
hcchar = READ4(sc, DOTG_HCCHAR(channel));
hctsiz = READ4(sc, DOTG_HCTSIZ(channel));
@@ -409,12 +451,12 @@
/* Free channel */
DPRINTF("idle=%02x\n", sc->idle_hardware_channels);
sc->td_for_channel[channel] = 0;
- sc->idle_hardware_channels |= (1<<channel);
+ dotg_free_channel(sc, channel);
DPRINTF("Release hardware channel %d. idle=%02x\n",
channel, sc->idle_hardware_channels);
} else {
/* No transfer for channel */
- DPRINTF("No transfer for channel %d\n", channel);
+ printf("No transfer for channel %d\n", channel);
#ifdef USB_DEBUG
if (dotgdebug) {
dump_channel_regs(sc, channel);
@@ -637,31 +679,26 @@
int channel = -1;
DPRINTF("idle=%02x\n", sc->idle_hardware_channels);
- for (channel = 0; channel < sc->channels; channel ++ ) {
- if (sc->idle_hardware_channels & (1<<channel)) {
- sc->td_for_channel[channel] = td;
- sc->idle_hardware_channels &= ~(1<<channel);
- td->channel = channel;
- DPRINTF("Allocate hardware channel %d. idle=%02x\n",
- channel, sc->idle_hardware_channels);
- break;
- }
- }
- if (channel < 0 || channel > 3) {
+ channel = dotg_allocate_channel(sc);
+ if (channel < 0)
+ return (EIO);
+
+ sc->td_for_channel[channel] = td;
+ td->channel = channel;
+
+ DPRINTF("Allocate hardware channel %d. idle=%02x\n",
+ channel, sc->idle_hardware_channels);
+
+ if (channel < 0 || channel > sc->channels) {
device_printf(sc->sc_dev, "Wrong allocated channel=%d\n", channel);
return (EIO);
}
- if (READ4(sc, DOTG_HCCHAR(td->channel)) & HCCHAR_CHENA) {
- device_printf(sc->sc_dev, "ERROR: channel %d already enabled\n", channel);
- return (EIO);
- }
-
- //SETFIELD32(sc, DOTG_GINTMSK, GINTMSK_SOFMSK, 1);
+ /* Force clear channel */
+ SETFIELD32(sc, DOTG_HCCHAR(td->channel), HCCHAR_CHENA, 0);
hcint = READ4(sc, DOTG_HCINT(td->channel));
WRITE4(sc, DOTG_HCINT(td->channel), hcint);
-// WRITE4(sc, DOTG_HCINTMSK(td->channel), HCINTMSK_ANY);
td->qh->this_xfersize = xfersize;
@@ -693,12 +730,17 @@
hcchar |= SETFLD(td->qh->ep_num & 0x0f, HCCHAR_EPNUM);
hcchar |= SETFLD(td->qh->max_packet_size, HCCHAR_MPS);
+ if (needs_split(sc, td)) {
+ hcsplt |= HCSPLT_SPLTENA;// | HCSPLT_COMPSPLT;
+ hcsplt |= SETFLD(td->qh->hs_hub_port, HCSPLT_PRTADDR);
+ hcsplt |= SETFLD(td->qh->hs_hub_addr, HCSPLT_HUBADDR);
+ hcsplt |= SETFLD(3, HCSPLT_XACTPOS);
+ }
+
WRITEDMA(sc, td->channel,
(unsigned int *)(td->qh->fixup_phys + td->qh->fixup_off));
WRITE4(sc, DOTG_HAINTMSK,
(READ4(sc, DOTG_HAINTMSK) | (1<<td->channel)));
- WRITE4(sc, DOTG_HCINTMSK(td->channel),
- HCINTMSK_CHHLTDMSK|HCINTMSK_AHBERRMSK);
WRITE4(sc, DOTG_HCINTMSK(td->channel), HCINTMSK_ANY);
WRITE4(sc, DOTG_HCSPLT(td->channel), hcsplt);
WRITE4(sc, DOTG_HCTSIZ(td->channel), hctsiz);
@@ -757,14 +799,6 @@
/* get softc */
sc = td->qh->sc;
-//#ifdef USB_DEBUG
-// if (dotgdebug) {
-// DPRINTF("\n");
-// hexdump((uint8_t *)MIPS_PHYS_TO_KSEG1(td->qh->fixup_phys),
-// 8, 0, 0);
-// }
-//#endif
-
int ret = configure_channel(td, 8, HCTSIZ_PID_SETUP, HCCHAR_EPDIR_OUT);
if (ret != 0)
return (1);
@@ -953,17 +987,14 @@
goto dotg_non_control_data_tx_retry;
}
-
/* allocate endpoint and check pending */
if (dotg_host_alloc_endpoint(td))
return (1); /* busy */
-
/* check error */
if (td->error_any)
return (0); /* done */
-
DPRINTF("td->qh->fixup_state = %d, td->short_pkt=%d, td->qh->dev_speed=%d == %d\n",td->qh->fixup_state, td->short_pkt, td->qh->dev_speed, USB_SPEED_HIGH);
if (td->qh->fixup_state == FIXUP_CMPL) {
if ((td->qh->ep_type & UE_XFERTYPE) == UE_ISOCHRONOUS) {
@@ -1035,9 +1066,6 @@
/*---------------------------------------------------------------*/
DPRINTF("+++++++++++++++++ rem=%d\n", rem);
-//#ifdef USB_DEBUG
-// if (dotgdebug == 0x0fffffff) hexdump((uint8_t *)MIPS_PHYS_TO_KSEG1(td->qh->fixup_phys), rem, 0, 0);
-//#endif
DPRINTF("\n");
int ret = configure_channel(td, rem, td->qh->ep_toggle_next?HCTSIZ_PID_DATA1:HCTSIZ_PID_DATA0, HCCHAR_EPDIR_OUT);
@@ -1100,12 +1128,6 @@
/* invalidate data */
usb_pc_cpu_invalidate(td->qh->fixup_pc);
- DPRINTF("\n");
-//#ifdef USB_DEBUG
-// if (dotgdebug == 0x0fffffff) hexdump((uint8_t *)MIPS_PHYS_TO_KSEG1(td->qh->fixup_phys), td->qh->fixup_actlen, 0, 0);
-//#endif
- DPRINTF("\n");
-
/* verify transfer length */
if (td->qh->this_xfersize != td->qh->fixup_actlen) {
if (td->qh->this_xfersize > td->qh->fixup_actlen) {
@@ -1346,7 +1368,11 @@
dotg_interrupt_poll(struct dotg_softc *sc)
{
struct usb_xfer *xfer;
- uint32_t gintsts = READ4(sc, DOTG_GINTSTS);
+ uint32_t gintsts;
+
+ cpu_dcache_inv_range((vm_offset_t)sc, sizeof(sc));
+
+ gintsts = READ4(sc, DOTG_GINTSTS);
WRITE4(sc, DOTG_GINTSTS, gintsts);
if ((gintsts & GINTSTS_PRTINT) || (gintsts & GINTSTS_DISCONNINT)) {
@@ -1367,11 +1393,10 @@
uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata, sizeof(sc->sc_hub_idata));
}
-
- {
+ /* if (gintsts & GINTSTS_HCHINT) */ {
uint32_t haint = READ4(sc, DOTG_HAINT);
WRITE4(sc, DOTG_HAINT, haint);
- haint &= ((1 << sc->channels) - 1);
+ haint &= ((1<<sc->channels) - 1);
while (haint) {
int channel;
for (channel = 0; channel < sc->channels; channel ++)
@@ -1382,9 +1407,6 @@
}
}
-
-// WRITE4(sc, DOTG_GINTSTS, gintsts);
-
repeat:
TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
if (!dotg_xfer_do_fifo(xfer)) {
@@ -1423,8 +1445,6 @@
}
-
-
usb_error_t
dotg_init(struct dotg_softc *sc)
{
@@ -2426,10 +2446,9 @@
return;
/* Allocate a queue head */
-
if (usbd_transfer_setup_sub_malloc(
parm, &pc, sizeof(struct dotg_qh),
- USB_HOST_ALIGN*4, 1)) { //XXX
+ USB_HOST_ALIGN, 1)) {
parm->err = USB_ERR_NOMEM;
return;
}
@@ -2439,7 +2458,6 @@
qh = page_info.buffer;
/* fill out QH */
-
qh->sc = DOTG_BUS2SC(xfer->xroot->bus);
qh->max_frame_size = xfer->max_frame_size;
qh->max_packet_size = xfer->max_packet_size;
@@ -2448,6 +2466,9 @@
qh->dev_addr = xfer->address;
qh->dev_speed = usbd_get_speed(xfer->xroot->udev);
qh->port_index = xfer->xroot->udev->port_index;
+ qh->ep_mult = xfer->max_packet_count & 3;
+ qh->hs_hub_addr = xfer->xroot->udev->hs_hub_addr;
+ qh->hs_hub_port = xfer->xroot->udev->hs_port_no;
switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
case UE_INTERRUPT:
@@ -2463,15 +2484,10 @@
qh->ep_interval = 0;
break;
}
-
- qh->ep_mult = xfer->max_packet_count & 3;
- qh->hs_hub_addr = xfer->xroot->udev->hs_hub_addr;
- qh->hs_hub_port = xfer->xroot->udev->hs_port_no;
}
xfer->qh_start[0] = qh;
/* Allocate a fixup buffer */
-
if (usbd_transfer_setup_sub_malloc(
parm, &pc, DOTG_MAX_FIXUP,
DOTG_MAX_FIXUP, 1)) {
@@ -2486,9 +2502,7 @@
qh->fixup_buf = page_info.buffer;
}
/* Allocate transfer descriptors */
-
last_obj = NULL;
-
ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ;
if (usbd_transfer_setup_sub_malloc(
diff -r 96cfccfdf2c4 -r e2394547cbfe head/sys/dev/usb/controller/dotg.h
--- a/head/sys/dev/usb/controller/dotg.h Fri Aug 31 00:26:22 2012 +0300
+++ b/head/sys/dev/usb/controller/dotg.h Sat Sep 01 00:32:47 2012 +0300
@@ -40,7 +40,9 @@
#endif
#if 1
-#define DOTG_MAX_FIXUP 4096 /* bytes */
+//#define DOTG_MAX_FIXUP 0x2000 /* bytes */
+#define DOTG_MAX_FIXUP 0x1000 /* bytes */
+//#define DOTG_MAX_FIXUP 4096 /* bytes */
#else
#define DOTG_MAX_FIXUP 2048 /* bytes */
#endif
diff -r 96cfccfdf2c4 -r e2394547cbfe head/sys/dev/usb/controller/dotgreg.h
--- a/head/sys/dev/usb/controller/dotgreg.h Fri Aug 31 00:26:22 2012 +0300
+++ b/head/sys/dev/usb/controller/dotgreg.h Sat Sep 01 00:32:47 2012 +0300
@@ -479,17 +479,17 @@
#define HCINTMSK_AHBERRMSK (1<<2)
#define HCINTMSK_CHHLTDMSK (1<<1)
#define HCINTMSK_XFERCOMPLMSK (1<<0)
-#define HCINTMSK_ANY (HCINTMSK_DATATGLERRMSK | \
- HCINTMSK_FRMOVRUNMSK | \
- HCINTMSK_BBLERRMSK | \
- HCINTMSK_XACTERRMSK | \
- HCINTMSK_NYETMSK | \
- HCINTMSK_ACKMSK | \
- HCINTMSK_NAKMSK | \
- HCINTMSK_STALLMSK | \
- HCINTMSK_AHBERRMSK | \
- HCINTMSK_CHHLTDMSK | \
- HCINTMSK_XFERCOMPLMSK)
+#define HCINTMSK_ANY (HCINTMSK_DATATGLERRMSK | \
+ HCINTMSK_FRMOVRUNMSK | \
+ HCINTMSK_BBLERRMSK | \
+ HCINTMSK_XACTERRMSK | \
+ HCINTMSK_NYETMSK | \
+ HCINTMSK_ACKMSK | \
+ HCINTMSK_NAKMSK | \
+ HCINTMSK_STALLMSK | \
+ HCINTMSK_AHBERRMSK | \
+ HCINTMSK_CHHLTDMSK | \
+ HCINTMSK_XFERCOMPLMSK)
#define HCTSIZ_DOPNG (1<<31)
#define HCTSIZ_PID_SHIFT 29
More information about the Zrouter-src-freebsd
mailing list