[PATCH 1/3] Kernel DLPAR infrastructure

2009-11-24 Thread Nathan Fontenot

This patch provides the kernel DLPAR infrastructure in a new filed named
dlpar.c.  The functionality provided is for acquiring and releasing a resource
from firmware and the parsing of information returned from the
ibm,configure-connector rtas call.  Additionally this exports the pSeries
reconfiguration notifier chain so that it can be invoked when device tree 
updates are made.


Signed-off-by: Nathan Fontenot nf...@austin.ibm.com 
---


---
arch/powerpc/include/asm/pSeries_reconfig.h |1 
arch/powerpc/platforms/pseries/Makefile |2 
arch/powerpc/platforms/pseries/dlpar.c  |  324 
arch/powerpc/platforms/pseries/reconfig.c   |2 
4 files changed, 327 insertions(+), 2 deletions(-)


Index: powerpc/arch/powerpc/platforms/pseries/dlpar.c
===
--- /dev/null   1970-01-01 00:00:00.0 +
+++ powerpc/arch/powerpc/platforms/pseries/dlpar.c  2009-11-24 
23:31:28.0 -0600
@@ -0,0 +1,324 @@
+/*
+ * Support for dynamic reconfiguration for PCI, Memory, and CPU
+ * Hotplug and Dynamic Logical Partitioning on RPA platforms.
+ *
+ * Copyright (C) 2009 Nathan Fontenot
+ * Copyright (C) 2009 IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ */
+
+#include linux/kernel.h
+#include linux/kref.h
+#include linux/notifier.h
+#include linux/proc_fs.h
+#include linux/spinlock.h
+#include linux/cpu.h
+
+#include asm/prom.h
+#include asm/machdep.h
+#include asm/uaccess.h
+#include asm/rtas.h
+#include asm/pSeries_reconfig.h
+
+struct cc_workarea {
+   u32 drc_index;
+   u32 zero;
+   u32 name_offset;
+   u32 prop_length;
+   u32 prop_offset;
+};
+
+static void dlpar_free_cc_property(struct property *prop)
+{
+   kfree(prop-name);
+   kfree(prop-value);
+   kfree(prop);
+}
+
+static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa)
+{
+   struct property *prop;
+   char *name;
+   char *value;
+
+   prop = kzalloc(sizeof(*prop), GFP_KERNEL);
+   if (!prop)
+   return NULL;
+
+   name = (char *)ccwa + ccwa-name_offset;
+   prop-name = kstrdup(name, GFP_KERNEL);
+
+   prop-length = ccwa-prop_length;
+   value = (char *)ccwa + ccwa-prop_offset;
+   prop-value = kzalloc(prop-length, GFP_KERNEL);
+   if (!prop-value) {
+   dlpar_free_cc_property(prop);
+   return NULL;
+   }
+
+   memcpy(prop-value, value, prop-length);
+   return prop;
+}
+
+static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa)
+{
+   struct device_node *dn;
+   char *name;
+
+   dn = kzalloc(sizeof(*dn), GFP_KERNEL);
+   if (!dn)
+   return NULL;
+
+   name = (char *)ccwa + ccwa-name_offset;
+   dn-full_name = kstrdup(name, GFP_KERNEL);
+
+   return dn;
+}
+
+static void dlpar_free_one_cc_node(struct device_node *dn)
+{
+   struct property *prop;
+
+   while (dn-properties) {
+   prop = dn-properties;
+   dn-properties = prop-next;
+   dlpar_free_cc_property(prop);
+   }
+
+   kfree(dn-full_name);
+   kfree(dn);
+}
+
+static void dlpar_free_cc_nodes(struct device_node *dn)
+{
+   if (dn-child)
+   dlpar_free_cc_nodes(dn-child);
+
+   if (dn-sibling)
+   dlpar_free_cc_nodes(dn-sibling);
+
+   dlpar_free_one_cc_node(dn);
+}
+
+#define NEXT_SIBLING1
+#define NEXT_CHILD  2
+#define NEXT_PROPERTY   3
+#define PREV_PARENT 4
+#define MORE_MEMORY 5
+#define CALL_AGAIN -2
+#define ERR_CFG_USE -9003
+
+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);
+  

Re: [PATCH 1/3] Kernel DLPAR infrastructure

2009-11-24 Thread Michael Neuling


In message 4b0c8ce3.4010...@austin.ibm.com you wrote:
 This patch provides the kernel DLPAR infrastructure in a new filed named
 dlpar.c.  The functionality provided is for acquiring and releasing a resourc
e
 from firmware and the parsing of information returned from the
 ibm,configure-connector rtas call.  Additionally this exports the pSeries
 reconfiguration notifier chain so that it can be invoked when device tree 
 updates are made.
 
 Signed-off-by: Nathan Fontenot nf...@austin.ibm.com 

These look like they got white space munged somewhere...

Mikey

 ---
 
 ---
  arch/powerpc/include/asm/pSeries_reconfig.h |1 
  arch/powerpc/platforms/pseries/Makefile |2 
  arch/powerpc/platforms/pseries/dlpar.c  |  324 +
+++
  arch/powerpc/platforms/pseries/reconfig.c   |2 
  4 files changed, 327 insertions(+), 2 deletions(-)
 
 Index: powerpc/arch/powerpc/platforms/pseries/dlpar.c
 ===
 --- /dev/null 1970-01-01 00:00:00.0 +
 +++ powerpc/arch/powerpc/platforms/pseries/dlpar.c2009-11-24 23:31:28.000
00 -0600
 @@ -0,0 +1,324 @@
 +/*
 + * Support for dynamic reconfiguration for PCI, Memory, and CPU
 + * Hotplug and Dynamic Logical Partitioning on RPA platforms.
 + *
 + * Copyright (C) 2009 Nathan Fontenot
 + * Copyright (C) 2009 IBM Corporation
 + *
 + * This program is free software; you can redistribute it and/or
 + * modify it under the terms of the GNU General Public License version
 + * 2 as published by the Free Software Foundation.
 + */
 +
 +#include linux/kernel.h
 +#include linux/kref.h
 +#include linux/notifier.h
 +#include linux/proc_fs.h
 +#include linux/spinlock.h
 +#include linux/cpu.h
 +
 +#include asm/prom.h
 +#include asm/machdep.h
 +#include asm/uaccess.h
 +#include asm/rtas.h
 +#include asm/pSeries_reconfig.h
 +
 +struct cc_workarea {
 + u32 drc_index;
 + u32 zero;
 + u32 name_offset;
 + u32 prop_length;
 + u32 prop_offset;
 +};
 +
 +static void dlpar_free_cc_property(struct property *prop)
 +{
 + kfree(prop-name);
 + kfree(prop-value);
 + kfree(prop);
 +}
 +
 +static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa)
 +{
 + struct property *prop;
 + char *name;
 + char *value;
 +
 + prop = kzalloc(sizeof(*prop), GFP_KERNEL);
 + if (!prop)
 + return NULL;
 +
 + name = (char *)ccwa + ccwa-name_offset;
 + prop-name = kstrdup(name, GFP_KERNEL);
 +
 + prop-length = ccwa-prop_length;
 + value = (char *)ccwa + ccwa-prop_offset;
 + prop-value = kzalloc(prop-length, GFP_KERNEL);
 + if (!prop-value) {
 + dlpar_free_cc_property(prop);
 + return NULL;
 + }
 +
 + memcpy(prop-value, value, prop-length);
 + return prop;
 +}
 +
 +static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa)
 +{
 + struct device_node *dn;
 + char *name;
 +
 + dn = kzalloc(sizeof(*dn), GFP_KERNEL);
 + if (!dn)
 + return NULL;
 +
 + name = (char *)ccwa + ccwa-name_offset;
 + dn-full_name = kstrdup(name, GFP_KERNEL);
 +
 + return dn;
 +}
 +
 +static void dlpar_free_one_cc_node(struct device_node *dn)
 +{
 + struct property *prop;
 +
 + while (dn-properties) {
 + prop = dn-properties;
 + dn-properties = prop-next;
 + dlpar_free_cc_property(prop);
 + }
 +
 + kfree(dn-full_name);
 + kfree(dn);
 +}
 +
 +static void dlpar_free_cc_nodes(struct device_node *dn)
 +{
 + if (dn-child)
 + dlpar_free_cc_nodes(dn-child);
 +
 + if (dn-sibling)
 + dlpar_free_cc_nodes(dn-sibling);
 +
 + dlpar_free_one_cc_node(dn);
 +}
 +
 +#define NEXT_SIBLING1
 +#define NEXT_CHILD  2
 +#define NEXT_PROPERTY   3
 +#define PREV_PARENT 4
 +#define MORE_MEMORY 5
 +#define CALL_AGAIN   -2
 +#define ERR_CFG_USE -9003
 +
 +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;
 + 

Re: [PATCH 1/3] Kernel DLPAR infrastructure

2009-11-24 Thread Michael Neuling


In message 31581.1259115...@neuling.org you wrote:
 
 
 In message 4b0c8ce3.4010...@austin.ibm.com you wrote:
  This patch provides the kernel DLPAR infrastructure in a new filed named
  dlpar.c.  The functionality provided is for acquiring and releasing a resou
rc
 e
  from firmware and the parsing of information returned from the
  ibm,configure-connector rtas call.  Additionally this exports the pSeries
  reconfiguration notifier chain so that it can be invoked when device tree 
  updates are made.
  
  Signed-off-by: Nathan Fontenot nf...@austin.ibm.com 
 
 These look like they got white space munged somewhere...

Gah, sorry, they are fine

Mikey
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 1/3] Kernel DLPAR infrastructure

2009-11-24 Thread Paul Mackerras
Nathan Fontenot writes:

 This patch provides the kernel DLPAR infrastructure in a new filed named
 dlpar.c.  The functionality provided is for acquiring and releasing a resource
 from firmware and the parsing of information returned from the
 ibm,configure-connector rtas call.  Additionally this exports the pSeries
 reconfiguration notifier chain so that it can be invoked when device tree 
 updates are made.

Mostly looks great.

 +static struct device_node *derive_parent(const char *path)
 +{
 + struct device_node *parent;
 + char parent_path[128];
 + int parent_path_len;
 +
 + parent_path_len = strrchr(path, '/') - path + 1;
 + strlcpy(parent_path, path, parent_path_len);

This looks a bit fragile if path could possibly not contain any '/' or
if the '/' is more than 128 characters from the start of path.  Please
fix this to check if strrchr returns NULL and to cope in some
reasonable fashion if the path happens to be very long.

 +#ifdef CONFIG_PROC_DEVICETREE
 + ent = proc_mkdir(strrchr(dn-full_name, '/') + 1, dn-parent-pde);
 + if (ent)
 + proc_device_tree_add_node(dn, ent);

Also assumes that dn-full_name contains a '/'.  If for some reason it
couldn't possibly not contain a '/', put in a comment explaining that.

Thanks,
Paul.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev