Re: [PATCH] PCI: dwc: Modify the check about MSI DMA mask 32-bit

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

 



> On Mon, Apr 11, 2022 at 03:59:05PM +0900, Wangseok Lee wrote:
>> driver_init() ->
>> -> platform_dma_configure() / platform.c
>>   |-> of_dma_configure() 
>>      |-> of_dma_configure_id()
>>         :Here, set dma of 33+ address.
>>          dma_set_mask(0xf`ffff`ffff), bus_dma_limit(0xf`ffff`ffff)
> 
> Where do we set a large than 32-bit dma mask here?  I can't find the
> code, and if there is we need to fix it.  In Linux devices to come
> up with 32-bit DMA masks for historical reasons (they really should
> with a zero dma mask, but it is probably to lte to fix it).
> 
>> -> artpec8_pcie_probe() / artpec-8 pcie driver code
>>   |-> dw_pcie_host_init() / pcie-designware-host.c
>>      |-> dma_set_mask(32)
>>          : Here, set the dma mask of 32 addresses.
>>      |-> dma_map_single_attrs() 
>>         |-> dma_map_page_attrs()
>>            |-> dma_direct_map_page()
>>               : Error return occurs here.
>>                 dma address has 33+ address and 
>>                 dma bus limit is 33+. 
>>                 However, this is because the mask value 
>>                 has 32 addresses.
> 
> If the dma_mask is set to 32-bits, we should never generate a
> large dma address, but bounce if it would othewise generate a
> larger address.
> 
> That being said I think this code would be much better off using
> dma_alloc_coherent anyway.
> 
>> Therefore, the dma_set_mask(32)(in dw_pcie_host_init())
>> was modified to be performed only when
>> the dev-dma_mask is not set larger than 32 bits.
> 
> So what sets dev->dma_mask to a larger than 32-bit value here?
> We need to find and fix that.

At the code of of_dma_configure_id() of driver/of/device.c..
In the 64bit system, if the dma start addr is used as 0x1'0000'0000
and the size is used as 0xf'0000'0000, "u64 end" is 0xf'ffff'ffff. 
And the dma_mask value is changed from 0xffff'ffff'ffff'ffff to
0xf'ffff'ffffff due to the code below.

181 line, driver/of/device.c
-------------------------------------------------
end = dma_start + size - 1;
mask = DMA_BIT_MASK(ilog2(end) + 1);
dev->coherent_dma_mask &= mask;
*dev->dma_mask &= mask;
-------------------------------------------------
Please let me know if I'm mistaken.

Thank you.




[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux