[Xenomai-git] Alexis Berlemont : analogy: [pcimio] fix many race conditions in DMA output transfers

2010-03-28 Thread GIT version control
Module: xenomai-2.5
Branch: master
Commit: 07bae25974ad76d29a427b195c6b7de1c0d30c63
URL:
http://git.xenomai.org/?p=xenomai-2.5.git;a=commit;h=07bae25974ad76d29a427b195c6b7de1c0d30c63

Author: Alexis Berlemont alexis.berlem...@gmail.com
Date:   Mon Mar  1 01:08:28 2010 +0100

analogy: [pcimio] fix many race conditions in DMA output transfers

WARNING: Some parts of the driver mio_common cannot be tolerated in a
real-time system. For example, the function ni_ao_wait_for_dma_load
must be reviewed; it contains two busy waiting loops which can last up
to 1 micro-seconds.

---

 .../analogy/national_instruments/mio_common.c  |   98 +++
 ksrc/drivers/analogy/national_instruments/mite.c   |   17 +++-
 2 files changed, 72 insertions(+), 43 deletions(-)

diff --git a/ksrc/drivers/analogy/national_instruments/mio_common.c 
b/ksrc/drivers/analogy/national_instruments/mio_common.c
index db9762a..1a39206 100644
--- a/ksrc/drivers/analogy/national_instruments/mio_common.c
+++ b/ksrc/drivers/analogy/national_instruments/mio_common.c
@@ -506,17 +506,28 @@ void mite_handle_b_linkc(a4l_subd_t *subd)
a4l_unlock_irqrestore(devpriv-mite_channel_lock, flags);
 }
 
