/********************************************* * Benjamin Krill *********************************************/ #include #include #include #include "fpgafs.h" #define FPGAFS_MAX_LLDRV 3 static struct fpgafs_lldrv *lldrv[FPGAFS_MAX_LLDRV]; static struct fpgafs_lldrv *lldrv_cur; static int lldrv_count = 0x0; static DEFINE_SPINLOCK(fpgafs_lldrv_lock); ssize_t fpgafs_send_data(struct file *file, const char __user *buf, size_t len, loff_t *pos) { return (lldrv_cur) ? lldrv_cur->send(buf, len) : -EBUSY; } EXPORT_SYMBOL_GPL(fpgafs_send_data); 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; } EXPORT_SYMBOL_GPL(fpgafs_recv_data); int fpgafs_write_load(char *buf, int len) { return (lldrv_cur) ? lldrv_cur->write_load(buf, len) : -EBUSY; } EXPORT_SYMBOL_GPL(fpgafs_write_load); int fpgafs_read_load(char *buf, int len) { return (lldrv_cur) ? lldrv_cur->read_load(buf, len) : -EBUSY; } EXPORT_SYMBOL_GPL(fpgafs_read_load); /* low level un-/register functions */ int fpgafs_register_lldrv(struct fpgafs_lldrv *drv) { unsigned long flags; int i; spin_lock_irqsave(&fpgafs_lldrv_lock, flags); if (lldrv_count == FPGAFS_MAX_LLDRV) return -EBUSY; /* find free space */ for(i=0; i < FPGAFS_MAX_LLDRV; i++) if (lldrv[lldrv_count] == NULL) { lldrv[lldrv_count] = drv; break; } if (lldrv[lldrv_count]->init) lldrv[lldrv_count]->init(); lldrv_cur = lldrv[lldrv_count]; lldrv_count++; spin_unlock_irqrestore(&fpgafs_lldrv_lock, flags); return 0; } EXPORT_SYMBOL_GPL(fpgafs_register_lldrv); int fpgafs_unregister_lldrv(struct fpgafs_lldrv *drv) { unsigned long flags; int i,k; spin_lock_irqsave(&fpgafs_lldrv_lock, flags); for(i=0; i < FPGAFS_MAX_LLDRV; i++) { if (lldrv[i] == drv) { /* call the exit function */ if (lldrv[i]->exit) lldrv[i]->exit(); lldrv[i] = NULL; /* if current, search another low level driver */ if (lldrv_cur == drv) { lldrv_cur = NULL; for(k=0; k < FPGAFS_MAX_LLDRV; k++) if (lldrv[k]) { lldrv_cur = lldrv[k]; break; } } break; } } lldrv_count--; spin_unlock_irqrestore(&fpgafs_lldrv_lock, flags); return 0; } EXPORT_SYMBOL_GPL(fpgafs_unregister_lldrv);