diff mbox series

[v3] PCI: create optional loc-code platform callback

Message ID 20200214141740.17195-1-klaus@linux.vnet.ibm.com
State Superseded
Headers show
Series [v3] PCI: create optional loc-code platform callback | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success Successfully applied on branch master (53944d45087bd78bf7f9494a54e464c74322a83a)
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot success Test snowpatch/job/snowpatch-skiboot on branch master
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot-dco success Signed-off-by present

Commit Message

Klaus Heinrich Kiwi Feb. 14, 2020, 2:17 p.m. UTC
Some platforms (mostly OpenPower-based) will favor a short,
slot-label-based string for the "ibm,loc-code" DT property. Other
platforms such as ZZ/FSP-based platforms will prefer the fully-qualified
slot-location-code for it.

This patch creates a new optional callbacl on the platform struct,
allowing platforms to create the "ibm,loc-code" property in their 
specific way. If the callback is not defined, default to the cleaned-up
pci_add_loc_code() that was in use so far.

Signed-off-by: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>
---
 core/pci.c                      | 70 +++++++++++----------------------
 include/platform.h              |  8 ++++
 platforms/ibm-fsp/firenze-pci.c | 68 ++++++++++++++++++++++++++++++++
 platforms/ibm-fsp/firenze.c     |  1 +
 platforms/ibm-fsp/ibm-fsp.h     |  2 +
 platforms/ibm-fsp/zz.c          |  1 +
 6 files changed, 103 insertions(+), 47 deletions(-)

Comments

Oliver O'Halloran Feb. 18, 2020, 4:16 a.m. UTC | #1
On Sat, Feb 15, 2020 at 1:18 AM Klaus Heinrich Kiwi
<klaus@linux.vnet.ibm.com> wrote:
>
> Some platforms (mostly OpenPower-based) will favor a short,
> slot-label-based string for the "ibm,loc-code" DT property. Other
> platforms such as ZZ/FSP-based platforms will prefer the fully-qualified
> slot-location-code for it.
>
> This patch creates a new optional callbacl on the platform struct,
> allowing platforms to create the "ibm,loc-code" property in their
> specific way. If the callback is not defined, default to the cleaned-up
> pci_add_loc_code() that was in use so far.
>
> Signed-off-by: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>
> ---
>  core/pci.c                      | 70 +++++++++++----------------------
>  include/platform.h              |  8 ++++
>  platforms/ibm-fsp/firenze-pci.c | 68 ++++++++++++++++++++++++++++++++
>  platforms/ibm-fsp/firenze.c     |  1 +
>  platforms/ibm-fsp/ibm-fsp.h     |  2 +
>  platforms/ibm-fsp/zz.c          |  1 +
>  6 files changed, 103 insertions(+), 47 deletions(-)
>
> diff --git a/core/pci.c b/core/pci.c
> index 8b52fc10..5170d30b 100644
> --- a/core/pci.c
> +++ b/core/pci.c
> @@ -1383,75 +1383,45 @@ void pci_std_swizzle_irq_map(struct dt_node *np,
>         free(map);
>  }
>
> -static void pci_add_loc_code(struct dt_node *np, struct pci_device *pd)
> +static void pci_add_loc_code(struct dt_node *np, struct pci_device *pd __unused)

Just remove the unused parameter. If someone needs it they can add it back.

