initial commit with v2.6.9
[linux-2.6.9-moxart.git] / arch / ia64 / sn / io / sn2 / pcibr / pcibr_hints.c
blob7bb247257fa239ba3b27c563960ffc87b779a6c8
1 /*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
6 * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
7 */
9 #include <linux/types.h>
10 #include <asm/sn/sgi.h>
11 #include <asm/sn/iograph.h>
12 #include <asm/sn/pci/pcibr.h>
13 #include <asm/sn/pci/pcibr_private.h>
14 #include <asm/sn/pci/pci_defs.h>
16 pcibr_hints_t pcibr_hints_get(vertex_hdl_t, int);
17 void pcibr_hints_fix_rrbs(vertex_hdl_t);
18 void pcibr_hints_dualslot(vertex_hdl_t, pciio_slot_t, pciio_slot_t);
19 void pcibr_hints_intr_bits(vertex_hdl_t, pcibr_intr_bits_f *);
20 void pcibr_set_rrb_callback(vertex_hdl_t, rrb_alloc_funct_t);
21 void pcibr_hints_handsoff(vertex_hdl_t);
22 void pcibr_hints_subdevs(vertex_hdl_t, pciio_slot_t, uint64_t);
24 pcibr_hints_t
25 pcibr_hints_get(vertex_hdl_t xconn_vhdl, int alloc)
27 arbitrary_info_t ainfo = 0;
28 graph_error_t rv;
29 pcibr_hints_t hint;
31 rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo);
33 if (alloc && (rv != GRAPH_SUCCESS)) {
35 hint = kmalloc(sizeof (*(hint)), GFP_KERNEL);
36 if ( !hint ) {
37 printk(KERN_WARNING "pcibr_hints_get(): unable to allocate "
38 "memory\n");
39 goto abnormal_exit;
41 memset(hint, 0, sizeof (*(hint)));
43 hint->rrb_alloc_funct = NULL;
44 hint->ph_intr_bits = NULL;
45 rv = hwgraph_info_add_LBL(xconn_vhdl,
46 INFO_LBL_PCIBR_HINTS,
47 (arbitrary_info_t) hint);
48 if (rv != GRAPH_SUCCESS)
49 goto abnormal_exit;
51 rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo);
53 if (rv != GRAPH_SUCCESS)
54 goto abnormal_exit;
56 if (ainfo != (arbitrary_info_t) hint)
57 goto abnormal_exit;
59 return (pcibr_hints_t) ainfo;
61 abnormal_exit:
62 kfree(hint);
63 return NULL;
67 void
68 pcibr_hints_fix_some_rrbs(vertex_hdl_t xconn_vhdl, unsigned mask)
70 pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1);
72 if (hint)
73 hint->ph_rrb_fixed = mask;
74 else
75 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
76 "pcibr_hints_fix_rrbs: pcibr_hints_get failed\n"));
79 void
80 pcibr_hints_fix_rrbs(vertex_hdl_t xconn_vhdl)
82 pcibr_hints_fix_some_rrbs(xconn_vhdl, 0xFF);
85 void
86 pcibr_hints_dualslot(vertex_hdl_t xconn_vhdl,
87 pciio_slot_t host,
88 pciio_slot_t guest)
90 pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1);
92 if (hint)
93 hint->ph_host_slot[guest] = host + 1;
94 else
95 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
96 "pcibr_hints_dualslot: pcibr_hints_get failed\n"));
99 void
100 pcibr_hints_intr_bits(vertex_hdl_t xconn_vhdl,
101 pcibr_intr_bits_f *xxx_intr_bits)
103 pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1);
105 if (hint)
106 hint->ph_intr_bits = xxx_intr_bits;
107 else
108 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
109 "pcibr_hints_intr_bits: pcibr_hints_get failed\n"));
112 void
113 pcibr_set_rrb_callback(vertex_hdl_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct)
115 pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1);
117 if (hint)
118 hint->rrb_alloc_funct = rrb_alloc_funct;
121 void
122 pcibr_hints_handsoff(vertex_hdl_t xconn_vhdl)
124 pcibr_hints_t hint = pcibr_hints_get(xconn_vhdl, 1);
126 if (hint)
127 hint->ph_hands_off = 1;
128 else
129 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
130 "pcibr_hints_handsoff: pcibr_hints_get failed\n"));
133 void
134 pcibr_hints_subdevs(vertex_hdl_t xconn_vhdl,
135 pciio_slot_t slot,
136 uint64_t subdevs)
138 arbitrary_info_t ainfo = 0;
139 char sdname[16];
140 vertex_hdl_t pconn_vhdl = GRAPH_VERTEX_NONE;
142 sprintf(sdname, "%s/%d", EDGE_LBL_PCI, slot);
143 (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl);
144 if (pconn_vhdl == GRAPH_VERTEX_NONE) {
145 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
146 "pcibr_hints_subdevs: hwgraph_path_create failed\n"));
147 return;
149 hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
150 if (ainfo == 0) {
151 uint64_t *subdevp;
153 subdevp = kmalloc(sizeof (*(subdevp)), GFP_KERNEL);
154 if (!subdevp) {
155 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
156 "pcibr_hints_subdevs: subdev ptr alloc failed\n"));
157 return;
159 memset(subdevp, 0, sizeof (*(subdevp)));
160 *subdevp = subdevs;
161 hwgraph_info_add_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, (arbitrary_info_t) subdevp);
162 hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
163 if (ainfo == (arbitrary_info_t) subdevp)
164 return;
165 kfree(subdevp);
166 if (ainfo == (arbitrary_info_t) NULL) {
167 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
168 "pcibr_hints_subdevs: null subdevs ptr\n"));
169 return;
171 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, xconn_vhdl,
172 "pcibr_subdevs_get: dup subdev add_LBL\n"));
174 *(uint64_t *) ainfo = subdevs;