Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 151083
b: refs/heads/master
c: a4e623f
h: refs/heads/master
i:
  151081: 67db67c
  151079: 1f141c8
v: v3
  • Loading branch information
Geert Uytterhoeven authored and Benjamin Herrenschmidt committed Jun 15, 2009
1 parent 41293f1 commit afcca94
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 88 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 47cb996b059e0e5696b8daa1f62881a6462a251a
refs/heads/master: a4e623fbc9b201930abcf78df6db5e49aa8e00cb
7 changes: 7 additions & 0 deletions trunk/arch/powerpc/include/asm/ps3.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void);
extern u64 ps3_os_area_get_rtc_diff(void);
extern void ps3_os_area_set_rtc_diff(u64 rtc_diff);

struct ps3_os_area_flash_ops {
ssize_t (*read)(void *buf, size_t count, loff_t pos);
ssize_t (*write)(const void *buf, size_t count, loff_t pos);
};

extern void ps3_os_area_flash_register(const struct ps3_os_area_flash_ops *ops);

/* dma routines */

enum ps3_dma_page_size {
Expand Down
138 changes: 75 additions & 63 deletions trunk/arch/powerpc/platforms/ps3/os-area.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,44 @@ static struct property property_av_multi_out = {
.value = &saved_params.av_multi_out,
};


static DEFINE_MUTEX(os_area_flash_mutex);

static const struct ps3_os_area_flash_ops *os_area_flash_ops;

void ps3_os_area_flash_register(const struct ps3_os_area_flash_ops *ops)
{
mutex_lock(&os_area_flash_mutex);
os_area_flash_ops = ops;
mutex_unlock(&os_area_flash_mutex);
}
EXPORT_SYMBOL_GPL(ps3_os_area_flash_register);

static ssize_t os_area_flash_read(void *buf, size_t count, loff_t pos)
{
ssize_t res = -ENODEV;

mutex_lock(&os_area_flash_mutex);
if (os_area_flash_ops)
res = os_area_flash_ops->read(buf, count, pos);
mutex_unlock(&os_area_flash_mutex);

return res;
}

static ssize_t os_area_flash_write(const void *buf, size_t count, loff_t pos)
{
ssize_t res = -ENODEV;

mutex_lock(&os_area_flash_mutex);
if (os_area_flash_ops)
res = os_area_flash_ops->write(buf, count, pos);
mutex_unlock(&os_area_flash_mutex);

return res;
}


/**
* os_area_set_property - Add or overwrite a saved_params value to the device tree.
*
Expand Down Expand Up @@ -352,12 +390,12 @@ static int db_verify(const struct os_area_db *db)
if (memcmp(db->magic_num, OS_AREA_DB_MAGIC_NUM,
sizeof(db->magic_num))) {
pr_debug("%s:%d magic_num failed\n", __func__, __LINE__);
return -1;
return -EINVAL;
}

if (db->version != 1) {
pr_debug("%s:%d version failed\n", __func__, __LINE__);
return -1;
return -EINVAL;
}

return 0;
Expand Down Expand Up @@ -578,59 +616,48 @@ static void os_area_db_init(struct os_area_db *db)
*
*/

static void __maybe_unused update_flash_db(void)
static int update_flash_db(void)
{
int result;
int file;
off_t offset;
const unsigned int buf_len = 8 * OS_AREA_SEGMENT_SIZE;
struct os_area_header *header;
ssize_t count;
static const unsigned int buf_len = 8 * OS_AREA_SEGMENT_SIZE;
const struct os_area_header *header;
int error;
loff_t pos;
struct os_area_db* db;

/* Read in header and db from flash. */

file = sys_open("/dev/ps3flash", O_RDWR, 0);

if (file < 0) {
pr_debug("%s:%d sys_open failed\n", __func__, __LINE__);
goto fail_open;
}

header = kmalloc(buf_len, GFP_KERNEL);

if (!header) {
pr_debug("%s:%d kmalloc failed\n", __func__, __LINE__);
goto fail_malloc;
pr_debug("%s: kmalloc failed\n", __func__);
return -ENOMEM;
}

offset = sys_lseek(file, 0, SEEK_SET);

if (offset != 0) {
pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__);
goto fail_header_seek;
count = os_area_flash_read(header, buf_len, 0);
if (count < 0) {
pr_debug("%s: os_area_flash_read failed %zd\n", __func__,
count);
error = count;
goto fail;
}

count = sys_read(file, (char __user *)header, buf_len);

result = count < OS_AREA_SEGMENT_SIZE || verify_header(header)
|| count < header->db_area_offset * OS_AREA_SEGMENT_SIZE;

if (result) {
pr_debug("%s:%d verify_header failed\n", __func__, __LINE__);
pos = header->db_area_offset * OS_AREA_SEGMENT_SIZE;
if (count < OS_AREA_SEGMENT_SIZE || verify_header(header) ||
count < pos) {
pr_debug("%s: verify_header failed\n", __func__);
dump_header(header);
goto fail_header;
error = -EINVAL;
goto fail;
}

/* Now got a good db offset and some maybe good db data. */

db = (void*)header + header->db_area_offset * OS_AREA_SEGMENT_SIZE;
db = (void *)header + pos;

result = db_verify(db);

if (result) {
printk(KERN_NOTICE "%s:%d: Verify of flash database failed, "
"formatting.\n", __func__, __LINE__);
error = db_verify(db);
if (error) {
pr_notice("%s: Verify of flash database failed, formatting.\n",
__func__);
dump_db(db);
os_area_db_init(db);
}
Expand All @@ -639,29 +666,16 @@ static void __maybe_unused update_flash_db(void)

db_set_64(db, &os_area_db_id_rtc_diff, saved_params.rtc_diff);

offset = sys_lseek(file, header->db_area_offset * OS_AREA_SEGMENT_SIZE,
SEEK_SET);

if (offset != header->db_area_offset * OS_AREA_SEGMENT_SIZE) {
pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__);
goto fail_db_seek;
}

count = sys_write(file, (const char __user *)db,
sizeof(struct os_area_db));

count = os_area_flash_write(db, sizeof(struct os_area_db), pos);
if (count < sizeof(struct os_area_db)) {
pr_debug("%s:%d sys_write failed\n", __func__, __LINE__);
pr_debug("%s: os_area_flash_write failed %zd\n", __func__,
count);
error = count < 0 ? count : -EIO;
}

fail_db_seek:
fail_header:
fail_header_seek:
fail:
kfree(header);
fail_malloc:
sys_close(file);
fail_open:
return;
return error;
}

/**
Expand All @@ -674,24 +688,22 @@ static void __maybe_unused update_flash_db(void)
static void os_area_queue_work_handler(struct work_struct *work)
{
struct device_node *node;
int error;

pr_debug(" -> %s:%d\n", __func__, __LINE__);

node = of_find_node_by_path("/");

if (node) {
os_area_set_property(node, &property_rtc_diff);
of_node_put(node);
} else
pr_debug("%s:%d of_find_node_by_path failed\n",
__func__, __LINE__);

#if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
update_flash_db();
#else
printk(KERN_WARNING "%s:%d: No flash rom driver configured.\n",
__func__, __LINE__);
#endif
error = update_flash_db();
if (error)
pr_warning("%s: Could not update FLASH ROM\n", __func__);

pr_debug(" <- %s:%d\n", __func__, __LINE__);
}

Expand Down
Loading

0 comments on commit afcca94

Please sign in to comment.