>  {
>         struct dt_node *p = np->parent;
> -       const char *blcode = NULL;
> -       char *lcode;
> -       uint32_t class_code;
> -       uint8_t class, sub;
> -       uint8_t pos, len;
> +       const char *lcode = NULL;
>
>         while (p) {
> -               /* if we have a slot label (i.e. openpower) use that */
> -               blcode = dt_prop_get_def(p, "ibm,slot-label", NULL);
> -               if (blcode)
> +               /* prefer slot-label by default */
> +               lcode = dt_prop_get_def(p, "ibm,slot-label", NULL);
> +               if (lcode)
>                         break;
>
>                 /* otherwise use the fully qualified location code */
> -               blcode = dt_prop_get_def(p, "ibm,slot-location-code", NULL);
> -               if (blcode)
> +               lcode = dt_prop_get_def(p, "ibm,slot-location-code", NULL);
> +               if (lcode)
>                         break;
>
>                 p = p->parent;
>         }
>
> -       if (!blcode)
> -               blcode = dt_prop_get_def(np, "ibm,slot-location-code", NULL);
> +       /* try the node itself if none is found */
> +       if (!lcode)
> +               lcode = dt_prop_get_def(np, "ibm,slot-location-code", NULL);
>
> -       if (!blcode) {
> +       if (!lcode) {
>                 /* Fall back to finding a ibm,loc-code */
>                 p = np->parent;
>
>                 while (p) {
> -                       blcode = dt_prop_get_def(p, "ibm,loc-code", NULL);
> -                       if (blcode)
> +                       lcode = dt_prop_get_def(p, "ibm,loc-code", NULL);
> +                       if (lcode)
>                                 break;
>                         p = p->parent;
>                 }
>         }

For future reference cleanups such as renaming variables should
probably go into a separate patch. I'm not that bothered if minor
cleanups are included in small patches, but this is one pretty large
already and the noise in the diff makes it harder to see what's going
on.

> -       if (!blcode)
> +       if (!lcode)
>                 return;
>
> -       /* ethernet devices get port codes */
> -       class_code = dt_prop_get_u32(np, "class-code");
> -       class = class_code >> 16;
> -       sub = (class_code >> 8) & 0xff;
> -
> -       /* XXX Don't do that on openpower for now, we will need to sort things
> -        * out later, otherwise the mezzanine slot on Habanero gets weird results
> -        */
> -       if (class == 0x02 && sub == 0x00 && !platform.bmc) {
> -               /* There's usually several spaces at the end of the property.
> -                  Test for, but don't rely on, that being the case */
> -               len = strlen(blcode);
> -               for (pos = 0; pos < len; pos++)
> -                       if (blcode[pos] == ' ') break;
> -               if (pos + 3 < len)
> -                       lcode = strdup(blcode);
> -               else {
> -                       lcode = malloc(pos + 3);
> -                       memcpy(lcode, blcode, len);
> -               }
> -               lcode[pos++] = '-';
> -               lcode[pos++] = 'T';
> -               lcode[pos++] = (char)PCI_FUNC(pd->bdfn) + '1';
> -               lcode[pos++] = '\0';
> -               dt_add_property_string(np, "ibm,loc-code", lcode);
> -               free(lcode);
> -       } else
> -               dt_add_property_string(np, "ibm,loc-code", blcode);
> +       dt_add_property_string(np, "ibm,loc-code", lcode);
>  }
>
>  static void pci_print_summary_line(struct phb *phb, struct pci_device *pd,
> @@ -1594,8 +1564,14 @@ static void __noinline pci_add_one_device_node(struct phb *phb,
>                 dt_add_property_string(np, "ibm,slot-location-code",
>                                        phb->base_loc_code);
>
> -       /* Make up location code */
> -       pci_add_loc_code(np, pd);

> +       /*
> +        * Use platform-specific callback (if there is one) to make up
> +        * location code
> +        */
Don't write comments like this. I know that it uses a platform
specific callback if one exists, because the code is right there.
Comments are for putting things in context and explaining why
something is happening. Repeating what the code says in prose can be
justifiable if it's something tricky is going on, but that's not the
case here.


> +       if (platform.pci_get_loc_code)
> +               platform.pci_get_loc_code(np, pd);
> +       else
> +               pci_add_loc_code(np, pd);

Why'd you change the name from _add_ to _get_? Add_loc_code makes more
sense to me since that's what the function actually does.

>         /* XXX FIXME: We don't look for BARs, we only put the config space
>          * entry in the "reg" property. That's enough for Linux and we might
> diff --git a/include/platform.h b/include/platform.h
> index 6909a6a4..22b5f6d2 100644
> --- a/include/platform.h
> +++ b/include/platform.h
> @@ -185,6 +185,14 @@ struct platform {
>         void            (*pci_get_slot_info)(struct phb *phb,
>                                              struct pci_device *pd);
>
> +       /*
> +        * Called for each device during pci_add_device_nodes() descend
> +        * to create the device tree, in order to get the correct per-platform
> +        * preference for the ibm,loc-code property
> +        */
> +       void            (*pci_get_loc_code)(struct dt_node *np,
> +                                            struct pci_device *pd);
> +
>         /*
>          * Called after PCI probe is complete and before inventory is
>          * displayed in console. This can either run platform fixups or
> diff --git a/platforms/ibm-fsp/firenze-pci.c b/platforms/ibm-fsp/firenze-pci.c
> index 6d5aab1e..bef69052 100644
> --- a/platforms/ibm-fsp/firenze-pci.c
> +++ b/platforms/ibm-fsp/firenze-pci.c
> @@ -972,3 +972,71 @@ void firenze_pci_get_slot_info(struct phb *phb, struct pci_device *pd)
>                 firenze_pci_slot_init(slot);
>         }
>  }
> +
> +void firenze_pci_get_loc_code(struct dt_node *np, struct pci_device *pd)
> +{
> +       struct dt_node *p = np->parent;
> +       const char *blcode = NULL;
> +       char *lcode;
> +       uint32_t class_code;
> +       uint8_t class,sub;
> +       uint8_t pos, len;
> +
> +
> +       /*
> +        * prefer fully-qualified slot-location-code, walk-up parent tree
> +        * to find one
> +        */
> +       while (p) {
> +               blcode = dt_prop_get_def(p, "ibm,slot-location-code", NULL);
> +               if (blcode)
> +                       break;
> +
> +               p = p-> parent;
stray space between the -> and parent.

Making this use a for loop instead wouldn't hurt either:
for (p = np->parent; p; p = np->parent) {
}

> +       }
> +
> +       /* try the node itself if none is found */
> +       if (!blcode)
> +               blcode = dt_prop_get_def(np, "ibm,slot-location-code", NULL);
> +
> +       if (!blcode) {
> +               /* still not found, fall back to ibm,loc-code */
> +               p = np->parent;
> +               while (p) {
> +                       blcode = dt_prop_get_def(p, "ibm,loc-code", NULL);
> +                       if (blcode)
> +                               break;
> +
> +                       p = p->parent;
> +               }
> +       }
> +
> +       if (!blcode)
> +               return;

Should this print an error? On IBM systems we should always have a
location code so if we're missing one it's probably a bug.

> +       /* ethernet devices get port codes */
> +       class_code = dt_prop_get_u32(np, "class-code");
> +       class = class_code >> 16;
> +       sub = (class_code >> 8) & 0xff;
> +
> +       if (class == 0x02 && sub == 0x00) {
> +               /* There's usually several spaces at the end of the property.
> +                  Test for, but don't rely on, that being the case */
> +               len = strlen(blcode);
> +               for (pos = 0; pos < len; pos++)
> +                       if (blcode[pos] == ' ') break;
> +               if (pos + 3 < len)
> +                       lcode = strdup(blcode);
> +               else {
> +                       lcode = malloc(pos + 3);
> +                       memcpy(lcode, blcode, len);
> +               }
> +               lcode[pos++] = '-';
> +               lcode[pos++] = 'T';
> +               lcode[pos++] = (char)PCI_FUNC(pd->bdfn) + '1';
> +               lcode[pos++] = '\0';
> +               dt_add_property_string(np, "ibm,loc-code", lcode);
> +               free(lcode);
> +       } else
> +               dt_add_property_string(np, "ibm,loc-code", blcode);

There should be braces around the else block. We follow the Linux
convention where you either have braces around every branch or a chain
of single line if .. else if .. else statements with no braces.

> +}
> diff --git a/platforms/ibm-fsp/firenze.c b/platforms/ibm-fsp/firenze.c
> index 26977450..8fc72e9b 100644
> --- a/platforms/ibm-fsp/firenze.c
> +++ b/platforms/ibm-fsp/firenze.c
> @@ -206,6 +206,7 @@ DECLARE_PLATFORM(firenze) = {
>         .cec_reboot             = ibm_fsp_cec_reboot,
>         .pci_setup_phb          = firenze_pci_setup_phb,
>         .pci_get_slot_info      = firenze_pci_get_slot_info,
> +       .pci_get_loc_code       = firenze_pci_get_loc_code,
>         .pci_probe_complete     = firenze_pci_send_inventory,
>         .nvram_info             = fsp_nvram_info,
>         .nvram_start_read       = fsp_nvram_start_read,
> diff --git a/platforms/ibm-fsp/ibm-fsp.h b/platforms/ibm-fsp/ibm-fsp.h
> index 16af68f8..122bbb41 100644
> --- a/platforms/ibm-fsp/ibm-fsp.h
> +++ b/platforms/ibm-fsp/ibm-fsp.h
> @@ -29,6 +29,8 @@ extern void firenze_pci_setup_phb(struct phb *phb,
>                                   unsigned int index);
>  extern void firenze_pci_get_slot_info(struct phb *phb,
>                                       struct pci_device *pd);
> +extern void firenze_pci_get_loc_code(struct dt_node *np,
> +                                     struct pci_device *pd);
>
>  /* VPD support */
>  void vpd_iohub_load(struct dt_node *hub_node);
> diff --git a/platforms/ibm-fsp/zz.c b/platforms/ibm-fsp/zz.c
> index f4aa85fa..a218b328 100644
> --- a/platforms/ibm-fsp/zz.c
> +++ b/platforms/ibm-fsp/zz.c
> @@ -184,6 +184,7 @@ DECLARE_PLATFORM(zz) = {
>         .cec_reboot             = ibm_fsp_cec_reboot,
>         .pci_setup_phb          = firenze_pci_setup_phb,
>         .pci_get_slot_info      = firenze_pci_get_slot_info,
> +       .pci_get_loc_code       = firenze_pci_get_loc_code,
>         .pci_probe_complete     = firenze_pci_send_inventory,
>         .nvram_info             = fsp_nvram_info,
>         .nvram_start_read       = fsp_nvram_start_read,
> --
> 2.17.1
>
> _______________________________________________
> Skiboot mailing list
> Skiboot@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/skiboot
diff mbox series

Patch

diff --git a/core/pci.c b/core/pci.c
index 8b52fc10..5170d30b 100644
--- a/core/pci.c
+++ b/core/pci.c
@@ -1383,75 +1383,45 @@  void pci_std_swizzle_irq_map(struct dt_node *np,
 	free(map);
 }
 
-static void pci_add_loc_code(struct dt_node *np, struct pci_device *pd)
+static void pci_add_loc_code(struct dt_node *np, struct pci_device *pd __unused)
 {
 	struct dt_node *p = np->parent;
-	const char *blcode = NULL;
-	char *lcode;
-	uint32_t class_code;
-	uint8_t class, sub;
-	uint8_t pos, len;
+	const char *lcode = NULL;
 
 	while (p) {
-		/* if we have a slot label (i.e. openpower) use that */
-		blcode = dt_prop_get_def(p, "ibm,slot-label", NULL);
-		if (blcode)
+		/* prefer slot-label by default */
+		lcode = dt_prop_get_def(p, "ibm,slot-label", NULL);
+		if (lcode)
 			break;
 
 		/* otherwise use the fully qualified location code */
-		blcode = dt_prop_get_def(p, "ibm,slot-location-code", NULL);
-		if (blcode)
+		lcode = dt_prop_get_def(p, "ibm,slot-location-code", NULL);
+		if (lcode)
 			break;
 
 		p = p->parent;
 	}
 
-	if (!blcode)
-		blcode = dt_prop_get_def(np, "ibm,slot-location-code", NULL);
+	/* try the node itself if none is found */
+	if (!lcode)
+		lcode = dt_prop_get_def(np, "ibm,slot-location-code", NULL);
 
-	if (!blcode) {
+	if (!lcode) {
 		/* Fall back to finding a ibm,loc-code */
 		p = np->parent;
 
 		while (p) {
-			blcode = dt_prop_get_def(p, "ibm,loc-code", NULL);
-			if (blcode)
+			lcode = dt_prop_get_def(p, "ibm,loc-code", NULL);
+			if (lcode)
 				break;
 			p = p->parent;
 		}
 	}
 
-	if (!blcode)
+	if (!lcode)
 		return;
 
-	/* ethernet devices get port codes */
-	class_code = dt_prop_get_u32(np, "class-code");
-	class = class_code >> 16;
-	sub = (class_code >> 8) & 0xff;
-
-	/* XXX Don't do that on openpower for now, we will need to sort things
-	 * out later, otherwise the mezzanine slot on Habanero gets weird results
-	 */
-	if (class == 0x02 && sub == 0x00 && !platform.bmc) {
-		/* There's usually several spaces at the end of the property.
-		   Test for, but don't rely on, that being the case */
-		len = strlen(blcode);
-		for (pos = 0; pos < len; pos++)
-			if (blcode[pos] == ' ') break;
-		if (pos + 3 < len)
-			lcode = strdup(blcode);
-		else {
-			lcode = malloc(pos + 3);
-			memcpy(lcode, blcode, len);
-		}
-		lcode[pos++] = '-';
-		lcode[pos++] = 'T';
-		lcode[pos++] = (char)PCI_FUNC(pd->bdfn) + '1';
-		lcode[pos++] = '\0';
-		dt_add_property_string(np, "ibm,loc-code", lcode);
-		free(lcode);
-	} else
-		dt_add_property_string(np, "ibm,loc-code", blcode);
+	dt_add_property_string(np, "ibm,loc-code", lcode);
 }
 
 static void pci_print_summary_line(struct phb *phb, struct pci_device *pd,
@@ -1594,8 +1564,14 @@  static void __noinline pci_add_one_device_node(struct phb *phb,
 		dt_add_property_string(np, "ibm,slot-location-code",
 				       phb->base_loc_code);
 
-	/* Make up location code */
-	pci_add_loc_code(np, pd);
+	/*
+	 * Use platform-specific callback (if there is one) to make up
+	 * location code
+	 */
+	if (platform.pci_get_loc_code)
+		platform.pci_get_loc_code(np, pd);
+	else
+		pci_add_loc_code(np, pd);
 
 	/* XXX FIXME: We don't look for BARs, we only put the config space
 	 * entry in the "reg" property. That's enough for Linux and we might
diff --git a/include/platform.h b/include/platform.h
index 6909a6a4..22b5f6d2 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -185,6 +185,14 @@  struct platform {
 	void		(*pci_get_slot_info)(struct phb *phb,
 					     struct pci_device *pd);
 
+	/*
+	 * Called for each device during pci_add_device_nodes() descend
+	 * to create the device tree, in order to get the correct per-platform
+	 * preference for the ibm,loc-code property
+	 */
+	void		(*pci_get_loc_code)(struct dt_node *np,
+					     struct pci_device *pd);
+
 	/*
 	 * Called after PCI probe is complete and before inventory is
 	 * displayed in console. This can either run platform fixups or
diff --git a/platforms/ibm-fsp/firenze-pci.c b/platforms/ibm-fsp/firenze-pci.c
index 6d5aab1e..bef69052 100644
--- a/platforms/ibm-fsp/firenze-pci.c
+++ b/platforms/ibm-fsp/firenze-pci.c
@@ -972,3 +972,71 @@  void firenze_pci_get_slot_info(struct phb *phb, struct pci_device *pd)
 		firenze_pci_slot_init(slot);
 	}
 }
+
+void firenze_pci_get_loc_code(struct dt_node *np, struct pci_device *pd)
+{
+	struct dt_node *p = np->parent;
+	const char *blcode = NULL;
+	char *lcode;
+	uint32_t class_code;
+	uint8_t class,sub;
+	uint8_t pos, len;
+
+
+	/*
+	 * prefer fully-qualified slot-location-code, walk-up parent tree
+	 * to find one
+	 */
+	while (p) {
+		blcode = dt_prop_get_def(p, "ibm,slot-location-code", NULL);
+		if (blcode)
+			break;
+
+		p = p-> parent;
+	}
+
+	/* try the node itself if none is found */
+	if (!blcode)
+		blcode = dt_prop_get_def(np, "ibm,slot-location-code", NULL);
+
+	if (!blcode) {
+		/* still not found, fall back to ibm,loc-code */
+		p = np->parent;
+		while (p) {
+			blcode = dt_prop_get_def(p, "ibm,loc-code", NULL);
+			if (blcode)
+				break;
+
+			p = p->parent;
+		}
+	}
+
+	if (!blcode)
+		return;
+
+	/* ethernet devices get port codes */
+	class_code = dt_prop_get_u32(np, "class-code");
+	class = class_code >> 16;
+	sub = (class_code >> 8) & 0xff;
+
+	if (class == 0x02 && sub == 0x00) {
+		/* There's usually several spaces at the end of the property.
+		   Test for, but don't rely on, that being the case */
+		len = strlen(blcode);
+		for (pos = 0; pos < len; pos++)
+			if (blcode[pos] == ' ') break;
+		if (pos + 3 < len)
+			lcode = strdup(blcode);
+		else {
+			lcode = malloc(pos + 3);
+			memcpy(lcode, blcode, len);
+		}
+		lcode[pos++] = '-';
+		lcode[pos++] = 'T';
+		lcode[pos++] = (char)PCI_FUNC(pd->bdfn) + '1';
+		lcode[pos++] = '\0';
+		dt_add_property_string(np, "ibm,loc-code", lcode);
+		free(lcode);
+	} else
+		dt_add_property_string(np, "ibm,loc-code", blcode);
+}
diff --git a/platforms/ibm-fsp/firenze.c b/platforms/ibm-fsp/firenze.c
index 26977450..8fc72e9b 100644
--- a/platforms/ibm-fsp/firenze.c
+++ b/platforms/ibm-fsp/firenze.c
@@ -206,6 +206,7 @@  DECLARE_PLATFORM(firenze) = {
 	.cec_reboot		= ibm_fsp_cec_reboot,
 	.pci_setup_phb		= firenze_pci_setup_phb,
 	.pci_get_slot_info	= firenze_pci_get_slot_info,
+	.pci_get_loc_code	= firenze_pci_get_loc_code,
 	.pci_probe_complete	= firenze_pci_send_inventory,
 	.nvram_info		= fsp_nvram_info,
 	.nvram_start_read	= fsp_nvram_start_read,
diff --git a/platforms/ibm-fsp/ibm-fsp.h b/platforms/ibm-fsp/ibm-fsp.h
index 16af68f8..122bbb41 100644
--- a/platforms/ibm-fsp/ibm-fsp.h
+++ b/platforms/ibm-fsp/ibm-fsp.h
@@ -29,6 +29,8 @@  extern void firenze_pci_setup_phb(struct phb *phb,
 				  unsigned int index);
 extern void firenze_pci_get_slot_info(struct phb *phb,
 				      struct pci_device *pd);
+extern void firenze_pci_get_loc_code(struct dt_node *np,
+				      struct pci_device *pd);
 
 /* VPD support */
 void vpd_iohub_load(struct dt_node *hub_node);
diff --git a/platforms/ibm-fsp/zz.c b/platforms/ibm-fsp/zz.c
index f4aa85fa..a218b328 100644
--- a/platforms/ibm-fsp/zz.c
+++ b/platforms/ibm-fsp/zz.c
@@ -184,6 +184,7 @@  DECLARE_PLATFORM(zz) = {
 	.cec_reboot		= ibm_fsp_cec_reboot,
 	.pci_setup_phb		= firenze_pci_setup_phb,
 	.pci_get_slot_info	= firenze_pci_get_slot_info,
+	.pci_get_loc_code	= firenze_pci_get_loc_code,
 	.pci_probe_complete	= firenze_pci_send_inventory,
 	.nvram_info		= fsp_nvram_info,
 	.nvram_start_read	= fsp_nvram_start_read,