]> jspc29.x-matter.uni-frankfurt.de Git - trbnettools.git/commitdiff
bugfix
authorhadaq <hadaq>
Wed, 19 Oct 2011 15:39:09 +0000 (15:39 +0000)
committerhadaq <hadaq>
Wed, 19 Oct 2011 15:39:09 +0000 (15:39 +0000)
pexor/kernel-module/pexor_trb.c
pexor/kernel-module/pexor_trb.h

index c3ac4df8d979c4790e67aa65b58a778430c3ea6b..0e6af13812004d7a0addbf77ad3aef582e4ee14c 100644 (file)
@@ -75,7 +75,7 @@ struct dev_pexor
 };
 
 #define DMA_BUFFER_NUM_PAGES ((8 * 1024 * 1024) / PAGE_SIZE)
-#define PEXOR_DMA_MAXPOLLS 1000000
+#define PEXOR_DMA_MAXPOLLS 10000
 #define PEXOR_DMA_POLLDELAY 0
 #define PEXOR_MEMWRITE_SIZE 128
 
@@ -635,7 +635,7 @@ static int probe(struct pci_dev *dev, const struct pci_device_id *id)
   }
 
   /* allocate memwrite_buffer */
-  privdata->memwrite_buffer = vmalloc_32(PEXOR_MEMWRITE_SIZE * 4);
+  privdata->memwrite_buffer = vmalloc_32_user(PEXOR_MEMWRITE_SIZE * 4);
   if (privdata->memwrite_buffer == NULL) {
     pexor_msg(KERN_ERR "ERROR> probe allocate memwrite_buffer failed\n");
     return -ENOMEM;
@@ -666,6 +666,8 @@ 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)
 {
@@ -681,13 +683,23 @@ ssize_t pexor_read(struct file * filp,
     return -EFAULT;
   }
   if (count > privdata->dma.size) {
+    pexor_msg(KERN_ERR "ERROR> pexor_read: requested count (%d) > Max: %d\n", 
+              (int)count, (int)privdata->dma.size);
+    return -EFAULT;
+  }
+  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;
   }
+  pexor_read_buffer_ctr -= count;
 
   if (down_interruptible(&privdata->sem) != 0) {
     return -ERESTARTSYS;
   }
   if (copy_to_user(buf, privdata->dma.buffer, count)) {
+    pexor_msg(KERN_ERR "ERROR> pexor_read: copy_to_user failed\n");
     retval = -EFAULT;
     goto out_read;
   }
@@ -1063,7 +1075,7 @@ static int pexor_alloc_dma_buffer(struct pexor_privdata *priv, size_t size)
   priv->dma.nr_sglist = 0;
 
   /* allocate DAM-Buffer */
-  priv->dma.buffer = vmalloc_32(size);
+  priv->dma.buffer = vmalloc_32_user(size);
   if (priv->dma.buffer == NULL) {
     pexor_msg(KERN_ERR
               "ERROR> pexor_alloc_dma_buffer: vmalloc failed buffer\n");
@@ -1150,22 +1162,19 @@ static int pexor_copy_fifo_to_dma(struct pexor_privdata *priv,
   unsigned int ctr = 0;
   volatile u32 val = 0;
   unsigned int i;
-
+  
   if (channel >= PEXOR_TRB_NUM_CHANNELS)
     return -1;
-
+  
+  pexor_read_buffer_ctr = 0;
   for (sg_ctr = 0; sg_ctr < priv->dma.nr_sglist; sg_ctr++) {
-    /* sync current sg-entry to CPU */
-    dma_sync_single_for_cpu(priv->class_dev,
-                            sg_dma_address(&priv->dma.sglist[sg_ctr]),
-                            sg_dma_len(&priv->dma.sglist[sg_ctr]),
-                            DMA_FROM_DEVICE);
     sg_length = sg_dma_len(&priv->dma.sglist[sg_ctr]);
     for (i = 0; i < sg_length; i++) {
       timeout = 0;
       do {
         val = ioread32(priv->pexor.trbnet_receiver_data[channel]);
         if ((val & MASK_FIFO_TRB_ACT) == 0) {
+          pexor_read_buffer_ctr += ctr * 4;
           return ctr;
         }
       } while (((val & MASK_FIFO_VALID) == 0) &&
@@ -1186,7 +1195,7 @@ static int pexor_copy_fifo_to_dma(struct pexor_privdata *priv,
 #endif
       ctr++;
     }
-
+    
   }
 
   /* should not happen,out of buffers etc */
@@ -1339,52 +1348,53 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg)
 
   if (descriptor.dma != 0 && channel == 3) {
     /* only channel 3 supports DMA */
-    
+    pexor_read_buffer_ctr = 0;
+
     /* Start DMA transfer */
     pexor_dbg(KERN_ERR "Start DMA transfer\n");
     for (sg_ctr = 0; sg_ctr < priv->dma.nr_sglist; sg_ctr++) {
       unsigned int loops = 0;
       
       mb();
-      /* do we need this?? */
-      /*
-        dma_sync_single_for_device(priv->class_dev,
-        sg_dma_address(&priv->dma.sglist[sg_ctr]),
-        sg_dma_len(&priv->dma.sglist[sg_ctr]),
-        DMA_FROM_DEVICE);
-      */
+      /* sync current sg-entry to Device */
+      dma_sync_single_for_device(priv->class_dev,
+                                 sg_dma_address(&priv->dma.sglist[sg_ctr]),
+                                 sg_dma_len(&priv->dma.sglist[sg_ctr]),
+                                 DMA_FROM_DEVICE);
+      
       iowrite32(sg_dma_address(&priv->dma.sglist[sg_ctr]),
                 priv->pexor.dma_dest);
       iowrite32(sg_dma_len(&priv->dma.sglist[sg_ctr]) / 4,
                 priv->pexor.dma_len);
       
       /* wait for dma complete */
-      for (loops = 0; loops < PEXOR_DMA_MAXPOLLS * 100; loops++) {
+      for (loops = 0; loops < PEXOR_DMA_MAXPOLLS; loops++) {
         dmastat = ioread32(priv->pexor.dma_control_stat);
-        //pexor_msg(KERN_ERR "DMA: Status: is: 0x%08x   %d\n", dmastat, loops);
         mb();
         if ((dmastat & PEXOR_TRB_BIT_DMA_FINISHED) != 0) {
           /* DMA is completed */
           dmaSize = dmastat >> 8;
           if (dmaSize == 0) {
-            pexor_msg(KERN_ERR "DMA: Zero Length Error, Status: 0x%08x\n", dmastat);
+            pexor_msg(KERN_ERR "DMA: Zero Length Error, Status: 0x%08x\n",
+                      dmastat);
           }
           break;
         }
         if ((dmastat & PEXOR_TRB_BIT_DMA_MORE) != 0) {
           /* Card needs more DMA-Buffers */
-          //pexor_msg(KERN_ERR "DMA: More Status: 0x%08x\n", dmastat);
           break;
         }
         if ((dmastat & PEXOR_TRB_BIT_DMA_TIMEOUT) != 0) {
           /* TRBNet Timeout */
-          //pexor_msg(KERN_ERR "DMA: Timeout Status: 0x%08x\n", dmastat);
           pexor_msg(KERN_ERR
                     "ERROR> wait_dma_complete: TRBNet Timeout Bit set "
                     "Status: 0x%08x\n",
                     (unsigned int)dmastat);
+          /* reset DMA */
+          iowrite32(PEXOR_TRB_DMA_RESET, priv->pexor.dma_control_stat);
+          /* do we need to flush the fifo-buffer? */
           status = -EFAULT;
-          goto OUT_DMA;
+          goto OUT_IOCTL;
         }
       }
       /* Check for kernel timeout */
@@ -1394,9 +1404,11 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg)
                   "(delay %d ns) for dma complete! Status: 0x%08x\n",
                   PEXOR_DMA_MAXPOLLS, PEXOR_DMA_POLLDELAY,
                   (unsigned int)dmastat);
+        /* reset DMA */
+        iowrite32(PEXOR_TRB_DMA_RESET, priv->pexor.dma_control_stat);
         /* do we need to flush the fifo-buffer? */
         status = -EFAULT;
-        goto OUT_DMA;
+        goto OUT_IOCTL;
       }
 
       /* sync current sg-entry to CPU */
@@ -1414,13 +1426,16 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg)
       if ((sg_ctr + 1) >= priv->dma.nr_sglist) {
         pexor_msg(KERN_ERR
                   "ERROR> no more DMA buffers available, aborting DMA\n");
+        /* reset DMA */
+        iowrite32(PEXOR_TRB_DMA_RESET, priv->pexor.dma_control_stat);
         /* do we need to flush the fifo-buffer? */
         status = -EFAULT;
-        goto OUT_DMA;
+        goto OUT_IOCTL;
       }
     }
 
     status = dmaSize;
+    pexor_read_buffer_ctr = dmaSize * 4;
 
 #ifdef PEXOR_TRB_DEBUG
     {
@@ -1438,16 +1453,14 @@ int pexor_ioctl_trbnet_request(struct pexor_privdata *priv, unsigned long arg)
 
   } else {
     /* do FIFO transfer to DMA Buffer */
-    pexor_dbg(KERN_ERR "Start FIFO copy to DMA buffer\n");
     status = pexor_copy_fifo_to_dma(priv, channel);
+    pexor_dbg(KERN_ERR "FIFO copy to DMA buffer returned Size: %d\n", status);
     if (status == -1) {
       status = -EFAULT;
       goto OUT_IOCTL;
     }
   }
 
-OUT_DMA:
-
 OUT_IOCTL:
   spin_unlock((&(priv->dma_lock)));
   return status;
index e58e930f2693cc4b817172d0ad719f3f9babd223..f0211429cb8414660e8e3924f68de5429186f6bf 100644 (file)
 #define PEXOR_TRB_BIT_DMA_FINISHED       0x04
 #define PEXOR_TRB_BIT_DMA_TIMEOUT        0x08
 
-#define PEXOR_DRAM                       0x100000       /* TODO: specify meaningful RAM position for fops io functions? */
-
-#define PEXOR_DMA_BASE                  0x00    /* base address of DMA engine */
-
-#define PEXOR_IRQ_CTRL   PEXOR_DMA_BASE /* DUMMY TODO meaningful register for trbnet */
-#define PEXOR_IRQ_STAT   PEXOR_DMA_BASE /* DUMMY TODO meaningful register for trbnet */
-#define PEXOR_IRQ_USER_BIT              0x01    /* DUMMY TODO meaningful register for trbnet */
+#define PEXOR_DRAM                       0x100000 /* TODO: specify meaningful 
+                                                     RAM position for fops io 
+                                                     functions? */
+
+#define PEXOR_DMA_BASE                   0x00  /* base address of DMA engine */
+
+#define PEXOR_IRQ_CTRL   PEXOR_DMA_BASE       /* DUMMY TODO meaningful 
+                                                 register for trbnet */
+#define PEXOR_IRQ_STAT   PEXOR_DMA_BASE       /* DUMMY TODO meaningful register
+                                                 for trbnet */
+#define PEXOR_IRQ_USER_BIT              0x01  /* DUMMY TODO meaningful register
+                                                 for trbnet */
 
 
 #define PEXOR_TRB_NUM_CHANNELS           4