summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/ps3/repository.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/ps3/repository.c')
-rw-r--r--arch/powerpc/platforms/ps3/repository.c220
1 files changed, 204 insertions, 16 deletions
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c
index 273a0d621bdd..ae586a0e5d3f 100644
--- a/arch/powerpc/platforms/ps3/repository.c
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -18,9 +18,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <asm/ps3.h>
#include <asm/lv1call.h>
+#include "platform.h"
+
enum ps3_vendor_id {
PS3_VENDOR_ID_NONE = 0,
PS3_VENDOR_ID_SONY = 0x8000000000000000UL,
@@ -257,7 +258,7 @@ int ps3_repository_read_dev_type(unsigned int bus_index,
int ps3_repository_read_dev_intr(unsigned int bus_index,
unsigned int dev_index, unsigned int intr_index,
- unsigned int *intr_type, unsigned int* interrupt_id)
+ enum ps3_interrupt_type *intr_type, unsigned int* interrupt_id)
{
int result;
u64 v1;
@@ -275,7 +276,8 @@ int ps3_repository_read_dev_intr(unsigned int bus_index,
}
int ps3_repository_read_dev_reg_type(unsigned int bus_index,
- unsigned int dev_index, unsigned int reg_index, unsigned int *reg_type)
+ unsigned int dev_index, unsigned int reg_index,
+ enum ps3_reg_type *reg_type)
{
int result;
u64 v1;
@@ -302,8 +304,8 @@ int ps3_repository_read_dev_reg_addr(unsigned int bus_index,
}
int ps3_repository_read_dev_reg(unsigned int bus_index,
- unsigned int dev_index, unsigned int reg_index, unsigned int *reg_type,
- u64 *bus_addr, u64 *len)
+ unsigned int dev_index, unsigned int reg_index,
+ enum ps3_reg_type *reg_type, u64 *bus_addr, u64 *len)
{
int result = ps3_repository_read_dev_reg_type(bus_index, dev_index,
reg_index, reg_type);
@@ -343,7 +345,7 @@ int ps3_repository_dump_resource_info(unsigned int bus_index,
}
for (res_index = 0; res_index < 10; res_index++) {
- enum ps3_region_type reg_type;
+ enum ps3_reg_type reg_type;
u64 bus_addr;
u64 len;
@@ -367,7 +369,55 @@ int ps3_repository_dump_resource_info(unsigned int bus_index,
return result;
}
-static int dump_device_info(unsigned int bus_index, unsigned int num_dev)
+static int dump_stor_dev_info(unsigned int bus_index, unsigned int dev_index)
+{
+ int result = 0;
+ unsigned int num_regions, region_index;
+ u64 port, blk_size, num_blocks;
+
+ pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
+ bus_index, dev_index);
+
+ result = ps3_repository_read_stor_dev_info(bus_index, dev_index, &port,
+ &blk_size, &num_blocks, &num_regions);
+ if (result) {
+ pr_debug("%s:%d ps3_repository_read_stor_dev_info"
+ " (%u:%u) failed\n", __func__, __LINE__,
+ bus_index, dev_index);
+ goto out;
+ }
+
+ pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks "
+ "%lu, num_regions %u\n",
+ __func__, __LINE__, bus_index, dev_index, port,
+ blk_size, num_blocks, num_regions);
+
+ for (region_index = 0; region_index < num_regions; region_index++) {
+ unsigned int region_id;
+ u64 region_start, region_size;
+
+ result = ps3_repository_read_stor_dev_region(bus_index,
+ dev_index, region_index, &region_id, &region_start,
+ &region_size);
+ if (result) {
+ pr_debug("%s:%d ps3_repository_read_stor_dev_region"
+ " (%u:%u) failed\n", __func__, __LINE__,
+ bus_index, dev_index);
+ break;
+ }
+
+ pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n",
+ __func__, __LINE__, bus_index, dev_index, region_id,
+ region_start, region_size);
+ }
+
+out:
+ pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ return result;
+}
+
+static int dump_device_info(unsigned int bus_index, enum ps3_bus_type bus_type,
+ unsigned int num_dev)
{
int result = 0;
unsigned int dev_index;
@@ -402,6 +452,9 @@ static int dump_device_info(unsigned int bus_index, unsigned int num_dev)
__LINE__, bus_index, dev_index, dev_type, dev_id);
ps3_repository_dump_resource_info(bus_index, dev_index);
+
+ if (bus_type == PS3_BUS_TYPE_STORAGE)
+ dump_stor_dev_info(bus_index, dev_index);
}
pr_debug(" <- %s:%d\n", __func__, __LINE__);
@@ -452,7 +505,7 @@ int ps3_repository_dump_bus_info(void)
__func__, __LINE__, bus_index, bus_type, bus_id,
num_dev);
- dump_device_info(bus_index, num_dev);
+ dump_device_info(bus_index, bus_type, num_dev);
}
pr_debug(" <- %s:%d\n", __func__, __LINE__);
@@ -487,7 +540,8 @@ static int find_device(unsigned int bus_index, unsigned int num_dev,
break;
}
- BUG_ON(dev_index == num_dev);
+ if (dev_index == num_dev)
+ return -1;
pr_debug("%s:%d: found dev_type %u at dev_index %u\n",
__func__, __LINE__, dev_type, dev_index);
@@ -521,7 +575,7 @@ int ps3_repository_find_device (enum ps3_bus_type bus_type,
pr_debug("%s:%d: find bus_type %u, dev_type %u\n", __func__, __LINE__,
bus_type, dev_type);
- dev->bus_index = UINT_MAX;
+ BUG_ON(start_dev && start_dev->bus_index > 10);
for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10;
bus_index++) {
@@ -532,13 +586,15 @@ int ps3_repository_find_device (enum ps3_bus_type bus_type,
if (result) {
pr_debug("%s:%d read_bus_type failed\n",
__func__, __LINE__);
+ dev->bus_index = UINT_MAX;
return result;
}
if (x == bus_type)
break;
}
- BUG_ON(bus_index == 10);
+ if (bus_index >= 10)
+ return -ENODEV;
pr_debug("%s:%d: found bus_type %u at bus_index %u\n",
__func__, __LINE__, bus_type, bus_index);
@@ -604,7 +660,8 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
}
}
- BUG_ON(res_index == 10);
+ if (res_index == 10)
+ return -ENODEV;
pr_debug("%s:%d: found intr_type %u at res_index %u\n",
__func__, __LINE__, intr_type, res_index);
@@ -612,8 +669,8 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
return result;
}
-int ps3_repository_find_region(const struct ps3_repository_device *dev,
- enum ps3_region_type reg_type, u64 *bus_addr, u64 *len)
+int ps3_repository_find_reg(const struct ps3_repository_device *dev,
+ enum ps3_reg_type reg_type, u64 *bus_addr, u64 *len)
{
int result = 0;
unsigned int res_index;
@@ -623,7 +680,7 @@ int ps3_repository_find_region(const struct ps3_repository_device *dev,
*bus_addr = *len = 0;
for (res_index = 0; res_index < 10; res_index++) {
- enum ps3_region_type t;
+ enum ps3_reg_type t;
u64 a;
u64 l;
@@ -643,7 +700,8 @@ int ps3_repository_find_region(const struct ps3_repository_device *dev,
}
}
- BUG_ON(res_index == 10);
+ if (res_index == 10)
+ return -ENODEV;
pr_debug("%s:%d: found reg_type %u at res_index %u\n",
__func__, __LINE__, reg_type, res_index);
@@ -651,6 +709,136 @@ int ps3_repository_find_region(const struct ps3_repository_device *dev,
return result;
}
+int ps3_repository_read_stor_dev_port(unsigned int bus_index,
+ unsigned int dev_index, u64 *port)
+{
+ return read_node(PS3_LPAR_ID_PME,
+ make_first_field("bus", bus_index),
+ make_field("dev", dev_index),
+ make_field("port", 0),
+ 0, port, 0);
+}
+
+int ps3_repository_read_stor_dev_blk_size(unsigned int bus_index,
+ unsigned int dev_index, u64 *blk_size)
+{
+ return read_node(PS3_LPAR_ID_PME,
+ make_first_field("bus", bus_index),
+ make_field("dev", dev_index),
+ make_field("blk_size", 0),
+ 0, blk_size, 0);
+}
+
+int ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index,
+ unsigned int dev_index, u64 *num_blocks)
+{
+ return read_node(PS3_LPAR_ID_PME,
+ make_first_field("bus", bus_index),
+ make_field("dev", dev_index),
+ make_field("n_blocks", 0),
+ 0, num_blocks, 0);
+}
+
+int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index,
+ unsigned int dev_index, unsigned int *num_regions)
+{
+ int result;
+ u64 v1;
+
+ result = read_node(PS3_LPAR_ID_PME,
+ make_first_field("bus", bus_index),
+ make_field("dev", dev_index),
+ make_field("n_regs", 0),
+ 0, &v1, 0);
+ *num_regions = v1;
+ return result;
+}
+
+int ps3_repository_read_stor_dev_region_id(unsigned int bus_index,
+ unsigned int dev_index, unsigned int region_index,
+ unsigned int *region_id)
+{
+ int result;
+ u64 v1;
+
+ result = read_node(PS3_LPAR_ID_PME,
+ make_first_field("bus", bus_index),
+ make_field("dev", dev_index),
+ make_field("region", region_index),
+ make_field("id", 0),
+ &v1, 0);
+ *region_id = v1;
+ return result;
+}
+
+int ps3_repository_read_stor_dev_region_size(unsigned int bus_index,
+ unsigned int dev_index, unsigned int region_index, u64 *region_size)
+{
+ return read_node(PS3_LPAR_ID_PME,
+ make_first_field("bus", bus_index),
+ make_field("dev", dev_index),
+ make_field("region", region_index),
+ make_field("size", 0),
+ region_size, 0);
+}
+
+int ps3_repository_read_stor_dev_region_start(unsigned int bus_index,
+ unsigned int dev_index, unsigned int region_index, u64 *region_start)
+{
+ return read_node(PS3_LPAR_ID_PME,
+ make_first_field("bus", bus_index),
+ make_field("dev", dev_index),
+ make_field("region", region_index),
+ make_field("start", 0),
+ region_start, 0);
+}
+
+int ps3_repository_read_stor_dev_info(unsigned int bus_index,
+ unsigned int dev_index, u64 *port, u64 *blk_size,
+ u64 *num_blocks, unsigned int *num_regions)
+{
+ int result;
+
+ result = ps3_repository_read_stor_dev_port(bus_index, dev_index, port);
+ if (result)
+ return result;
+
+ result = ps3_repository_read_stor_dev_blk_size(bus_index, dev_index,
+ blk_size);
+ if (result)
+ return result;
+
+ result = ps3_repository_read_stor_dev_num_blocks(bus_index, dev_index,
+ num_blocks);
+ if (result)
+ return result;
+
+ result = ps3_repository_read_stor_dev_num_regions(bus_index, dev_index,
+ num_regions);
+ return result;
+}
+
+int ps3_repository_read_stor_dev_region(unsigned int bus_index,
+ unsigned int dev_index, unsigned int region_index,
+ unsigned int *region_id, u64 *region_start, u64 *region_size)
+{
+ int result;
+
+ result = ps3_repository_read_stor_dev_region_id(bus_index, dev_index,
+ region_index, region_id);
+ if (result)
+ return result;
+
+ result = ps3_repository_read_stor_dev_region_start(bus_index, dev_index,
+ region_index, region_start);
+ if (result)
+ return result;
+
+ result = ps3_repository_read_stor_dev_region_size(bus_index, dev_index,
+ region_index, region_size);
+ return result;
+}
+
int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size)
{
return read_node(PS3_LPAR_ID_CURRENT,