Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 14 Dec 2008 14:32:57 -0700 (MST)
From:      "M. Warner Losh" <imp@bsdimp.com>
To:        sam@freebsd.org
Cc:        perforce@freebsd.org
Subject:   Re: PERFORCE change 154450 for review
Message-ID:  <20081214.143257.1645216129.imp@bsdimp.com>
In-Reply-To: <200812101754.mBAHsoEI024577@repoman.freebsd.org>
References:  <200812101754.mBAHsoEI024577@repoman.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
In message: <200812101754.mBAHsoEI024577@repoman.freebsd.org>
            Sam Leffler <sam@freebsd.org> writes:
: http://perforce.freebsd.org/chv.cgi?CH=154450
: 
: Change 154450 by sam@sam_ebb on 2008/12/10 17:53:56
: 
: 	Remove EHCI_SCFLG_BIGENDIAN; this appears to be the wrong
: 	approach.  Handle the 1- and 2-byte register ops by overriding
: 	the bus tag ops in the bus-shim.  Also mark the controller with
: 	EHCI_SCFLG_FORCESPEED as we need to identify the device speed
: 	from the PortStatus following a port enable.

FYI: On the Alchemy USB device, one has to always to 4-byte operations
on the hardware for a similar flag to be effective.  Thanks for
stubbing your toe on this limitation in our stack so I won't have to
stub mine nearly as badly...

Warner

