public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Roland Dreier <roland@topspin.com>
To: Paul Mackerras <paulus@samba.org>
Cc: Linus Torvalds <torvalds@osdl.org>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Alan Cox <alan@lxorguk.ukuu.org.uk>,
	Andrew Morton <akpm@osdl.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Petr Vandrovec <vandrove@vc.cvut.cz>
Subject: Re: [PATCH] ppc64: Fix __raw_* IO accessors
Date: Wed, 22 Sep 2004 00:36:34 -0700	[thread overview]
Message-ID: <52hdpqoiv1.fsf@topspin.com> (raw)
In-Reply-To: <16720.57400.930844.91232@cargo.ozlabs.ibm.com> (Paul Mackerras's message of "Tue, 21 Sep 2004 21:15:20 -0500")

    Paul> I believe this was done so that we could quickly work out
    Paul> the pci bus/device/function inside read/write[bwl].  We
    Paul> needed that for coping with the "Enhanced Error Handling"
    Paul> (EEH) stuff on pSeries machines.  I think we used to stuff
    Paul> the pci bus/dev/fn in the high bits and then change the top
    Paul> 4 bits to make quite clear that it wasn't a valid pointer.
    Paul> These days we don't put the pci bus/dev/fn in the high bits
    Paul> and we could certainly get rid of the IO_TOKEN_TO_ADDR
    Paul> games.

Here's a patch that gets rid of IO_TOKEN_TO_ADDR.  It's lightly tested
on my p630 (boots fine and my InfiniBand driver works well).

Thanks,
  Roland


Get rid of IO_TOKEN_TO_ADDR() and IO_ADDR_TO_TOKEN() for pSeries EEH;
the conversion to tokens is not needed now that we have __iomem
annotations to prevent drivers from dereferencing IO addresses.

Signed-off-by: Roland Dreier <roland@topspin.com>

Index: linux-bk/arch/ppc64/kernel/eeh.c
===================================================================
--- linux-bk.orig/arch/ppc64/kernel/eeh.c	2004-09-21 14:55:33.000000000 -0700
+++ linux-bk/arch/ppc64/kernel/eeh.c	2004-09-22 00:14:25.000000000 -0700
@@ -335,26 +335,19 @@
 
 /**
  * eeh_token_to_phys - convert EEH address token to phys address
- * @token i/o token, should be address in the form 0xA....
- *
- * Converts EEH address tokens into physical addresses.  Note that
- * ths routine does *not* convert I/O BAR addresses (which start
- * with 0xE...) to phys addresses!
+ * @token i/o token, should be address in the form 0xE....
  */
 static inline unsigned long eeh_token_to_phys(unsigned long token)
 {
 	pte_t *ptep;
-	unsigned long pa, vaddr;
+	unsigned long pa;
 
-	if (REGION_ID(token) == EEH_REGION_ID)
-		vaddr = IO_TOKEN_TO_ADDR(token);
-	else
+	ptep = find_linux_pte(ioremap_mm.pgd, token);
+	if (!ptep)
 		return token;
-
-	ptep = find_linux_pte(ioremap_mm.pgd, vaddr);
 	pa = pte_pfn(*ptep) << PAGE_SHIFT;
 
-	return pa | (vaddr & (PAGE_SIZE-1));
+	return pa | (token & (PAGE_SIZE-1));
 }
 
 /**
@@ -473,7 +466,7 @@
 	struct device_node *dn;
 
 	/* Finding the phys addr + pci device; this is pretty quick. */
-	addr = eeh_token_to_phys((unsigned long)token);
+	addr = eeh_token_to_phys((unsigned long __force) token);
 	dev = pci_get_device_by_addr(addr);
 	if (!dev)
 		return val;
@@ -750,15 +743,15 @@
  */
 void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
 {
-	_insb((void *) IO_TOKEN_TO_ADDR(addr), dst, count);
+	_insb((u8 __force *) addr, dst, count);
 }
 void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
 {
-	_insw_ns((void *) IO_TOKEN_TO_ADDR(addr), dst, count);
+	_insw_ns((u16 __force *) addr, dst, count);
 }
 void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
 {
-	_insl_ns((void *) IO_TOKEN_TO_ADDR(addr), dst, count);
+	_insl_ns((u32 __force *) addr, dst, count);
 }
 EXPORT_SYMBOL(ioread8_rep);
 EXPORT_SYMBOL(ioread16_rep);
@@ -766,15 +759,15 @@
 
 void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count)
 {
-	_outsb((void *) IO_TOKEN_TO_ADDR(addr), src, count);
+	_outsb((u8 __force *) addr, src, count);
 }
 void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count)
 {
-	_outsw_ns((void *) IO_TOKEN_TO_ADDR(addr), src, count);
+	_outsw_ns((u16 __force *) addr, src, count);
 }
 void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count)
 {
-	_outsl_ns((void *) IO_TOKEN_TO_ADDR(addr), src, count);
+	_outsl_ns((u32 __force *) addr, src, count);
 }
 EXPORT_SYMBOL(iowrite8_rep);
 EXPORT_SYMBOL(iowrite16_rep);
@@ -784,7 +777,7 @@
 {
 	if (!_IO_IS_VALID(port))
 		return NULL;
-	return (void __iomem *) IO_ADDR_TO_TOKEN(port+pci_io_base);
+	return (void __iomem *) (port+pci_io_base);
 }
 
 void ioport_unmap(void __iomem *addr)
@@ -806,15 +799,8 @@
 		len = max;
 	if (flags & IORESOURCE_IO)
 		return ioport_map(start, len);
-	if (flags & IORESOURCE_MEM) {
-		void __iomem *vaddr = (void __iomem *) start;
-		if (dev  && eeh_subsystem_enabled) {
-			struct device_node *dn = pci_device_to_OF_node(dev);
-			if (dn && !(dn->eeh_mode & EEH_MODE_NOCHECK))
-				return (void __iomem *) IO_ADDR_TO_TOKEN(vaddr);
-		}
-		return vaddr;
-	}
+	if (flags & IORESOURCE_MEM)
+		return (void __iomem *) start;
 	/* What? */
 	return NULL;
 }
@@ -826,39 +812,6 @@
 EXPORT_SYMBOL(pci_iomap);
 EXPORT_SYMBOL(pci_iounmap);
 
-/*
- * If EEH is implemented, find the PCI device using given phys addr
- * and check to see if eeh failure checking is disabled.
- * Remap the addr (trivially) to the EEH region if EEH checking enabled.
- * For addresses not known to PCI the vaddr is simply returned unchanged.
- */
-void __iomem *eeh_ioremap(unsigned long addr, void __iomem *vaddr)
-{
-	struct pci_dev *dev;
-	struct device_node *dn;
-
-	if (!eeh_subsystem_enabled)
-		return vaddr;
-
-	dev = pci_get_device_by_addr(addr);
-	if (!dev)
-		return vaddr;
-
-	dn = pci_device_to_OF_node(dev);
-	if (!dn) {
-		pci_dev_put(dev);
-		return vaddr;
-	}
-
-	if (dn->eeh_mode & EEH_MODE_NOCHECK) {
-		pci_dev_put(dev);
-		return vaddr;
-	}
-
-	pci_dev_put(dev);
-	return (void __iomem *)IO_ADDR_TO_TOKEN(vaddr);
-}
-
 static int proc_eeh_show(struct seq_file *m, void *v)
 {
 	unsigned int cpu;
Index: linux-bk/arch/ppc64/mm/init.c
===================================================================
--- linux-bk.orig/arch/ppc64/mm/init.c	2004-09-21 14:55:02.000000000 -0700
+++ linux-bk/arch/ppc64/mm/init.c	2004-09-21 19:42:58.000000000 -0700
@@ -203,10 +203,7 @@
 void __iomem *
 ioremap(unsigned long addr, unsigned long size)
 {
-	void __iomem *ret = __ioremap(addr, size, _PAGE_NO_CACHE);
-	if(mem_init_done)
-		return eeh_ioremap(addr, ret);	/* may remap the addr */
-	return ret;
+	return __ioremap(addr, size, _PAGE_NO_CACHE);
 }
 
 void __iomem *
@@ -363,9 +360,7 @@
 		return;
 	}
 	
-	/* addr could be in EEH or IO region, map it to IO region regardless.
-	 */
-	addr = (void *) (IO_TOKEN_TO_ADDR(token) & PAGE_MASK);
+	addr = (void *) ((unsigned long __force) token & PAGE_MASK);
 	
 	if ((size = im_free(addr)) == 0) {
 		return;
@@ -415,9 +410,7 @@
 	unsigned long addr;
 	int rc;
 	
-	/* addr could be in EEH or IO region, map it to IO region regardless.
-	 */
-	addr = (IO_TOKEN_TO_ADDR(start) & PAGE_MASK);
+	addr = (unsigned long __force) start & PAGE_MASK;
 
 	/* Verify that the region either exists or is a subset of an existing
 	 * region.  In the latter case, split the parent region to create 
Index: linux-bk/include/asm-ppc64/eeh.h
===================================================================
--- linux-bk.orig/include/asm-ppc64/eeh.h	2004-09-21 14:57:25.000000000 -0700
+++ linux-bk/include/asm-ppc64/eeh.h	2004-09-21 19:39:19.000000000 -0700
@@ -26,18 +26,6 @@
 struct pci_dev;
 struct device_node;
 
-/* I/O addresses are converted to EEH "tokens" such that a driver will cause
- * a bad page fault if the address is used directly (i.e. these addresses are
- * never actually mapped.  Translation between IO <-> EEH region is 1 to 1.
- */
-#define IO_TOKEN_TO_ADDR(token) \
-	(((unsigned long __force)(token) & ~(0xfUL << REGION_SHIFT)) | \
-	(IO_REGION_ID << REGION_SHIFT))
-
-#define IO_ADDR_TO_TOKEN(addr) \
-	(((unsigned long)(addr) & ~(0xfUL << REGION_SHIFT)) | \
-	(EEH_REGION_ID << REGION_SHIFT))
-
 /* Values for eeh_mode bits in device_node */
 #define EEH_MODE_SUPPORTED	(1<<0)
 #define EEH_MODE_NOCHECK	(1<<1)
@@ -109,83 +97,83 @@
  * MMIO read/write operations with EEH support.
  */
 static inline u8 eeh_readb(const volatile void __iomem *addr) {
-	volatile u8 *vaddr = (volatile u8 *)IO_TOKEN_TO_ADDR(addr);
+	volatile u8 *vaddr = (volatile u8 __force *) addr;
 	u8 val = in_8(vaddr);
 	if (EEH_POSSIBLE_ERROR(addr, vaddr, val, u8))
 		return eeh_check_failure(addr, val);
 	return val;
 }
 static inline void eeh_writeb(u8 val, volatile void __iomem *addr) {
-	volatile u8 *vaddr = (volatile u8 *)IO_TOKEN_TO_ADDR(addr);
+	volatile u8 *vaddr = (volatile u8 __force *) addr;
 	out_8(vaddr, val);
 }
 
 static inline u16 eeh_readw(const volatile void __iomem *addr) {
-	volatile u16 *vaddr = (volatile u16 *)IO_TOKEN_TO_ADDR(addr);
+	volatile u16 *vaddr = (volatile u16 __force *) addr;
 	u16 val = in_le16(vaddr);
 	if (EEH_POSSIBLE_ERROR(addr, vaddr, val, u16))
 		return eeh_check_failure(addr, val);
 	return val;
 }
 static inline void eeh_writew(u16 val, volatile void __iomem *addr) {
-	volatile u16 *vaddr = (volatile u16 *)IO_TOKEN_TO_ADDR(addr);
+	volatile u16 *vaddr = (volatile u16 __force *) addr;
 	out_le16(vaddr, val);
 }
 static inline u16 eeh_raw_readw(const volatile void __iomem *addr) {
-	volatile u16 *vaddr = (volatile u16 *)IO_TOKEN_TO_ADDR(addr);
+	volatile u16 *vaddr = (volatile u16 __force *) addr;
 	u16 val = in_be16(vaddr);
 	if (EEH_POSSIBLE_ERROR(addr, vaddr, val, u16))
 		return eeh_check_failure(addr, val);
 	return val;
 }
 static inline void eeh_raw_writew(u16 val, volatile void __iomem *addr) {
-	volatile u16 *vaddr = (volatile u16 *)IO_TOKEN_TO_ADDR(addr);
+	volatile u16 *vaddr = (volatile u16 __force *) addr;
 	out_be16(vaddr, val);
 }
 
 static inline u32 eeh_readl(const volatile void __iomem *addr) {
-	volatile u32 *vaddr = (volatile u32 *)IO_TOKEN_TO_ADDR(addr);
+	volatile u32 *vaddr = (volatile u32 __force *) addr;
 	u32 val = in_le32(vaddr);
 	if (EEH_POSSIBLE_ERROR(addr, vaddr, val, u32))
 		return eeh_check_failure(addr, val);
 	return val;
 }
 static inline void eeh_writel(u32 val, volatile void __iomem *addr) {
-	volatile u32 *vaddr = (volatile u32 *)IO_TOKEN_TO_ADDR(addr);
+	volatile u32 *vaddr = (volatile u32 __force *) addr;
 	out_le32(vaddr, val);
 }
 static inline u32 eeh_raw_readl(const volatile void __iomem *addr) {
-	volatile u32 *vaddr = (volatile u32 *)IO_TOKEN_TO_ADDR(addr);
+	volatile u32 *vaddr = (volatile u32 __force *) addr;
 	u32 val = in_be32(vaddr);
 	if (EEH_POSSIBLE_ERROR(addr, vaddr, val, u32))
 		return eeh_check_failure(addr, val);
 	return val;
 }
 static inline void eeh_raw_writel(u32 val, volatile void __iomem *addr) {
-	volatile u32 *vaddr = (volatile u32 *)IO_TOKEN_TO_ADDR(addr);
+	volatile u32 *vaddr = (volatile u32 __force *) addr;
 	out_be32(vaddr, val);
 }
 
 static inline u64 eeh_readq(const volatile void __iomem *addr) {
-	volatile u64 *vaddr = (volatile u64 *)IO_TOKEN_TO_ADDR(addr);
+	volatile u64 *vaddr = (volatile u64 __force *) addr;
 	u64 val = in_le64(vaddr);
 	if (EEH_POSSIBLE_ERROR(addr, vaddr, val, u64))
 		return eeh_check_failure(addr, val);
 	return val;
 }
 static inline void eeh_writeq(u64 val, volatile void __iomem *addr) {
-	volatile u64 *vaddr = (volatile u64 *)IO_TOKEN_TO_ADDR(addr);
+	volatile u64 *vaddr = (volatile u64 __force *) addr;
 	out_le64(vaddr, val);
 }
 static inline u64 eeh_raw_readq(const volatile void __iomem *addr) {
-	volatile u64 *vaddr = (volatile u64 *)IO_TOKEN_TO_ADDR(addr);
+	volatile u64 *vaddr = (volatile u64 __force *) addr;
 	u64 val = in_be64(vaddr);
 	if (EEH_POSSIBLE_ERROR(addr, vaddr, val, u64))
 		return eeh_check_failure(addr, val);
 	return val;
 }
 static inline void eeh_raw_writeq(u64 val, volatile void __iomem *addr) {
-	volatile u64 *vaddr = (volatile u64 *)IO_TOKEN_TO_ADDR(addr);
+	volatile u64 *vaddr = (volatile u64 __force *) addr;
 	out_be64(vaddr, val);
 }
 
@@ -193,7 +181,7 @@
 	((((unsigned long)(v)) & ((a) - 1)) == 0)
 
 static inline void eeh_memset_io(volatile void __iomem *addr, int c, unsigned long n) {
-	void *vaddr = (void *)IO_TOKEN_TO_ADDR(addr);
+	void *vaddr = (void __force *) addr;
 	u32 lc = c;
 	lc |= lc << 8;
 	lc |= lc << 16;
@@ -216,7 +204,7 @@
 	__asm__ __volatile__ ("sync" : : : "memory");
 }
 static inline void eeh_memcpy_fromio(void *dest, const volatile void __iomem *src, unsigned long n) {
-	void *vsrc = (void *)IO_TOKEN_TO_ADDR(src);
+	void *vsrc = (void __force *) src;
 	void *vsrcsave = vsrc, *destsave = dest;
 	const volatile void __iomem *srcsave = src;
 	unsigned long nsave = n;
@@ -255,7 +243,7 @@
 }
 
 static inline void eeh_memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n) {
-	void *vdest = (void *)IO_TOKEN_TO_ADDR(dest);
+	void *vdest = (void __force *) dest;
 
 	while(n && (!EEH_CHECK_ALIGN(vdest, 4) || !EEH_CHECK_ALIGN(src, 4))) {
 		*((volatile u8 *)vdest) = *((u8 *)src);

  reply	other threads:[~2004-09-22  7:36 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-09-21  9:23 [PATCH] ppc64: Fix __raw_* IO accessors Benjamin Herrenschmidt
2004-09-21 10:05 ` Alan Cox
2004-09-21 11:41   ` Benjamin Herrenschmidt
2004-09-21 19:30     ` Roland Dreier
2004-09-21 19:41       ` Linus Torvalds
2004-09-21 20:55         ` Geert Uytterhoeven
2004-09-21 22:05         ` Roland Dreier
2004-09-21 22:16           ` Linus Torvalds
2004-09-22  1:34             ` Benjamin Herrenschmidt
2004-09-22 18:58               ` Petr Vandrovec
2004-09-23  0:49                 ` Benjamin Herrenschmidt
2004-09-23 15:25                   ` Petr Vandrovec
2004-09-23 20:26                     ` [PATCH] matroxfb big-endian update (was Re: [PATCH] ppc64: Fix __raw_* IO accessors) Petr Vandrovec
2004-09-24  6:25                       ` Benjamin Herrenschmidt
2004-09-24  9:53                         ` Petr Vandrovec
2004-09-24 16:16                           ` Kostas Georgiou
2004-09-25  1:40                           ` Benjamin Herrenschmidt
2004-09-23 22:23                     ` [PATCH] ppc64: Fix __raw_* IO accessors Benjamin Herrenschmidt
2004-09-22  2:15             ` Paul Mackerras
2004-09-22  7:36               ` Roland Dreier [this message]
2004-09-22  1:31           ` Benjamin Herrenschmidt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=52hdpqoiv1.fsf@topspin.com \
    --to=roland@topspin.com \
    --cc=akpm@osdl.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=benh@kernel.crashing.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paulus@samba.org \
    --cc=torvalds@osdl.org \
    --cc=vandrove@vc.cvut.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox