Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 May 2014 10:01:19 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r266741 - head/sys/dev/usb/controller
Message-ID:  <201405271001.s4RA1JjQ017311@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Tue May 27 10:01:19 2014
New Revision: 266741
URL: http://svnweb.freebsd.org/changeset/base/266741

Log:
  Multiple fixes and improvements:
  - Put "_LE_" into the register access macros to indicate little endian
  byte order is expected by the hardware.
  - Avoid using the bounce buffer when not strictly needed. Try to move
  data directly using bus-space functions first.
  - Ensure we preserve the reserved bits in the power down mode
  register. Else the hardware goes into a non-recoverable state.
  - Always use 32-bit access when writing or reading registers or FIFOs,
  because the hardware is 32-bit oriented and don't really understand 8-
  and 16-bit access.
  - Correct writes to the memory address register. There is no need to
  shift the register offset.
  - Correct interval for interrupt endpoints.
  - Optimise 90ns internal memory buffer read delay.
  - Rename PDT into PTD, which is how the datasheet writes it.
  - Add missing programming for activating host controller PTDs.
  
  Sponsored by:	DARPA, AFRL

Modified:
  head/sys/dev/usb/controller/saf1761_otg.c
  head/sys/dev/usb/controller/saf1761_otg.h
  head/sys/dev/usb/controller/saf1761_otg_reg.h

Modified: head/sys/dev/usb/controller/saf1761_otg.c
==============================================================================
--- head/sys/dev/usb/controller/saf1761_otg.c	Tue May 27 09:42:07 2014	(r266740)
+++ head/sys/dev/usb/controller/saf1761_otg.c	Tue May 27 10:01:19 2014	(r266741)
@@ -195,9 +195,9 @@ saf1761_otg_wakeup_peer(struct saf1761_o
 
 	DPRINTFN(5, "\n");
 
-	temp = SAF1761_READ_2(sc, SOTG_MODE);
-	SAF1761_WRITE_2(sc, SOTG_MODE, temp | SOTG_MODE_SNDRSU);
-	SAF1761_WRITE_2(sc, SOTG_MODE, temp & ~SOTG_MODE_SNDRSU);
+	temp = SAF1761_READ_LE_4(sc, SOTG_MODE);
+	SAF1761_WRITE_LE_4(sc, SOTG_MODE, temp | SOTG_MODE_SNDRSU);
+	SAF1761_WRITE_LE_4(sc, SOTG_MODE, temp & ~SOTG_MODE_SNDRSU);
 
 	/* Wait 8ms for remote wakeup to complete. */
 	usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 125);
@@ -253,8 +253,8 @@ saf1761_host_channel_free(struct saf1761
 		return;
 
 	/* disable channel */
-	SAF1761_WRITE_4(sc, SOTG_PDT(td->channel) + SOTG_PDT_DW3, 0);
-	SAF1761_WRITE_4(sc, SOTG_PDT(td->channel) + SOTG_PDT_DW0, 0);
+	SAF1761_WRITE_LE_4(sc, SOTG_PTD(td->channel) + SOTG_PTD_DW3, 0);
+	SAF1761_WRITE_LE_4(sc, SOTG_PTD(td->channel) + SOTG_PTD_DW0, 0);
 
 	switch (td->ep_type) {
 	case UE_INTERRUPT:
@@ -275,49 +275,143 @@ saf1761_host_channel_free(struct saf1761
 	}
 }
 
+static uint32_t
+saf1761_peek_host_memory_le_4(struct saf1761_otg_softc *sc, uint32_t offset)
+{
+	SAF1761_WRITE_LE_4(sc, SOTG_MEMORY_REG, offset);
+	SAF1761_90NS_DELAY(sc);	/* read prefetch time is 90ns */
+	return (SAF1761_READ_LE_4(sc, offset));
+}
+
 static void
-saf1761_read_host_memory_4(struct saf1761_otg_softc *sc, uint32_t offset,
-    void *buf, uint32_t count)
+saf1761_read_host_memory(struct saf1761_otg_softc *sc,
+    struct saf1761_otg_td *td, uint32_t len)
 {
-	if (count == 0)
+	struct usb_page_search buf_res;
+	uint32_t offset;
+	uint32_t count;
+
+	if (len == 0)
 		return;
-	SAF1761_WRITE_4(sc, SOTG_MEMORY_REG, SOTG_HC_MEMORY_ADDR(offset));
-	DELAY(1);	/* read prefetch time is 90ns */
-	bus_space_read_region_4((sc)->sc_io_tag, (sc)->sc_io_hdl, offset, buf, count);
+
+	offset = SOTG_DATA_ADDR(td->channel);
+	SAF1761_WRITE_LE_4(sc, SOTG_MEMORY_REG, offset);
+	SAF1761_90NS_DELAY(sc);	/* read prefetch time is 90ns */
+
+	/* optimised read first */
+	while (len > 0) {
+		usbd_get_page(td->pc, td->offset, &buf_res);
+
+		/* get correct length */
+		if (buf_res.length > len)
+			buf_res.length = len;
+
+		/* check buffer alignment */
+		if (((uintptr_t)buf_res.buffer) & 3)
+			break;
+
+		count = buf_res.length & ~3;
+		if (count == 0)
+			break;
+
+		bus_space_read_region_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
+		    offset, buf_res.buffer, count / 4);
+
+		len -= count;
+		offset += count;
+
+		/* update remainder and offset */
+		td->remainder -= count;
+		td->offset += count;
+	}
+
+	if (len > 0) {
+		/* use bounce buffer */
+		bus_space_read_region_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
+		    offset, sc->sc_bounce_buffer, (len + 3) / 4);
+		usbd_copy_in(td->pc, td->offset,
+		    sc->sc_bounce_buffer, len);
+
+		/* update remainder and offset */
+		td->remainder -= len;
+		td->offset += len;
+	}
 }
 
 static void
-saf1761_write_host_memory_4(struct saf1761_otg_softc *sc, uint32_t offset,
-    void *buf, uint32_t count)
+saf1761_write_host_memory(struct saf1761_otg_softc *sc,
+    struct saf1761_otg_td *td, uint32_t len)
 {
-	if (count == 0)
+	struct usb_page_search buf_res;
+	uint32_t offset;
+	uint32_t count;
+
+	if (len == 0)
 		return;
-	bus_space_write_region_4((sc)->sc_io_tag, (sc)->sc_io_hdl, offset, buf, count);
+
+	offset = SOTG_DATA_ADDR(td->channel);
+
+	/* optimised write first */
+	while (len > 0) {
+		usbd_get_page(td->pc, td->offset, &buf_res);
+
+		/* get correct length */
+		if (buf_res.length > len)
+			buf_res.length = len;
+
+		/* check buffer alignment */
+		if (((uintptr_t)buf_res.buffer) & 3)
+			break;
+
+		count = buf_res.length & ~3;
+		if (count == 0)
+			break;
+
+		bus_space_write_region_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
+		    offset, buf_res.buffer, count / 4);
+
+		len -= count;
+		offset += count;
+
+		/* update remainder and offset */
+		td->remainder -= count;
+		td->offset += count;
+	}
+	if (len > 0) {
+		/* use bounce buffer */
+		usbd_copy_out(td->pc, td->offset, sc->sc_bounce_buffer, len);
+		bus_space_write_region_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
+		    offset, sc->sc_bounce_buffer, (len + 3) / 4);
+
+		/* update remainder and offset */
+		td->remainder -= len;
+		td->offset += len;
+	}
 }
 
 static uint8_t
 saf1761_host_setup_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
 {
-	struct usb_device_request req __aligned(4);
 	uint32_t pdt_addr;
 	uint32_t status;
 	uint32_t count;
 	uint32_t temp;
 
 	if (td->channel < SOTG_HOST_CHANNEL_MAX) {
-		pdt_addr = SOTG_PDT(td->channel);
+		pdt_addr = SOTG_PTD(td->channel);
 
-		saf1761_read_host_memory_4(sc, pdt_addr + SOTG_PDT_DW3, &status, 1);
+		status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
+		DPRINTFN(5, "STATUS=0x%08x\n", status);
 
-		if (status & SOTG_PDT_DW3_ACTIVE) {
+		if (status & SOTG_PTD_DW3_ACTIVE) {
 			goto busy;
-		} else if (status & SOTG_PDT_DW3_HALTED) {
+		} else if (status & SOTG_PTD_DW3_HALTED) {
 			td->error_stall = 1;
 			td->error_any = 1;
-		} else if (status & SOTG_PDT_DW3_ERRORS) {
+		} else if (status & SOTG_PTD_DW3_ERRORS) {
 			td->error_any = 1;
 		}
-		count = (status & SOTG_PDT_DW3_XFER_COUNT);
+		count = (status & SOTG_PTD_DW3_XFER_COUNT);
 
 		saf1761_host_channel_free(sc, td);
 		goto complete;
@@ -325,42 +419,37 @@ saf1761_host_setup_tx(struct saf1761_otg
 	if (saf1761_host_channel_alloc(sc, td))
 		goto busy;
 
-	if (sizeof(req) != td->remainder) {
+	count = 8;
+
+	if (count != td->remainder) {
 		td->error_any = 1;
 		goto complete;
 	}
 
-	count = sizeof(req);
-
-	usbd_copy_out(td->pc, 0, &req, count);
+	saf1761_write_host_memory(sc, td, count);
 
-	saf1761_write_host_memory_4(sc, SOTG_DATA_ADDR(td->channel),
-	    &req, (count + 3) / 4);
+	pdt_addr = SOTG_PTD(td->channel);
 
-	pdt_addr = SOTG_PDT(td->channel);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW7, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW6, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, 0);
 
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW7, 0);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW6, 0);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW5, 0);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW4, 0);
-
-	temp = SOTG_PDT_DW3_ACTIVE | (td->toggle << 25) | SOTG_PDT_DW3_CERR;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW3, temp);
+	temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR;
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
 	    
 	temp = SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW2, temp);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW2, temp);
 
 	temp = td->dw1_value | (2 << 10) /* SETUP PID */ | (td->ep_index >> 1);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW1, temp);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW1, temp);
 
 	temp = (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ |
 	    (td->max_packet_size << 18) /* wMaxPacketSize */ |
 	    (count << 3) /* transfer count */ |
-	    SOTG_PDT_DW0_VALID;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW0, temp);
+	    SOTG_PTD_DW0_VALID;
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
 
