Commit 9e1dadfd authored by Federico Vaga's avatar Federico Vaga

sw:drv: fix VME DMA concurrent transfers

On SVEC we can have up to two FMC-ADC-100M mezzanine, potentially
triggering at the same time. If such conditions, the driver fails in
performing the DMA on both mezzanine because one of the two will fail to
request a channel.

With this patch we introducte a 10s timeout for the ADC to request a DMA
channel on SVEC.
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 4f9f5589
...@@ -112,21 +112,28 @@ int fa_dma_request_channel(struct fa_dev *fa) ...@@ -112,21 +112,28 @@ int fa_dma_request_channel(struct fa_dev *fa)
* DMA channels. Then we will request a channel only once at probe like * DMA channels. Then we will request a channel only once at probe like
* on SPEC * on SPEC
*/ */
static int fa_dma_request_channel_svec(struct fa_dev *fa) static int fa_dma_request_channel_svec(struct fa_dev *fa,
unsigned int timeout_ms)
{ {
unsigned long j = jiffies + msecs_to_jiffies(timeout_ms);
dma_cap_mask_t dma_mask; dma_cap_mask_t dma_mask;
if (!fa_is_flag_set(fa, FMC_ADC_SVEC)) if (!fa_is_flag_set(fa, FMC_ADC_SVEC))
return 0; return 0;
dma_cap_zero(dma_mask); dma_cap_zero(dma_mask);
dma_cap_set(DMA_SLAVE, dma_mask); dma_cap_set(DMA_SLAVE, dma_mask);
dma_cap_set(DMA_PRIVATE, dma_mask); dma_cap_set(DMA_PRIVATE, dma_mask);
fa->dchan = dma_request_channel(dma_mask,
fa_dmaengine_filter_svec, fa); do {
if (!fa->dchan) fa->dchan = dma_request_channel(dma_mask,
return -ENODEV; fa_dmaengine_filter_svec, fa);
return 0; if (fa->dchan)
return 0;
cpu_relax();
} while (!fa->dchan && time_after(jiffies, j) == 0);
return -ETIMEDOUT;
} }
static void __fa_dma_release_channel(struct fa_dev *fa) static void __fa_dma_release_channel(struct fa_dev *fa)
...@@ -597,7 +604,7 @@ static int fa_dma_start_svec(struct zio_cset *cset) ...@@ -597,7 +604,7 @@ static int fa_dma_start_svec(struct zio_cset *cset)
struct zfad_block *zfad_block = cset->interleave->priv_d; struct zfad_block *zfad_block = cset->interleave->priv_d;
int err, i; int err, i;
err = fa_dma_request_channel_svec(fa); err = fa_dma_request_channel_svec(fa, 60000);
if (err) if (err)
return err; return err;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment