diff options
Diffstat (limited to 'Documentation/DMA-mapping.txt')
-rw-r--r-- | Documentation/DMA-mapping.txt | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt index b59a97dd1..daee34c11 100644 --- a/Documentation/DMA-mapping.txt +++ b/Documentation/DMA-mapping.txt @@ -59,7 +59,7 @@ In the failure case, you have two options: 1) Use some non-DMA mode for data transfer, if possible. 2) Ignore this device and do not initialize it. -It is recommended that your driver print a kernel KERN_WARN message +It is recommended that your driver print a kernel KERN_WARNING message when you do one of these two things. In this manner, if a user of your driver reports that performance is bad or that the device is not even detected, you can ask him for the kernel messages to find out @@ -71,12 +71,35 @@ address during PCI bus mastering you might do something like: if (! pci_dma_supported(pdev, 0x00ffffff)) goto ignore_this_device; +When DMA is possible for a given mask, the PCI layer must be informed of the +mask for later allocation operations on the device. This is achieved by +setting the dma_mask member of the pci_dev structure, like so: + +#define MY_HW_DMA_MASK 0x00ffffff + + if (! pci_dma_supported(pdev, MY_HW_DMA_MASK)) + goto ignore_this_device; + + pdev->dma_mask = MY_HW_DMA_MASK; + +A helper function is provided which performs this common code sequence: + + int pci_set_dma_mask(struct pci_dev *pdev, dma_addr_t device_mask) + +Unlike pci_dma_supported(), this returns -EIO when the PCI layer will not be +able to DMA with addresses restricted by that mask, and returns 0 when DMA +transfers are possible. If the call succeeds, the dma_mask will have been +updated so that your driver need not worry about it. + There is a case which we are aware of at this time, which is worth mentioning in this documentation. If your device supports multiple functions (for example a sound card provides playback and record functions) and the various different functions have _different_ DMA addressing limitations, you may wish to probe each mask and -only provide the functionality which the machine can handle. +only provide the functionality which the machine can handle. It +is important that the last call to pci_set_dma_mask() be for the +most specific mask. + Here is pseudo-code showing how this might be done: #define PLAYBACK_ADDRESS_BITS 0xffffffff @@ -86,14 +109,14 @@ Here is pseudo-code showing how this might be done: struct pci_dev *pdev; ... - if (pci_dma_supported(pdev, PLAYBACK_ADDRESS_BITS)) { + if (pci_set_dma_mask(pdev, PLAYBACK_ADDRESS_BITS)) { card->playback_enabled = 1; } else { card->playback_enabled = 0; printk(KERN_WARN "%s: Playback disabled due to DMA limitations.\n", card->name); } - if (pci_dma_supported(pdev, RECORD_ADDRESS_BITS)) { + if (pci_set_dma_mask(pdev, RECORD_ADDRESS_BITS)) { card->record_enabled = 1; } else { card->record_enabled = 0; |