linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Make lparcfg.c work when both iseries and pseries are selected
@ 2006-06-28  1:57 Stephen Rothwell
  2006-06-28  4:05 ` Nathan Lynch
  0 siblings, 1 reply; 5+ messages in thread
From: Stephen Rothwell @ 2006-06-28  1:57 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/kernel/lparcfg.c |   69 +++++++++++++++++++----------------------
 1 files changed, 32 insertions(+), 37 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index c02deaa..bcc358d 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -45,11 +45,9 @@ #define MODULE_NAME "lparcfg"
 static struct proc_dir_entry *proc_ppc64_lparcfg;
 #define LPARCFG_BUFF_SIZE 4096
 
-#ifdef CONFIG_PPC_ISERIES
-
 /*
- * For iSeries legacy systems, the PPA purr function is available from the
- * emulated_time_base field in the paca.
+ * Track sum of all purrs across all processors. This is used to further
+ * calculate usage values by different applications
  */
 static unsigned long get_purr(void)
 {
@@ -57,30 +55,30 @@ static unsigned long get_purr(void)
 	int cpu;
 
 	for_each_possible_cpu(cpu) {
-		sum_purr += lppaca[cpu].emulated_time_base;
+		if (firmware_has_feature(FW_FEATURE_ISERIES))
+			sum_purr += lppaca[cpu].emulated_time_base;
+		else {
+			struct cpu_usage *cu;
 
-#ifdef PURR_DEBUG
-		printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n",
-			cpu, lppaca[cpu].emulated_time_base);
-#endif
+			cu = &per_cpu(cpu_usage_array, cpu);
+			sum_purr += cu->current_tb;
+		}
 	}
 	return sum_purr;
 }
 
-#define lparcfg_write NULL
+#ifdef CONFIG_PPC_ISERIES
 
 /*
  * Methods used to fetch LPAR data when running on an iSeries platform.
  */
-static int lparcfg_data(struct seq_file *m, void *v)
+static int iseries_lparcfg_data(struct seq_file *m, void *v)
 {
 	unsigned long pool_id, lp_index;
 	int shared, entitled_capacity, max_entitled_capacity;
 	int processors, max_processors;
 	unsigned long purr = get_purr();
 
-	seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
-
 	shared = (int)(get_lppaca()->shared_proc);
 	seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n",
 		   e2a(xItExtVpdPanel.mfgID[2]),
@@ -213,22 +211,6 @@ static void h_pic(unsigned long *pool_id
 		log_plpar_hcall_return(rc, "H_PIC");
 }
 
-/* Track sum of all purrs across all processors. This is used to further */
-/* calculate usage values by different applications                       */
-
-static unsigned long get_purr(void)
-{
-	unsigned long sum_purr = 0;
-	int cpu;
-	struct cpu_usage *cu;
-
-	for_each_possible_cpu(cpu) {
-		cu = &per_cpu(cpu_usage_array, cpu);
-		sum_purr += cu->current_tb;
-	}
-	return sum_purr;
-}
-
 #define SPLPAR_CHARACTERISTICS_TOKEN 20
 #define SPLPAR_MAXLENGTH 1026*(sizeof(char))
 
@@ -333,7 +315,7 @@ #endif
 	return count;
 }
 
-static int lparcfg_data(struct seq_file *m, void *v)
+static int pseries_lparcfg_data(struct seq_file *m, void *v)
 {
 	int partition_potential_processors;
 	int partition_active_processors;
@@ -354,8 +336,6 @@ static int lparcfg_data(struct seq_file 
 			lp_index = *lp_index_ptr;
 	}
 
-	seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
-
 	seq_printf(m, "serial_number=%s\n", system_id);
 
 	seq_printf(m, "system_type=%s\n", model);
@@ -456,6 +436,21 @@ static int lparcfg_data(struct seq_file 
 	return 0;
 }
 
+#endif				/* CONFIG_PPC_PSERIES */
+
+static int lparcfg_data(struct seq_file *m, void *v)
+{
+	seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
+
+#ifdef CONFIG_PPC_ISERIES
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		return iseries_lparcfg_data(m, v);
+#endif
+#ifdef CONFIG_PPC_PSERIES
+	return pseries_lparcfg_data(m, v);
+#endif
+}
+
 /*
  * Interface for changing system parameters (variable capacity weight
  * and entitled capacity).  Format of input is "param_name=value";
@@ -469,6 +464,8 @@ static int lparcfg_data(struct seq_file 
 static ssize_t lparcfg_write(struct file *file, const char __user * buf,
 			     size_t count, loff_t * off)
 {
+	ssize_t retval = -ENOMEM;
+#ifdef CONFIG_PPC_PSERIES
 	char *kbuf;
 	char *tmp;
 	u64 new_entitled, *new_entitled_ptr = &new_entitled;
@@ -479,8 +476,6 @@ static ssize_t lparcfg_write(struct file
 	unsigned long resource;
 	u8 current_weight;
 
-	ssize_t retval = -ENOMEM;
-
 	kbuf = kmalloc(count, GFP_KERNEL);
 	if (!kbuf)
 		goto out;
@@ -546,11 +541,10 @@ static ssize_t lparcfg_write(struct file
 
 out:
 	kfree(kbuf);
+#endif				/* CONFIG_PPC_PSERIES */
 	return retval;
 }
 
-#endif				/* CONFIG_PPC_PSERIES */
-
 static int lparcfg_open(struct inode *inode, struct file *file)
 {
 	return single_open(file, lparcfg_data, NULL);
@@ -569,7 +563,8 @@ int __init lparcfg_init(void)
 	mode_t mode = S_IRUSR | S_IRGRP | S_IROTH;
 
 	/* Allow writing if we have FW_FEATURE_SPLPAR */
-	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
+	if (firmware_has_feature(FW_FEATURE_SPLPAR) &&
+			!firmware_has_feature(FW_FEATURE_ISERIES)) {
 		lparcfg_fops.write = lparcfg_write;
 		mode |= S_IWUSR;
 	}
-- 
1.4.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] Make lparcfg.c work when both iseries and pseries are selected
  2006-06-28  1:57 [PATCH] Make lparcfg.c work when both iseries and pseries are selected Stephen Rothwell
@ 2006-06-28  4:05 ` Nathan Lynch
  2006-06-28  6:19   ` Stephen Rothwell
  0 siblings, 1 reply; 5+ messages in thread
From: Nathan Lynch @ 2006-06-28  4:05 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppc-dev, paulus

Stephen Rothwell wrote:
>  static ssize_t lparcfg_write(struct file *file, const char __user * buf,
>  			     size_t count, loff_t * off)
>  {
> +	ssize_t retval = -ENOMEM;
> +#ifdef CONFIG_PPC_PSERIES
>  	char *kbuf;
>  	char *tmp;
>  	u64 new_entitled, *new_entitled_ptr = &new_entitled;
> @@ -479,8 +476,6 @@ static ssize_t lparcfg_write(struct file
>  	unsigned long resource;
>  	u8 current_weight;
>  
> -	ssize_t retval = -ENOMEM;
> -
>  	kbuf = kmalloc(count, GFP_KERNEL);
>  	if (!kbuf)
>  		goto out;
> @@ -546,11 +541,10 @@ static ssize_t lparcfg_write(struct file
>  
>  out:
>  	kfree(kbuf);
> +#endif				/* CONFIG_PPC_PSERIES */
>  	return retval;
>  }

Erm... this is kind of gross, and will return -ENOMEM on iSeries when
it should really return -ENOSYS (I think).

Would it be over-engineering to have an lparcfg_ops struct, with
lparcfg_read and lparcfg_write methods (and the latter would be null
on iSeries)?  All the additional #ifdeffery doesn't really improve
the readability of this code IMO.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Make lparcfg.c work when both iseries and pseries are selected
  2006-06-28  4:05 ` Nathan Lynch
@ 2006-06-28  6:19   ` Stephen Rothwell
  2006-06-28  7:29     ` Nathan Lynch
  0 siblings, 1 reply; 5+ messages in thread
From: Stephen Rothwell @ 2006-06-28  6:19 UTC (permalink / raw)
  To: Nathan Lynch; +Cc: linuxppc-dev, paulus

Hi Nathan,

On Tue, 27 Jun 2006 23:05:40 -0500 Nathan Lynch <ntl@pobox.com> wrote:
>
> Stephen Rothwell wrote:
> >  static ssize_t lparcfg_write(struct file *file, const char __user * buf,
> >  			     size_t count, loff_t * off)
> >  {
> > +	ssize_t retval = -ENOMEM;
> > +#ifdef CONFIG_PPC_PSERIES
	.
	.
	.
> > +#endif				/* CONFIG_PPC_PSERIES */
> >  	return retval;
> >  }
> 
> Erm... this is kind of gross, and will return -ENOMEM on iSeries when
> it should really return -ENOSYS (I think).

lparcfg_write will never be called on iSeries.  The function just needs to
exist to satisfy a conditional reference further down.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Make lparcfg.c work when both iseries and pseries are selected
  2006-06-28  6:19   ` Stephen Rothwell
@ 2006-06-28  7:29     ` Nathan Lynch
  2006-06-29  5:07       ` Stephen Rothwell
  0 siblings, 1 reply; 5+ messages in thread
From: Nathan Lynch @ 2006-06-28  7:29 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: linuxppc-dev, paulus

Stephen Rothwell wrote:
> Hi Nathan,
> 
> On Tue, 27 Jun 2006 23:05:40 -0500 Nathan Lynch <ntl@pobox.com> wrote:
> >
> > Stephen Rothwell wrote:
> > >  static ssize_t lparcfg_write(struct file *file, const char __user * buf,
> > >  			     size_t count, loff_t * off)
> > >  {
> > > +	ssize_t retval = -ENOMEM;
> > > +#ifdef CONFIG_PPC_PSERIES
> 	.
> 	.
> 	.
> > > +#endif				/* CONFIG_PPC_PSERIES */
> > >  	return retval;
> > >  }
> > 
> > Erm... this is kind of gross, and will return -ENOMEM on iSeries when
> > it should really return -ENOSYS (I think).
> 
> lparcfg_write will never be called on iSeries.  The function just needs to
> exist to satisfy a conditional reference further down.

Okay.  Well, my earlier comment regarding readability still stands,
and I think is bolstered somewhat by this explanation ;)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] Make lparcfg.c work when both iseries and pseries are selected
  2006-06-28  7:29     ` Nathan Lynch
@ 2006-06-29  5:07       ` Stephen Rothwell
  0 siblings, 0 replies; 5+ messages in thread
From: Stephen Rothwell @ 2006-06-29  5:07 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This also consolidates the initial bits of lparcfg_data() and adds the
partition number to the iSeries flattened device tree.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/kernel/lparcfg.c       |  147 ++++++++++++++++++-----------------
 arch/powerpc/platforms/iseries/dt.c |    2 
 2 files changed, 78 insertions(+), 71 deletions(-)

Built and run on iSeries, built on pSeries.

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index c02deaa..73edc3c 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -45,11 +45,9 @@ #define MODULE_NAME "lparcfg"
 static struct proc_dir_entry *proc_ppc64_lparcfg;
 #define LPARCFG_BUFF_SIZE 4096
 
-#ifdef CONFIG_PPC_ISERIES
-
 /*
- * For iSeries legacy systems, the PPA purr function is available from the
- * emulated_time_base field in the paca.
+ * Track sum of all purrs across all processors. This is used to further
+ * calculate usage values by different applications
  */
 static unsigned long get_purr(void)
 {
@@ -57,48 +55,31 @@ static unsigned long get_purr(void)
 	int cpu;
 
 	for_each_possible_cpu(cpu) {
-		sum_purr += lppaca[cpu].emulated_time_base;
+		if (firmware_has_feature(FW_FEATURE_ISERIES))
+			sum_purr += lppaca[cpu].emulated_time_base;
+		else {
+			struct cpu_usage *cu;
 
-#ifdef PURR_DEBUG
-		printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n",
-			cpu, lppaca[cpu].emulated_time_base);
-#endif
+			cu = &per_cpu(cpu_usage_array, cpu);
+			sum_purr += cu->current_tb;
+		}
 	}
 	return sum_purr;
 }
 
-#define lparcfg_write NULL
+#ifdef CONFIG_PPC_ISERIES
 
 /*
  * Methods used to fetch LPAR data when running on an iSeries platform.
  */
-static int lparcfg_data(struct seq_file *m, void *v)
+static int iseries_lparcfg_data(struct seq_file *m, void *v)
 {
-	unsigned long pool_id, lp_index;
+	unsigned long pool_id;
 	int shared, entitled_capacity, max_entitled_capacity;
 	int processors, max_processors;
 	unsigned long purr = get_purr();
 
-	seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
-
 	shared = (int)(get_lppaca()->shared_proc);
-	seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n",
-		   e2a(xItExtVpdPanel.mfgID[2]),
-		   e2a(xItExtVpdPanel.mfgID[3]),
-		   e2a(xItExtVpdPanel.systemSerial[1]),
-		   e2a(xItExtVpdPanel.systemSerial[2]),
-		   e2a(xItExtVpdPanel.systemSerial[3]),
-		   e2a(xItExtVpdPanel.systemSerial[4]),
-		   e2a(xItExtVpdPanel.systemSerial[5]));
-
-	seq_printf(m, "system_type=%c%c%c%c\n",
-		   e2a(xItExtVpdPanel.machineType[0]),
-		   e2a(xItExtVpdPanel.machineType[1]),
-		   e2a(xItExtVpdPanel.machineType[2]),
-		   e2a(xItExtVpdPanel.machineType[3]));
-
-	lp_index = HvLpConfig_getLpIndex();
-	seq_printf(m, "partition_id=%d\n", (int)lp_index);
 
 	seq_printf(m, "system_active_processors=%d\n",
 		   (int)HvLpConfig_getSystemPhysicalProcessors());
@@ -137,6 +118,14 @@ static int lparcfg_data(struct seq_file 
 
 	return 0;
 }
+
+#else				/* CONFIG_PPC_ISERIES */
+
+static int iseries_lparcfg_data(struct seq_file *m, void *v)
+{
+	return 0;
+}
+
 #endif				/* CONFIG_PPC_ISERIES */
 
 #ifdef CONFIG_PPC_PSERIES
@@ -213,22 +202,6 @@ static void h_pic(unsigned long *pool_id
 		log_plpar_hcall_return(rc, "H_PIC");
 }
 
-/* Track sum of all purrs across all processors. This is used to further */
-/* calculate usage values by different applications                       */
-
-static unsigned long get_purr(void)
-{
-	unsigned long sum_purr = 0;
-	int cpu;
-	struct cpu_usage *cu;
-
-	for_each_possible_cpu(cpu) {
-		cu = &per_cpu(cpu_usage_array, cpu);
-		sum_purr += cu->current_tb;
-	}
-	return sum_purr;
-}
-
 #define SPLPAR_CHARACTERISTICS_TOKEN 20
 #define SPLPAR_MAXLENGTH 1026*(sizeof(char))
 
@@ -333,35 +306,13 @@ #endif
 	return count;
 }
 
-static int lparcfg_data(struct seq_file *m, void *v)
+static int pseries_lparcfg_data(struct seq_file *m, void *v)
 {
 	int partition_potential_processors;
 	int partition_active_processors;
-	struct device_node *rootdn;
-	const char *model = "";
-	const char *system_id = "";
-	unsigned int *lp_index_ptr, lp_index = 0;
 	struct device_node *rtas_node;
 	int *lrdrp = NULL;
 
-	rootdn = find_path_device("/");
-	if (rootdn) {
-		model = get_property(rootdn, "model", NULL);
-		system_id = get_property(rootdn, "system-id", NULL);
-		lp_index_ptr = (unsigned int *)
-		    get_property(rootdn, "ibm,partition-no", NULL);
-		if (lp_index_ptr)
-			lp_index = *lp_index_ptr;
-	}
-
-	seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
-
-	seq_printf(m, "serial_number=%s\n", system_id);
-
-	seq_printf(m, "system_type=%s\n", model);
-
-	seq_printf(m, "partition_id=%d\n", (int)lp_index);
-
 	rtas_node = find_path_device("/rtas");
 	if (rtas_node)
 		lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity",
@@ -549,8 +500,61 @@ out:
 	return retval;
 }
 
+#else				/* CONFIG_PPC_PSERIES */
+
+static int pseries_lparcfg_data(struct seq_file *m, void *v)
+{
+	return 0;
+}
+
+static ssize_t lparcfg_write(struct file *file, const char __user * buf,
+			     size_t count, loff_t * off)
+{
+	return count;
+}
+
 #endif				/* CONFIG_PPC_PSERIES */
 
+static int lparcfg_data(struct seq_file *m, void *v)
+{
+	struct device_node *rootdn;
+	const char *model = "";
+	const char *system_id = "";
+	const char *tmp;
+	unsigned int *lp_index_ptr, lp_index = 0;
+
+	seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
+
+	rootdn = find_path_device("/");
+	if (rootdn) {
+		tmp = get_property(rootdn, "model", NULL);
+		if (tmp) {
+			model = tmp;
+			/* Skip "IBM," - see platforms/iseries/dt.c */
+			if (firmware_has_feature(FW_FEATURE_ISERIES))
+				model += 4;
+		}
+		tmp = get_property(rootdn, "system-id", NULL);
+		if (tmp) {
+			system_id = tmp;
+			/* Skip "IBM," - see platforms/iseries/dt.c */
+			if (firmware_has_feature(FW_FEATURE_ISERIES))
+				system_id += 4;
+		}
+		lp_index_ptr = (unsigned int *)
+			get_property(rootdn, "ibm,partition-no", NULL);
+		if (lp_index_ptr)
+			lp_index = *lp_index_ptr;
+	}
+	seq_printf(m, "serial_number=%s\n", system_id);
+	seq_printf(m, "system_type=%s\n", model);
+	seq_printf(m, "partition_id=%d\n", (int)lp_index);
+
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		return iseries_lparcfg_data(m, v);
+	return pseries_lparcfg_data(m, v);
+}
+
 static int lparcfg_open(struct inode *inode, struct file *file)
 {
 	return single_open(file, lparcfg_data, NULL);
@@ -569,7 +573,8 @@ int __init lparcfg_init(void)
 	mode_t mode = S_IRUSR | S_IRGRP | S_IROTH;
 
 	/* Allow writing if we have FW_FEATURE_SPLPAR */
-	if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
+	if (firmware_has_feature(FW_FEATURE_SPLPAR) &&
+			!firmware_has_feature(FW_FEATURE_ISERIES)) {
 		lparcfg_fops.write = lparcfg_write;
 		mode |= S_IWUSR;
 	}
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index d3444aa..d194140 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -252,6 +252,7 @@ static void __init dt_model(struct iseri
 {
 	char buf[16] = "IBM,";
 
+	/* N.B. lparcfg.c knows about the "IBM," prefixes ... */
 	/* "IBM," + mfgId[2:3] + systemSerial[1:5] */
 	strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2);
 	strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5);
@@ -264,6 +265,7 @@ static void __init dt_model(struct iseri
 	dt_prop_str(dt, "model", buf);
 
 	dt_prop_str(dt, "compatible", "IBM,iSeries");
+	dt_prop_u32(dt, "ibm,partition-no", HvLpConfig_getLpIndex());
 }
 
 static void __init dt_do_vdevice(struct iseries_flat_dt *dt,
-- 
1.4.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2006-06-29  5:08 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-06-28  1:57 [PATCH] Make lparcfg.c work when both iseries and pseries are selected Stephen Rothwell
2006-06-28  4:05 ` Nathan Lynch
2006-06-28  6:19   ` Stephen Rothwell
2006-06-28  7:29     ` Nathan Lynch
2006-06-29  5:07       ` Stephen Rothwell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).