rpms/kernel/devel linux-2.6-usb-endian-ehci.patch, NONE, 1.1 linux-2.6-usb-endian-quirks.patch, NONE, 1.1 linux-2.6-usb-endian-toshiba.patch, NONE, 1.1 kernel-2.6.spec, 1.2881, 1.2882 linux-2.6-ohci-platform-bus.patch, 1.1, 1.2

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Sun Dec 17 21:55:34 UTC 2006


Author: dwmw2

Update of /cvs/dist/rpms/kernel/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv17843

Modified Files:
	kernel-2.6.spec linux-2.6-ohci-platform-bus.patch 
Added Files:
	linux-2.6-usb-endian-ehci.patch 
	linux-2.6-usb-endian-quirks.patch 
	linux-2.6-usb-endian-toshiba.patch 
Log Message:
BE OHCI, for PS3 &c

linux-2.6-usb-endian-ehci.patch:
 Kconfig      |    5 ++
 ehci-dbg.c   |   24 ++++++------
 ehci-fsl.c   |    8 ++--
 ehci-hcd.c   |   92 +++++++++++++++++++++++++---------------------
 ehci-hub.c   |  118 +++++++++++++++++++++++++++++++----------------------------
 ehci-pci.c   |   37 +++++++++++++-----
 ehci-q.c     |   16 ++++----
 ehci-sched.c |   22 +++++------
 ehci.h       |   32 ++++++++++++++++
 9 files changed, 212 insertions(+), 142 deletions(-)

--- NEW FILE linux-2.6-usb-endian-ehci.patch ---
This patch implements supports for EHCI controllers whose MMIO
registers are big endian and enables that functionality for
the Toshiba SCC chip. It does _not_ add support for big endian
in-memory data structures as this is not needed for that chip
and I hope it will never be.

The guts of the patch are to convert readl(...) to
ehci_readl(ehci, ...) and similarly for register writes.

Signed-off-by: Kou Ishizaki <kou.ishizaki at toshiba.co.jp>
Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
Acked-by: David Brownell <dbrownell at users.sourceforge.net>

 drivers/usb/host/Kconfig      |    5 +
 drivers/usb/host/ehci-dbg.c   |   24 ++++----
 drivers/usb/host/ehci-fsl.c   |    8 +-
 drivers/usb/host/ehci-hcd.c   |   92 +++++++++++++++++---------------
 drivers/usb/host/ehci-hub.c   |  118 ++++++++++++++++++++++--------------------
 drivers/usb/host/ehci-pci.c   |   37 +++++++++----
 drivers/usb/host/ehci-q.c     |   16 +++--
 drivers/usb/host/ehci-sched.c |   22 +++----
 drivers/usb/host/ehci.h       |   32 +++++++++++
 9 files changed, 212 insertions(+), 142 deletions(-)

Index: linux-test-x86/drivers/usb/host/ehci-dbg.c
===================================================================
--- linux-test-x86.orig/drivers/usb/host/ehci-dbg.c	2006-12-13 13:03:44.000000000 +1100
+++ linux-test-x86/drivers/usb/host/ehci-dbg.c	2006-12-13 13:06:02.000000000 +1100
@@ -43,7 +43,7 @@
  */
 static void dbg_hcs_params (struct ehci_hcd *ehci, char *label)
 {
-	u32	params = readl (&ehci->caps->hcs_params);
+	u32	params = ehci_readl(ehci, &ehci->caps->hcs_params);
 
 	ehci_dbg (ehci,
 		"%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d\n",
@@ -87,7 +87,7 @@
  * */
 static void dbg_hcc_params (struct ehci_hcd *ehci, char *label)
 {
-	u32	params = readl (&ehci->caps->hcc_params);
+	u32	params = ehci_readl(ehci, &ehci->caps->hcc_params);
 
 	if (HCC_ISOC_CACHE (params)) {
 		ehci_dbg (ehci,
@@ -653,7 +653,7 @@
 	}
 
 	/* Capability Registers */
-	i = HC_VERSION(readl (&ehci->caps->hc_capbase));
+	i = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
 	temp = scnprintf (next, size,
 		"bus %s, device %s (driver " DRIVER_VERSION ")\n"
 		"%s\n"
@@ -673,7 +673,7 @@
 		unsigned	count = 256/4;
 
 		pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
-		offset = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
+		offset = HCC_EXT_CAPS (ehci_readl(ehci, &ehci->caps->hcc_params));
 		while (offset && count--) {
 			pci_read_config_dword (pdev, offset, &cap);
 			switch (cap & 0xff) {
@@ -704,50 +704,50 @@
 #endif
 
 	// FIXME interpret both types of params
-	i = readl (&ehci->caps->hcs_params);
+	i = ehci_readl(ehci, &ehci->caps->hcs_params);
 	temp = scnprintf (next, size, "structural params 0x%08x\n", i);
 	size -= temp;
 	next += temp;
 
-	i = readl (&ehci->caps->hcc_params);
+	i = ehci_readl(ehci, &ehci->caps->hcc_params);
 	temp = scnprintf (next, size, "capability params 0x%08x\n", i);
 	size -= temp;
 	next += temp;
 
 	/* Operational Registers */
 	temp = dbg_status_buf (scratch, sizeof scratch, label,
-			readl (&ehci->regs->status));
+			ehci_readl(ehci, &ehci->regs->status));
 	temp = scnprintf (next, size, fmt, temp, scratch);
 	size -= temp;
 	next += temp;
 
 	temp = dbg_command_buf (scratch, sizeof scratch, label,
-			readl (&ehci->regs->command));
+			ehci_readl(ehci, &ehci->regs->command));
 	temp = scnprintf (next, size, fmt, temp, scratch);
 	size -= temp;
 	next += temp;
 
 	temp = dbg_intr_buf (scratch, sizeof scratch, label,
-			readl (&ehci->regs->intr_enable));
+			ehci_readl(ehci, &ehci->regs->intr_enable));
 	temp = scnprintf (next, size, fmt, temp, scratch);
 	size -= temp;
 	next += temp;
 
 	temp = scnprintf (next, size, "uframe %04x\n",
-			readl (&ehci->regs->frame_index));
+			ehci_readl(ehci, &ehci->regs->frame_index));
 	size -= temp;
 	next += temp;
 
 	for (i = 1; i <= HCS_N_PORTS (ehci->hcs_params); i++) {
 		temp = dbg_port_buf (scratch, sizeof scratch, label, i,
-				readl (&ehci->regs->port_status [i - 1]));
+				ehci_readl(ehci, &ehci->regs->port_status [i - 1]));
 		temp = scnprintf (next, size, fmt, temp, scratch);
 		size -= temp;
 		next += temp;
 		if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) {
 			temp = scnprintf (next, size,
 					"    debug control %08x\n",
-					readl (&ehci->debug->control));
+					ehci_readl(ehci, &ehci->debug->control));
 			size -= temp;
 			next += temp;
 		}
Index: linux-test-x86/drivers/usb/host/Kconfig
===================================================================
--- linux-test-x86.orig/drivers/usb/host/Kconfig	2006-12-13 13:05:40.000000000 +1100
+++ linux-test-x86/drivers/usb/host/Kconfig	2006-12-13 13:06:02.000000000 +1100
@@ -67,6 +67,11 @@
 
 	  If unsure, say N.
 
+config USB_EHCI_BIG_ENDIAN_MMIO
+	bool
+	depends on USB_EHCI_HCD
+	default n
+
 config USB_ISP116X_HCD
 	tristate "ISP116X HCD support"
 	depends on USB
Index: linux-test-x86/drivers/usb/host/ehci-fsl.c
===================================================================
--- linux-test-x86.orig/drivers/usb/host/ehci-fsl.c	2006-09-28 20:44:49.000000000 +1000
+++ linux-test-x86/drivers/usb/host/ehci-fsl.c	2006-12-13 13:06:02.000000000 +1100
@@ -177,7 +177,7 @@
 	case FSL_USB2_PHY_NONE:
 		break;
 	}
-	writel(portsc, &ehci->regs->port_status[port_offset]);
+	ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]);
 }
 
 static void mpc83xx_usb_setup(struct usb_hcd *hcd)
@@ -214,7 +214,7 @@
 	}
 
 	/* put controller in host mode. */
-	writel(0x00000003, non_ehci + FSL_SOC_USB_USBMODE);
+	ehci_writel(ehci, 0x00000003, non_ehci + FSL_SOC_USB_USBMODE);
 	out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c);
 	out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040);
 	out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001);
@@ -238,12 +238,12 @@
 	/* EHCI registers start at offset 0x100 */
 	ehci->caps = hcd->regs + 0x100;
 	ehci->regs = hcd->regs + 0x100 +
-	    HC_LENGTH(readl(&ehci->caps->hc_capbase));
+	    HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
 	dbg_hcs_params(ehci, "reset");
 	dbg_hcc_params(ehci, "reset");
 
 	/* cache this readonly data; minimize chip reads */
-	ehci->hcs_params = readl(&ehci->caps->hcs_params);
+	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
 
 	retval = ehci_halt(ehci);
 	if (retval)
Index: linux-test-x86/drivers/usb/host/ehci-hcd.c
===================================================================
--- linux-test-x86.orig/drivers/usb/host/ehci-hcd.c	2006-12-13 13:03:44.000000000 +1100
+++ linux-test-x86/drivers/usb/host/ehci-hcd.c	2006-12-13 13:06:02.000000000 +1100
@@ -157,12 +157,13 @@
  * before driver shutdown. But it also seems to be caused by bugs in cardbus
  * bridge shutdown:  shutting down the bridge before the devices using it.
  */
-static int handshake (void __iomem *ptr, u32 mask, u32 done, int usec)
+static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
+		      u32 mask, u32 done, int usec)
 {
 	u32	result;
 
 	do {
-		result = readl (ptr);
+		result = ehci_readl(ehci, ptr);
 		if (result == ~(u32)0)		/* card removed */
 			return -ENODEV;
 		result &= mask;
@@ -177,18 +178,19 @@
 /* force HC to halt state from unknown (EHCI spec section 2.3) */
 static int ehci_halt (struct ehci_hcd *ehci)
 {
-	u32	temp = readl (&ehci->regs->status);
+	u32	temp = ehci_readl(ehci, &ehci->regs->status);
 
 	/* disable any irqs left enabled by previous code */
-	writel (0, &ehci->regs->intr_enable);
+	ehci_writel(ehci, 0, &ehci->regs->intr_enable);
 
 	if ((temp & STS_HALT) != 0)
 		return 0;
 
-	temp = readl (&ehci->regs->command);
+	temp = ehci_readl(ehci, &ehci->regs->command);
 	temp &= ~CMD_RUN;
-	writel (temp, &ehci->regs->command);
-	return handshake (&ehci->regs->status, STS_HALT, STS_HALT, 16 * 125);
+	ehci_writel(ehci, temp, &ehci->regs->command);
+	return handshake (ehci, &ehci->regs->status,
+			  STS_HALT, STS_HALT, 16 * 125);
 }
 
 /* put TDI/ARC silicon into EHCI mode */
@@ -198,23 +200,24 @@
 	u32		tmp;
 
 	reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + 0x68);
-	tmp = readl (reg_ptr);
+	tmp = ehci_readl(ehci, reg_ptr);
 	tmp |= 0x3;
-	writel (tmp, reg_ptr);
+	ehci_writel(ehci, tmp, reg_ptr);
 }
 
 /* reset a non-running (STS_HALT == 1) controller */
 static int ehci_reset (struct ehci_hcd *ehci)
 {
 	int	retval;
-	u32	command = readl (&ehci->regs->command);
+	u32	command = ehci_readl(ehci, &ehci->regs->command);
 
 	command |= CMD_RESET;
 	dbg_cmd (ehci, "reset", command);
-	writel (command, &ehci->regs->command);
+	ehci_writel(ehci, command, &ehci->regs->command);
 	ehci_to_hcd(ehci)->state = HC_STATE_HALT;
 	ehci->next_statechange = jiffies;
-	retval = handshake (&ehci->regs->command, CMD_RESET, 0, 250 * 1000);
+	retval = handshake (ehci, &ehci->regs->command,
+			    CMD_RESET, 0, 250 * 1000);
 
 	if (retval)
 		return retval;
@@ -236,21 +239,21 @@
 #endif
 
 	/* wait for any schedule enables/disables to take effect */
-	temp = readl (&ehci->regs->command) << 10;
+	temp = ehci_readl(ehci, &ehci->regs->command) << 10;
 	temp &= STS_ASS | STS_PSS;
-	if (handshake (&ehci->regs->status, STS_ASS | STS_PSS,
+	if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS,
 				temp, 16 * 125) != 0) {
 		ehci_to_hcd(ehci)->state = HC_STATE_HALT;
 		return;
 	}
 
 	/* then disable anything that's still active */
-	temp = readl (&ehci->regs->command);
+	temp = ehci_readl(ehci, &ehci->regs->command);
 	temp &= ~(CMD_ASE | CMD_IAAD | CMD_PSE);
-	writel (temp, &ehci->regs->command);
+	ehci_writel(ehci, temp, &ehci->regs->command);
 
 	/* hardware can take 16 microframes to turn off ... */
-	if (handshake (&ehci->regs->status, STS_ASS | STS_PSS,
+	if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS,
 				0, 16 * 125) != 0) {
 		ehci_to_hcd(ehci)->state = HC_STATE_HALT;
 		return;
@@ -277,11 +280,11 @@
 
 	/* lost IAA irqs wedge things badly; seen with a vt8235 */
 	if (ehci->reclaim) {
-		u32		status = readl (&ehci->regs->status);
+		u32		status = ehci_readl(ehci, &ehci->regs->status);
 		if (status & STS_IAA) {
 			ehci_vdbg (ehci, "lost IAA\n");
 			COUNT (ehci->stats.lost_iaa);
-			writel (STS_IAA, &ehci->regs->status);
+			ehci_writel(ehci, STS_IAA, &ehci->regs->status);
 			ehci->reclaim_ready = 1;
 		}
 	}
@@ -309,7 +312,7 @@
 	(void) ehci_halt (ehci);
 
 	/* make BIOS/etc use companion controller during reboot */
-	writel (0, &ehci->regs->configured_flag);
+	ehci_writel(ehci, 0, &ehci->regs->configured_flag);
 }
 
 static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
@@ -379,11 +382,11 @@
 		ehci_quiesce (ehci);
 
 	ehci_reset (ehci);
-	writel (0, &ehci->regs->intr_enable);
+	ehci_writel(ehci, 0, &ehci->regs->intr_enable);
 	spin_unlock_irq(&ehci->lock);
 
 	/* let companion controllers work when we aren't */
-	writel (0, &ehci->regs->configured_flag);
+	ehci_writel(ehci, 0, &ehci->regs->configured_flag);
 
 	remove_debug_files (ehci);
 
@@ -402,7 +405,8 @@
 		ehci->stats.complete, ehci->stats.unlink);
 #endif
 
-	dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status));
+	dbg_status (ehci, "ehci_stop completed",
+		    ehci_readl(ehci, &ehci->regs->status));
 }
 
 /* one-time init, only for memory state */
@@ -428,7 +432,7 @@
 		return retval;
 
 	/* controllers may cache some of the periodic schedule ... */
-	hcc_params = readl(&ehci->caps->hcc_params);
+	hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
 	if (HCC_ISOC_CACHE(hcc_params))		// full frame cache
 		ehci->i_thresh = 8;
 	else					// N microframes cached
@@ -501,8 +505,8 @@
 		ehci_mem_cleanup(ehci);
 		return retval;
 	}
-	writel(ehci->periodic_dma, &ehci->regs->frame_list);
-	writel((u32)ehci->async->qh_dma, &ehci->regs->async_next);
+	ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
+	ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next);
 
 	/*
 	 * hcc_params controls whether ehci->regs->segment must (!!!)
@@ -516,9 +520,9 @@
 	 * Scsi_Host.highmem_io, and so forth.  It's readonly to all
 	 * host side drivers though.
 	 */
-	hcc_params = readl(&ehci->caps->hcc_params);
+	hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
 	if (HCC_64BIT_ADDR(hcc_params)) {
-		writel(0, &ehci->regs->segment);
+		ehci_writel(ehci, 0, &ehci->regs->segment);
 #if 0
 // this is deeply broken on almost all architectures
 		if (!dma_set_mask(hcd->self.controller, DMA_64BIT_MASK))
@@ -531,7 +535,7 @@
 	// root hub will detect new devices (why?); NEC doesn't
 	ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
 	ehci->command |= CMD_RUN;
-	writel (ehci->command, &ehci->regs->command);
+	ehci_writel(ehci, ehci->command, &ehci->regs->command);
 	dbg_cmd (ehci, "init", ehci->command);
 
 	/*
@@ -541,17 +545,18 @@
 	 * and there's no companion controller unless maybe for USB OTG.)
 	 */
 	hcd->state = HC_STATE_RUNNING;
-	writel (FLAG_CF, &ehci->regs->configured_flag);
-	readl (&ehci->regs->command);	/* unblock posted writes */
+	ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
+	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
 
-	temp = HC_VERSION(readl (&ehci->caps->hc_capbase));
+	temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
 	ehci_info (ehci,
 		"USB %x.%x started, EHCI %x.%02x, driver %s%s\n",
 		((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
 		temp >> 8, temp & 0xff, DRIVER_VERSION,
 		ignore_oc ? ", overcurrent ignored" : "");
 
-	writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */
+	ehci_writel(ehci, INTR_MASK,
+		    &ehci->regs->intr_enable); /* Turn On Interrupts */
 
 	/* GRR this is run-once init(), being done every time the HC starts.
 	 * So long as they're part of class devices, we can't do it init()
@@ -572,7 +577,7 @@
 
 	spin_lock (&ehci->lock);
 
-	status = readl (&ehci->regs->status);
+	status = ehci_readl(ehci, &ehci->regs->status);
 
 	/* e.g. cardbus physical eject */
 	if (status == ~(u32) 0) {
@@ -587,8 +592,8 @@
 	}
 
 	/* clear (just) interrupts */
-	writel (status, &ehci->regs->status);
-	readl (&ehci->regs->command);	/* unblock posted write */
+	ehci_writel(ehci, status, &ehci->regs->status);
+	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted write */
 	bh = 0;
 
 #ifdef	EHCI_VERBOSE_DEBUG
@@ -619,11 +624,12 @@
 		unsigned	i = HCS_N_PORTS (ehci->hcs_params);
 
 		/* resume root hub? */
-		if (!(readl(&ehci->regs->command) & CMD_RUN))
+		if (!(ehci_readl(ehci, &ehci->regs->command) & CMD_RUN))
 			usb_hcd_resume_root_hub(hcd);
 
 		while (i--) {
-			int pstatus = readl (&ehci->regs->port_status [i]);
+			int pstatus = ehci_readl(ehci,
+						 &ehci->regs->port_status [i]);
 
 			if (pstatus & PORT_OWNER)
 				continue;
@@ -643,14 +649,15 @@
 	/* PCI errors [4.15.2.4] */
 	if (unlikely ((status & STS_FATAL) != 0)) {
 		/* bogus "fatal" IRQs appear on some chips... why?  */
-		status = readl (&ehci->regs->status);
-		dbg_cmd (ehci, "fatal", readl (&ehci->regs->command));
+		status = ehci_readl(ehci, &ehci->regs->status);
+		dbg_cmd (ehci, "fatal", ehci_readl(ehci,
+						   &ehci->regs->command));
 		dbg_status (ehci, "fatal", status);
 		if (status & STS_HALT) {
 			ehci_err (ehci, "fatal error\n");
 dead:
 			ehci_reset (ehci);
-			writel (0, &ehci->regs->configured_flag);
+			ehci_writel(ehci, 0, &ehci->regs->configured_flag);
 			/* generic layer kills/unlinks all urbs, then
 			 * uses ehci_stop to clean up the rest
 			 */
@@ -873,7 +880,8 @@
 static int ehci_get_frame (struct usb_hcd *hcd)
 {
 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
-	return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size;
+	return (ehci_readl(ehci, &ehci->regs->frame_index) >> 3) %
+		ehci->periodic_size;
 }
 
 /*-------------------------------------------------------------------------*/
Index: linux-test-x86/drivers/usb/host/ehci-hub.c
===================================================================
--- linux-test-x86.orig/drivers/usb/host/ehci-hub.c	2006-12-13 13:03:44.000000000 +1100
+++ linux-test-x86/drivers/usb/host/ehci-hub.c	2006-12-13 13:06:02.000000000 +1100
@@ -47,7 +47,7 @@
 		ehci_quiesce (ehci);
 		hcd->state = HC_STATE_QUIESCING;
 	}
-	ehci->command = readl (&ehci->regs->command);
+	ehci->command = ehci_readl(ehci, &ehci->regs->command);
 	if (ehci->reclaim)
 		ehci->reclaim_ready = 1;
 	ehci_work(ehci);
@@ -60,7 +60,7 @@
 	ehci->bus_suspended = 0;
 	while (port--) {
 		u32 __iomem	*reg = &ehci->regs->port_status [port];
-		u32		t1 = readl (reg) & ~PORT_RWC_BITS;
+		u32		t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
 		u32		t2 = t1;
 
 		/* keep track of which ports we suspend */
@@ -79,7 +79,7 @@
 		if (t1 != t2) {
 			ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
 				port + 1, t1, t2);
-			writel (t2, reg);
+			ehci_writel(ehci, t2, reg);
 		}
 	}
 
@@ -92,8 +92,8 @@
 	mask = INTR_MASK;
 	if (!device_may_wakeup(&hcd->self.root_hub->dev))
 		mask &= ~STS_PCD;
-	writel(mask, &ehci->regs->intr_enable);
-	readl(&ehci->regs->intr_enable);
+	ehci_writel(ehci, mask, &ehci->regs->intr_enable);
+	ehci_readl(ehci, &ehci->regs->intr_enable);
 
 	ehci->next_statechange = jiffies + msecs_to_jiffies(10);
 	spin_unlock_irq (&ehci->lock);
@@ -118,26 +118,26 @@
 	 * the last user of the controller, not reset/pm hardware keeping
 	 * state we gave to it.
 	 */
-	temp = readl(&ehci->regs->intr_enable);
+	temp = ehci_readl(ehci, &ehci->regs->intr_enable);
 	ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss");
 
 	/* at least some APM implementations will try to deliver
 	 * IRQs right away, so delay them until we're ready.
 	 */
-	writel(0, &ehci->regs->intr_enable);
+	ehci_writel(ehci, 0, &ehci->regs->intr_enable);
 
 	/* re-init operational registers */
-	writel(0, &ehci->regs->segment);
-	writel(ehci->periodic_dma, &ehci->regs->frame_list);
-	writel((u32) ehci->async->qh_dma, &ehci->regs->async_next);
+	ehci_writel(ehci, 0, &ehci->regs->segment);
+	ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
+	ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next);
 
 	/* restore CMD_RUN, framelist size, and irq threshold */
-	writel (ehci->command, &ehci->regs->command);
+	ehci_writel(ehci, ehci->command, &ehci->regs->command);
 
 	/* manually resume the ports we suspended during bus_suspend() */
 	i = HCS_N_PORTS (ehci->hcs_params);
 	while (i--) {
-		temp = readl (&ehci->regs->port_status [i]);
+		temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
 		temp &= ~(PORT_RWC_BITS
 			| PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E);
 		if (test_bit(i, &ehci->bus_suspended) &&
@@ -145,20 +145,20 @@
 			ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
 			temp |= PORT_RESUME;
 		}
-		writel (temp, &ehci->regs->port_status [i]);
+		ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
 	}
 	i = HCS_N_PORTS (ehci->hcs_params);
 	mdelay (20);
 	while (i--) {
-		temp = readl (&ehci->regs->port_status [i]);
+		temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
 		if (test_bit(i, &ehci->bus_suspended) &&
 				(temp & PORT_SUSPEND)) {
 			temp &= ~(PORT_RWC_BITS | PORT_RESUME);
-			writel (temp, &ehci->regs->port_status [i]);
+			ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
 			ehci_vdbg (ehci, "resumed port %d\n", i + 1);
 		}
 	}
-	(void) readl (&ehci->regs->command);
+	(void) ehci_readl(ehci, &ehci->regs->command);
 
 	/* maybe re-activate the schedule(s) */
 	temp = 0;
@@ -168,14 +168,14 @@
 		temp |= CMD_PSE;
 	if (temp) {
 		ehci->command |= temp;
-		writel (ehci->command, &ehci->regs->command);
+		ehci_writel(ehci, ehci->command, &ehci->regs->command);
 	}
 
 	ehci->next_statechange = jiffies + msecs_to_jiffies(5);
 	hcd->state = HC_STATE_RUNNING;
 
 	/* Now we can safely re-enable irqs */
-	writel(INTR_MASK, &ehci->regs->intr_enable);
+	ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
 
 	spin_unlock_irq (&ehci->lock);
 	return 0;
@@ -217,7 +217,8 @@
 		// what happens if HCS_N_CC(params) == 0 ?
 		port_status |= PORT_OWNER;
 		port_status &= ~PORT_RWC_BITS;
-		writel (port_status, &ehci->regs->port_status [index]);
+		ehci_writel(ehci, port_status,
+			    &ehci->regs->port_status [index]);
 
 	} else
 		ehci_dbg (ehci, "port %d high speed\n", index + 1);
@@ -268,13 +269,14 @@
 	/* port N changes (bit N)? */
 	spin_lock_irqsave (&ehci->lock, flags);
 	for (i = 0; i < ports; i++) {
-		temp = readl (&ehci->regs->port_status [i]);
+		temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
 		if (temp & PORT_OWNER) {
 			/* don't report this in GetPortStatus */
 			if (temp & PORT_CSC) {
 				temp &= ~PORT_RWC_BITS;
 				temp |= PORT_CSC;
-				writel (temp, &ehci->regs->port_status [i]);
+				ehci_writel(ehci, temp,
+					    &ehci->regs->port_status [i]);
 			}
 			continue;
 		}
@@ -373,18 +375,18 @@
 		if (!wIndex || wIndex > ports)
 			goto error;
 		wIndex--;
-		temp = readl (&ehci->regs->port_status [wIndex]);
+		temp = ehci_readl(ehci, &ehci->regs->port_status [wIndex]);
 		if (temp & PORT_OWNER)
 			break;
 
 		switch (wValue) {
 		case USB_PORT_FEAT_ENABLE:
-			writel (temp & ~PORT_PE,
-				&ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, temp & ~PORT_PE,
+				    &ehci->regs->port_status [wIndex]);
 			break;
 		case USB_PORT_FEAT_C_ENABLE:
-			writel((temp & ~PORT_RWC_BITS) | PORT_PEC,
-				&ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_PEC,
+				    &ehci->regs->port_status [wIndex]);
 			break;
 		case USB_PORT_FEAT_SUSPEND:
 			if (temp & PORT_RESET)
@@ -396,8 +398,8 @@
 					goto error;
 				/* resume signaling for 20 msec */
 				temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
-				writel (temp | PORT_RESUME,
-					&ehci->regs->port_status [wIndex]);
+				ehci_writel(ehci, temp | PORT_RESUME,
+					    &ehci->regs->port_status [wIndex]);
 				ehci->reset_done [wIndex] = jiffies
 						+ msecs_to_jiffies (20);
 			}
@@ -407,16 +409,17 @@
 			break;
 		case USB_PORT_FEAT_POWER:
 			if (HCS_PPC (ehci->hcs_params))
-				writel (temp & ~(PORT_RWC_BITS | PORT_POWER),
-					&ehci->regs->port_status [wIndex]);
+				ehci_writel(ehci,
+					  temp & ~(PORT_RWC_BITS | PORT_POWER),
+					  &ehci->regs->port_status [wIndex]);
 			break;
 		case USB_PORT_FEAT_C_CONNECTION:
-			writel((temp & ~PORT_RWC_BITS) | PORT_CSC,
-				&ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_CSC,
+				    &ehci->regs->port_status [wIndex]);
 			break;
 		case USB_PORT_FEAT_C_OVER_CURRENT:
-			writel((temp & ~PORT_RWC_BITS) | PORT_OCC,
-				&ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_OCC,
+				    &ehci->regs->port_status [wIndex]);
 			break;
 		case USB_PORT_FEAT_C_RESET:
 			/* GetPortStatus clears reset */
@@ -424,7 +427,7 @@
 		default:
 			goto error;
 		}
-		readl (&ehci->regs->command);	/* unblock posted write */
+		ehci_readl(ehci, &ehci->regs->command);	/* unblock posted write */
 		break;
 	case GetHubDescriptor:
 		ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *)
@@ -440,7 +443,7 @@
 			goto error;
 		wIndex--;
 		status = 0;
-		temp = readl (&ehci->regs->port_status [wIndex]);
+		temp = ehci_readl(ehci, &ehci->regs->port_status [wIndex]);
 
 		// wPortChange bits
 		if (temp & PORT_CSC)
@@ -458,12 +461,14 @@
 			ehci->reset_done [wIndex] = 0;
 
 			/* stop resume signaling */
-			temp = readl (&ehci->regs->port_status [wIndex]);
-			writel (temp & ~(PORT_RWC_BITS | PORT_RESUME),
-				&ehci->regs->port_status [wIndex]);
-			retval = handshake (
-					&ehci->regs->port_status [wIndex],
-					PORT_RESUME, 0, 2000 /* 2msec */);
+			temp = ehci_readl(ehci,
+					  &ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci,
+				    temp & ~(PORT_RWC_BITS | PORT_RESUME),
+				    &ehci->regs->port_status [wIndex]);
+			retval = handshake(ehci,
+					   &ehci->regs->port_status [wIndex],
+					   PORT_RESUME, 0, 2000 /* 2msec */);
 			if (retval != 0) {
 				ehci_err (ehci, "port %d resume error %d\n",
 					wIndex + 1, retval);
@@ -480,13 +485,13 @@
 			ehci->reset_done [wIndex] = 0;
 
 			/* force reset to complete */
-			writel (temp & ~(PORT_RWC_BITS | PORT_RESET),
-					&ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET),
+				    &ehci->regs->port_status [wIndex]);
 			/* REVISIT:  some hardware needs 550+ usec to clear
 			 * this bit; seems too long to spin routinely...
 			 */
-			retval = handshake (
-					&ehci->regs->port_status [wIndex],
+			retval = handshake(ehci,
+					   &ehci->regs->port_status [wIndex],
 					PORT_RESET, 0, 750);
 			if (retval != 0) {
 				ehci_err (ehci, "port %d reset error %d\n",
@@ -496,7 +501,8 @@
 
 			/* see what we found out */
 			temp = check_reset_complete (ehci, wIndex,
-				readl (&ehci->regs->port_status [wIndex]));
+				ehci_readl(ehci,
+					   &ehci->regs->port_status [wIndex]));
 		}
 
 		// don't show wPortStatus if it's owned by a companion hc
@@ -541,7 +547,7 @@
 		if (!wIndex || wIndex > ports)
 			goto error;
 		wIndex--;
-		temp = readl (&ehci->regs->port_status [wIndex]);
+		temp = ehci_readl(ehci, &ehci->regs->port_status [wIndex]);
 		if (temp & PORT_OWNER)
 			break;
 
@@ -555,13 +561,13 @@
 				goto error;
 			if (device_may_wakeup(&hcd->self.root_hub->dev))
 				temp |= PORT_WAKE_BITS;
-			writel (temp | PORT_SUSPEND,
-				&ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, temp | PORT_SUSPEND,
+				    &ehci->regs->port_status [wIndex]);
 			break;
 		case USB_PORT_FEAT_POWER:
 			if (HCS_PPC (ehci->hcs_params))
-				writel (temp | PORT_POWER,
-					&ehci->regs->port_status [wIndex]);
+				ehci_writel(ehci, temp | PORT_POWER,
+					    &ehci->regs->port_status [wIndex]);
 			break;
 		case USB_PORT_FEAT_RESET:
 			if (temp & PORT_RESUME)
@@ -589,7 +595,8 @@
 				ehci->reset_done [wIndex] = jiffies
 						+ msecs_to_jiffies (50);
 			}
-			writel (temp, &ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, temp,
+				    &ehci->regs->port_status [wIndex]);
 			break;
 
 		/* For downstream facing ports (these):  one hub port is put
@@ -604,13 +611,14 @@
 			ehci_quiesce(ehci);
 			ehci_halt(ehci);
 			temp |= selector << 16;
-			writel (temp, &ehci->regs->port_status [wIndex]);
+			ehci_writel(ehci, temp,
+				    &ehci->regs->port_status [wIndex]);
 			break;
 
 		default:
 			goto error;
 		}
-		readl (&ehci->regs->command);	/* unblock posted writes */
+		ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
 		break;
 
 	default:
Index: linux-test-x86/drivers/usb/host/ehci-pci.c
===================================================================
--- linux-test-x86.orig/drivers/usb/host/ehci-pci.c	2006-12-13 13:03:44.000000000 +1100
+++ linux-test-x86/drivers/usb/host/ehci-pci.c	2006-12-13 13:06:02.000000000 +1100
@@ -38,7 +38,7 @@
 		if ((temp & (3 << 13)) == (1 << 13)) {
 			temp &= 0x1fff;
 			ehci->debug = ehci_to_hcd(ehci)->regs + temp;
-			temp = readl(&ehci->debug->control);
+			temp = ehci_readl(ehci, &ehci->debug->control);
 			ehci_info(ehci, "debug port %d%s\n",
 				HCS_DEBUG_PORT(ehci->hcs_params),
 				(temp & DBGP_ENABLED)
@@ -72,7 +72,22 @@
 	int			retval;
 
 	ehci->caps = hcd->regs;
-	ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase));
+	ehci->regs = hcd->regs +
+		HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+	switch (pdev->vendor) {
+	case PCI_VENDOR_ID_TOSHIBA_2:
+		/* celleb's companion chip */
+		if (pdev->device == 0x01b5) {
+#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
+			ehci->big_endian_mmio = 1;
+#else
+			ehci_warn(ehci,
+				  "unsupported big endian Toshiba quirk\n");
+#endif
+		}
+		break;
+	}
+
 	dbg_hcs_params(ehci, "reset");
 	dbg_hcc_params(ehci, "reset");
 
@@ -101,7 +116,7 @@
 	}
 
 	/* cache this readonly data; minimize chip reads */