-	td->offset += count;
-	td->remainder -= count;
 	td->toggle = 1;
 busy:
 	return (1);	/* busy */
@@ -379,21 +468,22 @@ saf1761_host_bulk_data_rx(struct saf1761
 		uint32_t count;
 		uint8_t got_short;
 
-		pdt_addr = SOTG_PDT(td->channel);
+		pdt_addr = SOTG_PTD(td->channel);
 
-		saf1761_read_host_memory_4(sc, pdt_addr + SOTG_PDT_DW3, &status, 1);
+		status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
+		DPRINTFN(5, "STATUS=0x%08x\n", status);
 
-		if (status & SOTG_PDT_DW3_ACTIVE) {
+		if (status & SOTG_PTD_DW3_ACTIVE) {
 			goto busy;
-		} else if (status & SOTG_PDT_DW3_HALTED) {
+		} else if (status & SOTG_PTD_DW3_HALTED) {
 			td->error_stall = 1;
 			td->error_any = 1;
 			goto complete;
-		} else if (status & SOTG_PDT_DW3_ERRORS) {
+		} else if (status & SOTG_PTD_DW3_ERRORS) {
 			td->error_any = 1;
 			goto complete;
 		}
-		count = (status & SOTG_PDT_DW3_XFER_COUNT);
+		count = (status & SOTG_PTD_DW3_XFER_COUNT);
 		got_short = 0;
 
 		/* verify the packet byte count */
@@ -417,14 +507,7 @@ saf1761_host_bulk_data_rx(struct saf1761
 			goto complete;
 		}
 
-		saf1761_read_host_memory_4(sc, SOTG_DATA_ADDR(td->channel),
-		    sc->sc_bounce_buffer, (count + 3) / 4);
-
-		usbd_copy_in(td->pc, td->offset,
-		    sc->sc_bounce_buffer, count);
-
-		td->remainder -= count;
-		td->offset += count;
+		saf1761_read_host_memory(sc, td, count);
 
 		saf1761_host_channel_free(sc, td);
 
@@ -446,27 +529,27 @@ saf1761_host_bulk_data_rx(struct saf1761
 
 	/* receive one more packet */
 
-	pdt_addr = SOTG_PDT(td->channel);
+	pdt_addr = SOTG_PTD(td->channel);
 
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW7, 0);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW6, 0);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW5, 0);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW4, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW7, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW6, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, 0);
 
-	temp = SOTG_PDT_DW3_ACTIVE | (td->toggle << 25) | SOTG_PDT_DW3_CERR;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW3, temp);
+	temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR;
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
 
 	temp = SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW2, temp);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW2, temp);
 
 	temp = td->dw1_value | (1 << 10) /* IN-PID */ | (td->ep_index >> 1);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW1, temp);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW1, temp);
 
 	temp = (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ |
 	    (td->max_packet_size << 18) /* wMaxPacketSize */ |
 	    (td->max_packet_size << 3) /* transfer count */ |
-	    SOTG_PDT_DW0_VALID;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW0, temp);
+	    SOTG_PTD_DW0_VALID;
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
 busy:
 	return (1);	/* busy */
 complete:
@@ -483,16 +566,17 @@ saf1761_host_bulk_data_tx(struct saf1761
 	if (td->channel < SOTG_HOST_CHANNEL_MAX) {
 		uint32_t status;
 
-		pdt_addr = SOTG_PDT(td->channel);
+		pdt_addr = SOTG_PTD(td->channel);
 
-		saf1761_read_host_memory_4(sc, pdt_addr + SOTG_PDT_DW3, &status, 1);
+		status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
+		DPRINTFN(5, "STATUS=0x%08x\n", status);
 
-		if (status & SOTG_PDT_DW3_ACTIVE) {
+		if (status & SOTG_PTD_DW3_ACTIVE) {
 			goto busy;
-		} else if (status & SOTG_PDT_DW3_HALTED) {
+		} else if (status & SOTG_PTD_DW3_HALTED) {
 			td->error_stall = 1;
 			td->error_any = 1;
-		} else if (status & SOTG_PDT_DW3_ERRORS) {
+		} else if (status & SOTG_PTD_DW3_ERRORS) {
 			td->error_any = 1;
 		}
 
@@ -515,9 +599,7 @@ saf1761_host_bulk_data_tx(struct saf1761
 		count = td->remainder;
 	}
 
-	usbd_copy_out(td->pc, td->offset, sc->sc_bounce_buffer, count);
-	saf1761_write_host_memory_4(sc, SOTG_DATA_ADDR(td->channel),
-	    sc->sc_bounce_buffer, (count + 3) / 4);
+	saf1761_write_host_memory(sc, td, count);
 
 	/* set toggle, if any */
 	if (td->set_toggle) {
@@ -527,30 +609,28 @@ saf1761_host_bulk_data_tx(struct saf1761
 
 	/* send one more packet */
 
-	pdt_addr = SOTG_PDT(td->channel);
+	pdt_addr = SOTG_PTD(td->channel);
 
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW7, 0);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW6, 0);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW5, 0);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW4, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW7, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW6, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, 0);
 
-	temp = SOTG_PDT_DW3_ACTIVE | (td->toggle << 25) | SOTG_PDT_DW3_CERR;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW3, temp);
+	temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR;
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
 
 	temp = SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW2, temp);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW2, temp);
 
 	temp = td->dw1_value | (0 << 10) /* OUT-PID */ | (td->ep_index >> 1);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW1, temp);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW1, temp);
 
 	temp = (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ |
 	    (td->max_packet_size << 18) /* wMaxPacketSize */ |
 	    (count << 3) /* transfer count */ |
-	    SOTG_PDT_DW0_VALID;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW0, temp);
+	    SOTG_PTD_DW0_VALID;
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
 
-	td->offset += count;
-	td->remainder -= count;
 	td->toggle ^= 1;
 busy:
 	return (1);	/* busy */
@@ -569,19 +649,20 @@ saf1761_host_intr_data_rx(struct saf1761
 		uint32_t count;
 		uint8_t got_short;
 
-		pdt_addr = SOTG_PDT(td->channel);
+		pdt_addr = SOTG_PTD(td->channel);
 
-		saf1761_read_host_memory_4(sc, pdt_addr + SOTG_PDT_DW3, &status, 1);
+		status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
+		DPRINTFN(5, "STATUS=0x%08x\n", status);
 
-		if (status & SOTG_PDT_DW3_ACTIVE) {
+		if (status & SOTG_PTD_DW3_ACTIVE) {
 			goto busy;
-		} else if (status & SOTG_PDT_DW3_HALTED) {
+		} else if (status & SOTG_PTD_DW3_HALTED) {
 			td->error_stall = 1;
 			td->error_any = 1;
 			goto complete;
 		}
 
-		count = (status & SOTG_PDT_DW3_XFER_COUNT);
+		count = (status & SOTG_PTD_DW3_XFER_COUNT);
 		got_short = 0;
 
 		/* verify the packet byte count */
@@ -605,14 +686,7 @@ saf1761_host_intr_data_rx(struct saf1761
 			goto complete;
 		}
 
-		saf1761_read_host_memory_4(sc, SOTG_DATA_ADDR(td->channel),
-		    sc->sc_bounce_buffer, (count + 3) / 4);
-
-		usbd_copy_in(td->pc, td->offset,
-		    sc->sc_bounce_buffer, count);
-
-		td->remainder -= count;
-		td->offset += count;
+		saf1761_read_host_memory(sc, td, count);
 
 		saf1761_host_channel_free(sc, td);
 
@@ -634,31 +708,31 @@ saf1761_host_intr_data_rx(struct saf1761
 
 	/* receive one more packet */
 
-	pdt_addr = SOTG_PDT(td->channel);
+	pdt_addr = SOTG_PTD(td->channel);
 
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW7, 0);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW6, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW7, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW6, 0);
 
 	temp = (0xFC << td->uframe) & 0xFF;	/* complete split */
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW5, temp);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, temp);
 
 	temp = (1U << td->uframe);		/* start split */
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW4, temp);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, temp);
 
-	temp = SOTG_PDT_DW3_ACTIVE | (td->toggle << 25) | SOTG_PDT_DW3_CERR;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW3, temp);
+	temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR;
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
 
-	temp = (SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8) | td->interval;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW2, temp);
+	temp = (SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8) | (td->interval & 0xF8);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW2, temp);
 
 	temp = td->dw1_value | (1 << 10) /* IN-PID */ | (td->ep_index >> 1);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW1, temp);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW1, temp);
 
 	temp = (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ |
 	    (td->max_packet_size << 18) /* wMaxPacketSize */ |
 	    (td->max_packet_size << 3) /* transfer count */ |
-	    SOTG_PDT_DW0_VALID;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW0, temp);
+	    SOTG_PTD_DW0_VALID;
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
 busy:
 	return (1);	/* busy */
 complete:
