diff --git a/files.c b/files.c index a9c7c3c..fbfbab8 100644 --- a/files.c +++ b/files.c @@ -42,7 +42,6 @@ static ssize_t fpgafs_stat_read(struct file *file, char __user *buf, if (copy_to_user(buf, &data, sizeof(data))) return -EFAULT; - fpgafs_recv_data(NULL, 1); return 4; } @@ -67,7 +66,6 @@ static ssize_t fpgafs_cmd_write(struct file *file, const char __user *buf, return -EFAULT; do_cmd(BLA,data); - fpgafs_send_data(NULL, 1); return 4; } diff --git a/fpgafs.h b/fpgafs.h index 0d7d5a3..938a681 100644 --- a/fpgafs.h +++ b/fpgafs.h @@ -50,8 +50,10 @@ struct fpgafs_lldrv { int fpgafs_register_lldrv(struct fpgafs_lldrv *drv); int fpgafs_unregister_lldrv(struct fpgafs_lldrv *drv); -int fpgafs_send_data(char *buf, int len); -int fpgafs_recv_data(char *buf, int len); +static ssize_t fpgafs_send_data(struct file *file, char __user *buf, + size_t len, loff_t *pos); +static ssize_t fpgafs_recv_data(struct file *file, char __user *buf, + size_t len, loff_t *pos); int fpgafs_read_load(char *buf, int len); int fpgafs_write_load(char *buf, int len); diff --git a/fpgafs_lldrv_dbg.c b/fpgafs_lldrv_dbg.c index 423c4b6..1def73b 100644 --- a/fpgafs_lldrv_dbg.c +++ b/fpgafs_lldrv_dbg.c @@ -4,8 +4,13 @@ #include #include #include +#include +#include #include "fpgafs.h" +static int load = 0; +static unsigned char *load_buf; + static int fpgafs_send_data_dbg(unsigned char *buf, int len) { printk("fpgafs: send data DEBUG\n"); @@ -20,12 +25,42 @@ static int fpgafs_recv_data_dbg(unsigned char *buf, int len) static int fpgafs_read_load_dbg(unsigned char *buf, int len) { - return 0; + if (load == 0) + return -EBUSY; + + len = len > sizeof(load_buf)?sizeof(load_buf):len; + + if (copy_to_user(buf, load_buf, len)) + return -EFAULT; + + return len; } static int fpgafs_write_load_dbg(unsigned char *buf, int len) { - return 0; + u32 cp = 0; + u8 __user *usr; + + if (load == 1) + return -EBUSY; + + if (len < 2) + return -EINVAL; + + if (!access_ok(VERIFY_READ, buf, len)) + return -EFAULT; + + load_buf = kmalloc(len,GFP_USER); + + while (cp < len) { + usr = (u8*)&buf[cp]; + if (__get_user(load_buf[cp], usr)) + return -EFAULT; + cp++; + } + + load = 1; + return len; } static struct fpgafs_lldrv fpgafs_lldrv_dbg = { @@ -46,6 +81,8 @@ int __init fpgafs_lldrv_dbg_init(void) void __exit fpgafs_lldrv_dbg_exit(void) { + load = 0; + kfree(load_buf); fpgafs_unregister_lldrv(&fpgafs_lldrv_dbg); } diff --git a/llmgmt.c b/llmgmt.c index b6c6a3d..93c50a7 100644 --- a/llmgmt.c +++ b/llmgmt.c @@ -13,13 +13,15 @@ static struct fpgafs_lldrv *lldrv_cur; static int lldrv_count = 0x0; static DEFINE_SPINLOCK(fpgafs_lldrv_lock); -int fpgafs_send_data(char *buf, int len) +ssize_t fpgafs_send_data(struct file *file, char __user *buf, + size_t len, loff_t *pos) { return (lldrv_cur) ? lldrv_cur->send(buf, len) : -EBUSY; } EXPORT_SYMBOL_GPL(fpgafs_send_data); -int fpgafs_recv_data(char *buf, int len) +ssize_t fpgafs_recv_data(struct file *file, char __user *buf, + size_t len, loff_t *pos) { return (lldrv_cur) ? lldrv_cur->recv(buf, len) : -EBUSY; }