Commit 8f83d52d authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: addi_apci_3120: introduce struct apci3120_dmabuf

For aesthetics, wrap the DMA buffer information in a struct.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 1b90779b
...@@ -1003,6 +1003,8 @@ static int apci3120_cyclic_ai(int mode, ...@@ -1003,6 +1003,8 @@ static int apci3120_cyclic_ai(int mode,
} }
} else { } else {
/* If DMA Enabled */ /* If DMA Enabled */
struct apci3120_dmabuf *dmabuf0 = &devpriv->dmabuf[0];
struct apci3120_dmabuf *dmabuf1 = &devpriv->dmabuf[1];
unsigned int scan_bytes = cmd->scan_end_arg * sizeof(short); unsigned int scan_bytes = cmd->scan_end_arg * sizeof(short);
devpriv->b_InterruptMode = APCI3120_DMA_MODE; devpriv->b_InterruptMode = APCI3120_DMA_MODE;
...@@ -1014,8 +1016,8 @@ static int apci3120_cyclic_ai(int mode, ...@@ -1014,8 +1016,8 @@ static int apci3120_cyclic_ai(int mode,
outb(devpriv->b_ModeSelectRegister, outb(devpriv->b_ModeSelectRegister,
dev->iobase + APCI3120_WRITE_MODE_SELECT); dev->iobase + APCI3120_WRITE_MODE_SELECT);
dmalen0 = devpriv->ui_DmaBufferSize[0]; dmalen0 = dmabuf0->size;
dmalen1 = devpriv->ui_DmaBufferSize[1]; dmalen1 = dmabuf1->size;
if (cmd->stop_src == TRIG_COUNT) { if (cmd->stop_src == TRIG_COUNT) {
/* /*
...@@ -1050,8 +1052,8 @@ static int apci3120_cyclic_ai(int mode, ...@@ -1050,8 +1052,8 @@ static int apci3120_cyclic_ai(int mode,
if (dmalen1 > s->async->prealloc_bufsz) if (dmalen1 > s->async->prealloc_bufsz)
dmalen1 = s->async->prealloc_bufsz; dmalen1 = s->async->prealloc_bufsz;
} }
devpriv->ui_DmaBufferUsesize[0] = dmalen0; dmabuf0->use_size = dmalen0;
devpriv->ui_DmaBufferUsesize[1] = dmalen1; dmabuf1->use_size = dmalen1;
/* Initialize DMA */ /* Initialize DMA */
...@@ -1094,13 +1096,11 @@ static int apci3120_cyclic_ai(int mode, ...@@ -1094,13 +1096,11 @@ static int apci3120_cyclic_ai(int mode,
/* DMA Start Address Low */ /* DMA Start Address Low */
outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
outw((devpriv->ul_DmaBufferHw[0] & 0xFFFF), outw(dmabuf0->hw & 0xffff, devpriv->i_IobaseAddon + 2);
devpriv->i_IobaseAddon + 2);
/* DMA Start Address High */ /* DMA Start Address High */
outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
outw((devpriv->ul_DmaBufferHw[0] / 65536), outw((dmabuf0->hw >> 16) & 0xffff, devpriv->i_IobaseAddon + 2);
devpriv->i_IobaseAddon + 2);
/* /*
* 4 * 4
...@@ -1110,13 +1110,12 @@ static int apci3120_cyclic_ai(int mode, ...@@ -1110,13 +1110,12 @@ static int apci3120_cyclic_ai(int mode,
/* Nbr of acquisition LOW */ /* Nbr of acquisition LOW */
outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
outw((devpriv->ui_DmaBufferUsesize[0] & 0xFFFF), outw(dmabuf0->use_size & 0xffff, devpriv->i_IobaseAddon + 2);
devpriv->i_IobaseAddon + 2);
/* Nbr of acquisition HIGH */ /* Nbr of acquisition HIGH */
outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
outw((devpriv->ui_DmaBufferUsesize[0] / 65536), outw((dmabuf0->use_size >> 16) & 0xffff,
devpriv->i_IobaseAddon + 2); devpriv->i_IobaseAddon + 2);
/* /*
* 5 * 5
...@@ -1248,18 +1247,17 @@ static void apci3120_interrupt_dma(int irq, void *d) ...@@ -1248,18 +1247,17 @@ static void apci3120_interrupt_dma(int irq, void *d)
struct apci3120_private *devpriv = dev->private; struct apci3120_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev; struct comedi_subdevice *s = dev->read_subdev;
struct comedi_cmd *cmd = &s->async->cmd; struct comedi_cmd *cmd = &s->async->cmd;
unsigned int next_dma_buf, samplesinbuf; struct apci3120_dmabuf *dmabuf;
unsigned long low_word, high_word, var; unsigned int samplesinbuf;
unsigned int ui_Tmp; unsigned int ui_Tmp;
samplesinbuf = dmabuf = &devpriv->dmabuf[devpriv->ui_DmaActualBuffer];
devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer] -
inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC); samplesinbuf = dmabuf->use_size -
inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC);
if (samplesinbuf < if (samplesinbuf < dmabuf->use_size)
devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) {
dev_err(dev->class_dev, "Interrupted DMA transfer!\n"); dev_err(dev->class_dev, "Interrupted DMA transfer!\n");
}
if (samplesinbuf & 1) { if (samplesinbuf & 1) {
dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n"); dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n");
apci3120_cancel(dev, s); apci3120_cancel(dev, s);
...@@ -1268,7 +1266,9 @@ static void apci3120_interrupt_dma(int irq, void *d) ...@@ -1268,7 +1266,9 @@ static void apci3120_interrupt_dma(int irq, void *d)
samplesinbuf = samplesinbuf >> 1; /* number of received samples */ samplesinbuf = samplesinbuf >> 1; /* number of received samples */
if (devpriv->b_DmaDoubleBuffer) { if (devpriv->b_DmaDoubleBuffer) {
/* switch DMA buffers if is used double buffering */ /* switch DMA buffers if is used double buffering */
next_dma_buf = 1 - devpriv->ui_DmaActualBuffer; struct apci3120_dmabuf *next_dmabuf;
next_dmabuf = &devpriv->dmabuf[1 - devpriv->ui_DmaActualBuffer];
ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO; ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO;
outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS); outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS);
...@@ -1280,31 +1280,24 @@ static void apci3120_interrupt_dma(int irq, void *d) ...@@ -1280,31 +1280,24 @@ static void apci3120_interrupt_dma(int irq, void *d)
outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0); outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* 0x1000 is out putted in windows driver */ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); /* 0x1000 is out putted in windows driver */
var = devpriv->ul_DmaBufferHw[next_dma_buf];
low_word = var & 0xffff;
var = devpriv->ul_DmaBufferHw[next_dma_buf];
high_word = var / 65536;
/* DMA Start Address Low */ /* DMA Start Address Low */
outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
outw(low_word, devpriv->i_IobaseAddon + 2); outw(next_dmabuf->hw & 0xffff, devpriv->i_IobaseAddon + 2);
/* DMA Start Address High */ /* DMA Start Address High */
outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
outw(high_word, devpriv->i_IobaseAddon + 2); outw((next_dmabuf->hw >> 16) & 0xffff,
devpriv->i_IobaseAddon + 2);
var = devpriv->ui_DmaBufferUsesize[next_dma_buf];
low_word = var & 0xffff;
var = devpriv->ui_DmaBufferUsesize[next_dma_buf];
high_word = var / 65536;
/* Nbr of acquisition LOW */ /* Nbr of acquisition LOW */
outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
outw(low_word, devpriv->i_IobaseAddon + 2); outw(next_dmabuf->use_size & 0xffff,
devpriv->i_IobaseAddon + 2);
/* Nbr of acquisition HIGH */ /* Nbr of acquisition HIGH */
outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
outw(high_word, devpriv->i_IobaseAddon + 2); outw((next_dmabuf->use_size > 16) & 0xffff,
devpriv->i_IobaseAddon + 2);
/* /*
* To configure A2P FIFO * To configure A2P FIFO
...@@ -1319,9 +1312,8 @@ static void apci3120_interrupt_dma(int irq, void *d) ...@@ -1319,9 +1312,8 @@ static void apci3120_interrupt_dma(int irq, void *d)
} }
if (samplesinbuf) { if (samplesinbuf) {
v_APCI3120_InterruptDmaMoveBlock16bit(dev, s, v_APCI3120_InterruptDmaMoveBlock16bit(dev, s, dmabuf->virt,
devpriv->ul_DmaBufferVirtual[devpriv-> samplesinbuf);
ui_DmaActualBuffer], samplesinbuf);
if (!(cmd->flags & CMDF_WAKE_EOS)) if (!(cmd->flags & CMDF_WAKE_EOS))
s->async->events |= COMEDI_CB_EOS; s->async->events |= COMEDI_CB_EOS;
...@@ -1356,23 +1348,16 @@ static void apci3120_interrupt_dma(int irq, void *d) ...@@ -1356,23 +1348,16 @@ static void apci3120_interrupt_dma(int irq, void *d)
outl(APCI3120_A2P_FIFO_MANAGEMENT, outl(APCI3120_A2P_FIFO_MANAGEMENT,
devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR); devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR);
var = devpriv->ul_DmaBufferHw[0];
low_word = var & 0xffff;
var = devpriv->ul_DmaBufferHw[0];
high_word = var / 65536;
outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0); outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
outw(low_word, devpriv->i_IobaseAddon + 2); outw(dmabuf->hw & 0xffff, devpriv->i_IobaseAddon + 2);
outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0); outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
outw(high_word, devpriv->i_IobaseAddon + 2); outw((dmabuf->hw >> 16) & 0xffff, devpriv->i_IobaseAddon + 2);
var = devpriv->ui_DmaBufferUsesize[0];
low_word = var & 0xffff; /* changed */
var = devpriv->ui_DmaBufferUsesize[0];
high_word = var / 65536;
outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0); outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
outw(low_word, devpriv->i_IobaseAddon + 2); outw(dmabuf->use_size & 0xffff, devpriv->i_IobaseAddon + 2);
outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0); outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
outw(high_word, devpriv->i_IobaseAddon + 2); outw((dmabuf->use_size >> 16) & 0xffff,
devpriv->i_IobaseAddon + 2);
/* /*
* To configure A2P FIFO * To configure A2P FIFO
......
...@@ -29,6 +29,13 @@ static const struct apci3120_board apci3120_boardtypes[] = { ...@@ -29,6 +29,13 @@ static const struct apci3120_board apci3120_boardtypes[] = {
}, },
}; };
struct apci3120_dmabuf {
unsigned short *virt;
dma_addr_t hw;
unsigned int size;
unsigned int use_size;
};
struct apci3120_private { struct apci3120_private {
int iobase; int iobase;
int i_IobaseAmcc; int i_IobaseAmcc;
...@@ -41,10 +48,7 @@ struct apci3120_private { ...@@ -41,10 +48,7 @@ struct apci3120_private {
unsigned short us_UseDma; unsigned short us_UseDma;
unsigned char b_DmaDoubleBuffer; unsigned char b_DmaDoubleBuffer;
unsigned int ui_DmaActualBuffer; unsigned int ui_DmaActualBuffer;
unsigned short *ul_DmaBufferVirtual[2]; struct apci3120_dmabuf dmabuf[2];
dma_addr_t ul_DmaBufferHw[2];
unsigned int ui_DmaBufferSize[2];
unsigned int ui_DmaBufferUsesize[2];
unsigned char b_DigitalOutputRegister; unsigned char b_DigitalOutputRegister;
unsigned char b_TimerSelectMode; unsigned char b_TimerSelectMode;
unsigned char b_ModeSelectRegister; unsigned char b_ModeSelectRegister;
...@@ -64,22 +68,23 @@ struct apci3120_private { ...@@ -64,22 +68,23 @@ struct apci3120_private {
static void apci3120_dma_alloc(struct comedi_device *dev) static void apci3120_dma_alloc(struct comedi_device *dev)
{ {
struct apci3120_private *devpriv = dev->private; struct apci3120_private *devpriv = dev->private;
struct apci3120_dmabuf *dmabuf;
int order; int order;
int i; int i;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
dmabuf = &devpriv->dmabuf[i];
for (order = 2; order >= 0; order--) { for (order = 2; order >= 0; order--) {
devpriv->ul_DmaBufferVirtual[i] = dmabuf->virt = dma_alloc_coherent(dev->hw_dev,
dma_alloc_coherent(dev->hw_dev, PAGE_SIZE << order, PAGE_SIZE << order,
&devpriv->ul_DmaBufferHw[i], &dmabuf->hw,
GFP_KERNEL); GFP_KERNEL);
if (dmabuf->virt)
if (devpriv->ul_DmaBufferVirtual[i])
break; break;
} }
if (!devpriv->ul_DmaBufferVirtual[i]) if (!dmabuf->virt)
break; break;
devpriv->ui_DmaBufferSize[i] = PAGE_SIZE << order; dmabuf->size = PAGE_SIZE << order;
if (i == 0) if (i == 0)
devpriv->us_UseDma = 1; devpriv->us_UseDma = 1;
...@@ -91,17 +96,17 @@ static void apci3120_dma_alloc(struct comedi_device *dev) ...@@ -91,17 +96,17 @@ static void apci3120_dma_alloc(struct comedi_device *dev)
static void apci3120_dma_free(struct comedi_device *dev) static void apci3120_dma_free(struct comedi_device *dev)
{ {
struct apci3120_private *devpriv = dev->private; struct apci3120_private *devpriv = dev->private;
struct apci3120_dmabuf *dmabuf;
int i; int i;
if (!devpriv) if (!devpriv)
return; return;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
if (devpriv->ul_DmaBufferVirtual[i]) { dmabuf = &devpriv->dmabuf[i];
dma_free_coherent(dev->hw_dev, if (dmabuf->virt) {
devpriv->ui_DmaBufferSize[i], dma_free_coherent(dev->hw_dev, dmabuf->size,
devpriv->ul_DmaBufferVirtual[i], dmabuf->virt, dmabuf->hw);
devpriv->ul_DmaBufferHw[i]);
} }
} }
} }
......
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