ASMedia xhci controller errors

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In order to get an ASMedia xhci controller to even detect a device
being inserted I had to split the writeq() and readq().
The following patch is sufficient on amd64.

I've not yet tried to make the ax88179 card work.

	David

[PATCH] xhci: Do not use 64bit accesses to the controller registers

Some controllers (eg ASMedia) do not support 64 bit accesses to
their internal registers even though they are 64bit capable.

32bit transfers in the correct order.

Signed-off-by: David Laight <david.laight@xxxxxxxxxx>
---
 drivers/usb/host/xhci.h | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index f8416639..ee893e6 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1614,6 +1616,44 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci)
 #define xhci_warn_ratelimited(xhci, fmt, args...) \
 	dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
 
+/*
+ * Registers should always be accessed with double word or quad word accesses.
+ *
+ * Some xHCI implementations may support 64-bit address pointers.  Registers
+ * with 64-bit address pointers should be written to with dword accesses by
+ * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second.
+ * xHCI implementations that do not support 64-bit address pointers will ignore
+ * the high dword, and write order is irrelevant.
+ *
+ * Some 64bit capable controllers (eg ASMedia) do not support 64bit accesses
+ * to their own registers.
+ */
+static inline void xhci_write_64(const u64 val, __le64 __iomem *regs)
+{
+	__u32 __iomem *ptr = (__u32 __iomem *) regs;
+	u32 val_lo = lower_32_bits(val);
+	u32 val_hi = upper_32_bits(val);
+
+	writel(val_lo, ptr);
+	writel(val_hi, ptr + 1);
+}
+#define writeq writeq
+#undef writeq
+#define writeq(v, p) xhci_write_64(v, p)
+
+static inline u64 xhci_read_64(__le64 __iomem *regs)
+{
+	__u32 __iomem *ptr = (__u32 __iomem *) regs;
+	u32 val_lo = readl(ptr);
+	u32 val_hi = readl(ptr + 1);
+
+	return (u64)val_hi << 32 | val_lo;
+}
+#define readq readq
+#undef readq
+#define readq(p) xhci_read_64(p)
+
+
 static inline int xhci_link_trb_quirk(struct xhci_hcd *xhci)
 {
 	return xhci->quirks & XHCI_LINK_TRB_QUIRK;
-- 
1.8.1.2



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux