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
6 * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
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);
25 pcibr_hints_get(vertex_hdl_t xconn_vhdl
, int alloc
)
27 arbitrary_info_t ainfo
= 0;
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
);
37 printk(KERN_WARNING
"pcibr_hints_get(): unable to allocate "
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
,
47 (arbitrary_info_t
) hint
);
48 if (rv
!= GRAPH_SUCCESS
)
51 rv
= hwgraph_info_get_LBL(xconn_vhdl
, INFO_LBL_PCIBR_HINTS
, &ainfo
);
53 if (rv
!= GRAPH_SUCCESS
)
56 if (ainfo
!= (arbitrary_info_t
) hint
)
59 return (pcibr_hints_t
) ainfo
;
68 pcibr_hints_fix_some_rrbs(vertex_hdl_t xconn_vhdl
, unsigned mask
)
70 pcibr_hints_t hint
= pcibr_hints_get(xconn_vhdl
, 1);
73 hint
->ph_rrb_fixed
= mask
;
75 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS
, xconn_vhdl
,
76 "pcibr_hints_fix_rrbs: pcibr_hints_get failed\n"));
80 pcibr_hints_fix_rrbs(vertex_hdl_t xconn_vhdl
)
82 pcibr_hints_fix_some_rrbs(xconn_vhdl
, 0xFF);
86 pcibr_hints_dualslot(vertex_hdl_t xconn_vhdl
,
90 pcibr_hints_t hint
= pcibr_hints_get(xconn_vhdl
, 1);
93 hint
->ph_host_slot
[guest
] = host
+ 1;
95 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS
, xconn_vhdl
,
96 "pcibr_hints_dualslot: pcibr_hints_get failed\n"));
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);
106 hint
->ph_intr_bits
= xxx_intr_bits
;
108 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS
, xconn_vhdl
,
109 "pcibr_hints_intr_bits: pcibr_hints_get failed\n"));
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);
118 hint
->rrb_alloc_funct
= rrb_alloc_funct
;
122 pcibr_hints_handsoff(vertex_hdl_t xconn_vhdl
)
124 pcibr_hints_t hint
= pcibr_hints_get(xconn_vhdl
, 1);
127 hint
->ph_hands_off
= 1;
129 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS
, xconn_vhdl
,
130 "pcibr_hints_handsoff: pcibr_hints_get failed\n"));
134 pcibr_hints_subdevs(vertex_hdl_t xconn_vhdl
,
138 arbitrary_info_t ainfo
= 0;
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"));
149 hwgraph_info_get_LBL(pconn_vhdl
, INFO_LBL_SUBDEVS
, &ainfo
);
153 subdevp
= kmalloc(sizeof (*(subdevp
)), GFP_KERNEL
);
155 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS
, xconn_vhdl
,
156 "pcibr_hints_subdevs: subdev ptr alloc failed\n"));
159 memset(subdevp
, 0, sizeof (*(subdevp
)));
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
)
166 if (ainfo
== (arbitrary_info_t
) NULL
) {
167 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS
, xconn_vhdl
,
168 "pcibr_hints_subdevs: null subdevs ptr\n"));
171 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS
, xconn_vhdl
,
172 "pcibr_subdevs_get: dup subdev add_LBL\n"));
174 *(uint64_t *) ainfo
= subdevs
;