linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / include / asm-powerpc / eeh.h
index 6a78439..5207758 100644 (file)
@@ -21,6 +21,7 @@
 #define _PPC64_EEH_H
 #ifdef __KERNEL__
 
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/string.h>
@@ -59,9 +60,23 @@ void __init pci_addr_cache_build(void);
  * device (including config space i/o).  Call eeh_add_device_late
  * to finish the eeh setup for this device.
  */
+void eeh_add_device_early(struct device_node *);
+void eeh_add_device_late(struct pci_dev *dev);
 void eeh_add_device_tree_early(struct device_node *);
 void eeh_add_device_tree_late(struct pci_bus *);
 
+/**
+ * eeh_remove_device - undo EEH setup for the indicated pci device
+ * @dev: pci device to be removed
+ *
+ * This routine should be called when a device is removed from
+ * a running system (e.g. by hotplug or dlpar).  It unregisters
+ * the PCI device from the EEH subsystem.  I/O errors affecting
+ * this device will no longer be detected after this call; thus,
+ * i/o errors affecting this slot may leave this device unusable.
+ */
+void eeh_remove_device(struct pci_dev *);
+
 /**
  * eeh_remove_device_recursive - undo EEH for device & children.
  * @dev: pci device to be removed
@@ -101,6 +116,12 @@ static inline int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *d
 
 static inline void pci_addr_cache_build(void) { }
 
+static inline void eeh_add_device_early(struct device_node *dn) { }
+
+static inline void eeh_add_device_late(struct pci_dev *dev) { }
+
+static inline void eeh_remove_device(struct pci_dev *dev) { }
+
 static inline void eeh_add_device_tree_early(struct device_node *dn) { }
 
 static inline void eeh_add_device_tree_late(struct pci_bus *bus) { }
@@ -205,7 +226,6 @@ static inline void eeh_memset_io(volatile void __iomem *addr, int c,
        lc |= lc << 8;
        lc |= lc << 16;
 
-       __asm__ __volatile__ ("sync" : : : "memory");
        while(n && !EEH_CHECK_ALIGN(p, 4)) {
                *((volatile u8 *)p) = c;
                p++;
@@ -230,7 +250,6 @@ static inline void eeh_memcpy_fromio(void *dest, const volatile void __iomem *sr
        void *destsave = dest;
        unsigned long nsave = n;
 
-       __asm__ __volatile__ ("sync" : : : "memory");
        while(n && (!EEH_CHECK_ALIGN(vsrc, 4) || !EEH_CHECK_ALIGN(dest, 4))) {
                *((u8 *)dest) = *((volatile u8 *)vsrc);
                __asm__ __volatile__ ("eieio" : : : "memory");
@@ -268,7 +287,6 @@ static inline void eeh_memcpy_toio(volatile void __iomem *dest, const void *src,
 {
        void *vdest = (void __force *) dest;
 
-       __asm__ __volatile__ ("sync" : : : "memory");
        while(n && (!EEH_CHECK_ALIGN(vdest, 4) || !EEH_CHECK_ALIGN(src, 4))) {
                *((volatile u8 *)vdest) = *((u8 *)src);
                src++;
@@ -295,6 +313,8 @@ static inline void eeh_memcpy_toio(volatile void __iomem *dest, const void *src,
 static inline u8 eeh_inb(unsigned long port)
 {
        u8 val;
+       if (!_IO_IS_VALID(port))
+               return ~0;
        val = in_8((u8 __iomem *)(port+pci_io_base));
        if (EEH_POSSIBLE_ERROR(val, u8))
                return eeh_check_failure((void __iomem *)(port), val);
@@ -303,12 +323,15 @@ static inline u8 eeh_inb(unsigned long port)
 
 static inline void eeh_outb(u8 val, unsigned long port)
 {
-       out_8((u8 __iomem *)(port+pci_io_base), val);
+       if (_IO_IS_VALID(port))
+               out_8((u8 __iomem *)(port+pci_io_base), val);
 }
 
 static inline u16 eeh_inw(unsigned long port)
 {
        u16 val;
+       if (!_IO_IS_VALID(port))
+               return ~0;
        val = in_le16((u16 __iomem *)(port+pci_io_base));
        if (EEH_POSSIBLE_ERROR(val, u16))
                return eeh_check_failure((void __iomem *)(port), val);
@@ -317,12 +340,15 @@ static inline u16 eeh_inw(unsigned long port)
 
 static inline void eeh_outw(u16 val, unsigned long port)
 {
-       out_le16((u16 __iomem *)(port+pci_io_base), val);
+       if (_IO_IS_VALID(port))
+               out_le16((u16 __iomem *)(port+pci_io_base), val);
 }
 
 static inline u32 eeh_inl(unsigned long port)
 {
        u32 val;
+       if (!_IO_IS_VALID(port))
+               return ~0;
        val = in_le32((u32 __iomem *)(port+pci_io_base));
        if (EEH_POSSIBLE_ERROR(val, u32))
                return eeh_check_failure((void __iomem *)(port), val);
@@ -331,7 +357,8 @@ static inline u32 eeh_inl(unsigned long port)
 
 static inline void eeh_outl(u32 val, unsigned long port)
 {
-       out_le32((u32 __iomem *)(port+pci_io_base), val);
+       if (_IO_IS_VALID(port))
+               out_le32((u32 __iomem *)(port+pci_io_base), val);
 }
 
 /* in-string eeh macros */