/** * get_phandle * * @param char * device tree node path * @param int * pointer to phandle */ int get_phandle(char *path, uint *phandle) { int rc1,rc2; /* get "linux,phandle" property */ rc1 = get_ofdt_uint_property(path, "linux,phandle", phandle); /* overwrite with "ibm,handle" if it exists */ rc2 = get_ofdt_uint_property(path, "ibm,phandle", phandle); /* return bad if both gets failed */ if (rc1 && rc2) return rc1; else return 0; }
/** * add_child_node * * Create information about the Open Firmware node and * add that information to the appropriate per-node list of * Open Firmware nodes. Also create the corresponding information * for any PCI device. * * NOTES: * 1) does not need to be concerned about one or more Open * Firmware nodes having the used-by-rtas property present. * One of the RTAS services used during removing a PCI adapter * must take the appropriate action (most likely eliminate RTAS * usage) in this case. * 2) Open Firmware node RPA physical location code: * * [Un.m-]Pn[-Pm]-In[[/Zn]-An] * * where * Un.m is for the enclosure for multi-enclosue systems * Pn is for the planar * In is for the slot * /Zn is for the connector on the adapter card * An is for the device connected to the adapter * * note * There may be multiple levels of planars [Pm]. * * RECOVERY OPERATION: * 1) This function does not add the Open Firmware node if the user * mode process has exceeded all available malloc space. This * should not happen based on the rather small total amount of * memory allocation required. The node is marked as skip. * 2) This function does not add the device information if there * is a problem initializing device. The node is marked as skip. * * @param parent * @param child_path */ static void add_child_node(struct dr_node *parent, char *child_path) { struct dr_connector *drc_list, *drc; char loc_code[DR_BUF_SZ]; char *slash; struct dr_node *child; uint my_drc_index; int rc; assert(parent != NULL); assert(strlen(child_path) != 0); /* Make sure that the Open Firmware node is not added twice * in case the ibm,my-drc-index property is put in all nodes * for the adapter instead of just the ones at the connector. */ if (parent->children != NULL) { struct dr_node *tmp; for (tmp = parent->children; tmp; tmp = tmp->next) { if (! strcmp(tmp->ofdt_path, child_path)) return; } } /* Create the Open Firmware node's information and insert that * information into the node's list based on the node's RPA * physical location code. Ignore the OF node if the node * does not have an RPA physical location code because that is * a firmware error. */ rc = get_property(child_path, "ibm,loc-code", &loc_code, DR_BUF_SZ); if (rc) return; /* Skip the Open Firmware node if it is a device node. Determine that * the node is for a device by looking for a hyphen after the last * slash (...-In/Z1-An). */ slash = strrchr(loc_code, '/'); if (slash != NULL) { char *hyphen; hyphen = strchr(slash, '-'); if (hyphen != NULL) return; *slash = '\0'; } if (parent->dev_type == PCI_HP_DEV) { /* hotplug */ /* Squadrons don't have "/" in devices' (scsi, * ethernet, tokenring ...) loc-code strings. * * Skip the Open Firmware node if the node's RPA * physical location code does not match the node's * location code. Ignore the connector information, * i.e. information after last slash if no hyphen * follows. */ if ((strcmp(parent->drc_name, loc_code) != 0) && (slash != NULL)) { parent->skip = 1; return; } } /* Restore the slash because the full RPA location code * is saved for each OF node so that the connector * information can be used to sort the OF node list for * each node. */ if (slash != NULL) *slash = '/'; if (get_my_drc_index(child_path, &my_drc_index)) return; /* need the drc-info in the dir above */ slash = strrchr(child_path, '/'); *slash = '\0'; drc_list = get_drc_info(child_path); *slash = '/'; for (drc = drc_list; drc != NULL; drc = drc->next) { if (drc->index == my_drc_index) break; } /* Allocate space for the Open Firmware node information. */ child = alloc_dr_node(drc, parent->dev_type, child_path); if (child == NULL) { parent->skip = 1; return; } if ((! strcmp(parent->drc_type, "SLOT")) && (parent->dev_type == PCI_DLPAR_DEV)) snprintf(child->ofdt_dname, DR_STR_MAX, "%s", parent->ofdt_dname); else get_property(child_path, "name", child->ofdt_dname, sizeof(child->ofdt_dname)); switch (parent->dev_type) { case PCI_HP_DEV: case PCI_DLPAR_DEV: { get_ofdt_uint_property(child_path, "vendor-id", &child->pci_vendor_id); get_ofdt_uint_property(child_path, "device-id", &child->pci_device_id); get_ofdt_uint_property(child_path, "class_code", &child->pci_class_code); break; } case HEA_DEV: { child->dev_type = HEA_PORT_DEV; get_ofdt_uint_property(child_path, "ibm,hea-port-no", &child->hea_port_no); get_ofdt_uint_property(child_path, "ibm,hea-port-tenure", &child->hea_port_tenure); break; } } child->next = parent->children; parent->children = child; }