Messages in this thread Patch in this message | | | Date | Thu, 09 Jun 2005 21:51:57 +0900 | From | Hidetoshi Seto <> | Subject | [PATCH 03/10] IOCHK interface for I/O error handling/detecting |
| |
[This is 3 of 10 patches, "iochk-03-register.patch"]
- Implement ia64 version of basic codes: iochk_clear, iochk_read, iochk_init, and iocookie
The direction is:
- Have a "now in check" global list, "iochk_devices", for future use.
- Take a lock, "iochk_lock", to protect the global list.
- iochk_clear packs *dev into iocookie, and add it to the global list. After all prepared, clear error-flag in cookie to start io-critical-session.
- iochk_read checks error-flag and device's status register. After removing iocookie from list, return the result.
This is too simple. We need more codes... See next (4 of 10).
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
---
arch/ia64/lib/iomap_check.c | 54 ++++++++++++++++++++++++++++++++++++++++++-- include/asm-ia64/io.h | 8 +++++- 2 files changed, 59 insertions(+), 3 deletions(-)
Index: linux-2.6.11.11/arch/ia64/lib/iomap_check.c =================================================================== --- linux-2.6.11.11.orig/arch/ia64/lib/iomap_check.c +++ linux-2.6.11.11/arch/ia64/lib/iomap_check.c @@ -4,24 +4,74 @@ */
#include <linux/pci.h> +#include <linux/list.h> +#include <linux/spinlock.h>
void iochk_init(void); void iochk_clear(iocookie *cookie, struct pci_dev *dev); int iochk_read(iocookie *cookie);
+struct list_head iochk_devices; +DEFINE_SPINLOCK(iochk_lock); /* all works are excluded on this lock */ + +static int have_error(struct pci_dev *dev); + void iochk_init(void) { /* setup */ + INIT_LIST_HEAD(&iochk_devices); }
void iochk_clear(iocookie *cookie, struct pci_dev *dev) { - /* register device etc. */ + unsigned long flag; + + INIT_LIST_HEAD(&(cookie->list)); + + cookie->dev = dev; + + spin_lock_irqsave(&iochk_lock, flag); + list_add(&cookie->list, &iochk_devices); + spin_unlock_irqrestore(&iochk_lock, flag); + + cookie->error = 0; }
int iochk_read(iocookie *cookie) { - /* check error etc. */ + unsigned long flag; + int ret = 0; + + spin_lock_irqsave(&iochk_lock, flag); + if( cookie->error || have_error(cookie->dev) ) + ret = 1; + list_del(&cookie->list); + spin_unlock_irqrestore(&iochk_lock, flag); + + return ret; +} + +static int have_error(struct pci_dev *dev) +{ + u16 status; + + /* check status */ + switch (dev->hdr_type) { + case PCI_HEADER_TYPE_NORMAL: /* 0 */ + pci_read_config_word(dev, PCI_STATUS, &status); + break; + case PCI_HEADER_TYPE_BRIDGE: /* 1 */ + pci_read_config_word(dev, PCI_SEC_STATUS, &status); + break; + case PCI_HEADER_TYPE_CARDBUS: /* 2 */ + default: + BUG(); + } + + if ( (status & PCI_STATUS_REC_TARGET_ABORT) + || (status & PCI_STATUS_REC_MASTER_ABORT) + || (status & PCI_STATUS_DETECTED_PARITY) ) + return 1;
return 0; } Index: linux-2.6.11.11/include/asm-ia64/io.h =================================================================== --- linux-2.6.11.11.orig/include/asm-ia64/io.h +++ linux-2.6.11.11/include/asm-ia64/io.h @@ -72,9 +72,15 @@ extern unsigned int num_io_spaces; #include <asm/system.h>
#ifdef CONFIG_IOMAP_CHECK +#include <linux/list.h>
/* definition of ia64 iocookie */ -typedef unsigned long iocookie; +struct __iocookie { + struct list_head list; + struct pci_dev *dev; /* targeting device */ + unsigned long error; /* error flag */ +}; +typedef struct __iocookie iocookie;
/* enable ia64 iochk - See arch/ia64/lib/iomap_check.c */ #define HAVE_ARCH_IOMAP_CHECK - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |