From eb96c7fc24fb89d7e3382260e1b391c05895cfa6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Mon, 19 Oct 2015 13:13:05 -0700 Subject: [PATCH] staging: comedi: adl_pci9118: tidy up pci9118_ai_setup_dma() For aesthetics, init the dmalen[01] local variables when they are declared. Use a local variable, 'scan_bytes', for the (devpriv->ai_n_realscanlen << 1) calculation. For aesthetics and clarification, use comedi_bytes_per_sample() instead of the '<< 1' shift to calculate the value. The local variable 'i' is badly named. Remove it and use a local variable 'tmp' where it is used. When checking the DMA buffer lengths for non-neverending commands the scan length calculation, (devpriv->ai_n_realscanlen << 1) * cmd->stop_arg, could overflow. Use and unsigned long long local variable to hold the calculation and avoid the overflow. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/adl_pci9118.c | 67 +++++++++----------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c index e2302cb5ce2c..0dff1dbb53fb 100644 --- a/drivers/staging/comedi/drivers/adl_pci9118.c +++ b/drivers/staging/comedi/drivers/adl_pci9118.c @@ -801,10 +801,11 @@ static int pci9118_ai_setup_dma(struct comedi_device *dev, struct comedi_cmd *cmd = &s->async->cmd; struct pci9118_dmabuf *dmabuf0 = &devpriv->dmabuf[0]; struct pci9118_dmabuf *dmabuf1 = &devpriv->dmabuf[1]; - unsigned int dmalen0, dmalen1, i; + unsigned int dmalen0 = dmabuf0->size; + unsigned int dmalen1 = dmabuf1->size; + unsigned int scan_bytes = devpriv->ai_n_realscanlen * + comedi_bytes_per_sample(s); - dmalen0 = dmabuf0->size; - dmalen1 = dmabuf1->size; /* isn't output buff smaller that our DMA buff? */ if (dmalen0 > s->async->prealloc_bufsz) { /* align to 32bit down */ @@ -817,15 +818,15 @@ static int pci9118_ai_setup_dma(struct comedi_device *dev, /* we want wake up every scan? */ if (devpriv->ai_flags & CMDF_WAKE_EOS) { - if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) { + if (dmalen0 < scan_bytes) { /* uff, too short DMA buffer, disable EOS support! */ devpriv->ai_flags &= (~CMDF_WAKE_EOS); dev_info(dev->class_dev, "WAR: DMA0 buf too short, can't support CMDF_WAKE_EOS (%d<%d)\n", - dmalen0, devpriv->ai_n_realscanlen << 1); + dmalen0, scan_bytes); } else { /* short first DMA buffer to one scan */ - dmalen0 = devpriv->ai_n_realscanlen << 1; + dmalen0 = scan_bytes; if (dmalen0 < 4) { dev_info(dev->class_dev, "ERR: DMA0 buf len bug? (%d<4)\n", @@ -835,15 +836,15 @@ static int pci9118_ai_setup_dma(struct comedi_device *dev, } } if (devpriv->ai_flags & CMDF_WAKE_EOS) { - if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) { + if (dmalen1 < scan_bytes) { /* uff, too short DMA buffer, disable EOS support! */ devpriv->ai_flags &= (~CMDF_WAKE_EOS); dev_info(dev->class_dev, "WAR: DMA1 buf too short, can't support CMDF_WAKE_EOS (%d<%d)\n", - dmalen1, devpriv->ai_n_realscanlen << 1); + dmalen1, scan_bytes); } else { /* short second DMA buffer to one scan */ - dmalen1 = devpriv->ai_n_realscanlen << 1; + dmalen1 = scan_bytes; if (dmalen1 < 4) { dev_info(dev->class_dev, "ERR: DMA1 buf len bug? (%d<4)\n", @@ -855,45 +856,39 @@ static int pci9118_ai_setup_dma(struct comedi_device *dev, /* transfer without CMDF_WAKE_EOS */ if (!(devpriv->ai_flags & CMDF_WAKE_EOS)) { + unsigned int tmp; + /* if it's possible then align DMA buffers to length of scan */ - i = dmalen0; - dmalen0 = - (dmalen0 / (devpriv->ai_n_realscanlen << 1)) * - (devpriv->ai_n_realscanlen << 1); + tmp = dmalen0; + dmalen0 = (dmalen0 / scan_bytes) * scan_bytes; dmalen0 &= ~3L; if (!dmalen0) - dmalen0 = i; /* uff. very long scan? */ - i = dmalen1; - dmalen1 = - (dmalen1 / (devpriv->ai_n_realscanlen << 1)) * - (devpriv->ai_n_realscanlen << 1); + dmalen0 = tmp; /* uff. very long scan? */ + tmp = dmalen1; + dmalen1 = (dmalen1 / scan_bytes) * scan_bytes; dmalen1 &= ~3L; if (!dmalen1) - dmalen1 = i; /* uff. very long scan? */ + dmalen1 = tmp; /* uff. very long scan? */ /* * if measure isn't neverending then test, if it fits whole * into one or two DMA buffers */ if (!devpriv->ai_neverending) { + unsigned long long scanlen; + + scanlen = (unsigned long long)scan_bytes * + cmd->stop_arg; + /* fits whole measure into one DMA buffer? */ - if (dmalen0 > - ((devpriv->ai_n_realscanlen << 1) * - cmd->stop_arg)) { - dmalen0 = - (devpriv->ai_n_realscanlen << 1) * - cmd->stop_arg; + if (dmalen0 > scanlen) { + dmalen0 = scanlen; dmalen0 &= ~3L; - } else { /* - * fits whole measure into - * two DMA buffer? - */ - if (dmalen1 > - ((devpriv->ai_n_realscanlen << 1) * - cmd->stop_arg - dmalen0)) - dmalen1 = - (devpriv->ai_n_realscanlen << 1) * - cmd->stop_arg - dmalen0; - dmalen1 &= ~3L; + } else { + /* fits whole measure into two DMA buffer? */ + if (dmalen1 > (scanlen - dmalen0)) { + dmalen1 = scanlen - dmalen0; + dmalen1 &= ~3L; + } } } } -- 2.30.2