3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
7 * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
10 #include <linux/types.h>
11 #include <linux/ctype.h>
13 #include <linux/slab.h>
14 #include <asm/sn/sgi.h>
15 #include <asm/sn/invent.h>
16 #include <asm/sn/hcl.h>
17 #include <asm/sn/labelcl.h>
18 #include <asm/sn/pci/bridge.h>
19 #include <asm/sn/ioerror_handling.h>
20 #include <asm/sn/pci/pciio.h>
21 #include <asm/sn/slotnum.h>
24 snia_kmem_zalloc(size_t size, int flag)
26 void *ptr = kmalloc(size, GFP_KERNEL);
33 snia_kmem_free(void *ptr, size_t size)
39 * the alloc/free_node routines do a simple kmalloc for now ..
42 snia_kmem_alloc_node(register size_t size, register int flags, cnodeid_t node)
44 /* someday will Allocate on node 'node' */
45 return(kmalloc(size, GFP_KERNEL));
49 snia_kmem_zalloc_node(register size_t size, register int flags, cnodeid_t node)
51 void *ptr = kmalloc(size, GFP_KERNEL);
58 #define xtod(c) ((c) <= '9' ? '0' - (c) : 'a' - (c) - 10)
60 atoi(register char *p)
63 register int c, neg = 0;
68 if (!isdigit(c = *p)) {
74 case '+': /* fall-through */
80 if (c == '0' && *(p + 1) == 'x') {
84 while ((c = *++p) && isxdigit(c)) {
85 n *= 16; /* two steps to avoid unnecessary overflow */
86 n += xtod(c); /* accum neg to avoid surprises at MAX */
90 while ((c = *++p) && isdigit(c)) {
91 n *= 10; /* two steps to avoid unnecessary overflow */
92 n += '0' - c; /* accum neg to avoid surprises at MAX */
95 return (neg ? n : -n);
99 * print_register() allows formatted printing of bit fields. individual
100 * bit fields are described by a struct reg_desc, multiple bit fields within
101 * a single word can be described by multiple reg_desc structures.
102 * %r outputs a string of the format "<bit field descriptions>"
103 * %R outputs a string of the format "0x%x<bit field descriptions>"
105 * The fields in a reg_desc are:
106 * unsigned long long rd_mask; An appropriate mask to isolate the bit field
107 * within a word, and'ed with val
109 * int rd_shift; A shift amount to be done to the isolated
110 * bit field. done before printing the isolate
111 * bit field with rd_format and before searching
112 * for symbolic value names in rd_values
114 * char *rd_name; If non-null, a bit field name to label any
115 * out from rd_format or searching rd_values.
116 * if neither rd_format or rd_values is non-null
117 * rd_name is printed only if the isolated
118 * bit field is non-null.
120 * char *rd_format; If non-null, the shifted bit field value
121 * is printed using this format.
123 * struct reg_values *rd_values; If non-null, a pointer to a table
124 * matching numeric values with symbolic names.
125 * rd_values are searched and the symbolic
126 * value is printed if a match is found, if no
127 * match is found "???" is printed.
132 print_register(unsigned long long reg, struct reg_desc *addr)
134 register struct reg_desc *rd;
135 register struct reg_values *rv;
136 unsigned long long field;
141 for (rd = addr; rd->rd_mask; rd++) {
142 field = reg & rd->rd_mask;
143 field = (rd->rd_shift > 0) ? field << rd->rd_shift : field >> -rd->rd_shift;
144 if (any && (rd->rd_format || rd->rd_values || (rd->rd_name && field)))
147 if (rd->rd_format || rd->rd_values || field) {
148 printk("%s", rd->rd_name);
151 if (rd->rd_format || rd->rd_values) {
156 /* You can have any format so long as it is %x */
158 printk("%llx", field);
165 for (rv = rd->rd_values; rv->rv_name; rv++) {
166 if (field == rv->rv_value) {
167 printk("%s", rv->rv_name);
171 if (rv->rv_name == NULL)