All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/15] ps3: Support more than the OtherOS lpar
@ 2011-08-01 20:02 Andre Heider
  2011-08-01 20:02 ` [PATCH 01/15] [PS3] Add udbg driver using the PS3 gelic Ethernet device Andre Heider
                   ` (17 more replies)
  0 siblings, 18 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:02 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

This series addresses various issues and extends support when running
in lpars like GameOS. Included are some patches from Hector Martin, which
I found useful.

The ps3disk driver now creates multiple block devices instead of just one.
On the GameOS lpar we have access to all regions, and - depending on the
customizable layout - the linux partitions are likely not on the first.
The device names look similar the bsd slices, a bit unusual, but the best
I could think of. Better suggestions?

There're 2 new drivers: ps3vflash and ps3nflash. These are just modified
copies of the ps3disk driver:
  diff -u drivers/block/ps3disk.c drivers/block/ps3vflash.c
and "worse":
  diff -u drivers/block/ps3vflash.c drivers/block/ps3nflash.c
I'm not sure what the desired way to handle these similarities are. Should
that be merged to avoid code duplication? If so, how?

Patches are based on 2.6.39 since master doesn't boot with smp on my
console.  I wasn't able to pinpoint the cause so far (not that I tried
too hard). If anything get accepted I'll rebase :)

All patches were tested with the AsbestOS bootloader from Hector
Martin (http://git.marcansoft.com/?p=asbestos.git) on a PS3 slim.

Note: There are various patches floating around from anonymous
developers. None of those are signed-off and had various issues.
While some of those do contain simliar changes, I redid everything
in this series from scratch (except the patches from Hector).

Please let me know If there're any issues!

Thanks,
Andre

Andre Heider (12):
  ps3: MEMORY_HOTPLUG is not a requirement anymore
  ps3: Detect the current lpar environment
  ps3flash: Fix region align checks
  ps3flash: Refuse to work in lpars other than OtherOS
  ps3: Only prealloc the flash bounce buffer for the OtherOS lpar
  ps3: Limit the number of regions per storage device
  ps3stor_lib: Add support for multiple regions
  ps3disk: Provide a gendisk per accessible region
  ps3stor_lib: Add support for storage access flags
  ps3disk: Use region flags
  ps3: Add a vflash driver for lpars other than OtherOS
  ps3: Add a NOR FLASH driver for PS3s without NAND

Hector Martin (3):
  [PS3] Add udbg driver using the PS3 gelic Ethernet device
  [PS3] Get lv1 high memory region from devtree
  [PS3] Add region 1 memory early

 arch/powerpc/Kconfig.debug               |    8 +
 arch/powerpc/include/asm/ps3.h           |    9 +
 arch/powerpc/include/asm/ps3stor.h       |   11 +-
 arch/powerpc/include/asm/udbg.h          |    1 +
 arch/powerpc/kernel/udbg.c               |    2 +
 arch/powerpc/platforms/ps3/Kconfig       |   43 +++-
 arch/powerpc/platforms/ps3/Makefile      |    1 +
 arch/powerpc/platforms/ps3/device-init.c |   16 +
 arch/powerpc/platforms/ps3/gelic_udbg.c  |  272 ++++++++++++++++
 arch/powerpc/platforms/ps3/mm.c          |   91 ++++---
 arch/powerpc/platforms/ps3/platform.h    |    5 +
 arch/powerpc/platforms/ps3/repository.c  |   19 ++
 arch/powerpc/platforms/ps3/setup.c       |   27 ++-
 arch/powerpc/platforms/ps3/system-bus.c  |    2 +
 drivers/block/Makefile                   |    2 +
 drivers/block/ps3disk.c                  |  136 ++++++---
 drivers/block/ps3nflash.c                |  473 +++++++++++++++++++++++++++
 drivers/block/ps3vflash.c                |  508 ++++++++++++++++++++++++++++++
 drivers/char/ps3flash.c                  |   56 +++--
 drivers/net/ps3_gelic_net.c              |    3 +
 drivers/net/ps3_gelic_net.h              |    6 +
 drivers/ps3/ps3stor_lib.c                |   30 +-
 drivers/scsi/ps3rom.c                    |   11 +-
 23 files changed, 1617 insertions(+), 115 deletions(-)
 create mode 100644 arch/powerpc/platforms/ps3/gelic_udbg.c
 create mode 100644 drivers/block/ps3nflash.c
 create mode 100644 drivers/block/ps3vflash.c

-- 
1.7.5.4

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

* [PATCH 01/15] [PS3] Add udbg driver using the PS3 gelic Ethernet device
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
@ 2011-08-01 20:02 ` Andre Heider
  2011-08-03 22:32   ` Geoff Levand
  2011-08-01 20:02 ` [PATCH 02/15] [PS3] Get lv1 high memory region from devtree Andre Heider
                   ` (16 subsequent siblings)
  17 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:02 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

From: Hector Martin <hector@marcansoft.com>

Signed-off-by: Hector Martin <hector@marcansoft.com>
[a.heider: Various cleanups to make checkpatch.pl happy]
Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/Kconfig.debug              |    8 +
 arch/powerpc/include/asm/udbg.h         |    1 +
 arch/powerpc/kernel/udbg.c              |    2 +
 arch/powerpc/platforms/ps3/Kconfig      |   12 ++
 arch/powerpc/platforms/ps3/Makefile     |    1 +
 arch/powerpc/platforms/ps3/gelic_udbg.c |  272 +++++++++++++++++++++++++++++++
 drivers/net/ps3_gelic_net.c             |    3 +
 drivers/net/ps3_gelic_net.h             |    6 +
 8 files changed, 305 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/platforms/ps3/gelic_udbg.c

diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 2d38a50..47edab6 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -267,6 +267,14 @@ config PPC_EARLY_DEBUG_USBGECKO
 	  Select this to enable early debugging for Nintendo GameCube/Wii
 	  consoles via an external USB Gecko adapter.
 
+config PPC_EARLY_DEBUG_PS3GELIC
+	bool "Early debugging through the PS3 Ethernet port"
+	depends on PPC_PS3
+	select PS3GELIC_UDBG
+	help
+	  Select this to enable early debugging for the PlayStation3 via
+	  UDP broadcasts sent out through the Ethernet port.
+
 endchoice
 
 config PPC_EARLY_DEBUG_44x_PHYSLOW
diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h
index 11ae699..58f0ab9 100644
--- a/arch/powerpc/include/asm/udbg.h
+++ b/arch/powerpc/include/asm/udbg.h
@@ -52,6 +52,7 @@ extern void __init udbg_init_44x_as1(void);
 extern void __init udbg_init_40x_realmode(void);
 extern void __init udbg_init_cpm(void);
 extern void __init udbg_init_usbgecko(void);
+extern void __init udbg_init_ps3gelic(void);
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_UDBG_H */
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index e39cad8..9ea9897 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -62,6 +62,8 @@ void __init udbg_early_init(void)
 	udbg_init_cpm();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_USBGECKO)
 	udbg_init_usbgecko();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
+	udbg_init_ps3gelic();
 #endif
 
 #ifdef CONFIG_PPC_EARLY_DEBUG
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index dfe316b..476d9d9 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -148,4 +148,16 @@ config PS3_LPM
 	  profiling support of the Cell processor with programs like
 	  oprofile and perfmon2, then say Y or M, otherwise say N.
 
+config PS3GELIC_UDBG
+	bool "PS3 udbg output via UDP broadcasts on Ethernet"
+	depends on PPC_PS3
+	help
+	  Enables udbg early debugging output by sending broadcast UDP
+	  via the Ethernet port (UDP port number 18194).
+
+	  This driver uses a trivial implementation and is independent
+	  from the main network driver.
+
+	  If in doubt, say N here.
+
 endmenu
diff --git a/arch/powerpc/platforms/ps3/Makefile b/arch/powerpc/platforms/ps3/Makefile
index ac1bdf8..02b9e63 100644
--- a/arch/powerpc/platforms/ps3/Makefile
+++ b/arch/powerpc/platforms/ps3/Makefile
@@ -2,6 +2,7 @@ obj-y += setup.o mm.o time.o hvcall.o htab.o repository.o
 obj-y += interrupt.o exports.o os-area.o
 obj-y += system-bus.o
 
+obj-$(CONFIG_PS3GELIC_UDBG) += gelic_udbg.o
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_SPU_BASE) += spu.o
 obj-y += device-init.o
diff --git a/arch/powerpc/platforms/ps3/gelic_udbg.c b/arch/powerpc/platforms/ps3/gelic_udbg.c
new file mode 100644
index 0000000..9b383bd
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/gelic_udbg.c
@@ -0,0 +1,272 @@
+/*
+ * arch/powerpc/platforms/ps3/gelic_udbg.c
+ *
+ * udbg debug output routine via GELIC UDP broadcasts
+ * Copyright (C) 2010 Hector Martin <hector@marcansoft.com>
+ * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ */
+
+#include <asm/io.h>
+#include <asm/udbg.h>
+#include <asm/lv1call.h>
+
+#define GELIC_BUS_ID 1
+#define GELIC_DEVICE_ID 0
+#define GELIC_DEBUG_PORT 18194
+#define GELIC_MAX_MESSAGE_SIZE 1000
+
+#define GELIC_LV1_GET_MAC_ADDRESS 1
+#define GELIC_LV1_GET_VLAN_ID 4
+#define GELIC_LV1_VLAN_TX_ETHERNET_0 2
+
+#define GELIC_DESCR_DMA_STAT_MASK 0xf0000000
+#define GELIC_DESCR_DMA_CARDOWNED 0xa0000000
+
+#define GELIC_DESCR_TX_DMA_IKE 0x00080000
+#define GELIC_DESCR_TX_DMA_NO_CHKSUM 0x00000000
+#define GELIC_DESCR_TX_DMA_FRAME_TAIL 0x00040000
+
+#define GELIC_DESCR_DMA_CMD_NO_CHKSUM (GELIC_DESCR_DMA_CARDOWNED | \
+				       GELIC_DESCR_TX_DMA_IKE | \
+				       GELIC_DESCR_TX_DMA_NO_CHKSUM)
+
+static u64 bus_addr;
+
+struct gelic_descr {
+	/* as defined by the hardware */
+	u32 buf_addr;
+	u32 buf_size;
+	u32 next_descr_addr;
+	u32 dmac_cmd_status;
+	u32 result_size;
+	u32 valid_size;	/* all zeroes for tx */
+	u32 data_status;
+	u32 data_error;	/* all zeroes for tx */
+} __attribute__((aligned(32)));
+
+struct debug_block {
+	struct gelic_descr descr;
+	u8 pkt[1520];
+} __packed;
+
+struct ethhdr {
+	u8 dest[6];
+	u8 src[6];
+	u16 type;
+} __packed;
+
+struct vlantag {
+	u16 vlan;
+	u16 subtype;
+} __packed;
+
+struct iphdr {
+	u8 ver_len;
+	u8 dscp_ecn;
+	u16 total_length;
+	u16 ident;
+	u16 frag_off_flags;
+	u8 ttl;
+	u8 proto;
+	u16 checksum;
+	u32 src;
+	u32 dest;
+} __packed;
+
+struct udphdr {
+	u16 src;
+	u16 dest;
+	u16 len;
+	u16 checksum;
+} __packed;
+
+static __iomem struct ethhdr *h_eth;
+static __iomem struct vlantag *h_vlan;
+static __iomem struct iphdr *h_ip;
+static __iomem struct udphdr *h_udp;
+
+static __iomem char *pmsg;
+static __iomem char *pmsgc;
+
+static __iomem struct debug_block dbg __attribute__((aligned(32)));
+
+static int header_size;
+
+static void map_dma_mem(int bus_id, int dev_id, void *start, size_t len,
+			u64 *real_bus_addr)
+{
+	s64 result;
+	u64 real_addr = ((u64)start) & 0x0fffffffffffffffUL;
+	u64 real_end = real_addr + len;
+	u64 map_start = real_addr & ~0xfff;
+	u64 map_end = (real_end + 0xfff) & ~0xfff;
+	u64 bus_addr = 0;
+
+	u64 flags = 0xf800000000000000UL;
+
+	result = lv1_allocate_device_dma_region(bus_id, dev_id,
+						map_end - map_start, 12, 0,
+						&bus_addr);
+	if (result)
+		lv1_panic(0);
+
+	result = lv1_map_device_dma_region(bus_id, dev_id, map_start,
+					   bus_addr, map_end - map_start,
+					   flags);
+	if (result)
+		lv1_panic(0);
+
+	*real_bus_addr = bus_addr + real_addr - map_start;
+}
+
+static int unmap_dma_mem(int bus_id, int dev_id, u64 bus_addr, size_t len)
+{
+	s64 result;
+	u64 real_bus_addr;
+
+	real_bus_addr = bus_addr & ~0xfff;
+	len += bus_addr - real_bus_addr;
+	len = (len + 0xfff) & ~0xfff;
+
+	result = lv1_unmap_device_dma_region(bus_id, dev_id, real_bus_addr,
+					     len);
+	if (result)
+		return result;
+
+	return lv1_free_device_dma_region(bus_id, dev_id, real_bus_addr);
+}
+
+static void gelic_debug_init(void)
+{
+	s64 result;
+	u64 v2;
+	u64 mac;
+	u64 vlan_id;
+
+	result = lv1_open_device(GELIC_BUS_ID, GELIC_DEVICE_ID, 0);
+	if (result)
+		lv1_panic(0);
+
+	map_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID, &dbg, sizeof(dbg),
+		    &bus_addr);
+
+	memset(&dbg, 0, sizeof(dbg));
+
+	dbg.descr.buf_addr = bus_addr + offsetof(struct debug_block, pkt);
+
+	wmb();
+
+	result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
+				 GELIC_LV1_GET_MAC_ADDRESS, 0, 0, 0,
+				 &mac, &v2);
+	if (result)
+		lv1_panic(0);
+
+	mac <<= 16;
+
+	h_eth = (struct ethhdr *)dbg.pkt;
+
+	memset(&h_eth->dest, 0xff, 6);
+	memcpy(&h_eth->src, &mac, 6);
+
+	header_size = sizeof(struct ethhdr);
+
+	result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
+				 GELIC_LV1_GET_VLAN_ID,
+				 GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0,
+				 &vlan_id, &v2);
+	if (result == 0) {
+		h_eth->type = 0x8100;
+
+		header_size += sizeof(struct vlantag);
+		h_vlan = (struct vlantag *)(h_eth + 1);
+		h_vlan->vlan = vlan_id;
+		h_vlan->subtype = 0x0800;
+		h_ip = (struct iphdr *)(h_vlan + 1);
+	} else {
+		h_eth->type = 0x0800;
+		h_ip = (struct iphdr *)(h_eth + 1);
+	}
+
+	header_size += sizeof(struct iphdr);
+	h_ip->ver_len = 0x45;
+	h_ip->ttl = 10;
+	h_ip->proto = 0x11;
+	h_ip->src = 0x00000000;
+	h_ip->dest = 0xffffffff;
+
+	header_size += sizeof(struct udphdr);
+	h_udp = (struct udphdr *)(h_ip + 1);
+	h_udp->src = GELIC_DEBUG_PORT;
+	h_udp->dest = GELIC_DEBUG_PORT;
+
+	pmsgc = pmsg = (char *)(h_udp + 1);
+}
+
+static void gelic_debug_shutdown(void)
+{
+	if (bus_addr)
+		unmap_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID,
+			      bus_addr, sizeof(dbg));
+	lv1_close_device(GELIC_BUS_ID, GELIC_DEVICE_ID);
+}
+
+static void gelic_sendbuf(int msgsize)
+{
+	u16 *p;
+	u32 sum;
+	int i;
+
+	dbg.descr.buf_size = header_size + msgsize;
+	h_ip->total_length = msgsize + sizeof(struct udphdr) +
+			     sizeof(struct iphdr);
+	h_udp->len = msgsize + sizeof(struct udphdr);
+
+	h_ip->checksum = 0;
+	sum = 0;
+	p = (u16 *)h_ip;
+	for (i = 0; i < 5; i++)
+		sum += *p++;
+	h_ip->checksum = ~(sum + (sum >> 16));
+
+	dbg.descr.dmac_cmd_status = GELIC_DESCR_DMA_CMD_NO_CHKSUM |
+				    GELIC_DESCR_TX_DMA_FRAME_TAIL;
+	dbg.descr.result_size = 0;
+	dbg.descr.data_status = 0;
+
+	wmb();
+
+	lv1_net_start_tx_dma(GELIC_BUS_ID, GELIC_DEVICE_ID, bus_addr, 0);
+
+	while ((dbg.descr.dmac_cmd_status & GELIC_DESCR_DMA_STAT_MASK) ==
+	       GELIC_DESCR_DMA_CARDOWNED)
+		cpu_relax();
+}
+
+static void ps3gelic_udbg_putc(char ch)
+{
+	*pmsgc++ = ch;
+	if (ch == '\n' || (pmsgc-pmsg) >= GELIC_MAX_MESSAGE_SIZE) {
+		gelic_sendbuf(pmsgc-pmsg);
+		pmsgc = pmsg;
+	}
+}
+
+void __init udbg_init_ps3gelic(void)
+{
+	gelic_debug_init();
+	udbg_putc = ps3gelic_udbg_putc;
+}
+
+void udbg_shutdown_ps3gelic(void)
+{
+	udbg_putc = NULL;
+	gelic_debug_shutdown();
+}
+EXPORT_SYMBOL(udbg_shutdown_ps3gelic);
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 035a676..4488655 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -1688,6 +1688,9 @@ static int __devinit ps3_gelic_driver_probe(struct ps3_system_bus_device *dev)
 	int result;
 
 	pr_debug("%s: called\n", __func__);
+
+	udbg_shutdown_ps3gelic();
+
 	result = ps3_open_hv_device(dev);
 
 	if (result) {
diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h
index 07bdc17..57ef974 100644
--- a/drivers/net/ps3_gelic_net.h
+++ b/drivers/net/ps3_gelic_net.h
@@ -360,6 +360,12 @@ static inline void *port_priv(struct gelic_port *port)
 	return port->priv;
 }
 
+#ifdef CONFIG_PPC_EARLY_DEBUG_PS3GELIC
+extern void udbg_shutdown_ps3gelic(void);
+#else
+static inline void udbg_shutdown_ps3gelic(void) {}
+#endif
+
 extern int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask);
 /* shared netdev ops */
 extern void gelic_card_up(struct gelic_card *card);
-- 
1.7.5.4

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

* [PATCH 02/15] [PS3] Get lv1 high memory region from devtree
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
  2011-08-01 20:02 ` [PATCH 01/15] [PS3] Add udbg driver using the PS3 gelic Ethernet device Andre Heider
@ 2011-08-01 20:02 ` Andre Heider
  2011-08-03 22:30   ` Geoff Levand
  2011-08-01 20:02 ` [PATCH 03/15] [PS3] Add region 1 memory early Andre Heider
                   ` (15 subsequent siblings)
  17 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:02 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

From: Hector Martin <hector@marcansoft.com>

This lets the bootloader preallocate the high lv1 region and pass its
location to the kernel through the devtree. Thus, it can be used to hold
the initrd. If the property doesn't exist, the kernel retains the old
behavior and attempts to allocate the region itself.

Signed-off-by: Hector Martin <hector@marcansoft.com>
[a.heider: Various cleanups to make checkpatch.pl happy]
Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/platforms/ps3/mm.c |   61 +++++++++++++++++++++++++++++++++++++-
 1 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index c204588..30bb096 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -110,6 +110,7 @@ struct map {
 	u64 htab_size;
 	struct mem_region rm;
 	struct mem_region r1;
+	int destroy_r1;
 };
 
 #define debug_dump_map(x) _debug_dump_map(x, __func__, __LINE__)
@@ -287,6 +288,49 @@ static void ps3_mm_region_destroy(struct mem_region *r)
 	}
 }
 
+static int ps3_mm_scan_memory(unsigned long node, const char *uname,
+			      int depth, void *data)
+{
+	struct mem_region *r = data;
+	void *p;
+	u64 prop[2];
+	unsigned long l;
+	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+
+	if (type == NULL)
+		return 0;
+	if (strcmp(type, "memory") != 0)
+		return 0;
+
+	p = of_get_flat_dt_prop(node, "sony,lv1-highmem", &l);
+	if (p == NULL)
+		return 0;
+
+	BUG_ON(l != sizeof(prop));
+	memcpy(prop, p, sizeof(prop));
+
+	r->base = prop[0];
+	r->size = prop[1];
+	r->offset = r->base - map.rm.size;
+
+	return -1;
+}
+
+static int ps3_mm_get_devtree_highmem(struct mem_region *r)
+{
+	r->size = r->base = r->offset = 0;
+	of_scan_flat_dt(ps3_mm_scan_memory, r);
+
+	if (r->base && r->size) {
+		DBG("%s:%d got high region from devtree: %llxh %llxh\n",
+		__func__, __LINE__, r->base, r->size);
+		return 0;
+	} else {
+		DBG("%s:%d no high region in devtree...\n", __func__, __LINE__);
+		return -1;
+	}
+}
+
 /**
  * ps3_mm_add_memory - hot add memory
  */
@@ -303,6 +347,12 @@ static int __init ps3_mm_add_memory(void)
 
 	BUG_ON(!mem_init_done);
 
+	if (!map.r1.size) {
+		DBG("%s:%d: no region 1, not adding memory\n",
+		    __func__, __LINE__);
+		return 0;
+	}
+
 	start_addr = map.rm.size;
 	start_pfn = start_addr >> PAGE_SHIFT;
 	nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT;
@@ -1219,7 +1269,13 @@ void __init ps3_mm_init(void)
 
 
 	/* arrange to do this in ps3_mm_add_memory */
-	ps3_mm_region_create(&map.r1, map.total - map.rm.size);
+
+	if (ps3_mm_get_devtree_highmem(&map.r1) == 0) {
+		map.destroy_r1 = 0;
+	} else {
+		ps3_mm_region_create(&map.r1, map.total - map.rm.size);
+		map.destroy_r1 = 1;
+	}
 
 	/* correct map.total for the real total amount of memory we use */
 	map.total = map.rm.size + map.r1.size;
@@ -1233,5 +1289,6 @@ void __init ps3_mm_init(void)
 
 void ps3_mm_shutdown(void)
 {
-	ps3_mm_region_destroy(&map.r1);
+	if (map.destroy_r1)
+		ps3_mm_region_destroy(&map.r1);
 }
-- 
1.7.5.4

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

* [PATCH 03/15] [PS3] Add region 1 memory early
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
  2011-08-01 20:02 ` [PATCH 01/15] [PS3] Add udbg driver using the PS3 gelic Ethernet device Andre Heider
  2011-08-01 20:02 ` [PATCH 02/15] [PS3] Get lv1 high memory region from devtree Andre Heider
@ 2011-08-01 20:02 ` Andre Heider
  2011-08-03 22:32   ` Geoff Levand
  2011-08-01 20:02 ` [PATCH 04/15] ps3: MEMORY_HOTPLUG is not a requirement anymore Andre Heider
                   ` (14 subsequent siblings)
  17 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:02 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

From: Hector Martin <hector@marcansoft.com>

Signed-off-by: Hector Martin <hector@marcansoft.com>
[a.heider: Various cleanups to make checkpatch.pl happy]
Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/platforms/ps3/mm.c |   62 +++++++--------------------------------
 1 files changed, 11 insertions(+), 51 deletions(-)

diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 30bb096..15876d6 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -331,57 +331,6 @@ static int ps3_mm_get_devtree_highmem(struct mem_region *r)
 	}
 }
 
-/**
- * ps3_mm_add_memory - hot add memory
- */
-
-static int __init ps3_mm_add_memory(void)
-{
-	int result;
-	unsigned long start_addr;
-	unsigned long start_pfn;
-	unsigned long nr_pages;
-
-	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
-		return -ENODEV;
-
-	BUG_ON(!mem_init_done);
-
-	if (!map.r1.size) {
-		DBG("%s:%d: no region 1, not adding memory\n",
-		    __func__, __LINE__);
-		return 0;
-	}
-
-	start_addr = map.rm.size;
-	start_pfn = start_addr >> PAGE_SHIFT;
-	nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
-	DBG("%s:%d: start_addr %lxh, start_pfn %lxh, nr_pages %lxh\n",
-		__func__, __LINE__, start_addr, start_pfn, nr_pages);
-
-	result = add_memory(0, start_addr, map.r1.size);
-
-	if (result) {
-		pr_err("%s:%d: add_memory failed: (%d)\n",
-			__func__, __LINE__, result);
-		return result;
-	}
-
-	memblock_add(start_addr, map.r1.size);
-	memblock_analyze();
-
-	result = online_pages(start_pfn, nr_pages);
-
-	if (result)
-		pr_err("%s:%d: online_pages failed: (%d)\n",
-			__func__, __LINE__, result);
-
-	return result;
-}
-
-device_initcall(ps3_mm_add_memory);
-
 /*============================================================================*/
 /* dma routines                                                               */
 /*============================================================================*/
@@ -1280,6 +1229,17 @@ void __init ps3_mm_init(void)
 	/* correct map.total for the real total amount of memory we use */
 	map.total = map.rm.size + map.r1.size;
 
+	if (!map.r1.size) {
+		DBG("%s:%d: no region 1, not adding memory\n",
+			__func__, __LINE__);
+	} else {
+		DBG("%s:%d: adding memory: start %llxh, size %llxh\n",
+			__func__, __LINE__, map.rm.size, map.r1.size);
+
+		memblock_add(map.rm.size, map.r1.size);
+		memblock_analyze();
+	}
+
 	DBG(" <- %s:%d\n", __func__, __LINE__);
 }
 
-- 
1.7.5.4

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

* [PATCH 04/15] ps3: MEMORY_HOTPLUG is not a requirement anymore
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (2 preceding siblings ...)
  2011-08-01 20:02 ` [PATCH 03/15] [PS3] Add region 1 memory early Andre Heider
@ 2011-08-01 20:02 ` Andre Heider
  2011-08-01 20:02 ` [PATCH 05/15] ps3: Detect the current lpar environment Andre Heider
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:02 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/platforms/ps3/Kconfig |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 476d9d9..84df5c8 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -7,7 +7,6 @@ config PPC_PS3
 	select USB_OHCI_BIG_ENDIAN_MMIO
 	select USB_ARCH_HAS_EHCI
 	select USB_EHCI_BIG_ENDIAN_MMIO
-	select MEMORY_HOTPLUG
 	select PPC_PCI_CHOICE
 	help
 	  This option enables support for the Sony PS3 game console
-- 
1.7.5.4

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

* [PATCH 05/15] ps3: Detect the current lpar environment
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (3 preceding siblings ...)
  2011-08-01 20:02 ` [PATCH 04/15] ps3: MEMORY_HOTPLUG is not a requirement anymore Andre Heider
@ 2011-08-01 20:02 ` Andre Heider
  2011-08-03 22:31   ` Geoff Levand
  2011-08-01 20:02 ` [PATCH 06/15] ps3flash: Fix region align checks Andre Heider
                   ` (12 subsequent siblings)
  17 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:02 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

There is more than the OtherOS lpar the kernel can be launched in.
Detect it by reading the ss laid repository node, and be verbose about
it.

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/include/asm/ps3.h          |    7 +++++++
 arch/powerpc/platforms/ps3/platform.h   |    4 ++++
 arch/powerpc/platforms/ps3/repository.c |   19 +++++++++++++++++++
 arch/powerpc/platforms/ps3/setup.c      |   22 ++++++++++++++++++++++
 4 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
index 7f065e1..136354a 100644
--- a/arch/powerpc/include/asm/ps3.h
+++ b/arch/powerpc/include/asm/ps3.h
@@ -39,6 +39,13 @@ union ps3_firmware_version {
 void ps3_get_firmware_version(union ps3_firmware_version *v);
 int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev);
 
+enum ps3_ss_laid {
+	PS3_SS_LAID_GAMEOS = 0x1070000002000001UL,
+	PS3_SS_LAID_OTHEROS = 0x1080000004000001UL,
+};
+
+enum ps3_ss_laid ps3_get_ss_laid(void);
+
 /* 'Other OS' area */
 
 enum ps3_param_av_multi_out {
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index 9a196a8..1ba15b8 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -232,4 +232,8 @@ int ps3_repository_read_spu_resource_id(unsigned int res_index,
 int ps3_repository_read_vuart_av_port(unsigned int *port);
 int ps3_repository_read_vuart_sysmgr_port(unsigned int *port);
 
+/* repository ss info */
+
+int ps3_repository_read_ss_laid(enum ps3_ss_laid *laid);
+
 #endif
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c
index 5e304c2..6fa3e96 100644
--- a/arch/powerpc/platforms/ps3/repository.c
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -1002,6 +1002,25 @@ int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar,
 			    lpar, rights);
 }
 
+/**
+ * ps3_repository_read_ss_laid - Read the lpar auth id
+ */
+
+int ps3_repository_read_ss_laid(enum ps3_ss_laid *laid)
+{
+	int result;
+	u64 id, v1;
+
+	lv1_get_logical_partition_id(&id);
+	result = read_node(PS3_LPAR_ID_PME,
+			   make_first_field("ss", 0),
+			   make_field("laid", 0),
+			   id, 0,
+			   &v1, NULL);
+	*laid = v1;
+	return result;
+}
+
 #if defined(DEBUG)
 
 int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo)
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 149bea2..f430279 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -47,6 +47,7 @@ DEFINE_MUTEX(ps3_gpu_mutex);
 EXPORT_SYMBOL_GPL(ps3_gpu_mutex);
 
 static union ps3_firmware_version ps3_firmware_version;
+static enum ps3_ss_laid ps3_ss_laid;
 
 void ps3_get_firmware_version(union ps3_firmware_version *v)
 {
@@ -68,6 +69,12 @@ int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev)
 }
 EXPORT_SYMBOL_GPL(ps3_compare_firmware_version);
 
+enum ps3_ss_laid ps3_get_ss_laid(void)
+{
+	return ps3_ss_laid;
+}
+EXPORT_SYMBOL_GPL(ps3_get_ss_laid);
+
 static void ps3_power_save(void)
 {
 	/*
@@ -192,6 +199,7 @@ static int ps3_set_dabr(unsigned long dabr)
 
 static void __init ps3_setup_arch(void)
 {
+	const char *laid_str;
 
 	DBG(" -> %s:%d\n", __func__, __LINE__);
 
@@ -200,6 +208,20 @@ static void __init ps3_setup_arch(void)
 	       ps3_firmware_version.major, ps3_firmware_version.minor,
 	       ps3_firmware_version.rev);
 
+	ps3_repository_read_ss_laid(&ps3_ss_laid);
+	switch (ps3_ss_laid) {
+	case PS3_SS_LAID_GAMEOS:
+		laid_str = "GameOS";
+		break;
+	case PS3_SS_LAID_OTHEROS:
+		laid_str = "OtherOS";
+		break;
+	default:
+		laid_str = "unknown";
+		break;
+	}
+	printk(KERN_INFO "Running in %s lpar\n", laid_str);
+
 	ps3_spu_set_platform();
 
 #ifdef CONFIG_SMP
-- 
1.7.5.4

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

* [PATCH 06/15] ps3flash: Fix region align checks
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (4 preceding siblings ...)
  2011-08-01 20:02 ` [PATCH 05/15] ps3: Detect the current lpar environment Andre Heider
@ 2011-08-01 20:02 ` Andre Heider
  2011-08-01 20:29   ` [Cbe-oss-dev] " Geert Uytterhoeven
  2011-08-01 20:02 ` [PATCH 07/15] ps3flash: Refuse to work in lpars other than OtherOS Andre Heider
                   ` (11 subsequent siblings)
  17 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:02 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

The region fields used by the align checks are set in
ps3stor_setup(), so move those after that call.

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 drivers/char/ps3flash.c |   30 +++++++++++++++---------------
 1 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
index 85c004a..69c734a 100644
--- a/drivers/char/ps3flash.c
+++ b/drivers/char/ps3flash.c
@@ -360,21 +360,6 @@ static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev)
 	int error;
 	unsigned long tmp;
 
-	tmp = dev->regions[dev->region_idx].start*dev->blk_size;
-	if (tmp % FLASH_BLOCK_SIZE) {
-		dev_err(&dev->sbd.core,
-			"%s:%u region start %lu is not aligned\n", __func__,
-			__LINE__, tmp);
-		return -EINVAL;
-	}
-	tmp = dev->regions[dev->region_idx].size*dev->blk_size;
-	if (tmp % FLASH_BLOCK_SIZE) {
-		dev_err(&dev->sbd.core,
-			"%s:%u region size %lu is not aligned\n", __func__,
-			__LINE__, tmp);
-		return -EINVAL;
-	}
-
 	/* use static buffer, kmalloc cannot allocate 256 KiB */
 	if (!ps3flash_bounce_buffer.address)
 		return -ENODEV;
@@ -405,6 +390,21 @@ static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev)
 	if (error)
 		goto fail_free_priv;
 
+	tmp = dev->regions[dev->region_idx].start*dev->blk_size;
+	if (tmp % FLASH_BLOCK_SIZE) {
+		dev_err(&dev->sbd.core,
+			"%s:%u region start %lu is not aligned\n", __func__,
+			__LINE__, tmp);
+		return -EINVAL;
+	}
+	tmp = dev->regions[dev->region_idx].size*dev->blk_size;
+	if (tmp % FLASH_BLOCK_SIZE) {
+		dev_err(&dev->sbd.core,
+			"%s:%u region size %lu is not aligned\n", __func__,
+			__LINE__, tmp);
+		return -EINVAL;
+	}
+
 	ps3flash_misc.parent = &dev->sbd.core;
 	error = misc_register(&ps3flash_misc);
 	if (error) {
-- 
1.7.5.4

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

* [PATCH 07/15] ps3flash: Refuse to work in lpars other than OtherOS
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (5 preceding siblings ...)
  2011-08-01 20:02 ` [PATCH 06/15] ps3flash: Fix region align checks Andre Heider
@ 2011-08-01 20:02 ` Andre Heider
  2011-08-03 22:34   ` Geoff Levand
  2011-08-01 20:02 ` [PATCH 08/15] ps3: Only prealloc the flash bounce buffer for the OtherOS lpar Andre Heider
                   ` (10 subsequent siblings)
  17 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:02 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

The driver implements a character and misc device, meant for the
axed OtherOS to exchange various settings with GameOS.
Since Firmware 3.21 there is no GameOS support anymore to write these
settings, so limit the driver to the OtherOS environment.

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/platforms/ps3/Kconfig |    1 +
 drivers/char/ps3flash.c            |    7 +++++++
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 84df5c8..5eb956a 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -121,6 +121,7 @@ config PS3_FLASH
 
 	  This support is required to access the PS3 FLASH ROM, which
 	  contains the boot loader and some boot options.
+	  This driver only supports the deprecated OtherOS LPAR.
 	  In general, all users will say Y or M.
 
 	  As this driver needs a fixed buffer of 256 KiB of memory, it can
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
index 69c734a..b1e8659 100644
--- a/drivers/char/ps3flash.c
+++ b/drivers/char/ps3flash.c
@@ -25,6 +25,7 @@
 
 #include <asm/lv1call.h>
 #include <asm/ps3stor.h>
+#include <asm/firmware.h>
 
 
 #define DEVICE_NAME		"ps3flash"
@@ -455,6 +456,12 @@ static struct ps3_system_bus_driver ps3flash = {
 
 static int __init ps3flash_init(void)
 {
+	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+		return -ENODEV;
+
+	if (ps3_get_ss_laid() != PS3_SS_LAID_OTHEROS)
+		return -ENODEV;
+
 	return ps3_system_bus_driver_register(&ps3flash);
 }
 
-- 
1.7.5.4

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

* [PATCH 08/15] ps3: Only prealloc the flash bounce buffer for the OtherOS lpar
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (6 preceding siblings ...)
  2011-08-01 20:02 ` [PATCH 07/15] ps3flash: Refuse to work in lpars other than OtherOS Andre Heider
@ 2011-08-01 20:02 ` Andre Heider
  2011-08-01 20:03 ` [PATCH 09/15] ps3: Limit the number of regions per storage device Andre Heider
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:02 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

It's only used by the ps3flash driver, which only supports the
OtherOS lpar.

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/platforms/ps3/setup.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index f430279..923be8a 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -233,7 +233,10 @@ static void __init ps3_setup_arch(void)
 #endif
 
 	prealloc_ps3fb_videomemory();
-	prealloc_ps3flash_bounce_buffer();
+
+	/* the ps3flash driver only works for OtherOS */
+	if (ps3_get_ss_laid() == PS3_SS_LAID_OTHEROS)
+		prealloc_ps3flash_bounce_buffer();
 
 	ppc_md.power_save = ps3_power_save;
 	ps3_os_area_init();
-- 
1.7.5.4

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

* [PATCH 09/15] ps3: Limit the number of regions per storage device
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (7 preceding siblings ...)
  2011-08-01 20:02 ` [PATCH 08/15] ps3: Only prealloc the flash bounce buffer for the OtherOS lpar Andre Heider
@ 2011-08-01 20:03 ` Andre Heider
  2011-08-01 20:30   ` [Cbe-oss-dev] " Geert Uytterhoeven
  2011-08-01 20:03 ` [PATCH 10/15] ps3stor_lib: Add support for multiple regions Andre Heider
                   ` (8 subsequent siblings)
  17 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:03 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

There can be only 8 regions, add a sanity check

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/include/asm/ps3stor.h       |    1 +
 arch/powerpc/platforms/ps3/device-init.c |    8 ++++++++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/ps3stor.h b/arch/powerpc/include/asm/ps3stor.h
index 6fcaf71..d51e53c 100644
--- a/arch/powerpc/include/asm/ps3stor.h
+++ b/arch/powerpc/include/asm/ps3stor.h
@@ -25,6 +25,7 @@
 
 #include <asm/ps3.h>
 
+#define PS3_STORAGE_MAX_REGIONS		(8)
 
 struct ps3_storage_region {
 	unsigned int id;
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
index 6c4b583..830d741 100644
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -349,6 +349,14 @@ static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
 		return -ENODEV;
 	}
 
+	if (num_regions > PS3_STORAGE_MAX_REGIONS) {
+		pr_warning("%s:%u: device %u:%u reported %u regions, "
+			   "limiting to %u\n", __func__, __LINE__,
+			   num_regions, repo->bus_index, repo->dev_index,
+			   PS3_STORAGE_MAX_REGIONS);
+		num_regions = PS3_STORAGE_MAX_REGIONS;
+	}
+
 	pr_debug("%s:%u: (%u:%u:%u): port %llu blk_size %llu num_blocks %llu "
 		 "num_regions %u\n", __func__, __LINE__, repo->bus_index,
 		 repo->dev_index, repo->dev_type, port, blk_size, num_blocks,
-- 
1.7.5.4

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

* [PATCH 10/15] ps3stor_lib: Add support for multiple regions
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (8 preceding siblings ...)
  2011-08-01 20:03 ` [PATCH 09/15] ps3: Limit the number of regions per storage device Andre Heider
@ 2011-08-01 20:03 ` Andre Heider
  2011-08-01 20:35   ` Geert Uytterhoeven
  2011-08-01 20:03 ` [PATCH 11/15] ps3disk: Provide a gendisk per accessible region Andre Heider
                   ` (7 subsequent siblings)
  17 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:03 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

Users (ps3disk, ps3flash and ps3rom) retain the old behavior. That is:
they still only provide access to the first accessible region.

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/include/asm/ps3stor.h |    4 ++--
 drivers/block/ps3disk.c            |   15 +++++++++++++--
 drivers/char/ps3flash.c            |   23 +++++++++++++++++------
 drivers/ps3/ps3stor_lib.c          |   25 ++++++++++++-------------
 drivers/scsi/ps3rom.c              |   11 +++++++----
 5 files changed, 51 insertions(+), 27 deletions(-)

diff --git a/arch/powerpc/include/asm/ps3stor.h b/arch/powerpc/include/asm/ps3stor.h
index d51e53c..9871c05 100644
--- a/arch/powerpc/include/asm/ps3stor.h
+++ b/arch/powerpc/include/asm/ps3stor.h
@@ -51,7 +51,6 @@ struct ps3_storage_device {
 
 	unsigned int num_regions;
 	unsigned long accessible_regions;
-	unsigned int region_idx;		/* first accessible region */
 	struct ps3_storage_region regions[0];	/* Must be last */
 };
 
@@ -63,7 +62,8 @@ static inline struct ps3_storage_device *to_ps3_storage_device(struct device *de
 extern int ps3stor_setup(struct ps3_storage_device *dev,
 			 irq_handler_t handler);
 extern void ps3stor_teardown(struct ps3_storage_device *dev);
-extern u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, u64 lpar,
+extern u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev,
+				      unsigned int region_idx, u64 lpar,
 				      u64 start_sector, u64 sectors,
 				      int write);
 extern u64 ps3stor_send_command(struct ps3_storage_device *dev, u64 cmd,
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index 8e1ce2e..96e00ff 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -42,6 +42,7 @@ struct ps3disk_private {
 	spinlock_t lock;		/* Request queue spinlock */
 	struct request_queue *queue;
 	struct gendisk *gendisk;
+	unsigned int region_idx;	/* first accessible region */
 	unsigned int blocking_factor;
 	struct request *req;
 	u64 raw_capacity;
@@ -125,7 +126,7 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
 	int write = rq_data_dir(req), res;
 	const char *op = write ? "write" : "read";
 	u64 start_sector, sectors;
-	unsigned int region_id = dev->regions[dev->region_idx].id;
+	unsigned int region_id = dev->regions[priv->region_idx].id;
 
 #ifdef DEBUG
 	unsigned int n = 0;
@@ -408,6 +409,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
 	unsigned int devidx;
 	struct request_queue *queue;
 	struct gendisk *gendisk;
+	unsigned int region_idx;
 
 	if (dev->blk_size < 512) {
 		dev_err(&dev->sbd.core,
@@ -482,6 +484,14 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
 	}
 
 	priv->gendisk = gendisk;
+
+	/* find first accessible region */
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++)
+		if (test_bit(region_idx, &dev->accessible_regions)) {
+			priv->region_idx = region_idx;
+			break;
+		}
+
 	gendisk->major = ps3disk_major;
 	gendisk->first_minor = devidx * PS3DISK_MINORS;
 	gendisk->fops = &ps3disk_fops;
@@ -492,7 +502,8 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
 		 devidx+'a');
 	priv->blocking_factor = dev->blk_size >> 9;
 	set_capacity(gendisk,
-		     dev->regions[dev->region_idx].size*priv->blocking_factor);
+		     dev->regions[priv->region_idx].size *
+				 priv->blocking_factor);
 
 	dev_info(&dev->sbd.core,
 		 "%s is a %s (%llu MiB total, %lu MiB for OtherOS)\n",
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
index b1e8659..47b1dc7 100644
--- a/drivers/char/ps3flash.c
+++ b/drivers/char/ps3flash.c
@@ -36,6 +36,7 @@
 struct ps3flash_private {
 	struct mutex mutex;	/* Bounce buffer mutex */
 	u64 chunk_sectors;
+	unsigned int region_idx;	/* first accessible region */
 	int tag;		/* Start sector of buffer, -1 if invalid */
 	bool dirty;
 };
@@ -46,7 +47,8 @@ static int ps3flash_read_write_sectors(struct ps3_storage_device *dev,
 				       u64 start_sector, int write)
 {
 	struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
-	u64 res = ps3stor_read_write_sectors(dev, dev->bounce_lpar,
+	u64 res = ps3stor_read_write_sectors(dev, priv->region_idx,
+					     dev->bounce_lpar,
 					     start_sector, priv->chunk_sectors,
 					     write);
 	if (res) {
@@ -98,6 +100,7 @@ static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector)
 static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin)
 {
 	struct ps3_storage_device *dev = ps3flash_dev;
+	struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
 	loff_t res;
 
 	mutex_lock(&file->f_mapping->host->i_mutex);
@@ -106,7 +109,7 @@ static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin)
 		offset += file->f_pos;
 		break;
 	case 2:
-		offset += dev->regions[dev->region_idx].size*dev->blk_size;
+		offset += dev->regions[priv->region_idx].size*dev->blk_size;
 		break;
 	}
 	if (offset < 0) {
@@ -136,7 +139,7 @@ static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf,
 		"%s:%u: Reading %zu bytes at position %lld to U0x%p/K0x%p\n",
 		__func__, __LINE__, count, *pos, userbuf, kernelbuf);
 
-	size = dev->regions[dev->region_idx].size*dev->blk_size;
+	size = dev->regions[priv->region_idx].size*dev->blk_size;
 	if (*pos >= size || !count)
 		return 0;
 
@@ -205,7 +208,7 @@ static ssize_t ps3flash_write(const char __user *userbuf,
 		"%s:%u: Writing %zu bytes at position %lld from U0x%p/K0x%p\n",
 		__func__, __LINE__, count, *pos, userbuf, kernelbuf);
 
-	size = dev->regions[dev->region_idx].size*dev->blk_size;
+	size = dev->regions[priv->region_idx].size*dev->blk_size;
 	if (*pos >= size || !count)
 		return 0;
 
@@ -359,6 +362,7 @@ static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev)
 	struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
 	struct ps3flash_private *priv;
 	int error;
+	unsigned int region_idx;
 	unsigned long tmp;
 
 	/* use static buffer, kmalloc cannot allocate 256 KiB */
@@ -391,14 +395,21 @@ static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev)
 	if (error)
 		goto fail_free_priv;
 
-	tmp = dev->regions[dev->region_idx].start*dev->blk_size;
+	/* find first accessible region */
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++)
+		if (test_bit(region_idx, &dev->accessible_regions)) {
+			priv->region_idx = region_idx;
+			break;
+		}
+
+	tmp = dev->regions[priv->region_idx].start*dev->blk_size;
 	if (tmp % FLASH_BLOCK_SIZE) {
 		dev_err(&dev->sbd.core,
 			"%s:%u region start %lu is not aligned\n", __func__,
 			__LINE__, tmp);
 		return -EINVAL;
 	}
-	tmp = dev->regions[dev->region_idx].size*dev->blk_size;
+	tmp = dev->regions[priv->region_idx].size*dev->blk_size;
 	if (tmp % FLASH_BLOCK_SIZE) {
 		dev_err(&dev->sbd.core,
 			"%s:%u region size %lu is not aligned\n", __func__,
diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c
index af0afa1..5bbc023 100644
--- a/drivers/ps3/ps3stor_lib.c
+++ b/drivers/ps3/ps3stor_lib.c
@@ -101,9 +101,8 @@ static int ps3stor_probe_access(struct ps3_storage_device *dev)
 			"%s:%u: checking accessibility of region %u\n",
 			__func__, __LINE__, i);
 
-		dev->region_idx = i;
-		res = ps3stor_read_write_sectors(dev, dev->bounce_lpar, 0, 1,
-						 0);
+		res = ps3stor_read_write_sectors(dev, i, dev->bounce_lpar,
+						 0, 1, 0);
 		if (res) {
 			dev_dbg(&dev->sbd.core, "%s:%u: read failed, "
 				"region %u is not accessible\n", __func__,
@@ -117,6 +116,11 @@ static int ps3stor_probe_access(struct ps3_storage_device *dev)
 
 		/* We can access at least one region */
 		error = 0;
+
+		dev_info(&dev->sbd.core,
+			 "Accessible region found: #%u start %llu size %llu\n",
+			 i, dev->regions[i].start, dev->regions[i].size);
+
 	}
 	if (error)
 		return error;
@@ -124,15 +128,8 @@ static int ps3stor_probe_access(struct ps3_storage_device *dev)
 	n = hweight_long(dev->accessible_regions);
 	if (n > 1)
 		dev_info(&dev->sbd.core,
-			 "%s:%u: %lu accessible regions found. Only the first "
-			 "one will be used\n",
+			 "%s:%u: %lu accessible regions found\n",
 			 __func__, __LINE__, n);
-	dev->region_idx = __ffs(dev->accessible_regions);
-	dev_info(&dev->sbd.core,
-		 "First accessible region has index %u start %llu size %llu\n",
-		 dev->region_idx, dev->regions[dev->region_idx].start,
-		 dev->regions[dev->region_idx].size);
-
 	return 0;
 }
 
@@ -264,6 +261,7 @@ EXPORT_SYMBOL_GPL(ps3stor_teardown);
 /**
  *	ps3stor_read_write_sectors - read/write from/to a storage device
  *	@dev: Pointer to a struct ps3_storage_device
+ *	@region_idx: Index of the region to access
  *	@lpar: HV logical partition address
  *	@start_sector: First sector to read/write
  *	@sectors: Number of sectors to read/write
@@ -272,10 +270,11 @@ EXPORT_SYMBOL_GPL(ps3stor_teardown);
  *	Returns 0 for success, -1 in case of failure to submit the command, or
  *	an LV1 status value in case of other errors
  */
-u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, u64 lpar,
+u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev,
+			       unsigned int region_idx, u64 lpar,
 			       u64 start_sector, u64 sectors, int write)
 {
-	unsigned int region_id = dev->regions[dev->region_idx].id;
+	unsigned int region_id = dev->regions[region_idx].id;
 	const char *op = write ? "write" : "read";
 	int res;
 
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c
index cd178b9..68db03c 100644
--- a/drivers/scsi/ps3rom.c
+++ b/drivers/scsi/ps3rom.c
@@ -39,6 +39,7 @@
 
 #define PS3ROM_MAX_SECTORS		(BOUNCE_SIZE >> 9)
 
+#define PS3ROM_REGION_IDX		0
 
 struct ps3rom_private {
 	struct ps3_storage_device *dev;
@@ -177,8 +178,9 @@ static int ps3rom_read_request(struct ps3_storage_device *dev,
 		__func__, __LINE__, sectors, start_sector);
 
 	res = lv1_storage_read(dev->sbd.dev_id,
-			       dev->regions[dev->region_idx].id, start_sector,
-			       sectors, 0, dev->bounce_lpar, &dev->tag);
+			       dev->regions[PS3ROM_REGION_IDX].id,
+			       start_sector, sectors, 0,
+			       dev->bounce_lpar, &dev->tag);
 	if (res) {
 		dev_err(&dev->sbd.core, "%s:%u: read failed %d\n", __func__,
 			__LINE__, res);
@@ -200,8 +202,9 @@ static int ps3rom_write_request(struct ps3_storage_device *dev,
 	scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size);
 
 	res = lv1_storage_write(dev->sbd.dev_id,
-				dev->regions[dev->region_idx].id, start_sector,
-				sectors, 0, dev->bounce_lpar, &dev->tag);
+				dev->regions[PS3ROM_REGION_IDX].id,
+				start_sector, sectors, 0,
+				dev->bounce_lpar, &dev->tag);
 	if (res) {
 		dev_err(&dev->sbd.core, "%s:%u: write failed %d\n", __func__,
 			__LINE__, res);
-- 
1.7.5.4

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

* [PATCH 11/15] ps3disk: Provide a gendisk per accessible region
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (9 preceding siblings ...)
  2011-08-01 20:03 ` [PATCH 10/15] ps3stor_lib: Add support for multiple regions Andre Heider
@ 2011-08-01 20:03 ` Andre Heider
  2011-08-01 20:03 ` [PATCH 12/15] ps3stor_lib: Add support for storage access flags Andre Heider
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:03 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

This changes the behavior to name the block devices for lpars
other than OtherOS. Instead of a single disk with an alphanumeric
suffix (/dev/ps3da), disks are now numeric, while each
accessible region gets its own alphanumeric suffix:

/dev/ps3d1a
/dev/ps3d1b

The old behavior for OtherOS is kept:
- only one region will be exposed as block device
- the block device name stays the same

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 drivers/block/ps3disk.c |  118 ++++++++++++++++++++++++++++++----------------
 1 files changed, 77 insertions(+), 41 deletions(-)

diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index 96e00ff..cba8b45 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -35,18 +35,19 @@
 #define PS3DISK_MINORS		16
 
 
-#define PS3DISK_NAME		"ps3d%c"
+#define PS3DISK_NAME_OTHEROS	"ps3d%c"
+#define PS3DISK_NAME		"ps3d%c%c"
 
 
 struct ps3disk_private {
 	spinlock_t lock;		/* Request queue spinlock */
 	struct request_queue *queue;
-	struct gendisk *gendisk;
-	unsigned int region_idx;	/* first accessible region */
 	unsigned int blocking_factor;
 	struct request *req;
+	unsigned int devidx;
 	u64 raw_capacity;
 	unsigned char model[ATA_ID_PROD_LEN+1];
+	struct gendisk *gendisk[0];	/* Must be last */
 };
 
 
@@ -126,7 +127,9 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
 	int write = rq_data_dir(req), res;
 	const char *op = write ? "write" : "read";
 	u64 start_sector, sectors;
-	unsigned int region_id = dev->regions[priv->region_idx].id;
+	unsigned int region_idx = MINOR(disk_devt(req->rq_disk)) &
+				  (PS3DISK_MINORS - 1);
+	unsigned int region_id = dev->regions[region_idx].id;
 
 #ifdef DEBUG
 	unsigned int n = 0;
@@ -410,6 +413,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
 	struct request_queue *queue;
 	struct gendisk *gendisk;
 	unsigned int region_idx;
+	unsigned int otheros = ps3_get_ss_laid() == PS3_SS_LAID_OTHEROS;
 
 	if (dev->blk_size < 512) {
 		dev_err(&dev->sbd.core,
@@ -430,7 +434,9 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
 	__set_bit(devidx, &ps3disk_mask);
 	mutex_unlock(&ps3disk_mask_mutex);
 
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	priv = kzalloc(sizeof(*priv) +
+		       dev->num_regions * sizeof(struct gendisk),
+		       GFP_KERNEL);
 	if (!priv) {
 		error = -ENOMEM;
 		goto fail;
@@ -450,6 +456,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
 	if (error)
 		goto fail_free_bounce;
 
+	priv->devidx = devidx;
 	ps3disk_identify(dev);
 
 	queue = blk_init_queue(ps3disk_request, &priv->lock);
@@ -475,45 +482,60 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
 	blk_queue_max_segments(queue, -1);
 	blk_queue_max_segment_size(queue, dev->bounce_size);
 
-	gendisk = alloc_disk(PS3DISK_MINORS);
-	if (!gendisk) {
-		dev_err(&dev->sbd.core, "%s:%u: alloc_disk failed\n", __func__,
-			__LINE__);
-		error = -ENOMEM;
-		goto fail_cleanup_queue;
-	}
+	dev_info(&dev->sbd.core, "%s (%llu MiB)\n",
+		 priv->model, priv->raw_capacity >> 11);
 
-	priv->gendisk = gendisk;
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++) {
+		if (test_bit(region_idx, &dev->accessible_regions) == 0)
+			continue;
 
-	/* find first accessible region */
-	for (region_idx = 0; region_idx < dev->num_regions; region_idx++)
-		if (test_bit(region_idx, &dev->accessible_regions)) {
-			priv->region_idx = region_idx;
-			break;
+		gendisk = alloc_disk(PS3DISK_MINORS * PS3_STORAGE_MAX_REGIONS);
+		if (!gendisk) {
+			dev_err(&dev->sbd.core, "%s:%u: alloc_disk failed\n",
+				__func__, __LINE__);
+			error = -ENOMEM;
+			goto fail_cleanup_queue;
 		}
 
-	gendisk->major = ps3disk_major;
-	gendisk->first_minor = devidx * PS3DISK_MINORS;
-	gendisk->fops = &ps3disk_fops;
-	gendisk->queue = queue;
-	gendisk->private_data = dev;
-	gendisk->driverfs_dev = &dev->sbd.core;
-	snprintf(gendisk->disk_name, sizeof(gendisk->disk_name), PS3DISK_NAME,
-		 devidx+'a');
-	priv->blocking_factor = dev->blk_size >> 9;
-	set_capacity(gendisk,
-		     dev->regions[priv->region_idx].size *
-				 priv->blocking_factor);
-
-	dev_info(&dev->sbd.core,
-		 "%s is a %s (%llu MiB total, %lu MiB for OtherOS)\n",
-		 gendisk->disk_name, priv->model, priv->raw_capacity >> 11,
-		 get_capacity(gendisk) >> 11);
-
-	add_disk(gendisk);
+		priv->gendisk[region_idx] = gendisk;
+		gendisk->major = ps3disk_major;
+		gendisk->first_minor = devidx * PS3DISK_MINORS + region_idx;
+		gendisk->fops = &ps3disk_fops;
+		gendisk->queue = queue;
+		gendisk->private_data = dev;
+		gendisk->driverfs_dev = &dev->sbd.core;
+
+		if (otheros) {
+			/* keep the old block device name for OtherOS */
+			snprintf(gendisk->disk_name, sizeof(gendisk->disk_name),
+				 PS3DISK_NAME_OTHEROS, 'a' + devidx);
+		} else {
+			snprintf(gendisk->disk_name, sizeof(gendisk->disk_name),
+				 PS3DISK_NAME, '1' + devidx, 'a' + region_idx);
+		}
+
+		priv->blocking_factor = dev->blk_size >> 9;
+		set_capacity(gendisk, dev->regions[region_idx].size *
+				      priv->blocking_factor);
+
+		dev_info(&dev->sbd.core,
+			 "%s (%lu MiB region)\n",
+			 gendisk->disk_name, get_capacity(gendisk) >> 11);
+
+		add_disk(gendisk);
+
+		/* keep old behavior for OtherOS - only one region */
+		if (otheros)
+			break;
+	}
+
 	return 0;
 
 fail_cleanup_queue:
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++)
+		if (priv->gendisk[region_idx])
+			del_gendisk(priv->gendisk[region_idx]);
+
 	blk_cleanup_queue(queue);
 fail_teardown:
 	ps3stor_teardown(dev);
@@ -533,14 +555,28 @@ static int ps3disk_remove(struct ps3_system_bus_device *_dev)
 {
 	struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
 	struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
+	unsigned int region_idx;
 
 	mutex_lock(&ps3disk_mask_mutex);
-	__clear_bit(MINOR(disk_devt(priv->gendisk)) / PS3DISK_MINORS,
-		    &ps3disk_mask);
+	__clear_bit(priv->devidx, &ps3disk_mask);
 	mutex_unlock(&ps3disk_mask_mutex);
-	del_gendisk(priv->gendisk);
+
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++) {
+		if (test_bit(region_idx, &dev->accessible_regions) == 0)
+			continue;
+
+		del_gendisk(priv->gendisk[region_idx]);
+	}
+
 	blk_cleanup_queue(priv->queue);
-	put_disk(priv->gendisk);
+
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++) {
+		if (test_bit(region_idx, &dev->accessible_regions) == 0)
+			continue;
+
+		put_disk(priv->gendisk[region_idx]);
+	}
+
 	dev_notice(&dev->sbd.core, "Synchronizing disk cache\n");
 	ps3disk_sync_cache(dev);
 	ps3stor_teardown(dev);
-- 
1.7.5.4

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

* [PATCH 12/15] ps3stor_lib: Add support for storage access flags
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (10 preceding siblings ...)
  2011-08-01 20:03 ` [PATCH 11/15] ps3disk: Provide a gendisk per accessible region Andre Heider
@ 2011-08-01 20:03 ` Andre Heider
  2011-08-01 20:03 ` [PATCH 13/15] ps3disk: Use region flags Andre Heider
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:03 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

Users can now set the access flags in the region struct. This is
required for accessing the first region, or selecting an alternative
decryption key for the vflash partitions.

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/include/asm/ps3stor.h       |    8 +++++++-
 arch/powerpc/platforms/ps3/device-init.c |    1 +
 drivers/block/ps3disk.c                  |    5 +++--
 drivers/ps3/ps3stor_lib.c                |    5 +++--
 4 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/ps3stor.h b/arch/powerpc/include/asm/ps3stor.h
index 9871c05..f29aa37 100644
--- a/arch/powerpc/include/asm/ps3stor.h
+++ b/arch/powerpc/include/asm/ps3stor.h
@@ -25,12 +25,18 @@
 
 #include <asm/ps3.h>
 
-#define PS3_STORAGE_MAX_REGIONS		(8)
+#define PS3_STORAGE_MAX_REGIONS			(8)
+
+#define PS3_STORAGE_FLAG_DEFAULT		(0)
+#define PS3_STORAGE_FLAG_SKIP_ACL		(1 << 1)
+#define PS3_STORAGE_FLAG_ALT_KEY		(1 << 2)
+#define PS3_STORAGE_FLAG_UNENCRYPTED	(1 << 5)
 
 struct ps3_storage_region {
 	unsigned int id;
 	u64 start;
 	u64 size;
+	u64 flags;
 };
 
 struct ps3_storage_device {
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
index 830d741..7a3dbf8 100644
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -409,6 +409,7 @@ static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,
 		p->regions[i].id = id;
 		p->regions[i].start = start;
 		p->regions[i].size = size;
+		p->regions[i].flags = PS3_STORAGE_FLAG_DEFAULT;
 	}
 
 	result = ps3_system_bus_device_register(&p->sbd);
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index cba8b45..30dae10 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -130,6 +130,7 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
 	unsigned int region_idx = MINOR(disk_devt(req->rq_disk)) &
 				  (PS3DISK_MINORS - 1);
 	unsigned int region_id = dev->regions[region_idx].id;
+	u64 flags = dev->regions[region_idx].flags;
 
 #ifdef DEBUG
 	unsigned int n = 0;
@@ -152,11 +153,11 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
 		ps3disk_scatter_gather(dev, req, 1);
 
 		res = lv1_storage_write(dev->sbd.dev_id, region_id,
-					start_sector, sectors, 0,
+					start_sector, sectors, flags,
 					dev->bounce_lpar, &dev->tag);
 	} else {
 		res = lv1_storage_read(dev->sbd.dev_id, region_id,
-				       start_sector, sectors, 0,
+				       start_sector, sectors, flags,
 				       dev->bounce_lpar, &dev->tag);
 	}
 	if (res) {
diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c
index 5bbc023..8bb54ac 100644
--- a/drivers/ps3/ps3stor_lib.c
+++ b/drivers/ps3/ps3stor_lib.c
@@ -275,6 +275,7 @@ u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev,
 			       u64 start_sector, u64 sectors, int write)
 {
 	unsigned int region_id = dev->regions[region_idx].id;
+	u64 flags = dev->regions[region_idx].flags;
 	const char *op = write ? "write" : "read";
 	int res;
 
@@ -283,10 +284,10 @@ u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev,
 
 	init_completion(&dev->done);
 	res = write ? lv1_storage_write(dev->sbd.dev_id, region_id,
-					start_sector, sectors, 0, lpar,
+					start_sector, sectors, flags, lpar,
 					&dev->tag)
 		    : lv1_storage_read(dev->sbd.dev_id, region_id,
-				       start_sector, sectors, 0, lpar,
+				       start_sector, sectors, flags, lpar,
 				       &dev->tag);
 	if (res) {
 		dev_dbg(&dev->sbd.core, "%s:%u: %s failed %d\n", __func__,
-- 
1.7.5.4

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

* [PATCH 13/15] ps3disk: Use region flags
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (11 preceding siblings ...)
  2011-08-01 20:03 ` [PATCH 12/15] ps3stor_lib: Add support for storage access flags Andre Heider
@ 2011-08-01 20:03 ` Andre Heider
  2011-08-01 20:03 ` [PATCH 14/15] ps3: Add a vflash driver for lpars other than OtherOS Andre Heider
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:03 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

Provide a set of default region flags and make them overwritable via
a module parameter array.
Set PS3_STORAGE_FLAG_SKIP_ACL for region 0, so it can be accessed
from the GameOS lpar.

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 drivers/block/ps3disk.c |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)

diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index 30dae10..483806e 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -39,6 +39,19 @@
 #define PS3DISK_NAME		"ps3d%c%c"
 
 
+static unsigned int region_flags[] = {
+	PS3_STORAGE_FLAG_SKIP_ACL,		/* raw disk */
+	PS3_STORAGE_FLAG_DEFAULT,		/* core os */
+	PS3_STORAGE_FLAG_DEFAULT,		/* gameos pup */
+	PS3_STORAGE_FLAG_DEFAULT,		/* n/a */
+	PS3_STORAGE_FLAG_DEFAULT,		/* n/a */
+	PS3_STORAGE_FLAG_DEFAULT,		/* n/a */
+	PS3_STORAGE_FLAG_DEFAULT,		/* n/a */
+	PS3_STORAGE_FLAG_DEFAULT,		/* n/a */
+};
+module_param_array(region_flags, uint, NULL, S_IRUGO);
+MODULE_PARM_DESC(region_flags, "Region flags");
+
 struct ps3disk_private {
 	spinlock_t lock;		/* Request queue spinlock */
 	struct request_queue *queue;
@@ -453,6 +466,9 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
 		goto fail_free_priv;
 	}
 
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++)
+		dev->regions[region_idx].flags = region_flags[region_idx];
+
 	error = ps3stor_setup(dev, ps3disk_interrupt);
 	if (error)
 		goto fail_free_bounce;
-- 
1.7.5.4

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

* [PATCH 14/15] ps3: Add a vflash driver for lpars other than OtherOS
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (12 preceding siblings ...)
  2011-08-01 20:03 ` [PATCH 13/15] ps3disk: Use region flags Andre Heider
@ 2011-08-01 20:03 ` Andre Heider
  2011-08-01 20:03 ` [PATCH 15/15] ps3: Add a NOR FLASH driver for PS3s without NAND Andre Heider
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:03 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

This driver refuses to work on OtherOS, and hence complements the
ps3flash driver - which only works on OtherOS.
A gendisk for each accessible region is created, and a default set
of region flags is provided - overwritable via a module param array.

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/platforms/ps3/Kconfig |   16 +-
 drivers/block/Makefile             |    1 +
 drivers/block/ps3vflash.c          |  508 ++++++++++++++++++++++++++++++++++++
 3 files changed, 524 insertions(+), 1 deletions(-)
 create mode 100644 drivers/block/ps3vflash.c

diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 5eb956a..f8d865c 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -121,13 +121,27 @@ config PS3_FLASH
 
 	  This support is required to access the PS3 FLASH ROM, which
 	  contains the boot loader and some boot options.
-	  This driver only supports the deprecated OtherOS LPAR.
+	  This driver only supports the deprecated OtherOS LPAR, select
+	  PS3_VFLASH below for all other LPARs.
 	  In general, all users will say Y or M.
 
 	  As this driver needs a fixed buffer of 256 KiB of memory, it can
 	  be disabled on the kernel command line using "ps3flash=off", to
 	  not allocate this fixed buffer.
 
+config PS3_VFLASH
+	tristate "PS3 VFLASH Storage Driver"
+	depends on PPC_PS3 && BLOCK
+	select PS3_STORAGE
+	help
+	  Include support for the PS3 virtual FLASH Storage.
+
+	  This support is required to access the PS3 virtual FLASH ROM, which
+	  contains the boot loader and some boot options.
+	  This driver only supports LPARs other than the deprecated OtherOS,
+	  select PS3_FLASH above to add support for FLASH ROM for the
+	  OtherOS LPAR.
+
 config PS3_VRAM
 	tristate "PS3 Video RAM Storage Driver"
 	depends on FB_PS3=y && BLOCK && m
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 40528ba..8b02899 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_BLK_DEV_SWIM)	+= swim_mod.o
 obj-$(CONFIG_BLK_DEV_FD)	+= floppy.o
 obj-$(CONFIG_AMIGA_FLOPPY)	+= amiflop.o
 obj-$(CONFIG_PS3_DISK)		+= ps3disk.o
+obj-$(CONFIG_PS3_VFLASH)	+= ps3vflash.o
 obj-$(CONFIG_PS3_VRAM)		+= ps3vram.o
 obj-$(CONFIG_ATARI_FLOPPY)	+= ataflop.o
 obj-$(CONFIG_AMIGA_Z2RAM)	+= z2ram.o
diff --git a/drivers/block/ps3vflash.c b/drivers/block/ps3vflash.c
new file mode 100644
index 0000000..a59e9f7
--- /dev/null
+++ b/drivers/block/ps3vflash.c
@@ -0,0 +1,508 @@
+/*
+ * PS3 VFLASH Storage Driver
+ *
+ * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/ata.h>
+#include <linux/blkdev.h>
+#include <linux/slab.h>
+
+#include <asm/lv1call.h>
+#include <asm/ps3stor.h>
+#include <asm/firmware.h>
+
+
+#define DEVICE_NAME		"ps3vflash"
+
+#define BOUNCE_SIZE		(64*1024)
+
+#define PS3VFLASH_MAX_DISKS	16
+#define PS3VFLASH_MINORS	16
+
+
+#define PS3VFLASH_NAME		"ps3v%c%c"
+
+
+static unsigned int region_flags[] = {
+	PS3_STORAGE_FLAG_SKIP_ACL | PS3_STORAGE_FLAG_ALT_KEY,	/* raw vflash */
+	PS3_STORAGE_FLAG_SKIP_ACL,				/* lpar 1 */
+	PS3_STORAGE_FLAG_ALT_KEY,				/* dev_flash */
+	PS3_STORAGE_FLAG_ALT_KEY,				/* dev_flash2 */
+	PS3_STORAGE_FLAG_ALT_KEY,				/* dev_flash3 */
+	PS3_STORAGE_FLAG_DEFAULT,				/* otheros */
+	PS3_STORAGE_FLAG_SKIP_ACL,				/* unknown */
+	PS3_STORAGE_FLAG_DEFAULT,				/* n/a */
+};
+module_param_array(region_flags, uint, NULL, S_IRUGO);
+MODULE_PARM_DESC(region_flags, "Region flags");
+
+struct ps3vflash_private {
+	spinlock_t lock;		/* Request queue spinlock */
+	struct request_queue *queue;
+	unsigned int blocking_factor;
+	struct request *req;
+	unsigned int devidx;
+	struct gendisk *gendisk[0];	/* Must be last */
+};
+
+
+#define LV1_STORAGE_ATA_FLUSH_CACHE	(0x31)
+
+static int ps3vflash_major;
+
+
+static const struct block_device_operations ps3vflash_fops = {
+	.owner		= THIS_MODULE,
+};
+
+
+static void ps3vflash_scatter_gather(struct ps3_storage_device *dev,
+				     struct request *req, int gather)
+{
+	unsigned int offset = 0;
+	struct req_iterator iter;
+	struct bio_vec *bvec;
+	unsigned int i = 0;
+	size_t size;
+	void *buf;
+
+	rq_for_each_segment(bvec, req, iter) {
+		unsigned long flags;
+		dev_dbg(&dev->sbd.core,
+			"%s:%u: bio %u: %u segs %u sectors from %lu\n",
+			__func__, __LINE__, i, bio_segments(iter.bio),
+			bio_sectors(iter.bio), iter.bio->bi_sector);
+
+		size = bvec->bv_len;
+		buf = bvec_kmap_irq(bvec, &flags);
+		if (gather)
+			memcpy(dev->bounce_buf+offset, buf, size);
+		else
+			memcpy(buf, dev->bounce_buf+offset, size);
+		offset += size;
+		flush_kernel_dcache_page(bvec->bv_page);
+		bvec_kunmap_irq(buf, &flags);
+		i++;
+	}
+}
+
+static int ps3vflash_submit_request_sg(struct ps3_storage_device *dev,
+				       struct request *req)
+{
+	struct ps3vflash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
+	int write = rq_data_dir(req), res;
+	const char *op = write ? "write" : "read";
+	u64 start_sector, sectors;
+	unsigned int region_idx = MINOR(disk_devt(req->rq_disk)) &
+				  (PS3VFLASH_MINORS - 1);
+	unsigned int region_id = dev->regions[region_idx].id;
+	u64 flags = dev->regions[region_idx].flags;
+
+#ifdef DEBUG
+	unsigned int n = 0;
+	struct bio_vec *bv;
+	struct req_iterator iter;
+
+	rq_for_each_segment(bv, req, iter)
+		n++;
+	dev_dbg(&dev->sbd.core,
+		"%s:%u: %s req has %u bvecs for %u sectors\n",
+		__func__, __LINE__, op, n, blk_rq_sectors(req));
+#endif
+
+	start_sector = blk_rq_pos(req) * priv->blocking_factor;
+	sectors = blk_rq_sectors(req) * priv->blocking_factor;
+	dev_dbg(&dev->sbd.core, "%s:%u: %s %llu sectors starting at %llu\n",
+		__func__, __LINE__, op, sectors, start_sector);
+
+	if (write) {
+		ps3vflash_scatter_gather(dev, req, 1);
+
+		res = lv1_storage_write(dev->sbd.dev_id, region_id,
+					start_sector, sectors, flags,
+					dev->bounce_lpar, &dev->tag);
+	} else {
+		res = lv1_storage_read(dev->sbd.dev_id, region_id,
+				       start_sector, sectors, flags,
+				       dev->bounce_lpar, &dev->tag);
+	}
+	if (res) {
+		dev_err(&dev->sbd.core, "%s:%u: %s failed %d\n", __func__,
+			__LINE__, op, res);
+		__blk_end_request_all(req, -EIO);
+		return 0;
+	}
+
+	priv->req = req;
+	return 1;
+}
+
+static int ps3vflash_submit_flush_request(struct ps3_storage_device *dev,
+					  struct request *req)
+{
+	struct ps3vflash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
+	u64 res;
+
+	dev_dbg(&dev->sbd.core, "%s:%u: flush request\n", __func__, __LINE__);
+
+	res = lv1_storage_send_device_command(dev->sbd.dev_id,
+					      LV1_STORAGE_ATA_FLUSH_CACHE,
+					      0, 0, 0, 0, &dev->tag);
+	if (res) {
+		dev_err(&dev->sbd.core, "%s:%u: sync cache failed 0x%llx\n",
+			__func__, __LINE__, res);
+		__blk_end_request_all(req, -EIO);
+		return 0;
+	}
+
+	priv->req = req;
+	return 1;
+}
+
+static void ps3vflash_do_request(struct ps3_storage_device *dev,
+				 struct request_queue *q)
+{
+	struct request *req;
+
+	dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
+
+	while ((req = blk_fetch_request(q))) {
+		if (req->cmd_flags & REQ_FLUSH) {
+			if (ps3vflash_submit_flush_request(dev, req))
+				break;
+		} else if (req->cmd_type == REQ_TYPE_FS) {
+			if (ps3vflash_submit_request_sg(dev, req))
+				break;
+		} else {
+			blk_dump_rq_flags(req, DEVICE_NAME " bad request");
+			__blk_end_request_all(req, -EIO);
+			continue;
+		}
+	}
+}
+
+static void ps3vflash_request(struct request_queue *q)
+{
+	struct ps3_storage_device *dev = q->queuedata;
+	struct ps3vflash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
+
+	if (priv->req) {
+		dev_dbg(&dev->sbd.core, "%s:%u busy\n", __func__, __LINE__);
+		return;
+	}
+
+	ps3vflash_do_request(dev, q);
+}
+
+static irqreturn_t ps3vflash_interrupt(int irq, void *data)
+{
+	struct ps3_storage_device *dev = data;
+	struct ps3vflash_private *priv;
+	struct request *req;
+	int res, read, error;
+	u64 tag, status;
+	const char *op;
+
+	res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
+
+	if (tag != dev->tag)
+		dev_err(&dev->sbd.core,
+			"%s:%u: tag mismatch, got %llx, expected %llx\n",
+			__func__, __LINE__, tag, dev->tag);
+
+	if (res) {
+		dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%llx\n",
+			__func__, __LINE__, res, status);
+		return IRQ_HANDLED;
+	}
+
+	priv = ps3_system_bus_get_drvdata(&dev->sbd);
+	req = priv->req;
+	if (!req) {
+		dev_dbg(&dev->sbd.core,
+			"%s:%u non-block layer request completed\n", __func__,
+			__LINE__);
+		dev->lv1_status = status;
+		complete(&dev->done);
+		return IRQ_HANDLED;
+	}
+
+	if (req->cmd_flags & REQ_FLUSH) {
+		read = 0;
+		op = "flush";
+	} else {
+		read = !rq_data_dir(req);
+		op = read ? "read" : "write";
+	}
+	if (status) {
+		dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__,
+			__LINE__, op, status);
+		error = -EIO;
+	} else {
+		dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__,
+			__LINE__, op);
+		error = 0;
+		if (read)
+			ps3vflash_scatter_gather(dev, req, 0);
+	}
+
+	spin_lock(&priv->lock);
+	__blk_end_request_all(req, error);
+	priv->req = NULL;
+	ps3vflash_do_request(dev, priv->queue);
+	spin_unlock(&priv->lock);
+
+	return IRQ_HANDLED;
+}
+
+static unsigned long ps3vflash_mask;
+
+static DEFINE_MUTEX(ps3vflash_mask_mutex);
+
+static int __devinit ps3vflash_probe(struct ps3_system_bus_device *_dev)
+{
+	struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
+	struct ps3vflash_private *priv;
+	int error;
+	unsigned int devidx;
+	struct request_queue *queue;
+	struct gendisk *gendisk;
+	u64 raw_capacity;
+	unsigned int region_idx;
+
+	if (dev->blk_size < 512) {
+		dev_err(&dev->sbd.core,
+			"%s:%u: cannot handle block size %llu\n", __func__,
+			__LINE__, dev->blk_size);
+		return -EINVAL;
+	}
+
+	BUILD_BUG_ON(PS3VFLASH_MAX_DISKS > BITS_PER_LONG);
+	mutex_lock(&ps3vflash_mask_mutex);
+	devidx = find_first_zero_bit(&ps3vflash_mask, PS3VFLASH_MAX_DISKS);
+	if (devidx >= PS3VFLASH_MAX_DISKS) {
+		dev_err(&dev->sbd.core, "%s:%u: Too many disks\n", __func__,
+			__LINE__);
+		mutex_unlock(&ps3vflash_mask_mutex);
+		return -ENOSPC;
+	}
+	__set_bit(devidx, &ps3vflash_mask);
+	mutex_unlock(&ps3vflash_mask_mutex);
+
+	priv = kzalloc(sizeof(*priv) +
+		       dev->num_regions * sizeof(struct gendisk),
+		       GFP_KERNEL);
+	if (!priv) {
+		error = -ENOMEM;
+		goto fail;
+	}
+
+	ps3_system_bus_set_drvdata(_dev, priv);
+	spin_lock_init(&priv->lock);
+
+	dev->bounce_size = BOUNCE_SIZE;
+	dev->bounce_buf = kmalloc(BOUNCE_SIZE, GFP_DMA);
+	if (!dev->bounce_buf) {
+		error = -ENOMEM;
+		goto fail_free_priv;
+	}
+
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++)
+		dev->regions[region_idx].flags = region_flags[region_idx];
+
+	error = ps3stor_setup(dev, ps3vflash_interrupt);
+	if (error)
+		goto fail_free_bounce;
+
+	priv->devidx = devidx;
+
+	queue = blk_init_queue(ps3vflash_request, &priv->lock);
+	if (!queue) {
+		dev_err(&dev->sbd.core, "%s:%u: blk_init_queue failed\n",
+			__func__, __LINE__);
+		error = -ENOMEM;
+		goto fail_teardown;
+	}
+
+	priv->queue = queue;
+	queue->queuedata = dev;
+
+	blk_queue_bounce_limit(queue, BLK_BOUNCE_HIGH);
+
+	blk_queue_max_hw_sectors(queue, dev->bounce_size >> 9);
+	blk_queue_segment_boundary(queue, -1UL);
+	blk_queue_dma_alignment(queue, dev->blk_size-1);
+	blk_queue_logical_block_size(queue, dev->blk_size);
+
+	blk_queue_flush(queue, REQ_FLUSH);
+
+	blk_queue_max_segments(queue, -1);
+	blk_queue_max_segment_size(queue, dev->bounce_size);
+
+	if (test_bit(0, &dev->accessible_regions) == 0) {
+		raw_capacity = 0;
+		for (region_idx = 0; region_idx < dev->num_regions;
+		     region_idx++)
+			if (test_bit(region_idx, &dev->accessible_regions))
+				raw_capacity += dev->regions[0].size;
+	} else {
+		raw_capacity = dev->regions[0].size;
+	}
+
+	dev_info(&dev->sbd.core, "%llu MiB\n", raw_capacity >> 11);
+
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++) {
+		if (test_bit(region_idx, &dev->accessible_regions) == 0)
+			continue;
+
+		gendisk = alloc_disk(PS3VFLASH_MINORS *
+				     PS3_STORAGE_MAX_REGIONS);
+		if (!gendisk) {
+			dev_err(&dev->sbd.core, "%s:%u: alloc_disk failed\n",
+				__func__, __LINE__);
+			error = -ENOMEM;
+			goto fail_cleanup_queue;
+		}
+
+		priv->gendisk[region_idx] = gendisk;
+		gendisk->major = ps3vflash_major;
+		gendisk->first_minor = devidx * PS3VFLASH_MINORS + region_idx;
+		gendisk->fops = &ps3vflash_fops;
+		gendisk->queue = queue;
+		gendisk->private_data = dev;
+		gendisk->driverfs_dev = &dev->sbd.core;
+
+		snprintf(gendisk->disk_name, sizeof(gendisk->disk_name),
+			 PS3VFLASH_NAME, '1' + devidx, 'a' + region_idx);
+
+		priv->blocking_factor = dev->blk_size >> 9;
+		set_capacity(gendisk, dev->regions[region_idx].size *
+				      priv->blocking_factor);
+
+		dev_info(&dev->sbd.core,
+			 "%s (%lu MiB region)\n",
+			 gendisk->disk_name, get_capacity(gendisk) >> 11);
+
+		add_disk(gendisk);
+	}
+
+	return 0;
+
+fail_cleanup_queue:
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++)
+		if (priv->gendisk[region_idx])
+			del_gendisk(priv->gendisk[region_idx]);
+
+	blk_cleanup_queue(queue);
+fail_teardown:
+	ps3stor_teardown(dev);
+fail_free_bounce:
+	kfree(dev->bounce_buf);
+fail_free_priv:
+	kfree(priv);
+	ps3_system_bus_set_drvdata(_dev, NULL);
+fail:
+	mutex_lock(&ps3vflash_mask_mutex);
+	__clear_bit(devidx, &ps3vflash_mask);
+	mutex_unlock(&ps3vflash_mask_mutex);
+	return error;
+}
+
+static int ps3vflash_remove(struct ps3_system_bus_device *_dev)
+{
+	struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
+	struct ps3vflash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
+	unsigned int region_idx;
+
+	mutex_lock(&ps3vflash_mask_mutex);
+	__clear_bit(priv->devidx, &ps3vflash_mask);
+	mutex_unlock(&ps3vflash_mask_mutex);
+
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++) {
+		if (test_bit(region_idx, &dev->accessible_regions) == 0)
+			continue;
+
+		del_gendisk(priv->gendisk[region_idx]);
+	}
+
+	blk_cleanup_queue(priv->queue);
+
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++) {
+		if (test_bit(region_idx, &dev->accessible_regions) == 0)
+			continue;
+
+		put_disk(priv->gendisk[region_idx]);
+	}
+
+	ps3stor_teardown(dev);
+	kfree(dev->bounce_buf);
+	kfree(priv);
+	ps3_system_bus_set_drvdata(_dev, NULL);
+	return 0;
+}
+
+static struct ps3_system_bus_driver ps3vflash = {
+	.match_id	= PS3_MATCH_ID_STOR_FLASH,
+	.core.name	= DEVICE_NAME,
+	.core.owner	= THIS_MODULE,
+	.probe		= ps3vflash_probe,
+	.remove		= ps3vflash_remove,
+	.shutdown	= ps3vflash_remove,
+};
+
+
+static int __init ps3vflash_init(void)
+{
+	int error;
+
+	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+		return -ENODEV;
+
+	if (ps3_get_ss_laid() == PS3_SS_LAID_OTHEROS)
+		return -ENODEV;
+
+	error = register_blkdev(0, DEVICE_NAME);
+	if (error <= 0) {
+		printk(KERN_ERR "%s:%u: register_blkdev failed %d\n", __func__,
+		       __LINE__, error);
+		return error;
+	}
+	ps3vflash_major = error;
+
+	pr_info("%s:%u: registered block device major %d\n", __func__,
+		__LINE__, ps3vflash_major);
+
+	error = ps3_system_bus_driver_register(&ps3vflash);
+	if (error)
+		unregister_blkdev(ps3vflash_major, DEVICE_NAME);
+
+	return error;
+}
+
+static void __exit ps3vflash_exit(void)
+{
+	ps3_system_bus_driver_unregister(&ps3vflash);
+	unregister_blkdev(ps3vflash_major, DEVICE_NAME);
+}
+
+module_init(ps3vflash_init);
+module_exit(ps3vflash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PS3 VFLASH Storage Driver");
+MODULE_AUTHOR("Andre Heider");
+MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_FLASH);
-- 
1.7.5.4

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

* [PATCH 15/15] ps3: Add a NOR FLASH driver for PS3s without NAND
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (13 preceding siblings ...)
  2011-08-01 20:03 ` [PATCH 14/15] ps3: Add a vflash driver for lpars other than OtherOS Andre Heider
@ 2011-08-01 20:03 ` Andre Heider
  2011-08-03 22:23 ` [PATCH 00/15] ps3: Support more than the OtherOS lpar Geoff Levand
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:03 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

A gendisk for each accessible region is created, and a default set
of region flags is provided - overwritable via a module param array.

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/include/asm/ps3.h           |    2 +
 arch/powerpc/platforms/ps3/Kconfig       |   15 +
 arch/powerpc/platforms/ps3/device-init.c |    7 +
 arch/powerpc/platforms/ps3/platform.h    |    1 +
 arch/powerpc/platforms/ps3/system-bus.c  |    2 +
 drivers/block/Makefile                   |    1 +
 drivers/block/ps3nflash.c                |  473 ++++++++++++++++++++++++++++++
 7 files changed, 501 insertions(+), 0 deletions(-)
 create mode 100644 drivers/block/ps3nflash.c

diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
index 136354a..fe84231 100644
--- a/arch/powerpc/include/asm/ps3.h
+++ b/arch/powerpc/include/asm/ps3.h
@@ -333,6 +333,7 @@ enum ps3_match_id {
 	PS3_MATCH_ID_SOUND		= 9,
 	PS3_MATCH_ID_GPU		= 10,
 	PS3_MATCH_ID_LPM		= 11,
+	PS3_MATCH_ID_STOR_NFLASH	= 12,
 };
 
 enum ps3_match_sub_id {
@@ -352,6 +353,7 @@ enum ps3_match_sub_id {
 #define PS3_MODULE_ALIAS_GPU_FB		"ps3:10:1"
 #define PS3_MODULE_ALIAS_GPU_RAMDISK	"ps3:10:2"
 #define PS3_MODULE_ALIAS_LPM		"ps3:11:0"
+#define PS3_MODULE_ALIAS_STOR_NFLASH	"ps3:12:0"
 
 enum ps3_system_bus_device_type {
 	PS3_DEVICE_TYPE_IOC0 = 1,
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index f8d865c..9e1f841 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -142,6 +142,21 @@ config PS3_VFLASH
 	  select PS3_FLASH above to add support for FLASH ROM for the
 	  OtherOS LPAR.
 
+config PS3_NFLASH
+	tristate "PS3 NFLASH Storage Driver"
+	depends on PPC_PS3 && BLOCK && EXPERT
+	select PS3_STORAGE
+	help
+	  Include support for the PS3 NOR FLASH Storage.
+
+	  This support is required to access the PS3 NOR flash, which can be
+	  found on SKU models starting around October 2007.
+
+	  The NOR flash contains essential boot loaders. Damaging this area
+	  will render the console unbootable.
+
+	  If unsure, say N.
+
 config PS3_VRAM
 	tristate "PS3 Video RAM Storage Driver"
 	depends on FB_PS3=y && BLOCK && m
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c
index 7a3dbf8..c2fbe33 100644
--- a/arch/powerpc/platforms/ps3/device-init.c
+++ b/arch/powerpc/platforms/ps3/device-init.c
@@ -601,6 +601,13 @@ static int ps3_setup_dynamic_device(const struct ps3_repository_device *repo)
 				 __func__, __LINE__);
 		break;
 
+	case PS3_DEV_TYPE_STOR_NFLASH:
+		result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_NFLASH);
+		if (result)
+			pr_debug("%s:%u ps3_setup_storage_dev failed\n",
+				 __func__, __LINE__);
+		break;
+
 	default:
 		result = 0;
 		pr_debug("%s:%u: unsupported dev_type %u\n", __func__, __LINE__,
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index 1ba15b8..94b5048 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -87,6 +87,7 @@ enum ps3_dev_type {
 	PS3_DEV_TYPE_STOR_ROM = TYPE_ROM,	/* 5 */
 	PS3_DEV_TYPE_SB_GPIO = 6,
 	PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC,	/* 14 */
+	PS3_DEV_TYPE_STOR_NFLASH = 254,
 };
 
 int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 23083c3..810bbc5 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -174,6 +174,7 @@ int ps3_open_hv_device(struct ps3_system_bus_device *dev)
 	case PS3_MATCH_ID_STOR_DISK:
 	case PS3_MATCH_ID_STOR_ROM:
 	case PS3_MATCH_ID_STOR_FLASH:
+	case PS3_MATCH_ID_STOR_NFLASH:
 		return ps3_open_hv_device_sb(dev);
 
 	case PS3_MATCH_ID_SOUND:
@@ -212,6 +213,7 @@ int ps3_close_hv_device(struct ps3_system_bus_device *dev)
 	case PS3_MATCH_ID_STOR_DISK:
 	case PS3_MATCH_ID_STOR_ROM:
 	case PS3_MATCH_ID_STOR_FLASH:
+	case PS3_MATCH_ID_STOR_NFLASH:
 		return ps3_close_hv_device_sb(dev);
 
 	case PS3_MATCH_ID_SOUND:
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 8b02899..ab2bb06 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_BLK_DEV_FD)	+= floppy.o
 obj-$(CONFIG_AMIGA_FLOPPY)	+= amiflop.o
 obj-$(CONFIG_PS3_DISK)		+= ps3disk.o
 obj-$(CONFIG_PS3_VFLASH)	+= ps3vflash.o
+obj-$(CONFIG_PS3_NFLASH)	+= ps3nflash.o
 obj-$(CONFIG_PS3_VRAM)		+= ps3vram.o
 obj-$(CONFIG_ATARI_FLOPPY)	+= ataflop.o
 obj-$(CONFIG_AMIGA_Z2RAM)	+= z2ram.o
diff --git a/drivers/block/ps3nflash.c b/drivers/block/ps3nflash.c
new file mode 100644
index 0000000..5a7127e
--- /dev/null
+++ b/drivers/block/ps3nflash.c
@@ -0,0 +1,473 @@
+/*
+ * PS3 NOR FLASH Storage Driver
+ *
+ * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/ata.h>
+#include <linux/blkdev.h>
+#include <linux/slab.h>
+
+#include <asm/lv1call.h>
+#include <asm/ps3stor.h>
+#include <asm/firmware.h>
+
+
+#define DEVICE_NAME		"ps3nflash"
+
+#define BOUNCE_SIZE		(64*1024)
+
+#define PS3NFLASH_MAX_DISKS	16
+#define PS3NFLASH_MINORS	16
+
+
+#define PS3NFLASH_NAME		"ps3n%c%c"
+
+
+static unsigned int region_flags[] = {
+	PS3_STORAGE_FLAG_SKIP_ACL,
+	PS3_STORAGE_FLAG_SKIP_ACL,
+	PS3_STORAGE_FLAG_SKIP_ACL,
+	PS3_STORAGE_FLAG_SKIP_ACL,
+	PS3_STORAGE_FLAG_DEFAULT,
+	PS3_STORAGE_FLAG_DEFAULT,
+	PS3_STORAGE_FLAG_DEFAULT,
+	PS3_STORAGE_FLAG_DEFAULT,
+};
+module_param_array(region_flags, uint, NULL, S_IRUGO);
+MODULE_PARM_DESC(region_flags, "Region flags");
+
+struct ps3nflash_private {
+	spinlock_t lock;		/* Request queue spinlock */
+	struct request_queue *queue;
+	unsigned int blocking_factor;
+	struct request *req;
+	unsigned int devidx;
+	struct gendisk *gendisk[0];	/* Must be last */
+};
+
+static int ps3nflash_major;
+
+
+static const struct block_device_operations ps3nflash_fops = {
+	.owner		= THIS_MODULE,
+};
+
+
+static void ps3nflash_scatter_gather(struct ps3_storage_device *dev,
+				     struct request *req, int gather)
+{
+	unsigned int offset = 0;
+	struct req_iterator iter;
+	struct bio_vec *bvec;
+	unsigned int i = 0;
+	size_t size;
+	void *buf;
+
+	rq_for_each_segment(bvec, req, iter) {
+		unsigned long flags;
+		dev_dbg(&dev->sbd.core,
+			"%s:%u: bio %u: %u segs %u sectors from %lu\n",
+			__func__, __LINE__, i, bio_segments(iter.bio),
+			bio_sectors(iter.bio), iter.bio->bi_sector);
+
+		size = bvec->bv_len;
+		buf = bvec_kmap_irq(bvec, &flags);
+		if (gather)
+			memcpy(dev->bounce_buf+offset, buf, size);
+		else
+			memcpy(buf, dev->bounce_buf+offset, size);
+		offset += size;
+		flush_kernel_dcache_page(bvec->bv_page);
+		bvec_kunmap_irq(buf, &flags);
+		i++;
+	}
+}
+
+static int ps3nflash_submit_request_sg(struct ps3_storage_device *dev,
+				       struct request *req)
+{
+	struct ps3nflash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
+	int write = rq_data_dir(req), res;
+	const char *op = write ? "write" : "read";
+	u64 start_sector, sectors;
+	unsigned int region_idx = MINOR(disk_devt(req->rq_disk)) &
+				  (PS3NFLASH_MINORS - 1);
+	unsigned int region_id = dev->regions[region_idx].id;
+	u64 flags = dev->regions[region_idx].flags;
+
+#ifdef DEBUG
+	unsigned int n = 0;
+	struct bio_vec *bv;
+	struct req_iterator iter;
+
+	rq_for_each_segment(bv, req, iter)
+		n++;
+	dev_dbg(&dev->sbd.core,
+		"%s:%u: %s req has %u bvecs for %u sectors\n",
+		__func__, __LINE__, op, n, blk_rq_sectors(req));
+#endif
+
+	start_sector = blk_rq_pos(req) * priv->blocking_factor;
+	sectors = blk_rq_sectors(req) * priv->blocking_factor;
+	dev_dbg(&dev->sbd.core, "%s:%u: %s %llu sectors starting at %llu\n",
+		__func__, __LINE__, op, sectors, start_sector);
+
+	if (write) {
+		ps3nflash_scatter_gather(dev, req, 1);
+
+		res = lv1_storage_write(dev->sbd.dev_id, region_id,
+					start_sector, sectors, flags,
+					dev->bounce_lpar, &dev->tag);
+	} else {
+		res = lv1_storage_read(dev->sbd.dev_id, region_id,
+				       start_sector, sectors, flags,
+				       dev->bounce_lpar, &dev->tag);
+	}
+	if (res) {
+		dev_err(&dev->sbd.core, "%s:%u: %s failed %d\n", __func__,
+			__LINE__, op, res);
+		__blk_end_request_all(req, -EIO);
+		return 0;
+	}
+
+	priv->req = req;
+	return 1;
+}
+
+static void ps3nflash_do_request(struct ps3_storage_device *dev,
+				 struct request_queue *q)
+{
+	struct request *req;
+
+	dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
+
+	while ((req = blk_fetch_request(q))) {
+		if (req->cmd_type == REQ_TYPE_FS) {
+			if (ps3nflash_submit_request_sg(dev, req))
+				break;
+		} else {
+			blk_dump_rq_flags(req, DEVICE_NAME " bad request");
+			__blk_end_request_all(req, -EIO);
+			continue;
+		}
+	}
+}
+
+static void ps3nflash_request(struct request_queue *q)
+{
+	struct ps3_storage_device *dev = q->queuedata;
+	struct ps3nflash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
+
+	if (priv->req) {
+		dev_dbg(&dev->sbd.core, "%s:%u busy\n", __func__, __LINE__);
+		return;
+	}
+
+	ps3nflash_do_request(dev, q);
+}
+
+static irqreturn_t ps3nflash_interrupt(int irq, void *data)
+{
+	struct ps3_storage_device *dev = data;
+	struct ps3nflash_private *priv;
+	struct request *req;
+	int res, read, error;
+	u64 tag, status;
+	const char *op;
+
+	res = lv1_storage_get_async_status(dev->sbd.dev_id, &tag, &status);
+
+	if (tag != dev->tag)
+		dev_err(&dev->sbd.core,
+			"%s:%u: tag mismatch, got %llx, expected %llx\n",
+			__func__, __LINE__, tag, dev->tag);
+
+	if (res) {
+		dev_err(&dev->sbd.core, "%s:%u: res=%d status=0x%llx\n",
+			__func__, __LINE__, res, status);
+		return IRQ_HANDLED;
+	}
+
+	priv = ps3_system_bus_get_drvdata(&dev->sbd);
+	req = priv->req;
+	if (!req) {
+		dev_dbg(&dev->sbd.core,
+			"%s:%u non-block layer request completed\n", __func__,
+			__LINE__);
+		dev->lv1_status = status;
+		complete(&dev->done);
+		return IRQ_HANDLED;
+	}
+
+	read = !rq_data_dir(req);
+	op = read ? "read" : "write";
+
+	if (status) {
+		dev_dbg(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__,
+			__LINE__, op, status);
+		error = -EIO;
+	} else {
+		dev_dbg(&dev->sbd.core, "%s:%u: %s completed\n", __func__,
+			__LINE__, op);
+		error = 0;
+		if (read)
+			ps3nflash_scatter_gather(dev, req, 0);
+	}
+
+	spin_lock(&priv->lock);
+	__blk_end_request_all(req, error);
+	priv->req = NULL;
+	ps3nflash_do_request(dev, priv->queue);
+	spin_unlock(&priv->lock);
+
+	return IRQ_HANDLED;
+}
+
+static unsigned long ps3nflash_mask;
+
+static DEFINE_MUTEX(ps3nflash_mask_mutex);
+
+static int __devinit ps3nflash_probe(struct ps3_system_bus_device *_dev)
+{
+	struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
+	struct ps3nflash_private *priv;
+	int error;
+	unsigned int devidx;
+	struct request_queue *queue;
+	struct gendisk *gendisk;
+	u64 raw_capacity;
+	unsigned int region_idx;
+
+	if (dev->blk_size < 512) {
+		dev_err(&dev->sbd.core,
+			"%s:%u: cannot handle block size %llu\n", __func__,
+			__LINE__, dev->blk_size);
+		return -EINVAL;
+	}
+
+	BUILD_BUG_ON(PS3NFLASH_MAX_DISKS > BITS_PER_LONG);
+	mutex_lock(&ps3nflash_mask_mutex);
+	devidx = find_first_zero_bit(&ps3nflash_mask, PS3NFLASH_MAX_DISKS);
+	if (devidx >= PS3NFLASH_MAX_DISKS) {
+		dev_err(&dev->sbd.core, "%s:%u: Too many disks\n", __func__,
+			__LINE__);
+		mutex_unlock(&ps3nflash_mask_mutex);
+		return -ENOSPC;
+	}
+	__set_bit(devidx, &ps3nflash_mask);
+	mutex_unlock(&ps3nflash_mask_mutex);
+
+	priv = kzalloc(sizeof(*priv) +
+		       dev->num_regions * sizeof(struct gendisk),
+		       GFP_KERNEL);
+	if (!priv) {
+		error = -ENOMEM;
+		goto fail;
+	}
+
+	ps3_system_bus_set_drvdata(_dev, priv);
+	spin_lock_init(&priv->lock);
+
+	dev->bounce_size = BOUNCE_SIZE;
+	dev->bounce_buf = kmalloc(BOUNCE_SIZE, GFP_DMA);
+	if (!dev->bounce_buf) {
+		error = -ENOMEM;
+		goto fail_free_priv;
+	}
+
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++)
+		dev->regions[region_idx].flags = region_flags[region_idx];
+
+	error = ps3stor_setup(dev, ps3nflash_interrupt);
+	if (error)
+		goto fail_free_bounce;
+
+	priv->devidx = devidx;
+
+	queue = blk_init_queue(ps3nflash_request, &priv->lock);
+	if (!queue) {
+		dev_err(&dev->sbd.core, "%s:%u: blk_init_queue failed\n",
+			__func__, __LINE__);
+		error = -ENOMEM;
+		goto fail_teardown;
+	}
+
+	priv->queue = queue;
+	queue->queuedata = dev;
+
+	blk_queue_bounce_limit(queue, BLK_BOUNCE_HIGH);
+
+	blk_queue_max_hw_sectors(queue, dev->bounce_size >> 9);
+	blk_queue_segment_boundary(queue, -1UL);
+	blk_queue_dma_alignment(queue, dev->blk_size-1);
+	blk_queue_logical_block_size(queue, dev->blk_size);
+
+	blk_queue_flush(queue, REQ_FLUSH);
+
+	blk_queue_max_segments(queue, -1);
+	blk_queue_max_segment_size(queue, dev->bounce_size);
+
+	if (test_bit(0, &dev->accessible_regions) == 0) {
+		raw_capacity = 0;
+		for (region_idx = 0; region_idx < dev->num_regions;
+		     region_idx++)
+			if (test_bit(region_idx, &dev->accessible_regions))
+				raw_capacity += dev->regions[0].size;
+	} else {
+		raw_capacity = dev->regions[0].size;
+	}
+
+	dev_info(&dev->sbd.core, "%llu MiB\n", raw_capacity >> 11);
+
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++) {
+		if (test_bit(region_idx, &dev->accessible_regions) == 0)
+			continue;
+
+		gendisk = alloc_disk(PS3NFLASH_MINORS *
+				     PS3_STORAGE_MAX_REGIONS);
+		if (!gendisk) {
+			dev_err(&dev->sbd.core, "%s:%u: alloc_disk failed\n",
+				__func__, __LINE__);
+			error = -ENOMEM;
+			goto fail_cleanup_queue;
+		}
+
+		priv->gendisk[region_idx] = gendisk;
+		gendisk->major = ps3nflash_major;
+		gendisk->first_minor = devidx * PS3NFLASH_MINORS + region_idx;
+		gendisk->fops = &ps3nflash_fops;
+		gendisk->queue = queue;
+		gendisk->private_data = dev;
+		gendisk->driverfs_dev = &dev->sbd.core;
+
+		snprintf(gendisk->disk_name, sizeof(gendisk->disk_name),
+			 PS3NFLASH_NAME, '1' + devidx, 'a' + region_idx);
+
+		priv->blocking_factor = dev->blk_size >> 9;
+		set_capacity(gendisk, dev->regions[region_idx].size *
+				      priv->blocking_factor);
+
+		dev_info(&dev->sbd.core,
+			 "%s (%lu MiB region)\n",
+			 gendisk->disk_name, get_capacity(gendisk) >> 11);
+
+		add_disk(gendisk);
+	}
+
+	return 0;
+
+fail_cleanup_queue:
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++)
+		if (priv->gendisk[region_idx])
+			del_gendisk(priv->gendisk[region_idx]);
+
+	blk_cleanup_queue(queue);
+fail_teardown:
+	ps3stor_teardown(dev);
+fail_free_bounce:
+	kfree(dev->bounce_buf);
+fail_free_priv:
+	kfree(priv);
+	ps3_system_bus_set_drvdata(_dev, NULL);
+fail:
+	mutex_lock(&ps3nflash_mask_mutex);
+	__clear_bit(devidx, &ps3nflash_mask);
+	mutex_unlock(&ps3nflash_mask_mutex);
+	return error;
+}
+
+static int ps3nflash_remove(struct ps3_system_bus_device *_dev)
+{
+	struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
+	struct ps3nflash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
+	unsigned int region_idx;
+
+	mutex_lock(&ps3nflash_mask_mutex);
+	__clear_bit(priv->devidx, &ps3nflash_mask);
+	mutex_unlock(&ps3nflash_mask_mutex);
+
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++) {
+		if (test_bit(region_idx, &dev->accessible_regions) == 0)
+			continue;
+
+		del_gendisk(priv->gendisk[region_idx]);
+	}
+
+	blk_cleanup_queue(priv->queue);
+
+	for (region_idx = 0; region_idx < dev->num_regions; region_idx++) {
+		if (test_bit(region_idx, &dev->accessible_regions) == 0)
+			continue;
+
+		put_disk(priv->gendisk[region_idx]);
+	}
+
+	ps3stor_teardown(dev);
+	kfree(dev->bounce_buf);
+	kfree(priv);
+	ps3_system_bus_set_drvdata(_dev, NULL);
+	return 0;
+}
+
+static struct ps3_system_bus_driver ps3nflash = {
+	.match_id	= PS3_MATCH_ID_STOR_NFLASH,
+	.core.name	= DEVICE_NAME,
+	.core.owner	= THIS_MODULE,
+	.probe		= ps3nflash_probe,
+	.remove		= ps3nflash_remove,
+	.shutdown	= ps3nflash_remove,
+};
+
+
+static int __init ps3nflash_init(void)
+{
+	int error;
+
+	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+		return -ENODEV;
+
+	error = register_blkdev(0, DEVICE_NAME);
+	if (error <= 0) {
+		printk(KERN_ERR "%s:%u: register_blkdev failed %d\n", __func__,
+		       __LINE__, error);
+		return error;
+	}
+	ps3nflash_major = error;
+
+	pr_info("%s:%u: registered block device major %d\n", __func__,
+		__LINE__, ps3nflash_major);
+
+	error = ps3_system_bus_driver_register(&ps3nflash);
+	if (error)
+		unregister_blkdev(ps3nflash_major, DEVICE_NAME);
+
+	return error;
+}
+
+static void __exit ps3nflash_exit(void)
+{
+	ps3_system_bus_driver_unregister(&ps3nflash);
+	unregister_blkdev(ps3nflash_major, DEVICE_NAME);
+}
+
+module_init(ps3nflash_init);
+module_exit(ps3nflash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("PS3 NOR FLASH Storage Driver");
+MODULE_AUTHOR("Andre Heider");
+MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_NFLASH);
-- 
1.7.5.4

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

* Re: [Cbe-oss-dev] [PATCH 06/15] ps3flash: Fix region align checks
  2011-08-01 20:02 ` [PATCH 06/15] ps3flash: Fix region align checks Andre Heider
@ 2011-08-01 20:29   ` Geert Uytterhoeven
  2011-08-01 20:56     ` Andre Heider
  0 siblings, 1 reply; 70+ messages in thread
From: Geert Uytterhoeven @ 2011-08-01 20:29 UTC (permalink / raw)
  To: Andre Heider; +Cc: Geoff Levand, cbe-oss-dev, Hector Martin, linuxppc-dev

On Mon, Aug 1, 2011 at 22:02, Andre Heider <a.heider@gmail.com> wrote:
> The region fields used by the align checks are set in
> ps3stor_setup(), so move those after that call.

Are you sure?
Aren't they set in
arch/powerpc/platforms/ps3/device-init.c:ps3_setup_storage_dev()?

> Signed-off-by: Andre Heider <a.heider@gmail.com>
> ---
> =C2=A0drivers/char/ps3flash.c | =C2=A0 30 +++++++++++++++---------------
> =C2=A01 files changed, 15 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
> index 85c004a..69c734a 100644
> --- a/drivers/char/ps3flash.c
> +++ b/drivers/char/ps3flash.c
> @@ -360,21 +360,6 @@ static int __devinit ps3flash_probe(struct ps3_syste=
m_bus_device *_dev)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0int error;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned long tmp;
>
> - =C2=A0 =C2=A0 =C2=A0 tmp =3D dev->regions[dev->region_idx].start*dev->b=
lk_size;
> - =C2=A0 =C2=A0 =C2=A0 if (tmp % FLASH_BLOCK_SIZE) {
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dev_err(&dev->sbd.core=
,
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 "%s:%u region start %lu is not aligned\n", __func__,
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 __LINE__, tmp);
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -EINVAL;
> - =C2=A0 =C2=A0 =C2=A0 }
> - =C2=A0 =C2=A0 =C2=A0 tmp =3D dev->regions[dev->region_idx].size*dev->bl=
k_size;
> - =C2=A0 =C2=A0 =C2=A0 if (tmp % FLASH_BLOCK_SIZE) {
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dev_err(&dev->sbd.core=
,
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 "%s:%u region size %lu is not aligned\n", __func__,
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 __LINE__, tmp);
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -EINVAL;
> - =C2=A0 =C2=A0 =C2=A0 }
> -
> =C2=A0 =C2=A0 =C2=A0 =C2=A0/* use static buffer, kmalloc cannot allocate =
256 KiB */
> =C2=A0 =C2=A0 =C2=A0 =C2=A0if (!ps3flash_bounce_buffer.address)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -ENODEV;
> @@ -405,6 +390,21 @@ static int __devinit ps3flash_probe(struct ps3_syste=
m_bus_device *_dev)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0if (error)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto fail_free_pri=
v;
>
> + =C2=A0 =C2=A0 =C2=A0 tmp =3D dev->regions[dev->region_idx].start*dev->b=
lk_size;
> + =C2=A0 =C2=A0 =C2=A0 if (tmp % FLASH_BLOCK_SIZE) {
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dev_err(&dev->sbd.core=
,
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 "%s:%u region start %lu is not aligned\n", __func__,
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 __LINE__, tmp);
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -EINVAL;
> + =C2=A0 =C2=A0 =C2=A0 }
> + =C2=A0 =C2=A0 =C2=A0 tmp =3D dev->regions[dev->region_idx].size*dev->bl=
k_size;
> + =C2=A0 =C2=A0 =C2=A0 if (tmp % FLASH_BLOCK_SIZE) {
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dev_err(&dev->sbd.core=
,
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 "%s:%u region size %lu is not aligned\n", __func__,
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 __LINE__, tmp);
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -EINVAL;
> + =C2=A0 =C2=A0 =C2=A0 }
> +
> =C2=A0 =C2=A0 =C2=A0 =C2=A0ps3flash_misc.parent =3D &dev->sbd.core;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0error =3D misc_register(&ps3flash_misc);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0if (error) {

Gr{oetje,eeting}s,

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k=
.org

In personal conversations with technical people, I call myself a hacker. Bu=
t
when I'm talking to journalists I just say "programmer" or something like t=
hat.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0 =C2=A0=C2=A0 -- Linus Torvalds

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

* Re: [Cbe-oss-dev] [PATCH 09/15] ps3: Limit the number of regions per storage device
  2011-08-01 20:03 ` [PATCH 09/15] ps3: Limit the number of regions per storage device Andre Heider
@ 2011-08-01 20:30   ` Geert Uytterhoeven
  2011-08-01 20:58     ` Andre Heider
  0 siblings, 1 reply; 70+ messages in thread
From: Geert Uytterhoeven @ 2011-08-01 20:30 UTC (permalink / raw)
  To: Andre Heider; +Cc: Geoff Levand, cbe-oss-dev, Hector Martin, linuxppc-dev

On Mon, Aug 1, 2011 at 22:03, Andre Heider <a.heider@gmail.com> wrote:
> There can be only 8 regions, add a sanity check

Why can there be only 8 regions?

> Signed-off-by: Andre Heider <a.heider@gmail.com>
> ---
> =C2=A0arch/powerpc/include/asm/ps3stor.h =C2=A0 =C2=A0 =C2=A0 | =C2=A0 =
=C2=A01 +
> =C2=A0arch/powerpc/platforms/ps3/device-init.c | =C2=A0 =C2=A08 ++++++++
> =C2=A02 files changed, 9 insertions(+), 0 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/ps3stor.h b/arch/powerpc/include/as=
m/ps3stor.h
> index 6fcaf71..d51e53c 100644
> --- a/arch/powerpc/include/asm/ps3stor.h
> +++ b/arch/powerpc/include/asm/ps3stor.h
> @@ -25,6 +25,7 @@
>
> =C2=A0#include <asm/ps3.h>
>
> +#define PS3_STORAGE_MAX_REGIONS =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0(8)
>
> =C2=A0struct ps3_storage_region {
> =C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned int id;
> diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/plat=
forms/ps3/device-init.c
> index 6c4b583..830d741 100644
> --- a/arch/powerpc/platforms/ps3/device-init.c
> +++ b/arch/powerpc/platforms/ps3/device-init.c
> @@ -349,6 +349,14 @@ static int ps3_setup_storage_dev(const struct ps3_re=
pository_device *repo,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -ENODEV;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0}
>
> + =C2=A0 =C2=A0 =C2=A0 if (num_regions > PS3_STORAGE_MAX_REGIONS) {
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pr_warning("%s:%u: dev=
ice %u:%u reported %u regions, "
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0"limiting to %u\n", __func__, __LINE__,
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0num_regions, repo->bus_index, repo->dev_index,
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0PS3_STORAGE_MAX_REGIONS);
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 num_regions =3D PS3_ST=
ORAGE_MAX_REGIONS;
> + =C2=A0 =C2=A0 =C2=A0 }
> +
> =C2=A0 =C2=A0 =C2=A0 =C2=A0pr_debug("%s:%u: (%u:%u:%u): port %llu blk_siz=
e %llu num_blocks %llu "
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "num_regions %u\n=
", __func__, __LINE__, repo->bus_index,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 repo->dev_index, =
repo->dev_type, port, blk_size, num_blocks,

Gr{oetje,eeting}s,

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k=
.org

In personal conversations with technical people, I call myself a hacker. Bu=
t
when I'm talking to journalists I just say "programmer" or something like t=
hat.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0 =C2=A0=C2=A0 -- Linus Torvalds

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

* Re: [PATCH 10/15] ps3stor_lib: Add support for multiple regions
  2011-08-01 20:03 ` [PATCH 10/15] ps3stor_lib: Add support for multiple regions Andre Heider
@ 2011-08-01 20:35   ` Geert Uytterhoeven
  2011-08-01 21:01     ` Andre Heider
  0 siblings, 1 reply; 70+ messages in thread
From: Geert Uytterhoeven @ 2011-08-01 20:35 UTC (permalink / raw)
  To: Andre Heider; +Cc: Geoff Levand, cbe-oss-dev, Hector Martin, linuxppc-dev

On Mon, Aug 1, 2011 at 22:03, Andre Heider <a.heider@gmail.com> wrote:
> Users (ps3disk, ps3flash and ps3rom) retain the old behavior. That is:
> they still only provide access to the first accessible region.
>
> Signed-off-by: Andre Heider <a.heider@gmail.com>
> ---
> =C2=A0arch/powerpc/include/asm/ps3stor.h | =C2=A0 =C2=A04 ++--
> =C2=A0drivers/block/ps3disk.c =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0| =
=C2=A0 15 +++++++++++++--
> =C2=A0drivers/char/ps3flash.c =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0| =
=C2=A0 23 +++++++++++++++++------
> =C2=A0drivers/ps3/ps3stor_lib.c =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0| =C2=
=A0 25 ++++++++++++-------------
> =C2=A0drivers/scsi/ps3rom.c =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0| =C2=A0 11 +++++++----
> =C2=A05 files changed, 51 insertions(+), 27 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/ps3stor.h b/arch/powerpc/include/as=
m/ps3stor.h
> index d51e53c..9871c05 100644
> --- a/arch/powerpc/include/asm/ps3stor.h
> +++ b/arch/powerpc/include/asm/ps3stor.h
> @@ -51,7 +51,6 @@ struct ps3_storage_device {
>
> =C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned int num_regions;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned long accessible_regions;
> - =C2=A0 =C2=A0 =C2=A0 unsigned int region_idx; =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* first accessible region */
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct ps3_storage_region regions[0]; =C2=A0 /=
* Must be last */
> =C2=A0};
>
> @@ -63,7 +62,8 @@ static inline struct ps3_storage_device *to_ps3_storage=
_device(struct device *de
> =C2=A0extern int ps3stor_setup(struct ps3_storage_device *dev,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 irq_handler_t handler);
> =C2=A0extern void ps3stor_teardown(struct ps3_storage_device *dev);
> -extern u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, u6=
4 lpar,
> +extern u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev,
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 unsigned int region=
_idx, u64 lpar,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0u64 start_sector=
, u64 sectors,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0int write);
> =C2=A0extern u64 ps3stor_send_command(struct ps3_storage_device *dev, u64=
 cmd,
> diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
> index 8e1ce2e..96e00ff 100644
> --- a/drivers/block/ps3disk.c
> +++ b/drivers/block/ps3disk.c
> @@ -42,6 +42,7 @@ struct ps3disk_private {
> =C2=A0 =C2=A0 =C2=A0 =C2=A0spinlock_t lock; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Request queue spinlock */
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct request_queue *queue;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct gendisk *gendisk;
> + =C2=A0 =C2=A0 =C2=A0 unsigned int region_idx; =C2=A0 =C2=A0 =C2=A0 =C2=
=A0/* first accessible region */
> =C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned int blocking_factor;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct request *req;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0u64 raw_capacity;
> @@ -125,7 +126,7 @@ static int ps3disk_submit_request_sg(struct ps3_stora=
ge_device *dev,
> =C2=A0 =C2=A0 =C2=A0 =C2=A0int write =3D rq_data_dir(req), res;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0const char *op =3D write ? "write" : "read";
> =C2=A0 =C2=A0 =C2=A0 =C2=A0u64 start_sector, sectors;
> - =C2=A0 =C2=A0 =C2=A0 unsigned int region_id =3D dev->regions[dev->regio=
n_idx].id;
> + =C2=A0 =C2=A0 =C2=A0 unsigned int region_id =3D dev->regions[priv->regi=
on_idx].id;
>
> =C2=A0#ifdef DEBUG
> =C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned int n =3D 0;
> @@ -408,6 +409,7 @@ static int __devinit ps3disk_probe(struct ps3_system_=
bus_device *_dev)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned int devidx;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct request_queue *queue;
> =C2=A0 =C2=A0 =C2=A0 =C2=A0struct gendisk *gendisk;
> + =C2=A0 =C2=A0 =C2=A0 unsigned int region_idx;
>
> =C2=A0 =C2=A0 =C2=A0 =C2=A0if (dev->blk_size < 512) {
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0dev_err(&dev->sbd.=
core,
> @@ -482,6 +484,14 @@ static int __devinit ps3disk_probe(struct ps3_system=
_bus_device *_dev)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0}
>
> =C2=A0 =C2=A0 =C2=A0 =C2=A0priv->gendisk =3D gendisk;
> +
> + =C2=A0 =C2=A0 =C2=A0 /* find first accessible region */
> + =C2=A0 =C2=A0 =C2=A0 for (region_idx =3D 0; region_idx < dev->num_regio=
ns; region_idx++)
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (test_bit(region_id=
x, &dev->accessible_regions)) {
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 priv->region_idx =3D region_idx;
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 break;
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
> +

Why not

priv->region_idx =3D __ffs(dev->accessible_regions);

like the original code in ps3stor_probe_access() used? Cfr. the code
you removed:

> diff --git a/drivers/ps3/ps3stor_lib.c b/drivers/ps3/ps3stor_lib.c
> index af0afa1..5bbc023 100644
> --- a/drivers/ps3/ps3stor_lib.c
> +++ b/drivers/ps3/ps3stor_lib.c
> @@ -124,15 +128,8 @@ static int ps3stor_probe_access(struct ps3_storage_d=
evice *dev)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0n =3D hweight_long(dev->accessible_regions);
> =C2=A0 =C2=A0 =C2=A0 =C2=A0if (n > 1)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0dev_info(&dev->sbd=
.core,
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0"%s:%u: %lu accessible regions found. Only the first "
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0"one will be used\n",
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0"%s:%u: %lu accessible regions found\n",
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 __func__, __LINE__, n);
> - =C2=A0 =C2=A0 =C2=A0 dev->region_idx =3D __ffs(dev->accessible_regions)=
;
> - =C2=A0 =C2=A0 =C2=A0 dev_info(&dev->sbd.core,
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"First accessibl=
e region has index %u start %llu size %llu\n",
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0dev->region_idx,=
 dev->regions[dev->region_idx].start,
> - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0dev->regions[dev=
->region_idx].size);
> -
> =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;
> =C2=A0}
>

Same in the other drivers.

Gr{oetje,eeting}s,

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k=
.org

In personal conversations with technical people, I call myself a hacker. Bu=
t
when I'm talking to journalists I just say "programmer" or something like t=
hat.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0 =C2=A0=C2=A0 -- Linus Torvalds

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

* Re: [Cbe-oss-dev] [PATCH 06/15] ps3flash: Fix region align checks
  2011-08-01 20:29   ` [Cbe-oss-dev] " Geert Uytterhoeven
@ 2011-08-01 20:56     ` Andre Heider
  2011-08-01 21:00       ` Geert Uytterhoeven
  0 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:56 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Geoff Levand, cbe-oss-dev, Hector Martin, linuxppc-dev

On Mon, Aug 1, 2011 at 10:29 PM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
> On Mon, Aug 1, 2011 at 22:02, Andre Heider <a.heider@gmail.com> wrote:
>> The region fields used by the align checks are set in
>> ps3stor_setup(), so move those after that call.
>
> Are you sure?
> Aren't they set in
> arch/powerpc/platforms/ps3/device-init.c:ps3_setup_storage_dev()?

Hm right, unfortunate commit message... :)
dev->region_idx is set in ps3stor_probe_access(), which is called from
ps3stor_setup().
So the code always checked the first region, where it should check the
one beeing used.

Will fix the commit message.

Thanks

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

* Re: [Cbe-oss-dev] [PATCH 09/15] ps3: Limit the number of regions per storage device
  2011-08-01 20:30   ` [Cbe-oss-dev] " Geert Uytterhoeven
@ 2011-08-01 20:58     ` Andre Heider
  2011-08-06 12:28       ` Andre Heider
  0 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-01 20:58 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Geoff Levand, cbe-oss-dev, Hector Martin, linuxppc-dev

On Mon, Aug 1, 2011 at 10:30 PM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
> On Mon, Aug 1, 2011 at 22:03, Andre Heider <a.heider@gmail.com> wrote:
>> There can be only 8 regions, add a sanity check
>
> Why can there be only 8 regions?

I believe lv1 limits it to 8? I might be mistaken here, it mostly is a
check for the patches after this one

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

* Re: [Cbe-oss-dev] [PATCH 06/15] ps3flash: Fix region align checks
  2011-08-01 20:56     ` Andre Heider
@ 2011-08-01 21:00       ` Geert Uytterhoeven
  0 siblings, 0 replies; 70+ messages in thread
From: Geert Uytterhoeven @ 2011-08-01 21:00 UTC (permalink / raw)
  To: Andre Heider; +Cc: Geoff Levand, cbe-oss-dev, Hector Martin, linuxppc-dev

On Mon, Aug 1, 2011 at 22:56, Andre Heider <a.heider@gmail.com> wrote:
> On Mon, Aug 1, 2011 at 10:29 PM, Geert Uytterhoeven
> <geert@linux-m68k.org> wrote:
>> On Mon, Aug 1, 2011 at 22:02, Andre Heider <a.heider@gmail.com> wrote:
>>> The region fields used by the align checks are set in
>>> ps3stor_setup(), so move those after that call.
>>
>> Are you sure?
>> Aren't they set in
>> arch/powerpc/platforms/ps3/device-init.c:ps3_setup_storage_dev()?
>
> Hm right, unfortunate commit message... :)
> dev->region_idx is set in ps3stor_probe_access(), which is called from
> ps3stor_setup().
> So the code always checked the first region, where it should check the
> one beeing used.

IC. You're right. That's indeed a bug.

Gr{oetje,eeting}s,

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k=
.org

In personal conversations with technical people, I call myself a hacker. Bu=
t
when I'm talking to journalists I just say "programmer" or something like t=
hat.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0 =C2=A0=C2=A0 -- Linus Torvalds

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

* Re: [PATCH 10/15] ps3stor_lib: Add support for multiple regions
  2011-08-01 20:35   ` Geert Uytterhoeven
@ 2011-08-01 21:01     ` Andre Heider
  0 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-01 21:01 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Geoff Levand, cbe-oss-dev, Hector Martin, linuxppc-dev

On Mon, Aug 1, 2011 at 10:35 PM, Geert Uytterhoeven
<geert@linux-m68k.org> wrote:
> On Mon, Aug 1, 2011 at 22:03, Andre Heider <a.heider@gmail.com> wrote:
>> =A0 =A0 =A0 =A0priv->gendisk =3D gendisk;
>> +
>> + =A0 =A0 =A0 /* find first accessible region */
>> + =A0 =A0 =A0 for (region_idx =3D 0; region_idx < dev->num_regions; regi=
on_idx++)
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (test_bit(region_idx, &dev->accessible_=
regions)) {
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 priv->region_idx =3D regio=
n_idx;
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
>> +
>
> Why not
>
> priv->region_idx =3D __ffs(dev->accessible_regions);

Right, thanks. Will change that for v2

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

* Re: [PATCH 00/15] ps3: Support more than the OtherOS lpar
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (14 preceding siblings ...)
  2011-08-01 20:03 ` [PATCH 15/15] ps3: Add a NOR FLASH driver for PS3s without NAND Andre Heider
@ 2011-08-03 22:23 ` Geoff Levand
  2011-08-04 16:31   ` Andre Heider
  2011-08-11 12:17 ` [Cbe-oss-dev] " Arnd Bergmann
  2011-08-11 19:31 ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support " Andre Heider
  17 siblings, 1 reply; 70+ messages in thread
From: Geoff Levand @ 2011-08-03 22:23 UTC (permalink / raw)
  To: Andre Heider; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

Hi Andre,

On 08/01/2011 01:02 PM, Andre Heider wrote:
> This series addresses various issues and extends support when running
> in lpars like GameOS. Included are some patches from Hector Martin, which
> I found useful.

Much of this is just general fixups and improvements to the existing PS3
support.  I think you should separate those changes out and work to get
them included, then consider others.  If I give some comment, then
I consider that part worth pursuing at the present time.

I have limited time to review the patches, so it will take me a while to
get through them.

> Patches are based on 2.6.39 since master doesn't boot with smp on my
> console.  I wasn't able to pinpoint the cause so far (not that I tried
> too hard).

I'm looking into this problem, but it will take some time.

-Geoff

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

* Re: [PATCH 02/15] [PS3] Get lv1 high memory region from devtree
  2011-08-01 20:02 ` [PATCH 02/15] [PS3] Get lv1 high memory region from devtree Andre Heider
@ 2011-08-03 22:30   ` Geoff Levand
  2011-08-04  1:19     ` Hector Martin
  0 siblings, 1 reply; 70+ messages in thread
From: Geoff Levand @ 2011-08-03 22:30 UTC (permalink / raw)
  To: Andre Heider; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

On 08/01/2011 01:02 PM, Andre Heider wrote:
> 
> This lets the bootloader preallocate the high lv1 region and pass its
> location to the kernel through the devtree. Thus, it can be used to hold
> the initrd. If the property doesn't exist, the kernel retains the old
> behavior and attempts to allocate the region itself.

With this mechanism how is the address of the initrd passed to the
new kernel, in the DT?

How would a kexec based bootloader work?  If it's kernel were to allocate
high mem and the bootloader program uses the high mem, how could it tell
that kernel not to destroy the region on shutdown?

If arch/powerpc/boot/ps3.c allocated the mem and added a DT entry
then other OSes that don't know about the Linux device tree won't
be able to use that allocated memory.  Other OSes could do a
test to see if the allocation was already done.  Another option
that might work is to write info into the LV1 repository then
have boot code look there for allocated hig mem.

> Signed-off-by: Hector Martin <hector@marcansoft.com>
> [a.heider: Various cleanups to make checkpatch.pl happy]
> Signed-off-by: Andre Heider <a.heider@gmail.com>
> ---
>  arch/powerpc/platforms/ps3/mm.c |   61 +++++++++++++++++++++++++++++++++++++-
>  1 files changed, 59 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
> index c204588..30bb096 100644
> --- a/arch/powerpc/platforms/ps3/mm.c
> +++ b/arch/powerpc/platforms/ps3/mm.c
> @@ -110,6 +110,7 @@ struct map {
>  	u64 htab_size;
>  	struct mem_region rm;
>  	struct mem_region r1;
> +	int destroy_r1;

In the general case we could have multiple high mem
regions, and each could need to be destroyed, so I
think struct mem_region should have a destroy flag.

>  };
>  
>  #define debug_dump_map(x) _debug_dump_map(x, __func__, __LINE__)
> @@ -287,6 +288,49 @@ static void ps3_mm_region_destroy(struct mem_region *r)
>  	}
>  }
>  
> +static int ps3_mm_scan_memory(unsigned long node, const char *uname,
> +			      int depth, void *data)
> +{

Something like 'ps3_mm_dt_scan_highmem() is more descriptive.

> +	struct mem_region *r = data;
> +	void *p;
> +	u64 prop[2];
> +	unsigned long l;
> +	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
> +
> +	if (type == NULL)
> +		return 0;
> +	if (strcmp(type, "memory") != 0)

Should this be 'if (strcmp(type, "memory"))'?

> +		return 0;
> +
> +	p = of_get_flat_dt_prop(node, "sony,lv1-highmem", &l);
> +	if (p == NULL)
> +		return 0;
> +
> +	BUG_ON(l != sizeof(prop));
> +	memcpy(prop, p, sizeof(prop));
> +
> +	r->base = prop[0];
> +	r->size = prop[1];
> +	r->offset = r->base - map.rm.size;
> +
> +	return -1;
> +}
> +
> +static int ps3_mm_get_devtree_highmem(struct mem_region *r)
> +{
> +	r->size = r->base = r->offset = 0;
> +	of_scan_flat_dt(ps3_mm_scan_memory, r);
> +
> +	if (r->base && r->size) {
> +		DBG("%s:%d got high region from devtree: %llxh %llxh\n",
> +		__func__, __LINE__, r->base, r->size);
> +		return 0;
> +	} else {
> +		DBG("%s:%d no high region in devtree...\n", __func__, __LINE__);
> +		return -1;
> +	}
> +}
> +
>  /**
>   * ps3_mm_add_memory - hot add memory
>   */
> @@ -303,6 +347,12 @@ static int __init ps3_mm_add_memory(void)
>  
>  	BUG_ON(!mem_init_done);
>  
> +	if (!map.r1.size) {
> +		DBG("%s:%d: no region 1, not adding memory\n",
> +		    __func__, __LINE__);
> +		return 0;
> +	}

Did you find this to be hit?  Also, in the general case,
there could be more than one high mem region, but I don't
know of any current systems that do.

> +
>  	start_addr = map.rm.size;
>  	start_pfn = start_addr >> PAGE_SHIFT;
>  	nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT;
> @@ -1219,7 +1269,13 @@ void __init ps3_mm_init(void)
>  
>  
>  	/* arrange to do this in ps3_mm_add_memory */
> -	ps3_mm_region_create(&map.r1, map.total - map.rm.size);
> +
> +	if (ps3_mm_get_devtree_highmem(&map.r1) == 0) {
> +		map.destroy_r1 = 0;
> +	} else {

This should be

	if (!ps3_mm_get_devtree_highmem(&map.r1))
		map.destroy_r1 = 0;
	else {

> +		ps3_mm_region_create(&map.r1, map.total - map.rm.size);
> +		map.destroy_r1 = 1;
> +	}
>  
>  	/* correct map.total for the real total amount of memory we use */
>  	map.total = map.rm.size + map.r1.size;
> @@ -1233,5 +1289,6 @@ void __init ps3_mm_init(void)
>  
>  void ps3_mm_shutdown(void)
>  {
> -	ps3_mm_region_destroy(&map.r1);
> +	if (map.destroy_r1)
> +		ps3_mm_region_destroy(&map.r1);
>  }

-Geoff

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

* Re: [PATCH 05/15] ps3: Detect the current lpar environment
  2011-08-01 20:02 ` [PATCH 05/15] ps3: Detect the current lpar environment Andre Heider
@ 2011-08-03 22:31   ` Geoff Levand
  2011-08-04 16:34     ` Andre Heider
  0 siblings, 1 reply; 70+ messages in thread
From: Geoff Levand @ 2011-08-03 22:31 UTC (permalink / raw)
  To: Andre Heider; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

On 08/01/2011 01:02 PM, Andre Heider wrote:
> ---
>  arch/powerpc/include/asm/ps3.h          |    7 +++++++
>  arch/powerpc/platforms/ps3/platform.h   |    4 ++++
>  arch/powerpc/platforms/ps3/repository.c |   19 +++++++++++++++++++
>  arch/powerpc/platforms/ps3/setup.c      |   22 ++++++++++++++++++++++
>  4 files changed, 52 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
> index 7f065e1..136354a 100644
> --- a/arch/powerpc/include/asm/ps3.h
> +++ b/arch/powerpc/include/asm/ps3.h
> @@ -39,6 +39,13 @@ union ps3_firmware_version {
>  void ps3_get_firmware_version(union ps3_firmware_version *v);
>  int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev);
>  
> +enum ps3_ss_laid {
> +	PS3_SS_LAID_GAMEOS = 0x1070000002000001UL,
> +	PS3_SS_LAID_OTHEROS = 0x1080000004000001UL,

Only PS3_SS_LAID_OTHEROS is used for anything outside ps3_setup_arch(),
so I think it makes sense to split this into two patches with one adding
just PS3_SS_LAID_OTHEROS and ps3_get_ss_laid() with a comment that
it adds the ps3_get_ss_laid routine.

> +};
> +
> +enum ps3_ss_laid ps3_get_ss_laid(void);
> +
>  /* 'Other OS' area */
>  
>  enum ps3_param_av_multi_out {
> diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
> index 9a196a8..1ba15b8 100644
> --- a/arch/powerpc/platforms/ps3/platform.h
> +++ b/arch/powerpc/platforms/ps3/platform.h
> @@ -232,4 +232,8 @@ int ps3_repository_read_spu_resource_id(unsigned int res_index,
>  int ps3_repository_read_vuart_av_port(unsigned int *port);
>  int ps3_repository_read_vuart_sysmgr_port(unsigned int *port);
>  
> +/* repository ss info */
> +
> +int ps3_repository_read_ss_laid(enum ps3_ss_laid *laid);
> +
>  #endif
> diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c
> index 5e304c2..6fa3e96 100644
> --- a/arch/powerpc/platforms/ps3/repository.c
> +++ b/arch/powerpc/platforms/ps3/repository.c
> @@ -1002,6 +1002,25 @@ int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar,
>  			    lpar, rights);
>  }
>  
> +/**
> + * ps3_repository_read_ss_laid - Read the lpar auth id
> + */
> +
> +int ps3_repository_read_ss_laid(enum ps3_ss_laid *laid)
> +{
> +	int result;
> +	u64 id, v1;
> +
> +	lv1_get_logical_partition_id(&id);
> +	result = read_node(PS3_LPAR_ID_PME,
> +			   make_first_field("ss", 0),
> +			   make_field("laid", 0),
> +			   id, 0,
> +			   &v1, NULL);
> +	*laid = v1;
> +	return result;
> +}
> +
>  #if defined(DEBUG)
>  
>  int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo)
> diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
> index 149bea2..f430279 100644
> --- a/arch/powerpc/platforms/ps3/setup.c
> +++ b/arch/powerpc/platforms/ps3/setup.c
> @@ -47,6 +47,7 @@ DEFINE_MUTEX(ps3_gpu_mutex);
>  EXPORT_SYMBOL_GPL(ps3_gpu_mutex);
>  
>  static union ps3_firmware_version ps3_firmware_version;
> +static enum ps3_ss_laid ps3_ss_laid;
>  
>  void ps3_get_firmware_version(union ps3_firmware_version *v)
>  {
> @@ -68,6 +69,12 @@ int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev)
>  }
>  EXPORT_SYMBOL_GPL(ps3_compare_firmware_version);
>  
> +enum ps3_ss_laid ps3_get_ss_laid(void)
> +{
> +	return ps3_ss_laid;
> +}
> +EXPORT_SYMBOL_GPL(ps3_get_ss_laid);
> +
>  static void ps3_power_save(void)
>  {
>  	/*
> @@ -192,6 +199,7 @@ static int ps3_set_dabr(unsigned long dabr)
>  
>  static void __init ps3_setup_arch(void)
>  {
> +	const char *laid_str;
>  
>  	DBG(" -> %s:%d\n", __func__, __LINE__);
>  
> @@ -200,6 +208,20 @@ static void __init ps3_setup_arch(void)
>  	       ps3_firmware_version.major, ps3_firmware_version.minor,
>  	       ps3_firmware_version.rev);
>  
> +	ps3_repository_read_ss_laid(&ps3_ss_laid);
> +	switch (ps3_ss_laid) {
> +	case PS3_SS_LAID_GAMEOS:
> +		laid_str = "GameOS";
> +		break;
> +	case PS3_SS_LAID_OTHEROS:
> +		laid_str = "OtherOS";
> +		break;
> +	default:
> +		laid_str = "unknown";
> +		break;
> +	}
> +	printk(KERN_INFO "Running in %s lpar\n", laid_str);
> +
>  	ps3_spu_set_platform();
>  
>  #ifdef CONFIG_SMP

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

* Re: [PATCH 01/15] [PS3] Add udbg driver using the PS3 gelic Ethernet device
  2011-08-01 20:02 ` [PATCH 01/15] [PS3] Add udbg driver using the PS3 gelic Ethernet device Andre Heider
@ 2011-08-03 22:32   ` Geoff Levand
  2011-08-04 16:35     ` Andre Heider
  2011-08-11 12:13     ` [Cbe-oss-dev] " Arnd Bergmann
  0 siblings, 2 replies; 70+ messages in thread
From: Geoff Levand @ 2011-08-03 22:32 UTC (permalink / raw)
  To: Andre Heider; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

On 08/01/2011 01:02 PM, Andre Heider wrote:
> --- /dev/null
> +++ b/arch/powerpc/platforms/ps3/gelic_udbg.c
> @@ -0,0 +1,272 @@
> +/*
> + * arch/powerpc/platforms/ps3/gelic_udbg.c

Don't put file names in files.  When the file gets moved, then this will
no longer be correct.

> + *
> + * udbg debug output routine via GELIC UDP broadcasts
> + * Copyright (C) 2010 Hector Martin <hector@marcansoft.com>
> + * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>

Some of this seems to be taken from the gelic driver, so shouldn't
the copyright info from there be included here?

> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + */
> +
> +#include <asm/io.h>
> +#include <asm/udbg.h>
> +#include <asm/lv1call.h>
> +
> +#define GELIC_BUS_ID 1
> +#define GELIC_DEVICE_ID 0
> +#define GELIC_DEBUG_PORT 18194
> +#define GELIC_MAX_MESSAGE_SIZE 1000
> +
> +#define GELIC_LV1_GET_MAC_ADDRESS 1
> +#define GELIC_LV1_GET_VLAN_ID 4
> +#define GELIC_LV1_VLAN_TX_ETHERNET_0 2
> +
> +#define GELIC_DESCR_DMA_STAT_MASK 0xf0000000
> +#define GELIC_DESCR_DMA_CARDOWNED 0xa0000000
> +
> +#define GELIC_DESCR_TX_DMA_IKE 0x00080000
> +#define GELIC_DESCR_TX_DMA_NO_CHKSUM 0x00000000
> +#define GELIC_DESCR_TX_DMA_FRAME_TAIL 0x00040000
> +
> +#define GELIC_DESCR_DMA_CMD_NO_CHKSUM (GELIC_DESCR_DMA_CARDOWNED | \
> +				       GELIC_DESCR_TX_DMA_IKE | \
> +				       GELIC_DESCR_TX_DMA_NO_CHKSUM)
> +
> +static u64 bus_addr;
> +
> +struct gelic_descr {
> +	/* as defined by the hardware */

These are BE from the hardware, so should be __beXX types.

> +	u32 buf_addr;
> +	u32 buf_size;
> +	u32 next_descr_addr;
> +	u32 dmac_cmd_status;
> +	u32 result_size;
> +	u32 valid_size;	/* all zeroes for tx */
> +	u32 data_status;
> +	u32 data_error;	/* all zeroes for tx */
> +} __attribute__((aligned(32)));

...

> +static void gelic_debug_init(void)
> +{

...

> +	result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
> +				 GELIC_LV1_GET_VLAN_ID,
> +				 GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0,
> +				 &vlan_id, &v2);
> +	if (result == 0) {

This should be 'if (!result)'

-Geoff

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

* Re: [PATCH 03/15] [PS3] Add region 1 memory early
  2011-08-01 20:02 ` [PATCH 03/15] [PS3] Add region 1 memory early Andre Heider
@ 2011-08-03 22:32   ` Geoff Levand
  2011-08-04  0:08     ` Hector Martin
  0 siblings, 1 reply; 70+ messages in thread
From: Geoff Levand @ 2011-08-03 22:32 UTC (permalink / raw)
  To: Andre Heider; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

On 08/01/2011 01:02 PM, Andre Heider wrote:
> From: Hector Martin <hector@marcansoft.com>

We need an explanation of this change.

> Signed-off-by: Hector Martin <hector@marcansoft.com>
> [a.heider: Various cleanups to make checkpatch.pl happy]
> Signed-off-by: Andre Heider <a.heider@gmail.com>
> ---
>  arch/powerpc/platforms/ps3/mm.c |   62 +++++++--------------------------------
>  1 files changed, 11 insertions(+), 51 deletions(-)

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

* Re: [PATCH 07/15] ps3flash: Refuse to work in lpars other than OtherOS
  2011-08-01 20:02 ` [PATCH 07/15] ps3flash: Refuse to work in lpars other than OtherOS Andre Heider
@ 2011-08-03 22:34   ` Geoff Levand
  2011-08-04 16:40     ` Andre Heider
  0 siblings, 1 reply; 70+ messages in thread
From: Geoff Levand @ 2011-08-03 22:34 UTC (permalink / raw)
  To: Andre Heider; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

On 08/01/2011 01:02 PM, Andre Heider wrote:
> The driver implements a character and misc device, meant for the
> axed OtherOS to exchange various settings with GameOS.
> Since Firmware 3.21 there is no GameOS support anymore to write these
> settings, so limit the driver to the OtherOS environment.

This is really a test if running on the PS3 OtherOS, so this
comment should state that.

> 
> Signed-off-by: Andre Heider <a.heider@gmail.com>
> ---
>  arch/powerpc/platforms/ps3/Kconfig |    1 +
>  drivers/char/ps3flash.c            |    7 +++++++
>  2 files changed, 8 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
> index 84df5c8..5eb956a 100644
> --- a/arch/powerpc/platforms/ps3/Kconfig
> +++ b/arch/powerpc/platforms/ps3/Kconfig
> @@ -121,6 +121,7 @@ config PS3_FLASH
>  
>  	  This support is required to access the PS3 FLASH ROM, which
>  	  contains the boot loader and some boot options.
> +	  This driver only supports the deprecated OtherOS LPAR.

This will be confusing for OtherOS users, so should be removed.

>  	  In general, all users will say Y or M.


This could be changed to: 'In general, all PS3 OtherOS users will say Y or M.'

>  
>  	  As this driver needs a fixed buffer of 256 KiB of memory, it can
> diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
> index 69c734a..b1e8659 100644
> --- a/drivers/char/ps3flash.c
> +++ b/drivers/char/ps3flash.c
> @@ -25,6 +25,7 @@
>  
>  #include <asm/lv1call.h>
>  #include <asm/ps3stor.h>
> +#include <asm/firmware.h>
>  
>  
>  #define DEVICE_NAME		"ps3flash"
> @@ -455,6 +456,12 @@ static struct ps3_system_bus_driver ps3flash = {
>  
>  static int __init ps3flash_init(void)
>  {
> +	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
> +		return -ENODEV;

Is this needed?  Won't this driver only be loaded on PS3 hardware?

> +
> +	if (ps3_get_ss_laid() != PS3_SS_LAID_OTHEROS)
> +		return -ENODEV;
> +
>  	return ps3_system_bus_driver_register(&ps3flash);
>  }
>  

-Geoff

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

* Re: [PATCH 03/15] [PS3] Add region 1 memory early
  2011-08-03 22:32   ` Geoff Levand
@ 2011-08-04  0:08     ` Hector Martin
  2011-08-04  7:05       ` Geert Uytterhoeven
  2011-08-04 15:57       ` Geoff Levand
  0 siblings, 2 replies; 70+ messages in thread
From: Hector Martin @ 2011-08-04  0:08 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Andre Heider, linuxppc-dev

On 08/04/2011 12:32 AM, Geoff Levand wrote:
> We need an explanation of this change.

I actually have a hard time understanding the reason for the existing
behavior of hot-adding memory halfway through the boot process. Maybe
you can shed some light on this?

The reason for the change is that under the default GameOS LPAR, real
mode memory is 16MB which is already tight for a kernel (under certain
conditions) and runs out quickly as memory is allocated during kernel
startup. Having region1 available sooner fixes this.

Though, reviewing the code, I think I found a bug (that should already
have a chance of happening as things stand now, though this patch might
make it more likely): if storage bounce buffers or the ps3fb xdr happen
to straddle the boundary between the regions, bad things will happen
since they're not actually contiguous in LPAR space. This won't happen
right now for ps3flash or ps3fb since those are allocated early out of
bootmem, but it can currently happen for the other buffers (ps3disk,
ps3vram, etc.) AFAICT.

Maybe we should introduce a reserved or nonexistent page gap at the
beginning of region1 to ensure that nothing will ever allocate
contiguous memory across the boundary. That will probably prevent
bootmem from grabbing region1 due to the gap, so early on memory will be
tight. Can we get rid of the ps3flash and ps3fb preallocations to save
bootmem and just allocate them during device init like the other drivers
do? What is the reason for preallocating these?

-- 
Hector Martin (hector@marcansoft.com)
Public Key: http://www.marcansoft.com/marcan.asc

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

* Re: [PATCH 02/15] [PS3] Get lv1 high memory region from devtree
  2011-08-03 22:30   ` Geoff Levand
@ 2011-08-04  1:19     ` Hector Martin
  2011-08-04 19:24       ` Geoff Levand
  0 siblings, 1 reply; 70+ messages in thread
From: Hector Martin @ 2011-08-04  1:19 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Andre Heider, linuxppc-dev

On 08/04/2011 12:30 AM, Geoff Levand wrote:
> With this mechanism how is the address of the initrd passed to the
> new kernel, in the DT?

Using the /chosen linux,initrd-{start,end} properties. The bootloader
knows about the Linux trick of sticking together bootmem and highmem and
precalculates the linux "physical" address. Yeah, that's a hack, it
should probably be done in the kernel so the bootloader doesn't have to
know or care about how Linux decides to lay out its physical address
space. Do you have any suggestion as to how we would do this sanely?
Right now early_init_dt_setup_initrd_arch in arch/powerpc/kernel/prom.c
is generic and doesn't know anything about platform specifics.

> How would a kexec based bootloader work?  If it's kernel were to allocate
> high mem and the bootloader program uses the high mem, how could it tell
> that kernel not to destroy the region on shutdown?

The current code contemplates the case where a non-kexec based
bootloader is the first stage and allocates highmem (and knows how to
tell the kernel about it), possibly followed by kexec stages that just
keep that allocation. To support a kexec bootloader as the first
bootloader using this mechanism would indeed require extra support to
tell that kernel to retain its allocation, preferably something that can
be decided from userland. Of course the current kexec bootloader
behavior where highmem isn't handed over to the child kernel will still
work.

> If arch/powerpc/boot/ps3.c allocated the mem and added a DT entry
> then other OSes that don't know about the Linux device tree won't
> be able to use that allocated memory.  Other OSes could do a
> test to see if the allocation was already done.  Another option
> that might work is to write info into the LV1 repository then
> have boot code look there for allocated hig mem.

If you're booting another OS that isn't Linux then it also has no use
for a Linux-specific ramdisk (linux,initrd-start) and thus no use for
preallocated highmem and should be booted as such (maybe make the
userland tools tell the kernel to release highmem if there's no initrd
defined).

Using the lv1 repo is an option, but does it make sense? It's even less
standard than a FDT and we'd have to put both the region1 location and
the initrd location in there (there's no point to maintaining highmem if
you aren't going to use it).

FWIW, the lv1 repo writing hypercalls are unused and undocumented.

>> +	if (!map.r1.size) {
>> +		DBG("%s:%d: no region 1, not adding memory\n",
>> +		    __func__, __LINE__);
>> +		return 0;
>> +	}
> 
> Did you find this to be hit?  Also, in the general case,
> there could be more than one high mem region, but I don't
> know of any current systems that do.

Probably only during debugging, but it doesn't sound like a bad idea
anyway (e.g. bootloader allocated highmem but didn't tell the kernel so
the kernel couldn't allocate it).

As for multiple regions, well, currently it only supports one and that
is hardcoded in the phys->lpar translation, so I see no point in
worrying about that now.

ACK on the other code comments.

-- 
Hector Martin (hector@marcansoft.com)
Public Key: http://www.marcansoft.com/marcan.asc

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

* Re: [PATCH 03/15] [PS3] Add region 1 memory early
  2011-08-04  0:08     ` Hector Martin
@ 2011-08-04  7:05       ` Geert Uytterhoeven
  2011-08-04 11:13         ` Hector Martin
  2011-08-04 15:57       ` Geoff Levand
  1 sibling, 1 reply; 70+ messages in thread
From: Geert Uytterhoeven @ 2011-08-04  7:05 UTC (permalink / raw)
  To: Hector Martin; +Cc: Geoff Levand, cbe-oss-dev, Andre Heider, linuxppc-dev

On Thu, Aug 4, 2011 at 02:08, Hector Martin <hector@marcansoft.com> wrote:
> tight. Can we get rid of the ps3flash and ps3fb preallocations to save
> bootmem and just allocate them during device init like the other drivers
> do? What is the reason for preallocating these?

The reason for that is to make sure the allocations will succeed.
Chances are very
slim you can allocate a contiguous 9 MiB buffer at any arbitrary time.

Gr{oetje,eeting}s,

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k=
.org

In personal conversations with technical people, I call myself a hacker. Bu=
t
when I'm talking to journalists I just say "programmer" or something like t=
hat.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0 =C2=A0=C2=A0 -- Linus Torvalds

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

* Re: [PATCH 03/15] [PS3] Add region 1 memory early
  2011-08-04  7:05       ` Geert Uytterhoeven
@ 2011-08-04 11:13         ` Hector Martin
  0 siblings, 0 replies; 70+ messages in thread
From: Hector Martin @ 2011-08-04 11:13 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Geoff Levand, cbe-oss-dev, Andre Heider, linuxppc-dev

On 08/04/2011 09:05 AM, Geert Uytterhoeven wrote:
> The reason for that is to make sure the allocations will succeed.
> Chances are very
> slim you can allocate a contiguous 9 MiB buffer at any arbitrary time.

Fair enough, but then they don't need to happen as early as they do now;
any time during kernel startup should work (as long as they aren't freed
with the drivers if they're unloaded). How about switching to
__get_free_pages and doing the allocation inside an arch_initcall or
similar?

-- 
Hector Martin (hector@marcansoft.com)
Public Key: http://www.marcansoft.com/marcan.asc

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

* Re: [PATCH 03/15] [PS3] Add region 1 memory early
  2011-08-04  0:08     ` Hector Martin
  2011-08-04  7:05       ` Geert Uytterhoeven
@ 2011-08-04 15:57       ` Geoff Levand
  1 sibling, 0 replies; 70+ messages in thread
From: Geoff Levand @ 2011-08-04 15:57 UTC (permalink / raw)
  To: Hector Martin; +Cc: cbe-oss-dev, Andre Heider, linuxppc-dev

Hi Hector,

On 08/03/2011 05:08 PM, Hector Martin wrote:
> On 08/04/2011 12:32 AM, Geoff Levand wrote:
>> We need an explanation of this change.

Sorry for such a terse request.  What I meant was that
this is a significant change to how high mem is managed,
so the patch needs a comment explaining the change.

> I actually have a hard time understanding the reason for the existing
> behavior of hot-adding memory halfway through the boot process. Maybe
> you can shed some light on this?

LV1 was intended to be a generic hypervisor for the Cell
processor.  It was imagined that it could be used on machines
which could be running many lpars.  Around the same time I
was doing the high mem support the hot plug memory support was
being developed.  I thought at some point there would be
hot-unplug, which could be used to move memory between lpars.

At the present time this change make sense, since it is simpler
and more flexible.

-Geoff

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

* Re: [PATCH 00/15] ps3: Support more than the OtherOS lpar
  2011-08-03 22:23 ` [PATCH 00/15] ps3: Support more than the OtherOS lpar Geoff Levand
@ 2011-08-04 16:31   ` Andre Heider
  0 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-04 16:31 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

Hi Geoff,

On Thu, Aug 4, 2011 at 12:23 AM, Geoff Levand <geoff@infradead.org> wrote:
> Hi Andre,
>
> On 08/01/2011 01:02 PM, Andre Heider wrote:
>> This series addresses various issues and extends support when running
>> in lpars like GameOS. Included are some patches from Hector Martin, whic=
h
>> I found useful.
>
> Much of this is just general fixups and improvements to the existing PS3
> support. =A0I think you should separate those changes out and work to get
> them included, then consider others. =A0If I give some comment, then
> I consider that part worth pursuing at the present time.

Sounds like a good approach to me.

> I have limited time to review the patches, so it will take me a while to
> get through them.

No problem at all, it will probably take some time to resolve all the
details anyway.

>> Patches are based on 2.6.39 since master doesn't boot with smp on my
>> console. =A0I wasn't able to pinpoint the cause so far (not that I tried
>> too hard).
>
> I'm looking into this problem, but it will take some time.

Just for the record: I didn't mean to push ;)

Thanks,
Andre

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

* Re: [PATCH 05/15] ps3: Detect the current lpar environment
  2011-08-03 22:31   ` Geoff Levand
@ 2011-08-04 16:34     ` Andre Heider
  0 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-04 16:34 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

On Thu, Aug 4, 2011 at 12:31 AM, Geoff Levand <geoff@infradead.org> wrote:
> On 08/01/2011 01:02 PM, Andre Heider wrote:
>> ---
>> =A0arch/powerpc/include/asm/ps3.h =A0 =A0 =A0 =A0 =A0| =A0 =A07 +++++++
>> =A0arch/powerpc/platforms/ps3/platform.h =A0 | =A0 =A04 ++++
>> =A0arch/powerpc/platforms/ps3/repository.c | =A0 19 +++++++++++++++++++
>> =A0arch/powerpc/platforms/ps3/setup.c =A0 =A0 =A0| =A0 22 ++++++++++++++=
++++++++
>> =A04 files changed, 52 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/p=
s3.h
>> index 7f065e1..136354a 100644
>> --- a/arch/powerpc/include/asm/ps3.h
>> +++ b/arch/powerpc/include/asm/ps3.h
>> @@ -39,6 +39,13 @@ union ps3_firmware_version {
>> =A0void ps3_get_firmware_version(union ps3_firmware_version *v);
>> =A0int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev);
>>
>> +enum ps3_ss_laid {
>> + =A0 =A0 PS3_SS_LAID_GAMEOS =3D 0x1070000002000001UL,
>> + =A0 =A0 PS3_SS_LAID_OTHEROS =3D 0x1080000004000001UL,
>
> Only PS3_SS_LAID_OTHEROS is used for anything outside ps3_setup_arch(),
> so I think it makes sense to split this into two patches with one adding
> just PS3_SS_LAID_OTHEROS and ps3_get_ss_laid() with a comment that
> it adds the ps3_get_ss_laid routine.

Sounds reasonable, I will split that into two patches then.

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

* Re: [PATCH 01/15] [PS3] Add udbg driver using the PS3 gelic Ethernet device
  2011-08-03 22:32   ` Geoff Levand
@ 2011-08-04 16:35     ` Andre Heider
  2011-08-11 12:13     ` [Cbe-oss-dev] " Arnd Bergmann
  1 sibling, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-04 16:35 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

On Thu, Aug 4, 2011 at 12:32 AM, Geoff Levand <geoff@infradead.org> wrote:
> On 08/01/2011 01:02 PM, Andre Heider wrote:
>> --- /dev/null
>> +++ b/arch/powerpc/platforms/ps3/gelic_udbg.c
>> @@ -0,0 +1,272 @@
>> +/*
>> + * arch/powerpc/platforms/ps3/gelic_udbg.c
>
> Don't put file names in files. =A0When the file gets moved, then this wil=
l
> no longer be correct.
>
>> + *
>> + * udbg debug output routine via GELIC UDP broadcasts
>> + * Copyright (C) 2010 Hector Martin <hector@marcansoft.com>
>> + * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>
>
> Some of this seems to be taken from the gelic driver, so shouldn't
> the copyright info from there be included here?
>
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * as published by the Free Software Foundation; either version 2
>> + * of the License, or (at your option) any later version.
>> + *
>> + */
>> +
>> +#include <asm/io.h>
>> +#include <asm/udbg.h>
>> +#include <asm/lv1call.h>
>> +
>> +#define GELIC_BUS_ID 1
>> +#define GELIC_DEVICE_ID 0
>> +#define GELIC_DEBUG_PORT 18194
>> +#define GELIC_MAX_MESSAGE_SIZE 1000
>> +
>> +#define GELIC_LV1_GET_MAC_ADDRESS 1
>> +#define GELIC_LV1_GET_VLAN_ID 4
>> +#define GELIC_LV1_VLAN_TX_ETHERNET_0 2
>> +
>> +#define GELIC_DESCR_DMA_STAT_MASK 0xf0000000
>> +#define GELIC_DESCR_DMA_CARDOWNED 0xa0000000
>> +
>> +#define GELIC_DESCR_TX_DMA_IKE 0x00080000
>> +#define GELIC_DESCR_TX_DMA_NO_CHKSUM 0x00000000
>> +#define GELIC_DESCR_TX_DMA_FRAME_TAIL 0x00040000
>> +
>> +#define GELIC_DESCR_DMA_CMD_NO_CHKSUM (GELIC_DESCR_DMA_CARDOWNED | \
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0GELIC_DESCR_TX_DMA_IKE | \
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0GELIC_DESCR_TX_DMA_NO_CHKSUM)
>> +
>> +static u64 bus_addr;
>> +
>> +struct gelic_descr {
>> + =A0 =A0 /* as defined by the hardware */
>
> These are BE from the hardware, so should be __beXX types.
>
>> + =A0 =A0 u32 buf_addr;
>> + =A0 =A0 u32 buf_size;
>> + =A0 =A0 u32 next_descr_addr;
>> + =A0 =A0 u32 dmac_cmd_status;
>> + =A0 =A0 u32 result_size;
>> + =A0 =A0 u32 valid_size; /* all zeroes for tx */
>> + =A0 =A0 u32 data_status;
>> + =A0 =A0 u32 data_error; /* all zeroes for tx */
>> +} __attribute__((aligned(32)));
>
> ...
>
>> +static void gelic_debug_init(void)
>> +{
>
> ...
>
>> + =A0 =A0 result =3D lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0GELIC_LV1_G=
ET_VLAN_ID,
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0GELIC_LV1_V=
LAN_TX_ETHERNET_0, 0, 0,
>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0&vlan_id, &=
v2);
>> + =A0 =A0 if (result =3D=3D 0) {
>
> This should be 'if (!result)'

Ack on all points.

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

* Re: [PATCH 07/15] ps3flash: Refuse to work in lpars other than OtherOS
  2011-08-03 22:34   ` Geoff Levand
@ 2011-08-04 16:40     ` Andre Heider
  2011-08-04 19:27       ` [Cbe-oss-dev] " Geert Uytterhoeven
  0 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-04 16:40 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

On Thu, Aug 4, 2011 at 12:34 AM, Geoff Levand <geoff@infradead.org> wrote:
> On 08/01/2011 01:02 PM, Andre Heider wrote:
>> The driver implements a character and misc device, meant for the
>> axed OtherOS to exchange various settings with GameOS.
>> Since Firmware 3.21 there is no GameOS support anymore to write these
>> settings, so limit the driver to the OtherOS environment.
>
> This is really a test if running on the PS3 OtherOS, so this
> comment should state that.

Ok.

>
>>
>> Signed-off-by: Andre Heider <a.heider@gmail.com>
>> ---
>> =A0arch/powerpc/platforms/ps3/Kconfig | =A0 =A01 +
>> =A0drivers/char/ps3flash.c =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A07 +++++++
>> =A02 files changed, 8 insertions(+), 0 deletions(-)
>>
>> diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms=
/ps3/Kconfig
>> index 84df5c8..5eb956a 100644
>> --- a/arch/powerpc/platforms/ps3/Kconfig
>> +++ b/arch/powerpc/platforms/ps3/Kconfig
>> @@ -121,6 +121,7 @@ config PS3_FLASH
>>
>> =A0 =A0 =A0 =A0 This support is required to access the PS3 FLASH ROM, wh=
ich
>> =A0 =A0 =A0 =A0 contains the boot loader and some boot options.
>> + =A0 =A0 =A0 This driver only supports the deprecated OtherOS LPAR.
>
> This will be confusing for OtherOS users, so should be removed.

Ok.

>
>> =A0 =A0 =A0 =A0 In general, all users will say Y or M.
>
>
> This could be changed to: 'In general, all PS3 OtherOS users will say Y o=
r M.'

Yeah, you're right, that's much better

>
>>
>> =A0 =A0 =A0 =A0 As this driver needs a fixed buffer of 256 KiB of memory=
, it can
>> diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
>> index 69c734a..b1e8659 100644
>> --- a/drivers/char/ps3flash.c
>> +++ b/drivers/char/ps3flash.c
>> @@ -25,6 +25,7 @@
>>
>> =A0#include <asm/lv1call.h>
>> =A0#include <asm/ps3stor.h>
>> +#include <asm/firmware.h>
>>
>>
>> =A0#define DEVICE_NAME =A0 =A0 =A0 =A0 =A0"ps3flash"
>> @@ -455,6 +456,12 @@ static struct ps3_system_bus_driver ps3flash =3D {
>>
>> =A0static int __init ps3flash_init(void)
>> =A0{
>> + =A0 =A0 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
>> + =A0 =A0 =A0 =A0 =A0 =A0 return -ENODEV;
>
> Is this needed? =A0Won't this driver only be loaded on PS3 hardware?
>

The same code is in drivers/block/ps3disk.c, I wasn't sure if it is
missing here or redundant there.
Should I remove it here?

>> +
>> + =A0 =A0 if (ps3_get_ss_laid() !=3D PS3_SS_LAID_OTHEROS)
>> + =A0 =A0 =A0 =A0 =A0 =A0 return -ENODEV;
>> +
>> =A0 =A0 =A0 return ps3_system_bus_driver_register(&ps3flash);
>> =A0}
>>
>
> -Geoff
>
>

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

* Re: [PATCH 02/15] [PS3] Get lv1 high memory region from devtree
  2011-08-04  1:19     ` Hector Martin
@ 2011-08-04 19:24       ` Geoff Levand
  2011-08-06 11:50         ` Andre Heider
  0 siblings, 1 reply; 70+ messages in thread
From: Geoff Levand @ 2011-08-04 19:24 UTC (permalink / raw)
  To: Hector Martin; +Cc: cbe-oss-dev, Andre Heider, linuxppc-dev

On 08/03/2011 06:19 PM, Hector Martin wrote:
> On 08/04/2011 12:30 AM, Geoff Levand wrote:
>> How would a kexec based bootloader work?  If it's kernel were to allocate
>> high mem and the bootloader program uses the high mem, how could it tell
>> that kernel not to destroy the region on shutdown?
> 
> The current code contemplates the case where a non-kexec based
> bootloader is the first stage and allocates highmem (and knows how to
> tell the kernel about it), possibly followed by kexec stages that just
> keep that allocation. To support a kexec bootloader as the first
> bootloader using this mechanism would indeed require extra support to
> tell that kernel to retain its allocation, preferably something that can
> be decided from userland. Of course the current kexec bootloader
> behavior where highmem isn't handed over to the child kernel will still
> work.
> 
>> If arch/powerpc/boot/ps3.c allocated the mem and added a DT entry
>> then other OSes that don't know about the Linux device tree won't
>> be able to use that allocated memory.  Other OSes could do a
>> test to see if the allocation was already done.  Another option
>> that might work is to write info into the LV1 repository then
>> have boot code look there for allocated hig mem.
> 
> If you're booting another OS that isn't Linux then it also has no use
> for a Linux-specific ramdisk (linux,initrd-start) and thus no use for
> preallocated highmem and should be booted as such (maybe make the
> userland tools tell the kernel to release highmem if there's no initrd
> defined).

This sounds complicated, user programs managing memory regions.

Also, it needs to be considered that a lot of kernels are out
there will be confused if started with high mem already allocated.

> Using the lv1 repo is an option, but does it make sense? It's even less
> standard than a FDT and we'd have to put both the region1 location and
> the initrd location in there (there's no point to maintaining highmem if
> you aren't going to use it).
> 
> FWIW, the lv1 repo writing hypercalls are unused and undocumented.

The hcalls to create, write, and delete nodes are known, but I don't
recall if I verified they work:

  http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=arch/powerpc/include/asm/lv1call.h;hb=HEAD#l265

#92 should be named lv1_write_repository_node.

You can only modify the repo for your lpar, so:

  lv1_{create,write}_repository_node(n1, n2, n3, n4, v1, v2);
  lv1_delete_repository_node(n1, n2, n3, n4);

-Geoff

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

* Re: [Cbe-oss-dev] [PATCH 07/15] ps3flash: Refuse to work in lpars other than OtherOS
  2011-08-04 16:40     ` Andre Heider
@ 2011-08-04 19:27       ` Geert Uytterhoeven
  2011-08-06 12:40         ` Andre Heider
  0 siblings, 1 reply; 70+ messages in thread
From: Geert Uytterhoeven @ 2011-08-04 19:27 UTC (permalink / raw)
  To: Andre Heider; +Cc: Geoff Levand, cbe-oss-dev, Hector Martin, linuxppc-dev

On Thu, Aug 4, 2011 at 18:40, Andre Heider <a.heider@gmail.com> wrote:
> On Thu, Aug 4, 2011 at 12:34 AM, Geoff Levand <geoff@infradead.org> wrote=
:
>> On 08/01/2011 01:02 PM, Andre Heider wrote:
>>> --- a/drivers/char/ps3flash.c
>>> +++ b/drivers/char/ps3flash.c
>>> @@ -25,6 +25,7 @@
>>>
>>> =C2=A0#include <asm/lv1call.h>
>>> =C2=A0#include <asm/ps3stor.h>
>>> +#include <asm/firmware.h>
>>>
>>>
>>> =C2=A0#define DEVICE_NAME =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"ps3flash"
>>> @@ -455,6 +456,12 @@ static struct ps3_system_bus_driver ps3flash =3D {
>>>
>>> =C2=A0static int __init ps3flash_init(void)
>>> =C2=A0{
>>> + =C2=A0 =C2=A0 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
>>> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -ENODEV;
>>
>> Is this needed? =C2=A0Won't this driver only be loaded on PS3 hardware?
>>
>
> The same code is in drivers/block/ps3disk.c, I wasn't sure if it is
> missing here or redundant there.
> Should I remove it here?
>
>>> +
>>> + =C2=A0 =C2=A0 if (ps3_get_ss_laid() !=3D PS3_SS_LAID_OTHEROS)
>>> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -ENODEV;
>>> +
>>> =C2=A0 =C2=A0 =C2=A0 return ps3_system_bus_driver_register(&ps3flash);
>>> =C2=A0}

ps3flash_init() is called straight from module_init(), so it could be
called on non-PS3.
ps3_system_bus_driver_register() has the firmware_has_feature_check(),
so it will
reject non-PS3.

But if your *_init() does any processing before calling
ps3_system_bus_driver_register()
(like ps3disk_init() does, and ps3flash_init() now does due to your
patch), you have to
do the check yourself, to make sure it returns early on non-PS3.

Gr{oetje,eeting}s,

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k=
.org

In personal conversations with technical people, I call myself a hacker. Bu=
t
when I'm talking to journalists I just say "programmer" or something like t=
hat.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0 =C2=A0=C2=A0 -- Linus Torvalds

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

* Re: [PATCH 02/15] [PS3] Get lv1 high memory region from devtree
  2011-08-04 19:24       ` Geoff Levand
@ 2011-08-06 11:50         ` Andre Heider
  0 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-06 11:50 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

On Thu, Aug 4, 2011 at 9:24 PM, Geoff Levand <geoff@infradead.org> wrote:
> Also, it needs to be considered that a lot of kernels are out
> there will be confused if started with high mem already allocated.

True, but is there anything we can do about that?
Isn't is okay to tell users of first stage boot loaders utilizing this
mechanism that whatever steps their boot chain contains has to support
this highmem pass over? As far as I can tell all current loaders won't
be affected by this patch.
When a user wants to chain a loader with this mechanism with
petitboot, he needs a petitboot coming with a kernel containing this
feature, and can then kexec whatever contains it too.

>> Using the lv1 repo is an option, but does it make sense? It's even less
>> standard than a FDT and we'd have to put both the region1 location and
>> the initrd location in there (there's no point to maintaining highmem if
>> you aren't going to use it).
>>
>> FWIW, the lv1 repo writing hypercalls are unused and undocumented.
>
> The hcalls to create, write, and delete nodes are known, but I don't
> recall if I verified they work:
>
> =A0http://git.kernel.org/?p=3Dlinux/kernel/git/torvalds/linux-2.6.git;a=
=3Dblob;f=3Darch/powerpc/include/asm/lv1call.h;hb=3DHEAD#l265
>
> #92 should be named lv1_write_repository_node.
>
> You can only modify the repo for your lpar, so:
>
> =A0lv1_{create,write}_repository_node(n1, n2, n3, n4, v1, v2);
> =A0lv1_delete_repository_node(n1, n2, n3, n4);

I tried this and it indeed works - I can pass over the highmem info
just fine using repository nodes.
If there is a chance that another OS might require this highmem pass
over then I agree that using the repository makes more sense.

I can prepare a patch for that, replacing this one. Any suggestions on
which nodes to use?
For a test run I used:
  FIELD_FIRST("bi", 0),
  FIELD("highmem", 0),
  FIELD("address", 0),
  0
and
  FIELD_FIRST("bi", 0),
  FIELD("highmem", 0),
  FIELD("size", 0),
  0

Regards,
Andre

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

* Re: [Cbe-oss-dev] [PATCH 09/15] ps3: Limit the number of regions per storage device
  2011-08-01 20:58     ` Andre Heider
@ 2011-08-06 12:28       ` Andre Heider
  2011-08-06 12:47         ` Andre Heider
  0 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-06 12:28 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Geoff Levand, cbe-oss-dev, Hector Martin, linuxppc-dev

On Mon, Aug 1, 2011 at 10:58 PM, Andre Heider <a.heider@gmail.com> wrote:
> On Mon, Aug 1, 2011 at 10:30 PM, Geert Uytterhoeven
> <geert@linux-m68k.org> wrote:
>> On Mon, Aug 1, 2011 at 22:03, Andre Heider <a.heider@gmail.com> wrote:
>>> There can be only 8 regions, add a sanity check
>>
>> Why can there be only 8 regions?
>
> I believe lv1 limits it to 8? I might be mistaken here, it mostly is a
> check for the patches after this one

Small follow-up:
While the repository contains ("bus", "dev", "n_regs") to describe the
actual number of regions, it also contains ("bus", "dev", "region", [
"id" | "start" | "size" ]) for always exactly 8 regions (with a value
of 0xdeadbeef for invalid regions).

I added this check for the storage drivers, which contain:
  for (region_idx = 0; region_idx < dev->num_regions; region_idx++) {
    ...
    gendisk->first_minor = devidx * PS3DISK_MINORS + region_idx;

But that limit might be raised in future hypervisor versions.
Maybe a
  BUG_ON(dev->num_regions <= PS3DISK_MINORS);
is more appropriate?

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

* Re: [Cbe-oss-dev] [PATCH 07/15] ps3flash: Refuse to work in lpars other than OtherOS
  2011-08-04 19:27       ` [Cbe-oss-dev] " Geert Uytterhoeven
@ 2011-08-06 12:40         ` Andre Heider
  0 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-06 12:40 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Geoff Levand, cbe-oss-dev, Hector Martin, linuxppc-dev

On Thu, Aug 4, 2011 at 9:27 PM, Geert Uytterhoeven <geert@linux-m68k.org> w=
rote:
> On Thu, Aug 4, 2011 at 18:40, Andre Heider <a.heider@gmail.com> wrote:
>> On Thu, Aug 4, 2011 at 12:34 AM, Geoff Levand <geoff@infradead.org> wrot=
e:
>>> On 08/01/2011 01:02 PM, Andre Heider wrote:
>>>> --- a/drivers/char/ps3flash.c
>>>> +++ b/drivers/char/ps3flash.c
>>>> @@ -25,6 +25,7 @@
>>>>
>>>> =A0#include <asm/lv1call.h>
>>>> =A0#include <asm/ps3stor.h>
>>>> +#include <asm/firmware.h>
>>>>
>>>>
>>>> =A0#define DEVICE_NAME =A0 =A0 =A0 =A0 =A0"ps3flash"
>>>> @@ -455,6 +456,12 @@ static struct ps3_system_bus_driver ps3flash =3D =
{
>>>>
>>>> =A0static int __init ps3flash_init(void)
>>>> =A0{
>>>> + =A0 =A0 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
>>>> + =A0 =A0 =A0 =A0 =A0 =A0 return -ENODEV;
>>>
>>> Is this needed? =A0Won't this driver only be loaded on PS3 hardware?
>>>
>>
>> The same code is in drivers/block/ps3disk.c, I wasn't sure if it is
>> missing here or redundant there.
>> Should I remove it here?
>>
>>>> +
>>>> + =A0 =A0 if (ps3_get_ss_laid() !=3D PS3_SS_LAID_OTHEROS)
>>>> + =A0 =A0 =A0 =A0 =A0 =A0 return -ENODEV;
>>>> +
>>>> =A0 =A0 =A0 return ps3_system_bus_driver_register(&ps3flash);
>>>> =A0}
>
> ps3flash_init() is called straight from module_init(), so it could be
> called on non-PS3.
> ps3_system_bus_driver_register() has the firmware_has_feature_check(),
> so it will
> reject non-PS3.
>
> But if your *_init() does any processing before calling
> ps3_system_bus_driver_register()
> (like ps3disk_init() does, and ps3flash_init() now does due to your
> patch), you have to
> do the check yourself, to make sure it returns early on non-PS3.

Aha, makes perfect sense.

Thanks Geert

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

* Re: [Cbe-oss-dev] [PATCH 09/15] ps3: Limit the number of regions per storage device
  2011-08-06 12:28       ` Andre Heider
@ 2011-08-06 12:47         ` Andre Heider
  0 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-06 12:47 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Geoff Levand, cbe-oss-dev, Hector Martin, linuxppc-dev

On Sat, Aug 6, 2011 at 2:28 PM, Andre Heider <a.heider@gmail.com> wrote:
> On Mon, Aug 1, 2011 at 10:58 PM, Andre Heider <a.heider@gmail.com> wrote:
>> On Mon, Aug 1, 2011 at 10:30 PM, Geert Uytterhoeven
>> <geert@linux-m68k.org> wrote:
>>> On Mon, Aug 1, 2011 at 22:03, Andre Heider <a.heider@gmail.com> wrote:
>>>> There can be only 8 regions, add a sanity check
>>>
>>> Why can there be only 8 regions?
>>
>> I believe lv1 limits it to 8? I might be mistaken here, it mostly is a
>> check for the patches after this one
>
> Small follow-up:
> While the repository contains ("bus", "dev", "n_regs") to describe the
> actual number of regions, it also contains ("bus", "dev", "region", [
> "id" | "start" | "size" ]) for always exactly 8 regions (with a value
> of 0xdeadbeef for invalid regions).
>
> I added this check for the storage drivers, which contain:
> =A0for (region_idx =3D 0; region_idx < dev->num_regions; region_idx++) {
> =A0 =A0...
> =A0 =A0gendisk->first_minor =3D devidx * PS3DISK_MINORS + region_idx;
>
> But that limit might be raised in future hypervisor versions.
> Maybe a
> =A0BUG_ON(dev->num_regions <=3D PS3DISK_MINORS);
> is more appropriate?

Of course I meant the exact opposite, heh:
 =A0BUG_ON(dev->num_regions > PS3DISK_MINORS);

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

* Re: [Cbe-oss-dev] [PATCH 01/15] [PS3] Add udbg driver using the PS3 gelic Ethernet device
  2011-08-03 22:32   ` Geoff Levand
  2011-08-04 16:35     ` Andre Heider
@ 2011-08-11 12:13     ` Arnd Bergmann
  2011-08-11 17:32       ` Andre Heider
  1 sibling, 1 reply; 70+ messages in thread
From: Arnd Bergmann @ 2011-08-11 12:13 UTC (permalink / raw)
  To: cbe-oss-dev; +Cc: Geoff Levand, Andre Heider, linuxppc-dev, Hector Martin

On Thursday 04 August 2011, Geoff Levand wrote:
> > + *
> > + * udbg debug output routine via GELIC UDP broadcasts
> > + * Copyright (C) 2010 Hector Martin <hector@marcansoft.com>
> > + * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>
> 
> Some of this seems to be taken from the gelic driver, so shouldn't
> the copyright info from there be included here?

Moreover, if there is a significant amount of code duplication
between this driver and gelic, I would expect to actually share
the code instead, either by integrating the udbg code into the
gelic driver in form of netconsole support, or by moving the
common parts into a separate module.

	Arnd

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

* Re: [Cbe-oss-dev] [PATCH 00/15] ps3: Support more than the OtherOS lpar
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (15 preceding siblings ...)
  2011-08-03 22:23 ` [PATCH 00/15] ps3: Support more than the OtherOS lpar Geoff Levand
@ 2011-08-11 12:17 ` Arnd Bergmann
  2011-08-11 17:34   ` Andre Heider
  2011-08-11 19:31 ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support " Andre Heider
  17 siblings, 1 reply; 70+ messages in thread
From: Arnd Bergmann @ 2011-08-11 12:17 UTC (permalink / raw)
  To: cbe-oss-dev; +Cc: Geoff Levand, Andre Heider, linuxppc-dev, Hector Martin

On Monday 01 August 2011, Andre Heider wrote:
> This series addresses various issues and extends support when running
> in lpars like GameOS. Included are some patches from Hector Martin, which
> I found useful.

Hi Andre,

I've looked at the entire series and support merging it into 3.2 once
the concerns from Geoff and Geert are resolved. I don't have anything
to add there.

	Arnd

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

* Re: [Cbe-oss-dev] [PATCH 01/15] [PS3] Add udbg driver using the PS3 gelic Ethernet device
  2011-08-11 12:13     ` [Cbe-oss-dev] " Arnd Bergmann
@ 2011-08-11 17:32       ` Andre Heider
  2011-08-31  4:26         ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-11 17:32 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: cbe-oss-dev, Geoff Levand, Hector Martin, linuxppc-dev

On Thu, Aug 11, 2011 at 2:13 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday 04 August 2011, Geoff Levand wrote:
>> > + *
>> > + * udbg debug output routine via GELIC UDP broadcasts
>> > + * Copyright (C) 2010 Hector Martin <hector@marcansoft.com>
>> > + * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>
>>
>> Some of this seems to be taken from the gelic driver, so shouldn't
>> the copyright info from there be included here?
>
> Moreover, if there is a significant amount of code duplication
> between this driver and gelic, I would expect to actually share
> the code instead, either by integrating the udbg code into the
> gelic driver in form of netconsole support, or by moving the
> common parts into a separate module.

No, thankfully there is no significant code duplication :)
It contains a few structs and defines found elsewhere, but that's
because it's not a real netdev. It just prepares the eth/ip/udp header
once for its single purpose, then uses the hypervisor to send and poll
- in contrast to the gelic driver, which reuses its irqhandler for
netconsole support.

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

* Re: [Cbe-oss-dev] [PATCH 00/15] ps3: Support more than the OtherOS lpar
  2011-08-11 12:17 ` [Cbe-oss-dev] " Arnd Bergmann
@ 2011-08-11 17:34   ` Andre Heider
  0 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-11 17:34 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: cbe-oss-dev, Geoff Levand, Hector Martin, linuxppc-dev

On Thu, Aug 11, 2011 at 2:17 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Monday 01 August 2011, Andre Heider wrote:
>> This series addresses various issues and extends support when running
>> in lpars like GameOS. Included are some patches from Hector Martin, which
>> I found useful.
>
> Hi Andre,
>
> I've looked at the entire series and support merging it into 3.2 once
> the concerns from Geoff and Geert are resolved. I don't have anything
> to add there.

Hi Arnd,

thanks, I'll send the first part of v2 soon

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

* [PATCH part1 v2 0/9] ps3: General improvements and preparation for support more than the OtherOS lpar
  2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
                   ` (16 preceding siblings ...)
  2011-08-11 12:17 ` [Cbe-oss-dev] " Arnd Bergmann
@ 2011-08-11 19:31 ` Andre Heider
  2011-08-11 19:31   ` [PATCH part1 v2 1/9] Add udbg driver using the PS3 gelic Ethernet device Andre Heider
                     ` (9 more replies)
  17 siblings, 10 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-11 19:31 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

This is the first part of my previous series including the discussed fixups.

I dropped the old #2 ([PS3] Get lv1 high memory region from devtree)
and replaced it with 2 new patches, now #2 and #3. The latter contains
the fixups mentioned on the old #2 thread.

Patches are based on today's Linus' tree.

Andre Heider (7):
  ps3: Add helper functions to read highmem info from the repository
  ps3: Get lv1 high memory region from the repository
  ps3: MEMORY_HOTPLUG is not a requirement anymore
  ps3: Detect the current lpar
  ps3: Log the detected lpar on startup
  ps3flash: Refuse to work in lpars other than OtherOS
  ps3: Only prealloc the flash bounce buffer for the OtherOS lpar

Hector Martin (2):
  Add udbg driver using the PS3 gelic Ethernet device
  Add region 1 memory early

 arch/powerpc/Kconfig.debug              |    8 +
 arch/powerpc/include/asm/ps3.h          |    7 +
 arch/powerpc/include/asm/udbg.h         |    1 +
 arch/powerpc/kernel/udbg.c              |    2 +
 arch/powerpc/platforms/ps3/Kconfig      |   15 ++-
 arch/powerpc/platforms/ps3/Makefile     |    1 +
 arch/powerpc/platforms/ps3/gelic_udbg.c |  273 +++++++++++++++++++++++++++++++
 arch/powerpc/platforms/ps3/mm.c         |   85 +++++------
 arch/powerpc/platforms/ps3/platform.h   |    7 +
 arch/powerpc/platforms/ps3/repository.c |   55 ++++++
 arch/powerpc/platforms/ps3/setup.c      |   27 +++-
 drivers/char/ps3flash.c                 |    7 +
 drivers/net/ps3_gelic_net.c             |    3 +
 drivers/net/ps3_gelic_net.h             |    6 +
 14 files changed, 447 insertions(+), 50 deletions(-)
 create mode 100644 arch/powerpc/platforms/ps3/gelic_udbg.c

-- 
1.7.5.4

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

* [PATCH part1 v2 1/9] Add udbg driver using the PS3 gelic Ethernet device
  2011-08-11 19:31 ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support " Andre Heider
@ 2011-08-11 19:31   ` Andre Heider
  2011-08-23 20:53     ` Geoff Levand
  2011-08-11 19:31   ` [PATCH part1 v2 2/9] ps3: Add helper functions to read highmem info from the repository Andre Heider
                     ` (8 subsequent siblings)
  9 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-11 19:31 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

From: Hector Martin <hector@marcansoft.com>

Signed-off-by: Hector Martin <hector@marcansoft.com>
[a.heider: Various cleanups to make checkpatch.pl happy]
Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/Kconfig.debug              |    8 +
 arch/powerpc/include/asm/udbg.h         |    1 +
 arch/powerpc/kernel/udbg.c              |    2 +
 arch/powerpc/platforms/ps3/Kconfig      |   12 ++
 arch/powerpc/platforms/ps3/Makefile     |    1 +
 arch/powerpc/platforms/ps3/gelic_udbg.c |  273 +++++++++++++++++++++++++++++++
 drivers/net/ps3_gelic_net.c             |    3 +
 drivers/net/ps3_gelic_net.h             |    6 +
 8 files changed, 306 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/platforms/ps3/gelic_udbg.c

diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 067cb84..ab2335f 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -258,6 +258,14 @@ config PPC_EARLY_DEBUG_WSP
 	depends on PPC_WSP
 	select PPC_UDBG_16550
 
+config PPC_EARLY_DEBUG_PS3GELIC
+	bool "Early debugging through the PS3 Ethernet port"
+	depends on PPC_PS3
+	select PS3GELIC_UDBG
+	help
+	  Select this to enable early debugging for the PlayStation3 via
+	  UDP broadcasts sent out through the Ethernet port.
+
 endchoice
 
 config PPC_EARLY_DEBUG_HVSI_VTERMNO
diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h
index 93e05d1..7cf796f 100644
--- a/arch/powerpc/include/asm/udbg.h
+++ b/arch/powerpc/include/asm/udbg.h
@@ -54,6 +54,7 @@ extern void __init udbg_init_40x_realmode(void);
 extern void __init udbg_init_cpm(void);
 extern void __init udbg_init_usbgecko(void);
 extern void __init udbg_init_wsp(void);
+extern void __init udbg_init_ps3gelic(void);
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_UDBG_H */
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index faa82c1..5b3e98e 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -67,6 +67,8 @@ void __init udbg_early_init(void)
 	udbg_init_usbgecko();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP)
 	udbg_init_wsp();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
+	udbg_init_ps3gelic();
 #endif
 
 #ifdef CONFIG_PPC_EARLY_DEBUG
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index dfe316b..476d9d9 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -148,4 +148,16 @@ config PS3_LPM
 	  profiling support of the Cell processor with programs like
 	  oprofile and perfmon2, then say Y or M, otherwise say N.
 
+config PS3GELIC_UDBG
+	bool "PS3 udbg output via UDP broadcasts on Ethernet"
+	depends on PPC_PS3
+	help
+	  Enables udbg early debugging output by sending broadcast UDP
+	  via the Ethernet port (UDP port number 18194).
+
+	  This driver uses a trivial implementation and is independent
+	  from the main network driver.
+
+	  If in doubt, say N here.
+
 endmenu
diff --git a/arch/powerpc/platforms/ps3/Makefile b/arch/powerpc/platforms/ps3/Makefile
index ac1bdf8..02b9e63 100644
--- a/arch/powerpc/platforms/ps3/Makefile
+++ b/arch/powerpc/platforms/ps3/Makefile
@@ -2,6 +2,7 @@ obj-y += setup.o mm.o time.o hvcall.o htab.o repository.o
 obj-y += interrupt.o exports.o os-area.o
 obj-y += system-bus.o
 
+obj-$(CONFIG_PS3GELIC_UDBG) += gelic_udbg.o
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_SPU_BASE) += spu.o
 obj-y += device-init.o
diff --git a/arch/powerpc/platforms/ps3/gelic_udbg.c b/arch/powerpc/platforms/ps3/gelic_udbg.c
new file mode 100644
index 0000000..20b46a1
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/gelic_udbg.c
@@ -0,0 +1,273 @@
+/*
+ * udbg debug output routine via GELIC UDP broadcasts
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2006, 2007 Sony Corporation
+ * Copyright (C) 2010 Hector Martin <hector@marcansoft.com>
+ * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ */
+
+#include <asm/io.h>
+#include <asm/udbg.h>
+#include <asm/lv1call.h>
+
+#define GELIC_BUS_ID 1
+#define GELIC_DEVICE_ID 0
+#define GELIC_DEBUG_PORT 18194
+#define GELIC_MAX_MESSAGE_SIZE 1000
+
+#define GELIC_LV1_GET_MAC_ADDRESS 1
+#define GELIC_LV1_GET_VLAN_ID 4
+#define GELIC_LV1_VLAN_TX_ETHERNET_0 2
+
+#define GELIC_DESCR_DMA_STAT_MASK 0xf0000000
+#define GELIC_DESCR_DMA_CARDOWNED 0xa0000000
+
+#define GELIC_DESCR_TX_DMA_IKE 0x00080000
+#define GELIC_DESCR_TX_DMA_NO_CHKSUM 0x00000000
+#define GELIC_DESCR_TX_DMA_FRAME_TAIL 0x00040000
+
+#define GELIC_DESCR_DMA_CMD_NO_CHKSUM (GELIC_DESCR_DMA_CARDOWNED | \
+				       GELIC_DESCR_TX_DMA_IKE | \
+				       GELIC_DESCR_TX_DMA_NO_CHKSUM)
+
+static u64 bus_addr;
+
+struct gelic_descr {
+	/* as defined by the hardware */
+	__be32 buf_addr;
+	__be32 buf_size;
+	__be32 next_descr_addr;
+	__be32 dmac_cmd_status;
+	__be32 result_size;
+	__be32 valid_size;	/* all zeroes for tx */
+	__be32 data_status;
+	__be32 data_error;	/* all zeroes for tx */
+} __attribute__((aligned(32)));
+
+struct debug_block {
+	struct gelic_descr descr;
+	u8 pkt[1520];
+} __packed;
+
+struct ethhdr {
+	u8 dest[6];
+	u8 src[6];
+	u16 type;
+} __packed;
+
+struct vlantag {
+	u16 vlan;
+	u16 subtype;
+} __packed;
+
+struct iphdr {
+	u8 ver_len;
+	u8 dscp_ecn;
+	u16 total_length;
+	u16 ident;
+	u16 frag_off_flags;
+	u8 ttl;
+	u8 proto;
+	u16 checksum;
+	u32 src;
+	u32 dest;
+} __packed;
+
+struct udphdr {
+	u16 src;
+	u16 dest;
+	u16 len;
+	u16 checksum;
+} __packed;
+
+static __iomem struct ethhdr *h_eth;
+static __iomem struct vlantag *h_vlan;
+static __iomem struct iphdr *h_ip;
+static __iomem struct udphdr *h_udp;
+
+static __iomem char *pmsg;
+static __iomem char *pmsgc;
+
+static __iomem struct debug_block dbg __attribute__((aligned(32)));
+
+static int header_size;
+
+static void map_dma_mem(int bus_id, int dev_id, void *start, size_t len,
+			u64 *real_bus_addr)
+{
+	s64 result;
+	u64 real_addr = ((u64)start) & 0x0fffffffffffffffUL;
+	u64 real_end = real_addr + len;
+	u64 map_start = real_addr & ~0xfff;
+	u64 map_end = (real_end + 0xfff) & ~0xfff;
+	u64 bus_addr = 0;
+
+	u64 flags = 0xf800000000000000UL;
+
+	result = lv1_allocate_device_dma_region(bus_id, dev_id,
+						map_end - map_start, 12, 0,
+						&bus_addr);
+	if (result)
+		lv1_panic(0);
+
+	result = lv1_map_device_dma_region(bus_id, dev_id, map_start,
+					   bus_addr, map_end - map_start,
+					   flags);
+	if (result)
+		lv1_panic(0);
+
+	*real_bus_addr = bus_addr + real_addr - map_start;
+}
+
+static int unmap_dma_mem(int bus_id, int dev_id, u64 bus_addr, size_t len)
+{
+	s64 result;
+	u64 real_bus_addr;
+
+	real_bus_addr = bus_addr & ~0xfff;
+	len += bus_addr - real_bus_addr;
+	len = (len + 0xfff) & ~0xfff;
+
+	result = lv1_unmap_device_dma_region(bus_id, dev_id, real_bus_addr,
+					     len);
+	if (result)
+		return result;
+
+	return lv1_free_device_dma_region(bus_id, dev_id, real_bus_addr);
+}
+
+static void gelic_debug_init(void)
+{
+	s64 result;
+	u64 v2;
+	u64 mac;
+	u64 vlan_id;
+
+	result = lv1_open_device(GELIC_BUS_ID, GELIC_DEVICE_ID, 0);
+	if (result)
+		lv1_panic(0);
+
+	map_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID, &dbg, sizeof(dbg),
+		    &bus_addr);
+
+	memset(&dbg, 0, sizeof(dbg));
+
+	dbg.descr.buf_addr = bus_addr + offsetof(struct debug_block, pkt);
+
+	wmb();
+
+	result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
+				 GELIC_LV1_GET_MAC_ADDRESS, 0, 0, 0,
+				 &mac, &v2);
+	if (result)
+		lv1_panic(0);
+
+	mac <<= 16;
+
+	h_eth = (struct ethhdr *)dbg.pkt;
+
+	memset(&h_eth->dest, 0xff, 6);
+	memcpy(&h_eth->src, &mac, 6);
+
+	header_size = sizeof(struct ethhdr);
+
+	result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
+				 GELIC_LV1_GET_VLAN_ID,
+				 GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0,
+				 &vlan_id, &v2);
+	if (!result) {
+		h_eth->type = 0x8100;
+
+		header_size += sizeof(struct vlantag);
+		h_vlan = (struct vlantag *)(h_eth + 1);
+		h_vlan->vlan = vlan_id;
+		h_vlan->subtype = 0x0800;
+		h_ip = (struct iphdr *)(h_vlan + 1);
+	} else {
+		h_eth->type = 0x0800;
+		h_ip = (struct iphdr *)(h_eth + 1);
+	}
+
+	header_size += sizeof(struct iphdr);
+	h_ip->ver_len = 0x45;
+	h_ip->ttl = 10;
+	h_ip->proto = 0x11;
+	h_ip->src = 0x00000000;
+	h_ip->dest = 0xffffffff;
+
+	header_size += sizeof(struct udphdr);
+	h_udp = (struct udphdr *)(h_ip + 1);
+	h_udp->src = GELIC_DEBUG_PORT;
+	h_udp->dest = GELIC_DEBUG_PORT;
+
+	pmsgc = pmsg = (char *)(h_udp + 1);
+}
+
+static void gelic_debug_shutdown(void)
+{
+	if (bus_addr)
+		unmap_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID,
+			      bus_addr, sizeof(dbg));
+	lv1_close_device(GELIC_BUS_ID, GELIC_DEVICE_ID);
+}
+
+static void gelic_sendbuf(int msgsize)
+{
+	u16 *p;
+	u32 sum;
+	int i;
+
+	dbg.descr.buf_size = header_size + msgsize;
+	h_ip->total_length = msgsize + sizeof(struct udphdr) +
+			     sizeof(struct iphdr);
+	h_udp->len = msgsize + sizeof(struct udphdr);
+
+	h_ip->checksum = 0;
+	sum = 0;
+	p = (u16 *)h_ip;
+	for (i = 0; i < 5; i++)
+		sum += *p++;
+	h_ip->checksum = ~(sum + (sum >> 16));
+
+	dbg.descr.dmac_cmd_status = GELIC_DESCR_DMA_CMD_NO_CHKSUM |
+				    GELIC_DESCR_TX_DMA_FRAME_TAIL;
+	dbg.descr.result_size = 0;
+	dbg.descr.data_status = 0;
+
+	wmb();
+
+	lv1_net_start_tx_dma(GELIC_BUS_ID, GELIC_DEVICE_ID, bus_addr, 0);
+
+	while ((dbg.descr.dmac_cmd_status & GELIC_DESCR_DMA_STAT_MASK) ==
+	       GELIC_DESCR_DMA_CARDOWNED)
+		cpu_relax();
+}
+
+static void ps3gelic_udbg_putc(char ch)
+{
+	*pmsgc++ = ch;
+	if (ch == '\n' || (pmsgc-pmsg) >= GELIC_MAX_MESSAGE_SIZE) {
+		gelic_sendbuf(pmsgc-pmsg);
+		pmsgc = pmsg;
+	}
+}
+
+void __init udbg_init_ps3gelic(void)
+{
+	gelic_debug_init();
+	udbg_putc = ps3gelic_udbg_putc;
+}
+
+void udbg_shutdown_ps3gelic(void)
+{
+	udbg_putc = NULL;
+	gelic_debug_shutdown();
+}
+EXPORT_SYMBOL(udbg_shutdown_ps3gelic);
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index d82a82d..e743c94 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -1674,6 +1674,9 @@ static int __devinit ps3_gelic_driver_probe(struct ps3_system_bus_device *dev)
 	int result;
 
 	pr_debug("%s: called\n", __func__);
+
+	udbg_shutdown_ps3gelic();
+
 	result = ps3_open_hv_device(dev);
 
 	if (result) {
diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h
index d3fadfb..a93df6a 100644
--- a/drivers/net/ps3_gelic_net.h
+++ b/drivers/net/ps3_gelic_net.h
@@ -359,6 +359,12 @@ static inline void *port_priv(struct gelic_port *port)
 	return port->priv;
 }
 
+#ifdef CONFIG_PPC_EARLY_DEBUG_PS3GELIC
+extern void udbg_shutdown_ps3gelic(void);
+#else
+static inline void udbg_shutdown_ps3gelic(void) {}
+#endif
+
 extern int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask);
 /* shared netdev ops */
 extern void gelic_card_up(struct gelic_card *card);
-- 
1.7.5.4

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

* [PATCH part1 v2 2/9] ps3: Add helper functions to read highmem info from the repository
  2011-08-11 19:31 ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support " Andre Heider
  2011-08-11 19:31   ` [PATCH part1 v2 1/9] Add udbg driver using the PS3 gelic Ethernet device Andre Heider
@ 2011-08-11 19:31   ` Andre Heider
  2011-08-23 20:53     ` Geoff Levand
  2011-08-11 19:31   ` [PATCH part1 v2 3/9] ps3: Get lv1 high memory region " Andre Heider
                     ` (7 subsequent siblings)
  9 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-11 19:31 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

An earlier step in the boot chain can preallocate the highmem region.
A boot loader doing so will place the region infos in the repository.
Provide helper functions to read the required nodes.

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/platforms/ps3/platform.h   |    3 ++
 arch/powerpc/platforms/ps3/repository.c |   36 +++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index 9a196a8..d9b4ec0 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -187,6 +187,9 @@ int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size);
 int ps3_repository_read_region_total(u64 *region_total);
 int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size,
 	u64 *region_total);
+int ps3_repository_read_highmem_base(u64 *highmem_base);
+int ps3_repository_read_highmem_size(u64 *highmem_size);
+int ps3_repository_read_highmem_info(u64 *highmem_base, u64 *highmem_size);
 
 /* repository pme info */
 
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c
index 5e304c2..9908d61 100644
--- a/arch/powerpc/platforms/ps3/repository.c
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -778,6 +778,42 @@ int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total)
 		: ps3_repository_read_region_total(region_total);
 }
 
+int ps3_repository_read_highmem_base(u64 *highmem_base)
+{
+	return read_node(PS3_LPAR_ID_CURRENT,
+			 make_first_field("bi", 0),
+			 make_field("highmem", 0),
+			 make_field("base", 0),
+			 0,
+			 highmem_base, NULL);
+}
+
+int ps3_repository_read_highmem_size(u64 *highmem_size)
+{
+	return read_node(PS3_LPAR_ID_CURRENT,
+			 make_first_field("bi", 0),
+			 make_field("highmem", 0),
+			 make_field("size", 0),
+			 0,
+			 highmem_size, NULL);
+}
+
+/**
+ * ps3_repository_read_highmem_info - Read high memory info
+ * @highmem_base: High memory base address.
+ * @highmem_size: High mode memory size.
+ */
+
+int ps3_repository_read_highmem_info(u64 *highmem_base, u64 *highmem_size)
+{
+	int result;
+
+	*highmem_base = 0;
+	result = ps3_repository_read_highmem_base(highmem_base);
+	return result ? result
+		: ps3_repository_read_highmem_size(highmem_size);
+}
+
 /**
  * ps3_repository_read_num_spu_reserved - Number of physical spus reserved.
  * @num_spu: Number of physical spus.
-- 
1.7.5.4

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

* [PATCH part1 v2 3/9] ps3: Get lv1 high memory region from the repository
  2011-08-11 19:31 ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support " Andre Heider
  2011-08-11 19:31   ` [PATCH part1 v2 1/9] Add udbg driver using the PS3 gelic Ethernet device Andre Heider
  2011-08-11 19:31   ` [PATCH part1 v2 2/9] ps3: Add helper functions to read highmem info from the repository Andre Heider
@ 2011-08-11 19:31   ` Andre Heider
  2011-08-23 20:53     ` Geoff Levand
  2011-08-11 19:31   ` [PATCH part1 v2 4/9] Add region 1 memory early Andre Heider
                     ` (6 subsequent siblings)
  9 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-11 19:31 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

This lets the bootloader preallocate the high lv1 region and pass its
location to the kernel through the repository. Thus, it can be used to
hold the initrd. If the region info doesn't exist, the kernel retains
the old behavior and attempts to allocate the region itself.

Based on the patch
"[PS3] Get lv1 high memory region from devtree"
from Hector Martin <hector@marcansoft.com>

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/platforms/ps3/mm.c |   46 ++++++++++++++++++++++++++++++++++++--
 1 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index c204588..983b719 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -78,12 +78,14 @@ enum {
  * @base: base address
  * @size: size in bytes
  * @offset: difference between base and rm.size
+ * @destroy: flag if region should be destroyed upon shutdown
  */
 
 struct mem_region {
 	u64 base;
 	u64 size;
 	unsigned long offset;
+	int destroy;
 };
 
 /**
@@ -261,6 +263,7 @@ static int ps3_mm_region_create(struct mem_region *r, unsigned long size)
 		goto zero_region;
 	}
 
+	r->destroy = 1;
 	r->offset = r->base - map.rm.size;
 	return result;
 
@@ -279,6 +282,12 @@ static void ps3_mm_region_destroy(struct mem_region *r)
 	int result;
 
 	DBG("%s:%d: r->base = %llxh\n", __func__, __LINE__, r->base);
+
+	if (!r->destroy) {
+		DBG("%s:%d: not destroying region\n", __func__, __LINE__);
+		return;
+	}
+
 	if (r->base) {
 		result = lv1_release_memory(r->base);
 		BUG_ON(result);
@@ -287,6 +296,29 @@ static void ps3_mm_region_destroy(struct mem_region *r)
 	}
 }
 
+static int ps3_mm_get_repository_highmem(struct mem_region *r)
+{
+	int result = ps3_repository_read_highmem_info(&r->base, &r->size);
+
+	if (result)
+		goto zero_region;
+
+	if (!r->base || !r->size) {
+		result = -1;
+		goto zero_region;
+	}
+
+	r->offset = r->base - map.rm.size;
+	DBG("%s:%d got high region from repository: %llxh %llxh\n",
+	    __func__, __LINE__, r->base, r->size);
+	return 0;
+
+zero_region:
+	DBG("%s:%d no high region in repository...\n", __func__, __LINE__);
+	r->size = r->base = r->offset = 0;
+	return result;
+}
+
 /**
  * ps3_mm_add_memory - hot add memory
  */
@@ -303,6 +335,12 @@ static int __init ps3_mm_add_memory(void)
 
 	BUG_ON(!mem_init_done);
 
+	if (!map.r1.size) {
+		DBG("%s:%d: no region 1, not adding memory\n",
+		    __func__, __LINE__);
+		return 0;
+	}
+
 	start_addr = map.rm.size;
 	start_pfn = start_addr >> PAGE_SHIFT;
 	nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT;
@@ -1217,9 +1255,11 @@ void __init ps3_mm_init(void)
 	BUG_ON(map.rm.base);
 	BUG_ON(!map.rm.size);
 
-
-	/* arrange to do this in ps3_mm_add_memory */
-	ps3_mm_region_create(&map.r1, map.total - map.rm.size);
+	/* check if we got the highmem region from an earlier boot step */
+	if (ps3_mm_get_repository_highmem(&map.r1)) {
+		/* arrange to do this in ps3_mm_add_memory */
+		ps3_mm_region_create(&map.r1, map.total - map.rm.size);
+	}
 
 	/* correct map.total for the real total amount of memory we use */
 	map.total = map.rm.size + map.r1.size;
-- 
1.7.5.4

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

* [PATCH part1 v2 4/9] Add region 1 memory early
  2011-08-11 19:31 ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support " Andre Heider
                     ` (2 preceding siblings ...)
  2011-08-11 19:31   ` [PATCH part1 v2 3/9] ps3: Get lv1 high memory region " Andre Heider
@ 2011-08-11 19:31   ` Andre Heider
  2011-08-23 20:53     ` Geoff Levand
  2011-08-11 19:31   ` [PATCH part1 v2 5/9] ps3: MEMORY_HOTPLUG is not a requirement anymore Andre Heider
                     ` (5 subsequent siblings)
  9 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-11 19:31 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

From: Hector Martin <hector@marcansoft.com>

Real mode memory can be limited and runs out quickly as memory is
allocated during kernel startup.
Having region1 available sooner fixes this.

Signed-off-by: Hector Martin <hector@marcansoft.com>
[a.heider: Various cleanups to make checkpatch.pl happy]
Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/platforms/ps3/mm.c |   75 +++++++--------------------------------
 1 files changed, 13 insertions(+), 62 deletions(-)

diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 983b719..68b3879 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -20,7 +20,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/memory_hotplug.h>
 #include <linux/memblock.h>
 #include <linux/slab.h>
 
@@ -94,10 +93,8 @@ struct mem_region {
  * @vas_id - HV virtual address space id
  * @htab_size: htab size in bytes
  *
- * The HV virtual address space (vas) allows for hotplug memory regions.
- * Memory regions can be created and destroyed in the vas at runtime.
  * @rm: real mode (bootmem) region
- * @r1: hotplug memory region(s)
+ * @r1: high memory region
  *
  * ps3 addresses
  * virt_addr: a cpu 'translated' effective address
@@ -223,10 +220,6 @@ void ps3_mm_vas_destroy(void)
 	}
 }
 
-/*============================================================================*/
-/* memory hotplug routines                                                    */
-/*============================================================================*/
-
 /**
  * ps3_mm_region_create - create a memory region in the vas
  * @r: pointer to a struct mem_region to accept initialized values
@@ -319,57 +312,6 @@ zero_region:
 	return result;
 }
 
-/**
- * ps3_mm_add_memory - hot add memory
- */
-
-static int __init ps3_mm_add_memory(void)
-{
-	int result;
-	unsigned long start_addr;
-	unsigned long start_pfn;
-	unsigned long nr_pages;
-
-	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
-		return -ENODEV;
-
-	BUG_ON(!mem_init_done);
-
-	if (!map.r1.size) {
-		DBG("%s:%d: no region 1, not adding memory\n",
-		    __func__, __LINE__);
-		return 0;
-	}
-
-	start_addr = map.rm.size;
-	start_pfn = start_addr >> PAGE_SHIFT;
-	nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT;
-
-	DBG("%s:%d: start_addr %lxh, start_pfn %lxh, nr_pages %lxh\n",
-		__func__, __LINE__, start_addr, start_pfn, nr_pages);
-
-	result = add_memory(0, start_addr, map.r1.size);
-
-	if (result) {
-		pr_err("%s:%d: add_memory failed: (%d)\n",
-			__func__, __LINE__, result);
-		return result;
-	}
-
-	memblock_add(start_addr, map.r1.size);
-	memblock_analyze();
-
-	result = online_pages(start_pfn, nr_pages);
-
-	if (result)
-		pr_err("%s:%d: online_pages failed: (%d)\n",
-			__func__, __LINE__, result);
-
-	return result;
-}
-
-device_initcall(ps3_mm_add_memory);
-
 /*============================================================================*/
 /* dma routines                                                               */
 /*============================================================================*/
@@ -1256,14 +1198,23 @@ void __init ps3_mm_init(void)
 	BUG_ON(!map.rm.size);
 
 	/* check if we got the highmem region from an earlier boot step */
-	if (ps3_mm_get_repository_highmem(&map.r1)) {
-		/* arrange to do this in ps3_mm_add_memory */
+	if (ps3_mm_get_repository_highmem(&map.r1))
 		ps3_mm_region_create(&map.r1, map.total - map.rm.size);
-	}
 
 	/* correct map.total for the real total amount of memory we use */
 	map.total = map.rm.size + map.r1.size;
 
+	if (!map.r1.size) {
+		DBG("%s:%d: no region 1, not adding memory\n",
+			__func__, __LINE__);
+	} else {
+		DBG("%s:%d: adding memory: start %llxh, size %llxh\n",
+			__func__, __LINE__, map.rm.size, map.r1.size);
+
+		memblock_add(map.rm.size, map.r1.size);
+		memblock_analyze();
+	}
+
 	DBG(" <- %s:%d\n", __func__, __LINE__);
 }
 
-- 
1.7.5.4

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

* [PATCH part1 v2 5/9] ps3: MEMORY_HOTPLUG is not a requirement anymore
  2011-08-11 19:31 ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support " Andre Heider
                     ` (3 preceding siblings ...)
  2011-08-11 19:31   ` [PATCH part1 v2 4/9] Add region 1 memory early Andre Heider
@ 2011-08-11 19:31   ` Andre Heider
  2011-08-23 20:53     ` Geoff Levand
  2011-08-11 19:31   ` [PATCH part1 v2 6/9] ps3: Detect the current lpar Andre Heider
                     ` (4 subsequent siblings)
  9 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-11 19:31 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/platforms/ps3/Kconfig |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 476d9d9..84df5c8 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -7,7 +7,6 @@ config PPC_PS3
 	select USB_OHCI_BIG_ENDIAN_MMIO
 	select USB_ARCH_HAS_EHCI
 	select USB_EHCI_BIG_ENDIAN_MMIO
-	select MEMORY_HOTPLUG
 	select PPC_PCI_CHOICE
 	help
 	  This option enables support for the Sony PS3 game console
-- 
1.7.5.4

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

* [PATCH part1 v2 6/9] ps3: Detect the current lpar
  2011-08-11 19:31 ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support " Andre Heider
                     ` (4 preceding siblings ...)
  2011-08-11 19:31   ` [PATCH part1 v2 5/9] ps3: MEMORY_HOTPLUG is not a requirement anymore Andre Heider
@ 2011-08-11 19:31   ` Andre Heider
  2011-08-23 22:08     ` Geoff Levand
  2011-08-11 19:31   ` [PATCH part1 v2 7/9] ps3: Log the detected lpar on startup Andre Heider
                     ` (3 subsequent siblings)
  9 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-11 19:31 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

Detect it by reading the ss laid repository node, and make it
accessible via ps3_get_ss_laid().

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/include/asm/ps3.h          |    6 ++++++
 arch/powerpc/platforms/ps3/platform.h   |    4 ++++
 arch/powerpc/platforms/ps3/repository.c |   19 +++++++++++++++++++
 arch/powerpc/platforms/ps3/setup.c      |    9 +++++++++
 4 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
index 7f065e1..9e8c878 100644
--- a/arch/powerpc/include/asm/ps3.h
+++ b/arch/powerpc/include/asm/ps3.h
@@ -39,6 +39,12 @@ union ps3_firmware_version {
 void ps3_get_firmware_version(union ps3_firmware_version *v);
 int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev);
 
+enum ps3_ss_laid {
+	PS3_SS_LAID_OTHEROS = 0x1080000004000001UL,
+};
+
+enum ps3_ss_laid ps3_get_ss_laid(void);
+
 /* 'Other OS' area */
 
 enum ps3_param_av_multi_out {
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index d9b4ec0..b912d15 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -235,4 +235,8 @@ int ps3_repository_read_spu_resource_id(unsigned int res_index,
 int ps3_repository_read_vuart_av_port(unsigned int *port);
 int ps3_repository_read_vuart_sysmgr_port(unsigned int *port);
 
+/* repository ss info */
+
+int ps3_repository_read_ss_laid(enum ps3_ss_laid *laid);
+
 #endif
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c
index 9908d61..06f8801 100644
--- a/arch/powerpc/platforms/ps3/repository.c
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -1038,6 +1038,25 @@ int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar,
 			    lpar, rights);
 }
 
+/**
+ * ps3_repository_read_ss_laid - Read the lpar auth id
+ */
+
+int ps3_repository_read_ss_laid(enum ps3_ss_laid *laid)
+{
+	int result;
+	u64 id, v1;
+
+	lv1_get_logical_partition_id(&id);
+	result = read_node(PS3_LPAR_ID_PME,
+			   make_first_field("ss", 0),
+			   make_field("laid", 0),
+			   id, 0,
+			   &v1, NULL);
+	*laid = v1;
+	return result;
+}
+
 #if defined(DEBUG)
 
 int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo)
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 149bea2..9f23a6d 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -47,6 +47,7 @@ DEFINE_MUTEX(ps3_gpu_mutex);
 EXPORT_SYMBOL_GPL(ps3_gpu_mutex);
 
 static union ps3_firmware_version ps3_firmware_version;
+static enum ps3_ss_laid ps3_ss_laid;
 
 void ps3_get_firmware_version(union ps3_firmware_version *v)
 {
@@ -68,6 +69,12 @@ int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev)
 }
 EXPORT_SYMBOL_GPL(ps3_compare_firmware_version);
 
+enum ps3_ss_laid ps3_get_ss_laid(void)
+{
+	return ps3_ss_laid;
+}
+EXPORT_SYMBOL_GPL(ps3_get_ss_laid);
+
 static void ps3_power_save(void)
 {
 	/*
@@ -200,6 +207,8 @@ static void __init ps3_setup_arch(void)
 	       ps3_firmware_version.major, ps3_firmware_version.minor,
 	       ps3_firmware_version.rev);
 
+	ps3_repository_read_ss_laid(&ps3_ss_laid);
+
 	ps3_spu_set_platform();
 
 #ifdef CONFIG_SMP
-- 
1.7.5.4

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

* [PATCH part1 v2 7/9] ps3: Log the detected lpar on startup
  2011-08-11 19:31 ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support " Andre Heider
                     ` (5 preceding siblings ...)
  2011-08-11 19:31   ` [PATCH part1 v2 6/9] ps3: Detect the current lpar Andre Heider
@ 2011-08-11 19:31   ` Andre Heider
  2011-08-11 19:31   ` [PATCH part1 v2 8/9] ps3flash: Refuse to work in lpars other than OtherOS Andre Heider
                     ` (2 subsequent siblings)
  9 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-11 19:31 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

Add PS3_SS_LAID_GAMEOS to enum ps3_ss_laid.

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/include/asm/ps3.h     |    1 +
 arch/powerpc/platforms/ps3/setup.c |   13 +++++++++++++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/ps3.h b/arch/powerpc/include/asm/ps3.h
index 9e8c878..136354a 100644
--- a/arch/powerpc/include/asm/ps3.h
+++ b/arch/powerpc/include/asm/ps3.h
@@ -40,6 +40,7 @@ void ps3_get_firmware_version(union ps3_firmware_version *v);
 int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev);
 
 enum ps3_ss_laid {
+	PS3_SS_LAID_GAMEOS = 0x1070000002000001UL,
 	PS3_SS_LAID_OTHEROS = 0x1080000004000001UL,
 };
 
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 9f23a6d..1239059 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -199,6 +199,7 @@ static int ps3_set_dabr(unsigned long dabr)
 
 static void __init ps3_setup_arch(void)
 {
+	const char *laid_str;
 
 	DBG(" -> %s:%d\n", __func__, __LINE__);
 
@@ -208,6 +209,18 @@ static void __init ps3_setup_arch(void)
 	       ps3_firmware_version.rev);
 
 	ps3_repository_read_ss_laid(&ps3_ss_laid);
+	switch (ps3_ss_laid) {
+	case PS3_SS_LAID_GAMEOS:
+		laid_str = "GameOS";
+		break;
+	case PS3_SS_LAID_OTHEROS:
+		laid_str = "OtherOS";
+		break;
+	default:
+		laid_str = "unknown";
+		break;
+	}
+	printk(KERN_INFO "Running in %s LPAR\n", laid_str);
 
 	ps3_spu_set_platform();
 
-- 
1.7.5.4

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

* [PATCH part1 v2 8/9] ps3flash: Refuse to work in lpars other than OtherOS
  2011-08-11 19:31 ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support " Andre Heider
                     ` (6 preceding siblings ...)
  2011-08-11 19:31   ` [PATCH part1 v2 7/9] ps3: Log the detected lpar on startup Andre Heider
@ 2011-08-11 19:31   ` Andre Heider
  2011-08-23 22:12     ` Geoff Levand
  2011-08-11 19:31   ` [PATCH part1 v2 9/9] ps3: Only prealloc the flash bounce buffer for the OtherOS lpar Andre Heider
  2011-08-31  4:29   ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support more than " Benjamin Herrenschmidt
  9 siblings, 1 reply; 70+ messages in thread
From: Andre Heider @ 2011-08-11 19:31 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

The driver implements a character and misc device, meant for the
axed OtherOS to exchange various settings with GameOS.
Since Firmware 3.21 there is no support anymore to write these
settings, so test if we're running in OtherOS, and refuse to load
if that is not the case.

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/platforms/ps3/Kconfig |    2 +-
 drivers/char/ps3flash.c            |    7 +++++++
 2 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 84df5c8..72fdecd 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -121,7 +121,7 @@ config PS3_FLASH
 
 	  This support is required to access the PS3 FLASH ROM, which
 	  contains the boot loader and some boot options.
-	  In general, all users will say Y or M.
+	  In general, all PS3 OtherOS users will say Y or M.
 
 	  As this driver needs a fixed buffer of 256 KiB of memory, it can
 	  be disabled on the kernel command line using "ps3flash=off", to
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
index d0c57c2..fc6d867 100644
--- a/drivers/char/ps3flash.c
+++ b/drivers/char/ps3flash.c
@@ -25,6 +25,7 @@
 
 #include <asm/lv1call.h>
 #include <asm/ps3stor.h>
+#include <asm/firmware.h>
 
 
 #define DEVICE_NAME		"ps3flash"
@@ -464,6 +465,12 @@ static struct ps3_system_bus_driver ps3flash = {
 
 static int __init ps3flash_init(void)
 {
+	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+		return -ENODEV;
+
+	if (ps3_get_ss_laid() != PS3_SS_LAID_OTHEROS)
+		return -ENODEV;
+
 	return ps3_system_bus_driver_register(&ps3flash);
 }
 
-- 
1.7.5.4

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

* [PATCH part1 v2 9/9] ps3: Only prealloc the flash bounce buffer for the OtherOS lpar
  2011-08-11 19:31 ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support " Andre Heider
                     ` (7 preceding siblings ...)
  2011-08-11 19:31   ` [PATCH part1 v2 8/9] ps3flash: Refuse to work in lpars other than OtherOS Andre Heider
@ 2011-08-11 19:31   ` Andre Heider
  2011-08-31  4:29   ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support more than " Benjamin Herrenschmidt
  9 siblings, 0 replies; 70+ messages in thread
From: Andre Heider @ 2011-08-11 19:31 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

It's only used by the ps3flash driver, which only supports the
OtherOS lpar.

Signed-off-by: Andre Heider <a.heider@gmail.com>
---
 arch/powerpc/platforms/ps3/setup.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 1239059..81ce835 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -233,7 +233,10 @@ static void __init ps3_setup_arch(void)
 #endif
 
 	prealloc_ps3fb_videomemory();
-	prealloc_ps3flash_bounce_buffer();
+
+	/* the ps3flash driver only works for OtherOS */
+	if (ps3_get_ss_laid() == PS3_SS_LAID_OTHEROS)
+		prealloc_ps3flash_bounce_buffer();
 
 	ppc_md.power_save = ps3_power_save;
 	ps3_os_area_init();
-- 
1.7.5.4

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

* Re: [PATCH part1 v2 1/9] Add udbg driver using the PS3 gelic Ethernet device
  2011-08-11 19:31   ` [PATCH part1 v2 1/9] Add udbg driver using the PS3 gelic Ethernet device Andre Heider
@ 2011-08-23 20:53     ` Geoff Levand
  2011-08-31 16:32       ` [PATCH] [ps3] Add gelic udbg driver Geoff Levand
  0 siblings, 1 reply; 70+ messages in thread
From: Geoff Levand @ 2011-08-23 20:53 UTC (permalink / raw)
  To: Andre Heider; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

Hi,

We had some questions as to why we have this totally separate driver
from the gelic driver, so I think it worthwhile to have an
explanation of why in the commit log.   Otherwise, the code looks
OK.

-Geoff

> From: Hector Martin <hector@marcansoft.com>
> 
> Signed-off-by: Hector Martin <hector@marcansoft.com>
> [a.heider: Various cleanups to make checkpatch.pl happy]
> Signed-off-by: Andre Heider <a.heider@gmail.com>
> ---
>  arch/powerpc/Kconfig.debug              |    8 +
>  arch/powerpc/include/asm/udbg.h         |    1 +
>  arch/powerpc/kernel/udbg.c              |    2 +
>  arch/powerpc/platforms/ps3/Kconfig      |   12 ++
>  arch/powerpc/platforms/ps3/Makefile     |    1 +
>  arch/powerpc/platforms/ps3/gelic_udbg.c |  273 +++++++++++++++++++++++++++++++
>  drivers/net/ps3_gelic_net.c             |    3 +
>  drivers/net/ps3_gelic_net.h             |    6 +
>  8 files changed, 306 insertions(+), 0 deletions(-)
>  create mode 100644 arch/powerpc/platforms/ps3/gelic_udbg.c
> 
> diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
> index 067cb84..ab2335f 100644
> --- a/arch/powerpc/Kconfig.debug
> +++ b/arch/powerpc/Kconfig.debug
> @@ -258,6 +258,14 @@ config PPC_EARLY_DEBUG_WSP
>  	depends on PPC_WSP
>  	select PPC_UDBG_16550
>  
> +config PPC_EARLY_DEBUG_PS3GELIC
> +	bool "Early debugging through the PS3 Ethernet port"
> +	depends on PPC_PS3
> +	select PS3GELIC_UDBG
> +	help
> +	  Select this to enable early debugging for the PlayStation3 via
> +	  UDP broadcasts sent out through the Ethernet port.
> +
>  endchoice
>  
>  config PPC_EARLY_DEBUG_HVSI_VTERMNO
> diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h
> index 93e05d1..7cf796f 100644
> --- a/arch/powerpc/include/asm/udbg.h
> +++ b/arch/powerpc/include/asm/udbg.h
> @@ -54,6 +54,7 @@ extern void __init udbg_init_40x_realmode(void);
>  extern void __init udbg_init_cpm(void);
>  extern void __init udbg_init_usbgecko(void);
>  extern void __init udbg_init_wsp(void);
> +extern void __init udbg_init_ps3gelic(void);
>  
>  #endif /* __KERNEL__ */
>  #endif /* _ASM_POWERPC_UDBG_H */
> diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
> index faa82c1..5b3e98e 100644
> --- a/arch/powerpc/kernel/udbg.c
> +++ b/arch/powerpc/kernel/udbg.c
> @@ -67,6 +67,8 @@ void __init udbg_early_init(void)
>  	udbg_init_usbgecko();
>  #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP)
>  	udbg_init_wsp();
> +#elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
> +	udbg_init_ps3gelic();
>  #endif
>  
>  #ifdef CONFIG_PPC_EARLY_DEBUG
> diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
> index dfe316b..476d9d9 100644
> --- a/arch/powerpc/platforms/ps3/Kconfig
> +++ b/arch/powerpc/platforms/ps3/Kconfig
> @@ -148,4 +148,16 @@ config PS3_LPM
>  	  profiling support of the Cell processor with programs like
>  	  oprofile and perfmon2, then say Y or M, otherwise say N.
>  
> +config PS3GELIC_UDBG
> +	bool "PS3 udbg output via UDP broadcasts on Ethernet"
> +	depends on PPC_PS3
> +	help
> +	  Enables udbg early debugging output by sending broadcast UDP
> +	  via the Ethernet port (UDP port number 18194).
> +
> +	  This driver uses a trivial implementation and is independent
> +	  from the main network driver.
> +
> +	  If in doubt, say N here.
> +
>  endmenu
> diff --git a/arch/powerpc/platforms/ps3/Makefile b/arch/powerpc/platforms/ps3/Makefile
> index ac1bdf8..02b9e63 100644
> --- a/arch/powerpc/platforms/ps3/Makefile
> +++ b/arch/powerpc/platforms/ps3/Makefile
> @@ -2,6 +2,7 @@ obj-y += setup.o mm.o time.o hvcall.o htab.o repository.o
>  obj-y += interrupt.o exports.o os-area.o
>  obj-y += system-bus.o
>  
> +obj-$(CONFIG_PS3GELIC_UDBG) += gelic_udbg.o
>  obj-$(CONFIG_SMP) += smp.o
>  obj-$(CONFIG_SPU_BASE) += spu.o
>  obj-y += device-init.o
> diff --git a/arch/powerpc/platforms/ps3/gelic_udbg.c b/arch/powerpc/platforms/ps3/gelic_udbg.c
> new file mode 100644
> index 0000000..20b46a1
> --- /dev/null
> +++ b/arch/powerpc/platforms/ps3/gelic_udbg.c
> @@ -0,0 +1,273 @@
> +/*
> + * udbg debug output routine via GELIC UDP broadcasts
> + *
> + * Copyright (C) 2007 Sony Computer Entertainment Inc.
> + * Copyright 2006, 2007 Sony Corporation
> + * Copyright (C) 2010 Hector Martin <hector@marcansoft.com>
> + * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + */
> +
> +#include <asm/io.h>
> +#include <asm/udbg.h>
> +#include <asm/lv1call.h>
> +
> +#define GELIC_BUS_ID 1
> +#define GELIC_DEVICE_ID 0
> +#define GELIC_DEBUG_PORT 18194
> +#define GELIC_MAX_MESSAGE_SIZE 1000
> +
> +#define GELIC_LV1_GET_MAC_ADDRESS 1
> +#define GELIC_LV1_GET_VLAN_ID 4
> +#define GELIC_LV1_VLAN_TX_ETHERNET_0 2
> +
> +#define GELIC_DESCR_DMA_STAT_MASK 0xf0000000
> +#define GELIC_DESCR_DMA_CARDOWNED 0xa0000000
> +
> +#define GELIC_DESCR_TX_DMA_IKE 0x00080000
> +#define GELIC_DESCR_TX_DMA_NO_CHKSUM 0x00000000
> +#define GELIC_DESCR_TX_DMA_FRAME_TAIL 0x00040000
> +
> +#define GELIC_DESCR_DMA_CMD_NO_CHKSUM (GELIC_DESCR_DMA_CARDOWNED | \
> +				       GELIC_DESCR_TX_DMA_IKE | \
> +				       GELIC_DESCR_TX_DMA_NO_CHKSUM)
> +
> +static u64 bus_addr;
> +
> +struct gelic_descr {
> +	/* as defined by the hardware */
> +	__be32 buf_addr;
> +	__be32 buf_size;
> +	__be32 next_descr_addr;
> +	__be32 dmac_cmd_status;
> +	__be32 result_size;
> +	__be32 valid_size;	/* all zeroes for tx */
> +	__be32 data_status;
> +	__be32 data_error;	/* all zeroes for tx */
> +} __attribute__((aligned(32)));
> +
> +struct debug_block {
> +	struct gelic_descr descr;
> +	u8 pkt[1520];
> +} __packed;
> +
> +struct ethhdr {
> +	u8 dest[6];
> +	u8 src[6];
> +	u16 type;
> +} __packed;
> +
> +struct vlantag {
> +	u16 vlan;
> +	u16 subtype;
> +} __packed;
> +
> +struct iphdr {
> +	u8 ver_len;
> +	u8 dscp_ecn;
> +	u16 total_length;
> +	u16 ident;
> +	u16 frag_off_flags;
> +	u8 ttl;
> +	u8 proto;
> +	u16 checksum;
> +	u32 src;
> +	u32 dest;
> +} __packed;
> +
> +struct udphdr {
> +	u16 src;
> +	u16 dest;
> +	u16 len;
> +	u16 checksum;
> +} __packed;
> +
> +static __iomem struct ethhdr *h_eth;
> +static __iomem struct vlantag *h_vlan;
> +static __iomem struct iphdr *h_ip;
> +static __iomem struct udphdr *h_udp;
> +
> +static __iomem char *pmsg;
> +static __iomem char *pmsgc;
> +
> +static __iomem struct debug_block dbg __attribute__((aligned(32)));
> +
> +static int header_size;
> +
> +static void map_dma_mem(int bus_id, int dev_id, void *start, size_t len,
> +			u64 *real_bus_addr)
> +{
> +	s64 result;
> +	u64 real_addr = ((u64)start) & 0x0fffffffffffffffUL;
> +	u64 real_end = real_addr + len;
> +	u64 map_start = real_addr & ~0xfff;
> +	u64 map_end = (real_end + 0xfff) & ~0xfff;
> +	u64 bus_addr = 0;
> +
> +	u64 flags = 0xf800000000000000UL;
> +
> +	result = lv1_allocate_device_dma_region(bus_id, dev_id,
> +						map_end - map_start, 12, 0,
> +						&bus_addr);
> +	if (result)
> +		lv1_panic(0);
> +
> +	result = lv1_map_device_dma_region(bus_id, dev_id, map_start,
> +					   bus_addr, map_end - map_start,
> +					   flags);
> +	if (result)
> +		lv1_panic(0);
> +
> +	*real_bus_addr = bus_addr + real_addr - map_start;
> +}
> +
> +static int unmap_dma_mem(int bus_id, int dev_id, u64 bus_addr, size_t len)
> +{
> +	s64 result;
> +	u64 real_bus_addr;
> +
> +	real_bus_addr = bus_addr & ~0xfff;
> +	len += bus_addr - real_bus_addr;
> +	len = (len + 0xfff) & ~0xfff;
> +
> +	result = lv1_unmap_device_dma_region(bus_id, dev_id, real_bus_addr,
> +					     len);
> +	if (result)
> +		return result;
> +
> +	return lv1_free_device_dma_region(bus_id, dev_id, real_bus_addr);
> +}
> +
> +static void gelic_debug_init(void)
> +{
> +	s64 result;
> +	u64 v2;
> +	u64 mac;
> +	u64 vlan_id;
> +
> +	result = lv1_open_device(GELIC_BUS_ID, GELIC_DEVICE_ID, 0);
> +	if (result)
> +		lv1_panic(0);
> +
> +	map_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID, &dbg, sizeof(dbg),
> +		    &bus_addr);
> +
> +	memset(&dbg, 0, sizeof(dbg));
> +
> +	dbg.descr.buf_addr = bus_addr + offsetof(struct debug_block, pkt);
> +
> +	wmb();
> +
> +	result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
> +				 GELIC_LV1_GET_MAC_ADDRESS, 0, 0, 0,
> +				 &mac, &v2);
> +	if (result)
> +		lv1_panic(0);
> +
> +	mac <<= 16;
> +
> +	h_eth = (struct ethhdr *)dbg.pkt;
> +
> +	memset(&h_eth->dest, 0xff, 6);
> +	memcpy(&h_eth->src, &mac, 6);
> +
> +	header_size = sizeof(struct ethhdr);
> +
> +	result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
> +				 GELIC_LV1_GET_VLAN_ID,
> +				 GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0,
> +				 &vlan_id, &v2);
> +	if (!result) {
> +		h_eth->type = 0x8100;
> +
> +		header_size += sizeof(struct vlantag);
> +		h_vlan = (struct vlantag *)(h_eth + 1);
> +		h_vlan->vlan = vlan_id;
> +		h_vlan->subtype = 0x0800;
> +		h_ip = (struct iphdr *)(h_vlan + 1);
> +	} else {
> +		h_eth->type = 0x0800;
> +		h_ip = (struct iphdr *)(h_eth + 1);
> +	}
> +
> +	header_size += sizeof(struct iphdr);
> +	h_ip->ver_len = 0x45;
> +	h_ip->ttl = 10;
> +	h_ip->proto = 0x11;
> +	h_ip->src = 0x00000000;
> +	h_ip->dest = 0xffffffff;
> +
> +	header_size += sizeof(struct udphdr);
> +	h_udp = (struct udphdr *)(h_ip + 1);
> +	h_udp->src = GELIC_DEBUG_PORT;
> +	h_udp->dest = GELIC_DEBUG_PORT;
> +
> +	pmsgc = pmsg = (char *)(h_udp + 1);
> +}
> +
> +static void gelic_debug_shutdown(void)
> +{
> +	if (bus_addr)
> +		unmap_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID,
> +			      bus_addr, sizeof(dbg));
> +	lv1_close_device(GELIC_BUS_ID, GELIC_DEVICE_ID);
> +}
> +
> +static void gelic_sendbuf(int msgsize)
> +{
> +	u16 *p;
> +	u32 sum;
> +	int i;
> +
> +	dbg.descr.buf_size = header_size + msgsize;
> +	h_ip->total_length = msgsize + sizeof(struct udphdr) +
> +			     sizeof(struct iphdr);
> +	h_udp->len = msgsize + sizeof(struct udphdr);
> +
> +	h_ip->checksum = 0;
> +	sum = 0;
> +	p = (u16 *)h_ip;
> +	for (i = 0; i < 5; i++)
> +		sum += *p++;
> +	h_ip->checksum = ~(sum + (sum >> 16));
> +
> +	dbg.descr.dmac_cmd_status = GELIC_DESCR_DMA_CMD_NO_CHKSUM |
> +				    GELIC_DESCR_TX_DMA_FRAME_TAIL;
> +	dbg.descr.result_size = 0;
> +	dbg.descr.data_status = 0;
> +
> +	wmb();
> +
> +	lv1_net_start_tx_dma(GELIC_BUS_ID, GELIC_DEVICE_ID, bus_addr, 0);
> +
> +	while ((dbg.descr.dmac_cmd_status & GELIC_DESCR_DMA_STAT_MASK) ==
> +	       GELIC_DESCR_DMA_CARDOWNED)
> +		cpu_relax();
> +}
> +
> +static void ps3gelic_udbg_putc(char ch)
> +{
> +	*pmsgc++ = ch;
> +	if (ch == '\n' || (pmsgc-pmsg) >= GELIC_MAX_MESSAGE_SIZE) {
> +		gelic_sendbuf(pmsgc-pmsg);
> +		pmsgc = pmsg;
> +	}
> +}
> +
> +void __init udbg_init_ps3gelic(void)
> +{
> +	gelic_debug_init();
> +	udbg_putc = ps3gelic_udbg_putc;
> +}
> +
> +void udbg_shutdown_ps3gelic(void)
> +{
> +	udbg_putc = NULL;
> +	gelic_debug_shutdown();
> +}
> +EXPORT_SYMBOL(udbg_shutdown_ps3gelic);
> diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
> index d82a82d..e743c94 100644
> --- a/drivers/net/ps3_gelic_net.c
> +++ b/drivers/net/ps3_gelic_net.c
> @@ -1674,6 +1674,9 @@ static int __devinit ps3_gelic_driver_probe(struct ps3_system_bus_device *dev)
>  	int result;
>  
>  	pr_debug("%s: called\n", __func__);
> +
> +	udbg_shutdown_ps3gelic();
> +
>  	result = ps3_open_hv_device(dev);
>  
>  	if (result) {
> diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h
> index d3fadfb..a93df6a 100644
> --- a/drivers/net/ps3_gelic_net.h
> +++ b/drivers/net/ps3_gelic_net.h
> @@ -359,6 +359,12 @@ static inline void *port_priv(struct gelic_port *port)
>  	return port->priv;
>  }
>  
> +#ifdef CONFIG_PPC_EARLY_DEBUG_PS3GELIC
> +extern void udbg_shutdown_ps3gelic(void);
> +#else
> +static inline void udbg_shutdown_ps3gelic(void) {}
> +#endif
> +
>  extern int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask);
>  /* shared netdev ops */
>  extern void gelic_card_up(struct gelic_card *card);

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

* Re: [PATCH part1 v2 2/9] ps3: Add helper functions to read highmem info from the repository
  2011-08-11 19:31   ` [PATCH part1 v2 2/9] ps3: Add helper functions to read highmem info from the repository Andre Heider
@ 2011-08-23 20:53     ` Geoff Levand
  0 siblings, 0 replies; 70+ messages in thread
From: Geoff Levand @ 2011-08-23 20:53 UTC (permalink / raw)
  To: Andre Heider; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

On 08/11/2011 12:31 PM, Andre Heider wrote:
> An earlier step in the boot chain can preallocate the highmem region.
> A boot loader doing so will place the region infos in the repository.
> Provide helper functions to read the required nodes.
> 
> Signed-off-by: Andre Heider <a.heider@gmail.com>
> ---
>  arch/powerpc/platforms/ps3/platform.h   |    3 ++
>  arch/powerpc/platforms/ps3/repository.c |   36 +++++++++++++++++++++++++++++++
>  2 files changed, 39 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
> index 9a196a8..d9b4ec0 100644
> --- a/arch/powerpc/platforms/ps3/platform.h
> +++ b/arch/powerpc/platforms/ps3/platform.h
> @@ -187,6 +187,9 @@ int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size);
>  int ps3_repository_read_region_total(u64 *region_total);
>  int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size,
>  	u64 *region_total);
> +int ps3_repository_read_highmem_base(u64 *highmem_base);
> +int ps3_repository_read_highmem_size(u64 *highmem_size);
> +int ps3_repository_read_highmem_info(u64 *highmem_base, u64 *highmem_size);

In the general case we could have multiple regions.  If we
add a region arg here we can handle that if needed.
region_index would be {1..}.  ps3_repository_read_highmem_info
could hold how many regions, so:

  int ps3_repository_read_highmem_base(unsigned int region_index, u64 *highmem_base);
  int ps3_repository_read_highmem_size(unsigned int region_index, u64 *highmem_size);
  int ps3_repository_read_highmem_region(unsigned int region_index, u64 *highmem_base, u64 *highmem_size);

>  
>  /* repository pme info */
>  
> diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c
> index 5e304c2..9908d61 100644
> --- a/arch/powerpc/platforms/ps3/repository.c
> +++ b/arch/powerpc/platforms/ps3/repository.c
> @@ -778,6 +778,42 @@ int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total)
>  		: ps3_repository_read_region_total(region_total);
>  }
>  
> +int ps3_repository_read_highmem_base(u64 *highmem_base)
> +{
> +	return read_node(PS3_LPAR_ID_CURRENT,
> +			 make_first_field("bi", 0),
> +			 make_field("highmem", 0),
> +			 make_field("base", 0),
> +			 0,
> +			 highmem_base, NULL);
> +}

I think something like this seems better:

int ps3_repository_read_highmem_base(unsigned int region_index, u64 *highmem_base)
{
	return read_node(PS3_LPAR_ID_CURRENT,
		make_first_field("highmem", 0),
		make_field("region", region_index),
		make_field("base", 0),
		0,
		highmem_base, NULL);
}

> +
> +int ps3_repository_read_highmem_size(u64 *highmem_size)
> +{
> +	return read_node(PS3_LPAR_ID_CURRENT,
> +			 make_first_field("bi", 0),
> +			 make_field("highmem", 0),
> +			 make_field("size", 0),
> +			 0,
> +			 highmem_size, NULL);
> +}
> +
> +/**
> + * ps3_repository_read_highmem_info - Read high memory info
> + * @highmem_base: High memory base address.
> + * @highmem_size: High mode memory size.
> + */
> +
> +int ps3_repository_read_highmem_info(u64 *highmem_base, u64 *highmem_size)
> +{
> +	int result;
> +
> +	*highmem_base = 0;
> +	result = ps3_repository_read_highmem_base(highmem_base);
> +	return result ? result
> +		: ps3_repository_read_highmem_size(highmem_size);


	ps3_repository_read_highmem_base(1, highmem_base);
	...
> +}
> +
>  /**
>   * ps3_repository_read_num_spu_reserved - Number of physical spus reserved.
>   * @num_spu: Number of physical spus.

-Geoff

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

* Re: [PATCH part1 v2 3/9] ps3: Get lv1 high memory region from the repository
  2011-08-11 19:31   ` [PATCH part1 v2 3/9] ps3: Get lv1 high memory region " Andre Heider
@ 2011-08-23 20:53     ` Geoff Levand
  0 siblings, 0 replies; 70+ messages in thread
From: Geoff Levand @ 2011-08-23 20:53 UTC (permalink / raw)
  To: Andre Heider; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

On 08/11/2011 12:31 PM, Andre Heider wrote:
> This lets the bootloader preallocate the high lv1 region and pass its
> location to the kernel through the repository. Thus, it can be used to
> hold the initrd. If the region info doesn't exist, the kernel retains
> the old behavior and attempts to allocate the region itself.
> 
> Based on the patch
> "[PS3] Get lv1 high memory region from devtree"
> from Hector Martin <hector@marcansoft.com>
> 
> Signed-off-by: Andre Heider <a.heider@gmail.com>
> ---
>  arch/powerpc/platforms/ps3/mm.c |   46 ++++++++++++++++++++++++++++++++++++--
>  1 files changed, 43 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
> index c204588..983b719 100644
> --- a/arch/powerpc/platforms/ps3/mm.c
> +++ b/arch/powerpc/platforms/ps3/mm.c
> @@ -78,12 +78,14 @@ enum {
>   * @base: base address
>   * @size: size in bytes
>   * @offset: difference between base and rm.size
> + * @destroy: flag if region should be destroyed upon shutdown
>   */
>  
>  struct mem_region {
>  	u64 base;
>  	u64 size;
>  	unsigned long offset;
> +	int destroy;
>  };
>  
>  /**
> @@ -261,6 +263,7 @@ static int ps3_mm_region_create(struct mem_region *r, unsigned long size)
>  		goto zero_region;
>  	}
>  
> +	r->destroy = 1;
>  	r->offset = r->base - map.rm.size;
>  	return result;
>  
> @@ -279,6 +282,12 @@ static void ps3_mm_region_destroy(struct mem_region *r)
>  	int result;
>  
>  	DBG("%s:%d: r->base = %llxh\n", __func__, __LINE__, r->base);
> +
> +	if (!r->destroy) {
> +		DBG("%s:%d: not destroying region\n", __func__, __LINE__);
> +		return;
> +	}
> +
>  	if (r->base) {
>  		result = lv1_release_memory(r->base);
>  		BUG_ON(result);
> @@ -287,6 +296,29 @@ static void ps3_mm_region_destroy(struct mem_region *r)
>  	}
>  }
>  
> +static int ps3_mm_get_repository_highmem(struct mem_region *r)
> +{
> +	int result = ps3_repository_read_highmem_info(&r->base, &r->size);
> +
> +	if (result)
> +		goto zero_region;
> +
> +	if (!r->base || !r->size) {
> +		result = -1;
> +		goto zero_region;
> +	}
> +
> +	r->offset = r->base - map.rm.size;
> +	DBG("%s:%d got high region from repository: %llxh %llxh\n",
> +	    __func__, __LINE__, r->base, r->size);
> +	return 0;
> +
> +zero_region:
> +	DBG("%s:%d no high region in repository...\n", __func__, __LINE__);

Three dots implies something more is on its way.  I
don't think we need them.

> +	r->size = r->base = r->offset = 0;
> +	return result;
> +}
> +
>  /**
>   * ps3_mm_add_memory - hot add memory
>   */
> @@ -303,6 +335,12 @@ static int __init ps3_mm_add_memory(void)
>  
>  	BUG_ON(!mem_init_done);
>  
> +	if (!map.r1.size) {
> +		DBG("%s:%d: no region 1, not adding memory\n",
> +		    __func__, __LINE__);
> +		return 0;
> +	}
> +
>  	start_addr = map.rm.size;
>  	start_pfn = start_addr >> PAGE_SHIFT;
>  	nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT;
> @@ -1217,9 +1255,11 @@ void __init ps3_mm_init(void)
>  	BUG_ON(map.rm.base);
>  	BUG_ON(!map.rm.size);
>  
> -
> -	/* arrange to do this in ps3_mm_add_memory */
> -	ps3_mm_region_create(&map.r1, map.total - map.rm.size);
> +	/* check if we got the highmem region from an earlier boot step */
> +	if (ps3_mm_get_repository_highmem(&map.r1)) {
> +		/* arrange to do this in ps3_mm_add_memory */
> +		ps3_mm_region_create(&map.r1, map.total - map.rm.size);
> +	}
>  
>  	/* correct map.total for the real total amount of memory we use */
>  	map.total = map.rm.size + map.r1.size;

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

* Re: [PATCH part1 v2 4/9] Add region 1 memory early
  2011-08-11 19:31   ` [PATCH part1 v2 4/9] Add region 1 memory early Andre Heider
@ 2011-08-23 20:53     ` Geoff Levand
  2011-08-23 22:37       ` [Cbe-oss-dev] " Antonio Ospite
  0 siblings, 1 reply; 70+ messages in thread
From: Geoff Levand @ 2011-08-23 20:53 UTC (permalink / raw)
  To: Andre Heider; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

On 08/11/2011 12:31 PM, Andre Heider wrote:
> From: Hector Martin <hector@marcansoft.com>
> 
> Real mode memory can be limited and runs out quickly as memory is
> allocated during kernel startup.
> Having region1 available sooner fixes this.
> 
> Signed-off-by: Hector Martin <hector@marcansoft.com>
> [a.heider: Various cleanups to make checkpatch.pl happy]
> Signed-off-by: Andre Heider <a.heider@gmail.com>
> ---
>  arch/powerpc/platforms/ps3/mm.c |   75 +++++++--------------------------------
>  1 files changed, 13 insertions(+), 62 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
> index 983b719..68b3879 100644
> --- a/arch/powerpc/platforms/ps3/mm.c
> +++ b/arch/powerpc/platforms/ps3/mm.c
> @@ -20,7 +20,6 @@
>  
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> -#include <linux/memory_hotplug.h>
>  #include <linux/memblock.h>
>  #include <linux/slab.h>
>  
> @@ -94,10 +93,8 @@ struct mem_region {
>   * @vas_id - HV virtual address space id
>   * @htab_size: htab size in bytes
>   *
> - * The HV virtual address space (vas) allows for hotplug memory regions.
> - * Memory regions can be created and destroyed in the vas at runtime.

This is still true, so we should keep these comments.  We
are only changing the way we use the feature.

>   * @rm: real mode (bootmem) region
> - * @r1: hotplug memory region(s)
> + * @r1: high memory region

high memory region(s)

>   *
>   * ps3 addresses
>   * virt_addr: a cpu 'translated' effective address
> @@ -223,10 +220,6 @@ void ps3_mm_vas_destroy(void)
>  	}
>  }
>  
> -/*============================================================================*/
> -/* memory hotplug routines                                                    */
> -/*============================================================================*/
> -
>  /**
>   * ps3_mm_region_create - create a memory region in the vas
>   * @r: pointer to a struct mem_region to accept initialized values
> @@ -319,57 +312,6 @@ zero_region:
>  	return result;
>  }
>  
> -/**
> - * ps3_mm_add_memory - hot add memory
> - */
> -
> -static int __init ps3_mm_add_memory(void)
> -{
> -	int result;
> -	unsigned long start_addr;
> -	unsigned long start_pfn;
> -	unsigned long nr_pages;
> -
> -	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
> -		return -ENODEV;
> -
> -	BUG_ON(!mem_init_done);
> -
> -	if (!map.r1.size) {
> -		DBG("%s:%d: no region 1, not adding memory\n",
> -		    __func__, __LINE__);
> -		return 0;
> -	}
> -
> -	start_addr = map.rm.size;
> -	start_pfn = start_addr >> PAGE_SHIFT;
> -	nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT;
> -
> -	DBG("%s:%d: start_addr %lxh, start_pfn %lxh, nr_pages %lxh\n",
> -		__func__, __LINE__, start_addr, start_pfn, nr_pages);
> -
> -	result = add_memory(0, start_addr, map.r1.size);
> -
> -	if (result) {
> -		pr_err("%s:%d: add_memory failed: (%d)\n",
> -			__func__, __LINE__, result);
> -		return result;
> -	}
> -
> -	memblock_add(start_addr, map.r1.size);
> -	memblock_analyze();
> -
> -	result = online_pages(start_pfn, nr_pages);
> -
> -	if (result)
> -		pr_err("%s:%d: online_pages failed: (%d)\n",
> -			__func__, __LINE__, result);
> -
> -	return result;
> -}
> -
> -device_initcall(ps3_mm_add_memory);
> -
>  /*============================================================================*/
>  /* dma routines                                                               */
>  /*============================================================================*/
> @@ -1256,14 +1198,23 @@ void __init ps3_mm_init(void)
>  	BUG_ON(!map.rm.size);
>  
>  	/* check if we got the highmem region from an earlier boot step */
> -	if (ps3_mm_get_repository_highmem(&map.r1)) {
> -		/* arrange to do this in ps3_mm_add_memory */
> +	if (ps3_mm_get_repository_highmem(&map.r1))
>  		ps3_mm_region_create(&map.r1, map.total - map.rm.size);
> -	}

This should be folded into patch #3.

>  
>  	/* correct map.total for the real total amount of memory we use */
>  	map.total = map.rm.size + map.r1.size;
>  
> +	if (!map.r1.size) {
> +		DBG("%s:%d: no region 1, not adding memory\n",
> +			__func__, __LINE__);
> +	} else {

Remove brackets around a single line conditional.

> +		DBG("%s:%d: adding memory: start %llxh, size %llxh\n",
> +			__func__, __LINE__, map.rm.size, map.r1.size);
> +
> +		memblock_add(map.rm.size, map.r1.size);
> +		memblock_analyze();
> +	}
> +
>  	DBG(" <- %s:%d\n", __func__, __LINE__);
>  }
>  

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

* Re: [PATCH part1 v2 5/9] ps3: MEMORY_HOTPLUG is not a requirement anymore
  2011-08-11 19:31   ` [PATCH part1 v2 5/9] ps3: MEMORY_HOTPLUG is not a requirement anymore Andre Heider
@ 2011-08-23 20:53     ` Geoff Levand
  0 siblings, 0 replies; 70+ messages in thread
From: Geoff Levand @ 2011-08-23 20:53 UTC (permalink / raw)
  To: Andre Heider; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

On 08/11/2011 12:31 PM, Andre Heider wrote:
> Signed-off-by: Andre Heider <a.heider@gmail.com>
> ---
>  arch/powerpc/platforms/ps3/Kconfig |    1 -
>  1 files changed, 0 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
> index 476d9d9..84df5c8 100644
> --- a/arch/powerpc/platforms/ps3/Kconfig
> +++ b/arch/powerpc/platforms/ps3/Kconfig
> @@ -7,7 +7,6 @@ config PPC_PS3
>  	select USB_OHCI_BIG_ENDIAN_MMIO
>  	select USB_ARCH_HAS_EHCI
>  	select USB_EHCI_BIG_ENDIAN_MMIO
> -	select MEMORY_HOTPLUG


This one is OK, once the others are fixed up.

-Geoff

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

* Re: [PATCH part1 v2 6/9] ps3: Detect the current lpar
  2011-08-11 19:31   ` [PATCH part1 v2 6/9] ps3: Detect the current lpar Andre Heider
@ 2011-08-23 22:08     ` Geoff Levand
  0 siblings, 0 replies; 70+ messages in thread
From: Geoff Levand @ 2011-08-23 22:08 UTC (permalink / raw)
  To: Andre Heider; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

Hi,

On 08/11/2011 12:31 PM, Andre Heider wrote:
> Detect it by reading the ss laid repository node, and make it
> accessible via ps3_get_ss_laid().

I'm wondering now if we even need this.  It is mainly used by your
later patch 8/9 that modifies ps3flash_init() to test if we should
call ps3_system_bus_driver_register().  If we don't use
ps3_get_ss_laid() and just allow ps3_system_bus_driver_register()
to be called, would the device probe fail and have the same result
as the test?

I would prefer to not have ps3_get_ss_laid() if possible.

-Geoff

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

* Re: [PATCH part1 v2 8/9] ps3flash: Refuse to work in lpars other than OtherOS
  2011-08-11 19:31   ` [PATCH part1 v2 8/9] ps3flash: Refuse to work in lpars other than OtherOS Andre Heider
@ 2011-08-23 22:12     ` Geoff Levand
  0 siblings, 0 replies; 70+ messages in thread
From: Geoff Levand @ 2011-08-23 22:12 UTC (permalink / raw)
  To: Andre Heider; +Cc: cbe-oss-dev, Hector Martin, linuxppc-dev

On 08/11/2011 12:31 PM, Andre Heider wrote:
> The driver implements a character and misc device, meant for the
> axed OtherOS to exchange various settings with GameOS.
> Since Firmware 3.21 there is no support anymore to write these
> settings, so test if we're running in OtherOS, and refuse to load
> if that is not the case.

Please see my comments to the v1 patch regarding this text.

> Signed-off-by: Andre Heider <a.heider@gmail.com>
> ---
>  arch/powerpc/platforms/ps3/Kconfig |    2 +-
>  drivers/char/ps3flash.c            |    7 +++++++
>  2 files changed, 8 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
> index 84df5c8..72fdecd 100644
> --- a/arch/powerpc/platforms/ps3/Kconfig
> +++ b/arch/powerpc/platforms/ps3/Kconfig
> @@ -121,7 +121,7 @@ config PS3_FLASH
>  
>  	  This support is required to access the PS3 FLASH ROM, which
>  	  contains the boot loader and some boot options.
> -	  In general, all users will say Y or M.
> +	  In general, all PS3 OtherOS users will say Y or M.
>  
>  	  As this driver needs a fixed buffer of 256 KiB of memory, it can
>  	  be disabled on the kernel command line using "ps3flash=off", to
> diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
> index d0c57c2..fc6d867 100644
> --- a/drivers/char/ps3flash.c
> +++ b/drivers/char/ps3flash.c
> @@ -25,6 +25,7 @@
>  
>  #include <asm/lv1call.h>
>  #include <asm/ps3stor.h>
> +#include <asm/firmware.h>
>  
>  
>  #define DEVICE_NAME		"ps3flash"
> @@ -464,6 +465,12 @@ static struct ps3_system_bus_driver ps3flash = {
>  
>  static int __init ps3flash_init(void)
>  {
> +	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
> +		return -ENODEV;
> +
> +	if (ps3_get_ss_laid() != PS3_SS_LAID_OTHEROS)
> +		return -ENODEV;
> +
>  	return ps3_system_bus_driver_register(&ps3flash);
>  }
>  

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

* Re: [Cbe-oss-dev] [PATCH part1 v2 4/9] Add region 1 memory early
  2011-08-23 20:53     ` Geoff Levand
@ 2011-08-23 22:37       ` Antonio Ospite
  2011-08-24  2:15         ` Geoff Levand
  0 siblings, 1 reply; 70+ messages in thread
From: Antonio Ospite @ 2011-08-23 22:37 UTC (permalink / raw)
  To: Geoff Levand; +Cc: cbe-oss-dev, Andre Heider, linuxppc-dev, Hector Martin

[-- Attachment #1: Type: text/plain, Size: 1095 bytes --]

On Tue, 23 Aug 2011 13:53:46 -0700
Geoff Levand <geoff@infradead.org> wrote:

[...]
> >  
> > +	if (!map.r1.size) {
> > +		DBG("%s:%d: no region 1, not adding memory\n",
> > +			__func__, __LINE__);
> > +	} else {
> 
> Remove brackets around a single line conditional.
> 
> > +		DBG("%s:%d: adding memory: start %llxh, size %llxh\n",
> > +			__func__, __LINE__, map.rm.size, map.r1.size);
> > +
> > +		memblock_add(map.rm.size, map.r1.size);
> > +		memblock_analyze();
> > +	}
> > +

In Documentation/CodingStyle I read that if [only] one branch is a
single statement then the parenthesis are OK (and even recommended) for
both branches, I guess this is for style consistency. See Chapter 3,
around line 169 on my copy. I guess the wording on that paragraph can
be made more explicit, I'll try to fix that up.

Regards,
   Antonio

-- 
Antonio Ospite
http://ao2.it

PGP public key ID: 0x4553B001

A: Because it messes up the order in which people normally read text.
   See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

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

* Re: [Cbe-oss-dev] [PATCH part1 v2 4/9] Add region 1 memory early
  2011-08-23 22:37       ` [Cbe-oss-dev] " Antonio Ospite
@ 2011-08-24  2:15         ` Geoff Levand
  0 siblings, 0 replies; 70+ messages in thread
From: Geoff Levand @ 2011-08-24  2:15 UTC (permalink / raw)
  To: Antonio Ospite; +Cc: cbe-oss-dev, Andre Heider, linuxppc-dev, Hector Martin

Hi Antonio,

On 08/23/2011 03:37 PM, Antonio Ospite wrote:
> Geoff Levand <geoff@infradead.org> wrote:
>> > +	if (!map.r1.size) {
>> > +		DBG("%s:%d: no region 1, not adding memory\n",
>> > +			__func__, __LINE__);
>> > +	} else {
>> 
>> Remove brackets around a single line conditional.
>> 
>> > +		DBG("%s:%d: adding memory: start %llxh, size %llxh\n",
>> > +			__func__, __LINE__, map.rm.size, map.r1.size);
>> > +
>> > +		memblock_add(map.rm.size, map.r1.size);
>> > +		memblock_analyze();
>> > +	}
>> > +
> 
> In Documentation/CodingStyle I read that if [only] one branch is a
> single statement then the parenthesis are OK (and even recommended) for
> both branches, I guess this is for style consistency. See Chapter 3,
> around line 169 on my copy. I guess the wording on that paragraph can
> be made more explicit, I'll try to fix that up.

Thanks for the comments.  I don't think its such an important change,
mainly for consistency of style within the PS3 files.

-Geoff

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

* Re: [Cbe-oss-dev] [PATCH 01/15] [PS3] Add udbg driver using the PS3 gelic Ethernet device
  2011-08-11 17:32       ` Andre Heider
@ 2011-08-31  4:26         ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 70+ messages in thread
From: Benjamin Herrenschmidt @ 2011-08-31  4:26 UTC (permalink / raw)
  To: Andre Heider
  Cc: cbe-oss-dev, Geoff Levand, Hector Martin, linuxppc-dev, Arnd Bergmann

On Thu, 2011-08-11 at 19:32 +0200, Andre Heider wrote:
> On Thu, Aug 11, 2011 at 2:13 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Thursday 04 August 2011, Geoff Levand wrote:
> >> > + *
> >> > + * udbg debug output routine via GELIC UDP broadcasts
> >> > + * Copyright (C) 2010 Hector Martin <hector@marcansoft.com>
> >> > + * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>
> >>
> >> Some of this seems to be taken from the gelic driver, so shouldn't
> >> the copyright info from there be included here?
> >
> > Moreover, if there is a significant amount of code duplication
> > between this driver and gelic, I would expect to actually share
> > the code instead, either by integrating the udbg code into the
> > gelic driver in form of netconsole support, or by moving the
> > common parts into a separate module.
> 
> No, thankfully there is no significant code duplication :)
> It contains a few structs and defines found elsewhere, but that's
> because it's not a real netdev. It just prepares the eth/ip/udp header
> once for its single purpose, then uses the hypervisor to send and poll
> - in contrast to the gelic driver, which reuses its irqhandler for
> netconsole support.

Ack. As long as it's not enabled by default and understood to be what it
is, ie, a tool to debug really early boot code before a more "proper"
console is available, I have no objection. There is really no code dup,
just a couple of struct definitions and it's not a big deal.

I'll merge it.

Cheers,
Ben.

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

* Re: [PATCH part1 v2 0/9] ps3: General improvements and preparation for support more than the OtherOS lpar
  2011-08-11 19:31 ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support " Andre Heider
                     ` (8 preceding siblings ...)
  2011-08-11 19:31   ` [PATCH part1 v2 9/9] ps3: Only prealloc the flash bounce buffer for the OtherOS lpar Andre Heider
@ 2011-08-31  4:29   ` Benjamin Herrenschmidt
  9 siblings, 0 replies; 70+ messages in thread
From: Benjamin Herrenschmidt @ 2011-08-31  4:29 UTC (permalink / raw)
  To: Andre Heider; +Cc: Geoff Levand, cbe-oss-dev, Hector Martin, linuxppc-dev

On Thu, 2011-08-11 at 21:31 +0200, Andre Heider wrote:
> This is the first part of my previous series including the discussed fixups.
> 
> I dropped the old #2 ([PS3] Get lv1 high memory region from devtree)
> and replaced it with 2 new patches, now #2 and #3. The latter contains
> the fixups mentioned on the old #2 thread.

Just back from vacation. I like these, good stuff. I'd like to have that
in soon, can you address the remaining minor comments from Geoff ?

Cheers,
Ben.

> Patches are based on today's Linus' tree.
> 
> Andre Heider (7):
>   ps3: Add helper functions to read highmem info from the repository
>   ps3: Get lv1 high memory region from the repository
>   ps3: MEMORY_HOTPLUG is not a requirement anymore
>   ps3: Detect the current lpar
>   ps3: Log the detected lpar on startup
>   ps3flash: Refuse to work in lpars other than OtherOS
>   ps3: Only prealloc the flash bounce buffer for the OtherOS lpar
> 
> Hector Martin (2):
>   Add udbg driver using the PS3 gelic Ethernet device
>   Add region 1 memory early
> 
>  arch/powerpc/Kconfig.debug              |    8 +
>  arch/powerpc/include/asm/ps3.h          |    7 +
>  arch/powerpc/include/asm/udbg.h         |    1 +
>  arch/powerpc/kernel/udbg.c              |    2 +
>  arch/powerpc/platforms/ps3/Kconfig      |   15 ++-
>  arch/powerpc/platforms/ps3/Makefile     |    1 +
>  arch/powerpc/platforms/ps3/gelic_udbg.c |  273 +++++++++++++++++++++++++++++++
>  arch/powerpc/platforms/ps3/mm.c         |   85 +++++------
>  arch/powerpc/platforms/ps3/platform.h   |    7 +
>  arch/powerpc/platforms/ps3/repository.c |   55 ++++++
>  arch/powerpc/platforms/ps3/setup.c      |   27 +++-
>  drivers/char/ps3flash.c                 |    7 +
>  drivers/net/ps3_gelic_net.c             |    3 +
>  drivers/net/ps3_gelic_net.h             |    6 +
>  14 files changed, 447 insertions(+), 50 deletions(-)
>  create mode 100644 arch/powerpc/platforms/ps3/gelic_udbg.c
> 

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

* [PATCH] [ps3] Add gelic udbg driver
  2011-08-23 20:53     ` Geoff Levand
@ 2011-08-31 16:32       ` Geoff Levand
  0 siblings, 0 replies; 70+ messages in thread
From: Geoff Levand @ 2011-08-31 16:32 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: cbe-oss-dev, Andre Heider, linuxppc-dev, Hector Martin

From: Hector Martin <hector@marcansoft.com>

Add a new udbg driver for the PS3 gelic Ehthernet device.

This driver shares only a few stucture and constant definitions with the
gelic Ethernet device driver, so is implemented as a stand-alone driver
with no dependencies on the gelic Ethernet device driver.

Signed-off-by: Hector Martin <hector@marcansoft.com>
Signed-off-by: Andre Heider <a.heider@gmail.com>
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
 arch/powerpc/Kconfig.debug              |    8 +
 arch/powerpc/include/asm/udbg.h         |    1 +
 arch/powerpc/kernel/udbg.c              |    2 +
 arch/powerpc/platforms/ps3/Kconfig      |   12 ++
 arch/powerpc/platforms/ps3/Makefile     |    1 +
 arch/powerpc/platforms/ps3/gelic_udbg.c |  273 +++++++++++++++++++++++++++++++
 drivers/net/ps3_gelic_net.c             |    3 +
 drivers/net/ps3_gelic_net.h             |    6 +
 8 files changed, 306 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/platforms/ps3/gelic_udbg.c

diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 067cb84..ab2335f 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -258,6 +258,14 @@ config PPC_EARLY_DEBUG_WSP
 	depends on PPC_WSP
 	select PPC_UDBG_16550
 
+config PPC_EARLY_DEBUG_PS3GELIC
+	bool "Early debugging through the PS3 Ethernet port"
+	depends on PPC_PS3
+	select PS3GELIC_UDBG
+	help
+	  Select this to enable early debugging for the PlayStation3 via
+	  UDP broadcasts sent out through the Ethernet port.
+
 endchoice
 
 config PPC_EARLY_DEBUG_HVSI_VTERMNO
diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h
index 93e05d1..7cf796f 100644
--- a/arch/powerpc/include/asm/udbg.h
+++ b/arch/powerpc/include/asm/udbg.h
@@ -54,6 +54,7 @@ extern void __init udbg_init_40x_realmode(void);
 extern void __init udbg_init_cpm(void);
 extern void __init udbg_init_usbgecko(void);
 extern void __init udbg_init_wsp(void);
+extern void __init udbg_init_ps3gelic(void);
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_UDBG_H */
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index faa82c1..5b3e98e 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -67,6 +67,8 @@ void __init udbg_early_init(void)
 	udbg_init_usbgecko();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_WSP)
 	udbg_init_wsp();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
+	udbg_init_ps3gelic();
 #endif
 
 #ifdef CONFIG_PPC_EARLY_DEBUG
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index dfe316b..476d9d9 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -148,4 +148,16 @@ config PS3_LPM
 	  profiling support of the Cell processor with programs like
 	  oprofile and perfmon2, then say Y or M, otherwise say N.
 
+config PS3GELIC_UDBG
+	bool "PS3 udbg output via UDP broadcasts on Ethernet"
+	depends on PPC_PS3
+	help
+	  Enables udbg early debugging output by sending broadcast UDP
+	  via the Ethernet port (UDP port number 18194).
+
+	  This driver uses a trivial implementation and is independent
+	  from the main network driver.
+
+	  If in doubt, say N here.
+
 endmenu
diff --git a/arch/powerpc/platforms/ps3/Makefile b/arch/powerpc/platforms/ps3/Makefile
index ac1bdf8..02b9e63 100644
--- a/arch/powerpc/platforms/ps3/Makefile
+++ b/arch/powerpc/platforms/ps3/Makefile
@@ -2,6 +2,7 @@ obj-y += setup.o mm.o time.o hvcall.o htab.o repository.o
 obj-y += interrupt.o exports.o os-area.o
 obj-y += system-bus.o
 
+obj-$(CONFIG_PS3GELIC_UDBG) += gelic_udbg.o
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_SPU_BASE) += spu.o
 obj-y += device-init.o
diff --git a/arch/powerpc/platforms/ps3/gelic_udbg.c b/arch/powerpc/platforms/ps3/gelic_udbg.c
new file mode 100644
index 0000000..20b46a1
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/gelic_udbg.c
@@ -0,0 +1,273 @@
+/*
+ * udbg debug output routine via GELIC UDP broadcasts
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2006, 2007 Sony Corporation
+ * Copyright (C) 2010 Hector Martin <hector@marcansoft.com>
+ * Copyright (C) 2011 Andre Heider <a.heider@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ */
+
+#include <asm/io.h>
+#include <asm/udbg.h>
+#include <asm/lv1call.h>
+
+#define GELIC_BUS_ID 1
+#define GELIC_DEVICE_ID 0
+#define GELIC_DEBUG_PORT 18194
+#define GELIC_MAX_MESSAGE_SIZE 1000
+
+#define GELIC_LV1_GET_MAC_ADDRESS 1
+#define GELIC_LV1_GET_VLAN_ID 4
+#define GELIC_LV1_VLAN_TX_ETHERNET_0 2
+
+#define GELIC_DESCR_DMA_STAT_MASK 0xf0000000
+#define GELIC_DESCR_DMA_CARDOWNED 0xa0000000
+
+#define GELIC_DESCR_TX_DMA_IKE 0x00080000
+#define GELIC_DESCR_TX_DMA_NO_CHKSUM 0x00000000
+#define GELIC_DESCR_TX_DMA_FRAME_TAIL 0x00040000
+
+#define GELIC_DESCR_DMA_CMD_NO_CHKSUM (GELIC_DESCR_DMA_CARDOWNED | \
+				       GELIC_DESCR_TX_DMA_IKE | \
+				       GELIC_DESCR_TX_DMA_NO_CHKSUM)
+
+static u64 bus_addr;
+
+struct gelic_descr {
+	/* as defined by the hardware */
+	__be32 buf_addr;
+	__be32 buf_size;
+	__be32 next_descr_addr;
+	__be32 dmac_cmd_status;
+	__be32 result_size;
+	__be32 valid_size;	/* all zeroes for tx */
+	__be32 data_status;
+	__be32 data_error;	/* all zeroes for tx */
+} __attribute__((aligned(32)));
+
+struct debug_block {
+	struct gelic_descr descr;
+	u8 pkt[1520];
+} __packed;
+
+struct ethhdr {
+	u8 dest[6];
+	u8 src[6];
+	u16 type;
+} __packed;
+
+struct vlantag {
+	u16 vlan;
+	u16 subtype;
+} __packed;
+
+struct iphdr {
+	u8 ver_len;
+	u8 dscp_ecn;
+	u16 total_length;
+	u16 ident;
+	u16 frag_off_flags;
+	u8 ttl;
+	u8 proto;
+	u16 checksum;
+	u32 src;
+	u32 dest;
+} __packed;
+
+struct udphdr {
+	u16 src;
+	u16 dest;
+	u16 len;
+	u16 checksum;
+} __packed;
+
+static __iomem struct ethhdr *h_eth;
+static __iomem struct vlantag *h_vlan;
+static __iomem struct iphdr *h_ip;
+static __iomem struct udphdr *h_udp;
+
+static __iomem char *pmsg;
+static __iomem char *pmsgc;
+
+static __iomem struct debug_block dbg __attribute__((aligned(32)));
+
+static int header_size;
+
+static void map_dma_mem(int bus_id, int dev_id, void *start, size_t len,
+			u64 *real_bus_addr)
+{
+	s64 result;
+	u64 real_addr = ((u64)start) & 0x0fffffffffffffffUL;
+	u64 real_end = real_addr + len;
+	u64 map_start = real_addr & ~0xfff;
+	u64 map_end = (real_end + 0xfff) & ~0xfff;
+	u64 bus_addr = 0;
+
+	u64 flags = 0xf800000000000000UL;
+
+	result = lv1_allocate_device_dma_region(bus_id, dev_id,
+						map_end - map_start, 12, 0,
+						&bus_addr);
+	if (result)
+		lv1_panic(0);
+
+	result = lv1_map_device_dma_region(bus_id, dev_id, map_start,
+					   bus_addr, map_end - map_start,
+					   flags);
+	if (result)
+		lv1_panic(0);
+
+	*real_bus_addr = bus_addr + real_addr - map_start;
+}
+
+static int unmap_dma_mem(int bus_id, int dev_id, u64 bus_addr, size_t len)
+{
+	s64 result;
+	u64 real_bus_addr;
+
+	real_bus_addr = bus_addr & ~0xfff;
+	len += bus_addr - real_bus_addr;
+	len = (len + 0xfff) & ~0xfff;
+
+	result = lv1_unmap_device_dma_region(bus_id, dev_id, real_bus_addr,
+					     len);
+	if (result)
+		return result;
+
+	return lv1_free_device_dma_region(bus_id, dev_id, real_bus_addr);
+}
+
+static void gelic_debug_init(void)
+{
+	s64 result;
+	u64 v2;
+	u64 mac;
+	u64 vlan_id;
+
+	result = lv1_open_device(GELIC_BUS_ID, GELIC_DEVICE_ID, 0);
+	if (result)
+		lv1_panic(0);
+
+	map_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID, &dbg, sizeof(dbg),
+		    &bus_addr);
+
+	memset(&dbg, 0, sizeof(dbg));
+
+	dbg.descr.buf_addr = bus_addr + offsetof(struct debug_block, pkt);
+
+	wmb();
+
+	result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
+				 GELIC_LV1_GET_MAC_ADDRESS, 0, 0, 0,
+				 &mac, &v2);
+	if (result)
+		lv1_panic(0);
+
+	mac <<= 16;
+
+	h_eth = (struct ethhdr *)dbg.pkt;
+
+	memset(&h_eth->dest, 0xff, 6);
+	memcpy(&h_eth->src, &mac, 6);
+
+	header_size = sizeof(struct ethhdr);
+
+	result = lv1_net_control(GELIC_BUS_ID, GELIC_DEVICE_ID,
+				 GELIC_LV1_GET_VLAN_ID,
+				 GELIC_LV1_VLAN_TX_ETHERNET_0, 0, 0,
+				 &vlan_id, &v2);
+	if (!result) {
+		h_eth->type = 0x8100;
+
+		header_size += sizeof(struct vlantag);
+		h_vlan = (struct vlantag *)(h_eth + 1);
+		h_vlan->vlan = vlan_id;
+		h_vlan->subtype = 0x0800;
+		h_ip = (struct iphdr *)(h_vlan + 1);
+	} else {
+		h_eth->type = 0x0800;
+		h_ip = (struct iphdr *)(h_eth + 1);
+	}
+
+	header_size += sizeof(struct iphdr);
+	h_ip->ver_len = 0x45;
+	h_ip->ttl = 10;
+	h_ip->proto = 0x11;
+	h_ip->src = 0x00000000;
+	h_ip->dest = 0xffffffff;
+
+	header_size += sizeof(struct udphdr);
+	h_udp = (struct udphdr *)(h_ip + 1);
+	h_udp->src = GELIC_DEBUG_PORT;
+	h_udp->dest = GELIC_DEBUG_PORT;
+
+	pmsgc = pmsg = (char *)(h_udp + 1);
+}
+
+static void gelic_debug_shutdown(void)
+{
+	if (bus_addr)
+		unmap_dma_mem(GELIC_BUS_ID, GELIC_DEVICE_ID,
+			      bus_addr, sizeof(dbg));
+	lv1_close_device(GELIC_BUS_ID, GELIC_DEVICE_ID);
+}
+
+static void gelic_sendbuf(int msgsize)
+{
+	u16 *p;
+	u32 sum;
+	int i;
+
+	dbg.descr.buf_size = header_size + msgsize;
+	h_ip->total_length = msgsize + sizeof(struct udphdr) +
+			     sizeof(struct iphdr);
+	h_udp->len = msgsize + sizeof(struct udphdr);
+
+	h_ip->checksum = 0;
+	sum = 0;
+	p = (u16 *)h_ip;
+	for (i = 0; i < 5; i++)
+		sum += *p++;
+	h_ip->checksum = ~(sum + (sum >> 16));
+
+	dbg.descr.dmac_cmd_status = GELIC_DESCR_DMA_CMD_NO_CHKSUM |
+				    GELIC_DESCR_TX_DMA_FRAME_TAIL;
+	dbg.descr.result_size = 0;
+	dbg.descr.data_status = 0;
+
+	wmb();
+
+	lv1_net_start_tx_dma(GELIC_BUS_ID, GELIC_DEVICE_ID, bus_addr, 0);
+
+	while ((dbg.descr.dmac_cmd_status & GELIC_DESCR_DMA_STAT_MASK) ==
+	       GELIC_DESCR_DMA_CARDOWNED)
+		cpu_relax();
+}
+
+static void ps3gelic_udbg_putc(char ch)
+{
+	*pmsgc++ = ch;
+	if (ch == '\n' || (pmsgc-pmsg) >= GELIC_MAX_MESSAGE_SIZE) {
+		gelic_sendbuf(pmsgc-pmsg);
+		pmsgc = pmsg;
+	}
+}
+
+void __init udbg_init_ps3gelic(void)
+{
+	gelic_debug_init();
+	udbg_putc = ps3gelic_udbg_putc;
+}
+
+void udbg_shutdown_ps3gelic(void)
+{
+	udbg_putc = NULL;
+	gelic_debug_shutdown();
+}
+EXPORT_SYMBOL(udbg_shutdown_ps3gelic);
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index d82a82d..e743c94 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -1674,6 +1674,9 @@ static int __devinit ps3_gelic_driver_probe(struct ps3_system_bus_device *dev)
 	int result;
 
 	pr_debug("%s: called\n", __func__);
+
+	udbg_shutdown_ps3gelic();
+
 	result = ps3_open_hv_device(dev);
 
 	if (result) {
diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h
index d3fadfb..a93df6a 100644
--- a/drivers/net/ps3_gelic_net.h
+++ b/drivers/net/ps3_gelic_net.h
@@ -359,6 +359,12 @@ static inline void *port_priv(struct gelic_port *port)
 	return port->priv;
 }
 
+#ifdef CONFIG_PPC_EARLY_DEBUG_PS3GELIC
+extern void udbg_shutdown_ps3gelic(void);
+#else
+static inline void udbg_shutdown_ps3gelic(void) {}
+#endif
+
 extern int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask);
 /* shared netdev ops */
 extern void gelic_card_up(struct gelic_card *card);

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

end of thread, other threads:[~2011-08-31 16:32 UTC | newest]

Thread overview: 70+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-01 20:02 [PATCH 00/15] ps3: Support more than the OtherOS lpar Andre Heider
2011-08-01 20:02 ` [PATCH 01/15] [PS3] Add udbg driver using the PS3 gelic Ethernet device Andre Heider
2011-08-03 22:32   ` Geoff Levand
2011-08-04 16:35     ` Andre Heider
2011-08-11 12:13     ` [Cbe-oss-dev] " Arnd Bergmann
2011-08-11 17:32       ` Andre Heider
2011-08-31  4:26         ` Benjamin Herrenschmidt
2011-08-01 20:02 ` [PATCH 02/15] [PS3] Get lv1 high memory region from devtree Andre Heider
2011-08-03 22:30   ` Geoff Levand
2011-08-04  1:19     ` Hector Martin
2011-08-04 19:24       ` Geoff Levand
2011-08-06 11:50         ` Andre Heider
2011-08-01 20:02 ` [PATCH 03/15] [PS3] Add region 1 memory early Andre Heider
2011-08-03 22:32   ` Geoff Levand
2011-08-04  0:08     ` Hector Martin
2011-08-04  7:05       ` Geert Uytterhoeven
2011-08-04 11:13         ` Hector Martin
2011-08-04 15:57       ` Geoff Levand
2011-08-01 20:02 ` [PATCH 04/15] ps3: MEMORY_HOTPLUG is not a requirement anymore Andre Heider
2011-08-01 20:02 ` [PATCH 05/15] ps3: Detect the current lpar environment Andre Heider
2011-08-03 22:31   ` Geoff Levand
2011-08-04 16:34     ` Andre Heider
2011-08-01 20:02 ` [PATCH 06/15] ps3flash: Fix region align checks Andre Heider
2011-08-01 20:29   ` [Cbe-oss-dev] " Geert Uytterhoeven
2011-08-01 20:56     ` Andre Heider
2011-08-01 21:00       ` Geert Uytterhoeven
2011-08-01 20:02 ` [PATCH 07/15] ps3flash: Refuse to work in lpars other than OtherOS Andre Heider
2011-08-03 22:34   ` Geoff Levand
2011-08-04 16:40     ` Andre Heider
2011-08-04 19:27       ` [Cbe-oss-dev] " Geert Uytterhoeven
2011-08-06 12:40         ` Andre Heider
2011-08-01 20:02 ` [PATCH 08/15] ps3: Only prealloc the flash bounce buffer for the OtherOS lpar Andre Heider
2011-08-01 20:03 ` [PATCH 09/15] ps3: Limit the number of regions per storage device Andre Heider
2011-08-01 20:30   ` [Cbe-oss-dev] " Geert Uytterhoeven
2011-08-01 20:58     ` Andre Heider
2011-08-06 12:28       ` Andre Heider
2011-08-06 12:47         ` Andre Heider
2011-08-01 20:03 ` [PATCH 10/15] ps3stor_lib: Add support for multiple regions Andre Heider
2011-08-01 20:35   ` Geert Uytterhoeven
2011-08-01 21:01     ` Andre Heider
2011-08-01 20:03 ` [PATCH 11/15] ps3disk: Provide a gendisk per accessible region Andre Heider
2011-08-01 20:03 ` [PATCH 12/15] ps3stor_lib: Add support for storage access flags Andre Heider
2011-08-01 20:03 ` [PATCH 13/15] ps3disk: Use region flags Andre Heider
2011-08-01 20:03 ` [PATCH 14/15] ps3: Add a vflash driver for lpars other than OtherOS Andre Heider
2011-08-01 20:03 ` [PATCH 15/15] ps3: Add a NOR FLASH driver for PS3s without NAND Andre Heider
2011-08-03 22:23 ` [PATCH 00/15] ps3: Support more than the OtherOS lpar Geoff Levand
2011-08-04 16:31   ` Andre Heider
2011-08-11 12:17 ` [Cbe-oss-dev] " Arnd Bergmann
2011-08-11 17:34   ` Andre Heider
2011-08-11 19:31 ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support " Andre Heider
2011-08-11 19:31   ` [PATCH part1 v2 1/9] Add udbg driver using the PS3 gelic Ethernet device Andre Heider
2011-08-23 20:53     ` Geoff Levand
2011-08-31 16:32       ` [PATCH] [ps3] Add gelic udbg driver Geoff Levand
2011-08-11 19:31   ` [PATCH part1 v2 2/9] ps3: Add helper functions to read highmem info from the repository Andre Heider
2011-08-23 20:53     ` Geoff Levand
2011-08-11 19:31   ` [PATCH part1 v2 3/9] ps3: Get lv1 high memory region " Andre Heider
2011-08-23 20:53     ` Geoff Levand
2011-08-11 19:31   ` [PATCH part1 v2 4/9] Add region 1 memory early Andre Heider
2011-08-23 20:53     ` Geoff Levand
2011-08-23 22:37       ` [Cbe-oss-dev] " Antonio Ospite
2011-08-24  2:15         ` Geoff Levand
2011-08-11 19:31   ` [PATCH part1 v2 5/9] ps3: MEMORY_HOTPLUG is not a requirement anymore Andre Heider
2011-08-23 20:53     ` Geoff Levand
2011-08-11 19:31   ` [PATCH part1 v2 6/9] ps3: Detect the current lpar Andre Heider
2011-08-23 22:08     ` Geoff Levand
2011-08-11 19:31   ` [PATCH part1 v2 7/9] ps3: Log the detected lpar on startup Andre Heider
2011-08-11 19:31   ` [PATCH part1 v2 8/9] ps3flash: Refuse to work in lpars other than OtherOS Andre Heider
2011-08-23 22:12     ` Geoff Levand
2011-08-11 19:31   ` [PATCH part1 v2 9/9] ps3: Only prealloc the flash bounce buffer for the OtherOS lpar Andre Heider
2011-08-31  4:29   ` [PATCH part1 v2 0/9] ps3: General improvements and preparation for support more than " Benjamin Herrenschmidt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.