Re: [RFC v2] xhci: fix dma mask setup in xhci.c

2013-06-12 Thread Sarah Sharp
On Fri, Jun 07, 2013 at 11:37:53PM +0300, Felipe Balbi wrote:
 Hi,
 
 On Fri, Jun 07, 2013 at 10:19:23AM -0700, Sarah Sharp wrote:
  Adding Felipe.
  
  Xenia, Felipe is the USB gadget maintainer, and also added code for
  non-PCI xHCI hosts.  Felipe, Xenia is my summer intern through the FOSS
  Outreach Program for Women: http://kernelnewbies.org/OPWIntro
 
 Hey, cool Sarah :-)
 
 Welcome Xenia :-)

Ah, slight correction, my intern wants to be called Ksenia.  Xenia is
her legal name, but everyone calls her Ksenia. :)

  On Fri, Jun 07, 2013 at 03:00:47PM +0300, Mathias Nyman wrote:
   Andy explained his concern in more detail to me irl.
   
   The beef is that the dma_mask is a pointer while dma_coherent_mask
   is a u64 value in struct device, and dma_set_mask() fails if
   dev-dma_mask doesn't point anywhere.
   
   This is not a problem for PCI enumerated devices because PCI probe
   sets a default 32bit mask and makes the dma_mask of all new PCI
   devices point to this value.
   
   For non-pci enumerated devices the device dma_mask may be NULL and
   dma_set_mask() may fail even if dma is supported on the host
   machine.
   
   for example ehci-platform.c solves this by adding:
   
   if (!dev-dev.dma_mask)
   dev-dev.dma_mask = dev-dev.coherent_dma_mask;
   if (!dev-dev.coherent_dma_mask)
   dev-dev.coherent_dma_mask = DMA_BIT_MASK(32);
  
  So it sounds like xhci_plat_setup() in xhci-plat.c needs to do something
  similar before it calls xhci_gen_setup().  Felipe, do you agree?
 
 (now, after reading the whole thing...)
 
 I'll agree with that :)
 
  It's funny that the code worked before.  Perhaps setting the dma_mask
  pointer should be a separate patch for stable?
 
 sounds like a good plan to me :-)

Great!  Ok, Ksenia, can you create those two patches?  The first patch
in the series should add setting the dma_mask pointer to
xhci_plat_setup().  The second patch will be the same as this patch.
Let me know via IRC if you have any questions.

Sarah Sharp
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC v2] xhci: fix dma mask setup in xhci.c

2013-06-07 Thread Mathias Nyman

On 06/07/2013 01:54 AM, Sarah Sharp wrote:

On Thu, Jun 06, 2013 at 09:37:51PM +0300, Andy Shevchenko wrote:

On Thu, Jun 6, 2013 at 5:21 PM, Xenia Ragiadakouburzalod...@gmail.com  wrote:

This patch adds a check on whether the host machine
supports the xHC DMA address mask and sets the DMA
mask for coherent DMA address allocation via an
explicit call to dma_set_coherent_mask().

According to DMA-API-HOWTO, if coherent DMA address
mask has not been set explicitly via dma_set_coherent_mask(),
and the driver calls dma_alloc_coherent() or
dma_pool_create() to allocate consistent DMA memory
blocks, the consistent DMA mapping interface will
return by default DMA addresses which are 32-bit
addressable.

Hence, if 64-bit DMA mapping is supported, it
is appropriate to call dma_set_coherent_mask()
with DMA_BIT_MASK(64) to take advantage of it.

Also, according to DMA-API-HOWTO, dma_set_coherent_mask()
is guaranteed to set successfully the same or a smaller
mask as dma_set_mask().


It looks for me overcomplicated.


Why?


We have *dma_mask and dma_coherent mask in the struct device.
First question, who is allocating memory for dma_mask?


The xHCI driver is allocating memory for the host hardware structures,
and the USB core is using the DMA mask of the host controller in order
to move USB buffers into bounce buffers as necessary.

The xHCI driver allocates memory from both DMA pools and with kmalloc.
We need both calls to dma_set_coherent_mask() and
dma_set_coherent_mask() to get 64-bit DMA addresses for both types of
memory.


Second, in case of dma_mask == NULL, dma_set_mask fails with -EIO. It
doesn't mean we have no support of this one. How do you handle this
case?


When would the dma_mask be NULL?  Note that xHCI PCI hosts *must* be
able to support DMA.


I think it's pretty simple to set dma_coherent_mask and then apply its
address to the dma_mask, because you set the same values anyway.


I'm not quite understanding what you want to do.  (I'll blame lack of
sleep, sorry.)  Can you write some pseudo code for me?



Andy explained his concern in more detail to me irl.

The beef is that the dma_mask is a pointer while dma_coherent_mask is a 
u64 value in struct device, and dma_set_mask() fails if dev-dma_mask 
doesn't point anywhere.


This is not a problem for PCI enumerated devices because PCI probe sets 
a default 32bit mask and makes the dma_mask of all new PCI devices point 
to this value.


For non-pci enumerated devices the device dma_mask may be NULL and 
dma_set_mask() may fail even if dma is supported on the host machine.


for example ehci-platform.c solves this by adding:

if (!dev-dev.dma_mask)
dev-dev.dma_mask = dev-dev.coherent_dma_mask;
if (!dev-dev.coherent_dma_mask)
dev-dev.coherent_dma_mask = DMA_BIT_MASK(32);

-Mathias
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC v2] xhci: fix dma mask setup in xhci.c

2013-06-07 Thread Sarah Sharp
Adding Felipe.

Xenia, Felipe is the USB gadget maintainer, and also added code for
non-PCI xHCI hosts.  Felipe, Xenia is my summer intern through the FOSS
Outreach Program for Women: http://kernelnewbies.org/OPWIntro

Felipe, we're discussing the fact that the xHCI host currently does not
set up 64-bit coherent DMA, so we get 64-bit addresses for USB buffers,
but not xHCI data structures.  Xenia has a patch to fix it, which can be
found here: http://marc.info/?l=linux-usbm=137052855612729w=2

Andy thinks the patch has issues with non-PCI xHCI hosts.

On Fri, Jun 07, 2013 at 03:00:47PM +0300, Mathias Nyman wrote:
 Andy explained his concern in more detail to me irl.
 
 The beef is that the dma_mask is a pointer while dma_coherent_mask
 is a u64 value in struct device, and dma_set_mask() fails if
 dev-dma_mask doesn't point anywhere.
 
 This is not a problem for PCI enumerated devices because PCI probe
 sets a default 32bit mask and makes the dma_mask of all new PCI
 devices point to this value.
 
 For non-pci enumerated devices the device dma_mask may be NULL and
 dma_set_mask() may fail even if dma is supported on the host
 machine.
 
 for example ehci-platform.c solves this by adding:
 
 if (!dev-dev.dma_mask)
 dev-dev.dma_mask = dev-dev.coherent_dma_mask;
 if (!dev-dev.coherent_dma_mask)
 dev-dev.coherent_dma_mask = DMA_BIT_MASK(32);

So it sounds like xhci_plat_setup() in xhci-plat.c needs to do something
similar before it calls xhci_gen_setup().  Felipe, do you agree?

It's funny that the code worked before.  Perhaps setting the dma_mask
pointer should be a separate patch for stable?

Sarah Sharp
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC v2] xhci: fix dma mask setup in xhci.c

2013-06-07 Thread Felipe Balbi
Hi,

On Fri, Jun 07, 2013 at 10:19:23AM -0700, Sarah Sharp wrote:
 Adding Felipe.
 
 Xenia, Felipe is the USB gadget maintainer, and also added code for
 non-PCI xHCI hosts.  Felipe, Xenia is my summer intern through the FOSS
 Outreach Program for Women: http://kernelnewbies.org/OPWIntro

Hey, cool Sarah :-)

Welcome Xenia :-)

 Felipe, we're discussing the fact that the xHCI host currently does not
 set up 64-bit coherent DMA, so we get 64-bit addresses for USB buffers,
 but not xHCI data structures.  Xenia has a patch to fix it, which can be
 found here: http://marc.info/?l=linux-usbm=137052855612729w=2
 
 Andy thinks the patch has issues with non-PCI xHCI hosts.

Looking at the patch, I don't see why it would have any issues, unless
some HW engineer flipped the wrong bits in hcc_params, but that would be
a silicon bug anyway.

I don't have access to anything to test right now (on vacations, last
day :-( ) but I'll see if anyone from TI can help testing that patch.

Maybe Kishon can help us out  here ? Kishon, could you spend a few
minutes testing Xenia's patch on OMAP5 to make sure nothing goes wrong
with that platform.

Again, I can't see how it would fail.

 On Fri, Jun 07, 2013 at 03:00:47PM +0300, Mathias Nyman wrote:
  Andy explained his concern in more detail to me irl.
  
  The beef is that the dma_mask is a pointer while dma_coherent_mask
  is a u64 value in struct device, and dma_set_mask() fails if
  dev-dma_mask doesn't point anywhere.
  
  This is not a problem for PCI enumerated devices because PCI probe
  sets a default 32bit mask and makes the dma_mask of all new PCI
  devices point to this value.
  
  For non-pci enumerated devices the device dma_mask may be NULL and
  dma_set_mask() may fail even if dma is supported on the host
  machine.
  
  for example ehci-platform.c solves this by adding:
  
  if (!dev-dev.dma_mask)
  dev-dev.dma_mask = dev-dev.coherent_dma_mask;
  if (!dev-dev.coherent_dma_mask)
  dev-dev.coherent_dma_mask = DMA_BIT_MASK(32);
 
 So it sounds like xhci_plat_setup() in xhci-plat.c needs to do something
 similar before it calls xhci_gen_setup().  Felipe, do you agree?

(now, after reading the whole thing...)

I'll agree with that :)

 It's funny that the code worked before.  Perhaps setting the dma_mask
 pointer should be a separate patch for stable?

sounds like a good plan to me :-)

-- 
balbi


signature.asc
Description: Digital signature


[RFC v2] xhci: fix dma mask setup in xhci.c

2013-06-06 Thread Xenia Ragiadakou
This patch adds a check on whether the host machine
supports the xHC DMA address mask and sets the DMA
mask for coherent DMA address allocation via an
explicit call to dma_set_coherent_mask().

According to DMA-API-HOWTO, if coherent DMA address
mask has not been set explicitly via dma_set_coherent_mask(),
and the driver calls dma_alloc_coherent() or
dma_pool_create() to allocate consistent DMA memory
blocks, the consistent DMA mapping interface will
return by default DMA addresses which are 32-bit
addressable.

Hence, if 64-bit DMA mapping is supported, it
is appropriate to call dma_set_coherent_mask()
with DMA_BIT_MASK(64) to take advantage of it.

Also, according to DMA-API-HOWTO, dma_set_coherent_mask()
is guaranteed to set successfully the same or a smaller
mask as dma_set_mask().

Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com
---

Changes from v1:

fix of the following checkpatch warning, triggered in v1
WARNING: line over 80 characters

 drivers/usb/host/xhci.c |   33 +++--
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index b4aa79d..2167b98 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4662,11 +4662,22 @@ int xhci_gen_setup(struct usb_hcd *hcd, 
xhci_get_quirks_t get_quirks)
 */
xhci = hcd_to_xhci(hcd);
temp = xhci_readl(xhci, xhci-cap_regs-hcc_params);
-   if (HCC_64BIT_ADDR(temp)) {
+   /*
+* Check if host machine supports 64 bit DMA address mask
+* and enable it for both streaming and coherent DMA transfers.
+* Otherwise, use 32bit DMA mask, if it is supported.
+*/
+   if (HCC_64BIT_ADDR(temp) 
+   !dma_set_mask(hcd-self.controller, DMA_BIT_MASK(64))) {
xhci_dbg(xhci, Enabling 64-bit DMA addresses.\n);
-   dma_set_mask(hcd-self.controller, DMA_BIT_MASK(64));
+   dma_set_coherent_mask(hcd-self.controller,
+ DMA_BIT_MASK(64));
} else {
-   dma_set_mask(hcd-self.controller, DMA_BIT_MASK(32));
+   if (dma_set_mask(hcd-self.controller,
+DMA_BIT_MASK(32)))
+   goto error;
+   dma_set_coherent_mask(hcd-self.controller,
+ DMA_BIT_MASK(32));
}
return 0;
}
@@ -4700,11 +4711,21 @@ int xhci_gen_setup(struct usb_hcd *hcd, 
xhci_get_quirks_t get_quirks)
xhci_dbg(xhci, Reset complete\n);
 
