Deleted Added
full compact
ofw_pci.c (90613) ofw_pci.c (93067)
1/*
2 * Copyright (c) 1999, 2000 Matthew R. Green
3 * All rights reserved.
4 * Copyright 2001 by Thomas Moestl <tmm@FreeBSD.org>. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 14 unchanged lines hidden (view full) ---

23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * from: NetBSD: psycho.c,v 1.35 2001/09/10 16:17:06 eeh Exp
30 *
1/*
2 * Copyright (c) 1999, 2000 Matthew R. Green
3 * All rights reserved.
4 * Copyright 2001 by Thomas Moestl <tmm@FreeBSD.org>. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 14 unchanged lines hidden (view full) ---

23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * from: NetBSD: psycho.c,v 1.35 2001/09/10 16:17:06 eeh Exp
30 *
31 * $FreeBSD: head/sys/sparc64/pci/ofw_pci.c 90613 2002-02-13 15:44:58Z tmm $
31 * $FreeBSD: head/sys/sparc64/pci/ofw_pci.c 93067 2002-03-24 02:11:06Z tmm $
32 */
33
34#include "opt_ofw_pci.h"
35
36#include <sys/param.h>
37#include <sys/kernel.h>
38#include <sys/systm.h>
39#include <sys/bus.h>

--- 5 unchanged lines hidden (view full) ---

45#include <dev/ofw/openfirm.h>
46
47#include <sparc64/pci/ofw_pci.h>
48
49#include <machine/ofw_bus.h>
50
51#include "pcib_if.h"
52
32 */
33
34#include "opt_ofw_pci.h"
35
36#include <sys/param.h>
37#include <sys/kernel.h>
38#include <sys/systm.h>
39#include <sys/bus.h>

--- 5 unchanged lines hidden (view full) ---

45#include <dev/ofw/openfirm.h>
46
47#include <sparc64/pci/ofw_pci.h>
48
49#include <machine/ofw_bus.h>
50
51#include "pcib_if.h"
52
53/*
54 * Find the interrupt-map properties for a node. This might not be a property
55 * of the parent, because there may be bridges in between, so go up through the
56 * tree to find it.
57 * This seems to be only needed for PCI systems, so it has not been moved to
58 * ofw_bus.c
59 */
60int
61ofw_pci_find_imap(phandle_t node, struct ofw_pci_imap **imap,
62 struct ofw_pci_imap_msk *imapmsk)
53u_int32_t
54ofw_pci_route_intr(phandle_t node)
63{
55{
64 int nimap;
56 u_int32_t rv;
65
57
66 nimap = -1;
67 while ((node = OF_parent(node)) != 0) {
68 if ((nimap = OF_getprop_alloc(node, "interrupt-map",
69 sizeof(**imap), (void **)imap)) == -1 ||
70 OF_getprop(node, "interrupt-map-mask",
71 imapmsk, sizeof(*imapmsk)) == -1) {
72 if (*imap != NULL) {
73 free(*imap, M_OFWPROP);
74 *imap = NULL;
75 }
76 nimap = -1;
77 } else
78 break;
79 }
80 return (nimap);
81}
82
83/*
84 * Route an interrupt using the firmware nodes. Returns 255 for interrupts
85 * that cannot be routed (suitable for the PCI code).
86 */
87int
88ofw_pci_route_intr2(int intr, struct ofw_pci_register *pcir,
89 struct ofw_pci_imap *imap, int nimap, struct ofw_pci_imap_msk *imapmsk)
90{
91 char regm[12];
92 int cintr;
93
94 cintr = ofw_bus_route_intr(intr, pcir, sizeof(*pcir), 12, 1, imap,
95 nimap, imapmsk, regm);
96 if (cintr == -1)
58 rv = ofw_bus_route_intr(node, ORIP_NOINT);
59 if (rv == ORIR_NOTFOUND)
97 return (255);
60 return (255);
98 else
99 return (cintr);
61 return (rv);
100}
101
62}
63
102int
103ofw_pci_route_intr(phandle_t node, struct ofw_pci_register *pcir,
104 struct ofw_pci_imap *intrmap, int nintrmap,
105 struct ofw_pci_imap_msk *intrmapmsk)
106{
107 int intr;
108
109 if (OF_getprop(node, "interrupts", &intr, sizeof(intr)) == -1)
110 return (255);
111
112 return (ofw_pci_route_intr2(intr, pcir, intrmap, nintrmap, intrmapmsk));
113}
114
115#define OFW_PCI_PCIBUS "pci"
116/*
117 * Walk the PCI bus hierarchy, starting with the root PCI bus and descending
118 * through bridges, and initialize the interrupt line configuration registers
119 * of attached devices using firmware information.
120 */
121void
64#define OFW_PCI_PCIBUS "pci"
65/*
66 * Walk the PCI bus hierarchy, starting with the root PCI bus and descending
67 * through bridges, and initialize the interrupt line configuration registers
68 * of attached devices using firmware information.
69 */
70void
122ofw_pci_init_intr(device_t dev, phandle_t bus, struct ofw_pci_imap *intrmap,
123 int nintrmap, struct ofw_pci_imap_msk *intrmapmsk)
71ofw_pci_init_intr(device_t dev, phandle_t bus)
124{
72{
125 struct ofw_pci_imap_msk lintrmapmsk;
126 struct ofw_pci_register pcir;
127 phandle_t node;
128 char type[32];
129 int intr;
130 int freemap;
131
132 if ((node = OF_child(bus)) == 0)
133 return;

--- 7 unchanged lines hidden (view full) ---

141 type[sizeof(type) - 1] = '\0';
142 if (strcmp(type, OFW_PCI_PCIBUS) == 0) {
143 /*
144 * This is a pci-pci bridge, recurse to initialize the
145 * child bus. The hierarchy is usually at most 2 levels
146 * deep, so recursion is feasible.
147 */
148#ifdef OFW_PCI_DEBUG
73 struct ofw_pci_register pcir;
74 phandle_t node;
75 char type[32];
76 int intr;
77 int freemap;
78
79 if ((node = OF_child(bus)) == 0)
80 return;

--- 7 unchanged lines hidden (view full) ---

88 type[sizeof(type) - 1] = '\0';
89 if (strcmp(type, OFW_PCI_PCIBUS) == 0) {
90 /*
91 * This is a pci-pci bridge, recurse to initialize the
92 * child bus. The hierarchy is usually at most 2 levels
93 * deep, so recursion is feasible.
94 */
95#ifdef OFW_PCI_DEBUG
149 device_printf(dev, __func__": descending to "
150 "subordinate PCI bus\n");
96 device_printf(dev, "%s: descending to "
97 "subordinate PCI bus\n", __func__);
151#endif
98#endif
152 ofw_pci_init_intr(dev, node, NULL, 0, NULL);
99 ofw_pci_init_intr(dev, node);
153 } else {
154 if (OF_getprop(node, "reg", &pcir, sizeof(pcir)) == -1)
155 panic("ofw_pci_route_intr: OF_getprop failed");
100 } else {
101 if (OF_getprop(node, "reg", &pcir, sizeof(pcir)) == -1)
102 panic("ofw_pci_route_intr: OF_getprop failed");
156 /*
157 * If we didn't get interrupt map properties passed,
158 * try to find them now. On some systems, buses that
159 * have no non-bridge children have no such properties,
160 * so only try to find them at need.
161 */
162 if (intrmap == NULL) {
163 nintrmap = OF_getprop_alloc(bus,
164 "interrupt-map", sizeof(*intrmap),
165 (void **)&intrmap);
166 if (nintrmap == -1 ||
167 OF_getprop(bus, "interrupt-map-mask",
168 &lintrmapmsk, sizeof(lintrmapmsk)) == -1) {
169 printf("ofw_pci_init_intr: could not get "
170 "interrupt map properties\n");
171 if (nintrmap != -1)
172 free(intrmap, M_OFWPROP);
173 return;
174 }
175 intrmapmsk = &lintrmapmsk;
176 freemap = 1;
177 }
178 if ((intr = ofw_pci_route_intr(node, &pcir, intrmap,
179 nintrmap, intrmapmsk)) != 255) {
103
104 if ((intr = ofw_pci_route_intr(node)) != 255) {
180#ifdef OFW_PCI_DEBUG
105#ifdef OFW_PCI_DEBUG
181 device_printf(dev, __func__": mapping intr for "
106 device_printf(dev, "%s: mapping intr for "
182 "%d/%d/%d to %d (preset was %d)\n",
107 "%d/%d/%d to %d (preset was %d)\n",
108 __func__,
183 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi),
184 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi),
185 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi),
186 intr,
187 (int)PCIB_READ_CONFIG(dev,
188 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi),
189 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi),
190 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi),
191 PCIR_INTLINE, 1));
109 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi),
110 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi),
111 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi),
112 intr,
113 (int)PCIB_READ_CONFIG(dev,
114 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi),
115 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi),
116 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi),
117 PCIR_INTLINE, 1));
192
193#endif /* OFW_PCI_DEBUG */
194 PCIB_WRITE_CONFIG(dev,
195 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi),
196 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi),
197 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi),
198 PCIR_INTLINE, intr, 1);
199 } else {
200#ifdef OFW_PCI_DEBUG
118#endif /* OFW_PCI_DEBUG */
119 PCIB_WRITE_CONFIG(dev,
120 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi),
121 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi),
122 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi),
123 PCIR_INTLINE, intr, 1);
124 } else {
125#ifdef OFW_PCI_DEBUG
201 device_printf(dev, __func__": no interrupt "
126 device_printf(dev, "%s: no interrupt "
202 "mapping found for %d/%d/%d (preset %d)\n",
127 "mapping found for %d/%d/%d (preset %d)\n",
128 __func__,
203 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi),
204 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi),
205 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi),
206 (int)PCIB_READ_CONFIG(dev,
207 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi),
208 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi),
209 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi),
210 PCIR_INTLINE, 1));
211#endif /* OFW_PCI_DEBUG */
212 /* The firmware initializes to 0 instead 255 */
213 PCIB_WRITE_CONFIG(dev,
214 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi),
215 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi),
216 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi),
217 PCIR_INTLINE, 255, 1);
218 }
219 }
220 } while ((node = OF_peer(node)) != 0);
129 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi),
130 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi),
131 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi),
132 (int)PCIB_READ_CONFIG(dev,
133 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi),
134 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi),
135 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi),
136 PCIR_INTLINE, 1));
137#endif /* OFW_PCI_DEBUG */
138 /* The firmware initializes to 0 instead 255 */
139 PCIB_WRITE_CONFIG(dev,
140 OFW_PCI_PHYS_HI_BUS(pcir.phys_hi),
141 OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi),
142 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi),
143 PCIR_INTLINE, 255, 1);
144 }
145 }
146 } while ((node = OF_peer(node)) != 0);
221 if (freemap)
222 free(intrmap, M_OFWPROP);
223}
224
225phandle_t
226ofw_pci_find_node(int bus, int slot, int func)
227{
228 phandle_t node, bnode, parent;
229 struct ofw_pci_register pcir;
230 int br[2];

--- 32 unchanged lines hidden (view full) ---

263 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi) == func) {
264 if (OFW_PCI_PHYS_HI_BUS(pcir.phys_hi) != bus)
265 panic("ofw_pci_find_node: bus number mismatch");
266 return (node);
267 }
268 }
269 return (0);
270}
147}
148
149phandle_t
150ofw_pci_find_node(int bus, int slot, int func)
151{
152 phandle_t node, bnode, parent;
153 struct ofw_pci_register pcir;
154 int br[2];

--- 32 unchanged lines hidden (view full) ---

187 OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi) == func) {
188 if (OFW_PCI_PHYS_HI_BUS(pcir.phys_hi) != bus)
189 panic("ofw_pci_find_node: bus number mismatch");
190 return (node);
191 }
192 }
193 return (0);
194}
195
196phandle_t
197ofw_pci_node(device_t dev)
198{
199
200 return (ofw_pci_find_node(pci_get_bus(dev), pci_get_slot(dev),
201 pci_get_function(dev)));
202}