The comedi_device spinlock is used to protect the indirect addressing selected by the DAS1800_SELECT register. It also prevents races between the interrupt handler and the analog input (*poll). Update the comments to make this clear. Signed-off-by: H Hartley Sweeten <hsweeten@xxxxxxxxxxxxxxxxxxx> Cc: Ian Abbott <abbotti@xxxxxxxxx> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/staging/comedi/drivers/das1800.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 8dae3845..a2108d3 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -517,8 +517,9 @@ static void das1800_ai_handler(struct comedi_device *dev) struct comedi_cmd *cmd = &async->cmd; unsigned int status = inb(dev->iobase + DAS1800_STATUS); - /* select adc for base address + 0 */ + /* select adc register (spinlock is already held) */ outb(ADC, dev->iobase + DAS1800_SELECT); + /* dma buffer full */ if (devpriv->irq_dma_bits & DMA_ENABLED) { /* look for data from dma transfer even if dma terminal count hasn't happened yet */ @@ -562,9 +563,14 @@ static int das1800_ai_poll(struct comedi_device *dev, { unsigned long flags; - /* prevent race with interrupt handler */ + /* + * Protects the indirect addressing selected by DAS1800_SELECT + * in das1800_ai_handler() also prevents race with das1800_interrupt(). + */ spin_lock_irqsave(&dev->spinlock, flags); + das1800_ai_handler(dev); + spin_unlock_irqrestore(&dev->spinlock, flags); return comedi_buf_n_bytes_ready(s); @@ -580,9 +586,12 @@ static irqreturn_t das1800_interrupt(int irq, void *d) return IRQ_HANDLED; } - /* Prevent race with das1800_ai_poll() on multi processor systems. - * Also protects indirect addressing in das1800_ai_handler */ + /* + * Protects the indirect addressing selected by DAS1800_SELECT + * in das1800_ai_handler() also prevents race with das1800_ai_poll(). + */ spin_lock(&dev->spinlock); + status = inb(dev->iobase + DAS1800_STATUS); /* if interrupt was not caused by das-1800 */ @@ -1298,6 +1307,7 @@ static int das1800_attach(struct comedi_device *dev, /* initialize all channels to 0V */ for (i = 0; i < s->n_chan; i++) { + /* spinlock is not necessary during the attach */ outb(DAC(i), dev->iobase + DAS1800_SELECT); outw(0, dev->iobase + DAS1800_DAC); } -- 2.6.3 _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel