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);
next prev parent 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.