]> jspc29.x-matter.uni-frankfurt.de Git - trbnettools.git/commitdiff
replaced spinlocks by semaphores
authorLudwig Maier <lmaier@brett.e12.ph.tum.de>
Mon, 28 Oct 2013 01:23:40 +0000 (02:23 +0100)
committerLudwig Maier <lmaier@brett.e12.ph.tum.de>
Mon, 28 Oct 2013 01:23:40 +0000 (02:23 +0100)
pexor/kernel-module/pexor_trb.c

index ab59b7a109a49e6832e9a3ef7fa9fcef55a83e56..0c1f4b9037c58c76364b00e18fcc9464c0ec58f8 100644 (file)
@@ -8,9 +8,6 @@
 #include <linux/fs.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
-//#include <linux/smp_lock.h>
-//#include <linux/mutex.h>
-
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
@@ -30,7 +27,6 @@
 #define pexor_dbg( args... ) ;
 #endif
 
-
 #define pexor_msg( args... )                    \
   printk( args );
 
@@ -103,8 +99,9 @@ struct pexor_privdata
   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 semaphore sem_buf;     /* lock semaphore for DMA buffer          */
+  struct semaphore sem_ioctl;   /* lock semaphore for ioctl operations    */
+  spinlock_t spin_lock0;        /* Spin Lock #0                           */
 
   struct pexor_dma dma;         /* dma buffer                             */
   u32* memwrite_buffer;         /* buffer for register_write_mem          */
@@ -117,59 +114,72 @@ struct pexor_privdata
 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);
+static ssize_t pexor_sysfs_codeversion_show(struct device* dev,
+                                            struct device_attribute* attr,
+                                            char* buf
+                                            );
 
-void test_pci(struct pci_dev* dev);
+static void test_pci(struct pci_dev* dev);
 
-void cleanup_device(struct pexor_privdata* priv);
+static void cleanup_device(struct pexor_privdata* priv);
 
 struct pexor_privdata* get_privdata(struct file* filp);
 
-void set_pexor(struct dev_pexor* pg, 
-               void* membase, 
-               unsigned long bar);
+static 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);
+                 const struct pci_device_id* id
+                 );
 
-int pexor_open(struct inode* inode, 
-               struct file* filp);
+static int pexor_open(struct inode* inode, 
+                      struct file* filp);
 
-int pexor_release(struct inode* inode, 
-                  struct file* filp);
+static 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);
+static 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);
+static 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);
+static loff_t pexor_llseek(struct file* filp, 
+                           loff_t off, 
+                           int whence
+                           );
 
-int pexor_mmap(struct file* filp, 
-               struct vm_area_struct* vma);
+static 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_write_register(struct pexor_privdata* priv,
-                               unsigned long arg);
+static int pexor_ioctl(struct inode* inode, 
+                       struct file* filp,
+                       unsigned int cmd, 
+                       unsigned long arg
+                       );
 
-int pexor_ioctl_trbnet_request(struct pexor_privdata* priv,
-                               unsigned long arg);
+static int pexor_ioctl_read_register(struct pexor_privdata* priv,
+                                     unsigned long arg
+                                     );
 
-int pexor_ioctl(struct inode* inode, 
-                struct file* filp,
-                unsigned int cmd, 
-                unsigned long arg);
+static int pexor_ioctl_write_register(struct pexor_privdata* priv,
+                                      unsigned long arg
+                                      );
+
+static int pexor_ioctl_trbnet_request(struct pexor_privdata* priv,
+                                      unsigned long arg
+                                      );
 
 static void remove(struct pci_dev* dev);
 
@@ -180,11 +190,13 @@ 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);
+                          unsigned long arg
+                          );
 #endif
 
 static int pexor_alloc_dma_buffer(struct pexor_privdata* priv, 
-                                  size_t size);
+                                  size_t size
+                                  );
 
 static int pexor_free_dma_buffer(struct pexor_privdata* priv);
 
