diff mbox

[v7,1/2] usb: make xhci platform driver use 64 bit or 32 bit DMA

Message ID 69e6f5bf693d02fba001d02047453bed0519499d.1440098398.git.dhdang@apm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Duc Dang Aug. 20, 2015, 7:38 p.m. UTC
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.

[dhdang: regenerate the patch over 4.2-rc5 and address new comments]
Signed-off-by: Mark Langsdorf <mlangsdo@redhat.com>
Tested-by: Mark Salter <msalter@redhat.com>
Signed-off-by: Duc Dang <dhdang@apm.com>

---
Changes from v6:
	-Add WARN_ON if dma_mask is NULL
	-Use dma_coerce_mask_and_coherent to assign
	dma_mask and coherent_dma_mask

Changes from v5:
        -Change comment
        -Assign dma_mask to coherent_dma_mask if dma_mask is NULL
        to make sure dma_set_mask_and_coherent does not fail prematurely.

Changes from v4:
        -None

Changes from v3:
        -Re-generate the patch over 4.2-rc5
        -No code change.

Changes from v2:
        -None

Changes from v1:
        -Consolidated to use dma_set_mask_and_coherent
        -Got rid of the check against sizeof(dma_addr_t)

 drivers/usb/host/xhci-plat.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

Comments

Duc Dang Aug. 31, 2015, 6:58 p.m. UTC | #1
On Thu, Aug 20, 2015 at 12:38 PM, Duc Dang <dhdang@apm.com> 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.
>
> [dhdang: regenerate the patch over 4.2-rc5 and address new comments]
> Signed-off-by: Mark Langsdorf <mlangsdo@redhat.com>
> Tested-by: Mark Salter <msalter@redhat.com>
> Signed-off-by: Duc Dang <dhdang@apm.com>
>
> ---
> Changes from v6:
>         -Add WARN_ON if dma_mask is NULL
>         -Use dma_coerce_mask_and_coherent to assign
>         dma_mask and coherent_dma_mask
>
> Changes from v5:
>         -Change comment
>         -Assign dma_mask to coherent_dma_mask if dma_mask is NULL
>         to make sure dma_set_mask_and_coherent does not fail prematurely.
>
> Changes from v4:
>         -None
>
> Changes from v3:
>         -Re-generate the patch over 4.2-rc5
>         -No code change.
>
> Changes from v2:
>         -None
>
> Changes from v1:
>         -Consolidated to use dma_set_mask_and_coherent
>         -Got rid of the check against sizeof(dma_addr_t)
>
>  drivers/usb/host/xhci-plat.c | 21 +++++++++++++--------
>  1 file changed, 13 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index 890ad9d..e4c7f9d 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -93,14 +93,19 @@ static int xhci_plat_probe(struct platform_device *pdev)
>         if (irq < 0)
>                 return -ENODEV;
>
> -       /* Initialize dma_mask and coherent_dma_mask to 32-bits */
> -       ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
> -       if (ret)
> -               return ret;
> -       if (!pdev->dev.dma_mask)
> -               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
> -       else
> -               dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
> +       /* Throw a waring if broken platform code didn't initialize dma_mask */
> +       WARN_ON(!pdev->dev.dma_mask);
> +       /*
> +        * Try setting dma_mask and coherent_dma_mask to 64 bits,
> +        * then try 32 bits
> +        */
> +       ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
> +       if (ret) {
> +               ret = dma_coerce_mask_and_coherent(&pdev->dev,
> +                                                  DMA_BIT_MASK(32));
> +               if (ret)
> +                       return ret;
> +       }
>
>         hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
>         if (!hcd)
> --
> 1.9.1
>

Hi Greg, Arnd, Russell,

Do you have any more comment about this patch set?
Mathias Nyman Sept. 1, 2015, 11:54 a.m. UTC | #2
On 31.08.2015 21:58, Duc Dang wrote:
> On Thu, Aug 20, 2015 at 12:38 PM, Duc Dang <dhdang@apm.com> 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.
>>
>> [dhdang: regenerate the patch over 4.2-rc5 and address new comments]
>> Signed-off-by: Mark Langsdorf <mlangsdo@redhat.com>
>> Tested-by: Mark Salter <msalter@redhat.com>
>> Signed-off-by: Duc Dang <dhdang@apm.com>
>>
>> ---
>> Changes from v6:
>>          -Add WARN_ON if dma_mask is NULL
>>          -Use dma_coerce_mask_and_coherent to assign
>>          dma_mask and coherent_dma_mask
>>
>> Changes from v5:
>>          -Change comment
>>          -Assign dma_mask to coherent_dma_mask if dma_mask is NULL
>>          to make sure dma_set_mask_and_coherent does not fail prematurely.
>>
>> Changes from v4:
>>          -None
>>
>> Changes from v3:
>>          -Re-generate the patch over 4.2-rc5
>>          -No code change.
>>
>> Changes from v2:
>>          -None
>>
>> Changes from v1:
>>          -Consolidated to use dma_set_mask_and_coherent
>>          -Got rid of the check against sizeof(dma_addr_t)
>>
>>   drivers/usb/host/xhci-plat.c | 21 +++++++++++++--------
>>   1 file changed, 13 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
>> index 890ad9d..e4c7f9d 100644
>> --- a/drivers/usb/host/xhci-plat.c
>> +++ b/drivers/usb/host/xhci-plat.c
>> @@ -93,14 +93,19 @@ static int xhci_plat_probe(struct platform_device *pdev)
>>          if (irq < 0)
>>                  return -ENODEV;
>>
>> -       /* Initialize dma_mask and coherent_dma_mask to 32-bits */
>> -       ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
>> -       if (ret)
>> -               return ret;
>> -       if (!pdev->dev.dma_mask)
>> -               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
>> -       else
>> -               dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
>> +       /* Throw a waring if broken platform code didn't initialize dma_mask */
>> +       WARN_ON(!pdev->dev.dma_mask);
>> +       /*
>> +        * Try setting dma_mask and coherent_dma_mask to 64 bits,
>> +        * then try 32 bits
>> +        */
>> +       ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
>> +       if (ret) {
>> +               ret = dma_coerce_mask_and_coherent(&pdev->dev,
>> +                                                  DMA_BIT_MASK(32));
>> +               if (ret)
>> +                       return ret;
>> +       }
>>
>>          hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
>>          if (!hcd)
>> --
>> 1.9.1
>>
>
> Hi Greg, Arnd, Russell,
>
> Do you have any more comment about this patch set?
>

I'm not sure I fully understand why we need to try the 64 bit DMA mask in platform probe.

As I understood it we just want to have some DMA mask set before calling usb_create_hcd()
to make sure USB core gets the "uses_dma" flag set and dma_set_mask() won't fail because of
missing dev->dma_mask.

The correct DMA mask is set later in xhci_gen_setup()

We also need to make sure the controller supports 64bit addressing capability before setting a 64 bit DMA mask.
(bit 0 in HCCPARAMS)

So for platform devices it goes look go this:

xhci_plat_probe()
   usb_create_hcd()
     usb_create_shared_hcd()
       hcd->self.uses_dma = (dev->dma_mask != NULL);
   usb_add_hcd()
     hcd->driver->reset()  (.reset = xhci_plat_setup)
       xhci_plat_setup()
         xhci_gen_setup()
           if (HCC_64BIT_ADDR(xhci->hcc_params) && !dma_set_mask(dev, DMA_BIT_MASK(64))) {
             xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n");
             dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
           }

or do we end up with dev->dma_mask = NULL on 64-bit DMA only after trying to set it to 32 in xhci_plat_probe(),
and thus also failing the dma_set_mask() in xhci_gen_setup()?

-Mathias
Russell King - ARM Linux Sept. 1, 2015, 12:07 p.m. UTC | #3
On Tue, Sep 01, 2015 at 02:54:17PM +0300, Mathias Nyman wrote:
> On 31.08.2015 21:58, Duc Dang wrote:
> >On Thu, Aug 20, 2015 at 12:38 PM, Duc Dang <dhdang@apm.com> 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.
> >>
> >>[dhdang: regenerate the patch over 4.2-rc5 and address new comments]
> >>Signed-off-by: Mark Langsdorf <mlangsdo@redhat.com>
> >>Tested-by: Mark Salter <msalter@redhat.com>
> >>Signed-off-by: Duc Dang <dhdang@apm.com>
> >>
> >>---
> >>Changes from v6:
> >>         -Add WARN_ON if dma_mask is NULL
> >>         -Use dma_coerce_mask_and_coherent to assign
> >>         dma_mask and coherent_dma_mask
> >>
> >>Changes from v5:
> >>         -Change comment
> >>         -Assign dma_mask to coherent_dma_mask if dma_mask is NULL
> >>         to make sure dma_set_mask_and_coherent does not fail prematurely.
> >>
> >>Changes from v4:
> >>         -None
> >>
> >>Changes from v3:
> >>         -Re-generate the patch over 4.2-rc5
> >>         -No code change.
> >>
> >>Changes from v2:
> >>         -None
> >>
> >>Changes from v1:
> >>         -Consolidated to use dma_set_mask_and_coherent
> >>         -Got rid of the check against sizeof(dma_addr_t)
> >>
> >>  drivers/usb/host/xhci-plat.c | 21 +++++++++++++--------
> >>  1 file changed, 13 insertions(+), 8 deletions(-)
> >>
> >>diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> >>index 890ad9d..e4c7f9d 100644
> >>--- a/drivers/usb/host/xhci-plat.c
> >>+++ b/drivers/usb/host/xhci-plat.c
> >>@@ -93,14 +93,19 @@ static int xhci_plat_probe(struct platform_device *pdev)
> >>         if (irq < 0)
> >>                 return -ENODEV;
> >>
> >>-       /* Initialize dma_mask and coherent_dma_mask to 32-bits */
> >>-       ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
> >>-       if (ret)
> >>-               return ret;
> >>-       if (!pdev->dev.dma_mask)
> >>-               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
> >>-       else
> >>-               dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
> >>+       /* Throw a waring if broken platform code didn't initialize dma_mask */
> >>+       WARN_ON(!pdev->dev.dma_mask);
> >>+       /*
> >>+        * Try setting dma_mask and coherent_dma_mask to 64 bits,
> >>+        * then try 32 bits
> >>+        */
> >>+       ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
> >>+       if (ret) {
> >>+               ret = dma_coerce_mask_and_coherent(&pdev->dev,
> >>+                                                  DMA_BIT_MASK(32));
> >>+               if (ret)
> >>+                       return ret;
> >>+       }

This isn't very good.  If dev.dma_mask is already set,
dma_coerce_mask_and_coherent() will always overwrite it.  There's also
no need to call it twice.  This, imho, is much better:

	/* Try to set a 64-bit DMA mask first */
	if (WARN_ON(!pdev->dev.dma_mask)) {
		/* Eek, platform didn't initialise the streaming DMA mask */
		ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
	} else {
		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
	}

	/* If that failed, fall back to a 32-bit DMA mask */
	if (ret) {
		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
		if (ret)
			return ret;
	}

since it preserves the dev.dma_mask pointer if it was properly setup

Really, drivers shouldn't be messing around with that pointer - especially
if it's already been correctly setup.  A platform may require separate
streaming and coherent masks, and we should respect that.

