[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