1 /* $Id$
2  *
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
5  * for more details.
6  *
7  * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
8  */
9 
10 #include <linux/types.h>
11 #include <linux/ctype.h>
12 #include <linux/mm.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>
22 
23 void *
snia_kmem_zalloc(size_t size)24 snia_kmem_zalloc(size_t size)
25 {
26         void *ptr = kmalloc(size, GFP_KERNEL);
27 	if ( ptr )
28         	memset(ptr, 0, size);
29         return(ptr);
30 }
31 
32 void
snia_kmem_free(void * ptr,size_t size)33 snia_kmem_free(void *ptr, size_t size)
34 {
35         kfree(ptr);
36 }
37 
38 /*
39  * the alloc/free_node routines do a simple kmalloc for now ..
40  */
41 void *
snia_kmem_alloc_node(register size_t size,cnodeid_t node)42 snia_kmem_alloc_node(register size_t size, cnodeid_t node)
43 {
44 	/* someday will Allocate on node 'node' */
45 	return(kmalloc(size, GFP_KERNEL));
46 }
47 
48 
49 /*
50  * print_register() allows formatted printing of bit fields.  individual
51  * bit fields are described by a struct reg_desc, multiple bit fields within
52  * a single word can be described by multiple reg_desc structures.
53  * %r outputs a string of the format "<bit field descriptions>"
54  * %R outputs a string of the format "0x%x<bit field descriptions>"
55  *
56  * The fields in a reg_desc are:
57  *	unsigned long long rd_mask; An appropriate mask to isolate the bit field
58  *				within a word, and'ed with val
59  *
60  *	int rd_shift;		A shift amount to be done to the isolated
61  *				bit field.  done before printing the isolate
62  *				bit field with rd_format and before searching
63  *				for symbolic value names in rd_values
64  *
65  *	char *rd_name;		If non-null, a bit field name to label any
66  *				out from rd_format or searching rd_values.
67  *				if neither rd_format or rd_values is non-null
68  *				rd_name is printed only if the isolated
69  *				bit field is non-null.
70  *
71  *	char *rd_format;	If non-null, the shifted bit field value
72  *				is printed using this format.
73  *
74  *	struct reg_values *rd_values;	If non-null, a pointer to a table
75  *				matching numeric values with symbolic names.
76  *				rd_values are searched and the symbolic
77  *				value is printed if a match is found, if no
78  *				match is found "???" is printed.
79  *
80  */
81 
82 void
print_register(unsigned long long reg,struct reg_desc * addr)83 print_register(unsigned long long reg, struct reg_desc *addr)
84 {
85 	register struct reg_desc *rd;
86 	register struct reg_values *rv;
87 	unsigned long long field;
88 	int any;
89 
90 	printk("<");
91 	any = 0;
92 	for (rd = addr; rd->rd_mask; rd++) {
93 		field = reg & rd->rd_mask;
94 		field = (rd->rd_shift > 0) ? field << rd->rd_shift : field >> -rd->rd_shift;
95 		if (any && (rd->rd_format || rd->rd_values || (rd->rd_name && field)))
96 			printk(",");
97 		if (rd->rd_name) {
98 			if (rd->rd_format || rd->rd_values || field) {
99 				printk("%s", rd->rd_name);
100 				any = 1;
101 			}
102 			if (rd->rd_format || rd->rd_values) {
103 				printk("=");
104 				any = 1;
105 			}
106 		}
107 		/* You can have any format so long as it is %x */
108 		if (rd->rd_format) {
109 			printk("%llx", field);
110 			any = 1;
111 			if (rd->rd_values)
112 				printk(":");
113 		}
114 		if (rd->rd_values) {
115 			any = 1;
116 			for (rv = rd->rd_values; rv->rv_name; rv++) {
117 				if (field == rv->rv_value) {
118 					printk("%s", rv->rv_name);
119 					break;
120 				}
121 			}
122 			if (rv->rv_name == NULL)
123 				printk("???");
124 		}
125 	}
126 	printk(">\n");
127 }
128