did.c (60348818) | did.c (0db3240d) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 6 unchanged lines hidden (view full) --- 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE --- 6 unchanged lines hidden (view full) --- 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* |
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. | 23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. |
25 */ 26 27/* 28 * did.c 29 * The acronym did means "Dev-Info-Data". Many properties and 30 * characteristics of topology nodes are, with a bit of coaxing 31 * derived from devinfo nodes. These routines do some of the 32 * derivation and also encapsulate the discoveries in did_t --- 43 unchanged lines hidden (view full) --- 76 return; 77 slotnm_destroy(p->snm_next); 78 if (p->snm_name != NULL) 79 topo_mod_strfree(p->snm_mod, p->snm_name); 80 topo_mod_free(p->snm_mod, p, sizeof (slotnm_t)); 81} 82 83static int | 24 */ 25 26/* 27 * did.c 28 * The acronym did means "Dev-Info-Data". Many properties and 29 * characteristics of topology nodes are, with a bit of coaxing 30 * derived from devinfo nodes. These routines do some of the 31 * derivation and also encapsulate the discoveries in did_t --- 43 unchanged lines hidden (view full) --- 75 return; 76 slotnm_destroy(p->snm_next); 77 if (p->snm_name != NULL) 78 topo_mod_strfree(p->snm_mod, p->snm_name); 79 topo_mod_free(p->snm_mod, p, sizeof (slotnm_t)); 80} 81 82static int |
84slotnm_cp(did_t *from, did_t *to, int *nslots) 85{ 86 slotnm_t *nxt, *new; 87 slotnm_t *last = NULL; 88 89 *nslots = 0; 90 for (nxt = from->dp_slotnames; nxt != NULL; nxt = nxt->snm_next) { 91 new = slotnm_create(to->dp_mod, nxt->snm_dev, nxt->snm_name); 92 if (new == NULL) { 93 if (to->dp_slotnames != NULL) 94 slotnm_destroy(to->dp_slotnames); 95 to->dp_slotnames = NULL; 96 *nslots = 0; 97 return (-1); 98 } 99 if (last == NULL) { 100 to->dp_slotnames = last = new; 101 } else { 102 last->snm_next = new; 103 last = new; 104 } 105 (*nslots)++; 106 } 107 if (*nslots > 0) 108 topo_mod_dprintf(to->dp_mod, 109 "%p inherits %d slot label(s) from %p.\n", 110 to, *nslots, from); 111 return (0); 112} 113 114static int | |
115di_devtype_get(topo_mod_t *mp, di_node_t src, char **devtype) 116{ 117 int sz; 118 uchar_t *buf; 119 120 /* 121 * For PCI the device type defined the type of device directly below. 122 * For PCIe RP and Switches, the device-type should be "pciex". For --- 6 unchanged lines hidden (view full) --- 129 *devtype = NULL; 130 } 131 132 if (*devtype != NULL) 133 return (0); 134 return (-1); 135} 136 | 83di_devtype_get(topo_mod_t *mp, di_node_t src, char **devtype) 84{ 85 int sz; 86 uchar_t *buf; 87 88 /* 89 * For PCI the device type defined the type of device directly below. 90 * For PCIe RP and Switches, the device-type should be "pciex". For --- 6 unchanged lines hidden (view full) --- 97 *devtype = NULL; 98 } 99 100 if (*devtype != NULL) 101 return (0); 102 return (-1); 103} 104 |
105typedef struct smbios_slot_cb { 106 int cb_slotnum; 107 const char *cb_label; 108} smbios_slot_cb_t; 109 |
|
137static int | 110static int |
111di_smbios_find_slot(smbios_hdl_t *shp, const smbios_struct_t *strp, void *data) 112{ 113 smbios_slot_cb_t *cbp = data; 114 smbios_slot_t slot; 115 116 if (strp->smbstr_type != SMB_TYPE_SLOT || 117 smbios_info_slot(shp, strp->smbstr_id, &slot) != 0) 118 return (0); 119 120 if (slot.smbl_id == cbp->cb_slotnum) { 121 cbp->cb_label = slot.smbl_name; 122 return (1); 123 } 124 125 return (0); 126} 127 128static int |
|
138di_physlotinfo_get(topo_mod_t *mp, di_node_t src, int *slotnum, char **slotname) 139{ 140 char *slotbuf; 141 int sz; 142 uchar_t *buf; | 129di_physlotinfo_get(topo_mod_t *mp, di_node_t src, int *slotnum, char **slotname) 130{ 131 char *slotbuf; 132 int sz; 133 uchar_t *buf; |
134 smbios_hdl_t *shp; 135 boolean_t got_slotprop = B_FALSE; |
|
143 144 *slotnum = -1; | 136 137 *slotnum = -1; |
138 |
|
145 (void) di_uintprop_get(mp, src, DI_PHYSPROP, (uint_t *)slotnum); 146 | 139 (void) di_uintprop_get(mp, src, DI_PHYSPROP, (uint_t *)slotnum); 140 |
147 if (*slotnum == -1) 148 return (0); 149 | |
150 /* 151 * For PCI-Express, there is only one downstream device, so check for 152 * a slot-names property, and if it exists, ignore the slotmask value 153 * and use the string as the label. 154 */ 155 if (di_bytes_get(mp, src, DI_SLOTPROP, &sz, &buf) == 0 && 156 sz > 4) { | 141 /* 142 * For PCI-Express, there is only one downstream device, so check for 143 * a slot-names property, and if it exists, ignore the slotmask value 144 * and use the string as the label. 145 */ 146 if (di_bytes_get(mp, src, DI_SLOTPROP, &sz, &buf) == 0 && 147 sz > 4) { |
148 /* 149 * If there is a DI_SLOTPROP of the form SlotX (ie set up from 150 * the IRQ routing table) then trust that in preference to 151 * DI_PHYSPROP (which is set up from the PCIe slotcap reg). 152 */ 153 got_slotprop = B_TRUE; 154 (void) sscanf((char *)&buf[4], "Slot%d", slotnum); 155 } 156 157 if (*slotnum == -1) 158 return (0); 159 160 /* 161 * Order of preference 162 * 1) take slotnum and look up in SMBIOS table 163 * 2) use slot-names 164 * 3) fabricate name based on slotnum 165 */ 166 if ((shp = topo_mod_smbios(mp)) != NULL) { 167 /* 168 * The PCI spec describes slot number 0 as reserved for 169 * internal PCI devices. Not all platforms respect 170 * this, so we have to treat slot 0 as a valid device. 171 * But other platforms use 0 to identify an internal 172 * device. We deal with this by letting SMBIOS be the 173 * final decision maker. If SMBIOS is supported, but 174 * the given slot number is not represented in the 175 * SMBIOS tables, then ignore the slot entirely. 176 */ 177 smbios_slot_cb_t cbdata; 178 179 cbdata.cb_slotnum = *slotnum; 180 cbdata.cb_label = NULL; 181 if (smbios_iter(shp, di_smbios_find_slot, &cbdata) <= 0) 182 return (0); 183 slotbuf = (char *)cbdata.cb_label; 184 topo_mod_dprintf(mp, "%s: node=%p: using smbios name\n", 185 __func__, src); 186 } else if (got_slotprop == B_TRUE) { |
|
157 slotbuf = (char *)&buf[4]; | 187 slotbuf = (char *)&buf[4]; |
158 topo_mod_dprintf(mp, "di_physlotinfo_get: node=%p: " 159 "found %s property\n", src, DI_SLOTPROP); | 188 topo_mod_dprintf(mp, "%s: node=%p: found %s property\n", 189 __func__, src, DI_SLOTPROP); |
160 } else { 161 /* 162 * Make generic description string "SLOT <num>", allow up to 163 * 10 digits for number 164 */ 165 slotbuf = alloca(16); 166 (void) snprintf(slotbuf, 16, "SLOT %d", *slotnum); | 190 } else { 191 /* 192 * Make generic description string "SLOT <num>", allow up to 193 * 10 digits for number 194 */ 195 slotbuf = alloca(16); 196 (void) snprintf(slotbuf, 16, "SLOT %d", *slotnum); |
167 topo_mod_dprintf(mp, "di_physlotinfo_get: node=%p: " 168 "using generic slot name\n", src); | 197 topo_mod_dprintf(mp, "%s: node=%p: using generic slot name\n", 198 __func__, src); |
169 } 170 if ((*slotname = topo_mod_strdup(mp, slotbuf)) == NULL) 171 return (-1); 172 | 199 } 200 if ((*slotname = topo_mod_strdup(mp, slotbuf)) == NULL) 201 return (-1); 202 |
173 topo_mod_dprintf(mp, "di_physlotinfo_get: node=%p: slotname=%s\n", 174 src, *slotname); | 203 topo_mod_dprintf(mp, "%s: node=%p: slotname=%s\n", 204 __func__, src, *slotname); |
175 176 return (0); 177} 178 179static int 180di_slotinfo_get(topo_mod_t *mp, di_node_t src, int *nslots, 181 slotnm_t **slotnames) 182{ --- 102 unchanged lines hidden (view full) --- 285 np->dp_subclass = GETSUBCLASS(code); 286 } else { 287 np->dp_class = -1; 288 } 289 /* 290 * There *may* be a device type we can capture. 291 */ 292 (void) di_devtype_get(mp, src, &np->dp_devtype); | 205 206 return (0); 207} 208 209static int 210di_slotinfo_get(topo_mod_t *mp, di_node_t src, int *nslots, 211 slotnm_t **slotnames) 212{ --- 102 unchanged lines hidden (view full) --- 315 np->dp_subclass = GETSUBCLASS(code); 316 } else { 317 np->dp_class = -1; 318 } 319 /* 320 * There *may* be a device type we can capture. 321 */ 322 (void) di_devtype_get(mp, src, &np->dp_devtype); |
293 /* 294 * There *may* be a physical slot number property we can capture. 295 */ 296 if (di_physlotinfo_get(mp, 297 src, &np->dp_physlot, &np->dp_physlot_name) < 0) { 298 if (np->dp_devtype != NULL) 299 topo_mod_strfree(mp, np->dp_devtype); 300 topo_mod_free(mp, np, sizeof (did_t)); 301 return (NULL); | 323 324 if (irc >= 0) { 325 /* 326 * This is a pciex node. 327 */ 328 if (di_physlotinfo_get(mp, src, &np->dp_physlot, 329 &np->dp_physlot_name) < 0) { 330 if (np->dp_devtype != NULL) 331 topo_mod_strfree(mp, np->dp_devtype); 332 topo_mod_free(mp, np, sizeof (did_t)); 333 return (NULL); 334 } 335 } else { 336 /* 337 * This is a pci node. 338 */ 339 if (di_slotinfo_get(mp, src, &np->dp_nslots, 340 &np->dp_slotnames) < 0) { 341 if (np->dp_devtype != NULL) 342 topo_mod_strfree(mp, np->dp_devtype); 343 topo_mod_free(mp, np, sizeof (did_t)); 344 return (NULL); 345 } |
302 } | 346 } |
303 /* 304 * There *may* be PCI slot info we can capture 305 */ 306 if (di_slotinfo_get(mp, src, &np->dp_nslots, &np->dp_slotnames) < 0) { 307 if (np->dp_devtype != NULL) 308 topo_mod_strfree(mp, np->dp_devtype); 309 if (np->dp_physlot_name != NULL) 310 topo_mod_strfree(mp, np->dp_physlot_name); 311 topo_mod_free(mp, np, sizeof (did_t)); 312 return (NULL); 313 } | |
314 did_hash_insert(mp, src, np); 315 did_hold(np); 316 return (np); 317} 318 319did_t * 320did_link_get(did_t *dp) 321{ --- 124 unchanged lines hidden (view full) --- 446 447int 448did_rc(did_t *did) 449{ 450 assert(did != NULL); 451 return (did->dp_rc); 452} 453 | 347 did_hash_insert(mp, src, np); 348 did_hold(np); 349 return (np); 350} 351 352did_t * 353did_link_get(did_t *dp) 354{ --- 124 unchanged lines hidden (view full) --- 479 480int 481did_rc(did_t *did) 482{ 483 assert(did != NULL); 484 return (did->dp_rc); 485} 486 |
454static int 455did_numlabels(did_t *dp) 456{ 457 assert(dp != NULL); 458 return (dp->dp_nslots); 459} 460 | |
461int 462did_excap(did_t *dp) 463{ 464 assert(dp != NULL); 465 return ((int)dp->dp_excap); 466} 467 468void --- 10 unchanged lines hidden (view full) --- 479} 480 481const char * 482did_physlot_name(did_t *dp, int dev) 483{ 484 slotnm_t *slot; 485 486 assert(dp != NULL); | 487int 488did_excap(did_t *dp) 489{ 490 assert(dp != NULL); 491 return ((int)dp->dp_excap); 492} 493 494void --- 10 unchanged lines hidden (view full) --- 505} 506 507const char * 508did_physlot_name(did_t *dp, int dev) 509{ 510 slotnm_t *slot; 511 512 assert(dp != NULL); |
513 514 /* 515 * For pciex, name will be in dp_physlot_name 516 */ |
|
487 if (dp->dp_physlot_name != NULL) 488 return (dp->dp_physlot_name); | 517 if (dp->dp_physlot_name != NULL) 518 return (dp->dp_physlot_name); |
519 520 /* 521 * For pci, name will be in dp_slotnames 522 */ |
|
489 for (slot = dp->dp_slotnames; slot != NULL; slot = slot->snm_next) 490 if (slot->snm_dev == dev) 491 break; 492 if (slot != NULL) 493 return (slot->snm_name); 494 return (NULL); 495} 496 --- 65 unchanged lines hidden (view full) --- 562 did_t *dp; 563 564 if ((dp = did_find(mp, dn)) == NULL) 565 return (-1); 566 did_rele(dp); 567 return (dp->dp_excap); 568} 569 | 523 for (slot = dp->dp_slotnames; slot != NULL; slot = slot->snm_next) 524 if (slot->snm_dev == dev) 525 break; 526 if (slot != NULL) 527 return (slot->snm_name); 528 return (NULL); 529} 530 --- 65 unchanged lines hidden (view full) --- 596 did_t *dp; 597 598 if ((dp = did_find(mp, dn)) == NULL) 599 return (-1); 600 did_rele(dp); 601 return (dp->dp_excap); 602} 603 |
570int 571did_inherit(did_t *pdp, did_t *dp) 572{ 573 /* 574 * If the child already has a label, we're done. 575 */ 576 assert(dp != NULL); 577 if (did_numlabels(dp) > 0) 578 return (0); 579 580 assert(pdp != NULL); 581 582 /* 583 * If the child and parent are the same, we're done. 584 */ 585 if (dp == pdp) 586 return (0); 587 588 if (pdp->dp_physlot_name != NULL) { 589 topo_mod_dprintf(dp->dp_mod, 590 "%p inherits physlot label from %p.\n", dp, pdp); 591 dp->dp_physlot_name = 592 topo_mod_strdup(dp->dp_mod, pdp->dp_physlot_name); 593 if (dp->dp_physlot_name == NULL) 594 return (-1); 595 } 596 if (slotnm_cp(pdp, dp, &dp->dp_nslots) < 0) 597 return (-1); 598 return (0); 599} 600 | |
601void 602did_setspecific(topo_mod_t *mp, void *data) 603{ 604 did_t *hbdid; 605 606 hbdid = (did_t *)data; 607 topo_mod_setspecific(mp, hbdid->dp_hash); 608} --- 13 unchanged lines hidden --- | 604void 605did_setspecific(topo_mod_t *mp, void *data) 606{ 607 did_t *hbdid; 608 609 hbdid = (did_t *)data; 610 topo_mod_setspecific(mp, hbdid->dp_hash); 611} --- 13 unchanged lines hidden --- |