Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

H Hartley Sweeten and committed by
Greg Kroah-Hartman
eb96c7fc 45037a95

+31 -36
+31 -36
drivers/staging/comedi/drivers/adl_pci9118.c
··· 801 801 struct comedi_cmd *cmd = &s->async->cmd; 802 802 struct pci9118_dmabuf *dmabuf0 = &devpriv->dmabuf[0]; 803 803 struct pci9118_dmabuf *dmabuf1 = &devpriv->dmabuf[1]; 804 - unsigned int dmalen0, dmalen1, i; 804 + unsigned int dmalen0 = dmabuf0->size; 805 + unsigned int dmalen1 = dmabuf1->size; 806 + unsigned int scan_bytes = devpriv->ai_n_realscanlen * 807 + comedi_bytes_per_sample(s); 805 808 806 - dmalen0 = dmabuf0->size; 807 - dmalen1 = dmabuf1->size; 808 809 /* isn't output buff smaller that our DMA buff? */ 809 810 if (dmalen0 > s->async->prealloc_bufsz) { 810 811 /* align to 32bit down */ ··· 818 817 819 818 /* we want wake up every scan? */ 820 819 if (devpriv->ai_flags & CMDF_WAKE_EOS) { 821 - if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) { 820 + if (dmalen0 < scan_bytes) { 822 821 /* uff, too short DMA buffer, disable EOS support! */ 823 822 devpriv->ai_flags &= (~CMDF_WAKE_EOS); 824 823 dev_info(dev->class_dev, 825 824 "WAR: DMA0 buf too short, can't support CMDF_WAKE_EOS (%d<%d)\n", 826 - dmalen0, devpriv->ai_n_realscanlen << 1); 825 + dmalen0, scan_bytes); 827 826 } else { 828 827 /* short first DMA buffer to one scan */ 829 - dmalen0 = devpriv->ai_n_realscanlen << 1; 828 + dmalen0 = scan_bytes; 830 829 if (dmalen0 < 4) { 831 830 dev_info(dev->class_dev, 832 831 "ERR: DMA0 buf len bug? (%d<4)\n", ··· 836 835 } 837 836 } 838 837 if (devpriv->ai_flags & CMDF_WAKE_EOS) { 839 - if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) { 838 + if (dmalen1 < scan_bytes) { 840 839 /* uff, too short DMA buffer, disable EOS support! */ 841 840 devpriv->ai_flags &= (~CMDF_WAKE_EOS); 842 841 dev_info(dev->class_dev, 843 842 "WAR: DMA1 buf too short, can't support CMDF_WAKE_EOS (%d<%d)\n", 844 - dmalen1, devpriv->ai_n_realscanlen << 1); 843 + dmalen1, scan_bytes); 845 844 } else { 846 845 /* short second DMA buffer to one scan */ 847 - dmalen1 = devpriv->ai_n_realscanlen << 1; 846 + dmalen1 = scan_bytes; 848 847 if (dmalen1 < 4) { 849 848 dev_info(dev->class_dev, 850 849 "ERR: DMA1 buf len bug? (%d<4)\n", ··· 856 855 857 856 /* transfer without CMDF_WAKE_EOS */ 858 857 if (!(devpriv->ai_flags & CMDF_WAKE_EOS)) { 858 + unsigned int tmp; 859 + 859 860 /* if it's possible then align DMA buffers to length of scan */ 860 - i = dmalen0; 861 - dmalen0 = 862 - (dmalen0 / (devpriv->ai_n_realscanlen << 1)) * 863 - (devpriv->ai_n_realscanlen << 1); 861 + tmp = dmalen0; 862 + dmalen0 = (dmalen0 / scan_bytes) * scan_bytes; 864 863 dmalen0 &= ~3L; 865 864 if (!dmalen0) 866 - dmalen0 = i; /* uff. very long scan? */ 867 - i = dmalen1; 868 - dmalen1 = 869 - (dmalen1 / (devpriv->ai_n_realscanlen << 1)) * 870 - (devpriv->ai_n_realscanlen << 1); 865 + dmalen0 = tmp; /* uff. very long scan? */ 866 + tmp = dmalen1; 867 + dmalen1 = (dmalen1 / scan_bytes) * scan_bytes; 871 868 dmalen1 &= ~3L; 872 869 if (!dmalen1) 873 - dmalen1 = i; /* uff. very long scan? */ 870 + dmalen1 = tmp; /* uff. very long scan? */ 874 871 /* 875 872 * if measure isn't neverending then test, if it fits whole 876 873 * into one or two DMA buffers 877 874 */ 878 875 if (!devpriv->ai_neverending) { 876 + unsigned long long scanlen; 877 + 878 + scanlen = (unsigned long long)scan_bytes * 879 + cmd->stop_arg; 880 + 879 881 /* fits whole measure into one DMA buffer? */ 880 - if (dmalen0 > 881 - ((devpriv->ai_n_realscanlen << 1) * 882 - cmd->stop_arg)) { 883 - dmalen0 = 884 - (devpriv->ai_n_realscanlen << 1) * 885 - cmd->stop_arg; 882 + if (dmalen0 > scanlen) { 883 + dmalen0 = scanlen; 886 884 dmalen0 &= ~3L; 887 - } else { /* 888 - * fits whole measure into 889 - * two DMA buffer? 890 - */ 891 - if (dmalen1 > 892 - ((devpriv->ai_n_realscanlen << 1) * 893 - cmd->stop_arg - dmalen0)) 894 - dmalen1 = 895 - (devpriv->ai_n_realscanlen << 1) * 896 - cmd->stop_arg - dmalen0; 897 - dmalen1 &= ~3L; 885 + } else { 886 + /* fits whole measure into two DMA buffer? */ 887 + if (dmalen1 > (scanlen - dmalen0)) { 888 + dmalen1 = scanlen - dmalen0; 889 + dmalen1 &= ~3L; 890 + } 898 891 } 899 892 } 900 893 }