@@ -675,13 +749,14 @@ saf1761_host_intr_data_tx(struct saf1761
 	if (td->channel < SOTG_HOST_CHANNEL_MAX) {
 		uint32_t status;
 
-		pdt_addr = SOTG_PDT(td->channel);
+		pdt_addr = SOTG_PTD(td->channel);
 
-		saf1761_read_host_memory_4(sc, pdt_addr + SOTG_PDT_DW3, &status, 1);
+		status = saf1761_peek_host_memory_le_4(sc, pdt_addr + SOTG_PTD_DW3);
+		DPRINTFN(5, "STATUS=0x%08x\n", status);
 
-		if (status & SOTG_PDT_DW3_ACTIVE) {
+		if (status & SOTG_PTD_DW3_ACTIVE) {
 			goto busy;
-		} else if (status & SOTG_PDT_DW3_HALTED) {
+		} else if (status & SOTG_PTD_DW3_HALTED) {
 			td->error_stall = 1;
 			td->error_any = 1;
 		}
@@ -705,9 +780,7 @@ saf1761_host_intr_data_tx(struct saf1761
 		count = td->remainder;
 	}
 
-	usbd_copy_out(td->pc, td->offset, sc->sc_bounce_buffer, count);
-	saf1761_write_host_memory_4(sc, SOTG_DATA_ADDR(td->channel),
-	    sc->sc_bounce_buffer, (count + 3) / 4);
+	saf1761_write_host_memory(sc, td, count);
 
 	/* set toggle, if any */
 	if (td->set_toggle) {
@@ -717,34 +790,32 @@ saf1761_host_intr_data_tx(struct saf1761
 
 	/* send one more packet */
 
-	pdt_addr = SOTG_PDT(td->channel);
+	pdt_addr = SOTG_PTD(td->channel);
 
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW7, 0);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW6, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW7, 0);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW6, 0);
 
 	temp = (0xFC << td->uframe) & 0xFF;	/* complete split */
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW5, temp);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, temp);
 
 	temp = (1U << td->uframe);		/* start split */
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW4, temp);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, temp);
 
-	temp = SOTG_PDT_DW3_ACTIVE | (td->toggle << 25) | SOTG_PDT_DW3_CERR;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW3, temp);
+	temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR;
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
 
-	temp = (SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8) | td->interval;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW2, temp);
+	temp = (SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8) | (td->interval & 0xF8);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW2, temp);
 
 	temp = td->dw1_value | (0 << 10) /* OUT-PID */ | (td->ep_index >> 1);
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW1, temp);
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW1, temp);
 
 	temp = (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ |
 	    (td->max_packet_size << 18) /* wMaxPacketSize */ |
 	    (count << 3) /* transfer count */ |
-	    SOTG_PDT_DW0_VALID;
-	SAF1761_WRITE_4(sc, pdt_addr + SOTG_PDT_DW0, temp);
+	    SOTG_PTD_DW0_VALID;
+	SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
 
-	td->offset += count;
-	td->remainder -= count;
 	td->toggle ^= 1;
 busy:
 	return (1);	/* busy */
@@ -769,43 +840,117 @@ saf1761_otg_set_address(struct saf1761_o
 {
 	DPRINTFN(5, "addr=%d\n", addr);
 
-	SAF1761_WRITE_1(sc, SOTG_ADDRESS, addr | SOTG_ADDRESS_ENABLE);
+	SAF1761_WRITE_LE_4(sc, SOTG_ADDRESS, addr | SOTG_ADDRESS_ENABLE);
 }
 
+
 static void
-saf1761_read_device_fifo_1(struct saf1761_otg_softc *sc, void *buf, uint32_t len)
+saf1761_read_device_fifo(struct saf1761_otg_softc *sc,
+    struct saf1761_otg_td *td, uint32_t len)
 {
-	if (len == 0)
-		return;
-	bus_space_read_multi_1((sc)->sc_io_tag, (sc)->sc_io_hdl,
-	    SOTG_DATA_PORT, buf, len);
+	struct usb_page_search buf_res;
+	uint32_t count;
+
+	/* optimised read first */
+	while (len > 0) {
+		usbd_get_page(td->pc, td->offset, &buf_res);
+
+		/* get correct length */
+		if (buf_res.length > len)
+			buf_res.length = len;
+
+		/* check buffer alignment */
+		if (((uintptr_t)buf_res.buffer) & 3)
+			break;
+
+		count = buf_res.length & ~3;
+		if (count == 0)
+			break;
+
+		bus_space_read_multi_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
+		    SOTG_DATA_PORT, buf_res.buffer, count / 4);
+
+		len -= count;
+
+		/* update remainder and offset */
+		td->remainder -= count;
+		td->offset += count;
+	}
+
+	if (len > 0) {
+		/* use bounce buffer */
+		bus_space_read_multi_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
+		    SOTG_DATA_PORT, sc->sc_bounce_buffer, (len + 3) / 4);
+		usbd_copy_in(td->pc, td->offset,
+		    sc->sc_bounce_buffer, len);
+
+		/* update remainder and offset */
+		td->remainder -= len;
+		td->offset += len;
+	}
 }
 
 static void
-saf1761_write_device_fifo_1(struct saf1761_otg_softc *sc, void *buf, uint32_t len)
+saf1761_write_device_fifo(struct saf1761_otg_softc *sc,
+    struct saf1761_otg_td *td, uint32_t len)
 {
-	if (len == 0)
-		return;
-	bus_space_write_multi_1((sc)->sc_io_tag, (sc)->sc_io_hdl,
-	    SOTG_DATA_PORT, buf, len);
+	struct usb_page_search buf_res;
+	uint32_t count;
+
+	/* optimised write first */
+	while (len > 0) {
+		usbd_get_page(td->pc, td->offset, &buf_res);
+
+		/* get correct length */
+		if (buf_res.length > len)
+			buf_res.length = len;
+
+		/* check buffer alignment */
+		if (((uintptr_t)buf_res.buffer) & 3)
+			break;
+
+		count = buf_res.length & ~3;
+		if (count == 0)
+			break;
+
+		bus_space_write_multi_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
+		    SOTG_DATA_PORT, buf_res.buffer, count / 4);
+
+		len -= count;
+
+		/* update remainder and offset */
+		td->remainder -= count;
+		td->offset += count;
+	}
+	if (len > 0) {
+		/* use bounce buffer */
+		usbd_copy_out(td->pc, td->offset, sc->sc_bounce_buffer, len);
+		bus_space_write_multi_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
+		    SOTG_DATA_PORT, sc->sc_bounce_buffer, (len + 3) / 4);
+
+		/* update remainder and offset */
+		td->remainder -= len;
+		td->offset += len;
+	}
 }
 
 static uint8_t
 saf1761_device_setup_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
 {
 	struct usb_device_request req;
-	uint16_t count;
+	uint32_t count;
 
 	/* select the correct endpoint */
-	SAF1761_WRITE_1(sc, SOTG_EP_INDEX, SOTG_EP_INDEX_EP0SETUP);
+	SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX, SOTG_EP_INDEX_EP0SETUP);
+
+	count = SAF1761_READ_LE_4(sc, SOTG_BUF_LENGTH);
 
 	/* check buffer status */
-	if ((SAF1761_READ_1(sc, SOTG_DCBUFFERSTATUS) &
-	    SOTG_DCBUFFERSTATUS_FILLED_MASK) == 0)
+	if ((count & SOTG_BUF_LENGTH_FILLED_MASK) == 0)
 		goto busy;
 
-	/* read buffer length */
-	count = SAF1761_READ_2(sc, SOTG_BUF_LENGTH);
+	/* get buffer length */
+	count &= SOTG_BUF_LENGTH_BUFLEN_MASK;
 
 	DPRINTFN(5, "count=%u rem=%u\n", count, td->remainder);
 
@@ -813,7 +958,7 @@ saf1761_device_setup_rx(struct saf1761_o
 	td->did_stall = 0;
 
 	/* clear stall */
-	SAF1761_WRITE_1(sc, SOTG_CTRL_FUNC, 0);
+	SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, 0);
 
 	/* verify data length */
 	if (count != td->remainder) {
@@ -827,15 +972,12 @@ saf1761_device_setup_rx(struct saf1761_o
 		goto busy;
 	}
 	/* receive data */
-	saf1761_read_device_fifo_1(sc, &req, sizeof(req));
-
-	/* copy data into real buffer */
-	usbd_copy_in(td->pc, 0, &req, sizeof(req));
+	saf1761_read_device_fifo(sc, td, sizeof(req));
 
-	td->offset = sizeof(req);
-	td->remainder = 0;
+	/* extract SETUP packet again */
+	usbd_copy_out(td->pc, 0, &req, sizeof(req));
 
-	/* sneak peek the set address */
+	/* sneak peek the set address request */
 	if ((req.bmRequestType == UT_WRITE_DEVICE) &&
 	    (req.bRequest == UR_SET_ADDRESS)) {
 		sc->sc_dv_addr = req.wValue[0] & 0x7F;
@@ -851,7 +993,7 @@ busy:
 		DPRINTFN(5, "stalling\n");
 
 		/* set stall */
-		SAF1761_WRITE_1(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_STALL);
+		SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_STALL);
 
 		td->did_stall = 1;
 	}
@@ -861,17 +1003,17 @@ busy:
 static uint8_t
 saf1761_device_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
 {
-	struct usb_page_search buf_res;
-	uint16_t count;
+	uint32_t count;
 	uint8_t got_short = 0;
 
 	if (td->ep_index == 0) {
 		/* select the correct endpoint */
-		SAF1761_WRITE_1(sc, SOTG_EP_INDEX, SOTG_EP_INDEX_EP0SETUP);
+		SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX, SOTG_EP_INDEX_EP0SETUP);
+
+		count = SAF1761_READ_LE_4(sc, SOTG_BUF_LENGTH);
 
 		/* check buffer status */
-		if ((SAF1761_READ_1(sc, SOTG_DCBUFFERSTATUS) &
-		    SOTG_DCBUFFERSTATUS_FILLED_MASK) != 0) {
+		if ((count & SOTG_BUF_LENGTH_FILLED_MASK) != 0) {
 
 			if (td->remainder == 0) {
 				/*
@@ -890,23 +1032,24 @@ saf1761_device_data_rx(struct saf1761_ot
 		}
 	}
 	/* select the correct endpoint */
-	SAF1761_WRITE_1(sc, SOTG_EP_INDEX,
+	SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX,
 	    (td->ep_index << SOTG_EP_INDEX_ENDP_INDEX_SHIFT) |
 	    SOTG_EP_INDEX_DIR_OUT);
 
 	/* enable data stage */
 	if (td->set_toggle) {
 		td->set_toggle = 0;
-		SAF1761_WRITE_1(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_DSEN);
+		SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_DSEN);
 	}
 
+	count = SAF1761_READ_LE_4(sc, SOTG_BUF_LENGTH);
+
 	/* check buffer status */
-	if ((SAF1761_READ_1(sc, SOTG_DCBUFFERSTATUS) &
-	    SOTG_DCBUFFERSTATUS_FILLED_MASK) == 0) {
+	if ((count & SOTG_BUF_LENGTH_FILLED_MASK) == 0)
 		return (1);		/* not complete */
-	}
-	/* read buffer length */
-	count = SAF1761_READ_2(sc, SOTG_BUF_LENGTH);
+
+	/* get buffer length */
+	count &= SOTG_BUF_LENGTH_BUFLEN_MASK;
 
 	DPRINTFN(5, "rem=%u count=0x%04x\n", td->remainder, count);
 
@@ -928,21 +1071,9 @@ saf1761_device_data_rx(struct saf1761_ot
 		td->error_any = 1;
 		return (0);		/* we are complete */
 	}
-	while (count > 0) {
-		usbd_get_page(td->pc, td->offset, &buf_res);
-
-		/* get correct length */
-		if (buf_res.length > count)
-			buf_res.length = count;
-
-		/* receive data */
-		saf1761_read_device_fifo_1(sc, buf_res.buffer, buf_res.length);
+	/* receive data */
+	saf1761_read_device_fifo(sc, td, count);
 
-		/* update counters */
-		count -= buf_res.length;
-		td->offset += buf_res.length;
-		td->remainder -= buf_res.length;
-	}
 	/* check if we are complete */
 	if ((td->remainder == 0) || got_short) {
 		if (td->short_pkt) {
@@ -957,17 +1088,16 @@ saf1761_device_data_rx(struct saf1761_ot
 static uint8_t
 saf1761_device_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
 {
-	struct usb_page_search buf_res;
-	uint16_t count;
-	uint16_t count_old;
+	uint32_t count;
 
 	if (td->ep_index == 0) {
 		/* select the correct endpoint */
-		SAF1761_WRITE_1(sc, SOTG_EP_INDEX, SOTG_EP_INDEX_EP0SETUP);
+		SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX, SOTG_EP_INDEX_EP0SETUP);
+
+		count = SAF1761_READ_LE_4(sc, SOTG_BUF_LENGTH);
 
 		/* check buffer status */
-		if ((SAF1761_READ_1(sc, SOTG_DCBUFFERSTATUS) &
-		    SOTG_DCBUFFERSTATUS_FILLED_MASK) != 0) {
+		if ((count & SOTG_BUF_LENGTH_FILLED_MASK) != 0) {
 			DPRINTFN(5, "SETUP abort\n");
 			/*
 			 * USB Host Aborted the transfer.
@@ -977,20 +1107,20 @@ saf1761_device_data_tx(struct saf1761_ot
 		}
 	}
 	/* select the correct endpoint */
-	SAF1761_WRITE_1(sc, SOTG_EP_INDEX,
+	SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX,
 	    (td->ep_index << SOTG_EP_INDEX_ENDP_INDEX_SHIFT) |
 	    SOTG_EP_INDEX_DIR_IN);
 
+	count = SAF1761_READ_LE_4(sc, SOTG_BUF_LENGTH);
+
 	/* check buffer status */
-	if ((SAF1761_READ_1(sc, SOTG_DCBUFFERSTATUS) &
-	    SOTG_DCBUFFERSTATUS_FILLED_MASK) != 0) {
+	if ((count & SOTG_BUF_LENGTH_FILLED_MASK) != 0)
 		return (1);		/* not complete */
-	}
 
 	/* enable data stage */
 	if (td->set_toggle) {
 		td->set_toggle = 0;
-		SAF1761_WRITE_1(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_DSEN);
+		SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_DSEN);
 	}
 
 	DPRINTFN(5, "rem=%u\n", td->remainder);
@@ -1001,34 +1131,18 @@ saf1761_device_data_tx(struct saf1761_ot
 		td->short_pkt = 1;
 		count = td->remainder;
 	}
-	count_old = count;
-
-	while (count > 0) {
-
-		usbd_get_page(td->pc, td->offset, &buf_res);
-
-		/* get correct length */
-		if (buf_res.length > count)
-			buf_res.length = count;
-
-		/* transmit data */
-		saf1761_write_device_fifo_1(sc, buf_res.buffer, buf_res.length);
-
-		/* update counters */
-		count -= buf_res.length;
-		td->offset += buf_res.length;
-		td->remainder -= buf_res.length;
-	}
+	/* transmit data */
+	saf1761_write_device_fifo(sc, td, count);
 
 	if (td->ep_index == 0) {
-		if (count_old < SOTG_FS_MAX_PACKET_SIZE) {
+		if (count < SOTG_FS_MAX_PACKET_SIZE) {
 			/* set end of packet */
-			SAF1761_WRITE_1(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_VENDP);
+			SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_VENDP);
 		}
 	} else {
-		if (count_old < SOTG_HS_MAX_PACKET_SIZE) {
+		if (count < SOTG_HS_MAX_PACKET_SIZE) {
 			/* set end of packet */
-			SAF1761_WRITE_1(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_VENDP);
+			SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_VENDP);
 		}
 	}
 
@@ -1045,25 +1159,29 @@ saf1761_device_data_tx(struct saf1761_ot
 static uint8_t
 saf1761_device_data_tx_sync(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
 {
+	uint32_t count;
+
 	if (td->ep_index == 0) {
 		/* select the correct endpoint */
-		SAF1761_WRITE_1(sc, SOTG_EP_INDEX, SOTG_EP_INDEX_EP0SETUP);
+		SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX, SOTG_EP_INDEX_EP0SETUP);
+
+		count = SAF1761_READ_LE_4(sc, SOTG_BUF_LENGTH);
 
 		/* check buffer status */
-		if ((SAF1761_READ_1(sc, SOTG_DCBUFFERSTATUS) &
-		    SOTG_DCBUFFERSTATUS_FILLED_MASK) != 0) {
+		if ((count & SOTG_BUF_LENGTH_FILLED_MASK) != 0) {
 			DPRINTFN(5, "Faking complete\n");
 			return (0);	/* complete */
 		}
 	}
 	/* select the correct endpoint */
-	SAF1761_WRITE_1(sc, SOTG_EP_INDEX,
+	SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX,
 	    (td->ep_index << SOTG_EP_INDEX_ENDP_INDEX_SHIFT) |
 	    SOTG_EP_INDEX_DIR_IN);
 
+	count = SAF1761_READ_LE_4(sc, SOTG_BUF_LENGTH);
+
 	/* check buffer status */
-	if ((SAF1761_READ_1(sc, SOTG_DCBUFFERSTATUS) &
-	    SOTG_DCBUFFERSTATUS_FILLED_MASK) != 0)
+	if ((count & SOTG_BUF_LENGTH_FILLED_MASK) != 0)
 		return (1);		/* busy */
 
 	if (sc->sc_dv_addr != 0xFF) {
@@ -1143,7 +1261,7 @@ saf1761_otg_wait_suspend(struct saf1761_
 		sc->sc_intr_enable &= ~SOTG_DCINTERRUPT_IESUSP;
 		sc->sc_intr_enable |= SOTG_DCINTERRUPT_IERESM;
 	}
-	SAF1761_WRITE_4(sc, SOTG_DCINTERRUPT_EN, sc->sc_intr_enable);
+	SAF1761_WRITE_LE_4(sc, SOTG_DCINTERRUPT_EN, sc->sc_intr_enable);
 }
 
 static void
@@ -1152,7 +1270,7 @@ saf1761_otg_update_vbus(struct saf1761_o
 	uint16_t status;
 
 	/* read fresh status */
-	status = SAF1761_READ_2(sc, SOTG_STATUS);
+	status = SAF1761_READ_LE_4(sc, SOTG_STATUS);
 
 	DPRINTFN(4, "STATUS=0x%04x\n", status);
 
@@ -1188,16 +1306,18 @@ saf1761_otg_interrupt(struct saf1761_otg
 
 	USB_BUS_LOCK(&sc->sc_bus);
 
-	hcstat = SAF1761_READ_4(sc, SOTG_HCINTERRUPT);
+	hcstat = SAF1761_READ_LE_4(sc, SOTG_HCINTERRUPT);
 	/* acknowledge all host controller interrupts */
-	SAF1761_WRITE_4(sc, SOTG_HCINTERRUPT, hcstat);
+	SAF1761_WRITE_LE_4(sc, SOTG_HCINTERRUPT, hcstat);
 
-	status = SAF1761_READ_4(sc, SOTG_DCINTERRUPT);
+	status = SAF1761_READ_LE_4(sc, SOTG_DCINTERRUPT);
 	/* acknowledge all device controller interrupts */
-	SAF1761_WRITE_4(sc, SOTG_DCINTERRUPT, status);
+	SAF1761_WRITE_LE_4(sc, SOTG_DCINTERRUPT, status);
 
-	DPRINTF("DCINTERRUPT=0x%08x HCINTERRUPT=0x%08x SOF=0x%04x\n",
-	    status, hcstat, SAF1761_READ_2(sc, SOTG_FRAME_NUM));
+	DPRINTF("DCINTERRUPT=0x%08x HCINTERRUPT=0x%08x SOF=0x%08x "
+	    "FRINDEX=0x%08x\n", status, hcstat,
+	    SAF1761_READ_LE_4(sc, SOTG_FRAME_NUM),
+	    SAF1761_READ_LE_4(sc, SOTG_FRINDEX));
 
 	/* update VBUS and ID bits, if any */
 	if (status & SOTG_DCINTERRUPT_IEVBUS) {
@@ -1206,11 +1326,11 @@ saf1761_otg_interrupt(struct saf1761_otg
 
 	if (status & SOTG_DCINTERRUPT_IEBRST) {
 		/* unlock device */
-		SAF1761_WRITE_2(sc, SOTG_UNLOCK_DEVICE,
+		SAF1761_WRITE_LE_4(sc, SOTG_UNLOCK_DEVICE,
 		    SOTG_UNLOCK_DEVICE_CODE);
 
 		/* Enable device address */
-		SAF1761_WRITE_1(sc, SOTG_ADDRESS,
+		SAF1761_WRITE_LE_4(sc, SOTG_ADDRESS,

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



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