/** * init_node * * @param node * @returns 0 on success, !0 otherwise */ static int init_node(struct dr_node *node) { struct dirent **de_list, *de; char *newpath; int count; int rc, i; if (node->is_owned) find_ofdt_dname(node, node->ofdt_path); count = scandir(node->ofdt_path, &de_list, 0, alphasort); for (i = 0; i < count; i++) { de = de_list[i]; if ((de->d_type != DT_DIR) || is_dot_dir(de->d_name)) continue; newpath = zalloc(strlen(node->ofdt_path) + strlen(de->d_name) + 2); if (newpath == NULL) { say(ERROR, "Could not allocate path for node at " "%s/%s\n", node->ofdt_path, de->d_name); return 1; } sprintf(newpath, "%s/%s", node->ofdt_path, de->d_name); rc = examine_child(node, newpath); if (rc) return rc; } return 0; }
static void remove_dir (const char *dir) { HANDLE hFind; WIN32_FIND_DATA wfd; char path[MAX_PATH]; size_t dirlen = strlen (dir); /* Make sure the directory exists before going further */ memcpy (path, dir, dirlen); strcpy (path + dirlen++, "\\*"); hFind = FindFirstFile (path, &wfd); if (hFind == INVALID_HANDLE_VALUE) return; do { char *lp = wfd.cFileName; if (!lp[0]) lp = wfd.cAlternateFileName; /* ? FIXME not (!lp) ? */ if (is_dot_dir (lp)) continue; strcpy (path + dirlen, lp); if (FILE_ATTRIBUTE_DIRECTORY & wfd.dwFileAttributes) remove_dir(path); else if (!DeleteFile (path)) report (R_WARNING, "Can't delete file %s: error %d", path, GetLastError ()); } while (FindNextFile (hFind, &wfd)); FindClose (hFind); if (!RemoveDirectory (dir)) report (R_WARNING, "Can't remove directory %s: error %d", dir, GetLastError ()); }
/** * _get_hp_nodes * @brief The workhorse routine for finding hotplug nodes * * @param dir start directory for searching * @param pointer to list of nodes to return * @return 0 on success, !0 otherwise */ static int _get_hp_nodes(char *dir, struct dr_node **list) { struct dirent *de; DIR *d; char path[1024]; d = opendir(dir); if (d == NULL) { say(ERROR, "failed to open %s\n%s\n", dir, strerror(errno)); return -1; } while ((de = readdir(d)) != NULL) { if ((de->d_type != DT_DIR) || is_dot_dir(de->d_name)) continue; if (strncmp(de->d_name, "pci@", 4)) continue; memset(path, 0, 1024); sprintf(path, "%s/%s", dir, de->d_name); add_pci_vio_node(path, PCI_HP_DEV, list); _get_hp_nodes(path, list); } closedir(d); return 0; }
/** * get_dlpar_nodes * * @param list_type * @returns pointer to node list on success, NULL otherwise */ struct dr_node * get_dlpar_nodes(uint32_t node_types) { struct dr_connector *drc_list = NULL; struct dr_node *node_list = NULL; struct dirent *de; DIR *d; char path[1024]; say(DEBUG, "Getting node types 0x%08x\n", node_types); d = opendir(OFDT_BASE); if (d == NULL) { say(ERROR, "failed to open %s\n%s\n", OFDT_BASE, strerror(errno)); return NULL; } while ((de = readdir(d)) != NULL) { if ((de->d_type != DT_DIR) || is_dot_dir(de->d_name)) continue; memset(path, 0, 1024); sprintf(path, "%s/%s", OFDT_BASE, de->d_name); if ((! strcmp(de->d_name, "vdevice")) && (node_types & VIO_NODES)) add_pci_vio_node(path, VIO_DEV, &node_list); else if (! strncmp(de->d_name, "pci@", 4)) { if (node_types & PCI_NODES) add_pci_vio_node(path, PCI_DLPAR_DEV, &node_list); else if (node_types & PHB_NODES) { if (drc_list == NULL) drc_list = get_drc_info(OFDT_BASE); add_phb_node(path, drc_list, &node_list); } } else if ((! strncmp(de->d_name, "lhea@", 5)) && (node_types & HEA_NODES)) { if (drc_list == NULL) drc_list = get_drc_info(OFDT_BASE); add_hea_node(path, drc_list, &node_list); } } closedir(d); if (node_list != NULL) { add_linux_devices(NULL, node_list); if (node_types & PHB_NODES) update_phb_ic_info(node_list); } return node_list; }
/** * init_node * * @param node * @returns 0 on success, !0 otherwise */ static int init_node(struct dr_node *node) { DIR *d; struct dirent *de; char child_path[DR_PATH_MAX]; uint32_t my_drc_index; int rc; if (node->is_owned) find_ofdt_dname(node, node->ofdt_path); d = opendir(node->ofdt_path); if (!d) return -1; rc = 0; while ((de = readdir(d)) != NULL) { if ((de->d_type != DT_DIR) || is_dot_dir(de->d_name)) continue; sprintf(child_path, "%s/%s", node->ofdt_path, de->d_name); if (get_my_drc_index(child_path, &my_drc_index)) continue; if (node->dev_type == PCI_HP_DEV) { if (node->drc_index == my_drc_index) { /* Add hotplug children */ add_child_node(node, child_path); } } else { if (!node->is_owned) { if (node->drc_index == my_drc_index) { /* Update node path */ snprintf(node->ofdt_path, DR_PATH_MAX, "%s", child_path); node->is_owned = 1; /* Populate w/ children */ rc = init_node(node); if (rc) break; } } else { /* Add all DR-capable children */ add_child_node(node, child_path); } } } closedir(d); return rc; }
/** * remove_device_tree_nodes * * Remove all device nodes and children device nodes from Open Firmware * device tree * * @param root_path * @returns 0 on success, !0 otherwise */ int remove_device_tree_nodes(char *path) { DIR *d; struct dirent *de; struct stat sb; int found = 1; int rc; rc = lstat(path, &sb); if (rc || (!S_ISDIR(sb.st_mode)) || (S_ISLNK(sb.st_mode))) return rc; d = opendir(path); if (d == NULL) { say(ERROR, "Could not open %s: %s\n", path, strerror(errno)); return -1; } while (found) { char subdir_name[DR_PATH_MAX]; found = 0; /* Remove any subdirectories */ while ((de = readdir(d)) != NULL) { if (is_dot_dir(de->d_name)) continue; sprintf(subdir_name, "%s/%s", path, de->d_name); rc = lstat(subdir_name, &sb); if (!rc && (S_ISDIR(sb.st_mode)) && (!S_ISLNK(sb.st_mode))) { found = 1; break; } } if (found) { rc = remove_device_tree_nodes(subdir_name); rewinddir(d); } if (rc) break; } closedir(d); if (!rc) rc = remove_node(path); return rc; }
static int get_os_hp_devices(struct hpdev **hpdev_list) { struct hpdev *hp_list = NULL; struct hpdev *hpdev; DIR *d; struct dirent *de; int rc = 0; d = opendir(SYSFS_PCI_DEV_PATH); if (!d) { say(ERROR, "Failed to open %s\n", SYSFS_PCI_DEV_PATH); return -1; } while ((de = readdir(d)) != NULL) { if (is_dot_dir(de->d_name)) continue; hpdev = zalloc(sizeof(*hpdev)); if (!hpdev) { rc = -1; break; } rc = sprintf(hpdev->path, "%s/%s", SYSFS_PCI_DEV_PATH, de->d_name); if (rc < 0) break; rc = get_str_attribute(hpdev->path, "devspec", hpdev->devspec, 256); if (rc) break; say(DEBUG, "HPDEV: %s\n %s\n", hpdev->path, hpdev->devspec); hpdev->next = hp_list; hp_list = hpdev; } closedir(d); if (rc) { free_hpdev_list(hp_list); hp_list = NULL; } *hpdev_list = hp_list; return rc; }
static int cpu_index_to_path(struct dr_node *cpu) { DIR *d; struct dirent *de; int found = 0; int rc; char path[DR_PATH_MAX]; d = opendir(CPU_OFDT_BASE); if (d == NULL) { say(ERROR, "Could not open %s: %s\n", CPU_OFDT_BASE, strerror(errno)); return -1; } while ((de = readdir(d)) != NULL) { uint32_t my_drc_index; if ((de->d_type != DT_DIR) || is_dot_dir(de->d_name)) continue; if (strncmp(de->d_name, "PowerPC", 7)) continue; sprintf(path, "%s/%s", CPU_OFDT_BASE, de->d_name); rc = get_my_drc_index(path, &my_drc_index); if (rc) { /* This is an error, but continue searching since * this may not be the drc index we are looking for */ say(DEBUG, "Could not retrieve drc_index for %s\n", path); continue; } if (my_drc_index == cpu->drc_index) { found = 1; break; } } closedir(d); if (found) snprintf(cpu->ofdt_path, DR_PATH_MAX, "%s", path); return rc; }
/** * update_phb_ic_info * @brief Add interrupt controller information to PHB nodes * * We need to have the interrupt-controller ofdt paths for all PHB * nodes to do DLPAR. This routine adds that information for PHB nodes * that we found. * * @param node_list list of PHB nodes * @returns 0 on success, !0 otherwise */ static int update_phb_ic_info(struct dr_node *node_list) { char *ic_dir = "interrupt-controller"; struct dr_node *node; struct dirent *de; DIR *d; int rc = 0; d = opendir(OFDT_BASE); if (d == NULL) { say(ERROR, "failed to open %s\n%s\n", OFDT_BASE, strerror(errno)); return -1; } while ((de = readdir(d)) != NULL) { uint my_drc_index; char ofdt_path[DR_PATH_MAX]; if ((de->d_type != DT_DIR) || is_dot_dir(de->d_name)) continue; if (strncmp(de->d_name, ic_dir, strlen(ic_dir))) continue; sprintf(ofdt_path, "%s/%s", OFDT_BASE, de->d_name); rc = get_my_drc_index(ofdt_path, &my_drc_index); if (rc) /* This is expected to fail sometimes, as there can be * more ICs than PHBs on a system. In this case, some * ICs won't have my-drc-index. */ continue; for (node = node_list; node; node = node->next) { if ((node->dev_type == PHB_DEV) && (node->drc_index == my_drc_index)) { snprintf(node->phb_ic_ofdt_path, DR_PATH_MAX, "%s", ofdt_path); break; } } } closedir(d); return 0; }
static int disable_os_hp_children_recurse(struct dr_node *phb, struct hpdev *hpdev_list, char *ofpath) { struct hpdev *hpdev; DIR *d; struct dirent *de; int rc = 0; d = opendir(ofpath); if (!d) return -1; while ((de = readdir(d)) != NULL) { char devspec[256]; if (is_dot_dir(de->d_name)) continue; if (de->d_type == DT_DIR) { char lpath[4096]; sprintf(lpath, "%s/%s", ofpath, de->d_name); rc = disable_os_hp_children_recurse(phb, hpdev_list, lpath); } memset(devspec, 0, 256); sprintf(devspec, "%s/%s", ofpath + strlen(OFDT_BASE), de->d_name); for (hpdev = hpdev_list; hpdev; hpdev = hpdev->next) { if (!strcmp(hpdev->devspec, devspec)) { rc = hp_remove_os_device(hpdev); break; } } if (rc) { say(ERROR, "Failed to hotplug remove %s\n", hpdev->path); break; } } closedir(d); return rc; }
/** * get_drc_by_name * @brief Retrieve a dr_connector with the specified drc_name * * This routine searches the drc lists for a dr_connector with the * specified name starting at the specified directory. If a dr_connector * is found the root_dir that the dr_connector was found in is also * filled out. * * @param drc_name name of the dr_connector to search for * @param drc pointer to a drc to point to the found dr_connector * @param root_dir pointer to buf to fill in with root directory * @param start_dir, directory to start searching * @returns 0 on success (drc and root_dir filled in), !0 on failure */ int get_drc_by_name(char *drc_name, struct dr_connector *drc, char *root_dir, char *start_dir) { struct dr_connector *drc_list = NULL; struct dr_connector *drc_entry; struct dirent *de; DIR *d; int rc = -1; memset(drc, 0, sizeof(*drc)); /* Try to get the drc in this directory */ drc_list = get_drc_info(start_dir); if (drc_list == NULL) return -1; drc_entry = search_drc_list(drc_list, NULL, DRC_NAME, drc_name); if (drc_entry != NULL) { memcpy(drc, drc_entry, sizeof(*drc)); sprintf(root_dir, "%s", start_dir); return 0; } /* If we didn't find it here, check the subdirs */ d = opendir(start_dir); if (d == NULL) return -1; while ((de = readdir(d)) != NULL) { char dir_path[DR_PATH_MAX]; if ((de->d_type != DT_DIR) || is_dot_dir(de->d_name)) continue; sprintf(dir_path, "%s/%s", start_dir, de->d_name); rc = get_drc_by_name(drc_name, drc, root_dir, dir_path); if (rc == 0) break; } closedir(d); return rc; }
/** * add_linux_devices * */ static void add_linux_devices(char *start_dir, struct dr_node *node_list) { struct dirent *de; DIR *d; char *dir; int rc; if (start_dir == NULL) dir = "/sys/devices"; else dir = start_dir; d = opendir(dir); if (d == NULL) { say(ERROR, "failed to open %s\n%s\n", dir, strerror(errno)); return; } while ((de = readdir(d)) != NULL) { char buf[1024]; if (is_dot_dir(de->d_name)) continue; if (de->d_type == DT_DIR) { sprintf(buf, "%s/%s", dir, de->d_name); add_linux_devices(buf, node_list); } else if (! strcmp(de->d_name, "devspec")) { char devspec[DR_PATH_MAX]; sprintf(buf, "%s/%s", dir, de->d_name); rc = get_str_attribute(buf, NULL, devspec, DR_PATH_MAX); if (rc == 0) rc = correlate_devspec(dir, devspec, node_list); } } closedir(d); }
/** * init_cpu_info * @brief Initialize cpu information * * @returns pointer to cpu_info on success, NULL otherwise */ static int init_cpu_info(struct dr_info *dr_info) { struct dr_connector *drc_list, *drc; struct dr_node *cpu, *cpu_list = NULL; DIR *d; struct dirent *de; int rc = 0; drc_list = get_drc_info(CPU_OFDT_BASE); if (drc_list == NULL) { say(ERROR, "Could not get drc information for %s\n", CPU_OFDT_BASE); return -1; } /* For cpu dlpar, we need a list of all possible cpus on the system */ for (drc = drc_list; drc; drc = drc->next) { cpu = alloc_dr_node(drc, CPU_DEV, NULL); if (cpu == NULL) { say(ERROR, "Could not allocate CPU node structure: " "%s\n", strerror(errno)); free_node(cpu_list); return -1; } cpu->next = cpu_list; cpu_list = cpu; } d = opendir(CPU_OFDT_BASE); if (d == NULL) { say(ERROR, "Could not open %s: %s\n", CPU_OFDT_BASE, strerror(errno)); free_node(cpu_list); return -1; } while ((de = readdir(d)) != NULL) { char path[DR_PATH_MAX]; if ((de->d_type != DT_DIR) || is_dot_dir(de->d_name)) continue; if (! strncmp(de->d_name, "PowerPC", 7)) { uint32_t my_drc_index; memset(path, 0, 1024); sprintf(path, "%s/%s", CPU_OFDT_BASE, de->d_name); rc = get_my_drc_index(path, &my_drc_index); if (rc) { say(ERROR, "Could not retrieve drc index for " "%s\n", path); break; } for (cpu = cpu_list; cpu; cpu = cpu->next) { if (cpu->drc_index == my_drc_index) break; } if (cpu == NULL) { say(ERROR, "Could not find cpu with drc index " "%x\n", my_drc_index); rc = -1; break; } rc = update_cpu_node(cpu, path, dr_info); if (rc) break; say(DEBUG, "Found cpu %s\n", cpu->name); } } closedir(d); if (rc) free_node(cpu_list); else dr_info->all_cpus = cpu_list; return rc; }