(The whole dma_mask being a pointer thing is a left-over from the PCI
layer which has never been cleaned up through fear of breaking something.)
Duc Dang Sept. 10, 2015, 8:53 p.m. UTC | #4
On Tue, Sep 1, 2015 at 4:54 AM, Mathias Nyman
<mathias.nyman@linux.intel.com> wrote:
> On 31.08.2015 21:58, Duc Dang wrote:
>>
>> On Thu, Aug 20, 2015 at 12:38 PM, Duc Dang <dhdang@apm.com> 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.
>>>
>>> [dhdang: regenerate the patch over 4.2-rc5 and address new comments]
>>> Signed-off-by: Mark Langsdorf <mlangsdo@redhat.com>
>>> Tested-by: Mark Salter <msalter@redhat.com>
>>> Signed-off-by: Duc Dang <dhdang@apm.com>
>>>
>>> ---
>>> Changes from v6:
>>>          -Add WARN_ON if dma_mask is NULL
>>>          -Use dma_coerce_mask_and_coherent to assign
>>>          dma_mask and coherent_dma_mask
>>>
>>> Changes from v5:
>>>          -Change comment
>>>          -Assign dma_mask to coherent_dma_mask if dma_mask is NULL
>>>          to make sure dma_set_mask_and_coherent does not fail
>>> prematurely.
>>>
>>> Changes from v4:
>>>          -None
>>>
>>> Changes from v3:
>>>          -Re-generate the patch over 4.2-rc5
>>>          -No code change.
>>>
>>> Changes from v2:
>>>          -None
>>>
>>> Changes from v1:
>>>          -Consolidated to use dma_set_mask_and_coherent
>>>          -Got rid of the check against sizeof(dma_addr_t)
>>>
>>>   drivers/usb/host/xhci-plat.c | 21 +++++++++++++--------
>>>   1 file changed, 13 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
>>> index 890ad9d..e4c7f9d 100644
>>> --- a/drivers/usb/host/xhci-plat.c
>>> +++ b/drivers/usb/host/xhci-plat.c
>>> @@ -93,14 +93,19 @@ static int xhci_plat_probe(struct platform_device
>>> *pdev)
>>>          if (irq < 0)
>>>                  return -ENODEV;
>>>
>>> -       /* Initialize dma_mask and coherent_dma_mask to 32-bits */
>>> -       ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
>>> -       if (ret)
>>> -               return ret;
>>> -       if (!pdev->dev.dma_mask)
>>> -               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
>>> -       else
>>> -               dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
>>> +       /* Throw a waring if broken platform code didn't initialize
>>> dma_mask */
>>> +       WARN_ON(!pdev->dev.dma_mask);
>>> +       /*
>>> +        * Try setting dma_mask and coherent_dma_mask to 64 bits,
>>> +        * then try 32 bits
>>> +        */
>>> +       ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
>>> +       if (ret) {
>>> +               ret = dma_coerce_mask_and_coherent(&pdev->dev,
>>> +                                                  DMA_BIT_MASK(32));
>>> +               if (ret)
>>> +                       return ret;
>>> +       }
>>>
>>>          hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
>>>          if (!hcd)
>>> --
>>> 1.9.1
>>>
>>
>> Hi Greg, Arnd, Russell,
>>
>> Do you have any more comment about this patch set?
>>
>
> I'm not sure I fully understand why we need to try the 64 bit DMA mask in
> platform probe.
>
> As I understood it we just want to have some DMA mask set before calling
> usb_create_hcd()
> to make sure USB core gets the "uses_dma" flag set and dma_set_mask() won't
> fail because of
> missing dev->dma_mask.
>
> The correct DMA mask is set later in xhci_gen_setup()
>
> We also need to make sure the controller supports 64bit addressing
> capability before setting a 64 bit DMA mask.
> (bit 0 in HCCPARAMS)
>
> So for platform devices it goes look go this:
>
> xhci_plat_probe()
>   usb_create_hcd()
>     usb_create_shared_hcd()
>       hcd->self.uses_dma = (dev->dma_mask != NULL);
>   usb_add_hcd()
>     hcd->driver->reset()  (.reset = xhci_plat_setup)
>       xhci_plat_setup()
>         xhci_gen_setup()
>           if (HCC_64BIT_ADDR(xhci->hcc_params) && !dma_set_mask(dev,
> DMA_BIT_MASK(64))) {
>             xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n");
>             dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
>           }
>
> or do we end up with dev->dma_mask = NULL on 64-bit DMA only after trying to
> set it to 32 in xhci_plat_probe(),
> and thus also failing the dma_set_mask() in xhci_gen_setup()?
>

Hi Mathias,

dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)) in xhci_plat_probe
fails on our Arm64 X-Gene platform as we do not have DMA memory below 4GB. As a
consequence, xhci_plat_probe exits very early without creating any hcd.

The xhci_gen_setup code assumes that the dma_mask and
coherent_dma_mask were already
set to DMA_BIT_MASK(32) and only check to switch to DMA_BIT_MASK(64)
if the controller
supports 64-bit DMA. So I also see possible regression if a 32-bit
controller is used on 64-bit
system with my patch.

I will integrate Russell's suggestion and add changes to address the
case of 32-bit controller on 64-bit system
in my next version of this patch set.

> -Mathias
>
>
>
>
>
>
>
>
>
>


Regards,
Duc Dang Sept. 17, 2015, 6:19 p.m. UTC | #5
The xhci platform driver does not work with system that only supports
64-bit DMA as it requests 32-bit DMA mask during driver initialization.
This patch set addresses this issue and also adds XHCI-compliant USB
Controller ACPI identification into xhci-platform driver.

Changes from v7:
        - Only use dma_coerce_mask_and_coherent when
        dma_mask is NULL
        - Check the controller DMA capability and configure
        32-bit dma_mask if it only supports 32-bit DMA
        - Patches is generated over v4.3-rc1

Changes from v6:
        -Add WARN_ON if dma_mask is NULL
        -Use dma_coerce_mask_and_coherent to assign
        dma_mask and coherent_dma_mask

Change from v5:
        -Change comment to "XHCI-compliant USB Controller" as
        "PNP0D10" ID is not X-Gene specific
        -Change comment
        -Assign dma_mask to coherent_dma_mask if dma_mask is NULL
        to make sure dma_set_mask_and_coherent does not fail prematurely.

Changes from v4:
        -Remove #ifdef CONFIG_ACPI
        -Change comment
        -Assign dma_mask to coherent_dma_mask if dma_mask is NULL
        to make sure dma_set_mask_and_coherent does not fail prematurely.

Changes from v3:
        -Regenerate the patch over 4.2-rc5
        -No code change

Changes from v2
        -Replaced tristate with a boolean as the driver doesn't
                compile as a module
        -Correct --help-- to ---help---

Changes from v1
        -Consolidated to use dma_set_mask_and_coherent
        -Got rid of the check against sizeof(dma_addr_t)
        -Renamed from "add support for APM X-Gene to xhci-platform"
        -Removed changes to arm64/Kconfig
        -Made CONFIG_USB_XHCI_PLATFORM a user selectable config option

 drivers/usb/host/xhci-plat.c | 29 ++++++++++++++++++++++-------
 drivers/usb/host/xhci.c      | 10 ++++++++++
 2 files changed, 32 insertions(+), 7 deletions(-)
Duc Dang Sept. 30, 2015, 9:24 p.m. UTC | #6
On Thu, Sep 17, 2015 at 11:19 AM, Duc Dang <dhdang@apm.com> wrote:
> The xhci platform driver does not work with system that only supports
> 64-bit DMA as it requests 32-bit DMA mask during driver initialization.
> This patch set addresses this issue and also adds XHCI-compliant USB
> Controller ACPI identification into xhci-platform driver.

Hi Greg, Mathias,

Arnd already ack-ed the first patch, please let me know if you have
more comment on this set?