-	ehci->hcs_params = readl(&ehci->caps->hcs_params);
+	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
 
 	retval = ehci_halt(ehci);
 	if (retval)
@@ -235,8 +250,8 @@
 		rc = -EINVAL;
 		goto bail;
 	}
-	writel (0, &ehci->regs->intr_enable);
-	(void)readl(&ehci->regs->intr_enable);
+	ehci_writel(ehci, 0, &ehci->regs->intr_enable);
+	(void)ehci_readl(ehci, &ehci->regs->intr_enable);
 
 	/* make sure snapshot being resumed re-enumerates everything */
 	if (message.event == PM_EVENT_PRETHAW) {
@@ -270,13 +285,13 @@
 	/* If CF is still set, we maintained PCI Vaux power.
 	 * Just undo the effect of ehci_pci_suspend().
 	 */
-	if (readl(&ehci->regs->configured_flag) == FLAG_CF) {
+	if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) {
 		int	mask = INTR_MASK;
 
 		if (!device_may_wakeup(&hcd->self.root_hub->dev))
 			mask &= ~STS_PCD;
-		writel(mask, &ehci->regs->intr_enable);
-		readl(&ehci->regs->intr_enable);
+		ehci_writel(ehci, mask, &ehci->regs->intr_enable);
+		ehci_readl(ehci, &ehci->regs->intr_enable);
 		return 0;
 	}
 
@@ -300,9 +315,9 @@
 	/* here we "know" root ports should always stay powered */
 	ehci_port_power(ehci, 1);
 
-	writel(ehci->command, &ehci->regs->command);
-	writel(FLAG_CF, &ehci->regs->configured_flag);
-	readl(&ehci->regs->command);	/* unblock posted writes */
+	ehci_writel(ehci, ehci->command, &ehci->regs->command);
+	ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
+	ehci_readl(ehci, &ehci->regs->command);	/* unblock posted writes */
 
 	hcd->state = HC_STATE_SUSPENDED;
 	return 0;
Index: linux-test-x86/drivers/usb/host/ehci-q.c
===================================================================
--- linux-test-x86.orig/drivers/usb/host/ehci-q.c	2006-10-18 09:44:15.000000000 +1000
+++ linux-test-x86/drivers/usb/host/ehci-q.c	2006-12-13 13:06:02.000000000 +1100
@@ -789,13 +789,14 @@
 	head = ehci->async;
 	timer_action_done (ehci, TIMER_ASYNC_OFF);
 	if (!head->qh_next.qh) {
-		u32	cmd = readl (&ehci->regs->command);
+		u32	cmd = ehci_readl(ehci, &ehci->regs->command);
 
 		if (!(cmd & CMD_ASE)) {
 			/* in case a clear of CMD_ASE didn't take yet */
-			(void) handshake (&ehci->regs->status, STS_ASS, 0, 150);
+			(void)handshake(ehci, &ehci->regs->status,
+					STS_ASS, 0, 150);
 			cmd |= CMD_ASE | CMD_RUN;
-			writel (cmd, &ehci->regs->command);
+			ehci_writel(ehci, cmd, &ehci->regs->command);
 			ehci_to_hcd(ehci)->state = HC_STATE_RUNNING;
 			/* posted write need not be known to HC yet ... */
 		}
@@ -1007,7 +1008,7 @@
 
 static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
-	int		cmd = readl (&ehci->regs->command);
+	int		cmd = ehci_readl(ehci, &ehci->regs->command);
 	struct ehci_qh	*prev;
 
 #ifdef DEBUG
@@ -1025,7 +1026,8 @@
 		if (ehci_to_hcd(ehci)->state != HC_STATE_HALT
 				&& !ehci->reclaim) {
 			/* ... and CMD_IAAD clear */
-			writel (cmd & ~CMD_ASE, &ehci->regs->command);
+			ehci_writel(ehci, cmd & ~CMD_ASE,
+				    &ehci->regs->command);
 			wmb ();
 			// handshake later, if we need to
 			timer_action_done (ehci, TIMER_ASYNC_OFF);
@@ -1054,8 +1056,8 @@
 
 	ehci->reclaim_ready = 0;
 	cmd |= CMD_IAAD;
-	writel (cmd, &ehci->regs->command);
-	(void) readl (&ehci->regs->command);
+	ehci_writel(ehci, cmd, &ehci->regs->command);
+	(void)ehci_readl(ehci, &ehci->regs->command);
 	timer_action (ehci, TIMER_IAA_WATCHDOG);
 }
 
Index: linux-test-x86/drivers/usb/host/ehci-sched.c
===================================================================
--- linux-test-x86.orig/drivers/usb/host/ehci-sched.c	2006-10-06 21:44:38.000000000 +1000
+++ linux-test-x86/drivers/usb/host/ehci-sched.c	2006-12-13 13:06:02.000000000 +1100
@@ -433,20 +433,20 @@
 	/* did clearing PSE did take effect yet?
 	 * takes effect only at frame boundaries...
 	 */
-	status = handshake (&ehci->regs->status, STS_PSS, 0, 9 * 125);
+	status = handshake(ehci, &ehci->regs->status, STS_PSS, 0, 9 * 125);
 	if (status != 0) {
 		ehci_to_hcd(ehci)->state = HC_STATE_HALT;
 		return status;
 	}
 
-	cmd = readl (&ehci->regs->command) | CMD_PSE;
-	writel (cmd, &ehci->regs->command);
+	cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE;
+	ehci_writel(ehci, cmd, &ehci->regs->command);
 	/* posted write ... PSS happens later */
 	ehci_to_hcd(ehci)->state = HC_STATE_RUNNING;
 
 	/* make sure ehci_work scans these */
-	ehci->next_uframe = readl (&ehci->regs->frame_index)
-				% (ehci->periodic_size << 3);
+	ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index)
+		% (ehci->periodic_size << 3);
 	return 0;
 }
 
@@ -458,14 +458,14 @@
 	/* did setting PSE not take effect yet?
 	 * takes effect only at frame boundaries...
 	 */
-	status = handshake (&ehci->regs->status, STS_PSS, STS_PSS, 9 * 125);
+	status = handshake(ehci, &ehci->regs->status, STS_PSS, STS_PSS, 9 * 125);
 	if (status != 0) {
 		ehci_to_hcd(ehci)->state = HC_STATE_HALT;
 		return status;
 	}
 
-	cmd = readl (&ehci->regs->command) & ~CMD_PSE;
-	writel (cmd, &ehci->regs->command);
+	cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE;
+	ehci_writel(ehci, cmd, &ehci->regs->command);
 	/* posted write ... */
 
 	ehci->next_uframe = -1;
@@ -1336,7 +1336,7 @@
 		goto fail;
 	}
 
-	now = readl (&ehci->regs->frame_index) % mod;
+	now = ehci_readl(ehci, &ehci->regs->frame_index) % mod;
 
 	/* when's the last uframe this urb could start? */
 	max = now + mod;
@@ -2088,7 +2088,7 @@
 	 */
 	now_uframe = ehci->next_uframe;
 	if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
-		clock = readl (&ehci->regs->frame_index);
+		clock = ehci_readl(ehci, &ehci->regs->frame_index);
 	else
 		clock = now_uframe + mod - 1;
 	clock %= mod;
@@ -2213,7 +2213,7 @@
 			if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
 				break;
 			ehci->next_uframe = now_uframe;
-			now = readl (&ehci->regs->frame_index) % mod;
+			now = ehci_readl(ehci, &ehci->regs->frame_index) % mod;
 			if (now_uframe == now)
 				break;
 
Index: linux-test-x86/drivers/usb/host/ehci.h
===================================================================
--- linux-test-x86.orig/drivers/usb/host/ehci.h	2006-12-13 13:03:44.000000000 +1100
+++ linux-test-x86/drivers/usb/host/ehci.h	2006-12-13 13:06:02.000000000 +1100
@@ -92,6 +92,7 @@
 	unsigned		is_tdi_rh_tt:1;	/* TDI roothub with TT */
 	unsigned		no_selective_suspend:1;
 	unsigned		has_fsl_port_bug:1; /* FreeScale */
+	unsigned		big_endian_mmio:1;
 
 	u8			sbrn;		/* packed release number */
 
@@ -651,6 +652,37 @@
 #define	ehci_has_fsl_portno_bug(e)		(0)
 #endif
 
+/*
+ * While most USB host controllers implement their registers in
+ * little-endian format, a minority (celleb companion chip) implement
+ * them in big endian format.
+ *
+ * This attempts to support either format at compile time without a
+ * runtime penalty, or both formats with the additional overhead
+ * of checking a flag bit.
+ */
+
+#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
+#define ehci_big_endian_mmio(e)		((e)->big_endian_mmio)
+#else
+#define ehci_big_endian_mmio(e)		0
+#endif
+
+static inline unsigned int ehci_readl (const struct ehci_hcd *ehci,
+				       __u32 __iomem * regs)
+{
+	return ehci_big_endian_mmio(ehci) ?
+		readl_be((__force u32 *)regs) :
+		readl((__force u32 *)regs);
+}
+
+static inline void ehci_writel (const struct ehci_hcd *ehci,
+				const unsigned int val, __u32 __iomem *regs)
+{
+	ehci_big_endian_mmio(ehci) ?
+		writel_be(val, (__force u32 *)regs) :
+		writel(val, (__force u32 *)regs);
+}
 
 /*-------------------------------------------------------------------------*/
 

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
linux-usb-devel at lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
linux-2.6-usb-endian-quirks.patch:
 ohci-pci.c |  173 ++++++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 110 insertions(+), 63 deletions(-)

--- NEW FILE linux-2.6-usb-endian-quirks.patch ---
This patch applies David Brownell's suggestion for reworking the
OHCI quirk mechanism via a table of PCI IDs. It adapts the existing
quirks to use that mechanism.

This also moves the quirks to reset() as suggested by the comment
in there. This is necessary as we need to have the endian properly
set before we try to init the controller.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
Acked-by: David Brownell <dbrownell at users.sourceforge.net>

 drivers/usb/host/ohci-pci.c |  173 +++++++++++++++++++++++++++-----------------
 1 file changed, 110 insertions(+), 63 deletions(-)

diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 8744185..dab43bb 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -20,79 +20,128 @@
 
 /*-------------------------------------------------------------------------*/
 
-static int
-ohci_pci_reset (struct usb_hcd *hcd)
+/* AMD 756, for most chips (early revs), corrupts register
+ * values on read ... so enable the vendor workaround.
+ */
+static int __devinit ohci_quirk_amd756(struct usb_hcd *hcd)
 {
 	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
 
-	ohci_hcd_init (ohci);
-	return ohci_init (ohci);
+	ohci->flags = OHCI_QUIRK_AMD756;
+	ohci_dbg (ohci, "AMD756 erratum 4 workaround\n");
+
+	/* also erratum 10 (suspend/resume issues) */
+	device_init_wakeup(&hcd->self.root_hub->dev, 0);
+
+	return 0;
 }
 
-static int __devinit
-ohci_pci_start (struct usb_hcd *hcd)
+/* Apple's OHCI driver has a lot of bizarre workarounds
+ * for this chip.  Evidently control and bulk lists
+ * can get confused.  (B&W G3 models, and ...)
+ */
+static int __devinit ohci_quirk_opti(struct usb_hcd *hcd)
 {
 	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
-	int		ret;
 
-	/* REVISIT this whole block should move to reset(), which handles
-	 * all the other one-time init.
+	ohci_dbg (ohci, "WARNING: OPTi workarounds unavailable\n");
+
+	return 0;
+}
+
+/* Check for NSC87560. We have to look at the bridge (fn1) to
+ * identify the USB (fn2). This quirk might apply to more or
+ * even all NSC stuff.
+ */
+static int __devinit ohci_quirk_ns(struct usb_hcd *hcd)
+{
+	struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+	struct pci_dev	*b;
+
+	b  = pci_get_slot (pdev->bus, PCI_DEVFN (PCI_SLOT (pdev->devfn), 1));
+	if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO
+	    && b->vendor == PCI_VENDOR_ID_NS) {
+		struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
+
+		ohci->flags |= OHCI_QUIRK_SUPERIO;
+		ohci_dbg (ohci, "Using NSC SuperIO setup\n");
+	}
+	pci_dev_put(b);
+
+	return 0;
+}
+
+/* Check for Compaq's ZFMicro chipset, which needs short
+ * delays before control or bulk queues get re-activated
+ * in finish_unlinks()
+ */
+static int __devinit ohci_quirk_zfmicro(struct usb_hcd *hcd)
+{
+	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
+
+	ohci->flags |= OHCI_QUIRK_ZFMICRO;
+	ohci_dbg (ohci, "enabled Compaq ZFMicro chipset quirk\n");
+
+	return 0;
+}
+
+
+/* List of quirks for OHCI */
+static const struct pci_device_id ohci_pci_quirks[] = {
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x740c),
+		.driver_data = (unsigned long)ohci_quirk_amd756,
+	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_OPTI, 0xc861),
+		.driver_data = (unsigned long)ohci_quirk_opti,
+	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_ANY_ID),
+		.driver_data = (unsigned long)ohci_quirk_ns,
+	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xa0f8),
+		.driver_data = (unsigned long)ohci_quirk_zfmicro,
+	},
+	/* FIXME for some of the early AMD 760 southbridges, OHCI
+	 * won't work at all.  blacklist them.
 	 */
+	{},
+};
+
+static int ohci_pci_reset (struct usb_hcd *hcd)
+{
+	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
+	int ret = 0;
+
 	if (hcd->self.controller) {
 		struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+		const struct pci_device_id *quirk_id;
 
-		/* AMD 756, for most chips (early revs), corrupts register
-		 * values on read ... so enable the vendor workaround.
-		 */
-		if (pdev->vendor == PCI_VENDOR_ID_AMD
-				&& pdev->device == 0x740c) {
-			ohci->flags = OHCI_QUIRK_AMD756;
-			ohci_dbg (ohci, "AMD756 erratum 4 workaround\n");
-			/* also erratum 10 (suspend/resume issues) */
-			device_init_wakeup(&hcd->self.root_hub->dev, 0);
+		quirk_id = pci_match_id(ohci_pci_quirks, pdev);
+		if (quirk_id != NULL) {
+			int (*quirk)(struct usb_hcd *ohci);
+			quirk = (void *)quirk_id->driver_data;
+			ret = quirk(hcd);
 		}
+	}
+	if (ret == 0) {
+		ohci_hcd_init (ohci);
+		return ohci_init (ohci);
+	}
+	return ret;
+}
 
-		/* FIXME for some of the early AMD 760 southbridges, OHCI
-		 * won't work at all.  blacklist them.
-		 */
-
-		/* Apple's OHCI driver has a lot of bizarre workarounds
-		 * for this chip.  Evidently control and bulk lists
-		 * can get confused.  (B&W G3 models, and ...)
-		 */
-		else if (pdev->vendor == PCI_VENDOR_ID_OPTI
-				&& pdev->device == 0xc861) {
-			ohci_dbg (ohci,
-				"WARNING: OPTi workarounds unavailable\n");
-		}
 
-		/* Check for NSC87560. We have to look at the bridge (fn1) to
-		 * identify the USB (fn2). This quirk might apply to more or
-		 * even all NSC stuff.
-		 */
-		else if (pdev->vendor == PCI_VENDOR_ID_NS) {
-			struct pci_dev	*b;
-
-			b  = pci_get_slot (pdev->bus,
-					PCI_DEVFN (PCI_SLOT (pdev->devfn), 1));
-			if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO
-					&& b->vendor == PCI_VENDOR_ID_NS) {
-				ohci->flags |= OHCI_QUIRK_SUPERIO;
-				ohci_dbg (ohci, "Using NSC SuperIO setup\n");
-			}
-			pci_dev_put(b);
-		}
+static int __devinit ohci_pci_start (struct usb_hcd *hcd)
+{
+	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
+	int		ret;
 
-		/* Check for Compaq's ZFMicro chipset, which needs short 
-		 * delays before control or bulk queues get re-activated
-		 * in finish_unlinks()
-		 */
-		else if (pdev->vendor == PCI_VENDOR_ID_COMPAQ
-				&& pdev->device  == 0xa0f8) {
-			ohci->flags |= OHCI_QUIRK_ZFMICRO;
-			ohci_dbg (ohci,
-				"enabled Compaq ZFMicro chipset quirk\n");
-		}
+#ifdef CONFIG_PM /* avoid warnings about unused pdev */
+	if (hcd->self.controller) {
+		struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
 
 		/* RWC may not be set for add-in PCI cards, since boot
 		 * firmware probably ignored them.  This transfers PCI
@@ -101,16 +150,14 @@ ohci_pci_start (struct usb_hcd *hcd)
 		if (device_may_wakeup(&pdev->dev))
 			ohci->hc_control |= OHCI_CTRL_RWC;
 	}
+#endif /* CONFIG_PM */
 
-	/* NOTE: there may have already been a first reset, to
-	 * keep bios/smm irqs from making trouble
-	 */
-	if ((ret = ohci_run (ohci)) < 0) {
+	ret = ohci_run (ohci);
+	if (ret < 0) {
 		ohci_err (ohci, "can't start\n");
 		ohci_stop (hcd);
-		return ret;
 	}
-	return 0;
+	return ret;
 }
 
 #ifdef	CONFIG_PM

linux-2.6-usb-endian-toshiba.patch:
 Kconfig        |   10 +++
 ohci-pci.c     |   26 ++++++++++
 ohci-ppc-soc.c |    2 
 ohci.h         |  147 ++++++++++++++++++++++++++++++++++++---------------------
 4 files changed, 130 insertions(+), 55 deletions(-)

--- NEW FILE linux-2.6-usb-endian-toshiba.patch ---
This patch separates support for big endian MMIO register access
and big endian descriptors in order to support the Toshiba SCC
implementation which has big endian registers but little endian
in-memory descriptors.

It simplifies the access functions a bit in ohci.h while at it.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
Acked-by: David Brownell <dbrownell at users.sourceforge.net>

 drivers/usb/host/Kconfig        |   10 ++
 drivers/usb/host/ohci-pci.c     |   26 +++++++
 drivers/usb/host/ohci-ppc-soc.c |    2 
 drivers/usb/host/ohci.h         |  147 +++++++++++++++++++++++++---------------
 4 files changed, 130 insertions(+), 55 deletions(-)

Index: linux-test-x86/drivers/usb/host/ohci-pci.c
===================================================================
--- linux-test-x86.orig/drivers/usb/host/ohci-pci.c	2006-12-13 12:58:58.000000000 +1100
+++ linux-test-x86/drivers/usb/host/ohci-pci.c	2006-12-13 12:59:31.000000000 +1100
@@ -85,6 +85,27 @@
 	return 0;
 }
 
+/* Check for Toshiba SCC OHCI which has big endian registers
+ * and little endian in memory data structures
+ */
+static int __devinit ohci_quirk_toshiba_scc(struct usb_hcd *hcd)
+{
+	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);
+
+	/* That chip is only present in the southbridge of some
+	 * cell based platforms which are supposed to select
+	 * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO. We verify here if
+	 * that was the case though.
+	 */
+#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO
+	ohci->flags |= OHCI_QUIRK_BE_MMIO;
+	ohci_dbg (ohci, "enabled big endian Toshiba quirk\n");
+	return 0;
+#else
+	ohci_err (ohci, "unsupported big endian Toshiba quirk\n");
+	return -ENXIO;
+#endif
+}
 
 /* List of quirks for OHCI */
 static const struct pci_device_id ohci_pci_quirks[] = {
@@ -104,9 +125,14 @@
 		PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xa0f8),
 		.driver_data = (unsigned long)ohci_quirk_zfmicro,
 	},
+	{
+		PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, 0x01b6),
+		.driver_data = (unsigned long)ohci_quirk_toshiba_scc,
+	},
 	/* FIXME for some of the early AMD 760 southbridges, OHCI
 	 * won't work at all.  blacklist them.
 	 */
+
 	{},
 };
 
Index: linux-test-x86/drivers/usb/host/ohci-ppc-soc.c
===================================================================
--- linux-test-x86.orig/drivers/usb/host/ohci-ppc-soc.c	2006-12-13 12:56:27.000000000 +1100
+++ linux-test-x86/drivers/usb/host/ohci-ppc-soc.c	2006-12-13 12:59:31.000000000 +1100
@@ -72,7 +72,7 @@
 	}
 
 	ohci = hcd_to_ohci(hcd);
-	ohci->flags |= OHCI_BIG_ENDIAN;
+	ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC;
 	ohci_hcd_init(ohci);
 
 	retval = usb_add_hcd(hcd, irq, IRQF_DISABLED);
Index: linux-test-x86/drivers/usb/host/Kconfig
===================================================================
--- linux-test-x86.orig/drivers/usb/host/Kconfig	2006-12-13 12:39:48.000000000 +1100
+++ linux-test-x86/drivers/usb/host/Kconfig	2006-12-13 12:59:31.000000000 +1100
@@ -101,7 +101,8 @@
 	bool "OHCI support for on-chip PPC USB controller"
 	depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
 	default y
-	select USB_OHCI_BIG_ENDIAN
+	select USB_OHCI_BIG_ENDIAN_DESC
+	select USB_OHCI_BIG_ENDIAN_MMIO
 	---help---
 	  Enables support for the USB controller on the MPC52xx or
 	  STB03xxx processor chip.  If unsure, say Y.
@@ -115,7 +116,12 @@
 	  Enables support for PCI-bus plug-in USB controller cards.
 	  If unsure, say Y.
 
-config USB_OHCI_BIG_ENDIAN
+config USB_OHCI_BIG_ENDIAN_DESC
+	bool
+	depends on USB_OHCI_HCD
+	default n
+
+config USB_OHCI_BIG_ENDIAN_MMIO
 	bool
 	depends on USB_OHCI_HCD
 	default n
Index: linux-test-x86/drivers/usb/host/ohci.h
===================================================================
--- linux-test-x86.orig/drivers/usb/host/ohci.h	2006-12-13 12:56:27.000000000 +1100
+++ linux-test-x86/drivers/usb/host/ohci.h	2006-12-13 13:01:29.000000000 +1100
@@ -394,8 +394,9 @@
 #define	OHCI_QUIRK_AMD756	0x01			/* erratum #4 */
 #define	OHCI_QUIRK_SUPERIO	0x02			/* natsemi */
 #define	OHCI_QUIRK_INITRESET	0x04			/* SiS, OPTi, ... */
-#define	OHCI_BIG_ENDIAN		0x08			/* big endian HC */
-#define	OHCI_QUIRK_ZFMICRO	0x10			/* Compaq ZFMicro chipset*/
+#define	OHCI_QUIRK_BE_DESC	0x08			/* BE descriptors */
+#define	OHCI_QUIRK_BE_MMIO	0x10			/* BE registers */
+#define	OHCI_QUIRK_ZFMICRO	0x20			/* Compaq ZFMicro chipset*/
 	// there are also chip quirks/bugs in init logic
 
 };
@@ -439,117 +440,156 @@
  * a minority (notably the IBM STB04XXX and the Motorola MPC5200
  * processors) implement them in big endian format.
  *
+ * In addition some more exotic implementations like the Toshiba
+ * Spider (aka SCC) cell southbridge are "mixed" endian, that is,
+ * they have a different endianness for registers vs. in-memory
+ * descriptors.
+ *
  * This attempts to support either format at compile time without a
  * runtime penalty, or both formats with the additional overhead
  * of checking a flag bit.
+ *
+ * That leads to some tricky Kconfig rules howevber. There are
+ * different defaults based on some arch/ppc platforms, though
+ * the basic rules are:
+ *
+ * Controller type              Kconfig options needed
+ * ---------------              ----------------------
+ * little endian                CONFIG_USB_OHCI_LITTLE_ENDIAN
+ *
+ * fully big endian             CONFIG_USB_OHCI_BIG_ENDIAN_DESC _and_
+ *                              CONFIG_USB_OHCI_BIG_ENDIAN_MMIO
+ *
+ * mixed endian                 CONFIG_USB_OHCI_LITTLE_ENDIAN _and_
+ *                              CONFIG_USB_OHCI_BIG_ENDIAN_{MMIO,DESC}
+ *
+ * (If you have a mixed endian controller, you -must- also define
+ * CONFIG_USB_OHCI_LITTLE_ENDIAN or things will not work when building
+ * both your mixed endian and a fully big endian controller support in
+ * the same kernel image).
  */
 
-#ifdef CONFIG_USB_OHCI_BIG_ENDIAN
+#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_DESC
+#ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN
+#define big_endian_desc(ohci)	(ohci->flags & OHCI_QUIRK_BE_DESC)
+#else
+#define big_endian_desc(ohci)	1		/* only big endian */
+#endif
+#else
+#define big_endian_desc(ohci)	0		/* only little endian */
+#endif
 
+#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO
 #ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN
-#define big_endian(ohci)	(ohci->flags & OHCI_BIG_ENDIAN) /* either */
+#define big_endian_mmio(ohci)	(ohci->flags & OHCI_QUIRK_BE_MMIO)
+#else
+#define big_endian_mmio(ohci)	1		/* only big endian */
+#endif
 #else
-#define big_endian(ohci)	1		/* only big endian */
+#define big_endian_mmio(ohci)	0		/* only little endian */
 #endif
 
 /*
  * Big-endian read/write functions are arch-specific.
  * Other arches can be added if/when they're needed.
+ *
+ * REVISIT: arch/powerpc now has readl/writel_be, so the
+ * definition below can die once the STB04xxx support is
+ * finally ported over.
  */
-#if defined(CONFIG_PPC)
+#if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE)
 #define readl_be(addr)		in_be32((__force unsigned *)addr)
 #define writel_be(val, addr)	out_be32((__force unsigned *)addr, val)
 #endif
 
-static inline unsigned int ohci_readl (const struct ohci_hcd *ohci,
-							__hc32 __iomem * regs)
+static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci,
+					__hc32 __iomem * regs)
 {
-	return big_endian(ohci) ? readl_be (regs) : readl ((__force u32 *)regs);
+	return big_endian_mmio(ohci) ?
+		readl_be ((__force u32 *)regs) :
+		readl ((__force u32 *)regs);
 }
 
