1*84ceaea9SAndy Fiddaman /*
2*84ceaea9SAndy Fiddaman * This file and its contents are supplied under the terms of the
3*84ceaea9SAndy Fiddaman * Common Development and Distribution License ("CDDL"), version 1.0.
4*84ceaea9SAndy Fiddaman * You may only use this file in accordance with the terms of version
5*84ceaea9SAndy Fiddaman * 1.0 of the CDDL.
6*84ceaea9SAndy Fiddaman *
7*84ceaea9SAndy Fiddaman * A full copy of the text of the CDDL should have accompanied this
8*84ceaea9SAndy Fiddaman * source. A copy of the CDDL is also available via the Internet at
9*84ceaea9SAndy Fiddaman * http://www.illumos.org/license/CDDL.
10*84ceaea9SAndy Fiddaman */
11*84ceaea9SAndy Fiddaman
12*84ceaea9SAndy Fiddaman /*
13*84ceaea9SAndy Fiddaman * Copyright 2023 Oxide Computer Company
14*84ceaea9SAndy Fiddaman */
15*84ceaea9SAndy Fiddaman
16*84ceaea9SAndy Fiddaman /*
17*84ceaea9SAndy Fiddaman * This provides the basic mechanisms for dealing with the pcie schema. A pcie
18*84ceaea9SAndy Fiddaman * FMRI has the form:
19*84ceaea9SAndy Fiddaman *
20*84ceaea9SAndy Fiddaman * pcie:///cpu=C[/root-complex=R[function=F[...]]]
21*84ceaea9SAndy Fiddaman *
22*84ceaea9SAndy Fiddaman * That is to say that the top level nodes represent physical CPUs in the
23*84ceaea9SAndy Fiddaman * system and their PCIe root complexes are enumerated directly under that.
24*84ceaea9SAndy Fiddaman *
25*84ceaea9SAndy Fiddaman * Each node inherits the FMRI of its parent, and then appends a new
26*84ceaea9SAndy Fiddaman * '/<type>=<instance>' part, for example:
27*84ceaea9SAndy Fiddaman *
28*84ceaea9SAndy Fiddaman * pcie:///cpu=0
29*84ceaea9SAndy Fiddaman * pcie:///cpu=0/root-complex=0
30*84ceaea9SAndy Fiddaman * pcie:///cpu=0/root-complex=0/function=0
31*84ceaea9SAndy Fiddaman * pcie:///cpu=0/root-complex=0/function=0/port=0
32*84ceaea9SAndy Fiddaman *
33*84ceaea9SAndy Fiddaman * Types used in the scheme are:
34*84ceaea9SAndy Fiddaman * cpu
35*84ceaea9SAndy Fiddaman * root-complex
36*84ceaea9SAndy Fiddaman * device
37*84ceaea9SAndy Fiddaman * function
38*84ceaea9SAndy Fiddaman * port
39*84ceaea9SAndy Fiddaman * link
40*84ceaea9SAndy Fiddaman */
41*84ceaea9SAndy Fiddaman
42*84ceaea9SAndy Fiddaman #include <stdio.h>
43*84ceaea9SAndy Fiddaman #include <stdlib.h>
44*84ceaea9SAndy Fiddaman #include <string.h>
45*84ceaea9SAndy Fiddaman #include <errno.h>
46*84ceaea9SAndy Fiddaman #include <stdbool.h>
47*84ceaea9SAndy Fiddaman #include <ctype.h>
48*84ceaea9SAndy Fiddaman #include <alloca.h>
49*84ceaea9SAndy Fiddaman #include <limits.h>
50*84ceaea9SAndy Fiddaman #include <fm/topo_mod.h>
51*84ceaea9SAndy Fiddaman #include <sys/param.h>
52*84ceaea9SAndy Fiddaman #include <sys/systeminfo.h>
53*84ceaea9SAndy Fiddaman #include <sys/fm/protocol.h>
54*84ceaea9SAndy Fiddaman #include <sys/stat.h>
55*84ceaea9SAndy Fiddaman
56*84ceaea9SAndy Fiddaman #include <topo_method.h>
57*84ceaea9SAndy Fiddaman #include <topo_subr.h>
58*84ceaea9SAndy Fiddaman #include <pthread.h>
59*84ceaea9SAndy Fiddaman
60*84ceaea9SAndy Fiddaman #include <pcie.h>
61*84ceaea9SAndy Fiddaman
62*84ceaea9SAndy Fiddaman static size_t
fmri_nvl2str(nvlist_t * nvl,char * buf,size_t buflen)63*84ceaea9SAndy Fiddaman fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen)
64*84ceaea9SAndy Fiddaman {
65*84ceaea9SAndy Fiddaman size_t size = 0;
66*84ceaea9SAndy Fiddaman uint8_t version;
67*84ceaea9SAndy Fiddaman nvlist_t **plist;
68*84ceaea9SAndy Fiddaman uint_t nplist;
69*84ceaea9SAndy Fiddaman int err;
70*84ceaea9SAndy Fiddaman
71*84ceaea9SAndy Fiddaman if (nvlist_lookup_uint8(nvl, FM_VERSION, &version) != 0 ||
72*84ceaea9SAndy Fiddaman version > FM_PCIE_SCHEME_VERSION) {
73*84ceaea9SAndy Fiddaman return (0);
74*84ceaea9SAndy Fiddaman }
75*84ceaea9SAndy Fiddaman
76*84ceaea9SAndy Fiddaman if (!topo_fmristr_build(&size, buf, buflen, FM_FMRI_SCHEME_PCIE, NULL,
77*84ceaea9SAndy Fiddaman ":///")) {
78*84ceaea9SAndy Fiddaman return (0);
79*84ceaea9SAndy Fiddaman }
80*84ceaea9SAndy Fiddaman
81*84ceaea9SAndy Fiddaman err = nvlist_lookup_nvlist_array(nvl, FM_FMRI_PCIE_LIST,
82*84ceaea9SAndy Fiddaman &plist, &nplist);
83*84ceaea9SAndy Fiddaman if (err != 0 || plist == NULL)
84*84ceaea9SAndy Fiddaman return (0);
85*84ceaea9SAndy Fiddaman
86*84ceaea9SAndy Fiddaman for (uint_t i = 0; i < nplist; i++) {
87*84ceaea9SAndy Fiddaman char *name = NULL;
88*84ceaea9SAndy Fiddaman char *id = NULL;
89*84ceaea9SAndy Fiddaman
90*84ceaea9SAndy Fiddaman if (i > 0) {
91*84ceaea9SAndy Fiddaman if (!topo_fmristr_build(&size, buf, buflen, "/", NULL,
92*84ceaea9SAndy Fiddaman NULL)) {
93*84ceaea9SAndy Fiddaman return (0);
94*84ceaea9SAndy Fiddaman }
95*84ceaea9SAndy Fiddaman }
96*84ceaea9SAndy Fiddaman if (nvlist_lookup_string(plist[i],
97*84ceaea9SAndy Fiddaman FM_FMRI_PCIE_NAME, &name) != 0 ||
98*84ceaea9SAndy Fiddaman nvlist_lookup_string(plist[i],
99*84ceaea9SAndy Fiddaman FM_FMRI_PCIE_ID, &id) != 0) {
100*84ceaea9SAndy Fiddaman return (0);
101*84ceaea9SAndy Fiddaman }
102*84ceaea9SAndy Fiddaman if (name == NULL || id == NULL)
103*84ceaea9SAndy Fiddaman return (0);
104*84ceaea9SAndy Fiddaman if (!topo_fmristr_build(&size, buf, buflen, "=", name, id))
105*84ceaea9SAndy Fiddaman return (0);
106*84ceaea9SAndy Fiddaman }
107*84ceaea9SAndy Fiddaman
108*84ceaea9SAndy Fiddaman return (size);
109*84ceaea9SAndy Fiddaman }
110*84ceaea9SAndy Fiddaman
111*84ceaea9SAndy Fiddaman static int
pcie_fmri_nvl2str(topo_mod_t * mod,tnode_t * node,topo_version_t version,nvlist_t * nvl,nvlist_t ** out)112*84ceaea9SAndy Fiddaman pcie_fmri_nvl2str(topo_mod_t *mod, tnode_t *node, topo_version_t version,
113*84ceaea9SAndy Fiddaman nvlist_t *nvl, nvlist_t **out)
114*84ceaea9SAndy Fiddaman {
115*84ceaea9SAndy Fiddaman size_t len;
116*84ceaea9SAndy Fiddaman char *name = NULL;
117*84ceaea9SAndy Fiddaman nvlist_t *fmristr;
118*84ceaea9SAndy Fiddaman
119*84ceaea9SAndy Fiddaman if (version > TOPO_METH_NVL2STR_VERSION)
120*84ceaea9SAndy Fiddaman return (topo_mod_seterrno(mod, EMOD_VER_NEW));
121*84ceaea9SAndy Fiddaman
122*84ceaea9SAndy Fiddaman if ((len = fmri_nvl2str(nvl, NULL, 0)) == 0)
123*84ceaea9SAndy Fiddaman return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
124*84ceaea9SAndy Fiddaman
125*84ceaea9SAndy Fiddaman if ((name = topo_mod_alloc(mod, len + 1)) == NULL)
126*84ceaea9SAndy Fiddaman return (topo_mod_seterrno(mod, EMOD_NOMEM));
127*84ceaea9SAndy Fiddaman
128*84ceaea9SAndy Fiddaman if (fmri_nvl2str(nvl, name, len + 1) == 0) {
129*84ceaea9SAndy Fiddaman topo_mod_free(mod, name, len + 1);
130*84ceaea9SAndy Fiddaman return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
131*84ceaea9SAndy Fiddaman }
132*84ceaea9SAndy Fiddaman
133*84ceaea9SAndy Fiddaman if (topo_mod_nvalloc(mod, &fmristr, NV_UNIQUE_NAME) != 0) {
134*84ceaea9SAndy Fiddaman topo_mod_free(mod, name, len + 1);
135*84ceaea9SAndy Fiddaman return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
136*84ceaea9SAndy Fiddaman }
137*84ceaea9SAndy Fiddaman if (nvlist_add_string(fmristr, "fmri-string", name) != 0) {
138*84ceaea9SAndy Fiddaman topo_mod_free(mod, name, len + 1);
139*84ceaea9SAndy Fiddaman nvlist_free(fmristr);
140*84ceaea9SAndy Fiddaman return (topo_mod_seterrno(mod, EMOD_FMRI_NVL));
141*84ceaea9SAndy Fiddaman }
142*84ceaea9SAndy Fiddaman topo_mod_free(mod, name, len + 1);
143*84ceaea9SAndy Fiddaman *out = fmristr;
144*84ceaea9SAndy Fiddaman
145*84ceaea9SAndy Fiddaman return (0);
146*84ceaea9SAndy Fiddaman }
147*84ceaea9SAndy Fiddaman
148*84ceaea9SAndy Fiddaman static nvlist_t *
fmri_create_err(topo_mod_t * mod,nvlist_t ** list,uint_t elems,nvlist_t * fmri,int err)149*84ceaea9SAndy Fiddaman fmri_create_err(topo_mod_t *mod, nvlist_t **list, uint_t elems,
150*84ceaea9SAndy Fiddaman nvlist_t *fmri, int err)
151*84ceaea9SAndy Fiddaman {
152*84ceaea9SAndy Fiddaman if (list != NULL) {
153*84ceaea9SAndy Fiddaman for (uint_t i = 0; i < elems; i++)
154*84ceaea9SAndy Fiddaman nvlist_free(list[i]);
155*84ceaea9SAndy Fiddaman
156*84ceaea9SAndy Fiddaman topo_mod_free(mod, list, sizeof (nvlist_t *) * elems);
157*84ceaea9SAndy Fiddaman }
158*84ceaea9SAndy Fiddaman
159*84ceaea9SAndy Fiddaman nvlist_free(fmri);
160*84ceaea9SAndy Fiddaman
161*84ceaea9SAndy Fiddaman (void) topo_mod_seterrno(mod, err);
162*84ceaea9SAndy Fiddaman
163*84ceaea9SAndy Fiddaman topo_mod_dprintf(mod, "unable to create pcie FMRI: %s\n",
164*84ceaea9SAndy Fiddaman topo_mod_errmsg(mod));
165*84ceaea9SAndy Fiddaman
166*84ceaea9SAndy Fiddaman return (NULL);
167*84ceaea9SAndy Fiddaman }
168*84ceaea9SAndy Fiddaman
169*84ceaea9SAndy Fiddaman static nvlist_t *
fmri_create_component(topo_mod_t * mod,const char * name,topo_instance_t inst)170*84ceaea9SAndy Fiddaman fmri_create_component(topo_mod_t *mod, const char *name, topo_instance_t inst)
171*84ceaea9SAndy Fiddaman {
172*84ceaea9SAndy Fiddaman char str[21]; /* decimal representation of UINT64_MAX + '\0' */
173*84ceaea9SAndy Fiddaman nvlist_t *comp;
174*84ceaea9SAndy Fiddaman
175*84ceaea9SAndy Fiddaman if (topo_mod_nvalloc(mod, &comp, NV_UNIQUE_NAME) != 0)
176*84ceaea9SAndy Fiddaman return (NULL);
177*84ceaea9SAndy Fiddaman
178*84ceaea9SAndy Fiddaman (void) snprintf(str, sizeof (str), "%" PRIu64, inst);
179*84ceaea9SAndy Fiddaman
180*84ceaea9SAndy Fiddaman if (nvlist_add_string(comp, FM_FMRI_PCIE_NAME, name) != 0 ||
181*84ceaea9SAndy Fiddaman nvlist_add_string(comp, FM_FMRI_PCIE_ID, str) != 0) {
182*84ceaea9SAndy Fiddaman nvlist_free(comp);
183*84ceaea9SAndy Fiddaman return (NULL);
184*84ceaea9SAndy Fiddaman }
185*84ceaea9SAndy Fiddaman
186*84ceaea9SAndy Fiddaman return (comp);
187*84ceaea9SAndy Fiddaman }
188*84ceaea9SAndy Fiddaman
189*84ceaea9SAndy Fiddaman static nvlist_t *
fmri_create(topo_mod_t * mod,nvlist_t * pfmri,const char * name,topo_instance_t inst,nvlist_t * auth)190*84ceaea9SAndy Fiddaman fmri_create(topo_mod_t *mod, nvlist_t *pfmri, const char *name,
191*84ceaea9SAndy Fiddaman topo_instance_t inst, nvlist_t *auth)
192*84ceaea9SAndy Fiddaman {
193*84ceaea9SAndy Fiddaman nvlist_t **pplist = NULL;
194*84ceaea9SAndy Fiddaman nvlist_t **plist = NULL;
195*84ceaea9SAndy Fiddaman nvlist_t *fmri = NULL;
196*84ceaea9SAndy Fiddaman uint_t pelems = 0, elems;
197*84ceaea9SAndy Fiddaman uint_t i;
198*84ceaea9SAndy Fiddaman
199*84ceaea9SAndy Fiddaman /*
200*84ceaea9SAndy Fiddaman * This FMRI will be constructed from the FMRI of the parent, with a
201*84ceaea9SAndy Fiddaman * new path component (name=inst) after it. We copy the parent's
202*84ceaea9SAndy Fiddaman * property list to this node, and then add our new property to the
203*84ceaea9SAndy Fiddaman * end.
204*84ceaea9SAndy Fiddaman */
205*84ceaea9SAndy Fiddaman
206*84ceaea9SAndy Fiddaman /* Retrieve the parent's property list */
207*84ceaea9SAndy Fiddaman if (pfmri != NULL) {
208*84ceaea9SAndy Fiddaman if (nvlist_lookup_nvlist_array(pfmri, FM_FMRI_PCIE_LIST,
209*84ceaea9SAndy Fiddaman &pplist, &pelems) != 0) {
210*84ceaea9SAndy Fiddaman return (fmri_create_err(mod, plist, pelems, fmri,
211*84ceaea9SAndy Fiddaman EMOD_FMRI_MALFORM));
212*84ceaea9SAndy Fiddaman }
213*84ceaea9SAndy Fiddaman }
214*84ceaea9SAndy Fiddaman
215*84ceaea9SAndy Fiddaman /* We want space for an extra entry in the new FMRI's property list */
216*84ceaea9SAndy Fiddaman elems = pelems + 1;
217*84ceaea9SAndy Fiddaman
218*84ceaea9SAndy Fiddaman plist = topo_mod_zalloc(mod, sizeof (nvlist_t *) * elems);
219*84ceaea9SAndy Fiddaman if (plist == NULL) {
220*84ceaea9SAndy Fiddaman return (fmri_create_err(mod, plist, elems, fmri,
221*84ceaea9SAndy Fiddaman ETOPO_FMRI_NOMEM));
222*84ceaea9SAndy Fiddaman }
223*84ceaea9SAndy Fiddaman
224*84ceaea9SAndy Fiddaman /* Copy the parent properties */
225*84ceaea9SAndy Fiddaman for (i = 0; i < pelems; i++) {
226*84ceaea9SAndy Fiddaman if (topo_mod_nvdup(mod, pplist[i], &plist[i]) != 0) {
227*84ceaea9SAndy Fiddaman return (fmri_create_err(mod, plist, elems, fmri,
228*84ceaea9SAndy Fiddaman EMOD_FMRI_NVL));
229*84ceaea9SAndy Fiddaman }
230*84ceaea9SAndy Fiddaman }
231*84ceaea9SAndy Fiddaman
232*84ceaea9SAndy Fiddaman /* Add the new path component */
233*84ceaea9SAndy Fiddaman if ((plist[i] = fmri_create_component(mod, name, inst)) == NULL) {
234*84ceaea9SAndy Fiddaman return (fmri_create_err(mod, plist, elems, fmri,
235*84ceaea9SAndy Fiddaman EMOD_FMRI_NVL));
236*84ceaea9SAndy Fiddaman }
237*84ceaea9SAndy Fiddaman
238*84ceaea9SAndy Fiddaman /* Create the fmri */
239*84ceaea9SAndy Fiddaman if (topo_mod_nvalloc(mod, &fmri, NV_UNIQUE_NAME) != 0) {
240*84ceaea9SAndy Fiddaman return (fmri_create_err(mod, plist, elems, fmri,
241*84ceaea9SAndy Fiddaman EMOD_FMRI_NVL));
242*84ceaea9SAndy Fiddaman }
243*84ceaea9SAndy Fiddaman
244*84ceaea9SAndy Fiddaman if (nvlist_add_uint8(fmri, FM_VERSION, FM_PCIE_SCHEME_VERSION) ||
245*84ceaea9SAndy Fiddaman nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_PCIE)) {
246*84ceaea9SAndy Fiddaman return (fmri_create_err(mod, plist, elems, fmri,
247*84ceaea9SAndy Fiddaman EMOD_FMRI_NVL));
248*84ceaea9SAndy Fiddaman }
249*84ceaea9SAndy Fiddaman
250*84ceaea9SAndy Fiddaman /* Add the new property list */
251*84ceaea9SAndy Fiddaman if (nvlist_add_nvlist_array(fmri, FM_FMRI_PCIE_LIST,
252*84ceaea9SAndy Fiddaman plist, elems) != 0) {
253*84ceaea9SAndy Fiddaman return (fmri_create_err(mod, plist, elems, fmri,
254*84ceaea9SAndy Fiddaman EMOD_FMRI_NVL));
255*84ceaea9SAndy Fiddaman }
256*84ceaea9SAndy Fiddaman
257*84ceaea9SAndy Fiddaman if (auth != NULL)
258*84ceaea9SAndy Fiddaman (void) nvlist_add_nvlist(fmri, FM_FMRI_AUTHORITY, auth);
259*84ceaea9SAndy Fiddaman
260*84ceaea9SAndy Fiddaman if (plist != NULL) {
261*84ceaea9SAndy Fiddaman for (uint_t i = 0; i < elems; i++)
262*84ceaea9SAndy Fiddaman nvlist_free(plist[i]);
263*84ceaea9SAndy Fiddaman topo_mod_free(mod, plist, sizeof (nvlist_t *) * elems);
264*84ceaea9SAndy Fiddaman }
265*84ceaea9SAndy Fiddaman
266*84ceaea9SAndy Fiddaman return (fmri);
267*84ceaea9SAndy Fiddaman }
268*84ceaea9SAndy Fiddaman
269*84ceaea9SAndy Fiddaman static int
pcie_fmri_create_meth(topo_mod_t * mod,tnode_t * tnode,topo_version_t version,nvlist_t * in,nvlist_t ** out)270*84ceaea9SAndy Fiddaman pcie_fmri_create_meth(topo_mod_t *mod, tnode_t *tnode, topo_version_t version,
271*84ceaea9SAndy Fiddaman nvlist_t *in, nvlist_t **out)
272*84ceaea9SAndy Fiddaman {
273*84ceaea9SAndy Fiddaman char *name;
274*84ceaea9SAndy Fiddaman topo_instance_t inst;
275*84ceaea9SAndy Fiddaman nvlist_t *args, *auth = NULL, *pfmri = NULL;
276*84ceaea9SAndy Fiddaman int ret;
277*84ceaea9SAndy Fiddaman
278*84ceaea9SAndy Fiddaman if (version > TOPO_METH_FMRI_VERSION)
279*84ceaea9SAndy Fiddaman return (topo_mod_seterrno(mod, EMOD_VER_NEW));
280*84ceaea9SAndy Fiddaman
281*84ceaea9SAndy Fiddaman if (nvlist_lookup_string(in, TOPO_METH_FMRI_ARG_NAME, &name) != 0 ||
282*84ceaea9SAndy Fiddaman nvlist_lookup_uint64(in, TOPO_METH_FMRI_ARG_INST, &inst) != 0) {
283*84ceaea9SAndy Fiddaman return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
284*84ceaea9SAndy Fiddaman }
285*84ceaea9SAndy Fiddaman
286*84ceaea9SAndy Fiddaman if ((ret = nvlist_lookup_nvlist(in, TOPO_METH_FMRI_ARG_NVL,
287*84ceaea9SAndy Fiddaman &args)) != 0) {
288*84ceaea9SAndy Fiddaman if (ret != ENOENT)
289*84ceaea9SAndy Fiddaman return (topo_mod_seterrno(mod, EMOD_METHOD_INVAL));
290*84ceaea9SAndy Fiddaman } else {
291*84ceaea9SAndy Fiddaman (void) nvlist_lookup_nvlist(args, TOPO_METH_FMRI_ARG_PARENT,
292*84ceaea9SAndy Fiddaman &pfmri);
293*84ceaea9SAndy Fiddaman (void) nvlist_lookup_nvlist(args, TOPO_METH_FMRI_ARG_AUTH,
294*84ceaea9SAndy Fiddaman &auth);
295*84ceaea9SAndy Fiddaman }
296*84ceaea9SAndy Fiddaman
297*84ceaea9SAndy Fiddaman *out = fmri_create(mod, pfmri, name, inst, auth);
298*84ceaea9SAndy Fiddaman if (*out == NULL)
299*84ceaea9SAndy Fiddaman return (-1);
300*84ceaea9SAndy Fiddaman
301*84ceaea9SAndy Fiddaman return (0);
302*84ceaea9SAndy Fiddaman }
303*84ceaea9SAndy Fiddaman
304*84ceaea9SAndy Fiddaman const topo_method_t pcie_methods[] = {
305*84ceaea9SAndy Fiddaman {
306*84ceaea9SAndy Fiddaman .tm_name = TOPO_METH_NVL2STR,
307*84ceaea9SAndy Fiddaman .tm_desc = TOPO_METH_NVL2STR_DESC,
308*84ceaea9SAndy Fiddaman .tm_version = TOPO_METH_NVL2STR_VERSION,
309*84ceaea9SAndy Fiddaman .tm_stability = TOPO_STABILITY_INTERNAL,
310*84ceaea9SAndy Fiddaman .tm_func = pcie_fmri_nvl2str
311*84ceaea9SAndy Fiddaman },
312*84ceaea9SAndy Fiddaman {
313*84ceaea9SAndy Fiddaman .tm_name = TOPO_METH_FMRI,
314*84ceaea9SAndy Fiddaman .tm_desc = TOPO_METH_FMRI_DESC,
315*84ceaea9SAndy Fiddaman .tm_version = TOPO_METH_FMRI_VERSION,
316*84ceaea9SAndy Fiddaman .tm_stability = TOPO_STABILITY_INTERNAL,
317*84ceaea9SAndy Fiddaman .tm_func = pcie_fmri_create_meth
318*84ceaea9SAndy Fiddaman },
319*84ceaea9SAndy Fiddaman { NULL }
320*84ceaea9SAndy Fiddaman };
321*84ceaea9SAndy Fiddaman
322*84ceaea9SAndy Fiddaman int
pcie_enum(topo_mod_t * mod,tnode_t * pnode,const char * name,topo_instance_t min,topo_instance_t max,void * u1 __unused,void * u2 __unused)323*84ceaea9SAndy Fiddaman pcie_enum(topo_mod_t *mod, tnode_t *pnode, const char *name,
324*84ceaea9SAndy Fiddaman topo_instance_t min, topo_instance_t max, void *u1 __unused,
325*84ceaea9SAndy Fiddaman void *u2 __unused)
326*84ceaea9SAndy Fiddaman {
327*84ceaea9SAndy Fiddaman topo_mod_dprintf(mod, "enumerating pcie: %s (%"PRIu64" - %"PRIu64")",
328*84ceaea9SAndy Fiddaman name, min, max);
329*84ceaea9SAndy Fiddaman
330*84ceaea9SAndy Fiddaman (void) topo_method_register(mod, pnode, pcie_methods);
331*84ceaea9SAndy Fiddaman return (0);
332*84ceaea9SAndy Fiddaman }
333*84ceaea9SAndy Fiddaman
334*84ceaea9SAndy Fiddaman static void
pcie_rele(topo_mod_t * mp,tnode_t * node)335*84ceaea9SAndy Fiddaman pcie_rele(topo_mod_t *mp, tnode_t *node)
336*84ceaea9SAndy Fiddaman {
337*84ceaea9SAndy Fiddaman topo_method_unregister_all(mp, node);
338*84ceaea9SAndy Fiddaman }
339*84ceaea9SAndy Fiddaman
340*84ceaea9SAndy Fiddaman static const topo_modops_t pcie_ops = {
341*84ceaea9SAndy Fiddaman .tmo_enum = pcie_enum,
342*84ceaea9SAndy Fiddaman .tmo_release = pcie_rele
343*84ceaea9SAndy Fiddaman };
344*84ceaea9SAndy Fiddaman
345*84ceaea9SAndy Fiddaman static const topo_modinfo_t pcie_info = {
346*84ceaea9SAndy Fiddaman .tmi_desc = PCIE,
347*84ceaea9SAndy Fiddaman .tmi_scheme = FM_FMRI_SCHEME_PCIE,
348*84ceaea9SAndy Fiddaman .tmi_version = PCIE_VERSION,
349*84ceaea9SAndy Fiddaman .tmi_ops = &pcie_ops
350*84ceaea9SAndy Fiddaman };
351*84ceaea9SAndy Fiddaman
352*84ceaea9SAndy Fiddaman int
pcie_init(topo_mod_t * mod,topo_version_t version)353*84ceaea9SAndy Fiddaman pcie_init(topo_mod_t *mod, topo_version_t version)
354*84ceaea9SAndy Fiddaman {
355*84ceaea9SAndy Fiddaman if (getenv("TOPOPCIEDEBUG"))
356*84ceaea9SAndy Fiddaman topo_mod_setdebug(mod);
357*84ceaea9SAndy Fiddaman
358*84ceaea9SAndy Fiddaman topo_mod_dprintf(mod, "initializing pcie builtin");
359*84ceaea9SAndy Fiddaman
360*84ceaea9SAndy Fiddaman if (version != PCIE_VERSION)
361*84ceaea9SAndy Fiddaman return (topo_mod_seterrno(mod, EMOD_VER_NEW));
362*84ceaea9SAndy Fiddaman
363*84ceaea9SAndy Fiddaman if (topo_mod_register(mod, &pcie_info, TOPO_VERSION) != 0) {
364*84ceaea9SAndy Fiddaman topo_mod_dprintf(mod, "failed to register pcie: %s",
365*84ceaea9SAndy Fiddaman topo_mod_errmsg(mod));
366*84ceaea9SAndy Fiddaman return (-1); /* mod errno already set */
367*84ceaea9SAndy Fiddaman }
368*84ceaea9SAndy Fiddaman
369*84ceaea9SAndy Fiddaman return (0);
370*84ceaea9SAndy Fiddaman }
371*84ceaea9SAndy Fiddaman
372*84ceaea9SAndy Fiddaman void
pcie_fini(topo_mod_t * mod)373*84ceaea9SAndy Fiddaman pcie_fini(topo_mod_t *mod)
374*84ceaea9SAndy Fiddaman {
375*84ceaea9SAndy Fiddaman topo_mod_unregister(mod);
376*84ceaea9SAndy Fiddaman }
377