From 750f73bff36da5eb0c5c3ef86c0a83d820df0b4f Mon Sep 17 00:00:00 2001 From: Ludwig Maier Date: Sat, 26 Oct 2013 17:08:45 +0200 Subject: [PATCH] pexor kernel module update --- pexor/kernel-module/Makefile | 2 +- pexor/kernel-module/pexor_trb.c | 571 +++++++++++++++++--------------- pexor/kernel-module/pexor_trb.h | 4 - 3 files changed, 302 insertions(+), 275 deletions(-) diff --git a/pexor/kernel-module/Makefile b/pexor/kernel-module/Makefile index d75db38..21012e2 100644 --- a/pexor/kernel-module/Makefile +++ b/pexor/kernel-module/Makefile @@ -32,5 +32,5 @@ install: $(TARGETS) # ------------ Dependencies -------------------------------------------- -pexor.ko: +pexor.ko: pexor_trb.c pexor_trb.h pexor_user.h $(MAKE) -C $(KERNELDIR) M=$(PWD) diff --git a/pexor/kernel-module/pexor_trb.c b/pexor/kernel-module/pexor_trb.c index c840256..a8f9e74 100644 --- a/pexor/kernel-module/pexor_trb.c +++ b/pexor/kernel-module/pexor_trb.c @@ -36,182 +36,208 @@ /* ---------------------------------------------------------------------- */ -#define PEXORNAME "pexor" -#define PEXORNAMEFMT "pexor-%d" +#define PEXOR_NAME "pexor" +#define PEXOR_NAME_FMT "pexor-%d" #define PEXOR_VENDOR_ID 0x1204 #define PEXOR_DEVICE_ID 0x5303 -#define PEXOR_MAX_DEVS 4 +#define PEXOR_MAX_DEVS 4 + static dev_t pexor_major; -static struct class *pexor_class; +static struct class* pexor_class; static dev_t pexor_devt; static int my_major_nr = 0; struct dev_pexor { - u32 *irq_control; /* irq control register */ - u32 *irq_status; /* irq status register */ - u32 *dma_control_stat; /* dma control and statusregister */ - u32 *dma_source; /* dma source address */ - u32 *dma_dest; /* dma destination address */ - u32 *dma_len; /* dma length */ - u32 *dma_burstsize; /* dma burstsize, <=0x80 */ - u32 *dma_statbits; /* optional further status bits */ - u32 *dma_credits; /* credits */ - u32 *dma_counts; /* counter values */ - u32 *ram_start; /* RAM start */ - u32 *ram_end; /* RAM end */ + u32* irq_control; /* irq control register */ + u32* irq_status; /* irq status register */ + u32* dma_control_stat; /* dma control and statusregister */ + u32* dma_source; /* dma source address */ + u32* dma_dest; /* dma destination address */ + u32* dma_len; /* dma length */ + u32* dma_burstsize; /* dma burstsize, <=0x80 */ + u32* dma_statbits; /* optional further status bits */ + u32* dma_credits; /* credits */ + u32* dma_counts; /* counter values */ + u32* ram_start; /* RAM start */ + u32* ram_end; /* RAM end */ dma_addr_t ram_dma_base; /* RAM start expressed as dma address */ dma_addr_t ram_dma_cursor; /* cursor for next dma to issue start */ - u32 *trbnet_sender_err[PEXOR_TRB_NUM_CHANNELS]; - u32 *trbnet_sender_data[PEXOR_TRB_NUM_CHANNELS]; - u32 *trbnet_receiver_data[PEXOR_TRB_NUM_CHANNELS]; - u32 *trbnet_sender_ctl[PEXOR_TRB_NUM_CHANNELS]; - u32 *trbnet_dma_ctl[PEXOR_TRB_NUM_CHANNELS]; - u32 *trbnet_sender_trigger_info; - u32 *dma_debug0; - u32 *dma_debug1; - u32 *dma_debug2; + u32* trbnet_sender_err[PEXOR_TRB_NUM_CHANNELS]; + u32* trbnet_sender_data[PEXOR_TRB_NUM_CHANNELS]; + u32* trbnet_receiver_data[PEXOR_TRB_NUM_CHANNELS]; + u32* trbnet_sender_ctl[PEXOR_TRB_NUM_CHANNELS]; + u32* trbnet_dma_ctl[PEXOR_TRB_NUM_CHANNELS]; + u32* trbnet_sender_trigger_info; + u32* dma_debug0; + u32* dma_debug1; + u32* dma_debug2; unsigned char init_done; /* object is ready flag */ }; -#define PEXOR_DMA_MAXPOLLS 10000000 +#define PEXOR_DMA_MAXPOLLS 10000000 #define PEXOR_DMA_POLLDELAY 0 #define PEXOR_MEMWRITE_SIZE 128 struct pexor_dma { - void *buffer; + void* buffer; size_t size; int nr_pages; - struct scatterlist *sglist; + struct scatterlist* sglist; int nr_sglist; }; struct pexor_privdata { - atomic_t state; /* run state of device */ - dev_t devno; /* device number (major and minor) */ - int devid; /* local id (counter number) */ - struct pci_dev *pdev; /* PCI device */ - struct device *class_dev; /* Class device */ - struct cdev cdev; /* char device struct */ - struct dev_pexor pexor; /* mapped pexor address pointers */ - unsigned long bases[6]; /* contains pci resource bases */ - unsigned long reglen[6]; /* contains pci resource length */ - void *iomem[6]; /* points to mapped io memory of the bars */ - struct semaphore sem; /* lock semaphore */ - spinlock_t dma_lock; /* protects DMA Buffer */ - - struct pexor_dma dma; /* dma buffer */ - u32 *memwrite_buffer; /* buffer for register_write_mem */ - int magic; /* magic number to identify irq */ + atomic_t state; /* run state of device */ + dev_t devno; /* device number (major and minor) */ + int devid; /* local id (counter number) */ + struct pci_dev* pdev; /* PCI device */ + struct device* class_dev; /* Class device */ + struct cdev cdev; /* char device struct */ + struct dev_pexor pexor; /* mapped pexor address pointers */ + unsigned long bases[6]; /* contains pci resource bases */ + unsigned long reglen[6]; /* contains pci resource length */ + void* iomem[6]; /* points to mapped io memory of the bars */ + struct semaphore sem; /* lock semaphore */ + spinlock_t dma_lock; /* protects DMA Buffer */ + + struct pexor_dma dma; /* dma buffer */ + u32* memwrite_buffer; /* buffer for register_write_mem */ + int magic; /* magic number to identify irq */ }; /* ---------------------------------------------------------------------- */ #ifdef PEXOR_DEBUGPRINT -static unsigned char get_pci_revision(struct pci_dev *dev); +static unsigned char get_pci_revision(struct pci_dev* dev); #endif -ssize_t pexor_sysfs_codeversion_show(struct device *dev, - struct device_attribute *attr, - char *buf); +ssize_t pexor_sysfs_codeversion_show(struct device* dev, + struct device_attribute* attr, + char* buf); -void test_pci(struct pci_dev *dev); +void test_pci(struct pci_dev* dev); -void cleanup_device(struct pexor_privdata *priv); +void cleanup_device(struct pexor_privdata* priv); -struct pexor_privdata *get_privdata(struct file *filp); +struct pexor_privdata* get_privdata(struct file* filp); -void set_pexor(struct dev_pexor *pg, void *membase, unsigned long bar); +void set_pexor(struct dev_pexor* pg, + void* membase, + unsigned long bar); -static int probe(struct pci_dev *dev, const struct pci_device_id *id); +static int probe(struct pci_dev* dev, + const struct pci_device_id* id); -int pexor_open(struct inode *inode, struct file *filp); +int pexor_open(struct inode* inode, + struct file* filp); -int pexor_release(struct inode *inode, struct file *filp); +int pexor_release(struct inode* inode, + struct file* filp); -ssize_t pexor_read(struct file *filp, char __user * buf, size_t count, - loff_t * f_pos); +ssize_t pexor_read(struct file* filp, + char __user * buf, + size_t count, + loff_t* f_pos); -ssize_t pexor_write(struct file *filp, const char __user * buf, size_t count, - loff_t * f_pos); +ssize_t pexor_write(struct file* filp, + const char __user * buf, + size_t count, + loff_t* f_pos); -loff_t pexor_llseek(struct file *filp, loff_t off, int whence); +loff_t pexor_llseek(struct file* filp, + loff_t off, + int whence); -int pexor_mmap(struct file *filp, struct vm_area_struct *vma); +int pexor_mmap(struct file* filp, + struct vm_area_struct* vma); -int pexor_ioctl_read_register(struct pexor_privdata *priv, unsigned long arg); +int pexor_ioctl_read_register(struct pexor_privdata* priv, + unsigned long arg); -int pexor_ioctl_write_register(struct pexor_privdata *priv, +int pexor_ioctl_write_register(struct pexor_privdata* priv, unsigned long arg); -int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, +int pexor_ioctl_trbnet_request(struct pexor_privdata* priv, unsigned long arg); -int pexor_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); +int pexor_ioctl(struct inode* inode, + struct file* filp, + unsigned int cmd, + unsigned long arg); -static void remove(struct pci_dev *dev); +static void remove(struct pci_dev* dev); static int __init pexor_init(void); static void __exit pexor_exit(void); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) -long pexor_unlocked_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg); +long pexor_unlocked_ioctl(struct file* filp, + unsigned int cmd, + unsigned long arg); #endif -static int pexor_alloc_dma_buffer(struct pexor_privdata *priv, size_t size); +static int pexor_alloc_dma_buffer(struct pexor_privdata* priv, + size_t size); -static int pexor_free_dma_buffer(struct pexor_privdata *priv); +static int pexor_free_dma_buffer(struct pexor_privdata* priv); /* ---------------------------------------------------------------------- */ +static const struct pci_device_id ids[ ] = { + { PCI_DEVICE(PEXOR_VENDOR_ID, PEXOR_DEVICE_ID) }, + { 0, } +}; + +static struct pci_driver pci_driver = { + .name = PEXOR_NAME, + .id_table = ids, + .probe = probe, + .remove = remove +}; + static struct file_operations pexor_fops = { - .owner = THIS_MODULE, - .llseek = pexor_llseek, - .read = pexor_read, - .write = pexor_write, + .owner = THIS_MODULE, + .llseek = pexor_llseek, + .read = pexor_read, + .write = pexor_write, #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) .unlocked_ioctl = pexor_unlocked_ioctl, #else - .ioctl = pexor_ioctl, + .ioctl = pexor_ioctl, #endif - .mmap = pexor_mmap, - .open = pexor_open, - .release = pexor_release, -}; - -static struct pci_device_id ids[] = { - {PCI_DEVICE(PEXOR_VENDOR_ID, PEXOR_DEVICE_ID),}, - {0,}, + .mmap = pexor_mmap, + .open = pexor_open, + .release = pexor_release }; -static struct pci_driver pci_driver = { - .name = PEXORNAME, - .id_table = ids, - .probe = probe, - .remove = remove, -}; - -static DEVICE_ATTR(codeversion, S_IRUGO, pexor_sysfs_codeversion_show, NULL); +static DEVICE_ATTR(codeversion, + S_IRUGO, + pexor_sysfs_codeversion_show, + NULL + ); #ifdef PEXOR_WITH_SFP -static DEVICE_ATTR(sfpregs, S_IRUGO, pexor_sysfs_sfpregs_show, NULL); +static DEVICE_ATTR(sfpregs, + S_IRUGO, + pexor_sysfs_sfpregs_show, + NULL + ); #endif static atomic_t pexor_numdevs = ATOMIC_INIT(0); /* ---------------------------------------------------------------------- */ -struct pexor_privdata *get_privdata(struct file *filp) +struct pexor_privdata* get_privdata(struct file* filp) { - struct pexor_privdata *privdata; - privdata = (struct pexor_privdata *)filp->private_data; + struct pexor_privdata* privdata; + privdata = (struct pexor_privdata*)filp->private_data; if (privdata->pexor.init_done == 0) { pexor_dbg(KERN_ERR "*** PEXOR structure was not initialized!\n"); return NULL; @@ -220,7 +246,7 @@ struct pexor_privdata *get_privdata(struct file *filp) } #ifdef PEXOR_DEBUGPRINT -static unsigned char get_pci_revision(struct pci_dev *dev) +static unsigned char get_pci_revision(struct pci_dev* dev) { u8 revision; pci_read_config_byte(dev, PCI_REVISION_ID, &revision); @@ -228,9 +254,9 @@ static unsigned char get_pci_revision(struct pci_dev *dev) } #endif -static void remove(struct pci_dev *dev) +static void remove(struct pci_dev* dev) { - struct pexor_privdata *priv = (struct pexor_privdata *)pci_get_drvdata(dev); + struct pexor_privdata* priv = (struct pexor_privdata* )pci_get_drvdata(dev); cleanup_device(priv); pexor_free_dma_buffer(priv); @@ -240,16 +266,17 @@ static void remove(struct pci_dev *dev) pexor_msg(KERN_NOTICE "PEXOR pci driver end remove.\n"); } -ssize_t pexor_sysfs_codeversion_show(struct device *dev, - struct device_attribute *attr, char *buf) +ssize_t pexor_sysfs_codeversion_show(struct device* dev, + struct device_attribute* attr, + char* buf) { char vstring[256]; ssize_t curs = 0; #ifdef PEXOR_WITH_SFP - struct dev_pexor *pg; + struct dev_pexor* pg; #endif - struct pexor_privdata *privdata; - privdata = (struct pexor_privdata *)dev_get_drvdata(dev); + struct pexor_privdata* privdata; + privdata = (struct pexor_privdata* )dev_get_drvdata(dev); curs = snprintf(vstring, 256, "*** This is PEXOR driver version %s build on %s at %s \n\t", PEXORVERSION, __DATE__, __TIME__); @@ -261,27 +288,31 @@ ssize_t pexor_sysfs_codeversion_show(struct device *dev, } -void test_pci(struct pci_dev *dev) +void test_pci(struct pci_dev* dev) { int bar = 0; u32 originalvalue = 0; u32 base = 0; u16 comstat = 0; - u8 typ = 0; + u8 typ = 0; pexor_dbg(KERN_NOTICE "\n test_pci found PCI revision number %x\n", get_pci_revision(dev)); - /*********** test the address regions*/ + /*********** Test the address regions*/ for (bar = 0; bar < 6; bar++) { pexor_dbg(KERN_NOTICE "Resource %d start=%x\n", bar, (unsigned)pci_resource_start(dev, bar)); + pexor_dbg(KERN_NOTICE "Resource %d end=%x\n", bar, (unsigned)pci_resource_end(dev, bar)); + pexor_dbg(KERN_NOTICE "Resource %d len=%x\n", bar, (unsigned)pci_resource_len(dev, bar)); + pexor_dbg(KERN_NOTICE "Resource %d flags=%x\n", bar, (unsigned)pci_resource_flags(dev, bar)); + if ((pci_resource_flags(dev, bar) & IORESOURCE_IO)) { /* Ressource im IO-Adressraum */ pexor_dbg(KERN_NOTICE " - resource is IO\n"); @@ -320,35 +351,44 @@ void test_pci(struct pci_dev *dev) pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &base); pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, originalvalue); pexor_dbg("size of base address 0: %i\n", ~base + 1); + pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &originalvalue); pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0xffffffff); pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &base); pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, originalvalue); pexor_dbg("size of base address 1: %i\n", ~base + 1); + pci_read_config_dword(dev, PCI_BASE_ADDRESS_2, &originalvalue); pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, 0xffffffff); pci_read_config_dword(dev, PCI_BASE_ADDRESS_2, &base); pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, originalvalue); pexor_dbg("size of base address 2: %i\n", ~base + 1); + pci_read_config_dword(dev, PCI_BASE_ADDRESS_3, &originalvalue); pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, 0xffffffff); pci_read_config_dword(dev, PCI_BASE_ADDRESS_3, &base); pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, originalvalue); pexor_dbg("size of base address 3: %i\n", ~base + 1); - /***** here tests of configuration/status register:******/ + /* Tests of configuration/status register */ pci_read_config_word(dev, PCI_COMMAND, &comstat); pexor_dbg("\n**** Command register is: %d\n", comstat); + pci_read_config_word(dev, PCI_STATUS, &comstat); pexor_dbg("\n**** Status register is: %d\n", comstat); + pci_read_config_byte(dev, PCI_HEADER_TYPE, &typ); pexor_dbg("\n**** Header type is: %d\n", typ); + + /* Test Interrupts */ + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &typ); + pexor_dbg("\n**** Interrupt Line is: %d\n", typ); } -void cleanup_device(struct pexor_privdata *priv) +void cleanup_device(struct pexor_privdata* priv) { int j = 0; - struct pci_dev *pcidev; + struct pci_dev* pcidev; if (!priv) { return; @@ -402,10 +442,12 @@ void cleanup_device(struct pexor_privdata *priv) } -void set_pexor(struct dev_pexor *pg, void *membase, unsigned long bar) +void set_pexor(struct dev_pexor* pg, + void* membase, + unsigned long bar) { int i = 0; - void *dmabase = 0; + void* dmabase = 0; if (pg == NULL) return; @@ -415,44 +457,45 @@ void set_pexor(struct dev_pexor *pg, void *membase, unsigned long bar) set_sfp(&(pg->sfp), membase, bar); #endif - pg->dma_control_stat = (u32 *) (dmabase + (PEXOR_TRB_DMA_CTL << 2)); - pg->dma_source = (u32 *) (dmabase + 0xff0); - pg->dma_dest = (u32 *) (dmabase + (PEXOR_TRB_DMA_ADD << 2)); - pg->dma_len = (u32 *) (dmabase + (PEXOR_TRB_DMA_LEN << 2)); - pg->dma_burstsize = (u32 *) (dmabase + (PEXOR_TRB_DMA_BST << 2)); - pg->dma_statbits = (u32 *) (dmabase + (PEXOR_TRB_DMA_STA << 2)); - pg->dma_credits = (u32 *) (dmabase + (PEXOR_TRB_DMA_CRE << 2)); - pg->dma_counts = (u32 *) (dmabase + (PEXOR_TRB_DMA_CNT << 2)); + pg->dma_control_stat = (u32* ) (dmabase + (PEXOR_TRB_DMA_CTL << 2)); + pg->dma_source = (u32* ) (dmabase + 0xff0); + pg->dma_dest = (u32* ) (dmabase + (PEXOR_TRB_DMA_ADD << 2)); + pg->dma_len = (u32* ) (dmabase + (PEXOR_TRB_DMA_LEN << 2)); + pg->dma_burstsize = (u32* ) (dmabase + (PEXOR_TRB_DMA_BST << 2)); + pg->dma_statbits = (u32* ) (dmabase + (PEXOR_TRB_DMA_STA << 2)); + pg->dma_credits = (u32* ) (dmabase + (PEXOR_TRB_DMA_CRE << 2)); + pg->dma_counts = (u32* ) (dmabase + (PEXOR_TRB_DMA_CNT << 2)); pg->trbnet_sender_trigger_info = - (u32 *) (membase + (PEXOR_TRB_SENDER_TRIGGER_INFO << 2)); + (u32* ) (membase + (PEXOR_TRB_SENDER_TRIGGER_INFO << 2)); for (i = 0; i < PEXOR_TRB_NUM_CHANNELS; i++) { - pg->trbnet_sender_err[i] = (u32 *) + pg->trbnet_sender_err[i] = (u32* ) (membase + ((PEXOR_TRB_SENDER_ERROR | ((i * 2 + 1) << 4)) << 2)); - pg->trbnet_sender_data[i] = (u32 *) + pg->trbnet_sender_data[i] = (u32* ) (membase + ((PEXOR_TRB_SENDER_DATA | ((i * 2 + 1) << 4)) << 2)); - pg->trbnet_receiver_data[i] = (u32 *) + pg->trbnet_receiver_data[i] = (u32* ) (membase + ((PEXOR_TRB_RECEIVER_DATA | ((i * 2 + 1) << 4)) << 2)); - pg->trbnet_sender_ctl[i] = (u32 *) + pg->trbnet_sender_ctl[i] = (u32* ) (membase + ((PEXOR_TRB_SENDER_CONTROL | ((i * 2 + 1) << 4)) << 2)); - pg->trbnet_dma_ctl[i] = (u32 *) (membase + (PEXOR_TRB_DMA_CRE << 2)); + pg->trbnet_dma_ctl[i] = (u32* ) (membase + (PEXOR_TRB_DMA_CRE << 2)); } - pg->dma_debug0 = (u32 *) (membase + (0xe00 << 2)); - pg->dma_debug1 = (u32 *) (membase + (0xe01 << 2)); - pg->dma_debug2 = (u32 *) (membase + (0x705 << 2)); + pg->dma_debug0 = (u32* ) (membase + (0xe00 << 2)); + pg->dma_debug1 = (u32* ) (membase + (0xe01 << 2)); + pg->dma_debug2 = (u32* ) (membase + (0x705 << 2)); pg->init_done = 0x1; pexor_dbg(KERN_NOTICE "** Set pexor structure %lx.\n", (long unsigned int)pg); } -static int probe(struct pci_dev *dev, const struct pci_device_id *id) +static int probe(struct pci_dev* dev, + const struct pci_device_id* id) { int err = 0, ix = 0; - struct pexor_privdata *privdata; + struct pexor_privdata* privdata; pexor_msg(KERN_NOTICE "PEXOR pci driver starts probe...\n"); if ((err = pci_enable_device(dev)) != 0) { pexor_msg(KERN_ERR @@ -469,7 +512,7 @@ static int probe(struct pci_dev *dev, const struct pci_device_id *id) pexor_dbg(KERN_NOTICE "MWI not supported.\n"); } pci_set_master(dev); /* NOTE: DMA worked without, but maybe - depends on bios */ + depends on BIOS */ test_pci(dev); @@ -482,7 +525,7 @@ static int probe(struct pci_dev *dev, const struct pci_device_id *id) memset(privdata, 0, sizeof(struct pexor_privdata)); pci_set_drvdata(dev, privdata); privdata->pdev = dev; - privdata->magic = PEXOR_DEVICE_ID; /* for irq test TODO: what if multiple + privdata->magic = PEXOR_DEVICE_ID; /* for IRQ test TODO: what if multiple pexors share same irq? */ atomic_set(&(privdata->state), PEXOR_STATE_STOPPED); @@ -536,7 +579,7 @@ static int probe(struct pci_dev *dev, const struct pci_device_id *id) spin_lock_init(&(privdata->dma_lock)); /* TODO may use rw semaphore instead? init_rwsem(struct - rw_semaphore *sem); */ + rw_semaphore* sem); */ ////////////////// here chardev registering privdata->devid = atomic_inc_return(&pexor_numdevs) - 1; @@ -568,41 +611,22 @@ static int probe(struct pci_dev *dev, const struct pci_device_id *id) /* driver init had successfully created class, now we create device: */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) privdata->class_dev = device_create(pexor_class, NULL, privdata->devno, - privdata, PEXORNAMEFMT, + privdata, PEXOR_NAME_FMT, MINOR(pexor_devt) + privdata->devid); #else privdata->class_dev = device_create(pexor_class, NULL, privdata->devno, - PEXORNAMEFMT, + PEXOR_NAME_FMT, MINOR(pexor_devt) + privdata->devid); #endif dev_set_drvdata(privdata->class_dev, privdata); pexor_msg(KERN_NOTICE "Added PEXOR device: %s-%d\n", - PEXORNAME, MINOR(pexor_devt) + privdata->devid); + PEXOR_NAME, MINOR(pexor_devt) + privdata->devid); -#if 0 - if (device_create_file(privdata->class_dev, &dev_attr_freebufs) != 0) { - pexor_msg(KERN_ERR - "Could not add device file node for free buffers.\n"); - } - if (device_create_file(privdata->class_dev, &dev_attr_usedbufs) != 0) { - pexor_msg(KERN_ERR - "Could not add device file node for used buffers.\n"); - } - if (device_create_file(privdata->class_dev, &dev_attr_rcvbufs) != 0) { - pexor_msg(KERN_ERR - "Could not add device file node for receive buffers.\n"); - } -#endif if (device_create_file(privdata->class_dev, &dev_attr_codeversion) != 0) { pexor_msg(KERN_ERR "Could not add device file node for code version.\n"); } -#if 0 - if (device_create_file(privdata->class_dev, &dev_attr_dmaregs) != 0) { - pexor_msg(KERN_ERR - "Could not add device file node for dma registers.\n"); - } -#endif + #ifdef PEXOR_WITH_SFP if (device_create_file(privdata->class_dev, &dev_attr_sfpregs) != 0) { pexor_msg(KERN_ERR @@ -633,9 +657,9 @@ static int probe(struct pci_dev *dev, const struct pci_device_id *id) return 0; } -int pexor_open(struct inode *inode, struct file *filp) +int pexor_open(struct inode* inode, struct file* filp) { - struct pexor_privdata *privdata; + struct pexor_privdata* privdata; pexor_dbg(KERN_NOTICE "** starting pexor_open...\n"); /* Set the private data area for the file */ privdata = container_of(inode->i_cdev, struct pexor_privdata, cdev); @@ -643,24 +667,26 @@ int pexor_open(struct inode *inode, struct file *filp) return 0; } -int pexor_release(struct inode *inode, struct file *filp) +int pexor_release(struct inode* inode, struct file* filp) { pexor_dbg(KERN_NOTICE "** starting pexor_release...\n"); return 0; } -loff_t pexor_llseek(struct file * filp, loff_t off, int whence) +loff_t pexor_llseek(struct file* filp, loff_t off, int whence) { return 0; } static ssize_t pexor_read_buffer_ctr = 0; -ssize_t pexor_read(struct file * filp, - char __user * buf, size_t count, loff_t * f_pos) +ssize_t pexor_read(struct file* filp, + char __user * buf, + size_t count, + loff_t* f_pos) { /* here we read from dma buffer */ - struct pexor_privdata *privdata; + struct pexor_privdata* privdata; ssize_t retval = 0; /* u32 kbuf[lcount]; */ @@ -699,11 +725,13 @@ out_read: return retval; } -ssize_t pexor_write(struct file * filp, - const char __user * buf, size_t count, loff_t * f_pos) +ssize_t pexor_write(struct file* filp, + const char __user * buf, + size_t count, + loff_t* f_pos) { /* here we read from dma buffer */ - struct pexor_privdata *privdata; + struct pexor_privdata* privdata; ssize_t retval = 0; /* u32 kbuf[lcount]; */ @@ -720,7 +748,7 @@ ssize_t pexor_write(struct file * filp, if (down_interruptible(&privdata->sem) != 0) { return -ERESTARTSYS; } - if (copy_from_user((void *)privdata->memwrite_buffer, buf, count)) { + if (copy_from_user((void* )privdata->memwrite_buffer, buf, count)) { retval = -EFAULT; goto out_read; } @@ -732,10 +760,11 @@ out_read: return retval; } -int pexor_mmap(struct file *filp, struct vm_area_struct *vma) +int pexor_mmap(struct file* filp, + struct vm_area_struct* vma) { - struct pexor_privdata *privdata; - char *vmalloc_area_ptr = NULL; + struct pexor_privdata* privdata; + char* vmalloc_area_ptr = NULL; unsigned long size; unsigned long start; unsigned long pfn; @@ -781,70 +810,86 @@ int pexor_mmap(struct file *filp, struct vm_area_struct *vma) return 0; } -int pexor_ioctl_read_register(struct pexor_privdata *priv, unsigned long arg) +int pexor_ioctl_read_register(struct pexor_privdata* priv, + unsigned long arg) { int retval = 0; - u32 *ad = 0; + u32* ad = 0; u32 val = 0; int bar = 0; struct pexor_reg_io descriptor; - retval = - copy_from_user(&descriptor, (void __user *)arg, - sizeof(struct pexor_reg_io)); - if (retval) - return retval; - ad = (u32 *) (ptrdiff_t) descriptor.address; + + spin_lock((&(priv->dma_lock))); + + retval = copy_from_user(&descriptor, (void __user *)arg, + sizeof(struct pexor_reg_io)); + if (retval != 0) { + goto OUT_READ_REG; + } + + ad = (u32* ) (ptrdiff_t) descriptor.address; pexor_dbg(KERN_NOTICE "** pexor_ioctl_reading from register address %p\n", ad); bar = descriptor.bar; - if ((bar > 5) || priv->iomem[bar] == 0) { + if ((bar > 5) || (priv->iomem[bar] == 0)) { pexor_msg(KERN_ERR "** pexor_ioctl_read_register: no mapped bar %d\n", bar); - return -EIO; + retval = -EIO; + goto OUT_READ_REG; } pexor_dbg(KERN_NOTICE "** pexor_ioctl_read_register reads from address %p within " "bar %d \n", ad, bar); + if ((unsigned long)ad > priv->reglen[bar]) { pexor_msg(KERN_ERR "** pexor_ioctl_read_register: address %p is exceeding " "length %lx of bar %d\n", ad, priv->reglen[bar], bar); - return -EIO; + retval = -EIO; + goto OUT_READ_REG; } - ad = (u32 *) ((unsigned long)priv->iomem[bar] + (unsigned long)ad); + ad = (u32* ) ((unsigned long)priv->iomem[bar] + (unsigned long)ad); + val = ioread32(ad); - mb(); + rmb(); ndelay(20); pexor_dbg(KERN_NOTICE "** pexor_ioctl_read_register read value %x from mapped " "PCI address %p !\n", val, ad); descriptor.value = val; - retval = - copy_to_user((void __user *)arg, &descriptor, - sizeof(struct pexor_reg_io)); + retval = copy_to_user((void __user *)arg, &descriptor, + sizeof(struct pexor_reg_io)); + OUT_READ_REG: + spin_unlock((&(priv->dma_lock))); return retval; } -int pexor_ioctl_write_register(struct pexor_privdata *priv, unsigned long arg) +int pexor_ioctl_write_register(struct pexor_privdata* priv, + unsigned long arg) { int retval = 0; - u32 *ad = 0; + u32* ad = 0; u32 val = 0; int bar = 0; struct pexor_reg_io descriptor; + + spin_lock((&(priv->dma_lock))); + retval = copy_from_user(&descriptor, (void __user *)arg, sizeof(struct pexor_reg_io)); - if (retval) - return retval; + if (retval != 0) { + goto OUT_WRITE_REG; + } /* here we assume something for this very connection, to be adjusted later */ - ad = (u32 *) (ptrdiff_t) descriptor.address; + ad = (u32* ) (ptrdiff_t) descriptor.address; val = (u32) descriptor.value; bar = descriptor.bar; if ((bar > 5) || priv->iomem[bar] == 0) { pexor_msg(KERN_ERR "** pexor_ioctl_write_register: no mapped bar %d\n", bar); - return -EIO; + retval = -EIO; + goto OUT_WRITE_REG; } pexor_dbg(KERN_NOTICE "** pexor_ioctl_write_register writes value %x to address %p " @@ -853,25 +898,29 @@ int pexor_ioctl_write_register(struct pexor_privdata *priv, unsigned long arg) pexor_msg(KERN_ERR "** pexor_ioctl_write_register: address %p is exceeding " "length %lx of bar %d\n", ad, priv->reglen[bar], bar); - return -EIO; + retval = -EIO; + goto OUT_WRITE_REG; } - ad = (u32 *) ((unsigned long)priv->iomem[bar] + (unsigned long)ad); + ad = (u32* ) ((unsigned long)priv->iomem[bar] + (unsigned long)ad); pexor_dbg(KERN_NOTICE "** pexor_ioctl_write_register writes value %x to mapped " "PCI address %p !\n", val, ad); iowrite32(val, ad); - mb(); + wmb(); ndelay(20); + + OUT_WRITE_REG: + spin_unlock((&(priv->dma_lock))); return retval; } DEFINE_MUTEX(fs_mutex); - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) -long pexor_unlocked_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg) +long pexor_unlocked_ioctl(struct file* filp, + unsigned int cmd, + unsigned long arg) { long ret; @@ -885,10 +934,12 @@ long pexor_unlocked_ioctl(struct file *filp, } #endif -int pexor_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int pexor_ioctl(struct inode* inode, + struct file* filp, + unsigned int cmd, + unsigned long arg) { - struct pexor_privdata *privdata; + struct pexor_privdata* privdata; /* here validity check for magic number etc. */ privdata = get_privdata(filp); @@ -935,16 +986,16 @@ static int __init pexor_init(void) * Register your major, and accept a dynamic number. */ if (my_major_nr) - result = register_chrdev_region(pexor_devt, PEXOR_MAX_DEVS, PEXORNAME); + result = register_chrdev_region(pexor_devt, PEXOR_MAX_DEVS, PEXOR_NAME); else { - result = alloc_chrdev_region(&pexor_devt, 0, PEXOR_MAX_DEVS, PEXORNAME); + result = alloc_chrdev_region(&pexor_devt, 0, PEXOR_MAX_DEVS, PEXOR_NAME); my_major_nr = MAJOR(pexor_devt); } if (result < 0) return result; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) - pexor_class = class_create(THIS_MODULE, PEXORNAME); + pexor_class = class_create(THIS_MODULE, PEXOR_NAME); if (IS_ERR(pexor_class)) { pexor_msg(KERN_ALERT "Could not create class for sysfs support!\n"); } @@ -962,60 +1013,8 @@ static int __init pexor_init(void) return 0; /* note: actual assignment will be done on probe time */ - - } -#if 0 -int __init pexor_init(void) -{ - dev_t dev; - int result; - pexor_msg(KERN_NOTICE "pexor driver init...\n"); - - /* Register a dynamic major number */ - result = alloc_chrdev_region(&dev, 0, PEXOR_MAX_DEVS, PEXORNAME); - if (result != 0) { - pexor_msg(KERN_ALERT "failed to get a major number for pexor\n"); - goto out_init; - } - pexor_major = MAJOR(dev); - - /* create module class */ - pexor_class = class_create(THIS_MODULE, PEXORNAME); - if (IS_ERR(pexor_class)) { - result = PTR_ERR(pexor_class); - pexor_msg(KERN_ALERT - "could not create class for sysfs support, error = %x\n", - result); - goto out_unreg_chrdev; - } - - /* register PCI driver */ - result = pci_register_driver(&pci_driver); - if (result != 0) { - pexor_msg(KERN_ALERT "could not register pexor pci driver\n"); - goto out_unreg_chrdev; - } - - pexor_msg(KERN_NOTICE - "\t\tdriver init with registration for major no %d done.\n", - pexor_major); - - pexor_devt = dev; - - return 0; - - /* note: actual assignment will be done on probe time */ - -out_unreg_chrdev: - unregister_chrdev_region(MKDEV(pexor_major, 0), PEXOR_MAX_DEVS); - -out_init: - return result; -} -#endif - static void __exit pexor_exit(void) { pexor_msg(KERN_NOTICE "pexor driver exit...\n"); @@ -1030,7 +1029,7 @@ static void __exit pexor_exit(void) /* ------ TRBNet Specific ----------------------------------------------- */ -static int pexor_free_dma_buffer(struct pexor_privdata *priv) +static int pexor_free_dma_buffer(struct pexor_privdata* priv) { /* free sglist */ if (priv->dma.sglist != NULL) { @@ -1056,9 +1055,10 @@ static int pexor_free_dma_buffer(struct pexor_privdata *priv) return 0; } -static int pexor_alloc_dma_buffer(struct pexor_privdata *priv, size_t size) +static int pexor_alloc_dma_buffer(struct pexor_privdata* priv, + size_t size) { - struct page *pg = NULL; + struct page* pg = NULL; unsigned long uaddr = 0; unsigned int i; @@ -1147,7 +1147,7 @@ static int pexor_alloc_dma_buffer(struct pexor_privdata *priv, size_t size) #define MASK_HEADER_TYPE (0x0007 << SHIFT_HEADER_TYPE) #define HEADER_TRM 0x0003 -static int pexor_copy_fifo_to_dma(struct pexor_privdata *priv, +static int pexor_copy_fifo_to_dma(struct pexor_privdata* priv, unsigned int channel) { unsigned int sg_ctr; @@ -1182,10 +1182,10 @@ static int pexor_copy_fifo_to_dma(struct pexor_privdata *priv, /* to be done: flush FIFO here, not libtrbnet takes care of this */ return -1; } - ((u32 *) priv->dma.buffer)[ctr] = val; + ((u32* ) priv->dma.buffer)[ctr] = val; #ifdef PEXOR_TRB_DEBUG pexor_msg(KERN_ERR "FIFO COPY: %d: 0x%08x channel: %d\n", - ctr, ((u32 *) priv->dma.buffer)[ctr], channel); + ctr, ((u32* ) priv->dma.buffer)[ctr], channel); #endif ctr++; } @@ -1197,7 +1197,8 @@ static int pexor_copy_fifo_to_dma(struct pexor_privdata *priv, return -1; } -int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg) +int pexor_ioctl_trbnet_request(struct pexor_privdata* priv, + unsigned long arg) { int status = -1; unsigned int channel = 3; @@ -1227,16 +1228,21 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg) priv->pexor.trbnet_sender_data[3]); iowrite32(descriptor.arg0 & 0xffff, priv->pexor.trbnet_sender_data[3]); iowrite32(0x00000000, priv->pexor.trbnet_sender_data[3]); + wmb(); + ndelay(20); iowrite32((((u32) descriptor.trb_address << 16) | PEXOR_TRB_CMD_REGISTER_WRITE), priv->pexor.trbnet_sender_ctl[3]); + wmb(); + ndelay(20); break; case PEXOR_TRBNETCOM_REG_WRITE_MEM: { unsigned int i; if (descriptor.arg1 > PEXOR_MEMWRITE_SIZE) { - pexor_msg(KERN_ERR "ERROR> REG_WRITE_MEM: invalid size: %d shoud be < %d\n", + pexor_msg(KERN_ERR + "ERROR> REG_WRITE_MEM: invalid size: %d shoud be < %d\n", descriptor.arg1, PEXOR_MEMWRITE_SIZE); status = -EFAULT; goto OUT_IOCTL; @@ -1256,9 +1262,13 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg) priv->pexor.trbnet_sender_data[3]); iowrite32(0x00000000, priv->pexor.trbnet_sender_data[3]); } + wmb(); + ndelay(20); iowrite32((((u32) descriptor.trb_address << 16) | PEXOR_TRB_CMD_REGISTER_WRITE_MEM), priv->pexor.trbnet_sender_ctl[3]); + wmb(); + ndelay(20); } break; @@ -1269,11 +1279,15 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg) iowrite32(0x00000000, priv->pexor.trbnet_sender_data[3]); iowrite32(0x00000000, priv->pexor.trbnet_sender_data[3]); iowrite32(0x00000000, priv->pexor.trbnet_sender_data[3]); + wmb(); + ndelay(20); iowrite32((((u32) descriptor.trb_address << 16) | PEXOR_TRB_CMD_REGISTER_READ), priv->pexor.trbnet_sender_ctl[3]); + wmb(); + ndelay(20); break; - + case PEXOR_TRBNETCOM_REG_READ_MEM: // first send trbnet request iowrite32(0x00000000, priv->pexor.trbnet_sender_err[3]); @@ -1281,9 +1295,13 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg) iowrite32(descriptor.arg0, priv->pexor.trbnet_sender_data[3]); iowrite32(0x00000000, priv->pexor.trbnet_sender_data[3]); iowrite32(0x00000000, priv->pexor.trbnet_sender_data[3]); + wmb(); + ndelay(20); iowrite32((((u32) descriptor.trb_address << 16) | PEXOR_TRB_CMD_REGISTER_READ_MEM), priv->pexor.trbnet_sender_ctl[3]); + wmb(); + ndelay(20); break; case PEXOR_TRBNETCOM_READ_UID: @@ -1293,9 +1311,13 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg) iowrite32(0x00000000, priv->pexor.trbnet_sender_data[3]); iowrite32(0x00000000, priv->pexor.trbnet_sender_data[3]); iowrite32(0x00000000, priv->pexor.trbnet_sender_data[3]); + wmb(); + ndelay(20); iowrite32((((u32) descriptor.trb_address << 16) | PEXOR_TRB_CMD_NETADMINISTRATION), priv->pexor.trbnet_sender_ctl[3]); + wmb(); + ndelay(20); break; case PEXOR_TRBNETCOM_SET_ADDRESS: @@ -1318,8 +1340,12 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg) case PEXOR_TRBNETCOM_IPU_DATA_READ: iowrite32(((descriptor.arg1 & 0xff) << 24) | (descriptor.arg2 & 0xffffff), priv->pexor.trbnet_sender_err[1]); + wmb(); + ndelay(20); iowrite32((descriptor.arg0 & 0x0f) | PEXOR_TRB_CMD_SHORT_TRANSFER, priv->pexor.trbnet_sender_ctl[1]); + wmb(); + ndelay(20); channel = 1; break; @@ -1328,9 +1354,12 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg) priv->pexor.trbnet_sender_err[0]); iowrite32((descriptor.arg1 >> 8) & 0xffff, priv->pexor.trbnet_sender_trigger_info); - + wmb(); + ndelay(20); iowrite32((descriptor.arg0 & 0x0f) | PEXOR_TRB_CMD_SHORT_TRANSFER, priv->pexor.trbnet_sender_ctl[0]); + wmb(); + ndelay(20); channel = 0; break; @@ -1366,11 +1395,11 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg) priv->pexor.dma_dest); iowrite32(sg_dma_len(&priv->dma.sglist[sg_ctr]) / 4, priv->pexor.dma_len); - + wmb(); /* wait for dma complete */ for (loops = 0; loops < PEXOR_DMA_MAXPOLLS; loops++) { dmastat = ioread32(priv->pexor.dma_control_stat); - mb(); + rmb(); if ((dmastat & PEXOR_TRB_BIT_DMA_FINISHED) != 0) { /* DMA is completed */ dmaSize = dmastat >> 8; @@ -1460,6 +1489,7 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg) /* Check Credentials */ cred2 = ioread32(priv->pexor.dma_debug2); + rmb(); if (cred2 != cred1) { pexor_msg(KERN_ERR "ERROR> Lost DMA Credentials: 0x%08x != 0x%08x Command: %d\n", @@ -1477,8 +1507,9 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg) u32 val = 0; val = ioread32((i % 2 == 0) ? priv->pexor.dma_debug0 : priv->pexor.dma_debug1); + rmb(); pexor_msg(KERN_ERR "DMA: %d 0x%08x DEBUG:0x%08x\n", i, - ((u32 *) priv->dma.buffer)[i], val); + ((u32* ) priv->dma.buffer)[i], val); } } #endif diff --git a/pexor/kernel-module/pexor_trb.h b/pexor/kernel-module/pexor_trb.h index d25cc20..408508e 100644 --- a/pexor/kernel-module/pexor_trb.h +++ b/pexor/kernel-module/pexor_trb.h @@ -152,8 +152,4 @@ struct pexor_token_io (on synchronous reply) */ }; - - - - #endif -- 2.43.0