1 --- a/drivers/ps3/ps3-sys-manager.c 2012-01-26 20:35:02.242768746 +0100
2 +++ b/drivers/ps3/ps3-sys-manager.c 2012-01-26 20:38:07.325547265 +0100
5 * Copyright (C) 2007 Sony Computer Entertainment Inc.
6 * Copyright 2007 Sony Corp.
7 + * Copyright (C) 2011 graf_chokolo <grafchokolo@gmail.com>.
8 + * Copyright (C) 2011, 2012 glevand <geoffrey.levand@mail.ru>.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
13 #include <linux/module.h>
14 #include <linux/workqueue.h>
15 #include <linux/reboot.h>
16 +#include <linux/slab.h>
17 +#include <linux/uaccess.h>
18 +#include <linux/fs.h>
19 +#include <linux/miscdevice.h>
21 +#include <asm/atomic.h>
22 #include <asm/firmware.h>
23 #include <asm/lv1call.h>
29 +#define DEVICE_NAME "ps3sysmngr"
31 +static struct ps3sm {
32 + struct ps3_system_bus_device *dev;
33 + struct miscdevice misc;
34 + atomic_t misc_in_use;
38 * struct ps3_sys_manager_header - System manager message header.
39 * @version: Header version, currently 1.
41 ps3_vuart_read_async(dev, PS3_SM_RX_MSG_LEN_MIN);
44 +static int ps3_sys_manager_misc_open(struct inode *inode, struct file *file)
46 + if (atomic_inc_return(&ps3sm->misc_in_use) == 1)
47 + ps3_vuart_cancel_async(ps3sm->dev);
52 +static int ps3_sys_manager_misc_release(struct inode *inode, struct file *file)
54 + if (atomic_dec_and_test(&ps3sm->misc_in_use))
55 + ps3_vuart_read_async(ps3sm->dev, PS3_SM_RX_MSG_LEN_MIN);
60 +static ssize_t ps3_sys_manager_misc_read(struct file *file, char __user *usrbuf,
61 + size_t count, loff_t *pos)
66 + buf = kmalloc(count, GFP_KERNEL);
70 + result = ps3_vuart_read(ps3sm->dev, buf, count);
74 + if (copy_to_user(usrbuf, buf, count)) {
88 +static ssize_t ps3_sys_manager_misc_write(struct file *file, const char __user *usrbuf,
89 + size_t count, loff_t *pos)
94 + buf = kmalloc(count, GFP_KERNEL);
98 + if (copy_from_user(buf, usrbuf, count)) {
103 + result = ps3_vuart_write(ps3sm->dev, buf, count);
116 +static const struct file_operations ps3_sys_manager_misc_fops = {
117 + .owner = THIS_MODULE,
118 + .open = ps3_sys_manager_misc_open,
119 + .release = ps3_sys_manager_misc_release,
120 + .read = ps3_sys_manager_misc_read,
121 + .write = ps3_sys_manager_misc_write,
124 static int ps3_sys_manager_probe(struct ps3_system_bus_device *dev)
127 @@ -727,12 +822,47 @@
128 result = ps3_vuart_read_async(dev, PS3_SM_RX_MSG_LEN_MIN);
131 + ps3sm = kzalloc(sizeof(*ps3sm), GFP_KERNEL);
137 + ps3sm->misc.parent = &dev->core;
138 + ps3sm->misc.minor = MISC_DYNAMIC_MINOR,
139 + ps3sm->misc.name = DEVICE_NAME,
140 + ps3sm->misc.fops = &ps3_sys_manager_misc_fops,
141 + atomic_set(&ps3sm->misc_in_use, 0);
143 + result = misc_register(&ps3sm->misc);
145 + dev_err(&dev->core, "%s:%u: misc_register failed %d\n",
146 + __func__, __LINE__, result);
152 + dev_info(&dev->core, "%s:%u: registered misc device %d\n",
153 + __func__, __LINE__, ps3sm->misc.minor);
162 static int ps3_sys_manager_remove(struct ps3_system_bus_device *dev)
164 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
167 + misc_deregister(&ps3sm->misc);