struct device_node *dlpar_configure_connector(u32 drc_index) { struct device_node *dn; struct device_node *first_dn = NULL; struct device_node *last_dn = NULL; struct property *property; struct property *last_property = NULL; struct cc_workarea *ccwa; char *data_buf; int cc_token; int rc = -1; cc_token = rtas_token("ibm,configure-connector"); if (cc_token == RTAS_UNKNOWN_SERVICE) return NULL; data_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); if (!data_buf) return NULL; ccwa = (struct cc_workarea *)&data_buf[0]; ccwa->drc_index = drc_index; ccwa->zero = 0; do { /* Since we release the rtas_data_buf lock between configure * connector calls we want to re-populate the rtas_data_buffer * with the contents of the previous call. */ spin_lock(&rtas_data_buf_lock); memcpy(rtas_data_buf, data_buf, RTAS_DATA_BUF_SIZE); rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); memcpy(data_buf, rtas_data_buf, RTAS_DATA_BUF_SIZE); spin_unlock(&rtas_data_buf_lock); switch (rc) { case COMPLETE: break; case NEXT_SIBLING: dn = dlpar_parse_cc_node(ccwa); if (!dn) goto cc_error; dn->parent = last_dn->parent; last_dn->sibling = dn; last_dn = dn; break; case NEXT_CHILD: dn = dlpar_parse_cc_node(ccwa); if (!dn) goto cc_error; if (!first_dn) first_dn = dn; else { dn->parent = last_dn; if (last_dn) last_dn->child = dn; } last_dn = dn; break; case NEXT_PROPERTY: property = dlpar_parse_cc_property(ccwa); if (!property) goto cc_error; if (!last_dn->properties) last_dn->properties = property; else last_property->next = property; last_property = property; break; case PREV_PARENT: last_dn = last_dn->parent; break; case CALL_AGAIN: break; case MORE_MEMORY: case ERR_CFG_USE: default: printk(KERN_ERR "Unexpected Error (%d) " "returned from configure-connector\n", rc); goto cc_error; } } while (rc); cc_error: kfree(data_buf); if (rc) { if (first_dn) dlpar_free_cc_nodes(first_dn); return NULL; } return first_dn; }
struct device_node *dlpar_configure_connector(u32 drc_index) { struct device_node *dn; struct device_node *first_dn = NULL; struct device_node *last_dn = NULL; struct property *property; struct property *last_property = NULL; struct cc_workarea *ccwa; int cc_token; int rc; cc_token = rtas_token("ibm,configure-connector"); if (cc_token == RTAS_UNKNOWN_SERVICE) return NULL; spin_lock(&rtas_data_buf_lock); ccwa = (struct cc_workarea *)&rtas_data_buf[0]; ccwa->drc_index = drc_index; ccwa->zero = 0; rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); while (rc) { switch (rc) { case NEXT_SIBLING: dn = dlpar_parse_cc_node(ccwa); if (!dn) goto cc_error; dn->parent = last_dn->parent; last_dn->sibling = dn; last_dn = dn; break; case NEXT_CHILD: dn = dlpar_parse_cc_node(ccwa); if (!dn) goto cc_error; if (!first_dn) first_dn = dn; else { dn->parent = last_dn; if (last_dn) last_dn->child = dn; } last_dn = dn; break; case NEXT_PROPERTY: property = dlpar_parse_cc_property(ccwa); if (!property) goto cc_error; if (!last_dn->properties) last_dn->properties = property; else last_property->next = property; last_property = property; break; case PREV_PARENT: last_dn = last_dn->parent; break; case CALL_AGAIN: break; case MORE_MEMORY: case ERR_CFG_USE: default: printk(KERN_ERR "Unexpected Error (%d) " "returned from configure-connector\n", rc); goto cc_error; } rc = rtas_call(cc_token, 2, 1, NULL, rtas_data_buf, NULL); } spin_unlock(&rtas_data_buf_lock); return first_dn; cc_error: if (first_dn) dlpar_free_cc_nodes(first_dn); spin_unlock(&rtas_data_buf_lock); return NULL; }