On 07/27/2016 09:23 AM, Michael Bringmann wrote: > rpadlpar_core.c: Provide parallel routines to search the older device- > tree properties ("ibm,drc-indexes", "ibm,drc-names", "ibm,drc-types" > and "ibm,drc-power-domains"), or the new property "ibm,drc-info". The > code searches for PHP PCI Slots, gets the DRC properties within the > current node (using my-drc-index as correlation), and performs searches > by name or type of DRC node.
This looks correct, and I like the change from a get to check routine. I think a little more explanation of this would be good. This update allows for the ibm,drc-info properties and also changes the routine to validate the drc-name and/or drc-type instead of having the caller do this. I think that should be mentioned. -Nathan > > Signed-off-by: Michael Bringmann <m...@linux.vnet.ibm.com> > --- > diff --git a/drivers/pci/hotplug/rpadlpar_core.c > b/drivers/pci/hotplug/rpadlpar_core.c > index dc67f39..bea9723 100644 > --- a/drivers/pci/hotplug/rpadlpar_core.c > +++ b/drivers/pci/hotplug/rpadlpar_core.c > @@ -27,6 +27,7 @@ > #include <linux/mutex.h> > #include <asm/rtas.h> > #include <asm/vio.h> > +#include <linux/firmware.h> > > #include "../pci.h" > #include "rpaphp.h" > @@ -44,15 +45,14 @@ static struct device_node *find_vio_slot_node(char > *drc_name) > { > struct device_node *parent = of_find_node_by_name(NULL, "vdevice"); > struct device_node *dn = NULL; > - char *name; > int rc; > > if (!parent) > return NULL; > > while ((dn = of_get_next_child(parent, dn))) { > - rc = rpaphp_get_drc_props(dn, NULL, &name, NULL, NULL); > - if ((rc == 0) && (!strcmp(drc_name, name))) > + rc = rpaphp_check_drc_props(dn, drc_name, NULL); > + if (rc == 0) > break; > } > > @@ -64,15 +64,12 @@ static struct device_node *find_php_slot_pci_node(char > *drc_name, > char *drc_type) > { > struct device_node *np = NULL; > - char *name; > - char *type; > int rc; > > while ((np = of_find_node_by_name(np, "pci"))) { > - rc = rpaphp_get_drc_props(np, NULL, &name, &type, NULL); > + rc = rpaphp_check_drc_props(np, drc_name, drc_type); > if (rc == 0) > - if (!strcmp(drc_name, name) && !strcmp(drc_type, type)) > - break; > + break; > } > > return np; > diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h > index 7db024e..8db5f2e 100644 > --- a/drivers/pci/hotplug/rpaphp.h > +++ b/drivers/pci/hotplug/rpaphp.h > @@ -91,8 +91,8 @@ int rpaphp_get_sensor_state(struct slot *slot, int *state); > > /* rpaphp_core.c */ > int rpaphp_add_slot(struct device_node *dn); > -int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, > - char **drc_name, char **drc_type, int *drc_power_domain); > +int rpaphp_check_drc_props(struct device_node *dn, char *drc_name, > + char *drc_type); > > /* rpaphp_slot.c */ > void dealloc_slot_struct(struct slot *slot); > diff --git a/drivers/pci/hotplug/rpaphp_core.c > b/drivers/pci/hotplug/rpaphp_core.c > index 8d13202..0cfdbd9 100644 > --- a/drivers/pci/hotplug/rpaphp_core.c > +++ b/drivers/pci/hotplug/rpaphp_core.c > @@ -30,6 +30,7 @@ > #include <linux/smp.h> > #include <linux/init.h> > #include <linux/vmalloc.h> > +#include <asm/firmware.h> > #include <asm/eeh.h> /* for eeh_add_device() */ > #include <asm/rtas.h> /* rtas_call */ > #include <asm/pci-bridge.h> /* for pci_controller */ > @@ -142,15 +143,6 @@ static enum pci_bus_speed get_max_bus_speed(struct slot > *slot) > case 5: > case 6: > speed = PCI_SPEED_33MHz; /* speed for case 1-6 */ > - break; > - case 7: > - case 8: > - speed = PCI_SPEED_66MHz; > - break; > - case 11: > - case 14: > - speed = PCI_SPEED_66MHz_PCIX; > - break; Why are you getting rid of these? > case 12: > case 15: > speed = PCI_SPEED_100MHz_PCIX; > @@ -196,25 +188,21 @@ static int get_children_props(struct device_node *dn, > const int **drc_indexes, > return 0; > } > > -/* To get the DRC props describing the current node, first obtain it's > - * my-drc-index property. Next obtain the DRC list from it's parent. Use > - * the my-drc-index for correlation, and obtain the requested properties. > + > +/* Verify the existence of 'drc_name' and/or 'drc_type' within the > + * current node. First obtain it's my-drc-index property. Next, > + * obtain the DRC info from it's parent. Use the my-drc-index for > + * correlation, and obtain/validate the requested properties. > */ > -int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, > - char **drc_name, char **drc_type, int *drc_power_domain) > + > +static int rpaphp_check_drc_props_v1(struct device_node *dn, char *drc_name, > + char *drc_type, unsigned int my_index) > { > + char *name_tmp, *type_tmp; > const int *indexes, *names; > const int *types, *domains; > - const unsigned int *my_index; > - char *name_tmp, *type_tmp; > int i, rc; > > - my_index = of_get_property(dn, "ibm,my-drc-index", NULL); > - if (!my_index) { > - /* Node isn't DLPAR/hotplug capable */ > - return -EINVAL; > - } > - > rc = get_children_props(dn->parent, &indexes, &names, &types, &domains); > if (rc < 0) { > return -EINVAL; > @@ -225,24 +213,83 @@ int rpaphp_get_drc_props(struct device_node *dn, int > *drc_index, > > /* Iterate through parent properties, looking for my-drc-index */ > for (i = 0; i < be32_to_cpu(indexes[0]); i++) { > - if ((unsigned int) indexes[i + 1] == *my_index) { > - if (drc_name) > - *drc_name = name_tmp; > - if (drc_type) > - *drc_type = type_tmp; > - if (drc_index) > - *drc_index = be32_to_cpu(*my_index); > - if (drc_power_domain) > - *drc_power_domain = be32_to_cpu(domains[i+1]); > - return 0; > - } > + if ((unsigned int) indexes[i + 1] == my_index) > + break; > + > name_tmp += (strlen(name_tmp) + 1); > type_tmp += (strlen(type_tmp) + 1); > } > > + if (((drc_name == NULL) || (drc_name && !strcmp(drc_name, name_tmp))) && > + ((drc_type == NULL) || (drc_type && !strcmp(drc_type, type_tmp)))) > + return 0; > + > + return -EINVAL; > +} > + > +static int rpaphp_check_drc_props_v2(struct device_node *dn, char *drc_name, > + char *drc_type, unsigned int my_index) > +{ > + int *info = (int *)dn; > + unsigned int entries; > + unsigned long int fdi = 0, ldi = 0, nsl = 0, si = 0; > + char *name_tmp, *type_tmp; > + int j, ret = -EINVAL; > + > + info = (int *)of_get_property(dn->parent, "ibm,drc-info", NULL); > + if (info == NULL) > + return -EINVAL; > + > + entries = be32_to_cpu(*info++); > + > + for (j = 0; j < entries; j++) { > + read_one_drc_info(&info, &type_tmp, &name_tmp, > + &fdi, &nsl, &si, &ldi); > + > + /* Should now know end of current entry */ > + > + ldi = fdi + ((nsl-1)*si); > + > + WARN_ON(my_index < fdi); > + if (my_index > ldi) > + continue; > + > + WARN_ON(((my_index-fdi)%si) != 0); > + > + ret = ((my_index-fdi)/si); > + break; > + } > + /* Found it */ > + > + if (((drc_name == NULL) || > + (drc_name && !strcmp(drc_name, name_tmp))) && > + ((drc_type == NULL) || > + (drc_type && !strcmp(drc_type, type_tmp)))) > + return 0; > + > return -EINVAL; > } > -EXPORT_SYMBOL_GPL(rpaphp_get_drc_props); > + > +int rpaphp_check_drc_props(struct device_node *dn, char *drc_name, > + char *drc_type) > +{ > + const unsigned int *my_index; > + > + my_index = of_get_property(dn, "ibm,my-drc-index", NULL); > + if (!my_index) { > + /* Node isn't DLPAR/hotplug capable */ > + return -EINVAL; > + } > + > + if (firmware_has_feature(FW_FEATURE_DRC_INFO)) > + return rpaphp_check_drc_props_v2(dn, drc_name, drc_type, > + *my_index); > + else > + return rpaphp_check_drc_props_v1(dn, drc_name, drc_type, > + *my_index); > +} > +EXPORT_SYMBOL_GPL(rpaphp_check_drc_props); > + > > static int is_php_type(char *drc_type) > { > > _______________________________________________ > Linuxppc-dev mailing list > Linuxppc-dev@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/linuxppc-dev > _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev