diff options
| author | Christoph Hellwig <hch@lst.de> | 2019-02-15 03:01:53 -0500 |
|---|---|---|
| committer | Christoph Hellwig <hch@lst.de> | 2019-02-20 09:29:47 -0500 |
| commit | 9eb9e96e97b3381e94cba81d93f4a390c26ca6cb (patch) | |
| tree | 5b4dd2fc6d7e974b754a7b1e6e82c86910c9b0d5 | |
| parent | 24132a419c68f1d69eb8ecc91b3c80d730ecbb59 (diff) | |
Documentation/DMA-API-HOWTO: update dma_mask sections
We don't require drivers to guess a DMA mask that might actually
match the system capabilities any more, so fix up the documentation
to clear this up.
Signed-off-by: Christoph Hellwig <hch@lst.de>
| -rw-r--r-- | Documentation/DMA-API-HOWTO.txt | 121 |
1 files changed, 41 insertions, 80 deletions
diff --git a/Documentation/DMA-API-HOWTO.txt b/Documentation/DMA-API-HOWTO.txt index f0cc3f772265..1a721d0f35c8 100644 --- a/Documentation/DMA-API-HOWTO.txt +++ b/Documentation/DMA-API-HOWTO.txt | |||
| @@ -146,114 +146,75 @@ What about block I/O and networking buffers? The block I/O and | |||
| 146 | networking subsystems make sure that the buffers they use are valid | 146 | networking subsystems make sure that the buffers they use are valid |
| 147 | for you to DMA from/to. | 147 | for you to DMA from/to. |
| 148 | 148 | ||
| 149 | DMA addressing limitations | 149 | DMA addressing capabilities |
| 150 | ========================== | 150 | ========================== |
| 151 | 151 | ||
| 152 | Does your device have any DMA addressing limitations? For example, is | 152 | By default, the kernel assumes that your device can address 32-bits of DMA |
| 153 | your device only capable of driving the low order 24-bits of address? | 153 | addressing. For a 64-bit capable device, this needs to be increased, and for |
| 154 | If so, you need to inform the kernel of this fact. | 154 | a device with limitations, it needs to be decreased. |
| 155 | 155 | ||
| 156 | By default, the kernel assumes that your device can address the full | 156 | Special note about PCI: PCI-X specification requires PCI-X devices to support |
| 157 | 32-bits. For a 64-bit capable device, this needs to be increased. | 157 | 64-bit addressing (DAC) for all transactions. And at least one platform (SGI |
| 158 | And for a device with limitations, as discussed in the previous | 158 | SN2) requires 64-bit consistent allocations to operate correctly when the IO |
| 159 | paragraph, it needs to be decreased. | 159 | bus is in PCI-X mode. |
| 160 | 160 | ||
| 161 | Special note about PCI: PCI-X specification requires PCI-X devices to | 161 | For correct operation, you must set the DMA mask to inform the kernel about |
| 162 | support 64-bit addressing (DAC) for all transactions. And at least | 162 | your devices DMA addressing capabilities. |
| 163 | one platform (SGI SN2) requires 64-bit consistent allocations to | ||
| 164 | operate correctly when the IO bus is in PCI-X mode. | ||
| 165 | 163 | ||
| 166 | For correct operation, you must interrogate the kernel in your device | 164 | This is performed via a call to dma_set_mask_and_coherent():: |
| 167 | probe routine to see if the DMA controller on the machine can properly | ||
| 168 | support the DMA addressing limitation your device has. It is good | ||
| 169 | style to do this even if your device holds the default setting, | ||
| 170 | because this shows that you did think about these issues wrt. your | ||
| 171 | device. | ||
| 172 | |||
| 173 | The query is performed via a call to dma_set_mask_and_coherent():: | ||
| 174 | 165 | ||
| 175 | int dma_set_mask_and_coherent(struct device *dev, u64 mask); | 166 | int dma_set_mask_and_coherent(struct device *dev, u64 mask); |
| 176 | 167 | ||
| 177 | which will query the mask for both streaming and coherent APIs together. | 168 | which will set the mask for both streaming and coherent APIs together. If you |
| 178 | If you have some special requirements, then the following two separate | 169 | have some special requirements, then the following two separate calls can be |
| 179 | queries can be used instead: | 170 | used instead: |
| 180 | 171 | ||
| 181 | The query for streaming mappings is performed via a call to | 172 | The setup for streaming mappings is performed via a call to |
| 182 | dma_set_mask():: | 173 | dma_set_mask():: |
| 183 | 174 | ||
| 184 | int dma_set_mask(struct device *dev, u64 mask); | 175 | int dma_set_mask(struct device *dev, u64 mask); |
| 185 | 176 | ||
| 186 | The query for consistent allocations is performed via a call | 177 | The setup for consistent allocations is performed via a call |
| 187 | to dma_set_coherent_mask():: | 178 | to dma_set_coherent_mask():: |
| 188 | 179 | ||
| 189 | int dma_set_coherent_mask(struct device *dev, u64 mask); | 180 | int dma_set_coherent_mask(struct device *dev, u64 mask); |
| 190 | 181 | ||
| 191 | Here, dev is a pointer to the device struct of your device, and mask | 182 | Here, dev is a pointer to the device struct of your device, and mask is a bit |
| 192 | is a bit mask describing which bits of an address your device | 183 | mask describing which bits of an address your device supports. Often the |
| 193 | supports. It returns zero if your card can perform DMA properly on | 184 | device struct of your device is embedded in the bus-specific device struct of |
| 194 | the machine given the address mask you provided. In general, the | 185 | your device. For example, &pdev->dev is a pointer to the device struct of a |
| 195 | device struct of your device is embedded in the bus-specific device | 186 | PCI device (pdev is a pointer to the PCI device struct of your device). |
| 196 | struct of your device. For example, &pdev->dev is a pointer to the | ||
| 197 | device struct of a PCI device (pdev is a pointer to the PCI device | ||
| 198 | struct of your device). | ||
| 199 | 187 | ||
| 200 | If it returns non-zero, your device cannot perform DMA properly on | 188 | These calls usually return zero to indicated your device can perform DMA |
| 201 | this platform, and attempting to do so will result in undefined | 189 | properly on the machine given the address mask you provided, but they might |
| 202 | behavior. You must either use a different mask, or not use DMA. | 190 | return an error if the mask is too small to be supportable on the given |
| 191 | system. If it returns non-zero, your device cannot perform DMA properly on | ||
| 192 | this platform, and attempting to do so will result in undefined behavior. | ||
| 193 | You must not use DMA on this device unless the dma_set_mask family of | ||
| 194 | functions has returned success. | ||
| 203 | 195 | ||
| 204 | This means that in the failure case, you have three options: | 196 | This means that in the failure case, you have two options: |
| 205 | 197 | ||
| 206 | 1) Use another DMA mask, if possible (see below). | 198 | 1) Use some non-DMA mode for data transfer, if possible. |
| 207 | 2) Use some non-DMA mode for data transfer, if possible. | 199 | 2) Ignore this device and do not initialize it. |
| 208 | 3) Ignore this device and do not initialize it. | ||
| 209 | 200 | ||
| 210 | It is recommended that your driver print a kernel KERN_WARNING message | 201 | It is recommended that your driver print a kernel KERN_WARNING message when |
| 211 | when you end up performing either #2 or #3. In this manner, if a user | 202 | setting the DMA mask fails. In this manner, if a user of your driver reports |
| 212 | of your driver reports that performance is bad or that the device is not | 203 | that performance is bad or that the device is not even detected, you can ask |
| 213 | even detected, you can ask them for the kernel messages to find out | 204 | them for the kernel messages to find out exactly why. |
| 214 | exactly why. | ||
| 215 | 205 | ||
| 216 | The standard 32-bit addressing device would do something like this:: | 206 | The standard 64-bit addressing device would do something like this:: |
| 217 | 207 | ||
| 218 | if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) { | 208 | if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) { |
| 219 | dev_warn(dev, "mydev: No suitable DMA available\n"); | 209 | dev_warn(dev, "mydev: No suitable DMA available\n"); |
| 220 | goto ignore_this_device; | 210 | goto ignore_this_device; |
| 221 | } | 211 | } |
| 222 | 212 | ||
| 223 | Another common scenario is a 64-bit capable device. The approach here | 213 | If the device only supports 32-bit addressing for descriptors in the |
| 224 | is to try for 64-bit addressing, but back down to a 32-bit mask that | 214 | coherent allocations, but supports full 64-bits for streaming mappings |
| 225 | should not fail. The kernel may fail the 64-bit mask not because the | 215 | it would look like this: |
| 226 | platform is not capable of 64-bit addressing. Rather, it may fail in | ||
| 227 | this case simply because 32-bit addressing is done more efficiently | ||
| 228 | than 64-bit addressing. For example, Sparc64 PCI SAC addressing is | ||
| 229 | more efficient than DAC addressing. | ||
| 230 | |||
| 231 | Here is how you would handle a 64-bit capable device which can drive | ||
| 232 | all 64-bits when accessing streaming DMA:: | ||
| 233 | |||
| 234 | int using_dac; | ||
| 235 | 216 | ||
| 236 | if (!dma_set_mask(dev, DMA_BIT_MASK(64))) { | 217 | if (dma_set_mask(dev, DMA_BIT_MASK(64))) { |
| 237 | using_dac = 1; | ||
| 238 | } else if (!dma_set_mask(dev, DMA_BIT_MASK(32))) { | ||
| 239 | using_dac = 0; | ||
| 240 | } else { | ||
| 241 | dev_warn(dev, "mydev: No suitable DMA available\n"); | ||
| 242 | goto ignore_this_device; | ||
| 243 | } | ||
| 244 | |||
| 245 | If a card is capable of using 64-bit consistent allocations as well, | ||
| 246 | the case would look like this:: | ||
| 247 | |||
| 248 | int using_dac, consistent_using_dac; | ||
| 249 | |||
| 250 | if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) { | ||
| 251 | using_dac = 1; | ||
| 252 | consistent_using_dac = 1; | ||
| 253 | } else if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) { | ||
| 254 | using_dac = 0; | ||
| 255 | consistent_using_dac = 0; | ||
| 256 | } else { | ||
| 257 | dev_warn(dev, "mydev: No suitable DMA available\n"); | 218 | dev_warn(dev, "mydev: No suitable DMA available\n"); |
| 258 | goto ignore_this_device; | 219 | goto ignore_this_device; |
| 259 | } | 220 | } |
