PCI Error Recovery (readX_check)
PATCH 2/2 PCI Error Recovery (readX_check)
The implementation patch, pasted (not attached).
Signed-off-by Hidetoshi Seto <[email protected]>
-----
tmp/linux-2.6.8.1/arch/i386/pci/common.c renamed from usr/src/linux-2.6.8.1/arch/i386/pci/common.c +22 -0
@@ -118,6 +118,19 @@pci_read_bridge_bases (b); } +#ifdef CONFIG_PCI_ERROR_RECOVERY +static void pci_i386_fixup_host_bridge_self (struct pci_bus *bus) +{ +struct pci_dev *pdev; + +list_for_each_entry (pdev, &bus->devices, bus_list) { + if (pdev->class >> 8 = PCI_CLASS_BRIDGE_HOST) { + bus->self = pdev; +return ; + } + } +} +#endif struct pci_bus *__devinit pcibios_scan_root (int busnum) {
@@ -132,7 +145,16 @@printk ("PCI: Probing PCI hardware (bus %02x)\n" , busnum); +#ifdef CONFIG_PCI_ERROR_RECOVERY +{ +struct pci_bus *bus =pci_scan_bus (busnum, &pci_root_ops,NULL ); +if (bus) +pci_i386_fixup_host_bridge_self (bus); +return bus; +} +#else return pci_scan_bus (busnum, &pci_root_ops,NULL ); +#endif }extern u8 pci_cache_line_size;
tmp/linux-2.6.8.1/drivers/pci/Kconfig renamed from usr/src/linux-2.6.8.1/drivers/pci/Kconfig +7 -0
@@ -47,3 +47,10 @@ When in doubt, say Y. +config PCI_ERROR_RECOVERY + bool "PCI device error recovery" + depends on PCI + ---help--- + By default, the device driver hardly recovers from PCI errors. When + this feature is available, the special io interface are provided + from the kernel.
tmp/linux-2.6.8.1/drivers/pci/Makefile renamed from usr/src/linux-2.6.8.1/drivers/pci/Makefile +1 -0
@@ -5,6 +5,7 @@ obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \ names.o pci-driver.o search.o pci-sysfs.o obj-$(CONFIG_PROC_FS) += proc.o +obj-$(CONFIG_PCI_ERROR_RECOVERY) += pci-rec.o ifndef CONFIG_SPARC64 obj-y += setup-res.o
tmp/linux-2.6.8.1/drivers/pci/pci-rec.c renamed from usr/src/linux-2.6.8.1/drivers/pci/pci-rec.c +222 -0
222 lines not on this page · raw message
tmp/linux-2.6.8.1/drivers/pci/pci.c renamed from usr/src/linux-2.6.8.1/drivers/pci/pci.c +3 -0
@@ -750,6 +750,9 @@while ((dev =pci_find_device (PCI_ANY_ID ,PCI_ANY_ID , dev)) !=NULL ) {pci_fixup_device (PCI_FIXUP_FINAL , dev); } +#ifdef CONFIG_PCI_ERROR_RECOVERY +pciwhole_lock_init (); +#endif return 0 ; }
tmp/linux-2.6.8.1/drivers/pci/probe.c renamed from usr/src/linux-2.6.8.1/drivers/pci/probe.c +6 -0
@@ -270,6 +270,9 @@INIT_LIST_HEAD (&b->node);INIT_LIST_HEAD (&b->children);INIT_LIST_HEAD (&b->devices); +#ifdef CONFIG_PCI_ERROR_RECOVERY +pcibus_lock_init (b); +#endif }return b; }
@@ -624,6 +627,9 @@ dev->dev.dma_mask = &dev->dma_mask; dev->dev.coherent_dma_mask =0xffffffffull ; +#ifdef CONFIG_PCI_ERROR_RECOVERY +pcidev_extra_init (dev); +#endif return dev; }
tmp/linux-2.6.8.1/include/asm-i386/io.h renamed from usr/src/linux-2.6.8.1/include/asm-i386/io.h +15 -0
@@ -364,4 +364,19 @@ BUILDIO(w,w,short) BUILDIO(l,,int) +static inline unsigned char _readb_check (unsigned char *addr) +{ +return readb (addr); +} + +static inline unsigned short _readw_check (unsigned short *addr) +{ +return readw (addr); +} + +static inline unsigned int _readl_check (unsigned int *addr) +{ +return readl (addr); +} +#endif
tmp/linux-2.6.8.1/include/asm-i386/pci.h renamed from usr/src/linux-2.6.8.1/include/asm-i386/pci.h +5 -0
@@ -99,6 +99,11 @@ { } +#ifdef CONFIG_PCI_ERROR_RECOVERY +u8 readb_check (struct pci_dev *,u8 *); +u16 readw_check (struct pci_dev *,u16 *); +u32 readl_check (struct pci_dev *,u32 *); +#endif #endif /* __KERNEL__ */ /* implement the pci_ DMA API in terms of the generic device dma_ one */
tmp/linux-2.6.8.1/include/asm-ia64/io.h renamed from usr/src/linux-2.6.8.1/include/asm-ia64/io.h +35 -0
@@ -457,4 +457,39 @@#define BIO_VMERGE_BOUNDARY (ia64_max_iommu_merge_mask + 1)#endif +static inline unsigned char +_readb_check(unsignged char *addr) +{ + registerunsigned long gr8 asm("r8" ); +unsigned char val; + + val =readb (addr); + asmvolatile ("add %0=%1,r0" :"=r" (gr8) :"r" (val)); + +return val; +} + +static inline unsigned short +_readw_check (unsignged short *addr) +{ + registerunsigned long gr8 asm("r8" ); +unsigned short val; + + val =readw (addr); + asmvolatile ("add %0=%1,r0" :"=r" (gr8) :"r" (val)); + +return val; +} + +static inline unsigned int +_readl_check(unsignged int *addr) +{ + registerunsigned long gr8 asm("r8" ); +unsigned int val; + + val =readl (addr); + asmvolatile ("add %0=%1,r0" :"=r" (gr8) :"r" (val)); + +return val; +}#endif /* _ASM_IA64_IO_H */
tmp/linux-2.6.8.1/include/asm-ia64/pci.h renamed from usr/src/linux-2.6.8.1/include/asm-ia64/pci.h +5 -0
@@ -119,6 +119,11 @@ { } +#ifdef CONFIG_PCI_ERROR_RECOVERY +u8 readb_check (struct pci_dev *,u8 *); +u16 readw_check (struct pci_dev *,u16 *); +u32 readl_check (struct pci_dev *,u32 *); +#endif /* generic pci stuff */ #include <asm-generic/pci.h>
tmp/linux-2.6.8.1/include/linux/pci.h renamed from usr/src/linux-2.6.8.1/include/linux/pci.h +23 -0
@@ -486,6 +486,10 @@struct pci_dev {struct list_head global_list;/* node in list of all PCI devices */ struct list_head bus_list;/* node in per-bus list */ +#ifdef CONFIG_PCI_ERROR_RECOVERY +struct list_head working_device;/* working device */ +unsigned err_status;/* root bridge status and other error */ +#endif struct pci_bus *bus;/* bus this device is on */ struct pci_bus *subordinate;/* bus this device bridges to */
@@ -568,6 +572,9 @@struct pci_bus {struct list_head node;/* node in list of buses */ +#ifdef CONFIG_PCI_ERROR_RECOVERY +struct rw_semaphore bus_lock;/* for serialized operation under same root bridge */ +#endif struct pci_bus *parent;/* parent bus this bridge is on */ struct list_head children;/* list of child buses */ struct list_head devices;/* list of devices on this bus */
@@ -1021,5 +1028,21 @@#define PCIPCI_VSFX 16#define PCIPCI_ALIMAGIK 32 +#ifdef CONFIG_PCI_ERROR_RECOVERY +void pcidev_extra_init (struct pci_dev *); +void pcibus_lock_init (struct pci_bus *); +void pcibus_lock (struct pci_bus *); +void pcibus_unlock (struct pci_bus *); +void pciwhole_lock_init (void ); +void pciwhole_read_lock (void ); +void pciwhole_read_unlock (void ); +void pciwhole_write_lock (void ); +void pciwhole_write_unlock (void ); +void clear_pci_errors (struct pci_dev *); +int read_pci_errors (struct pci_dev *); +u8 readb_check (struct pci_dev *,u8 *); +u16 readw_check (struct pci_dev *,u16 *); +u32 readl_check (struct pci_dev *,u32 *); +#endif #endif /* __KERNEL__ */ #endif /* LINUX_PCI_H */
tmp/linux-2.6.8.1/drivers/pci/Kconfig line 52
Quoted 2 lines · Hidetoshi Seto
tmp/linux-2.6.8.1/drivers/pci/Kconfig renamed from usr/src/linux-2.6.8.1/drivers/pci/Kconfig +2
-0+ bool "PCI device error recovery" + depends on PCI
depends on PCI && EXPERIMENTAL
tmp/linux-2.6.8.1/drivers/pci/Kconfig line 56
Quoted 4 lines
tmp/linux-2.6.8.1/drivers/pci/Kconfig renamed from usr/src/linux-2.6.8.1/drivers/pci/Kconfig +4
-0+ ---help--- + By default, the device driver hardly recovers from PCI errors. When + this feature is available, the special io interface are provided + from the kernel.
May I suggest an alternate text?
Saying Y provides PCI infrastructure to recover from some PCI errors. Currently, very few PCI drivers actually implement this. See Documentation/pci-errors.txt for a description of the infrastructure provided.
I'm still digesting the rest of the patch.
grant