>
> Changes from v7:
>         - Only use dma_coerce_mask_and_coherent when
>         dma_mask is NULL
>         - Check the controller DMA capability and configure
>         32-bit dma_mask if it only supports 32-bit DMA
>         - Patches is generated over v4.3-rc1
>
> Changes from v6:
>         -Add WARN_ON if dma_mask is NULL
>         -Use dma_coerce_mask_and_coherent to assign
>         dma_mask and coherent_dma_mask
>
> Change from v5:
>         -Change comment to "XHCI-compliant USB Controller" as
>         "PNP0D10" ID is not X-Gene specific
>         -Change comment
>         -Assign dma_mask to coherent_dma_mask if dma_mask is NULL
>         to make sure dma_set_mask_and_coherent does not fail prematurely.
>
> Changes from v4:
>         -Remove #ifdef CONFIG_ACPI
>         -Change comment
>         -Assign dma_mask to coherent_dma_mask if dma_mask is NULL
>         to make sure dma_set_mask_and_coherent does not fail prematurely.
>
> Changes from v3:
>         -Regenerate the patch over 4.2-rc5
>         -No code change
>
> Changes from v2
>         -Replaced tristate with a boolean as the driver doesn't
>                 compile as a module
>         -Correct --help-- to ---help---
>
> Changes from v1
>         -Consolidated to use dma_set_mask_and_coherent
>         -Got rid of the check against sizeof(dma_addr_t)
>         -Renamed from "add support for APM X-Gene to xhci-platform"
>         -Removed changes to arm64/Kconfig
>         -Made CONFIG_USB_XHCI_PLATFORM a user selectable config option
>
>  drivers/usb/host/xhci-plat.c | 29 ++++++++++++++++++++++-------
>  drivers/usb/host/xhci.c      | 10 ++++++++++
>  2 files changed, 32 insertions(+), 7 deletions(-)
>
> --
> 1.9.1
>

Regards,
Duc Dang.
Greg KH Oct. 4, 2015, 9:10 a.m. UTC | #7
On Wed, Sep 30, 2015 at 02:24:30PM -0700, Duc Dang wrote:
> On Thu, Sep 17, 2015 at 11:19 AM, Duc Dang <dhdang@apm.com> wrote:
> > The xhci platform driver does not work with system that only supports
> > 64-bit DMA as it requests 32-bit DMA mask during driver initialization.
> > This patch set addresses this issue and also adds XHCI-compliant USB
> > Controller ACPI identification into xhci-platform driver.
> 
> Hi Greg, Mathias,
> 
> Arnd already ack-ed the first patch, please let me know if you have
> more comment on this set?

I'm waiting for Mathias to forward this on to me as he's the xhci
maintainer.

thanks,

greg k-h
Mathias Nyman Oct. 7, 2015, 1:20 p.m. UTC | #8
On 04.10.2015 12:10, Greg KH wrote:
> On Wed, Sep 30, 2015 at 02:24:30PM -0700, Duc Dang wrote:
>> On Thu, Sep 17, 2015 at 11:19 AM, Duc Dang <dhdang@apm.com> wrote:
>>> The xhci platform driver does not work with system that only supports
>>> 64-bit DMA as it requests 32-bit DMA mask during driver initialization.
>>> This patch set addresses this issue and also adds XHCI-compliant USB
>>> Controller ACPI identification into xhci-platform driver.
>>
>> Hi Greg, Mathias,
>>
>> Arnd already ack-ed the first patch, please let me know if you have
>> more comment on this set?
>
> I'm waiting for Mathias to forward this on to me as he's the xhci
> maintainer.
>

I got them waiting in my queue, just need to sort out some other unrelated patches
before passing everything forward.

-Mathias
diff mbox

Patch

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 890ad9d..e4c7f9d 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -93,14 +93,19 @@  static int xhci_plat_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return -ENODEV;
 
-	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
-	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
-	if (ret)
-		return ret;
-	if (!pdev->dev.dma_mask)
-		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
-	else
-		dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+	/* Throw a waring if broken platform code didn't initialize dma_mask */
+	WARN_ON(!pdev->dev.dma_mask);
+	/*
+	 * Try setting dma_mask and coherent_dma_mask to 64 bits,
+	 * then try 32 bits
+	 */
+	ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+	if (ret) {
+		ret = dma_coerce_mask_and_coherent(&pdev->dev,
+						   DMA_BIT_MASK(32));
+		if (ret)
+			return ret;
+	}
 
 	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
 	if (!hcd)