/* ***************************************************************** * (C) Copyright 2007 Benjamin Krill * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, * MA 02110-1301 USA * *****************************************************************/ #include #include #include #include #include #include #include "fpgafs.h" #define MEM_SIZE 255 /* some test memory */ static char *mem; static unsigned int stat; static int do_cmd(uint32_t cmd, uint32_t data) { switch(cmd) { case BLA: stat = data; break; default: return -EFAULT; } return 0; } static int fpgafs_stat_dbg(struct fpga_context *ctx, unsigned char *buf, int len) { //struct fpga_context *ctx = file->private_data; uint32_t data; data=stat; if (copy_to_user(buf, &data, sizeof(data))) return -EFAULT; return 4; } static int fpgafs_cmd_dbg(struct fpga_context *ctx, const char __user *buf, int len) { uint32_t data, __user *udata; if (len < 4) return -EINVAL; udata = (void __user *)buf; if (!access_ok(VERIFY_READ, buf, len)) return -EFAULT; if (__get_user(data, udata)) return -EFAULT; do_cmd(BLA,data); return 4; } static int fpgafs_send_data_dbg(struct fpga_context *ctx, const char __user *buf, int len) { uint32_t cp = 0; uint8_t __user *usr; if (mem == NULL) return -EBUSY; len = (len > MEM_SIZE)?MEM_SIZE:len; if (len < 2) return -EINVAL; if (!access_ok(VERIFY_READ, buf, len)) return -EFAULT; while (cp < len) { usr = (uint8_t*)&buf[cp]; if (__get_user(mem[cp], usr)) return -EFAULT; cp++; } return len; } static int fpgafs_recv_data_dbg(struct fpga_context *ctx, unsigned char *buf, int len) { printk("fpgafs: receive data DEBUG\n"); len = (len > MEM_SIZE)?MEM_SIZE:len; if (copy_to_user(buf, mem, len)) return -EFAULT; return len; } static int fpgafs_read_load_dbg(struct fpga_context *ctx, unsigned char *buf, int len) { if (ctx->load_buf == NULL) return -EBUSY; len = len > sizeof(ctx->load_buf)?sizeof(ctx->load_buf):len; if (copy_to_user(buf, ctx->load_buf, len)) return -EFAULT; return len; } static int fpgafs_write_load_dbg(struct fpga_context *ctx, const char __user *buf, int len) { uint32_t cp = 0; uint8_t __user *usr; if (ctx->load_buf != NULL) return -EBUSY; if (len < 2) return -EINVAL; if (!access_ok(VERIFY_READ, buf, len)) return -EFAULT; ctx->load_buf = kmalloc(len, GFP_USER); while (cp < len) { usr = (uint8_t*)&buf[cp]; if (__get_user(ctx->load_buf[cp], usr)) return -EFAULT; cp++; } return len; } static int fpgafs_init_dbg(void) { mem = kmalloc(MEM_SIZE, GFP_USER); return 0; } static int fpgafs_exit_dbg(void) { kfree(mem); return 0; } static struct fpgafs_lldrv fpgafs_lldrv_dbg = { .name = "dbg", .init = fpgafs_init_dbg, .exit = fpgafs_exit_dbg, .send = &fpgafs_send_data_dbg, .recv = &fpgafs_recv_data_dbg, .stat = &fpgafs_stat_dbg, .cmd = &fpgafs_cmd_dbg, .read_load = &fpgafs_read_load_dbg, .write_load = &fpgafs_write_load_dbg, }; /* init exit functions ... */ int __init fpgafs_lldrv_dbg_init(void) { return fpgafs_register_lldrv(&fpgafs_lldrv_dbg); } void __exit fpgafs_lldrv_dbg_exit(void) { fpgafs_unregister_lldrv(&fpgafs_lldrv_dbg); } module_init(fpgafs_lldrv_dbg_init); module_exit(fpgafs_lldrv_dbg_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Benjamin Krill ");