Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | /* $Id$ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc. * Copyright (C) 2000 by Colin Ngam */ #ifndef _ASM_SN_IOERROR_H #define _ASM_SN_IOERROR_H #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) /* * Macros defining the various Errors to be handled as part of * IO Error handling. */ /* * List of errors to be handled by each subsystem. * "error_code" field will take one of these values. * The error code is built up of single bits expressing * our confidence that the error was that type; note * that it is possible to have a PIO or DMA error where * we don't know whether it was a READ or a WRITE, or * even a READ or WRITE error that we're not sure whether * to call a PIO or DMA. * * It is also possible to set both PIO and DMA, and possible * to set both READ and WRITE; the first may be nonsensical * but the second *could* be used to designate an access * that is known to be a read-modify-write cycle. It is * quite possible that nobody will ever use PIO|DMA or * READ|WRITE ... but being flexible is good. */ #define IOECODE_UNSPEC 0 #define IOECODE_READ 1 #define IOECODE_WRITE 2 #define IOECODE_PIO 4 #define IOECODE_DMA 8 #define IOECODE_PIO_READ (IOECODE_PIO|IOECODE_READ) #define IOECODE_PIO_WRITE (IOECODE_PIO|IOECODE_WRITE) #define IOECODE_DMA_READ (IOECODE_DMA|IOECODE_READ) #define IOECODE_DMA_WRITE (IOECODE_DMA|IOECODE_WRITE) /* support older names, but try to move everything * to using new names that identify which package * controls their values ... */ #define PIO_READ_ERROR IOECODE_PIO_READ #define PIO_WRITE_ERROR IOECODE_PIO_WRITE #define DMA_READ_ERROR IOECODE_DMA_READ #define DMA_WRITE_ERROR IOECODE_DMA_WRITE /* * List of error numbers returned by error handling sub-system. */ #define IOERROR_HANDLED 0 /* Error Properly handled. */ #define IOERROR_NODEV 0x1 /* No such device attached */ #define IOERROR_BADHANDLE 0x2 /* Received bad handle */ #define IOERROR_BADWIDGETNUM 0x3 /* Bad widget number */ #define IOERROR_BADERRORCODE 0x4 /* Bad error code passed in */ #define IOERROR_INVALIDADDR 0x5 /* Invalid address specified */ #define IOERROR_WIDGETLEVEL 0x6 /* Some failure at widget level */ #define IOERROR_XTALKLEVEL 0x7 #define IOERROR_HWGRAPH_LOOKUP 0x8 /* hwgraph lookup failed for path */ #define IOERROR_UNHANDLED 0x9 /* handler rejected error */ #define IOERROR_PANIC 0xA /* subsidiary handler has already * started decode: continue error * data dump, and panic from top * caller in error chain. */ /* * IO errors at the bus/device driver level */ #define IOERROR_DEV_NOTFOUND 0x10 /* Device matching bus addr not found */ #define IOERROR_DEV_SHUTDOWN 0x11 /* Device has been shutdown */ /* * Type of address. * Indicates the direction of transfer that caused the error. */ #define IOERROR_ADDR_PIO 1 /* Error Address generated due to PIO */ #define IOERROR_ADDR_DMA 2 /* Error address generated due to DMA */ /* * IO error structure. * * This structure would expand to hold the information retrieved from * all IO related error registers. * * This structure is defined to hold all system specific * information related to a single error. * * This serves a couple of purpose. * - Error handling often involves translating one form of address to other * form. So, instead of having different data structures at each level, * we have a single structure, and the appropriate fields get filled in * at each layer. * - This provides a way to dump all error related information in any layer * of erorr handling (debugging aid). * * A second possibility is to allow each layer to define its own error * data structure, and fill in the proper fields. This has the advantage * of isolating the layers. * A big concern is the potential stack usage (and overflow), if each layer * defines these structures on stack (assuming we don't want to do kmalloc. * * Any layer wishing to pass extra information to a layer next to it in * error handling hierarchy, can do so as a separate parameter. */ typedef struct io_error_s { /* Bit fields indicating which sturcture fields are valid */ union { struct { unsigned ievb_errortype:1; unsigned ievb_widgetnum:1; unsigned ievb_widgetdev:1; unsigned ievb_srccpu:1; unsigned ievb_srcnode:1; unsigned ievb_errnode:1; unsigned ievb_sysioaddr:1; unsigned ievb_xtalkaddr:1; unsigned ievb_busspace:1; unsigned ievb_busaddr:1; unsigned ievb_vaddr:1; unsigned ievb_memaddr:1; unsigned ievb_epc:1; unsigned ievb_ef:1; } iev_b; unsigned iev_a; } ie_v; short ie_errortype; /* error type: extra info about error */ short ie_widgetnum; /* Widget number that's in error */ short ie_widgetdev; /* Device within widget in error */ cpuid_t ie_srccpu; /* CPU on srcnode generating error */ cnodeid_t ie_srcnode; /* Node which caused the error */ cnodeid_t ie_errnode; /* Node where error was noticed */ iopaddr_t ie_sysioaddr; /* Sys specific IO address */ iopaddr_t ie_xtalkaddr; /* Xtalk (48bit) addr of Error */ iopaddr_t ie_busspace; /* Bus specific address space */ iopaddr_t ie_busaddr; /* Bus specific address */ caddr_t ie_vaddr; /* Virtual address of error */ paddr_t ie_memaddr; /* Physical memory address */ caddr_t ie_epc; /* pc when error reported */ caddr_t ie_ef; /* eframe when error reported */ } ioerror_t; #define IOERROR_INIT(e) do { (e)->ie_v.iev_a = 0; } while (0) #define IOERROR_SETVALUE(e,f,v) do { (e)->ie_ ## f = (v); (e)->ie_v.iev_b.ievb_ ## f = 1; } while (0) #define IOERROR_FIELDVALID(e,f) (((e)->ie_v.iev_b.ievb_ ## f) != 0) #define IOERROR_GETVALUE(e,f) (ASSERT(IOERROR_FIELDVALID(e,f)),((e)->ie_ ## f)) #if IP27 || IP35 /* hub code likes to call the SysAD address "hubaddr" ... */ #define ie_hubaddr ie_sysioaddr #define ievb_hubaddr ievb_sysioaddr #endif /* * Error handling Modes. */ typedef enum { MODE_DEVPROBE, /* Probing mode. Errors not fatal */ MODE_DEVERROR, /* Error while system is running */ MODE_DEVUSERERROR, /* Device Error created due to user mode access */ MODE_DEVREENABLE /* Reenable pass */ } ioerror_mode_t; #endif /* C || C++ */ typedef int error_handler_f(void *, int, ioerror_mode_t, ioerror_t *); typedef void *error_handler_arg_t; extern void ioerror_dump(char *, int, int, ioerror_t *); #ifdef ERROR_DEBUG #define IOERROR_DUMP(x, y, z, t) ioerror_dump((x), (y), (z), (t)) #define IOERR_PRINTF(x) (x) #else #define IOERROR_DUMP(x, y, z, t) #define IOERR_PRINTF(x) #endif /* ERROR_DEBUG */ #endif /* _ASM_SN_IOERROR_H */ |