patch-2.4.21 linux-2.4.21/include/asm-ppc64/eeh.h
Next file: linux-2.4.21/include/asm-ppc64/elf.h
Previous file: linux-2.4.21/include/asm-ppc64/delay.h
Back to the patch index
Back to the overall index
- Lines: 160
- Date:
2003-06-13 07:51:38.000000000 -0700
- Orig file:
linux-2.4.20/include/asm-ppc64/eeh.h
- Orig date:
2002-11-28 15:53:15.000000000 -0800
diff -urN linux-2.4.20/include/asm-ppc64/eeh.h linux-2.4.21/include/asm-ppc64/eeh.h
@@ -27,25 +27,26 @@
struct pci_dev;
-#define IO_UNMAPPED_REGION_ID 0xaUL
-
-#define IO_TOKEN_TO_ADDR(token) ((((unsigned long)(token)) & 0xFFFFFFFF) | (0xEUL << 60))
-/* Flag bits encoded in the 3 unused function bits of devfn */
-#define EEH_TOKEN_DISABLED (1UL << 34UL) /* eeh is disabled for this token */
-#define IS_EEH_TOKEN_DISABLED(token) ((unsigned long)(token) & EEH_TOKEN_DISABLED)
-
-#define EEH_STATE_OVERRIDE 1 /* IOA does not require eeh traps */
-#define EEH_STATE_FAILURE 16 /* */
+/* 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)(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)
/* This is for profiling only */
extern unsigned long eeh_total_mmio_ffs;
-extern int eeh_implemented;
-
void eeh_init(void);
-static inline int is_eeh_implemented(void) { return eeh_implemented; }
int eeh_get_state(unsigned long ea);
unsigned long eeh_check_failure(void *token, unsigned long val);
+void *eeh_ioremap(unsigned long addr, void *vaddr);
#define EEH_DISABLE 0
#define EEH_ENABLE 1
@@ -58,15 +59,11 @@
*/
int is_eeh_configured(struct pci_dev *dev);
-/* Generate an EEH token.
- * The high nibble of the offset is cleared, otherwise bounds checking is performed.
- * Use IO_TOKEN_TO_ADDR(token) to translate this token back to a mapped virtual addr.
- * Do NOT do this to perform IO -- use the read/write macros!
- */
-unsigned long eeh_token(unsigned long phb,
- unsigned long bus,
- unsigned long devfn,
- unsigned long offset);
+/* Translate a (possible) eeh token to a physical addr.
+ * If "token" is not an eeh token it is simply returned under
+ * the assumption that it is already a physical addr.
+ */
+unsigned long eeh_token_to_phys(unsigned long token);
extern void *memcpy(void *, const void *, unsigned long);
extern void *memset(void *,int, unsigned long);
@@ -77,15 +74,16 @@
* If EEH is off for a device and it is a memory BAR, ioremap will
* map it to the IOREGION. In this case addr == vaddr and since these
* should be in registers we compare them first. Next we check for
- * all ones which is perhaps fastest as ~val. Finally we weed out
- * EEH disabled IO BARs.
+ * ff's which indicates a (very) possible failure.
*
* If this macro yields TRUE, the caller relays to eeh_check_failure()
* which does further tests out of line.
*/
-/* #define EEH_POSSIBLE_ERROR(addr, vaddr, val) ((vaddr) != (addr) && ~(val) == 0 && !IS_EEH_TOKEN_DISABLED(addr)) */
+/* #define EEH_POSSIBLE_IO_ERROR(val) (~(val) == 0) */
+/* #define EEH_POSSIBLE_ERROR(addr, vaddr, val) ((vaddr) != (addr) && EEH_POSSIBLE_IO_ERROR(val) */
/* This version is rearranged to collect some profiling data */
-#define EEH_POSSIBLE_ERROR(addr, vaddr, val) (~(val) == 0 && (++eeh_total_mmio_ffs, (vaddr) != (addr) && !IS_EEH_TOKEN_DISABLED(addr)))
+#define EEH_POSSIBLE_IO_ERROR(val) (~(val) == 0 && ++eeh_total_mmio_ffs)
+#define EEH_POSSIBLE_ERROR(addr, vaddr, val) (EEH_POSSIBLE_IO_ERROR(val) && (vaddr) != (addr))
/*
* MMIO read/write operations with EEH support.
@@ -149,38 +147,56 @@
memcpy(vdest, src, n);
}
-static inline void eeh_insb(volatile u8 *addr, void *buf, int n) {
- volatile u8 *vaddr = (volatile u8 *)IO_TOKEN_TO_ADDR(addr);
- _insb(vaddr, buf, n);
- /* ToDo: look for ff's in buf[n] */
-}
+/* The I/O macros must handle ISA ports as well as PCI I/O bars.
+ * ISA does not implement EEH and ISA may not exist in the system.
+ * For PCI we check for EEH failures.
+ */
+#define _IO_IS_ISA(port) ((port) < 0x10000)
+#define _IO_HAS_ISA_BUS (isa_io_base != 0)
-static inline void eeh_outsb(volatile u8 *addr, const void *buf, int n) {
- volatile u8 *vaddr = (volatile u8 *)IO_TOKEN_TO_ADDR(addr);
- _outsb(vaddr, buf, n);
+static inline u8 eeh_inb(unsigned long port) {
+ u8 val;
+ if (_IO_IS_ISA(port) && !_IO_HAS_ISA_BUS)
+ return ~0;
+ val = in_8((u8 *)(port+pci_io_base));
+ if (!_IO_IS_ISA(port) && EEH_POSSIBLE_IO_ERROR(val))
+ return eeh_check_failure((void*)(port+pci_io_base), val);
+ return val;
}
-static inline void eeh_insw_ns(volatile u16 *addr, void *buf, int n) {
- volatile u16 *vaddr = (volatile u16 *)IO_TOKEN_TO_ADDR(addr);
- _insw_ns(vaddr, buf, n);
- /* ToDo: look for ffff's in buf[n] */
+static inline void eeh_outb(u8 val, unsigned long port) {
+ if (!_IO_IS_ISA(port) || _IO_HAS_ISA_BUS)
+ return out_8((u8 *)(port+pci_io_base), val);
}
-static inline void eeh_outsw_ns(volatile u16 *addr, const void *buf, int n) {
- volatile u16 *vaddr = (volatile u16 *)IO_TOKEN_TO_ADDR(addr);
- _outsw_ns(vaddr, buf, n);
+static inline u16 eeh_inw(unsigned long port) {
+ u16 val;
+ if (_IO_IS_ISA(port) && !_IO_HAS_ISA_BUS)
+ return ~0;
+ val = in_le16((u16 *)(port+pci_io_base));
+ if (!_IO_IS_ISA(port) && EEH_POSSIBLE_IO_ERROR(val))
+ return eeh_check_failure((void*)(port+pci_io_base), val);
+ return val;
}
-static inline void eeh_insl_ns(volatile u32 *addr, void *buf, int n) {
- volatile u32 *vaddr = (volatile u32 *)IO_TOKEN_TO_ADDR(addr);
- _insl_ns(vaddr, buf, n);
- /* ToDo: look for ffffffff's in buf[n] */
+static inline void eeh_outw(u16 val, unsigned long port) {
+ if (!_IO_IS_ISA(port) || _IO_HAS_ISA_BUS)
+ return out_le16((u16 *)(port+pci_io_base), val);
}
-static inline void eeh_outsl_ns(volatile u32 *addr, const void *buf, int n) {
- volatile u32 *vaddr = (volatile u32 *)IO_TOKEN_TO_ADDR(addr);
- _outsl_ns(vaddr, buf, n);
+static inline u32 eeh_inl(unsigned long port) {
+ u32 val;
+ if (_IO_IS_ISA(port) && !_IO_HAS_ISA_BUS)
+ return ~0;
+ val = in_le32((u32 *)(port+pci_io_base));
+ if (!_IO_IS_ISA(port) && EEH_POSSIBLE_IO_ERROR(val))
+ return eeh_check_failure((void*)(port+pci_io_base), val);
+ return val;
}
+static inline void eeh_outl(u32 val, unsigned long port) {
+ if (!_IO_IS_ISA(port) || _IO_HAS_ISA_BUS)
+ return out_le32((u32 *)(port+pci_io_base), val);
+}
#endif /* _EEH_H */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)