: Affected files ...
: 
: .. //depot/projects/vap/sys/arm/xscale/ixp425/ixp435_ehci.c#2 edit
: .. //depot/projects/vap/sys/dev/usb/ehci.c#16 edit
: .. //depot/projects/vap/sys/dev/usb/ehcivar.h#10 edit
: 
: Differences ...
: 
: ==== //depot/projects/vap/sys/arm/xscale/ixp425/ixp435_ehci.c#2 (text+ko) ====
: 
: @@ -38,10 +38,12 @@
:  #include <sys/lock.h>
:  #include <sys/mutex.h>
:  #include <sys/bus.h>
: +#include <sys/endian.h>
:  #include <sys/queue.h>
:  #include <sys/lockmgr.h>
: +#include <sys/rman.h>
: +
:  #include <machine/bus.h>
: -#include <sys/rman.h>
:  #include <machine/resource.h>
:  
:  #include <dev/usb/usb.h>
: @@ -58,11 +60,21 @@
:  #define EHCI_VENDORID_IXP4XX	0x42fa05
:  #define EHCI_HC_DEVSTR		"IXP4XX Integrated USB 2.0 controller"
:  
: -static device_attach_t ehci_ixp_attach;
: -static device_detach_t ehci_ixp_detach;
: -static device_shutdown_t ehci_ixp_shutdown;
: -static device_suspend_t ehci_ixp_suspend;
: -static device_resume_t ehci_ixp_resume;
: +struct ixp_ehci_softc {
: +	ehci_softc_t		base;	/* storage for EHCI code */
: +	bus_space_tag_t		iot;
: +	bus_space_handle_t	ioh;
: +	struct bus_space	tag;	/* tag for private bus space ops */
: +};
: +
: +static int ehci_ixp_detach(device_t self);
: +
: +static uint8_t ehci_bs_r_1(void *, bus_space_handle_t, bus_size_t);
: +static void ehci_bs_w_1(void *, bus_space_handle_t, bus_size_t, u_int8_t);
: +static uint16_t ehci_bs_r_2(void *, bus_space_handle_t, bus_size_t);
: +static void ehci_bs_w_2(void *, bus_space_handle_t, bus_size_t, uint16_t);
: +static uint32_t ehci_bs_r_4(void *, bus_space_handle_t, bus_size_t);
: +static void ehci_bs_w_4(void *, bus_space_handle_t, bus_size_t, uint32_t);
:  
:  static int
:  ehci_ixp_suspend(device_t self)
: @@ -112,7 +124,8 @@
:  static int
:  ehci_ixp_attach(device_t self)
:  {
: -	ehci_softc_t *sc = device_get_softc(self);
: +	struct ixp_ehci_softc *isc = device_get_softc(self);
: +	ehci_softc_t *sc = &isc->base;
:  	int err, rid;
:  
:  	sc->sc_bus.usbrev = USBREV_2_0;
: @@ -126,16 +139,27 @@
:  		device_printf(self, "Could not map memory\n");
:  		return ENXIO;
:  	}
: -	sc->iot = rman_get_bustag(sc->io_res);
: +
: +	/*
: +	 * Craft special resource for bus space ops that handle
: +	 * byte-alignment of non-word addresses.  Also, since
: +	 * we're already intercepting bus space ops we handle
: +	 * the register window offset that could otherwise be
: +	 * done with bus_space_subregion.
: +	 */
: +	isc->iot = rman_get_bustag(sc->io_res);
: +	isc->tag.bs_cookie = isc->iot;
: +	/* read single */
: +	isc->tag.bs_r_1	= ehci_bs_r_1,
: +	isc->tag.bs_r_2	= ehci_bs_r_2,
: +	isc->tag.bs_r_4	= ehci_bs_r_4,
: +	/* write (single) */
: +	isc->tag.bs_w_1	= ehci_bs_w_1,
: +	isc->tag.bs_w_2	= ehci_bs_w_2,
: +	isc->tag.bs_w_4	= ehci_bs_w_4,
: +
: +	sc->iot = &isc->tag;
:  	sc->ioh = rman_get_bushandle(sc->io_res);
: -
: -	/* shift register window for EHCI driver */
: -	if (bus_space_subregion(sc->iot, sc->ioh,
: -	    0x100, IXP435_USB1_SIZE - 0x100, &sc->ioh) != 0) {
: -		device_printf(self, "Could not setup subregion for USB host"
: -		     "registers\n");
: -		return ENXIO;
: -	}
:  	sc->sc_size = IXP435_USB1_SIZE - 0x100;
:  
:  	rid = 0;
: @@ -197,10 +221,13 @@
:  	 * Arrange to force Host mode, select big-endian byte alignment,
:  	 * and arrange to not terminate reset operations (the adapter
:  	 * will ignore it if we do but might as well save a reg write).
: +	 * Also, the controller has an embedded Transaction Translator
: +	 * which means port speed must be read from the Port Status
: +	 * register following a port enable.
:  	 */
:  	sc->sc_flags |= EHCI_SCFLG_SETMODE
: -		     | EHCI_SCFLG_BIGENDIAN
:  		     | EHCI_SCFLG_NORESTERM
: +		     | EHCI_SCFLG_FORCESPEED
:  		     ;
:  	err = ehci_init(sc);
:  	if (!err) {
: @@ -219,7 +246,8 @@
:  static int
:  ehci_ixp_detach(device_t self)
:  {
: -	ehci_softc_t *sc = device_get_softc(self);
: +	struct ixp_ehci_softc *isc = device_get_softc(self);
: +	ehci_softc_t *sc = &isc->base;
:  	int err;
:  
:  	if (sc->sc_flags & EHCI_SCFLG_DONEINIT) {
: @@ -262,6 +290,48 @@
:  	return 0;
:  }
:  
: +/*
: + * Bus space accessors for PIO operations.
: + */
: +
: +static uint8_t
: +ehci_bs_r_1(void *t, bus_space_handle_t h, bus_size_t o)
: +{
: +	return bus_space_read_1((bus_space_tag_t) t, h,
: +	    0x100 + (o &~ 3) + (3 - (o & 3)));
: +}
: +
: +static void
: +ehci_bs_w_1(void *t, bus_space_handle_t h, bus_size_t o, u_int8_t v)
: +{
: +	panic("%s", __func__);
: +}
: +
: +static uint16_t
: +ehci_bs_r_2(void *t, bus_space_handle_t h, bus_size_t o)
: +{
: +	return bus_space_read_2((bus_space_tag_t) t, h,
: +	    0x100 + (o &~ 3) + (2 - (o & 3)));
: +}
: +
: +static void
: +ehci_bs_w_2(void *t, bus_space_handle_t h, bus_size_t o, uint16_t v)
: +{
: +	panic("%s", __func__);
: +}
: +
: +static uint32_t
: +ehci_bs_r_4(void *t, bus_space_handle_t h, bus_size_t o)
: +{
: +	return bus_space_read_4((bus_space_tag_t) t, h, 0x100 + o);
: +}
: +
: +static void
: +ehci_bs_w_4(void *t, bus_space_handle_t h, bus_size_t o, uint32_t v)
: +{
: +	bus_space_write_4((bus_space_tag_t) t, h, 0x100 + o, v);
: +}
: +
:  static device_method_t ehci_methods[] = {
:  	/* Device interface */
:  	DEVMETHOD(device_probe, ehci_ixp_probe),
: @@ -280,7 +350,7 @@
:  static driver_t ehci_driver = {
:  	"ehci",
:  	ehci_methods,
: -	sizeof(ehci_softc_t),
: +	sizeof(struct ixp_ehci_softc),
:  };
:  static devclass_t ehci_devclass;
:  DRIVER_MODULE(ehci, ixp, ehci_driver, ehci_devclass, 0, 0);
: 
: ==== //depot/projects/vap/sys/dev/usb/ehci.c#16 (text+ko) ====
: 
: @@ -351,12 +351,10 @@
:  		usb_delay_ms(&sc->sc_bus, 1);
:  		hcr = EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET;
:  		if (!hcr) {
: -			if (sc->sc_flags & (EHCI_SCFLG_SETMODE | EHCI_SCFLG_BIGENDIAN)) {
: +			if (sc->sc_flags & EHCI_SCFLG_SETMODE) {
:  				/*
:  				 * Force USBMODE as requested.  Controllers
: -				 * may have multiple operating modes and on
: -				 * some platforms we need to force big-endian
: -				 * byte alignement of data structures.
: +				 * may have multiple operating modes.
:  				 */
:  				uint32_t usbmode = EOREAD4(sc, EHCI_USBMODE);
:  				if (sc->sc_flags & EHCI_SCFLG_SETMODE) {
: @@ -364,11 +362,6 @@
:  					device_printf(sc->sc_bus.bdev,
:  					    "set host controller mode\n");
:  				}
: -				if (sc->sc_flags & EHCI_SCFLG_BIGENDIAN) {
: -					usbmode |= EHCI_UM_ES_BE;
: -					device_printf(sc->sc_bus.bdev,
: -					    "set big-endian byte alignment\n");
: -				}
:  				EOWRITE4(sc,  EHCI_USBMODE, usbmode);
:  			}
:  			return (USBD_NORMAL_COMPLETION);
: @@ -395,11 +388,9 @@
:  
:  	/* NB: must handle byte-order manually before ehci_hcreset */
:  
: -	sc->sc_offs = EREAD1(sc, sc->sc_flags & EHCI_SCFLG_BIGENDIAN ?
: -	    3-EHCI_CAPLENGTH : EHCI_CAPLENGTH);
: +	sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
:  
: -	version = EREAD2(sc, sc->sc_flags & EHCI_SCFLG_BIGENDIAN ?
: -	    2-EHCI_HCIVERSION : EHCI_HCIVERSION);
: +	version = EREAD2(sc, EHCI_HCIVERSION);
:  	device_printf(sc->sc_bus.bdev, "EHCI version %x.%x\n",
:  	       version >> 8, version & 0xff);
:  
: 
: ==== //depot/projects/vap/sys/dev/usb/ehcivar.h#10 (text+ko) ====
: 
: @@ -125,7 +125,6 @@
:  #define EHCI_SCFLG_SETMODE	0x0004	/* set bridge mode again after init (Marvell) */
:  #define EHCI_SCFLG_FORCESPEED	0x0008	/* force speed (Marvell) */
:  #define EHCI_SCFLG_NORESTERM	0x0010	/* don't terminate reset sequence (Marvell) */
: -#define EHCI_SCFLG_BIGENDIAN	0x0020	/* set big-endian select on reset */
:  
:  typedef struct ehci_softc {
:  	struct usbd_bus sc_bus;		/* base device */
: 



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