@@ -229,13 +241,12 @@ static atomic_t pexor_numdevs = ATOMIC_INIT(0);
 
 struct pexor_privdata* get_privdata(struct file* filp)
 {
-  struct pexor_privdata* privdata;
-  privdata = (struct pexor_privdata*)filp->private_data;
-  if (privdata->pexor.init_done == 0) {
+  struct pexor_privdata* priv = (struct pexor_privdata*)filp->private_data;
+  if (priv->pexor.init_done == 0) {
     pexor_dbg(KERN_ERR "*** PEXOR structure was not initialized!\n");
     return NULL;
   }
-  return privdata;
+  return priv;
 }
 
 #ifdef PEXOR_DEBUGPRINT
@@ -463,12 +474,12 @@ void set_pexor(struct dev_pexor* pg,
          (long unsigned int)pg);
 }
 
-static int probe(struct pci_dev* dev, 
-                 const struct pci_device_id* id)
+int probe(struct pci_dev* dev, 
+          const struct pci_device_id* id)
 {
   int err = 0, ix = 0;
 
-  struct pexor_privdata* privdata;
+  struct pexor_privdata* priv;
   pexor_msg(KERN_NOTICE "PEXOR pci driver starts probe...\n");
   if ((err = pci_enable_device(dev)) != 0) {
     pexor_msg(KERN_ERR
@@ -490,90 +501,92 @@ static int probe(struct pci_dev* dev,
   test_pci(dev);
 
   /* Allocate and initialize the private data for this device */
-  privdata = kmalloc(sizeof(struct pexor_privdata), GFP_KERNEL);
-  if (privdata == NULL) {
-    cleanup_device(privdata);
+  priv = kmalloc(sizeof(struct pexor_privdata), GFP_KERNEL);
+  if (priv == NULL) {
+    cleanup_device(priv);
     return -ENOMEM;
   }
-  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 
-                                           pexors share same irq? */
+  memset(priv, 0, sizeof(struct pexor_privdata));
+  pci_set_drvdata(dev, priv);
+  priv->pdev = dev;
+  priv->magic = PEXOR_DEVICE_ID;    /* for IRQ test TODO: what if multiple 
+                                       pexors share same irq? */
 
-  atomic_set(&(privdata->state), PEXOR_STATE_STOPPED);
+  atomic_set(&(priv->state), PEXOR_STATE_STOPPED);
 
   for (ix = 0; ix < 6; ix++) {
-    privdata->bases[ix] = pci_resource_start(dev, ix);
-    privdata->reglen[ix] = pci_resource_len(dev, ix);
-    if (privdata->bases[ix] == 0)
+    priv->bases[ix] = pci_resource_start(dev, ix);
+    priv->reglen[ix] = pci_resource_len(dev, ix);
+    if (priv->bases[ix] == 0) {
       continue;
+    }
     if ((pci_resource_flags(dev, ix) & IORESOURCE_IO)) {
 
       printk(KERN_NOTICE " - Requesting io ports for bar %d\n", ix);
-      if (request_region(privdata->bases[ix], privdata->reglen[ix],
+      if (request_region(priv->bases[ix], priv->reglen[ix],
                          dev->dev.kobj.name) == NULL) {
         printk(KERN_ERR
                "I/O address conflict at bar %d for device \"%s\"\n", ix,
                dev->dev.kobj.name);
-        cleanup_device(privdata);
+        cleanup_device(priv);
         return -EIO;
       }
       printk("requested ioport at %lx with length %lx\n",
-             privdata->bases[ix], privdata->reglen[ix]);
+             priv->bases[ix], priv->reglen[ix]);
     } else if ((pci_resource_flags(dev, ix) & IORESOURCE_MEM)) {
       printk(KERN_NOTICE " - Requesting memory region for bar %d\n", ix);
-      if (request_mem_region(privdata->bases[ix], privdata->reglen[ix],
+      if (request_mem_region(priv->bases[ix], priv->reglen[ix],
                              dev->dev.kobj.name) == NULL) {
         printk(KERN_ERR
                "Memory address conflict at bar %d for device \"%s\"\n", ix,
                dev->dev.kobj.name);
-        cleanup_device(privdata);
+        cleanup_device(priv);
         return -EIO;
       }
       printk("requested memory at %lx with length %lx\n",
-             privdata->bases[ix], privdata->reglen[ix]);
-      privdata->iomem[ix] =
-        ioremap_nocache(privdata->bases[ix], privdata->reglen[ix]);
-      if (privdata->iomem[ix] == NULL) {
+             priv->bases[ix], priv->reglen[ix]);
+      priv->iomem[ix] =
+        ioremap_nocache(priv->bases[ix], priv->reglen[ix]);
+      if (priv->iomem[ix] == NULL) {
         printk(KERN_ERR
                "Could not remap memory  at bar %d for device \"%s\"\n", ix,
                dev->dev.kobj.name);
-        cleanup_device(privdata);
+        cleanup_device(priv);
         return -EIO;
       }
       printk("remapped memory to %lx with length %lx\n",
-             (unsigned long)privdata->iomem[ix], privdata->reglen[ix]);
+             (unsigned long)priv->iomem[ix], priv->reglen[ix]);
     }
   }                             //for
-  set_pexor(&(privdata->pexor), privdata->iomem[0], privdata->bases[0]);
+  set_pexor(&(priv->pexor), priv->iomem[0], priv->bases[0]);
 
-  sema_init(&(privdata->sem), 1);
-  spin_lock_init(&(privdata->dma_lock));
 
-  /* TODO may use rw semaphore instead? init_rwsem(struct 
-     rw_semaphore* sem); */
+  /* Initialize Semaphore Locks */
+  sema_init(&(priv->sem_buf), 1);
+  sema_init(&(priv->sem_ioctl), 1);
+  
+  /* Initialize Spin Locks, not needed at the moment */
+  spin_lock_init(&(priv->spin_lock0));
 
   ////////////////// here chardev registering
-  privdata->devid = atomic_inc_return(&pexor_numdevs) - 1;
-  if (privdata->devid >= PEXOR_MAX_DEVS) {
+  priv->devid = atomic_inc_return(&pexor_numdevs) - 1;
+  if (priv->devid >= PEXOR_MAX_DEVS) {
     pexor_msg(KERN_ERR
               "Maximum number of devices reached! Increase MAXDEVICES.\n");
-    cleanup_device(privdata);
+    cleanup_device(priv);
     return -ENOMSG;
   }
 
-  privdata->devno
-    = MKDEV(MAJOR(pexor_devt), MINOR(pexor_devt) + privdata->devid);
+  priv->devno = MKDEV(MAJOR(pexor_devt), MINOR(pexor_devt) + priv->devid);
 
   /* Register character device */
-  cdev_init(&(privdata->cdev), &pexor_fops);
-  privdata->cdev.owner = THIS_MODULE;
-  privdata->cdev.ops = &pexor_fops;
-  err = cdev_add(&privdata->cdev, privdata->devno, 1);
+  cdev_init(&(priv->cdev), &pexor_fops);
+  priv->cdev.owner = THIS_MODULE;
+  priv->cdev.ops = &pexor_fops;
+  err = cdev_add(&priv->cdev, priv->devno, 1);
   if (err) {
     pexor_msg("Couldn't add character device.\n");
-    cleanup_device(privdata);
+    cleanup_device(priv);
     return err;
   }
 
@@ -583,19 +596,19 @@ static int probe(struct pci_dev* dev,
   if (!IS_ERR(pexor_class)) {
     /* 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, PEXOR_NAME_FMT,
-                                        MINOR(pexor_devt) + privdata->devid);
+    priv->class_dev = device_create(pexor_class, NULL, priv->devno,
+                                    priv, PEXOR_NAME_FMT,
+                                    MINOR(pexor_devt) + priv->devid);
 #else
-    privdata->class_dev = device_create(pexor_class, NULL, privdata->devno,
-                                        PEXOR_NAME_FMT,
-                                        MINOR(pexor_devt) + privdata->devid);
+    priv->class_dev = device_create(pexor_class, NULL, priv->devno,
+                                    PEXOR_NAME_FMT,
+                                    MINOR(pexor_devt) + priv->devid);
 #endif
-    dev_set_drvdata(privdata->class_dev, privdata);
+    dev_set_drvdata(priv->class_dev, priv);
     pexor_msg(KERN_NOTICE "Added PEXOR device: %s-%d\n",
-              PEXOR_NAME, MINOR(pexor_devt) + privdata->devid);
+              PEXOR_NAME, MINOR(pexor_devt) + priv->devid);
 
-    if (device_create_file(privdata->class_dev, &dev_attr_codeversion) != 0) {
+    if (device_create_file(priv->class_dev, &dev_attr_codeversion) != 0) {
       pexor_msg(KERN_ERR
                 "Could not add device file node for code version.\n");
     }
@@ -606,14 +619,14 @@ static int probe(struct pci_dev* dev,
   }
 
   /* init pexor_dma buffer */
-  if (pexor_alloc_dma_buffer(privdata, DMA_BUFFER_NUM_PAGES * PAGE_SIZE) != 0) {
+  if (pexor_alloc_dma_buffer(priv, DMA_BUFFER_NUM_PAGES * PAGE_SIZE) != 0) {
     pexor_msg(KERN_ERR "ERROR> probe init dma  failed\n");
     return -EFAULT;
   }
 
   /* allocate memwrite_buffer */
-  privdata->memwrite_buffer = vmalloc_32_user(PEXOR_MEMWRITE_SIZE * 4);
-  if (privdata->memwrite_buffer == NULL) {
+  priv->memwrite_buffer = vmalloc_32_user(PEXOR_MEMWRITE_SIZE * 4);
+  if (priv->memwrite_buffer == NULL) {
     pexor_msg(KERN_ERR "ERROR> probe allocate memwrite_buffer failed\n");
     return -ENOMEM;
   }
@@ -624,17 +637,20 @@ static int probe(struct pci_dev* dev,
 
 int pexor_open(struct inode* inode, struct file* filp)
 {
-  struct pexor_privdata* privdata;
+  struct pexor_privdata* priv = NULL;
+  
   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);
-  filp->private_data = privdata;
+  priv = container_of(inode->i_cdev, struct pexor_privdata, cdev);
+  filp->private_data = priv;
   return 0;
 }
 
 int pexor_release(struct inode* inode, struct file* filp)
 {
-  printk(KERN_NOTICE "** starting pexor_release...\n");
+  pexor_dbg(KERN_NOTICE "** starting pexor_release...\n");
+  
   return 0;
 }
 
@@ -650,34 +666,44 @@ ssize_t pexor_read(struct file*  filp,
                    size_t count, 
                    loff_t*  f_pos)
 {
+
   /* here we read from dma buffer */
-  struct pexor_privdata* privdata;
+  struct pexor_privdata* priv = NULL;
   ssize_t retval = 0;
-
+  
   /*  u32 kbuf[lcount]; */
   pexor_dbg(KERN_NOTICE "** starting pexor_read for f_pos=%d count=%d\n",
             (int)*f_pos, (int)count);
-  privdata = get_privdata(filp);
-  if (privdata == NULL) {
-    return -EFAULT;
+  
+  /* Request Semaphore */
+  if (down_interruptible(&priv->sem_buf) != 0) {
+    printk(KERN_ERR "pexor_read: could not get Semaphore sem_buf\n");
+    return -ERESTARTSYS;
+  }  
+    
+  priv = get_privdata(filp);
+  if (priv == NULL) {
+    retval= -EFAULT;
+    goto out_read;
   }
-  if (count > privdata->dma.size * PAGE_SIZE) {
+  
+  if (count > priv->dma.size * PAGE_SIZE) {
     pexor_msg(KERN_ERR "ERROR> pexor_read: requested count (%d) > Max: %d\n", 
-              (int)(count / 4), (int)privdata->dma.size);
-    return -EFAULT;
+              (int)(count / 4), (int)priv->dma.size);
+    retval = -EFAULT;
+    goto out_read;
   }
+  
   if (count > pexor_read_buffer_ctr) {
     pexor_msg(KERN_ERR "ERROR> pexor_read: requested count (%d) > "
               "Buffer: %d\n", 
               (int)count, (int)pexor_read_buffer_ctr);
-    return -EFAULT;
+    retval = -EFAULT;
+    goto out_read;
   }
   pexor_read_buffer_ctr -= count;
-
-  if (down_interruptible(&privdata->sem) != 0) {
-    return -ERESTARTSYS;
-  }
-  if (copy_to_user(buf, privdata->dma.buffer, count)) {
+    
+  if (copy_to_user(buf, priv->dma.buffer, count)) {
     pexor_msg(KERN_ERR "ERROR> pexor_read: copy_to_user failed\n");
     retval = -EFAULT;
     goto out_read;
@@ -686,7 +712,7 @@ ssize_t pexor_read(struct file*  filp,
   retval = count;
 
  out_read:
-  up(&privdata->sem);
+  up(&priv->sem_buf);
   return retval;
 }
 
@@ -696,52 +722,61 @@ ssize_t pexor_write(struct file*  filp,
                     loff_t*  f_pos)
 {
   /* here we read from dma buffer */
-  struct pexor_privdata* privdata;
+  struct pexor_privdata* priv = NULL;
   ssize_t retval = 0;
 
-  /*  u32 kbuf[lcount]; */
   pexor_dbg(KERN_NOTICE "** starting pexor_write for f_pos=%d count=%d\n",
             (int)*f_pos, (int)count);
-  privdata = get_privdata(filp);
-  if (privdata == NULL) {
-    return -EFAULT;
+
+  /* Request Semaphore */
+  if (down_interruptible(&priv->sem_buf) != 0) {
+    printk(KERN_ERR "pexor_write: could not get Semaphore sem_buf\n");
+    return -ERESTARTSYS;
   }
+  
+  /*  u32 kbuf[lcount]; */
+  priv = get_privdata(filp);
+  if (priv == NULL) {
+    retval = -EFAULT;
+    goto out_write;
+  }
+  
   if (count > 4 * PEXOR_MEMWRITE_SIZE) {
-    return -EFAULT;
+    retval = -EFAULT;
+    goto out_write;
   }
 
-  if (down_interruptible(&privdata->sem) != 0) {
-    return -ERESTARTSYS;
-  }
-  if (copy_from_user((void* )privdata->memwrite_buffer, buf, count)) {
+  
+  if (copy_from_user((void* )priv->memwrite_buffer, buf, count)) {
     retval = -EFAULT;
-    goto out_read;
+    goto out_write;
   }
   *f_pos += count;
   retval = count;
 
- out_read:
-  up(&privdata->sem);
+ out_write:
+  up(&priv->sem_buf);
   return retval;
 }
 
 int pexor_mmap(struct file* filp,
                struct vm_area_struct* vma)
 {
-  struct pexor_privdata* privdata;
+#ifdef PEXOR_MMAP_ENABLED
+  struct pexor_privdata* priv;
   char* vmalloc_area_ptr = NULL;
   unsigned long size;
   unsigned long start;
   unsigned long pfn;
   int ret = 0;
 
-  privdata = get_privdata(filp);
+  priv = get_privdata(filp);
   pexor_dbg(KERN_NOTICE "** starting pexor_mmap...\n");
 
-  if (privdata == NULL)
+  if (priv == NULL)
     return -EFAULT;
 
-  vmalloc_area_ptr = privdata->dma.buffer;
+  vmalloc_area_ptr = priv->dma.buffer;
   start = vma->vm_start;
   size = (vma->vm_end - vma->vm_start);
 
@@ -749,7 +784,7 @@ int pexor_mmap(struct file* filp,
             "** starting pexor_mmap for s:%lx e:%lx size=%ld\n",
             vma->vm_start, vma->vm_end, size);
 
-  if (size > privdata->dma.size) {
+  if (size > priv->dma.size) {
     return -EFAULT;
   }
 
@@ -757,24 +792,25 @@ int pexor_mmap(struct file* filp,
     pfn = vmalloc_to_pfn(vmalloc_area_ptr);
     if ((ret = remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED)) < 0) {
       pexor_dbg(KERN_ERR "kmem remap failed: %d (%p)\n",
-                ret, privdata->dma.buffer);
+                ret, priv->dma.buffer);
       return ret;
     }
     start += PAGE_SIZE;
     vmalloc_area_ptr += PAGE_SIZE;
     size -= PAGE_SIZE;
   }
+  
+  return 0;
 
-#if 0
-  /* map kernel addresses to vma */
-  //  vma->vm_flags |= (VM_RESERVED); /* TODO: do we need this?*/
-  /* der scheiss geht nicht!!! */
-  ret = remap_vmalloc_range(vma, privdata->dma.buffer, 0);
+#else
+  /* MMAP is not suppoprted and needed up to now */
+  return EFAULT;
 #endif
-
-  return 0;
 }
 
+/* ---------------------------------------------------------------------- */
+/* -- PEXOR PCI Handler Processes                                         */
+/* ---------------------------------------------------------------------- */
 
 #define iowrite32_mb( args... )                 \
   iowrite32( args ); wmb();
@@ -788,8 +824,13 @@ int pexor_ioctl_read_register(struct pexor_privdata* priv,
   int bar = 0;
   struct pexor_reg_io descriptor;
   
-  spin_lock((&(priv->dma_lock)));
-
+  /* Request Semaphore */
+  if (down_interruptible(&priv->sem_ioctl) != 0) {
+    printk(KERN_ERR 
+           "pexor_ioctl_read_register: could not get Semaphore sem_buf\n");
+    return -ERESTARTSYS;
+  }
+  
   retval = copy_from_user(&descriptor, (void __user *)arg,
                           sizeof(struct pexor_reg_io));
   if (retval != 0) {
@@ -829,7 +870,7 @@ int pexor_ioctl_read_register(struct pexor_privdata* priv,
   retval = copy_to_user((void __user *)arg, &descriptor,
                         sizeof(struct pexor_reg_io));
  OUT_READ_REG:
-  spin_unlock((&(priv->dma_lock)));
+  up(&priv->sem_ioctl);
   return retval;
 }
 
@@ -841,12 +882,16 @@ int pexor_ioctl_write_register(struct pexor_privdata* priv,
   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));
+  /* Request Semaphore */
+  if (down_interruptible(&priv->sem_ioctl) != 0) {
+    printk(KERN_ERR 
+           "pexor_ioctl_write_register: could not get Semaphore sem_buf\n");
+    return -ERESTARTSYS;
+  }
+
+  retval = copy_from_user(&descriptor, (void __user *)arg,
+                          sizeof(struct pexor_reg_io));
   if (retval != 0) {
     goto OUT_WRITE_REG;
   }
@@ -878,11 +923,10 @@ int pexor_ioctl_write_register(struct pexor_privdata* priv,
   udelay(UDELAY_TIME);
   
  OUT_WRITE_REG:
-  spin_unlock((&(priv->dma_lock)));
+  up(&priv->sem_ioctl);
   return retval;
 }
 
-
 DEFINE_MUTEX(fs_mutex);
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
@@ -907,42 +951,39 @@ int pexor_ioctl(struct inode* inode,
                 unsigned int cmd, 
                 unsigned long arg)
 {
-  struct pexor_privdata* privdata;
+  struct pexor_privdata* priv;
   /* here validity check for magic number etc. */
 
-  privdata = get_privdata(filp);
-  if (!privdata)
+  priv = get_privdata(filp);
+  if (!priv) {
     return -EFAULT;
+  }
+  
   /* Select the appropiate command */
   switch (cmd) {
-
+    
     /* first all common ioctls: */
-
   case PEXOR_IOC_WRITE_REGISTER:
     pexor_dbg(KERN_NOTICE "** pexor_ioctl write register\n");
-    return pexor_ioctl_write_register(privdata, arg);
-    break;
-
+    return pexor_ioctl_write_register(priv, arg);
+    
   case PEXOR_IOC_READ_REGISTER:
     pexor_dbg(KERN_NOTICE "** pexor_ioctl read register\n");
-    return pexor_ioctl_read_register(privdata, arg);
-    break;
-
-
+    return pexor_ioctl_read_register(priv, arg);
+    
     /* special ioctls for different protocol implementations: */
-
   case PEXOR_IOC_TRBNET_REQUEST:
     pexor_dbg(KERN_NOTICE "** pexor_ioctl trbnet request \n");
-    return pexor_ioctl_trbnet_request(privdata, arg);
-    break;
-
+    return pexor_ioctl_trbnet_request(priv, arg);
+    
   default:
     return -ENOTTY;
   }
+
   return -ENOTTY;
 }
 
-static int __init pexor_init(void)
+int __init pexor_init(void)
 {
 
   int result;
@@ -997,7 +1038,7 @@ static void __exit pexor_exit(void)
 
 /* ------ TRBNet Specific ----------------------------------------------- */
 
-static int pexor_free_dma_buffer(struct pexor_privdata* priv)
+int pexor_free_dma_buffer(struct pexor_privdata* priv)
 {
   /* free sglist */
   if (priv->dma.sglist != NULL) {
@@ -1023,8 +1064,8 @@ 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)
+int pexor_alloc_dma_buffer(struct pexor_privdata* priv, 
+                           size_t size)
 {
   struct page* pg = NULL;
   unsigned long uaddr = 0;
@@ -1115,8 +1156,8 @@ static int pexor_alloc_dma_buffer(struct pexor_privdata* priv,
 #define MASK_HEADER_TYPE    (0x0007 << SHIFT_HEADER_TYPE)
 #define HEADER_TRM          0x0003
 
-static int pexor_copy_fifo_to_dma(struct pexor_privdata* priv,
-                                  unsigned int channel)
+int pexor_copy_fifo_to_dma(struct pexor_privdata* priv,
+                           unsigned int channel)
 {
   unsigned int sg_ctr;
   unsigned int sg_length;
@@ -1177,7 +1218,12 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata* priv,
   unsigned int dmaSize = 0;
   struct pexor_trbnet_io descriptor;
 
-  spin_lock((&(priv->dma_lock)));
+  /* Request Semaphore */
+  if (down_interruptible(&priv->sem_ioctl) != 0) {
+    printk(KERN_ERR 
+           "pexor_ioctl_trbnet_request: could not get Semaphore sem_buf\n");
+    return -ERESTARTSYS;
+  }
 
   if (copy_from_user(&descriptor,
                      (void __user *)arg, sizeof(struct pexor_trbnet_io))) {
@@ -1483,7 +1529,7 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata* priv,
   }
   
  OUT_IOCTL:
-  spin_unlock((&(priv->dma_lock)));
+  up(&priv->sem_ioctl);
   return status;
 }