/* * During each register callback: totally rebuild the group list from a new * libdevinfo snapshot, and then update the registrants. */ static int mpxio_register(rcm_handle_t *hdl) { int nclients = 0; di_node_t devroot; rcm_log_message(RCM_TRACE1, "MPXIO: register()\n"); (void) mutex_lock(&mpxio_lock); /* Destroy the previous group list */ free_grouplist(); /* Get a current libdevinfo snapshot */ if ((devroot = di_init("/", DINFOCPYALL | DINFOPATH)) == DI_NODE_NIL) { rcm_log_message(RCM_ERROR, "MPXIO: libdevinfo initialization failed (%s).\n", strerror(errno)); (void) mutex_unlock(&mpxio_lock); return (RCM_FAILURE); } /* * First count the total number of clients. This'll be a useful * upper bound when allocating client arrays within each group. */ (void) di_walk_node(devroot, DI_WALK_CLDFIRST, &nclients, get_nclients); rcm_log_message(RCM_TRACE2, gettext("MPXIO: found %d clients.\n"), nclients); /* * Then walk the libdevinfo snapshot, building up the new group list * along the way. Pass in the total number of clients (from above) to * assist in group construction. */ (void) di_walk_node(devroot, DI_WALK_CLDFIRST, &nclients, build_groups); /* Now with a new group list constructed, refresh the registrants */ refresh_regs(hdl); /* Free the libdevinfo snapshot */ di_fini(devroot); (void) mutex_unlock(&mpxio_lock); return (0); }
int dev_list_gather(topo_mod_t *mod, topo_list_t *listp) { di_node_t devtree; di_devlink_handle_t devhdl; disk_cbdata_t dcb; if ((devtree = topo_mod_devinfo(mod)) == DI_NODE_NIL) { topo_mod_dprintf(mod, "disk_list_gather: " "topo_mod_devinfo() failed"); return (-1); } if ((devhdl = di_devlink_init(NULL, 0)) == DI_NODE_NIL) { topo_mod_dprintf(mod, "disk_list_gather: " "di_devlink_init() failed"); return (-1); } dcb.dcb_mod = mod; dcb.dcb_list = listp; dcb.dcb_devhdl = devhdl; /* walk the devinfo snapshot looking for disk nodes */ (void) di_walk_node(devtree, DI_WALK_CLDFIRST, &dcb, dev_walk_di_nodes); (void) di_devlink_fini(&devhdl); return (0); }
static int destroy_console_devs(zlog_t *zlogp) { char conspath[MAXPATHLEN]; di_node_t root; struct cb_data cb; int masterfd; int slavefd; /* * Signal the master side to release its handle on the slave side by * issuing a ZC_RELEASESLAVE ioctl. */ (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s", zone_name, ZCONS_MASTER_NAME); if ((masterfd = open(conspath, O_RDWR | O_NOCTTY)) != -1) { (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s", zone_name, ZCONS_SLAVE_NAME); if ((slavefd = open(conspath, O_RDWR | O_NOCTTY)) != -1) { if (ioctl(masterfd, ZC_RELEASESLAVE, (caddr_t)(intptr_t)slavefd) != 0) zerror(zlogp, B_TRUE, "WARNING: error while " "releasing slave handle of zone console for" " %s", zone_name); (void) close(slavefd); } else { zerror(zlogp, B_TRUE, "WARNING: could not open slave " "side of zone console for %s to release slave " "handle", zone_name); } (void) close(masterfd); } else { zerror(zlogp, B_TRUE, "WARNING: could not open master side of " "zone console for %s to release slave handle", zone_name); } bzero(&cb, sizeof (cb)); cb.zlogp = zlogp; if ((root = di_init(ZCONSNEX_DEVTREEPATH, DINFOCPYALL)) == DI_NODE_NIL) { zerror(zlogp, B_TRUE, "%s failed", "di_init"); return (-1); } (void) di_walk_node(root, DI_WALK_CLDFIRST, (void *)&cb, destroy_cb); if (cb.found > 1) { zerror(zlogp, B_FALSE, "WARNING: multiple zone console " "instances detected for zone '%s'; %d of %d " "successfully removed.", zone_name, cb.killed, cb.found); } di_fini(root); return (0); }
/* * Map a device path to its matching di_node_t. */ static di_node_t path2node(char *path) { cb_t cb; cb.cb_path = path; cb.cb_node = DI_NODE_NIL; (void) di_walk_node(root_node, DI_WALK_CLDFIRST, &cb, p2n_cb); return (cb.cb_node); }
PUSBDEVICE USBProxyServiceSolaris::getDevices(void) { USBDEVICELIST DevList; DevList.pHead = NULL; DevList.pTail = NULL; di_node_t RootNode = di_init("/", DINFOCPYALL); if (RootNode != DI_NODE_NIL) di_walk_node(RootNode, DI_WALK_CLDFIRST, &DevList, solarisWalkDeviceNode); di_fini(RootNode); return DevList.pHead; }
/* * checks if a fru is present under location using pdev-path and busaddr */ boolean_t is_fru_present_under_location(frutree_locnode_t *locp) { di_node_t rnode; frutree_devinfo_t *devinfo = NULL; char probe_path[PICL_PROPNAMELEN_MAX]; if (locp == NULL) { return (B_FALSE); } if (ptree_get_propval_by_name(locp->locnodeh, PICL_PROP_PROBE_PATH, probe_path, sizeof (probe_path)) != PICL_SUCCESS) { if (ptree_get_propval_by_name(locp->locnodeh, PICL_PROP_DEVFS_PATH, probe_path, sizeof (probe_path)) != PICL_SUCCESS) { return (B_FALSE); } } rnode = di_init(probe_path, DINFOSUBTREE); if (rnode == DI_NODE_NIL) { di_fini(rnode); return (B_FALSE); } devinfo = (frutree_devinfo_t *)malloc(sizeof (frutree_devinfo_t)); if (devinfo == NULL) { di_fini(rnode); return (B_FALSE); } devinfo->rnode = rnode; devinfo->arg = (frutree_locnode_t **)&locp; devinfo->retval = PICL_FAILURE; if (di_walk_node(rnode, DI_WALK_SIBFIRST, &devinfo, find_fru_node) != 0) { di_fini(rnode); free(devinfo); return (B_FALSE); } di_fini(rnode); if (devinfo->retval == PICL_SUCCESS) { free(devinfo); return (B_TRUE); } else { free(devinfo); return (B_FALSE); } }
static int count_zfd_devs(zlog_t *zlogp) { di_node_t root; struct cb_data cb; bzero(&cb, sizeof (cb)); cb.zlogp = zlogp; if ((root = di_init(ZFDNEX_DEVTREEPATH, DINFOCPYALL)) == DI_NODE_NIL) { zerror(zlogp, B_TRUE, "di_init failed"); return (-1); } (void) di_walk_node(root, DI_WALK_CLDFIRST, (void *)&cb, count_cb); di_fini(root); return (cb.found); }
/* * Force all "network" drivers to be loaded. * * Returns: ICFG_SUCCESS or ICFG_FAILURE. In the case of * ICFG_FAILURE, syserr will contain the errno. */ static int nic_load_drivers(int *syserr) { di_node_t root_node; di_prom_handle_t ph; int ret; root_node = di_init(NIC_DEVTREE_ROOT, DINFOCPYALL); if (root_node == DI_NODE_NIL) { *syserr = errno; return (ICFG_FAILURE); } /* * Create handle to PROM */ if ((ph = di_prom_init()) == DI_PROM_HANDLE_NIL) { *syserr = errno; di_fini(root_node); return (ICFG_FAILURE); } /* * Walk nodes and make sure all network devices have * drivers loaded so that devinfo has accurate data. */ ret = di_walk_node(root_node, DI_WALK_CLDFIRST, ph, process_node); if (ret != 0) { *syserr = errno; di_prom_fini(ph); di_fini(root_node); return (ICFG_FAILURE); } /* * Clean up handles */ di_prom_fini(ph); di_fini(root_node); return (ICFG_SUCCESS); }
static picl_errno_t load_drivers(char *path) { di_node_t rnode; if (path == NULL) { return (PICL_INVALIDARG); } rnode = di_init(path, DINFOSUBTREE|DINFOMINOR); if (rnode == DI_NODE_NIL) { return (PICL_FAILURE); } if (di_walk_node(rnode, DI_WALK_CLDFIRST, NULL, load_driver) != 0) { di_fini(rnode); return (PICL_FAILURE); } di_fini(rnode); return (PICL_SUCCESS); }
int sunos_get_device_list(struct libusb_context * ctx, struct discovered_devs **discdevs) { di_node_t root_node; struct node_args args; di_devlink_handle_t devlink_hdl; args.ctx = ctx; args.discdevs = discdevs; args.last_ugenpath = NULL; if ((root_node = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) { usbi_dbg("di_int() failed: %s", strerror(errno)); return (LIBUSB_ERROR_IO); } if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) { di_fini(root_node); usbi_dbg("di_devlink_init() failed: %s", strerror(errno)); return (LIBUSB_ERROR_IO); } args.dlink_hdl = devlink_hdl; /* walk each node to find USB devices */ if (di_walk_node(root_node, DI_WALK_SIBFIRST, &args, sunos_walk_minor_node_link) == -1) { usbi_dbg("di_walk_node() failed: %s", strerror(errno)); di_fini(root_node); return (LIBUSB_ERROR_IO); } di_fini(root_node); di_devlink_fini(&devlink_hdl); usbi_dbg("%d devices", (*discdevs)->len); return ((*discdevs)->len); }
int main() { di_node_t root_node; int fd; if ((fd = open("/tmp/bootparams", O_RDONLY)) != -1) { /* If this file exists it acts as a replacement for the normal data */ raw_cat(fd); close(fd); } else { /* We didn't have or couldn't open the file, so just get actual params */ root_node = di_init("/", (DINFOSUBTREE | DINFOPROP)); if (root_node == DI_NODE_NIL) { fprintf(stderr, "di_init() failed\n"); exit(1); } di_walk_node(root_node, DI_WALK_CLDFIRST, NULL, prt_node); di_fini(root_node); } exit(EXIT_SUCCESS); }
static int getpath(char *path, int instance, char *name, int pathlen) { di_node_t node; struct walk_arg warg; warg.instance = instance; (void) strncpy(warg.name, name, MAXPATHLEN); warg.path = path; warg.pathlen = pathlen; warg.found = 0; if ((node = di_init("/", DINFOSUBTREE)) == DI_NODE_NIL) return (-1); if (di_walk_node(node, DI_WALK_CLDFIRST, &warg, walk_callback) == -1) { di_fini(node); return (-1); } if (warg.found == 0) { di_fini(node); return (-1); } di_fini(node); return (0); }
/* * Solaris version */ static int pci_device_solx_devfs_probe( struct pci_device * dev ) { int err = 0; di_node_t rnode = DI_NODE_NIL; i_devnode_t args = { 0, 0, 0, DI_NODE_NIL }; int *regbuf; pci_regspec_t *reg; int i; int len = 0; uint ent = 0; nexus_t *nexus; #ifdef __sparc if ( (nexus = find_nexus_for_dev(dev)) == NULL ) #else if ( (nexus = find_nexus_for_bus(dev->domain, dev->bus)) == NULL ) #endif return ENODEV; /* * starting to find if it is MEM/MEM64/IO * using libdevinfo */ if ((rnode = di_init(nexus->dev_path, DINFOCPYALL)) == DI_NODE_NIL) { err = errno; (void) fprintf(stderr, "di_init failed: %s\n", strerror(errno)); } else { args.bus = dev->bus; args.dev = dev->dev; args.func = dev->func; (void) di_walk_node(rnode, DI_WALK_CLDFIRST, (void *)&args, find_target_node); } if (args.node != DI_NODE_NIL) { #ifdef __sparc di_minor_t minor; #endif #ifdef __sparc if (minor = di_minor_next(args.node, DI_MINOR_NIL)) MAPPING_DEV_PATH(dev) = di_devfs_minor_path (minor); else MAPPING_DEV_PATH(dev) = NULL; #endif /* * It will succeed for sure, because it was * successfully called in find_target_node */ len = di_prop_lookup_ints(DDI_DEV_T_ANY, args.node, "assigned-addresses", ®buf); #ifdef __sparc if ((len <= 0) && di_phdl) { len = di_prom_prop_lookup_ints(di_phdl, args.node, "assigned-addresses", ®buf); } #endif } if (len <= 0) goto cleanup; /* * how to find the size of rom??? * if the device has expansion rom, * it must be listed in the last * cells because solaris find probe * the base address from offset 0x10 * to 0x30h. So only check the last * item. */ reg = (pci_regspec_t *)®buf[len - CELL_NUMS_1275]; if (PCI_REG_REG_G(reg->pci_phys_hi) == PCI_CONF_ROM) { /* * rom can only be 32 bits */ dev->rom_size = reg->pci_size_low; len = len - CELL_NUMS_1275; } else { /* * size default to 64K and base address * default to 0xC0000 */ dev->rom_size = 0x10000; } /* * Solaris has its own BAR index. * Linux give two region slot for 64 bit address. */ for (i = 0; i < len; i = i + CELL_NUMS_1275) { reg = (pci_regspec_t *)®buf[i]; ent = reg->pci_phys_hi & 0xff; /* * G35 broken in BAR0 */ ent = (ent - PCI_CONF_BASE0) >> 2; if (ent >= 6) { fprintf(stderr, "error ent = %d\n", ent); break; } /* * non relocatable resource is excluded * such like 0xa0000, 0x3b0. If it is met, * the loop is broken; */ if (!PCI_REG_REG_G(reg->pci_phys_hi)) break; if (reg->pci_phys_hi & PCI_PREFETCH_B) { dev->regions[ent].is_prefetchable = 1; } /* * We split the shift count 32 into two 16 to * avoid the complaining of the compiler */ dev->regions[ent].base_addr = reg->pci_phys_low + ((reg->pci_phys_mid << 16) << 16); dev->regions[ent].size = reg->pci_size_low + ((reg->pci_size_hi << 16) << 16); switch (reg->pci_phys_hi & PCI_REG_ADDR_M) { case PCI_ADDR_IO: dev->regions[ent].is_IO = 1; break; case PCI_ADDR_MEM32: break; case PCI_ADDR_MEM64: dev->regions[ent].is_64 = 1; /* * Skip one slot for 64 bit address */ break; } } cleanup: if (rnode != DI_NODE_NIL) { di_fini(rnode); } return (err); }
/* This routine probes libdevinfo for port nodes */ picl_errno_t probe_libdevinfo(frutree_frunode_t *frup, frutree_device_args_t ** device, boolean_t load_drv) { di_node_t rnode; picl_errno_t rc; plist_t list; if (frup == NULL) { return (PICL_FAILURE); } FRUTREE_DEBUG1(EVENTS, "loading drivers for %s", frup->name); if (load_drv == B_TRUE) { if ((rc = load_drivers(frup->fru_path)) != PICL_SUCCESS) { return (rc); } } FRUTREE_DEBUG1(EVENTS, "done with loading drivers for %s", frup->name); rnode = di_init(frup->fru_path, DINFOSUBTREE|DINFOMINOR); if (rnode == DI_NODE_NIL) { return (PICL_FAILURE); } list.first = NULL; list.last = NULL; list.n_network = 0; list.n_serial = 0; list.n_parallel = 0; if (di_walk_node(rnode, DI_WALK_CLDFIRST, &list, probe_tree) != 0) { di_fini(rnode); free_list(&list); return (PICL_FAILURE); } if (list.n_serial > 0) if ((rc = assign_geo_addr(&list, SERIAL_PORT)) != PICL_SUCCESS) { di_fini(rnode); free_list(&list); return (rc); } if (list.n_network > 0) if ((rc = assign_geo_addr(&list, NETWORK_PORT)) != PICL_SUCCESS) { di_fini(rnode); free_list(&list); return (rc); } if (list.n_parallel > 0) if ((rc = assign_geo_addr(&list, PARALLEL_PORT)) != PICL_SUCCESS) { di_fini(rnode); free_list(&list); return (rc); } if ((rc = create_port_config_info(&list, *device)) != PICL_SUCCESS) { di_fini(rnode); free_list(&list); return (rc); } di_fini(rnode); free_list(&list); FRUTREE_DEBUG1(EVENTS, "done with probing %s", frup->name); return (PICL_SUCCESS); }
picl_errno_t get_fru_path(char *parent_path, frutree_frunode_t *frup) { picl_errno_t rc = 0; picl_nodehdl_t loch; di_node_t rnode; frutree_devinfo_t *devinfo = NULL; char slot_type[PICL_PROPNAMELEN_MAX]; char probe_path[PICL_PROPNAMELEN_MAX]; char bus_addr[PICL_PROPNAMELEN_MAX]; if ((rc = ptree_get_propval_by_name(frup->frunodeh, PICL_PROP_PARENT, &loch, sizeof (loch))) != PICL_SUCCESS) { return (rc); } if ((rc = ptree_get_propval_by_name(loch, PICL_PROP_SLOT_TYPE, slot_type, sizeof (slot_type))) != PICL_SUCCESS) { return (rc); } if (strcmp(slot_type, SANIBEL_SCSI_SLOT) == 0 || strcmp(slot_type, SANIBEL_IDE_SLOT) == 0) { if (ptree_get_propval_by_name(loch, PICL_PROP_PROBE_PATH, probe_path, sizeof (probe_path)) != PICL_SUCCESS) { return (rc); } (void) strncpy(frup->fru_path, probe_path, sizeof (frup->fru_path)); return (PICL_SUCCESS); } prom_handle = di_prom_init(); rnode = di_init(parent_path, DINFOSUBTREE|DINFOMINOR); if (rnode == DI_NODE_NIL) { di_prom_fini(prom_handle); return (PICL_FAILURE); } devinfo = (frutree_devinfo_t *)malloc(sizeof (frutree_devinfo_t)); if (devinfo == NULL) { di_fini(rnode); di_prom_fini(prom_handle); return (PICL_NOSPACE); } if (ptree_get_propval_by_name(loch, PICL_PROP_BUS_ADDR, bus_addr, sizeof (bus_addr)) != PICL_SUCCESS) { free(devinfo); di_fini(rnode); di_prom_fini(prom_handle); return (rc); } devinfo->rnode = rnode; (void) strncpy(devinfo->bus_addr, bus_addr, sizeof (devinfo->bus_addr)); devinfo->path[0] = '\0'; devinfo->arg = frup; if (di_walk_node(rnode, DI_WALK_SIBFIRST, &devinfo, walk_tree) != 0) { di_fini(rnode); di_prom_fini(prom_handle); free(devinfo); return (PICL_FAILURE); } di_fini(rnode); di_prom_fini(prom_handle); if (devinfo->path[0]) { (void) strncpy(frup->fru_path, devinfo->path, sizeof (frup->fru_path)); free(devinfo); return (PICL_SUCCESS); } else { free(devinfo); return (PICL_NODENOTFOUND); } }
int main(int argc, char *argv[]) { int c, i, ret; di_node_t root; ahciem_t ahci; ahciem_progname = basename(argv[0]); bzero(&ahci, sizeof (ahciem_t)); while ((c = getopt(argc, argv, ":s:")) != -1) { switch (c) { case 's': ahci.ahci_set = B_TRUE; ahci.ahci_led = ahciem_parse(optarg); break; case ':': ahciem_usage("option -%c requires an operand\n", optopt); return (EXIT_USAGE); case '?': default: ahciem_usage("unknown option: -%c\n", optopt); return (EXIT_USAGE); } } argc -= optind; argv += optind; ahci.ahci_argc = argc; ahci.ahci_argv = argv; if (argc > 0) { ahci.ahci_found = calloc(argc, sizeof (boolean_t)); if (ahci.ahci_found == NULL) { err(EXIT_FAILURE, "failed to alloc memory for %d " "booleans", argc); } } if ((root = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) { err(EXIT_FAILURE, "failed to open devinfo tree"); } if (!ahci.ahci_set) { (void) printf("%-20s %-12s %s\n", "PORT", "ACTIVE", "SUPPORTED"); } if (di_walk_node(root, DI_WALK_CLDFIRST, &ahci, ahciem_devinfo) != 0) { err(EXIT_FAILURE, "failed to walk devinfo tree"); } ret = ahci.ahci_err; for (i = 0; i < argc; i++) { if (ahci.ahci_found[i]) continue; warnx("failed to find ahci enclosure port \"%s\"", ahci.ahci_argv[i]); ret = 1; } return (ret); }
/* * Refreshes information about an HBA * * Note: This routine holds the locks in write mode * during most of the processing, and as such, will cause * all other threads to block on entry into the library * until the refresh is complete. An optimization would be * to put fine-grain locking in for the open_handle structures. */ void Sun_sasRefreshAdapterConfiguration() { const char ROUTINE[] = "Sun_sasRefreshAdapterConfiguration"; struct sun_sas_hba *hba_ptr; di_node_t root; hrtime_t start; hrtime_t end; double duration; walkarg_t wa; /* * We're going to be tweaking a lot of global lists, so write * lock them. */ lock(&all_hbas_lock); lock(&open_handles_lock); start = gethrtime(); /* Grab device tree */ if ((root = di_init("/", DINFOCACHE)) == DI_NODE_NIL) { log(LOG_DEBUG, ROUTINE, "Unable to load device tree for reason \"%s\"", strerror(errno)); unlock(&open_handles_lock); unlock(&all_hbas_lock); return; } end = gethrtime(); duration = end - start; duration /= HR_SECOND; log(LOG_DEBUG, ROUTINE, "Device tree init took " "%.6f seconds", duration); for (hba_ptr = global_hba_head; hba_ptr != NULL; hba_ptr = hba_ptr->next) { wa.devpath = hba_ptr->device_path; wa.flag = (boolean_t *)calloc(1, sizeof (boolean_t)); *wa.flag = B_FALSE; if (di_walk_node(root, DI_WALK_SIBFIRST, &wa, find_matching_hba) != 0) { log(LOG_DEBUG, ROUTINE, "di_walk_node failed."); unlock(&open_handles_lock); unlock(&all_hbas_lock); S_FREE(wa.flag); di_fini(root); return; } if (*wa.flag == B_FALSE) { /* * Keep the HBA as it is including open handles * per the SM-HBA standards. Just mark it as invalid. */ log(LOG_DEBUG, ROUTINE, "No matching HBA found. %s", hba_ptr->device_path); hba_ptr->invalid = B_TRUE; } S_FREE(wa.flag); } /* * Now we marked missing HBA(s). Redisoover hbas to refresh * or add any new adapter to the hba list. * Simply call devtree_get_all_hbas(). */ if (devtree_get_all_hbas(root) != HBA_STATUS_OK) { log(LOG_DEBUG, ROUTINE, "devtree_get_all_hbas failed."); } di_fini(root); unlock(&open_handles_lock); unlock(&all_hbas_lock); }