For aesthetics, move some of the functions to make the code easier to follow. Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx> Cc: Ian Abbott <abbotti@xxxxxxxxx> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/staging/comedi/drivers/das16.c | 300 ++++++++++++++++----------------- 1 file changed, 146 insertions(+), 154 deletions(-) diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index a482bd5..cd2fa4c 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -311,6 +311,116 @@ static void das16_ai_disable(struct comedi_device *dev) outb(devpriv->ctrl_reg, dev->iobase + DAS16_CONTROL); } +/* the pc104-das16jr (at least) has problems if the dma + transfer is interrupted in the middle of transferring + a 16 bit sample, so this function takes care to get + an even transfer count after disabling dma + channel. +*/ +static int disable_dma_on_even(struct comedi_device *dev) +{ + struct das16_private_struct *devpriv = dev->private; + int residue; + int i; + static const int disable_limit = 100; + static const int enable_timeout = 100; + + disable_dma(devpriv->dma_chan); + residue = get_dma_residue(devpriv->dma_chan); + for (i = 0; i < disable_limit && (residue % 2); ++i) { + int j; + enable_dma(devpriv->dma_chan); + for (j = 0; j < enable_timeout; ++j) { + int new_residue; + udelay(2); + new_residue = get_dma_residue(devpriv->dma_chan); + if (new_residue != residue) + break; + } + disable_dma(devpriv->dma_chan); + residue = get_dma_residue(devpriv->dma_chan); + } + if (i == disable_limit) { + comedi_error(dev, "failed to get an even dma transfer, " + "could be trouble."); + } + return residue; +} + +static void das16_interrupt(struct comedi_device *dev) +{ + struct das16_private_struct *devpriv = dev->private; + unsigned long dma_flags, spin_flags; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async; + struct comedi_cmd *cmd; + int num_bytes, residue; + int buffer_index; + + if (!dev->attached) { + comedi_error(dev, "premature interrupt"); + return; + } + /* initialize async here to make sure it is not NULL */ + async = s->async; + cmd = &async->cmd; + + spin_lock_irqsave(&dev->spinlock, spin_flags); + if ((devpriv->ctrl_reg & DMA_ENABLE) == 0) { + spin_unlock_irqrestore(&dev->spinlock, spin_flags); + return; + } + + dma_flags = claim_dma_lock(); + clear_dma_ff(devpriv->dma_chan); + residue = disable_dma_on_even(dev); + + /* figure out how many points to read */ + if (residue > devpriv->dma_transfer_size) { + comedi_error(dev, "residue > transfer size!\n"); + async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; + num_bytes = 0; + } else + num_bytes = devpriv->dma_transfer_size - residue; + + if (cmd->stop_src == TRIG_COUNT && + num_bytes >= devpriv->adc_byte_count) { + num_bytes = devpriv->adc_byte_count; + async->events |= COMEDI_CB_EOA; + } + + buffer_index = devpriv->current_buffer; + devpriv->current_buffer = (devpriv->current_buffer + 1) % 2; + devpriv->adc_byte_count -= num_bytes; + + /* re-enable dma */ + if ((async->events & COMEDI_CB_EOA) == 0) { + set_dma_addr(devpriv->dma_chan, + devpriv->dma_buffer_addr[devpriv->current_buffer]); + set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); + enable_dma(devpriv->dma_chan); + } + release_dma_lock(dma_flags); + + spin_unlock_irqrestore(&dev->spinlock, spin_flags); + + cfc_write_array_to_buffer(s, + devpriv->dma_buffer[buffer_index], num_bytes); + + cfc_handle_events(dev, s); +} + +static void das16_timer_interrupt(unsigned long arg) +{ + struct comedi_device *dev = (struct comedi_device *)arg; + struct das16_private_struct *devpriv = dev->private; + + das16_interrupt(dev); + + if (devpriv->timer_running) + mod_timer(&devpriv->timer, jiffies + timer_period()); +} + static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { @@ -554,12 +664,20 @@ static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } -static void das16_reset(struct comedi_device *dev) +static void das16_ai_munge(struct comedi_device *dev, + struct comedi_subdevice *s, void *array, + unsigned int num_bytes, + unsigned int start_chan_index) { - outb(0, dev->iobase + DAS16_STATUS); - outb(0, dev->iobase + DAS16_CONTROL); - outb(0, dev->iobase + DAS16_PACER); - outb(0, dev->iobase + DAS16_CNTR_CONTROL); + unsigned int i, num_samples = num_bytes / sizeof(short); + short *data = array; + + for (i = 0; i < num_samples; i++) { + data[i] = le16_to_cpu(data[i]); + if (s->maxdata == 0x0fff) + data[i] >>= 4; + data[i] &= s->maxdata; + } } static int das16_ai_wait_for_conv(struct comedi_device *dev, @@ -619,36 +737,6 @@ static int das16_ai_insn_read(struct comedi_device *dev, return insn->n; } -static int das16_di_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - data[1] = inb(dev->iobase + DAS16_DIO) & 0xf; - - return insn->n; -} - -static int das16_do_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - unsigned int mask = data[0]; - unsigned int bits = data[1]; - - if (mask) { - s->state &= ~mask; - s->state |= (bits & mask); - - outb(s->state, dev->iobase + DAS16_DIO); - } - - data[1] = s->state; - - return insn->n; -} - static int das16_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -669,114 +757,34 @@ static int das16_ao_insn_write(struct comedi_device *dev, return insn->n; } -/* the pc104-das16jr (at least) has problems if the dma - transfer is interrupted in the middle of transferring - a 16 bit sample, so this function takes care to get - an even transfer count after disabling dma - channel. -*/ -static int disable_dma_on_even(struct comedi_device *dev) +static int das16_di_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - struct das16_private_struct *devpriv = dev->private; - int residue; - int i; - static const int disable_limit = 100; - static const int enable_timeout = 100; + data[1] = inb(dev->iobase + DAS16_DIO) & 0xf; - disable_dma(devpriv->dma_chan); - residue = get_dma_residue(devpriv->dma_chan); - for (i = 0; i < disable_limit && (residue % 2); ++i) { - int j; - enable_dma(devpriv->dma_chan); - for (j = 0; j < enable_timeout; ++j) { - int new_residue; - udelay(2); - new_residue = get_dma_residue(devpriv->dma_chan); - if (new_residue != residue) - break; - } - disable_dma(devpriv->dma_chan); - residue = get_dma_residue(devpriv->dma_chan); - } - if (i == disable_limit) { - comedi_error(dev, "failed to get an even dma transfer, " - "could be trouble."); - } - return residue; + return insn->n; } -static void das16_interrupt(struct comedi_device *dev) +static int das16_do_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { - struct das16_private_struct *devpriv = dev->private; - unsigned long dma_flags, spin_flags; - struct comedi_subdevice *s = dev->read_subdev; - struct comedi_async *async; - struct comedi_cmd *cmd; - int num_bytes, residue; - int buffer_index; - - if (!dev->attached) { - comedi_error(dev, "premature interrupt"); - return; - } - /* initialize async here to make sure it is not NULL */ - async = s->async; - cmd = &async->cmd; - - spin_lock_irqsave(&dev->spinlock, spin_flags); - if ((devpriv->ctrl_reg & DMA_ENABLE) == 0) { - spin_unlock_irqrestore(&dev->spinlock, spin_flags); - return; - } - - dma_flags = claim_dma_lock(); - clear_dma_ff(devpriv->dma_chan); - residue = disable_dma_on_even(dev); - - /* figure out how many points to read */ - if (residue > devpriv->dma_transfer_size) { - comedi_error(dev, "residue > transfer size!\n"); - async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - num_bytes = 0; - } else - num_bytes = devpriv->dma_transfer_size - residue; - - if (cmd->stop_src == TRIG_COUNT && - num_bytes >= devpriv->adc_byte_count) { - num_bytes = devpriv->adc_byte_count; - async->events |= COMEDI_CB_EOA; - } + unsigned int mask = data[0]; + unsigned int bits = data[1]; - buffer_index = devpriv->current_buffer; - devpriv->current_buffer = (devpriv->current_buffer + 1) % 2; - devpriv->adc_byte_count -= num_bytes; + if (mask) { + s->state &= ~mask; + s->state |= (bits & mask); - /* re-enable dma */ - if ((async->events & COMEDI_CB_EOA) == 0) { - set_dma_addr(devpriv->dma_chan, - devpriv->dma_buffer_addr[devpriv->current_buffer]); - set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); - enable_dma(devpriv->dma_chan); + outb(s->state, dev->iobase + DAS16_DIO); } - release_dma_lock(dma_flags); - - spin_unlock_irqrestore(&dev->spinlock, spin_flags); - cfc_write_array_to_buffer(s, - devpriv->dma_buffer[buffer_index], num_bytes); - - cfc_handle_events(dev, s); -} - -static void das16_timer_interrupt(unsigned long arg) -{ - struct comedi_device *dev = (struct comedi_device *)arg; - struct das16_private_struct *devpriv = dev->private; - - das16_interrupt(dev); + data[1] = s->state; - if (devpriv->timer_running) - mod_timer(&devpriv->timer, jiffies + timer_period()); + return insn->n; } static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it) @@ -814,30 +822,14 @@ static int das1600_mode_detect(struct comedi_device *dev) return 0; } -static void das16_ai_munge(struct comedi_device *dev, - struct comedi_subdevice *s, void *array, - unsigned int num_bytes, - unsigned int start_chan_index) +static void das16_reset(struct comedi_device *dev) { - unsigned int i, num_samples = num_bytes / sizeof(short); - short *data = array; - - for (i = 0; i < num_samples; i++) { - data[i] = le16_to_cpu(data[i]); - if (s->maxdata == 0x0fff) - data[i] >>= 4; - data[i] &= s->maxdata; - } + outb(0, dev->iobase + DAS16_STATUS); + outb(0, dev->iobase + DAS16_CONTROL); + outb(0, dev->iobase + DAS16_PACER); + outb(0, dev->iobase + DAS16_CNTR_CONTROL); } -/* - * - * Options list: - * 0 I/O base - * 1 IRQ - * 2 DMA - * 3 Clock speed (in MHz) - */ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct das16_board *board = comedi_board(dev); -- 1.8.3.2 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel