Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 20 Jan 2012 23:37:05 +0000 (UTC)
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r230405 - head/sys/mips/cavium/usb
Message-ID:  <201201202337.q0KNb5Qg064091@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gonzo
Date: Fri Jan 20 23:37:04 2012
New Revision: 230405
URL: http://svn.freebsd.org/changeset/base/230405

Log:
  We use port_index field of struct octusb_qh to reference USB state
  of root HUB. Although it is initialized with port index of the
  device's parent hub, which is worng. So track the USB tree up to
  root HUB  and initialize this filed ptroprly
  
  Rename port_index to root_port_index in order to reflect its
  real semantics.

Modified:
  head/sys/mips/cavium/usb/octusb.c
  head/sys/mips/cavium/usb/octusb.h

Modified: head/sys/mips/cavium/usb/octusb.c
==============================================================================
--- head/sys/mips/cavium/usb/octusb.c	Fri Jan 20 22:56:57 2012	(r230404)
+++ head/sys/mips/cavium/usb/octusb.c	Fri Jan 20 23:37:04 2012	(r230405)
@@ -159,7 +159,7 @@ octusb_host_alloc_endpoint(struct octusb
 	sc = td->qh->sc;
 
 	ep_handle = cvmx_usb_open_pipe(
-	    &sc->sc_port[td->qh->port_index].state,
+	    &sc->sc_port[td->qh->root_port_index].state,
 	    0,
 	    td->qh->dev_addr,
 	    td->qh->ep_num & UE_ADDR,
@@ -173,11 +173,13 @@ octusb_host_alloc_endpoint(struct octusb
 	    td->qh->hs_hub_addr,
 	    td->qh->hs_hub_port);
 
-	if (ep_handle < 0)
+	if (ep_handle < 0) {
+		DPRINTFN(1, "cvmx_usb_open_pipe failed: %d\n", ep_handle);
 		return (1);		/* busy */
+	}
 
 	cvmx_usb_set_toggle(
-	    &sc->sc_port[td->qh->port_index].state,
+	    &sc->sc_port[td->qh->root_port_index].state,
 	    ep_handle, td->qh->ep_toggle_next);
 
 	td->qh->fixup_handle = -1;
@@ -206,10 +208,10 @@ octusb_host_free_endpoint(struct octusb_
 
 	if (td->qh->fixup_handle >= 0) {
 		/* cancel, if any */
-		cvmx_usb_cancel(&sc->sc_port[td->qh->port_index].state,
+		cvmx_usb_cancel(&sc->sc_port[td->qh->root_port_index].state,
 		    td->qh->ep_handle, td->qh->fixup_handle);
 	}
-	cvmx_usb_close_pipe(&sc->sc_port[td->qh->port_index].state, td->qh->ep_handle);
+	cvmx_usb_close_pipe(&sc->sc_port[td->qh->root_port_index].state, td->qh->ep_handle);
 
 	td->qh->ep_allocated = 0;
 }
@@ -301,7 +303,7 @@ octusb_host_control_header_tx(struct oct
 		usb_pc_cpu_flush(td->qh->fixup_pc);
 
 		status = cvmx_usb_submit_control(
-		    &sc->sc_port[td->qh->port_index].state,
+		    &sc->sc_port[td->qh->root_port_index].state,
 		    td->qh->ep_handle, td->qh->fixup_phys,
 		    td->qh->fixup_phys + 8, td->qh->fixup_len,
 		    &octusb_complete_cb, td);
@@ -410,7 +412,7 @@ octusb_host_control_status_tx(struct oct
 
 		/* start USB transfer */
 		status = cvmx_usb_submit_control(
-		    &sc->sc_port[td->qh->port_index].state,
+		    &sc->sc_port[td->qh->root_port_index].state,
 		    td->qh->ep_handle, td->qh->fixup_phys,
 		    td->qh->fixup_phys + 8, td->qh->fixup_len,
 		    &octusb_complete_cb, td);
@@ -493,19 +495,19 @@ octusb_non_control_data_tx(struct octusb
 		td->qh->iso_pkt.length = rem;
 		td->qh->iso_pkt.status = 0;
 		/* start USB transfer */
-		status = cvmx_usb_submit_isochronous(&sc->sc_port[td->qh->port_index].state,
+		status = cvmx_usb_submit_isochronous(&sc->sc_port[td->qh->root_port_index].state,
 		    td->qh->ep_handle, 1, CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT |
 		    CVMX_USB_ISOCHRONOUS_FLAGS_ASAP, 1, &td->qh->iso_pkt,
 		    td->qh->fixup_phys, rem, &octusb_complete_cb, td);
 		break;
 	case UE_BULK:
 		/* start USB transfer */
-		status = cvmx_usb_submit_bulk(&sc->sc_port[td->qh->port_index].state,
+		status = cvmx_usb_submit_bulk(&sc->sc_port[td->qh->root_port_index].state,
 		    td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td);
 		break;
 	case UE_INTERRUPT:
 		/* start USB transfer (interrupt or interrupt) */
-		status = cvmx_usb_submit_interrupt(&sc->sc_port[td->qh->port_index].state,
+		status = cvmx_usb_submit_interrupt(&sc->sc_port[td->qh->root_port_index].state,
 		    td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td);
 		break;
 	default:
@@ -612,19 +614,19 @@ octusb_non_control_data_rx(struct octusb
 		td->qh->iso_pkt.length = rem;
 		td->qh->iso_pkt.status = 0;
 		/* start USB transfer */
-		status = cvmx_usb_submit_isochronous(&sc->sc_port[td->qh->port_index].state,
+		status = cvmx_usb_submit_isochronous(&sc->sc_port[td->qh->root_port_index].state,
 		    td->qh->ep_handle, 1, CVMX_USB_ISOCHRONOUS_FLAGS_ALLOW_SHORT |
 		    CVMX_USB_ISOCHRONOUS_FLAGS_ASAP, 1, &td->qh->iso_pkt,
 		    td->qh->fixup_phys, rem, &octusb_complete_cb, td);
 		break;
 	case UE_BULK:
 		/* start USB transfer */
-		status = cvmx_usb_submit_bulk(&sc->sc_port[td->qh->port_index].state,
+		status = cvmx_usb_submit_bulk(&sc->sc_port[td->qh->root_port_index].state,
 		    td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td);
 		break;
 	case UE_INTERRUPT:
 		/* start USB transfer */
-		status = cvmx_usb_submit_interrupt(&sc->sc_port[td->qh->port_index].state,
+		status = cvmx_usb_submit_interrupt(&sc->sc_port[td->qh->root_port_index].state,
 		    td->qh->ep_handle, td->qh->fixup_phys, rem, &octusb_complete_cb, td);
 		break;
 	default:
@@ -798,7 +800,7 @@ done:
 
 	xfer->endpoint->toggle_next =
 	    cvmx_usb_get_toggle(
-	    &sc->sc_port[qh->port_index].state,
+	    &sc->sc_port[qh->root_port_index].state,
 	    qh->ep_handle) ? 1 : 0;
 
 	octusb_device_done(xfer, error);
@@ -1729,6 +1731,7 @@ octusb_xfer_setup(struct usb_setup_param
 	struct octusb_softc *sc;
 	struct octusb_qh *qh;
 	struct usb_xfer *xfer;
+	struct usb_device *hub;
 	void *last_obj;
 	uint32_t n;
 	uint32_t ntd;
@@ -1774,7 +1777,13 @@ octusb_xfer_setup(struct usb_setup_param
 		qh->ep_type = xfer->endpoint->edesc->bmAttributes;
 		qh->dev_addr = xfer->address;
 		qh->dev_speed = usbd_get_speed(xfer->xroot->udev);
-		qh->port_index = xfer->xroot->udev->port_index;
+		qh->root_port_index = xfer->xroot->udev->port_index;
+		/* We need Octeon USB HUB's port index, not the local port */
+		hub = xfer->xroot->udev->parent_hub;
+		while(hub && hub->parent_hub) {
+			qh->root_port_index = hub->port_index;
+			hub = hub->parent_hub;
+		}
 
 		switch (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
 		case UE_INTERRUPT:

Modified: head/sys/mips/cavium/usb/octusb.h
==============================================================================
--- head/sys/mips/cavium/usb/octusb.h	Fri Jan 20 22:56:57 2012	(r230404)
+++ head/sys/mips/cavium/usb/octusb.h	Fri Jan 20 23:37:04 2012	(r230405)
@@ -80,7 +80,7 @@ struct octusb_qh {
 	uint8_t	ep_num;
 	uint8_t	ep_type;
 	uint8_t	ep_toggle_next;
-	uint8_t	port_index;
+	uint8_t	root_port_index;
 	uint8_t	fixup_complete;
 	uint8_t	fixup_pending;
 	uint8_t	hs_hub_addr;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201201202337.q0KNb5Qg064091>