[PATCH] x86_64: Implement compat code for raw1394 read/write
Not for the ioctls so far because I was too lazy. Cc: bcollins@debian.org Cc: dan@dennedy.org Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
60c1bc82d9
commit
4bc32c4d5c
@ -42,6 +42,7 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <linux/devfs_fs_kernel.h>
|
||||
#include <linux/compat.h>
|
||||
|
||||
#include "csr1212.h"
|
||||
#include "ieee1394.h"
|
||||
@ -406,6 +407,65 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
|
||||
queue_complete_req(req);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
struct compat_raw1394_req {
|
||||
__u32 type;
|
||||
__s32 error;
|
||||
__u32 misc;
|
||||
|
||||
__u32 generation;
|
||||
__u32 length;
|
||||
|
||||
__u64 address;
|
||||
|
||||
__u64 tag;
|
||||
|
||||
__u64 sendb;
|
||||
__u64 recvb;
|
||||
} __attribute__((packed));
|
||||
|
||||
static const char __user *raw1394_compat_write(const char __user *buf)
|
||||
{
|
||||
struct compat_raw1394_req __user *cr = (typeof(cr)) buf;
|
||||
struct raw1394_request __user *r;
|
||||
r = compat_alloc_user_space(sizeof(struct raw1394_request));
|
||||
|
||||
#define C(x) __copy_in_user(&r->x, &cr->x, sizeof(r->x))
|
||||
|
||||
if (copy_in_user(r, cr, sizeof(struct compat_raw1394_req)) ||
|
||||
C(address) ||
|
||||
C(tag) ||
|
||||
C(sendb) ||
|
||||
C(recvb))
|
||||
return ERR_PTR(-EFAULT);
|
||||
return (const char __user *)r;
|
||||
}
|
||||
#undef C
|
||||
|
||||
#define P(x) __put_user(r->x, &cr->x)
|
||||
|
||||
static int
|
||||
raw1394_compat_read(const char __user *buf, struct raw1394_request *r)
|
||||
{
|
||||
struct compat_raw1394_req __user *cr = (typeof(cr)) r;
|
||||
if (!access_ok(VERIFY_WRITE,cr,sizeof(struct compat_raw1394_req)) ||
|
||||
P(type) ||
|
||||
P(error) ||
|
||||
P(misc) ||
|
||||
P(generation) ||
|
||||
P(length) ||
|
||||
P(address) ||
|
||||
P(tag) ||
|
||||
P(sendb) ||
|
||||
P(recvb))
|
||||
return -EFAULT;
|
||||
return sizeof(struct compat_raw1394_req);
|
||||
}
|
||||
#undef P
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static ssize_t raw1394_read(struct file *file, char __user * buffer,
|
||||
size_t count, loff_t * offset_is_ignored)
|
||||
{
|
||||
@ -415,6 +475,11 @@ static ssize_t raw1394_read(struct file *file, char __user * buffer,
|
||||
struct pending_request *req;
|
||||
ssize_t ret;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (count == sizeof(struct compat_raw1394_req)) {
|
||||
/* ok */
|
||||
} else
|
||||
#endif
|
||||
if (count != sizeof(struct raw1394_request)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -446,12 +511,22 @@ static ssize_t raw1394_read(struct file *file, char __user * buffer,
|
||||
req->req.error = RAW1394_ERROR_MEMFAULT;
|
||||
}
|
||||
}
|
||||
if (copy_to_user(buffer, &req->req, sizeof(req->req))) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = (ssize_t) sizeof(struct raw1394_request);
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (count == sizeof(struct compat_raw1394_req) &&
|
||||
sizeof(struct compat_raw1394_req) !=
|
||||
sizeof(struct raw1394_request)) {
|
||||
ret = raw1394_compat_read(buffer, &req->req);
|
||||
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (copy_to_user(buffer, &req->req, sizeof(req->req))) {
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
ret = (ssize_t) sizeof(struct raw1394_request);
|
||||
}
|
||||
out:
|
||||
free_pending_request(req);
|
||||
return ret;
|
||||
@ -2274,6 +2349,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req)
|
||||
return handle_async_request(fi, req, node);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t raw1394_write(struct file *file, const char __user * buffer,
|
||||
size_t count, loff_t * offset_is_ignored)
|
||||
{
|
||||
@ -2281,6 +2357,15 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
|
||||
struct pending_request *req;
|
||||
ssize_t retval = 0;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (count == sizeof(struct compat_raw1394_req) &&
|
||||
sizeof(struct compat_raw1394_req) !=
|
||||
sizeof(struct raw1394_request)) {
|
||||
buffer = raw1394_compat_write(buffer);
|
||||
if (IS_ERR(buffer))
|
||||
return PTR_ERR(buffer);
|
||||
} else
|
||||
#endif
|
||||
if (count != sizeof(struct raw1394_request)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -2893,6 +2978,7 @@ static struct file_operations raw1394_fops = {
|
||||
.write = raw1394_write,
|
||||
.mmap = raw1394_mmap,
|
||||
.ioctl = raw1394_ioctl,
|
||||
// .compat_ioctl = ... someone needs to do this
|
||||
.poll = raw1394_poll,
|
||||
.open = raw1394_open,
|
||||
.release = raw1394_release,
|
||||
|
Loading…
Reference in New Issue
Block a user