-static inline void ohci_writel (const struct ohci_hcd *ohci,
-				const unsigned int val, __hc32 __iomem *regs)
+static inline void _ohci_writel (const struct ohci_hcd *ohci,
+				 const unsigned int val, __hc32 __iomem *regs)
 {
-	big_endian(ohci) ? writel_be (val, regs) :
-			   writel (val, (__force u32 *)regs);
+	big_endian_mmio(ohci) ?
+		writel_be (val, (__force u32 *)regs) :
+		writel (val, (__force u32 *)regs);
 }
 
-#else	/* !CONFIG_USB_OHCI_BIG_ENDIAN */
-
-#define big_endian(ohci)	0		/* only little endian */
-
 #ifdef CONFIG_ARCH_LH7A404
-	/* Marc Singer: at the time this code was written, the LH7A404
-	 * had a problem reading the USB host registers.  This
-	 * implementation of the ohci_readl function performs the read
-	 * twice as a work-around.
-	 */
-static inline unsigned int
-ohci_readl (const struct ohci_hcd *ohci, const __hc32 *regs)
-{
-	*(volatile __force unsigned int*) regs;
-	return *(volatile __force unsigned int*) regs;
-}
+/* Marc Singer: at the time this code was written, the LH7A404
+ * had a problem reading the USB host registers.  This
+ * implementation of the ohci_readl function performs the read
+ * twice as a work-around.
+ */
+#define ohci_readl(o,r)		(_ohci_readl(o,r),_ohci_readl(o,r))
+#define ohci_writel(o,v,r)	_ohci_writel(o,v,r)
 #else
-	/* Standard version of ohci_readl uses standard, platform
-	 * specific implementation. */
-static inline unsigned int
-ohci_readl (const struct ohci_hcd *ohci, __hc32 __iomem * regs)
-{
-	return readl(regs);
-}
+#define ohci_readl(o,r)		_ohci_readl(o,r)
+#define ohci_writel(o,v,r)	_ohci_writel(o,v,r)
 #endif
 
-static inline void ohci_writel (const struct ohci_hcd *ohci,
-				const unsigned int val, __hc32 __iomem *regs)
-{
-	writel (val, regs);
-}
-
-#endif	/* !CONFIG_USB_OHCI_BIG_ENDIAN */
 
 /*-------------------------------------------------------------------------*/
 
 /* cpu to ohci */
 static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x)
 {
-	return big_endian(ohci) ? (__force __hc16)cpu_to_be16(x) : (__force __hc16)cpu_to_le16(x);
+	return big_endian_desc(ohci) ?
+		(__force __hc16)cpu_to_be16(x) :
+		(__force __hc16)cpu_to_le16(x);
 }
 
 static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x)
 {
-	return big_endian(ohci) ? cpu_to_be16p(x) : cpu_to_le16p(x);
+	return big_endian_desc(ohci) ?
+		cpu_to_be16p(x) :
+		cpu_to_le16p(x);
 }
 
 static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x)
 {
-	return big_endian(ohci) ? (__force __hc32)cpu_to_be32(x) : (__force __hc32)cpu_to_le32(x);
+	return big_endian_desc(ohci) ?
+		(__force __hc32)cpu_to_be32(x) :
+		(__force __hc32)cpu_to_le32(x);
 }
 
 static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x)
 {
-	return big_endian(ohci) ? cpu_to_be32p(x) : cpu_to_le32p(x);
+	return big_endian_desc(ohci) ?
+		cpu_to_be32p(x) :
+		cpu_to_le32p(x);
 }
 
 /* ohci to cpu */
 static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x)
 {
-	return big_endian(ohci) ? be16_to_cpu((__force __be16)x) : le16_to_cpu((__force __le16)x);
+	return big_endian_desc(ohci) ?
+		be16_to_cpu((__force __be16)x) :
+		le16_to_cpu((__force __le16)x);
 }
 
 static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x)
 {
-	return big_endian(ohci) ? be16_to_cpup((__force __be16 *)x) : le16_to_cpup((__force __le16 *)x);
+	return big_endian_desc(ohci) ?
+		be16_to_cpup((__force __be16 *)x) :
+		le16_to_cpup((__force __le16 *)x);
 }
 
 static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x)
 {
-	return big_endian(ohci) ? be32_to_cpu((__force __be32)x) : le32_to_cpu((__force __le32)x);
+	return big_endian_desc(ohci) ?
+		be32_to_cpu((__force __be32)x) :
+		le32_to_cpu((__force __le32)x);
 }
 
 static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x)
 {
-	return big_endian(ohci) ? be32_to_cpup((__force __be32 *)x) : le32_to_cpup((__force __le32 *)x);
+	return big_endian_desc(ohci) ?
+		be32_to_cpup((__force __be32 *)x) :
+		le32_to_cpup((__force __le32 *)x);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -557,6 +597,9 @@
 /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all
  * hardware handles 16 bit reads.  That creates a different confusion on
  * some big-endian SOC implementations.  Same thing happens with PSW access.
+ *
+ * FIXME: Deal with that as a runtime quirk when STB03xxx is ported over
+ * to arch/powerpc
  */
 
 #ifdef CONFIG_STB03xxx
@@ -568,7 +611,7 @@
 static inline u16 ohci_frame_no(const struct ohci_hcd *ohci)
 {
 	u32 tmp;
-	if (big_endian(ohci)) {
+	if (big_endian_desc(ohci)) {
 		tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no);
 		tmp >>= OHCI_BE_FRAME_NO_SHIFT;
 	} else
@@ -580,7 +623,7 @@
 static inline __hc16 *ohci_hwPSWp(const struct ohci_hcd *ohci,
                                  const struct td *td, int index)
 {
-	return (__hc16 *)(big_endian(ohci) ?
+	return (__hc16 *)(big_endian_desc(ohci) ?
 			&td->hwPSW[index ^ 1] : &td->hwPSW[index]);
 }
 

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
linux-usb-devel at lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Index: kernel-2.6.spec
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/kernel-2.6.spec,v
retrieving revision 1.2881
retrieving revision 1.2882
diff -u -r1.2881 -r1.2882
--- kernel-2.6.spec	17 Dec 2006 17:29:06 -0000	1.2881
+++ kernel-2.6.spec	17 Dec 2006 21:55:32 -0000	1.2882
@@ -319,6 +319,9 @@
 Patch302: linux-2.6-systemsim-work.patch
 Patch303: linux-2.6-ppc32-ucmpdi2.patch
 Patch304: linux-2.6-of_platform-uevent.patch
+Patch305: linux-2.6-usb-endian-quirks.patch
+Patch306: linux-2.6-usb-endian-toshiba.patch
+Patch307: linux-2.6-usb-endian-ehci.patch
 Patch310: linux-2.6-g5-therm-shutdown.patch
 # Efika support
 Patch311: linux-2.6-ohci-multi-init.patch
@@ -702,10 +705,10 @@
   cd kernel-%{kversion}
   if [ -d linux-%{kversion}.%{_target_cpu} ]; then
      # Just in case we ctrl-c'd a prep already
-     rm -rf deleteme
+     rm -rf deleteme.%{_target_cpu}
      # Move away the stale away, and delete in background.
-     mv linux-%{kversion}.%{_target_cpu} deleteme
-     rm -rf deleteme &
+     mv linux-%{kversion}.%{_target_cpu} deleteme.%{_target_cpu}
+     rm -rf deleteme.%{_target_cpu} &
   fi
 fi
 cp -rl vanilla linux-%{kversion}.%{_target_cpu}
@@ -752,6 +755,10 @@
 %patch303 -p1
 # uevent support for of_platform device
 %patch304 -p1
+# Big-endian USB support (Celleb, PS3)
+%patch305 -p1
+%patch306 -p1
+%patch307 -p1
 # Alleviate G5 thermal shutdown problems
 %patch310 -p1
 # OHCI bus glue rework to allow several at once
@@ -1030,7 +1037,7 @@
 # when find traverses into directories that get deleted.
 # So we serialise until the dir has gone away.
 cd ..
-while [ -d deleteme ];
+while [ -d deleteme.%{_target_cpu} ];
 do
 	sleep 1
 done

linux-2.6-ohci-platform-bus.patch:
 Kconfig       |   23 +++++
 ohci-hcd.c    |   20 +++++
 ohci-ppc-of.c |  232 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 274 insertions(+), 1 deletion(-)

Index: linux-2.6-ohci-platform-bus.patch
===================================================================
RCS file: /cvs/dist/rpms/kernel/devel/linux-2.6-ohci-platform-bus.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- linux-2.6-ohci-platform-bus.patch	17 Dec 2006 17:29:07 -0000	1.1
+++ linux-2.6-ohci-platform-bus.patch	17 Dec 2006 21:55:32 -0000	1.2
@@ -248,7 +248,7 @@
 +
 +	ohci = hcd_to_ohci(hcd);
 +	if (is_bigendian)
-+		ohci->flags |= OHCI_BIG_ENDIAN;
++		ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC;
 +
 +	ohci_hcd_init(ohci);
 +




More information about the fedora-cvs-commits mailing list