Re: [RFC v5] xhci: fix dma mask setup in xhci.c
Hi Xenia, When I apply this patch to Greg's usb-next tree and try to compile, I get the following error: sarah@xanatos:~/git/kernels/xhci$ git am -s ~/Maildir.fetchmail/.to-apply Applying: xhci: fix dma mask setup in xhci.c total: 0 errors, 0 warnings, 53 lines checked Your patch has no obvious style problems and is ready for submission. sarah@xanatos:~/git/kernels/xhci$ make drivers/usb/host/xhci-plat.ko make[1]: Nothing to be done for `all'. make[1]: Nothing to be done for `relocs'. CHK include/generated/uapi/linux/version.h CHK include/generated/utsrelease.h CALLscripts/checksyscalls.sh stdin:1220:2: warning: #warning syscall kcmp not implemented [-Wcpp] stdin:1223:2: warning: #warning syscall finit_module not implemented [-Wcpp] CC [M] drivers/usb/host/xhci-plat.o drivers/usb/host/xhci-plat.c: In function ‘xhci_plat_probe’: drivers/usb/host/xhci-plat.c:109:2: error: implicit declaration of function ‘dma_set_coherent_mask’ [-Werror=implicit-function-declaration] drivers/usb/host/xhci-plat.c:109:2: error: implicit declaration of function ‘DMA_BIT_MASK’ [-Werror=implicit-function-declaration] drivers/usb/host/xhci-plat.c:115:3: error: implicit declaration of function ‘dma_set_mask’ [-Werror=implicit-function-declaration] cc1: some warnings being treated as errors make[1]: *** [drivers/usb/host/xhci-plat.o] Error 1 make: *** [drivers/usb/host/xhci-plat.ko] Error 2 Maybe you're missing a header file in xhci-plat.c? Please make sure to run `make menuconfig` and double check that all the dependencies for CONFIG_XHCI_PLATFORM are met, so that you're compiling xhci-plat.ko. Please fix this and resubmit. Sarah Sharp On Mon, Aug 05, 2013 at 10:50:20PM +0300, Xenia Ragiadakou wrote: The function dma_set_mask() tests internally whether the dma_mask pointer for the device is initialized and fails if the dma_mask pointer is NULL. On pci platforms, the device dma_mask pointer is initialized, when pci devices are enumerated, to point to the pci_dev-dma_mask which is 0x. However, for non-pci platforms, the dma_mask pointer may not be initialized and in that case dma_set_mask() will fail. This patch initializes the dma_mask and the coherent_dma_mask to 32bits in xhci_plat_probe(), before the call to usb_create_hcd() that sets the uses_dma flag for the usb bus and the call to usb_add_hcd() that creates coherent dma pools for the usb hcd. Moreover, a call to dma_set_mask() does not set the device coherent_dma_mask. Since the xhci-hcd driver calls dma_alloc_coherent() and dma_pool_alloc() to allocate consistent DMA memory blocks, the coherent DMA address mask has to be set explicitly. This patch sets the coherent_dma_mask to 64bits in xhci_gen_setup() when the xHC is capable for 64-bit DMA addressing. If dma_set_mask() succeeds, for a given bitmask, it is guaranteed that the given bitmask is also supported for consistent DMA mappings. Other changes introduced in this patch are: - The return value of dma_set_mask() is checked to ensure that the required dma bitmask conforms with the host system's addressing capabilities. - The dma_mask setup code for the non-primary hcd was removed since both primary and non-primary hcd refer to the same generic device whose dma_mask and coherent_dma_mask are already set during the setup of the primary hcd. - The code for reading the HCCPARAMS register to find out the addressing capabilities of xHC was removed since its value is already cached in xhci-hccparams. - hcd-self.controller was replaced with the dev variable since it is already available. Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com --- Differences from version 4: - Change the initialization code in xhci_plat_probe() to avoid unnecessary second assignment of the dma_mask if the dma_mask pointer is initialized to point to the coherent_dma_mask. - Use dma_set_coherent_mask() instead of assigning directly to the coherent_dma_mask. drivers/usb/host/xhci-plat.c | 9 + drivers/usb/host/xhci.c | 19 +-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 51e22bf..1d83a7a 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -104,6 +104,15 @@ static int xhci_plat_probe(struct platform_device *pdev) if (!res) 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)); + hcd = usb_create_hcd(driver, pdev-dev, dev_name(pdev-dev)); if (!hcd) return -ENOMEM; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index
[RFC v5] xhci: fix dma mask setup in xhci.c
The function dma_set_mask() tests internally whether the dma_mask pointer for the device is initialized and fails if the dma_mask pointer is NULL. On pci platforms, the device dma_mask pointer is initialized, when pci devices are enumerated, to point to the pci_dev-dma_mask which is 0x. However, for non-pci platforms, the dma_mask pointer may not be initialized and in that case dma_set_mask() will fail. This patch initializes the dma_mask and the coherent_dma_mask to 32bits in xhci_plat_probe(), before the call to usb_create_hcd() that sets the uses_dma flag for the usb bus and the call to usb_add_hcd() that creates coherent dma pools for the usb hcd. Moreover, a call to dma_set_mask() does not set the device coherent_dma_mask. Since the xhci-hcd driver calls dma_alloc_coherent() and dma_pool_alloc() to allocate consistent DMA memory blocks, the coherent DMA address mask has to be set explicitly. This patch sets the coherent_dma_mask to 64bits in xhci_gen_setup() when the xHC is capable for 64-bit DMA addressing. If dma_set_mask() succeeds, for a given bitmask, it is guaranteed that the given bitmask is also supported for consistent DMA mappings. Other changes introduced in this patch are: - The return value of dma_set_mask() is checked to ensure that the required dma bitmask conforms with the host system's addressing capabilities. - The dma_mask setup code for the non-primary hcd was removed since both primary and non-primary hcd refer to the same generic device whose dma_mask and coherent_dma_mask are already set during the setup of the primary hcd. - The code for reading the HCCPARAMS register to find out the addressing capabilities of xHC was removed since its value is already cached in xhci-hccparams. - hcd-self.controller was replaced with the dev variable since it is already available. Signed-off-by: Xenia Ragiadakou burzalod...@gmail.com --- Differences from version 4: - Change the initialization code in xhci_plat_probe() to avoid unnecessary second assignment of the dma_mask if the dma_mask pointer is initialized to point to the coherent_dma_mask. - Use dma_set_coherent_mask() instead of assigning directly to the coherent_dma_mask. drivers/usb/host/xhci-plat.c | 9 + drivers/usb/host/xhci.c | 19 +-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 51e22bf..1d83a7a 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -104,6 +104,15 @@ static int xhci_plat_probe(struct platform_device *pdev) if (!res) 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)); + hcd = usb_create_hcd(driver, pdev-dev, dev_name(pdev-dev)); if (!hcd) return -ENOMEM; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index bef1e77..6daf439 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4804,7 +4804,6 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) struct xhci_hcd *xhci; struct device *dev = hcd-self.controller; int retval; - u32 temp; /* Accept arbitrarily long scatter-gather lists */ hcd-self.sg_tablesize = ~0; @@ -4832,14 +4831,6 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) /* xHCI private pointer was set in xhci_pci_probe for the second * registered roothub. */ - xhci = hcd_to_xhci(hcd); - temp = xhci_readl(xhci, xhci-cap_regs-hcc_params); - if (HCC_64BIT_ADDR(temp)) { - xhci_dbg(xhci, Enabling 64-bit DMA addresses.\n); - dma_set_mask(hcd-self.controller, DMA_BIT_MASK(64)); - } else { - dma_set_mask(hcd-self.controller, DMA_BIT_MASK(32)); - } return 0; } @@ -4871,12 +4862,12 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) goto error; xhci_dbg(xhci, Reset complete\n); - temp = xhci_readl(xhci, xhci-cap_regs-hcc_params); - if (HCC_64BIT_ADDR(temp)) { + /* Set dma_mask and coherent_dma_mask to 64-bits, +* if xHC supports 64-bit addressing */ + 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_mask(hcd-self.controller, DMA_BIT_MASK(64)); - } else { -