-static int ni_ao_wait_for_dma_load(a4l_dev_t *dev)
+static int ni_ao_wait_for_dma_load(a4l_subd_t *subd)
 {
static const int timeout = 1;
+
+   a4l_dev_t *dev = subd-dev;
+   a4l_buf_t *buf = dev-transfer.bufs[subd-idx];
+
int i;
 
for (i = 0; i  timeout; i++) {
+   
+   int buffer_filled;
unsigned short b_status;
 
b_status = devpriv-stc_readw(dev, AO_Status_1_Register);
-   if (b_status  AO_FIFO_Half_Full_St)
+
+   buffer_filled = test_bit(A4L_BUF_EOA_NR, buf-evt_flags);
+   buffer_filled |= (b_status  AO_FIFO_Half_Full_St);
+
+   if (buffer_filled)
break;
+
/* If we poll too often, the pci bus activity seems
   to slow the dma transfer down */
a4l_udelay(10);
@@ -569,7 +580,7 @@ static inline int ni_request_cdo_mite_channel(a4l_dev_t 
*dev)
 #define ni_sync_ai_dma(x) do { } while (0)
 #define mite_handle_b_linkc(x) do { } while (0)
 
-static inline int ni_ao_wait_for_dma_load(a4l_dev_t *dev)
+static inline int ni_ao_wait_for_dma_load(a4l_subd_t *subd)
 {
return -ENOTSUPP;
 }
@@ -714,14 +725,12 @@ static void ni_handle_eos(a4l_subd_t *subd)
 }
 
 static void ni_event(a4l_subd_t * subd)
-{
-   
+{  
/* Temporary hack */
a4l_dev_t *dev = subd-dev;
a4l_buf_t *buf = dev-transfer.bufs[subd-idx];
 
-   if(test_bit(A4L_BUF_ERROR, buf-evt_flags)) {
-
+   if(test_bit(A4L_BUF_ERROR_NR, buf-evt_flags)) {
if (subd-cancel != NULL)
subd-cancel(subd);
}
@@ -939,28 +948,15 @@ static void handle_b_interrupt(a4l_dev_t * dev,
 
a4l_subd_t *subd = a4l_get_subd(dev, NI_AO_SUBDEV);
 
-   a4l_info(dev, ni_mio_common: interrupt: b_status=%04x 
m1_status=%08x\n,
-b_status, ao_mite_status);
-   ni_mio_print_status_b(b_status);
-
-#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \
- defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE))
-   /* Currently, mite.c requires us to handle LINKC */
-   if (ao_mite_status  CHSR_LINKC) {
-   mite_handle_b_linkc(subd);
-   }
+   a4l_dbg(1, drv_dbg, dev, 
+   ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n,
+   b_status, ao_mite_status);
 
-   if (ao_mite_status  ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
-  CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
-  CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
-   a4l_info(dev, unknown mite interrupt, ack! 
(ao_mite_status=%08x)\n,
-ao_mite_status);
-   a4l_buf_evt(subd, A4L_BUF_ERROR);
-   }
-#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */
+   ni_mio_print_status_b(b_status);
 
if (b_status == 0x)
return;
+
if (b_status  AO_Overrun_St) {
a4l_err(dev,
ni_mio_common: interrupt: 
@@ -971,15 +967,38 @@ static void handle_b_interrupt(a4l_dev_t * dev,
}
 
if (b_status  AO_BC_TC_St) {
-   a4l_info(dev,
-ni_mio_common: interrupt: 
-AO BC_TC status=0x%04x status2=0x%04x\n, 
-b_status, devpriv-stc_readw(dev, 
AO_Status_2_Register));
+   a4l_dbg(1, drv_dbg, dev,
+   ni_mio_common: interrupt: 
+   AO BC_TC status=0x%04x status2=0x%04x\n, 
+   b_status, devpriv-stc_readw(dev, 
AO_Status_2_Register));
a4l_buf_evt(subd, A4L_BUF_EOA);
}
 
+#if 

[Xenomai-git] Alexis Berlemont : analogy: [pcimio] fix many race conditions in DMA output transfers

2010-03-18 Thread GIT version control
Module: xenomai-abe
Branch: analogy
Commit: 07bae25974ad76d29a427b195c6b7de1c0d30c63
URL:
http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=07bae25974ad76d29a427b195c6b7de1c0d30c63

Author: Alexis Berlemont alexis.berlem...@gmail.com
Date:   Mon Mar  1 01:08:28 2010 +0100

analogy: [pcimio] fix many race conditions in DMA output transfers

WARNING: Some parts of the driver mio_common cannot be tolerated in a
real-time system. For example, the function ni_ao_wait_for_dma_load
must be reviewed; it contains two busy waiting loops which can last up
to 1 micro-seconds.

---

 .../analogy/national_instruments/mio_common.c  |   98 +++
 ksrc/drivers/analogy/national_instruments/mite.c   |   17 +++-
 2 files changed, 72 insertions(+), 43 deletions(-)

diff --git a/ksrc/drivers/analogy/national_instruments/mio_common.c 
b/ksrc/drivers/analogy/national_instruments/mio_common.c
index db9762a..1a39206 100644
--- a/ksrc/drivers/analogy/national_instruments/mio_common.c
+++ b/ksrc/drivers/analogy/national_instruments/mio_common.c
@@ -506,17 +506,28 @@ void mite_handle_b_linkc(a4l_subd_t *subd)
a4l_unlock_irqrestore(devpriv-mite_channel_lock, flags);
 }
 
-static int ni_ao_wait_for_dma_load(a4l_dev_t *dev)
+static int ni_ao_wait_for_dma_load(a4l_subd_t *subd)
 {
static const int timeout = 1;
+
+   a4l_dev_t *dev = subd-dev;
+   a4l_buf_t *buf = dev-transfer.bufs[subd-idx];
+
int i;
 
for (i = 0; i  timeout; i++) {
+   
+   int buffer_filled;
unsigned short b_status;
 
b_status = devpriv-stc_readw(dev, AO_Status_1_Register);
-   if (b_status  AO_FIFO_Half_Full_St)
+
+   buffer_filled = test_bit(A4L_BUF_EOA_NR, buf-evt_flags);
+   buffer_filled |= (b_status  AO_FIFO_Half_Full_St);
+
+   if (buffer_filled)
break;
+
/* If we poll too often, the pci bus activity seems
   to slow the dma transfer down */
a4l_udelay(10);
@@ -569,7 +580,7 @@ static inline int ni_request_cdo_mite_channel(a4l_dev_t 
*dev)
 #define ni_sync_ai_dma(x) do { } while (0)
 #define mite_handle_b_linkc(x) do { } while (0)
 
-static inline int ni_ao_wait_for_dma_load(a4l_dev_t *dev)
+static inline int ni_ao_wait_for_dma_load(a4l_subd_t *subd)
 {
return -ENOTSUPP;
 }
@@ -714,14 +725,12 @@ static void ni_handle_eos(a4l_subd_t *subd)
 }
 
 static void ni_event(a4l_subd_t * subd)
-{
-   
+{  
/* Temporary hack */
a4l_dev_t *dev = subd-dev;
a4l_buf_t *buf = dev-transfer.bufs[subd-idx];
 
-   if(test_bit(A4L_BUF_ERROR, buf-evt_flags)) {
-
+   if(test_bit(A4L_BUF_ERROR_NR, buf-evt_flags)) {
if (subd-cancel != NULL)
subd-cancel(subd);
}
@@ -939,28 +948,15 @@ static void handle_b_interrupt(a4l_dev_t * dev,
 
a4l_subd_t *subd = a4l_get_subd(dev, NI_AO_SUBDEV);
 
-   a4l_info(dev, ni_mio_common: interrupt: b_status=%04x 
m1_status=%08x\n,
-b_status, ao_mite_status);
-   ni_mio_print_status_b(b_status);
-
-#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \
- defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE))
-   /* Currently, mite.c requires us to handle LINKC */
-   if (ao_mite_status  CHSR_LINKC) {
-   mite_handle_b_linkc(subd);
-   }
+   a4l_dbg(1, drv_dbg, dev, 
+   ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n,
+   b_status, ao_mite_status);
 
-   if (ao_mite_status  ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
-  CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
-  CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
-   a4l_info(dev, unknown mite interrupt, ack! 
(ao_mite_status=%08x)\n,
-ao_mite_status);
-   a4l_buf_evt(subd, A4L_BUF_ERROR);
-   }
-#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */
+   ni_mio_print_status_b(b_status);
 
if (b_status == 0x)
return;
+
if (b_status  AO_Overrun_St) {
a4l_err(dev,
ni_mio_common: interrupt: 
@@ -971,15 +967,38 @@ static void handle_b_interrupt(a4l_dev_t * dev,
}
 
if (b_status  AO_BC_TC_St) {
-   a4l_info(dev,
-ni_mio_common: interrupt: 
-AO BC_TC status=0x%04x status2=0x%04x\n, 
-b_status, devpriv-stc_readw(dev, 
AO_Status_2_Register));
+   a4l_dbg(1, drv_dbg, dev,
+   ni_mio_common: interrupt: 
+   AO BC_TC status=0x%04x status2=0x%04x\n, 
+   b_status, devpriv-stc_readw(dev, 
AO_Status_2_Register));
a4l_buf_evt(subd, A4L_BUF_EOA);
}
 
+#if 

[Xenomai-git] Alexis Berlemont : analogy: [pcimio] fix many race conditions in DMA output transfers

2010-02-28 Thread GIT version control
Module: xenomai-abe
Branch: analogy
Commit: 1ab31f83998636f2fc7b9bf1f53d73adfc950ecc
URL:
http://git.xenomai.org/?p=xenomai-abe.git;a=commit;h=1ab31f83998636f2fc7b9bf1f53d73adfc950ecc

Author: Alexis Berlemont alexis.berlem...@gmail.com
Date:   Mon Mar  1 01:08:28 2010 +0100

analogy: [pcimio] fix many race conditions in DMA output transfers

WARNING: Some parts of the driver mio_common cannot be tolerated in a
real-time system. For example, the function ni_ao_wait_for_dma_load
must be reviewed; it contains two busy waiting loops which can last up
to 1 micro-seconds.

---

 .../analogy/national_instruments/mio_common.c  |   98 +++
 ksrc/drivers/analogy/national_instruments/mite.c   |   17 +++-
 2 files changed, 72 insertions(+), 43 deletions(-)

diff --git a/ksrc/drivers/analogy/national_instruments/mio_common.c 
b/ksrc/drivers/analogy/national_instruments/mio_common.c
index db9762a..1a39206 100644
--- a/ksrc/drivers/analogy/national_instruments/mio_common.c
+++ b/ksrc/drivers/analogy/national_instruments/mio_common.c
@@ -506,17 +506,28 @@ void mite_handle_b_linkc(a4l_subd_t *subd)
a4l_unlock_irqrestore(devpriv-mite_channel_lock, flags);
 }
 
-static int ni_ao_wait_for_dma_load(a4l_dev_t *dev)
+static int ni_ao_wait_for_dma_load(a4l_subd_t *subd)
 {
static const int timeout = 1;
+
+   a4l_dev_t *dev = subd-dev;
+   a4l_buf_t *buf = dev-transfer.bufs[subd-idx];
+
int i;
 
for (i = 0; i  timeout; i++) {
+   
+   int buffer_filled;
unsigned short b_status;
 
b_status = devpriv-stc_readw(dev, AO_Status_1_Register);
-   if (b_status  AO_FIFO_Half_Full_St)
+
+   buffer_filled = test_bit(A4L_BUF_EOA_NR, buf-evt_flags);
+   buffer_filled |= (b_status  AO_FIFO_Half_Full_St);
+
+   if (buffer_filled)
break;
+
/* If we poll too often, the pci bus activity seems
   to slow the dma transfer down */
a4l_udelay(10);
@@ -569,7 +580,7 @@ static inline int ni_request_cdo_mite_channel(a4l_dev_t 
*dev)
 #define ni_sync_ai_dma(x) do { } while (0)
 #define mite_handle_b_linkc(x) do { } while (0)
 
-static inline int ni_ao_wait_for_dma_load(a4l_dev_t *dev)
+static inline int ni_ao_wait_for_dma_load(a4l_subd_t *subd)
 {
return -ENOTSUPP;
 }
@@ -714,14 +725,12 @@ static void ni_handle_eos(a4l_subd_t *subd)
 }
 
 static void ni_event(a4l_subd_t * subd)
-{
-   
+{  
/* Temporary hack */
a4l_dev_t *dev = subd-dev;
a4l_buf_t *buf = dev-transfer.bufs[subd-idx];
 
-   if(test_bit(A4L_BUF_ERROR, buf-evt_flags)) {
-
+   if(test_bit(A4L_BUF_ERROR_NR, buf-evt_flags)) {
if (subd-cancel != NULL)
subd-cancel(subd);
}
@@ -939,28 +948,15 @@ static void handle_b_interrupt(a4l_dev_t * dev,
 
a4l_subd_t *subd = a4l_get_subd(dev, NI_AO_SUBDEV);
 
-   a4l_info(dev, ni_mio_common: interrupt: b_status=%04x 
m1_status=%08x\n,
-b_status, ao_mite_status);
-   ni_mio_print_status_b(b_status);
-
-#if (defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE) || \
- defined(CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE_MODULE))
-   /* Currently, mite.c requires us to handle LINKC */
-   if (ao_mite_status  CHSR_LINKC) {
-   mite_handle_b_linkc(subd);
-   }
+   a4l_dbg(1, drv_dbg, dev, 
+   ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n,
+   b_status, ao_mite_status);
 
-   if (ao_mite_status  ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
-  CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
-  CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
-   a4l_info(dev, unknown mite interrupt, ack! 
(ao_mite_status=%08x)\n,
-ao_mite_status);
-   a4l_buf_evt(subd, A4L_BUF_ERROR);
-   }
-#endif /* CONFIG_XENO_DRIVERS_ANALOGY_NI_MITE */
+   ni_mio_print_status_b(b_status);
 
if (b_status == 0x)
return;
+
if (b_status  AO_Overrun_St) {
a4l_err(dev,
ni_mio_common: interrupt: 
@@ -971,15 +967,38 @@ static void handle_b_interrupt(a4l_dev_t * dev,
}
 
if (b_status  AO_BC_TC_St) {
-   a4l_info(dev,
-ni_mio_common: interrupt: 
-AO BC_TC status=0x%04x status2=0x%04x\n, 
-b_status, devpriv-stc_readw(dev, 
AO_Status_2_Register));
+   a4l_dbg(1, drv_dbg, dev,
+   ni_mio_common: interrupt: 
+   AO BC_TC status=0x%04x status2=0x%04x\n, 
+   b_status, devpriv-stc_readw(dev, 
AO_Status_2_Register));
a4l_buf_evt(subd, A4L_BUF_EOA);
}
 
+#if