[Prism54-devel] Broken DMA mask check

Jens Maurer Jens.Maurer@gmx.net
Thu, 01 Jan 2004 19:07:24 +0100


Hello!

In prism54_probe(), we set the DMA mask of the device.
The code is completely broken (see below): If the
original all-ones DMA mask does not work, we try succeedingly
smaller mask values until one fits.

However, the pci_alloc_consistent() and pci_map_single()
calls do not honour the DMA mask of the device
(in particular, pci_map_single just takes a memory region
and makes it "available" to the device).

So, if the dma_mask is not 32bit all-ones, we may offer
memory to the device that it cannot address.  Bad.

Just use a fixed dma_mask with 32bit all-ones, as all
the other network device drivers do, and bail out if
the device doesn't like it.  (Is this driver ported
from Windows?  Probably you can do such things there...)

Jens Maurer


         int dma_mask = 0xffffffff;
[...]
         /* determine what the supported DMA memory region is */
         while (pci_set_dma_mask(pdev, dma_mask) != 0) {
                 /* range not supported, shift the mask and check again */
                 if (dma_mask >>= 1, dma_mask == 0) {
                         /* mask is zero, DMA memory not supported by PCI */
                         printk(KERN_ERR "%s: DMA Memory not supported\n",
                                DRV_NAME);
                         goto do_pci_disable_device;
                 }
         }