temp = xhci_readl(xhci, xhci-cap_regs-hcc_params);
-   if (HCC_64BIT_ADDR(temp)) {
+   /*
+* Check if host machine supports 64 bit DMA address mask
+* and enable it for both streaming and coherent DMA transfers.
+* Otherwise, use 32bit DMA mask, if it is supported.
+*/
+   if (HCC_64BIT_ADDR(temp) 
+   !dma_set_mask(hcd-self.controller, DMA_BIT_MASK(64))) {
xhci_dbg(xhci, Enabling 64-bit DMA addresses.\n);
-   dma_set_mask(hcd-self.controller, DMA_BIT_MASK(64));
+   dma_set_coherent_mask(hcd-self.controller,
+ DMA_BIT_MASK(64));
} else {
-   dma_set_mask(hcd-self.controller, DMA_BIT_MASK(32));
+   if (dma_set_mask(hcd-self.controller, DMA_BIT_MASK(32)))
+   goto error;
+   dma_set_coherent_mask(hcd-self.controller,
+ DMA_BIT_MASK(32));
}
 
xhci_dbg(xhci, Calling HCD init\n);
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC v2] xhci: fix dma mask setup in xhci.c

2013-06-06 Thread Andy Shevchenko
On Thu, Jun 6, 2013 at 5:21 PM, Xenia Ragiadakou burzalod...@gmail.com wrote:
 This patch adds a check on whether the host machine
 supports the xHC DMA address mask and sets the DMA
 mask for coherent DMA address allocation via an
 explicit call to dma_set_coherent_mask().

 According to DMA-API-HOWTO, if coherent DMA address
 mask has not been set explicitly via dma_set_coherent_mask(),
 and the driver calls dma_alloc_coherent() or
 dma_pool_create() to allocate consistent DMA memory
 blocks, the consistent DMA mapping interface will
 return by default DMA addresses which are 32-bit
 addressable.

 Hence, if 64-bit DMA mapping is supported, it
 is appropriate to call dma_set_coherent_mask()
 with DMA_BIT_MASK(64) to take advantage of it.

 Also, according to DMA-API-HOWTO, dma_set_coherent_mask()
 is guaranteed to set successfully the same or a smaller
 mask as dma_set_mask().

It looks for me overcomplicated.

We have *dma_mask and dma_coherent mask in the struct device.
First question, who is allocating memory for dma_mask?
Second, in case of dma_mask == NULL, dma_set_mask fails with -EIO. It
doesn't mean we have no support of this one. How do you handle this
case?

I think it's pretty simple to set dma_coherent_mask and then apply its
address to the dma_mask, because you set the same values anyway.


--
With Best Regards,
Andy Shevchenko
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC v2] xhci: fix dma mask setup in xhci.c

2013-06-06 Thread Sarah Sharp
On Thu, Jun 06, 2013 at 09:37:51PM +0300, Andy Shevchenko wrote:
 On Thu, Jun 6, 2013 at 5:21 PM, Xenia Ragiadakou burzalod...@gmail.com 
 wrote:
  This patch adds a check on whether the host machine
  supports the xHC DMA address mask and sets the DMA
  mask for coherent DMA address allocation via an
  explicit call to dma_set_coherent_mask().
 
  According to DMA-API-HOWTO, if coherent DMA address
  mask has not been set explicitly via dma_set_coherent_mask(),
  and the driver calls dma_alloc_coherent() or
  dma_pool_create() to allocate consistent DMA memory
  blocks, the consistent DMA mapping interface will
  return by default DMA addresses which are 32-bit
  addressable.
 
  Hence, if 64-bit DMA mapping is supported, it
  is appropriate to call dma_set_coherent_mask()
  with DMA_BIT_MASK(64) to take advantage of it.
 
  Also, according to DMA-API-HOWTO, dma_set_coherent_mask()
  is guaranteed to set successfully the same or a smaller
  mask as dma_set_mask().
 
 It looks for me overcomplicated.

Why?

 We have *dma_mask and dma_coherent mask in the struct device.
 First question, who is allocating memory for dma_mask?

The xHCI driver is allocating memory for the host hardware structures,
and the USB core is using the DMA mask of the host controller in order
to move USB buffers into bounce buffers as necessary.

The xHCI driver allocates memory from both DMA pools and with kmalloc.
We need both calls to dma_set_coherent_mask() and
dma_set_coherent_mask() to get 64-bit DMA addresses for both types of
memory.

 Second, in case of dma_mask == NULL, dma_set_mask fails with -EIO. It
 doesn't mean we have no support of this one. How do you handle this
 case?

When would the dma_mask be NULL?  Note that xHCI PCI hosts *must* be
able to support DMA.

 I think it's pretty simple to set dma_coherent_mask and then apply its
 address to the dma_mask, because you set the same values anyway.

I'm not quite understanding what you want to do.  (I'll blame lack of
sleep, sorry.)  Can you write some pseudo code for me?

Sarah Sharp
--
To unsubscribe from this list: send the line unsubscribe linux-usb in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html