Re: [PATCH 4/6] usb: make xhci platform driver use 64 bit or 32 bit DMA

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx> writes:
> [ text/plain ]
> On 04.03.2016 20:30, Timur Tabi wrote:
>> On Fri, Oct 9, 2015 at 5:30 AM, Mathias Nyman
>> <mathias.nyman@xxxxxxxxxxxxxxx> wrote:
>>> The xhci platform driver needs to work on systems that
>>> either only support 64-bit DMA or only support 32-bit DMA.
>>> Attempt to set a coherent dma mask for 64-bit DMA, and
>>> attempt again with 32-bit DMA if that fails.
>>
>> I know this patch is a few months old and has already been merged, but
>> I have a question about how it works, because we're thinking about
>> doing something similar for another driver.
>>
>>> +       /* Try to set 64-bit DMA first */
>>> +       if (WARN_ON(!pdev->dev.dma_mask))
>>> +               /* Platform did not initialize dma_mask */
>>> +               ret = dma_coerce_mask_and_coherent(&pdev->dev,
>>> +                                                  DMA_BIT_MASK(64));
>>>          else
>>> -               dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
>>> +               ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
>>> +
>>> +       /* If seting 64-bit DMA mask fails, fall back to 32-bit DMA mask */
>>> +       if (ret) {
>>> +               ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
>>> +               if (ret)
>>> +                       return ret;
>>> +       }
>>
>> I don't understand why this is necessary.  I was under the impression
>> that when a driver calls dma_set_mask_xxx, all it's doing is telling
>> the kernel what DMA ranges the device is capable of. If a device is
>> physically capable of DMA'ing to all of RAM (let's assume everything
>> is coherent), then it should set the mask to 64 and leave it at that.
>> If the platform has some other DMA address range limitation, the
>> driver shouldn't have to worry about that.  It should still set the
>> mask to 64, and something else will figure out that the *real* mask is
>> less than that.  Then when the driver calls dma_alloc_coherent(), it
>> will always get a DMA buffer from low memory, but that's okay.
>>
>> But apparently, that's not how it really works, which is why this
>> patch exists.  And that's why I'm confused.
>>
>> I have a few other related questions.  Let's say that we have a device
>> that is normally capable of 64-bit DMA.  But on one particular
>> platform, only 32 bits of the address bus is wired up, so effectively
>> the device is only capable of 32-bit DMA.  This information is hidden
>> from the device, so the driver cannot query the device itself to
>> discover this.  What is the proper way to handle this?  We probably
>> don't want to add platform-specific code to the driver (like an MIDR
>> check on ARM systems).
>>
>> Thanks in advance for any answers.  DMA-API-HOWTO.txt says this:
>>
>>          "Rather, it may fail in this case simply because 32-bit
>> addressing is done more efficiently than 64-bit addressing."
>>
>> But that doesn't apply in our situation.  And even then, this seems
>> like an odd reason to fail.  Wouldn't it make more sense for the
>> dma_set_mask_xxx() API to just automatically adjust the mask to a
>> smaller value, and return success?
>> --
>
> Evolution of the patch can be found in this thread:
>
> http://www.spinics.net/lists/linux-usb/msg128495.html
>
> I think version 8 was the final one.

wonder if we should provide a generic static inline for that. Seems like
that will replicate on many drivers. How about:

static inline int dma_try_mask_and_coherent(struct device *dev)
{
        int ret;

        ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
        if (ret) {
        	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
                if (ret) {
                	dev_err(dev, "failed to set dma mask\n");
                        return ret;
                }
        }

	return 0;
}

-- 
balbi

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux