/* * Given the root node of the device tree. * compare it to the picl tree and add to it cpus * that are new. */ static void add_cpus(di_node_t di_node) { int err; di_node_t cnode; picl_nodehdl_t plath; cpu_lookup_t cpu_arg; char *nodename; err = ptree_get_node_by_path(PLATFORM_PATH, &plath); if (err != PICL_SUCCESS) return; for (cnode = di_child_node(di_node); cnode != DI_NODE_NIL; cnode = di_sibling_node(cnode)) { nodename = di_node_name(cnode); if (nodename == NULL) continue; if (strcmp(nodename, OBP_CPU) == 0) { cpu_arg.di_node = cnode; if (ptree_walk_tree_by_class(plath, PICL_CLASS_CPU, &cpu_arg, cpu_exists) != PICL_SUCCESS) return; if (cpu_arg.result == 0) /* * Didn't find a matching cpu, add it. */ (void) construct_cpu_node(plath, cnode); } } }
static int niufn_instantiate(tnode_t *parent, const char *name, di_node_t pnode, topo_mod_t *mod) { di_node_t sib; tnode_t *ntn; topo_instance_t inst; if (strcmp(name, NIUFN) != 0) { topo_mod_dprintf(mod, "Currently only know how to enumerate %s components.\n", NIUFN); return (0); } sib = di_child_node(pnode); while (sib != DI_NODE_NIL) { if (niufn_instance_get(mod, sib, &inst) != 0) { topo_mod_dprintf(mod, "Enumeration of %s " "instance failed.\n", NIUFN); sib = di_sibling_node(sib); continue; } if ((ntn = niufn_declare(parent, NIUFN, inst, sib, mod)) == NULL) { topo_mod_dprintf(mod, "Enumeration of %s=%d " "failed: %s\n", NIUFN, inst, topo_strerror(topo_mod_errno(mod))); return (-1); } if (topo_mod_enumerate(mod, ntn, XAUI, XAUI, inst, inst, sib) != 0) { return (topo_mod_seterrno(mod, EMOD_PARTIAL_ENUM)); } sib = di_sibling_node(sib); } return (0); }
static int create_peers(mmd_t *mdp, di_prom_handle_t ph, md_node_t *node, di_node_t dev) { di_node_t di_peer; int rv; while ((di_peer = di_sibling_node(dev)) != DI_NODE_NIL) { rv = create_children(mdp, ph, node, di_peer); if (rv != 0) return (rv); dev = di_peer; } return (0); }
/* * Get the value of the named property on the named node in root. */ static char * get_prop(const char *nodename, const char *propname, size_t *lenp) { di_node_t node; di_prom_prop_t pp; char *val = NULL; int len; /* * Locate nodename within '/'. */ for (node = di_child_node(root_node); node != DI_NODE_NIL; node = di_sibling_node(node)) { if (strcmp(di_node_name(node), nodename) == 0) { break; } } if (node == DI_NODE_NIL) { return (NULL); } /* * Scan all properties of /nodename for the 'propname' property. */ for (pp = di_prom_prop_next(phdl, node, DI_PROM_PROP_NIL); pp != DI_PROM_PROP_NIL; pp = di_prom_prop_next(phdl, node, pp)) { if (strcmp(propname, di_prom_prop_name(pp)) == 0) { break; } } if (pp == DI_PROM_PROP_NIL) { return (NULL); } /* * Found the property; copy out its length and return its value. */ len = di_prom_prop_data(pp, (uchar_t **)&val); if (lenp != NULL) { *lenp = len; } return (val); }
int find_cpu(di_node_t node, int cpuid) { int dcpuid; di_node_t cnode; char *nodename; for (cnode = di_child_node(node); cnode != DI_NODE_NIL; cnode = di_sibling_node(cnode)) { nodename = di_node_name(cnode); if (nodename == NULL) continue; if (strcmp(nodename, OBP_CPU) == 0) { dcpuid = get_cpuid(cnode); if (dcpuid == cpuid) { return (1); } } } return (0); }
void devinfo_add_subtree(HalDevice *parent, di_node_t node, gboolean is_root) { HalDevice *d; di_node_t root_node, child_node; HAL_INFO (("add_subtree: %s", di_node_name (node))); root_node = node; do { d = devinfo_add_node (parent, node); if ((d != NULL) && (child_node = di_child_node (node)) != DI_NODE_NIL) { devinfo_add_subtree (d, child_node, FALSE); } node = di_sibling_node (node); } while ((node != DI_NODE_NIL) && (!is_root || di_parent_node (node) == root_node)); }
static int device_tree_to_md(mmd_t *mdp, md_node_t *top) { di_node_t node; di_node_t root; di_prom_handle_t ph; int rv = 0; root = di_init("/", DINFOSUBTREE | DINFOPROP); if (root == DI_NODE_NIL) { LDMA_ERR("di_init cannot find device tree root node."); return (errno); } ph = di_prom_init(); if (ph == DI_PROM_HANDLE_NIL) { LDMA_ERR("di_prom_init failed."); di_fini(root); return (errno); } node = di_child_node(root); while (node != NULL) { if (is_root_complex(ph, node)) { rv = create_children(mdp, ph, top, node); if (rv != 0) break; } node = di_sibling_node(node); } di_prom_fini(ph); di_fini(root); return (rv); }
int emulex_update(char *file) { int fd, retval = 0; int devcnt = 0; uint_t state = 0, fflag = 0; static uchar_t bootpath[PATH_MAX]; int fcode_fd = -1; static struct utmpx *utmpp = NULL; di_node_t root; di_node_t node, sib_node, count_node; di_minor_t minor_node; char phys_path[PATH_MAX], *path; int errnum = 0, fcio_errno = 0; static uchar_t prom_ver_data[MAXNAMELEN]; static char ver_file[EMULEX_FCODE_VERSION_LENGTH]; void (*sigint)(); int prop_entries = -1; int *port_data = NULL; if (file) { /* set the fcode download flag */ fflag++; /* check for a valid file */ if ((fcode_fd = open(file, O_RDONLY)) < 0) { (void) fprintf(stderr, MSGSTR(21118, "Error: Could not open %s, failed " "with errno %d\n"), file, errno); return (1); } /* check for single user mode */ while ((utmpp = getutxent()) != NULL) { if (strstr(utmpp->ut_line, "run-level") && (strcmp(utmpp->ut_line, "run-level S") && strcmp(utmpp->ut_line, "run-level 1"))) { if (q_warn(1)) { (void) endutxent(); (void) close(fcode_fd); return (1); } break; } } (void) endutxent(); /* get bootpath */ if (!q_getbootdev((uchar_t *)&bootpath[0]) && getenv("_LUX_D_DEBUG") != NULL) { (void) fprintf(stdout, " Bootpath: %s\n", bootpath); } } /* * Download the Fcode to all the emulex cards found */ /* Create a snapshot of the kernel device tree */ if ((root = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) { (void) fprintf(stderr, MSGSTR(21114, "Error: Could not get /devices path to " "Emulex Devices.\n")); retval++; } /* point to first node which matches emulex driver */ node = di_drv_first_node("emlxs", root); if (node == DI_NODE_NIL) { /* * Could not find any emulex cards */ (void) di_fini(root); (void) fprintf(stderr, MSGSTR(21115, "\n Found Path to %d Emulex Devices.\n"), devcnt); retval++; } else { count_node = node; while (count_node != DI_NODE_NIL) { state = di_state(count_node); if ((state & DI_DRIVER_DETACHED) != DI_DRIVER_DETACHED) { sib_node = di_child_node(count_node); while (sib_node != DI_NODE_NIL) { state = di_state(sib_node); if ((state & DI_DRIVER_DETACHED) != DI_DRIVER_DETACHED) { /* Found an attached node */ prop_entries = di_prop_lookup_ints( DDI_DEV_T_ANY, sib_node, "port", &port_data); if (prop_entries != -1) { devcnt++; break; } } sib_node = di_sibling_node(sib_node); } } count_node = di_drv_next_node(count_node); } (void) fprintf(stdout, MSGSTR(21116, "\n Found Path to %d Emulex Devices.\n"), devcnt); } /* * Traverse device tree to find all emulex cards */ while (node != DI_NODE_NIL) { state = di_state(node); if ((state & DI_DRIVER_DETACHED) == DI_DRIVER_DETACHED) { node = di_drv_next_node(node); continue; } sib_node = di_child_node(node); while (sib_node != DI_NODE_NIL) { state = di_state(sib_node); if ((state & DI_DRIVER_DETACHED) != DI_DRIVER_DETACHED) { /* Found an attached node */ prop_entries = di_prop_lookup_ints( DDI_DEV_T_ANY, sib_node, "port", &port_data); if (prop_entries != -1) { /* Found a node with "port" property */ minor_node = di_minor_next(sib_node, DI_MINOR_NIL); break; } } sib_node = di_sibling_node(sib_node); } if (sib_node == DI_NODE_NIL) { goto try_next; } path = di_devfs_path(sib_node); (void) strcpy(phys_path, "/devices"); (void) strncat(phys_path, path, strlen(path)); di_devfs_path_free(path); if (fflag && (strstr((char *)bootpath, (char *)phys_path) != NULL)) { (void) fprintf(stderr, MSGSTR(21117, "Ignoring %s (bootpath)\n"), phys_path); node = di_drv_next_node(node); continue; } if (minor_node) { (void) strncat(phys_path, ":", 1); (void) strncat(phys_path, di_minor_name(minor_node), strlen(di_minor_name(minor_node))); } (void) fprintf(stdout, MSGSTR(21107, "\n Opening Device: %s\n"), phys_path); /* Check if the device is valid */ if ((fd = open(phys_path, O_RDWR)) < 0) { (void) fprintf(stderr, MSGSTR(21121, "Error: Could not open %s, failed " "with errno %d\n"), phys_path, errno); retval++; node = di_drv_next_node(node); continue; } (void) close(fd); /* * Check FCode version present on the adapter * (at last boot) */ memset(prom_ver_data, 0, sizeof (prom_ver_data)); if (emulex_fcodeversion(node, (uchar_t *)&prom_ver_data[0]) == 0) { errnum = 0; if (strlen((char *)prom_ver_data) == 0) { (void) fprintf(stdout, MSGSTR(21108, " Detected FCode Version:\tNo version available for this FCode\n")); } else { (void) fprintf(stdout, MSGSTR(21109, " Detected FCode Version:\t%s\n"), prom_ver_data); } } else { errnum = 2; /* can't get prom properties */ retval++; } if (fflag) { memset(ver_file, 0, sizeof (ver_file)); if (emulex_fcode_reader(fcode_fd, "fcode-version", ver_file, sizeof (ver_file)) == 0) { (void) fprintf(stdout, MSGSTR(21110, " New FCode Version:\t\t%s\n"), ver_file); } else { di_fini(root); (void) close(fcode_fd); return (1); } /* * Load the New FCode * Give warning if file doesn't appear to be correct */ if (!q_warn(errnum)) { /* Disable user-interrupt Control-C */ sigint = (void (*)(int)) signal(SIGINT, SIG_IGN); /* Load FCode */ (void) fprintf(stdout, MSGSTR(21111, " Loading FCode: %s\n"), file); if (fcode_load_file(fcode_fd, phys_path, &fcio_errno) == FCODE_SUCCESS) { (void) fprintf(stdout, MSGSTR(21112, " Successful FCode download: %s\n"), phys_path); } else { handle_emulex_error(fcio_errno, phys_path); retval++; } /* Restore SIGINT (user interrupt) setting */ (void) signal(SIGINT, sigint); } } try_next: node = di_drv_next_node(node); } di_fini(root); (void) fprintf(stdout, " "); (void) fprintf(stdout, MSGSTR(125, "Complete\n")); if (fcode_fd != -1) (void) close(fcode_fd); return (retval); }
char *getDeviceFileName(MP_UINT64 objectSequenceNumber) { char *deviceFileName = NULL; di_node_t root_node = DI_NODE_NIL; di_node_t cur_node = DI_NODE_NIL; int instNum; int majorNum; MP_UINT64 osn; char *pathName = NULL; char *minorName = "c,raw"; char *devLink = NULL; char fullName[512]; walk_devlink_t warg; di_devlink_handle_t dlHandle = NULL; int diStatus = 0; log(LOG_INFO, "getDeviceFileName()", " - enter"); log(LOG_INFO, "getDeviceFileName()", " - objectSequenceNumber: %llx", objectSequenceNumber); root_node = di_init("/", DINFOCACHE); if (DI_NODE_NIL == root_node) { log(LOG_INFO, "MP_GetMultipathLusPlugin()", " - $ERROR, di_init() failed"); return (NULL); } cur_node = di_drv_first_node("scsi_vhci", root_node); if (DI_NODE_NIL == cur_node) { log(LOG_INFO, "getDeviceFileName()", " - $ERROR, di_drv_first_node() failed"); di_fini(root_node); return (NULL); } cur_node = di_child_node(cur_node); while (DI_NODE_NIL != cur_node) { instNum = di_instance(cur_node); majorNum = di_driver_major(cur_node); osn = 0; osn = MP_STORE_INST_TO_ID(instNum, osn); osn = MP_STORE_MAJOR_TO_ID(majorNum, osn); if (osn == objectSequenceNumber) { log(LOG_INFO, "getDeviceFileName()", " - found node."); break; } cur_node = di_sibling_node(cur_node); } if (DI_NODE_NIL != cur_node) { dlHandle = di_devlink_init(NULL, 0); if (NULL == dlHandle) { log(LOG_INFO, "getDeviceFileName()", " - $ERROR, di_devlink_init() failed."); di_fini(root_node); return (NULL); } pathName = di_devfs_path(cur_node); (void) snprintf(fullName, 511, "%s:%s", pathName, minorName); log(LOG_INFO, "getDeviceFileName()", " - fullName: {%s]", fullName); (void) memset(&warg, 0, sizeof (walk_devlink_t)); devLink = NULL; warg.linkpp = &devLink; diStatus = di_devlink_walk(dlHandle, NULL, fullName, DI_PRIMARY_LINK, (void *)&warg, get_devlink); if (diStatus != 0) { log(LOG_INFO, "getDeviceFileName()", "diStatus: %d", diStatus); if (diStatus < 0) { diStatus = errno; } log(LOG_INFO, "getDeviceFileName()", "diStatus: %d", diStatus); log(LOG_INFO, "getDeviceFileName()", "strerror(diStatus): %s", strerror(diStatus)); } if (NULL != devLink) { deviceFileName = (char *)calloc(1, strlen(devLink) + 1); (void) strncpy(deviceFileName, devLink, strlen(devLink)); } else { log(LOG_INFO, "getDeviceFileName()", " - $ERROR, devLink is NULL."); deviceFileName = (char *)calloc(1, 256); (void) strncpy(deviceFileName, pathName, 255); } di_devfs_path_free(pathName); (void) di_devlink_fini(&dlHandle); } di_fini(root_node); free(devLink); log(LOG_INFO, "getDeviceFileName()", " - exit"); return (deviceFileName); }
static int do_driver_update_ioctl(char *drivername, char *node_desc, char *hca_desc, uint64_t inp_hca_guid, uint32_t update_flag) { di_node_t hcanode, childnode; char *devpath; char *access_devname; int devlength, devfd, rc = -1; uint64_t *hca_guid; char *desc_str = (node_desc ? node_desc : hca_desc); if ((hcanode = di_drv_first_node(drivername, di_rootnode)) == DI_NODE_NIL) { return (-1); } while (hca_desc && hcanode != DI_NODE_NIL) { childnode = di_child_node(hcanode); while (childnode != DI_NODE_NIL) { if (di_prop_lookup_int64(DDI_DEV_T_ANY, childnode, "hca-guid", (int64_t **)&hca_guid) != 1) { childnode = di_sibling_node(childnode); continue; } else { break; } } if (*hca_guid == inp_hca_guid) break; hcanode = di_drv_next_node(hcanode); } if ((hca_desc && childnode == DI_NODE_NIL) || hcanode == DI_NODE_NIL) { IBERROR("matching GUID not found"); return (-1); } devpath = di_devfs_path(hcanode); devlength = strlen(devpath_prefix) + strlen(devpath) + strlen(devpath_suffix) + 2; access_devname = malloc(devlength); (void) snprintf(access_devname, devlength, "%s%s%s", devpath_prefix, devpath, devpath_suffix); if ((devfd = open(access_devname, O_RDONLY)) < 0) { IBERROR("open device file %s failed", access_devname); free(access_devname); return (rc); } if (strcmp(drivername, "hermon") == 0) { hermon_nodedesc_ioctl_t nodedesc_ioctl; strncpy(nodedesc_ioctl.node_desc_str, desc_str, 64); if (update_flag & NODEDESC_UPDATE_STRING) nodedesc_ioctl.node_desc_update_flag = HERMON_NODEDESC_UPDATE_STRING; else if (update_flag & NODEDESC_UPDATE_HCA_STRING) nodedesc_ioctl.node_desc_update_flag = HERMON_NODEDESC_UPDATE_HCA_STRING; else { IBERROR("Invalid option"); exit(-1); } if ((rc = ioctl(devfd, HERMON_IOCTL_SET_NODEDESC, (void *)&nodedesc_ioctl)) != 0) { IBERROR("hermon ioctl failure"); } } else { IBERROR("drivername != hermon: %s", drivername); } free(access_devname); close(devfd); return (rc); }
static void do_driver_read_ioctl(char *drivername) { di_node_t hcanode, childnode; char *devpath; char *access_devname; int devlength, devfd, rc = -1; uint64_t *hca_guid; if ((hcanode = di_drv_first_node(drivername, di_rootnode)) == DI_NODE_NIL) { return; } while (hcanode != DI_NODE_NIL) { childnode = di_child_node(hcanode); while (childnode != DI_NODE_NIL) { if (di_prop_lookup_int64(DDI_DEV_T_ANY, childnode, "hca-guid", (int64_t **)&hca_guid) != 1) { childnode = di_sibling_node(childnode); continue; } else { break; } } if (childnode == DI_NODE_NIL) { hcanode = di_drv_next_node(hcanode); continue; } devpath = di_devfs_path(hcanode); devlength = strlen(devpath_prefix) + strlen(devpath) + strlen(devpath_suffix) + 2; access_devname = malloc(devlength); (void) snprintf(access_devname, devlength, "%s%s%s", devpath_prefix, devpath, devpath_suffix); if ((devfd = open(access_devname, O_RDONLY)) < 0) { IBERROR("open device file %s failed", access_devname); free(access_devname); hcanode = di_drv_next_node(hcanode); continue; } if (strcmp(drivername, "hermon") == 0) { hermon_nodedesc_ioctl_t nodedesc_ioctl; if ((rc = ioctl(devfd, HERMON_IOCTL_GET_NODEDESC, (void *)&nodedesc_ioctl)) != 0) { IBERROR("hermon ioctl failure"); free(access_devname); close(devfd); hcanode = di_drv_next_node(hcanode); continue; } add_read_info_arr((char *)nodedesc_ioctl.node_desc_str, *hca_guid); } else { IBERROR("drivername != hermon: %s", drivername); } free(access_devname); close(devfd); hcanode = di_drv_next_node(hcanode); } }
/* * initializes the port driver and instance fields based on libdevinfo */ picl_errno_t get_port_info(frutree_portnode_t *portp) { picl_errno_t rc; di_node_t rnode, curr, peer; char devfs_path[PICL_PROPNAMELEN_MAX]; char bus_addr[PICL_PROPNAMELEN_MAX]; char *di_busaddr = NULL, *di_drv = NULL; int di_int_busaddr, int_busaddr; if ((rc = ptree_get_propval_by_name(portp->portnodeh, PICL_PROP_DEVFS_PATH, devfs_path, sizeof (devfs_path))) != PICL_SUCCESS) { return (rc); } if (ptree_get_propval_by_name(portp->portnodeh, PICL_PROP_BUS_ADDR, bus_addr, sizeof (bus_addr)) != PICL_SUCCESS) { return (rc); } rnode = di_init(devfs_path, DINFOCPYALL); if (rnode == DI_NODE_NIL) { return (PICL_FAILURE); } peer = di_child_node(rnode); while (peer != DI_NODE_NIL) { curr = peer; peer = di_sibling_node(curr); di_busaddr = di_bus_addr(curr); if (di_busaddr == NULL) { continue; } /* compare the bus_addr */ if (strstr(bus_addr, ",") != NULL) { /* bus addr is of type 1,0 */ if (strcmp(bus_addr, di_busaddr) != 0) { continue; } } else { /* bus addr is of type 0x */ errno = 0; int_busaddr = strtol(bus_addr, (char **)NULL, 16); if (errno != 0) { continue; } errno = 0; di_int_busaddr = strtol(di_busaddr, (char **)NULL, 16); if (errno != 0) { continue; } if (di_int_busaddr != int_busaddr) { continue; } } di_drv = di_driver_name(curr); if (di_drv == NULL) { di_fini(rnode); return (PICL_FAILURE); } /* initialize the driver name and instance number */ (void) strncpy(portp->driver, di_drv, sizeof (portp->driver)); portp->instance = di_instance(curr); di_fini(rnode); return (PICL_SUCCESS); } di_fini(rnode); return (PICL_NODENOTFOUND); }