home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-powerpc / eeh.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  9.3 KB  |  367 lines

  1. /*
  2.  * eeh.h
  3.  * Copyright (C) 2001  Dave Engebretsen & Todd Inglett IBM Corporation.
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18.  */
  19.  
  20. #ifndef _PPC64_EEH_H
  21. #define _PPC64_EEH_H
  22. #ifdef __KERNEL__
  23.  
  24. #include <linux/init.h>
  25. #include <linux/list.h>
  26. #include <linux/string.h>
  27.  
  28. struct pci_dev;
  29. struct pci_bus;
  30. struct device_node;
  31.  
  32. #ifdef CONFIG_EEH
  33.  
  34. extern int eeh_subsystem_enabled;
  35.  
  36. /* Values for eeh_mode bits in device_node */
  37. #define EEH_MODE_SUPPORTED     (1<<0)
  38. #define EEH_MODE_NOCHECK       (1<<1)
  39. #define EEH_MODE_ISOLATED      (1<<2)
  40. #define EEH_MODE_RECOVERING    (1<<3)
  41. #define EEH_MODE_IRQ_DISABLED  (1<<4)
  42.  
  43. /* Max number of EEH freezes allowed before we consider the device
  44.  * to be permanently disabled. */
  45. #define EEH_MAX_ALLOWED_FREEZES 5
  46.  
  47. void __init eeh_init(void);
  48. unsigned long eeh_check_failure(const volatile void __iomem *token,
  49.                 unsigned long val);
  50. int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev);
  51. void __init pci_addr_cache_build(void);
  52.  
  53. /**
  54.  * eeh_add_device_early
  55.  * eeh_add_device_late
  56.  *
  57.  * Perform eeh initialization for devices added after boot.
  58.  * Call eeh_add_device_early before doing any i/o to the
  59.  * device (including config space i/o).  Call eeh_add_device_late
  60.  * to finish the eeh setup for this device.
  61.  */
  62. void eeh_add_device_tree_early(struct device_node *);
  63. void eeh_add_device_tree_late(struct pci_bus *);
  64.  
  65. /**
  66.  * eeh_remove_device_recursive - undo EEH for device & children.
  67.  * @dev: pci device to be removed
  68.  *
  69.  * As above, this removes the device; it also removes child
  70.  * pci devices as well.
  71.  */
  72. void eeh_remove_bus_device(struct pci_dev *);
  73.  
  74. /**
  75.  * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
  76.  *
  77.  * If this macro yields TRUE, the caller relays to eeh_check_failure()
  78.  * which does further tests out of line.
  79.  */
  80. #define EEH_POSSIBLE_ERROR(val, type)    ((val) == (type)~0 && eeh_subsystem_enabled)
  81.  
  82. /*
  83.  * Reads from a device which has been isolated by EEH will return
  84.  * all 1s.  This macro gives an all-1s value of the given size (in
  85.  * bytes: 1, 2, or 4) for comparing with the result of a read.
  86.  */
  87. #define EEH_IO_ERROR_VALUE(size)    (~0U >> ((4 - (size)) * 8))
  88.  
  89. #else /* !CONFIG_EEH */
  90. static inline void eeh_init(void) { }
  91.  
  92. static inline unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val)
  93. {
  94.     return val;
  95. }
  96.  
  97. static inline int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
  98. {
  99.     return 0;
  100. }
  101.  
  102. static inline void pci_addr_cache_build(void) { }
  103.  
  104. static inline void eeh_add_device_tree_early(struct device_node *dn) { }
  105.  
  106. static inline void eeh_add_device_tree_late(struct pci_bus *bus) { }
  107.  
  108. static inline void eeh_remove_bus_device(struct pci_dev *dev) { }
  109. #define EEH_POSSIBLE_ERROR(val, type) (0)
  110. #define EEH_IO_ERROR_VALUE(size) (-1UL)
  111. #endif /* CONFIG_EEH */
  112.  
  113. /*
  114.  * MMIO read/write operations with EEH support.
  115.  */
  116. static inline u8 eeh_readb(const volatile void __iomem *addr)
  117. {
  118.     u8 val = in_8(addr);
  119.     if (EEH_POSSIBLE_ERROR(val, u8))
  120.         return eeh_check_failure(addr, val);
  121.     return val;
  122. }
  123. static inline void eeh_writeb(u8 val, volatile void __iomem *addr)
  124. {
  125.     out_8(addr, val);
  126. }
  127.  
  128. static inline u16 eeh_readw(const volatile void __iomem *addr)
  129. {
  130.     u16 val = in_le16(addr);
  131.     if (EEH_POSSIBLE_ERROR(val, u16))
  132.         return eeh_check_failure(addr, val);
  133.     return val;
  134. }
  135. static inline void eeh_writew(u16 val, volatile void __iomem *addr)
  136. {
  137.     out_le16(addr, val);
  138. }
  139. static inline u16 eeh_raw_readw(const volatile void __iomem *addr)
  140. {
  141.     u16 val = in_be16(addr);
  142.     if (EEH_POSSIBLE_ERROR(val, u16))
  143.         return eeh_check_failure(addr, val);
  144.     return val;
  145. }
  146. static inline void eeh_raw_writew(u16 val, volatile void __iomem *addr) {
  147.     volatile u16 __iomem *vaddr = (volatile u16 __iomem *) addr;
  148.     out_be16(vaddr, val);
  149. }
  150.  
  151. static inline u32 eeh_readl(const volatile void __iomem *addr)
  152. {
  153.     u32 val = in_le32(addr);
  154.     if (EEH_POSSIBLE_ERROR(val, u32))
  155.         return eeh_check_failure(addr, val);
  156.     return val;
  157. }
  158. static inline void eeh_writel(u32 val, volatile void __iomem *addr)
  159. {
  160.     out_le32(addr, val);
  161. }
  162. static inline u32 eeh_raw_readl(const volatile void __iomem *addr)
  163. {
  164.     u32 val = in_be32(addr);
  165.     if (EEH_POSSIBLE_ERROR(val, u32))
  166.         return eeh_check_failure(addr, val);
  167.     return val;
  168. }
  169. static inline void eeh_raw_writel(u32 val, volatile void __iomem *addr)
  170. {
  171.     out_be32(addr, val);
  172. }
  173.  
  174. static inline u64 eeh_readq(const volatile void __iomem *addr)
  175. {
  176.     u64 val = in_le64(addr);
  177.     if (EEH_POSSIBLE_ERROR(val, u64))
  178.         return eeh_check_failure(addr, val);
  179.     return val;
  180. }
  181. static inline void eeh_writeq(u64 val, volatile void __iomem *addr)
  182. {
  183.     out_le64(addr, val);
  184. }
  185. static inline u64 eeh_raw_readq(const volatile void __iomem *addr)
  186. {
  187.     u64 val = in_be64(addr);
  188.     if (EEH_POSSIBLE_ERROR(val, u64))
  189.         return eeh_check_failure(addr, val);
  190.     return val;
  191. }
  192. static inline void eeh_raw_writeq(u64 val, volatile void __iomem *addr)
  193. {
  194.     out_be64(addr, val);
  195. }
  196.  
  197. #define EEH_CHECK_ALIGN(v,a) \
  198.     ((((unsigned long)(v)) & ((a) - 1)) == 0)
  199.  
  200. static inline void eeh_memset_io(volatile void __iomem *addr, int c,
  201.                  unsigned long n)
  202. {
  203.     void *p = (void __force *)addr;
  204.     u32 lc = c;
  205.     lc |= lc << 8;
  206.     lc |= lc << 16;
  207.  
  208.     while(n && !EEH_CHECK_ALIGN(p, 4)) {
  209.         *((volatile u8 *)p) = c;
  210.         p++;
  211.         n--;
  212.     }
  213.     while(n >= 4) {
  214.         *((volatile u32 *)p) = lc;
  215.         p += 4;
  216.         n -= 4;
  217.     }
  218.     while(n) {
  219.         *((volatile u8 *)p) = c;
  220.         p++;
  221.         n--;
  222.     }
  223.     __asm__ __volatile__ ("sync" : : : "memory");
  224. }
  225. static inline void eeh_memcpy_fromio(void *dest, const volatile void __iomem *src,
  226.                      unsigned long n)
  227. {
  228.     void *vsrc = (void __force *) src;
  229.     void *destsave = dest;
  230.     unsigned long nsave = n;
  231.  
  232.     while(n && (!EEH_CHECK_ALIGN(vsrc, 4) || !EEH_CHECK_ALIGN(dest, 4))) {
  233.         *((u8 *)dest) = *((volatile u8 *)vsrc);
  234.         __asm__ __volatile__ ("eieio" : : : "memory");
  235.         vsrc++;
  236.         dest++;
  237.         n--;
  238.     }
  239.     while(n > 4) {
  240.         *((u32 *)dest) = *((volatile u32 *)vsrc);
  241.         __asm__ __volatile__ ("eieio" : : : "memory");
  242.         vsrc += 4;
  243.         dest += 4;
  244.         n -= 4;
  245.     }
  246.     while(n) {
  247.         *((u8 *)dest) = *((volatile u8 *)vsrc);
  248.         __asm__ __volatile__ ("eieio" : : : "memory");
  249.         vsrc++;
  250.         dest++;
  251.         n--;
  252.     }
  253.     __asm__ __volatile__ ("sync" : : : "memory");
  254.  
  255.     /* Look for ffff's here at dest[n].  Assume that at least 4 bytes
  256.      * were copied. Check all four bytes.
  257.      */
  258.     if ((nsave >= 4) &&
  259.         (EEH_POSSIBLE_ERROR((*((u32 *) destsave+nsave-4)), u32))) {
  260.         eeh_check_failure(src, (*((u32 *) destsave+nsave-4)));
  261.     }
  262. }
  263.  
  264. static inline void eeh_memcpy_toio(volatile void __iomem *dest, const void *src,
  265.                    unsigned long n)
  266. {
  267.     void *vdest = (void __force *) dest;
  268.  
  269.     while(n && (!EEH_CHECK_ALIGN(vdest, 4) || !EEH_CHECK_ALIGN(src, 4))) {
  270.         *((volatile u8 *)vdest) = *((u8 *)src);
  271.         src++;
  272.         vdest++;
  273.         n--;
  274.     }
  275.     while(n > 4) {
  276.         *((volatile u32 *)vdest) = *((volatile u32 *)src);
  277.         src += 4;
  278.         vdest += 4;
  279.         n-=4;
  280.     }
  281.     while(n) {
  282.         *((volatile u8 *)vdest) = *((u8 *)src);
  283.         src++;
  284.         vdest++;
  285.         n--;
  286.     }
  287.     __asm__ __volatile__ ("sync" : : : "memory");
  288. }
  289.  
  290. #undef EEH_CHECK_ALIGN
  291.  
  292. static inline u8 eeh_inb(unsigned long port)
  293. {
  294.     u8 val;
  295.     if (!_IO_IS_VALID(port))
  296.         return ~0;
  297.     val = in_8((u8 __iomem *)(port+pci_io_base));
  298.     if (EEH_POSSIBLE_ERROR(val, u8))
  299.         return eeh_check_failure((void __iomem *)(port), val);
  300.     return val;
  301. }
  302.  
  303. static inline void eeh_outb(u8 val, unsigned long port)
  304. {
  305.     if (_IO_IS_VALID(port))
  306.         out_8((u8 __iomem *)(port+pci_io_base), val);
  307. }
  308.  
  309. static inline u16 eeh_inw(unsigned long port)
  310. {
  311.     u16 val;
  312.     if (!_IO_IS_VALID(port))
  313.         return ~0;
  314.     val = in_le16((u16 __iomem *)(port+pci_io_base));
  315.     if (EEH_POSSIBLE_ERROR(val, u16))
  316.         return eeh_check_failure((void __iomem *)(port), val);
  317.     return val;
  318. }
  319.  
  320. static inline void eeh_outw(u16 val, unsigned long port)
  321. {
  322.     if (_IO_IS_VALID(port))
  323.         out_le16((u16 __iomem *)(port+pci_io_base), val);
  324. }
  325.  
  326. static inline u32 eeh_inl(unsigned long port)
  327. {
  328.     u32 val;
  329.     if (!_IO_IS_VALID(port))
  330.         return ~0;
  331.     val = in_le32((u32 __iomem *)(port+pci_io_base));
  332.     if (EEH_POSSIBLE_ERROR(val, u32))
  333.         return eeh_check_failure((void __iomem *)(port), val);
  334.     return val;
  335. }
  336.  
  337. static inline void eeh_outl(u32 val, unsigned long port)
  338. {
  339.     if (_IO_IS_VALID(port))
  340.         out_le32((u32 __iomem *)(port+pci_io_base), val);
  341. }
  342.  
  343. /* in-string eeh macros */
  344. static inline void eeh_insb(unsigned long port, void * buf, int ns)
  345. {
  346.     _insb((u8 __iomem *)(port+pci_io_base), buf, ns);
  347.     if (EEH_POSSIBLE_ERROR((*(((u8*)buf)+ns-1)), u8))
  348.         eeh_check_failure((void __iomem *)(port), *(u8*)buf);
  349. }
  350.  
  351. static inline void eeh_insw_ns(unsigned long port, void * buf, int ns)
  352. {
  353.     _insw_ns((u16 __iomem *)(port+pci_io_base), buf, ns);
  354.     if (EEH_POSSIBLE_ERROR((*(((u16*)buf)+ns-1)), u16))
  355.         eeh_check_failure((void __iomem *)(port), *(u16*)buf);
  356. }
  357.  
  358. static inline void eeh_insl_ns(unsigned long port, void * buf, int nl)
  359. {
  360.     _insl_ns((u32 __iomem *)(port+pci_io_base), buf, nl);
  361.     if (EEH_POSSIBLE_ERROR((*(((u32*)buf)+nl-1)), u32))
  362.         eeh_check_failure((void __iomem *)(port), *(u32*)buf);
  363. }
  364.  
  365. #endif /* __KERNEL__ */
  366. #endif /* _PPC64_EEH_H */
  367.