From 8f6429c7cb59f28433253575cc8e3262eed63592 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Thu, 16 Jul 2015 19:40:12 +0100 Subject: iommu/iova: Avoid over-allocating when size-aligned Currently, allocating a size-aligned IOVA region quietly adjusts the actual allocation size in the process, returning a rounded-up power-of-two-sized allocation. This results in mismatched behaviour in the IOMMU driver if the original size was not a power of two, where the original size is mapped, but the rounded-up IOVA size is unmapped. Whilst some IOMMUs will happily unmap already-unmapped pages, others consider this an error, so fix it by computing the necessary alignment padding without altering the actual allocation size. Also clean up by making pad_size unsigned, since its callers always pass unsigned values and negative padding makes little sense here anyway. Signed-off-by: Robin Murphy Signed-off-by: David Woodhouse --- drivers/iommu/intel-iommu.c | 2 ++ drivers/iommu/iova.c | 23 ++++++----------------- 2 files changed, 8 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index a98a7b27aca1..92101597cede 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -3233,6 +3233,8 @@ static struct iova *intel_alloc_iova(struct device *dev, /* Restrict dma_mask to the width that the iommu can handle */ dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask); + /* Ensure we reserve the whole size-aligned region */ + nrpages = __roundup_pow_of_two(nrpages); if (!dmar_forcedac && dma_mask > DMA_BIT_MASK(32)) { /* diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index b7c3d923f3e1..29f2efcf668e 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -120,19 +120,14 @@ __cached_rbnode_delete_update(struct iova_domain *iovad, struct iova *free) } } -/* Computes the padding size required, to make the - * the start address naturally aligned on its size +/* + * Computes the padding size required, to make the start address + * naturally aligned on the power-of-two order of its size */ -static int -iova_get_pad_size(int size, unsigned int limit_pfn) +static unsigned int +iova_get_pad_size(unsigned int size, unsigned int limit_pfn) { - unsigned int pad_size = 0; - unsigned int order = ilog2(size); - - if (order) - pad_size = (limit_pfn + 1) % (1 << order); - - return pad_size; + return (limit_pfn + 1 - size) & (__roundup_pow_of_two(size) - 1); } static int __alloc_and_insert_iova_range(struct iova_domain *iovad, @@ -265,12 +260,6 @@ alloc_iova(struct iova_domain *iovad, unsigned long size, if (!new_iova) return NULL; - /* If size aligned is set then round the size to - * to next power of two. - */ - if (size_aligned) - size = __roundup_pow_of_two(size); - ret = __alloc_and_insert_iova_range(iovad, size, limit_pfn, new_iova, size_aligned); -- cgit v1.2.3 From ae1ff3d623905947158fd3394854c23026337810 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 13 Jul 2015 14:31:28 +0300 Subject: iommu: iova: Move iova cache management to the iova library This is necessary to separate intel-iommu from the iova library. Signed-off-by: Sakari Ailus Signed-off-by: David Woodhouse --- drivers/iommu/intel-iommu.c | 6 ++-- drivers/iommu/iova.c | 83 ++++++++++++++++++++++++++------------------- 2 files changed, 52 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 92101597cede..2d5cf39e1053 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -3743,7 +3743,7 @@ static inline int iommu_devinfo_cache_init(void) static int __init iommu_init_mempool(void) { int ret; - ret = iommu_iova_cache_init(); + ret = iova_cache_get(); if (ret) return ret; @@ -3757,7 +3757,7 @@ static int __init iommu_init_mempool(void) kmem_cache_destroy(iommu_domain_cache); domain_error: - iommu_iova_cache_destroy(); + iova_cache_put(); return -ENOMEM; } @@ -3766,7 +3766,7 @@ static void __init iommu_exit_mempool(void) { kmem_cache_destroy(iommu_devinfo_cache); kmem_cache_destroy(iommu_domain_cache); - iommu_iova_cache_destroy(); + iova_cache_put(); } static void quirk_ioat_snb_local_iommu(struct pci_dev *pdev) diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index 29f2efcf668e..ed95f7a0fad3 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -20,40 +20,6 @@ #include #include -static struct kmem_cache *iommu_iova_cache; - -int iommu_iova_cache_init(void) -{ - int ret = 0; - - iommu_iova_cache = kmem_cache_create("iommu_iova", - sizeof(struct iova), - 0, - SLAB_HWCACHE_ALIGN, - NULL); - if (!iommu_iova_cache) { - pr_err("Couldn't create iova cache\n"); - ret = -ENOMEM; - } - - return ret; -} - -void iommu_iova_cache_destroy(void) -{ - kmem_cache_destroy(iommu_iova_cache); -} - -struct iova *alloc_iova_mem(void) -{ - return kmem_cache_alloc(iommu_iova_cache, GFP_ATOMIC); -} - -void free_iova_mem(struct iova *iova) -{ - kmem_cache_free(iommu_iova_cache, iova); -} - void init_iova_domain(struct iova_domain *iovad, unsigned long granule, unsigned long start_pfn, unsigned long pfn_32bit) @@ -237,6 +203,55 @@ iova_insert_rbtree(struct rb_root *root, struct iova *iova) rb_insert_color(&iova->node, root); } +static struct kmem_cache *iova_cache; +static unsigned int iova_cache_users; +static DEFINE_MUTEX(iova_cache_mutex); + +struct iova *alloc_iova_mem(void) +{ + return kmem_cache_alloc(iova_cache, GFP_ATOMIC); +} +EXPORT_SYMBOL(alloc_iova_mem); + +void free_iova_mem(struct iova *iova) +{ + kmem_cache_free(iova_cache, iova); +} +EXPORT_SYMBOL(free_iova_mem); + +int iova_cache_get(void) +{ + mutex_lock(&iova_cache_mutex); + if (!iova_cache_users) { + iova_cache = kmem_cache_create( + "iommu_iova", sizeof(struct iova), 0, + SLAB_HWCACHE_ALIGN, NULL); + if (!iova_cache) { + mutex_unlock(&iova_cache_mutex); + printk(KERN_ERR "Couldn't create iova cache\n"); + return -ENOMEM; + } + } + + iova_cache_users++; + mutex_unlock(&iova_cache_mutex); + + return 0; +} + +void iova_cache_put(void) +{ + mutex_lock(&iova_cache_mutex); + if (WARN_ON(!iova_cache_users)) { + mutex_unlock(&iova_cache_mutex); + return; + } + iova_cache_users--; + if (!iova_cache_users) + kmem_cache_destroy(iova_cache); + mutex_unlock(&iova_cache_mutex); +} + /** * alloc_iova - allocates an iova * @iovad: - iova domain in question -- cgit v1.2.3 From 9b41760b03816b34f4c9eee2cbb8fda8439920fc Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 13 Jul 2015 14:31:29 +0300 Subject: iommu: iova: Export symbols Use EXPORT_SYMBOL_GPL() to export the iova library symbols. The symbols include: init_iova_domain(); iova_cache_get(); iova_cache_put(); iova_cache_init(); alloc_iova(); find_iova(); __free_iova(); free_iova(); put_iova_domain(); reserve_iova(); copy_reserved_iova(); Signed-off-by: Sakari Ailus Signed-off-by: David Woodhouse --- drivers/iommu/iova.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index ed95f7a0fad3..cbd74c79b212 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -38,6 +38,7 @@ init_iova_domain(struct iova_domain *iovad, unsigned long granule, iovad->start_pfn = start_pfn; iovad->dma_32bit_pfn = pfn_32bit; } +EXPORT_SYMBOL_GPL(init_iova_domain); static struct rb_node * __get_cached_rbnode(struct iova_domain *iovad, unsigned long *limit_pfn) @@ -238,6 +239,7 @@ int iova_cache_get(void) return 0; } +EXPORT_SYMBOL_GPL(iova_cache_get); void iova_cache_put(void) { @@ -251,6 +253,7 @@ void iova_cache_put(void) kmem_cache_destroy(iova_cache); mutex_unlock(&iova_cache_mutex); } +EXPORT_SYMBOL_GPL(iova_cache_put); /** * alloc_iova - allocates an iova @@ -285,6 +288,7 @@ alloc_iova(struct iova_domain *iovad, unsigned long size, return new_iova; } +EXPORT_SYMBOL_GPL(alloc_iova); /** * find_iova - find's an iova for a given pfn @@ -325,6 +329,7 @@ struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn) spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags); return NULL; } +EXPORT_SYMBOL_GPL(find_iova); /** * __free_iova - frees the given iova @@ -343,6 +348,7 @@ __free_iova(struct iova_domain *iovad, struct iova *iova) spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags); free_iova_mem(iova); } +EXPORT_SYMBOL_GPL(__free_iova); /** * free_iova - finds and frees the iova for a given pfn @@ -360,6 +366,7 @@ free_iova(struct iova_domain *iovad, unsigned long pfn) __free_iova(iovad, iova); } +EXPORT_SYMBOL_GPL(free_iova); /** * put_iova_domain - destroys the iova doamin @@ -382,6 +389,7 @@ void put_iova_domain(struct iova_domain *iovad) } spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags); } +EXPORT_SYMBOL_GPL(put_iova_domain); static int __is_range_overlap(struct rb_node *node, @@ -471,6 +479,7 @@ finish: spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags); return iova; } +EXPORT_SYMBOL_GPL(reserve_iova); /** * copy_reserved_iova - copies the reserved between domains @@ -497,6 +506,7 @@ copy_reserved_iova(struct iova_domain *from, struct iova_domain *to) } spin_unlock_irqrestore(&from->iova_rbtree_lock, flags); } +EXPORT_SYMBOL_GPL(copy_reserved_iova); struct iova * split_and_remove_iova(struct iova_domain *iovad, struct iova *iova, -- cgit v1.2.3 From 15bbdec3931e617231c12b0920e497e87ec8c2c6 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 13 Jul 2015 14:31:30 +0300 Subject: iommu: Make the iova library a module The iova library has use outside the intel-iommu driver, thus make it a module. Signed-off-by: Sakari Ailus Signed-off-by: David Woodhouse --- drivers/iommu/Kconfig | 2 +- drivers/iommu/iova.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f1fb1d3ccc56..0a141cd44ddd 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -42,7 +42,7 @@ config IOMMU_IO_PGTABLE_LPAE_SELFTEST endmenu config IOMMU_IOVA - bool + tristate config OF_IOMMU def_bool y diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index cbd74c79b212..fa0adef32bd6 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -18,6 +18,7 @@ */ #include +#include #include void @@ -548,3 +549,6 @@ error: free_iova_mem(prev); return NULL; } + +MODULE_AUTHOR("Anil S Keshavamurthy "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 135919a3a80565070b9645009e65f73e72c661c0 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Wed, 9 Sep 2015 13:35:05 -0400 Subject: intel_idle: Skylake Client Support - updated Addition of PC9 state, and minor tweaks to existing PC6 and PC8 states. Signed-off-by: Len Brown --- drivers/idle/intel_idle.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 3a3738fe016b..cd4510a63375 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -620,7 +620,7 @@ static struct cpuidle_state skl_cstates[] = { .name = "C6-SKL", .desc = "MWAIT 0x20", .flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED, - .exit_latency = 75, + .exit_latency = 85, .target_residency = 200, .enter = &intel_idle, .enter_freeze = intel_idle_freeze, }, @@ -636,10 +636,18 @@ static struct cpuidle_state skl_cstates[] = { .name = "C8-SKL", .desc = "MWAIT 0x40", .flags = MWAIT2flg(0x40) | CPUIDLE_FLAG_TLB_FLUSHED, - .exit_latency = 174, + .exit_latency = 200, .target_residency = 800, .enter = &intel_idle, .enter_freeze = intel_idle_freeze, }, + { + .name = "C9-SKL", + .desc = "MWAIT 0x50", + .flags = MWAIT2flg(0x50) | CPUIDLE_FLAG_TLB_FLUSHED, + .exit_latency = 480, + .target_residency = 5000, + .enter = &intel_idle, + .enter_freeze = intel_idle_freeze, }, { .name = "C10-SKL", .desc = "MWAIT 0x60", -- cgit v1.2.3 From 4de2ced795272db3ee5d668510b3a91a2bf1d1fb Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 17 Aug 2015 11:08:23 -0700 Subject: staging: most: fix HDM_USB dependencies and build errors Fix kconfig dependency warning and build errors. warning: (HDM_USB) selects AIM_NETWORK which has unmet direct dependencies (STAGING && MOST && NET) drivers/built-in.o: In function `aim_resume_tx_channel': networking.c:(.text+0xd6f7a2): undefined reference to `netif_tx_wake_queue' drivers/built-in.o: In function `aim_rx_data': networking.c:(.text+0xd6f8c5): undefined reference to `__netdev_alloc_skb' networking.c:(.text+0xd6f99a): undefined reference to `skb_put' networking.c:(.text+0xd6fa44): undefined reference to `eth_type_trans' networking.c:(.text+0xd6fa6f): undefined reference to `netif_rx' drivers/built-in.o: In function `most_nd_setup': networking.c:(.text+0xd6fad2): undefined reference to `ether_setup' drivers/built-in.o: In function `most_nd_set_mac_address': networking.c:(.text+0xd6fb0f): undefined reference to `eth_mac_addr' drivers/built-in.o: In function `most_nd_open': networking.c:(.text+0xd6fd37): undefined reference to `netif_tx_wake_queue' drivers/built-in.o: In function `aim_probe_channel': networking.c:(.text+0xd6febb): undefined reference to `alloc_netdev_mqs' networking.c:(.text+0xd6ff18): undefined reference to `register_netdev' networking.c:(.text+0xd6ff4a): undefined reference to `free_netdev' drivers/built-in.o: In function `most_net_rm_netdev_safe.isra.0': networking.c:(.text+0xd6ffcf): undefined reference to `unregister_netdev' networking.c:(.text+0xd6ffdf): undefined reference to `free_netdev' drivers/built-in.o: In function `most_nd_start_xmit': networking.c:(.text+0xd70390): undefined reference to `kfree_skb' drivers/built-in.o: In function `most_deliver_netinfo': (.text+0xd70499): undefined reference to `netif_tx_wake_queue' Signed-off-by: Randy Dunlap Cc: Christian Gromm Cc: Michael Fabry Cc: Christian Gromm Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/hdm-usb/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/most/hdm-usb/Kconfig b/drivers/staging/most/hdm-usb/Kconfig index a482c3fdf34b..ec1546312ee6 100644 --- a/drivers/staging/most/hdm-usb/Kconfig +++ b/drivers/staging/most/hdm-usb/Kconfig @@ -4,7 +4,7 @@ config HDM_USB tristate "USB HDM" - depends on USB + depends on USB && NET select AIM_NETWORK ---help--- Say Y here if you want to connect via USB to network tranceiver. -- cgit v1.2.3 From b786a8ad6a34b45ff6e40cf9c21f9c13c38e2f70 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 1 Sep 2015 22:05:58 +0200 Subject: Staging: most: MOST and MOSTCORE should depend on HAS_DMA If NO_DMA=y: ERROR: "dma_free_coherent" [drivers/staging/most/mostcore/mostcore.ko] undefined! ERROR: "dma_alloc_coherent" [drivers/staging/most/mostcore/mostcore.ko] undefined! As all MOST sub drivers use DMA functionality, add a dependency on HAS_DMA to MOSTCORE, and to MOST, which selects MOSTCORE. Signed-off-by: Geert Uytterhoeven Acked-by: Christian Gromm Signed-off-by: Greg Kroah-Hartman --- drivers/staging/most/Kconfig | 1 + drivers/staging/most/mostcore/Kconfig | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/most/Kconfig b/drivers/staging/most/Kconfig index d50de03de7b9..0b9b9b539f70 100644 --- a/drivers/staging/most/Kconfig +++ b/drivers/staging/most/Kconfig @@ -1,5 +1,6 @@ menuconfig MOST tristate "MOST driver" + depends on HAS_DMA select MOSTCORE default n ---help--- diff --git a/drivers/staging/most/mostcore/Kconfig b/drivers/staging/most/mostcore/Kconfig index 38abf1b21b66..47172546d728 100644 --- a/drivers/staging/most/mostcore/Kconfig +++ b/drivers/staging/most/mostcore/Kconfig @@ -4,6 +4,7 @@ config MOSTCORE tristate "MOST Core" + depends on HAS_DMA ---help--- Say Y here if you want to enable MOST support. -- cgit v1.2.3 From a6ee5ac15ddf2425a066339f1ab030c97ec74b25 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 21 Aug 2015 14:02:57 -0700 Subject: staging/android: Update ION TODO per LPC discussion We discussed a bit with the folks on the Cc: list below what to do with ION. Two big take-aways: - High-performance drivers (like gpus) always want to play tricks with coherency and will lie to the dma api (radeon, nouveau, i915 gpu drivers all do so in upstream). What needs to be done here is fill gaps in dma-buf so that we can do this without breaking the dma-api expections of other clients like v4l. The consesus is that hw won't stop needing these tricks anytime soon. - Placement constraints for shared buffers won't be solved any other way than through something platform-specific like ion with platform-specific knowledge in userspace in something like gralloc. For general-purpose devices where this assumption would be painful for userspace (like servers) the consensus is that such devices will have proper MMUs where placement constraint handling is fairly irrelevant. Hence it is reasonable to destage ion as-is without changing the overall design to enable these use-cases and just fixing up a these few fairly minor things. Since there won't relly be an open-source userspace for ion (and hence drm maintainers won't take it) the proposal is to eventually move it to drivers/android/ion.[hc]. Laura would be ok with being maintainer once this is all done and ion is destaged. Note that Thiago is working on exposing the cpu cache flushing for cpu access from userspace through mmaps so this is alread in progress. Also adding him to the Cc: list. v2: Add ION_IOC_IMPORT to the list of ioctl that probably should go. Cc: Laura Abbott Cc: sumit.semwal@linaro.org Cc: laurent.pinchart@ideasonboard.com Cc: ghackmann@google.com Cc: robdclark@gmail.com Cc: david.brown@arm.com Cc: romlem@google.com Cc: Tiago Vignatti Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/TODO | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/android/TODO b/drivers/staging/android/TODO index 20288fc53946..8f3ac37bfe12 100644 --- a/drivers/staging/android/TODO +++ b/drivers/staging/android/TODO @@ -5,5 +5,25 @@ TODO: - add proper arch dependencies as needed - audit userspace interfaces to make sure they are sane + +ion/ + - Remove ION_IOC_SYNC: Flushing for devices should be purely a kernel internal + interface on top of dma-buf. flush_for_device needs to be added to dma-buf + first. + - Remove ION_IOC_CUSTOM: Atm used for cache flushing for cpu access in some + vendor trees. Should be replaced with an ioctl on the dma-buf to expose the + begin/end_cpu_access hooks to userspace. + - Clarify the tricks ion plays with explicitly managing coherency behind the + dma api's back (this is absolutely needed for high-perf gpu drivers): Add an + explicit coherency management mode to flush_for_device to be used by drivers + which want to manage caches themselves and which indicates whether cpu caches + need flushing. + - With those removed there's probably no use for ION_IOC_IMPORT anymore either + since ion would just be the central allocator for shared buffers. + - Add dt-binding to expose cma regions as ion heaps, with the rule that any + such cma regions must already be used by some device for dma. I.e. ion only + exposes existing cma regions and doesn't reserve unecessarily memory when + booting a system which doesn't use ion. + Please send patches to Greg Kroah-Hartman and Cc: Arve Hjønnevåg and Riley Andrews -- cgit v1.2.3 From d98229f0299d5d5a741873c5900159844b2b2de5 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Mon, 24 Aug 2015 11:11:49 -0400 Subject: staging/lustre: change Lustre URLs and mailing list Now that the lustre.org domain has been liberated we can again use that for the main website URL and mailing list. Also update the URL for userspace tools downloads and Git repo. Signed-off-by: Andreas Dilger Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/README.txt | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/lustre/README.txt b/drivers/staging/lustre/README.txt index cf0ca50ff83b..0676243eea9e 100644 --- a/drivers/staging/lustre/README.txt +++ b/drivers/staging/lustre/README.txt @@ -14,10 +14,8 @@ Unlike shared disk storage cluster filesystems (e.g. OCFS2, GFS, GPFS), Lustre has independent Metadata and Data servers that clients can access in parallel to maximize performance. -In order to use Lustre client you will need to download lustre client -tools from -https://downloads.hpdd.intel.com/public/lustre/latest-feature-release/ -the package name is lustre-client. +In order to use Lustre client you will need to download the "lustre-client" +package that contains the userspace tools from http://lustre.org/download/ You will need to install and configure your Lustre servers separately. @@ -76,12 +74,10 @@ Mount Options More Information ================ -You can get more information at -OpenSFS website: http://lustre.opensfs.org/about/ -Intel HPDD wiki: https://wiki.hpdd.intel.com +You can get more information at the Lustre website: http://wiki.lustre.org/ -Out of tree Lustre client and server code is available at: -http://git.whamcloud.com/fs/lustre-release.git +Source for the userspace tools and out-of-tree client and server code +is available at: http://git.hpdd.intel.com/fs/lustre-release.git Latest binary packages: -http://lustre.opensfs.org/download-lustre/ +http://lustre.org/download/ -- cgit v1.2.3 From cabb5b2a2866829177df2f1cee70f0dd42ee6ae0 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Tue, 25 Aug 2015 21:04:11 +0000 Subject: staging: fbtft: fix 9-bit SPI support detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the result of the setup function isn't adequate to check 9-bit SPI support, we better check bits_per_word_mask. Btw this change avoids a NULL pointer dereference with master drivers without a separate setup function. Signed-off-by: Stefan Wahren Acked-by: Noralf Trønnes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fbtft/fbtft-core.c | 10 +++------- drivers/staging/fbtft/flexfb.c | 11 ++++------- 2 files changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index 23392eb6799e..7f5fa3d1cab0 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -1436,15 +1436,11 @@ int fbtft_probe_common(struct fbtft_display *display, /* 9-bit SPI setup */ if (par->spi && display->buswidth == 9) { - par->spi->bits_per_word = 9; - ret = par->spi->master->setup(par->spi); - if (ret) { + if (par->spi->master->bits_per_word_mask & SPI_BPW_MASK(9)) { + par->spi->bits_per_word = 9; + } else { dev_warn(&par->spi->dev, "9-bit SPI not available, emulating using 8-bit.\n"); - par->spi->bits_per_word = 8; - ret = par->spi->master->setup(par->spi); - if (ret) - goto out_release; /* allocate buffer with room for dc bits */ par->extra = devm_kzalloc(par->info->device, par->txbuf.len + (par->txbuf.len / 8) + 8, diff --git a/drivers/staging/fbtft/flexfb.c b/drivers/staging/fbtft/flexfb.c index c763efc5de7d..3f380a0086c3 100644 --- a/drivers/staging/fbtft/flexfb.c +++ b/drivers/staging/fbtft/flexfb.c @@ -463,15 +463,12 @@ static int flexfb_probe_common(struct spi_device *sdev, } par->fbtftops.write_register = fbtft_write_reg8_bus9; par->fbtftops.write_vmem = fbtft_write_vmem16_bus9; - sdev->bits_per_word = 9; - ret = sdev->master->setup(sdev); - if (ret) { + if (par->spi->master->bits_per_word_mask + & SPI_BPW_MASK(9)) { + par->spi->bits_per_word = 9; + } else { dev_warn(dev, "9-bit SPI not available, emulating using 8-bit.\n"); - sdev->bits_per_word = 8; - ret = sdev->master->setup(sdev); - if (ret) - goto out_release; /* allocate buffer with room for dc bits */ par->extra = devm_kzalloc(par->info->device, par->txbuf.len + (par->txbuf.len / 8) + 8, -- cgit v1.2.3 From dd3afa57c515801f37071734f56be9035fdeaa8c Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Tue, 25 Aug 2015 21:04:12 +0000 Subject: staging: fbtft: replace master->setup() with spi_setup() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calling the setup of the SPI master directly causes a NULL pointer dereference with master drivers without a separate setup function. This problem is reproduceable on ARM MXS platform. So fix this issue by using spi_setup() instead. Signed-off-by: Stefan Wahren Acked-by: Noralf Trønnes Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fbtft/fb_uc1611.c | 2 +- drivers/staging/fbtft/fb_watterott.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/fbtft/fb_uc1611.c b/drivers/staging/fbtft/fb_uc1611.c index 32f3a9d921d6..5cafa50d1fac 100644 --- a/drivers/staging/fbtft/fb_uc1611.c +++ b/drivers/staging/fbtft/fb_uc1611.c @@ -76,7 +76,7 @@ static int init_display(struct fbtft_par *par) /* Set CS active high */ par->spi->mode |= SPI_CS_HIGH; - ret = par->spi->master->setup(par->spi); + ret = spi_setup(par->spi); if (ret) { dev_err(par->info->device, "Could not set SPI_CS_HIGH\n"); return ret; diff --git a/drivers/staging/fbtft/fb_watterott.c b/drivers/staging/fbtft/fb_watterott.c index 88fb2c0132d5..8eae6ef25846 100644 --- a/drivers/staging/fbtft/fb_watterott.c +++ b/drivers/staging/fbtft/fb_watterott.c @@ -169,7 +169,7 @@ static int init_display(struct fbtft_par *par) /* enable SPI interface by having CS and MOSI low during reset */ save_mode = par->spi->mode; par->spi->mode |= SPI_CS_HIGH; - ret = par->spi->master->setup(par->spi); /* set CS inactive low */ + ret = spi_setup(par->spi); /* set CS inactive low */ if (ret) { dev_err(par->info->device, "Could not set SPI_CS_HIGH\n"); return ret; @@ -180,7 +180,7 @@ static int init_display(struct fbtft_par *par) par->fbtftops.reset(par); mdelay(1000); par->spi->mode = save_mode; - ret = par->spi->master->setup(par->spi); + ret = spi_setup(par->spi); if (ret) { dev_err(par->info->device, "Could not restore SPI mode\n"); return ret; -- cgit v1.2.3 From 5b12100a53c11ef760e78c2899be8f1bf33812ca Mon Sep 17 00:00:00 2001 From: David Kershner Date: Fri, 4 Sep 2015 12:01:29 -0400 Subject: staging: unisys: unregister netdev when create debugfs fails Noticed we were not unregistering the netdevice if we failed to create the debugfs entries. This patch fixes that problem. Signed-off-by: David Kershner Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visornic/visornic_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index 8c9da7ea7845..bacf1af4e8d4 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -1924,13 +1924,16 @@ static int visornic_probe(struct visor_device *dev) "%s debugfs_create_dir %s failed\n", __func__, netdev->name); err = -ENOMEM; - goto cleanup_xmit_cmdrsp; + goto cleanup_register_netdev; } dev_info(&dev->device, "%s success netdev=%s\n", __func__, netdev->name); return 0; +cleanup_register_netdev: + unregister_netdev(netdev); + cleanup_napi_add: del_timer_sync(&devdata->irq_poll_timer); netif_napi_del(&devdata->napi); -- cgit v1.2.3 From f6b6a8ec9a3bcba8cc9a9c302b514cf3848e7d35 Mon Sep 17 00:00:00 2001 From: David Kershner Date: Fri, 4 Sep 2015 12:01:30 -0400 Subject: staging: unisys: visornic: Fix receive bytes statistics The receive byte statistics was wrong in /proc/net/dev. Move the collection of statistics after the proper amount of bytes has been calculated and make sure you add it to rx_bytes instead of just replacing it. Signed-off-by: David Kershner Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visornic/visornic_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index bacf1af4e8d4..7b08a8998a6d 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -1189,16 +1189,16 @@ visornic_rx(struct uiscmdrsp *cmdrsp) spin_lock_irqsave(&devdata->priv_lock, flags); atomic_dec(&devdata->num_rcvbuf_in_iovm); - /* update rcv stats - call it with priv_lock held */ - devdata->net_stats.rx_packets++; - devdata->net_stats.rx_bytes = skb->len; - /* set length to how much was ACTUALLY received - * NOTE: rcv_done_len includes actual length of data rcvd * including ethhdr */ skb->len = cmdrsp->net.rcv.rcv_done_len; + /* update rcv stats - call it with priv_lock held */ + devdata->net_stats.rx_packets++; + devdata->net_stats.rx_bytes += skb->len; + /* test enabled while holding lock */ if (!(devdata->enabled && devdata->enab_dis_acked)) { /* don't process it unless we're in enable mode and until -- cgit v1.2.3 From 418627ddc6d1ed50a3dfd2c8f938741b0cbcc1ed Mon Sep 17 00:00:00 2001 From: David Kershner Date: Fri, 4 Sep 2015 12:01:31 -0400 Subject: staging: unisys: visorbus: Unregister driver on error If there is an error in registering driver attributes, unregister the driver as well. Signed-off-by: David Kershner Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorbus_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 2309f5f2b238..7905ea920a4a 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -885,6 +885,8 @@ int visorbus_register_visor_driver(struct visor_driver *drv) if (rc < 0) return rc; rc = register_driver_attributes(drv); + if (rc < 0) + driver_unregister(&drv->driver); return rc; } EXPORT_SYMBOL_GPL(visorbus_register_visor_driver); -- cgit v1.2.3 From 6155a3cf11a6d4ed102ef5a30f655d4d2a38076b Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 4 Sep 2015 12:01:32 -0400 Subject: staging: unisys: stop device registration before visorbus registration In cases where visorbus is compiled directly into the kernel, if visorbus registration fails for any reason, it is still possible for other drivers to call visorbus_register_visor_driver(), which could cause an oops. Prevent this by saving the result of the call to create_bus() in a static variable, and return an error code when the bus hasn't been registered successfully. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorbus/visorbus_main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visorbus/visorbus_main.c b/drivers/staging/unisys/visorbus/visorbus_main.c index 7905ea920a4a..a272b48bab28 100644 --- a/drivers/staging/unisys/visorbus/visorbus_main.c +++ b/drivers/staging/unisys/visorbus/visorbus_main.c @@ -37,6 +37,8 @@ static int visorbus_debugref; #define POLLJIFFIES_TESTWORK 100 #define POLLJIFFIES_NORMALCHANNEL 10 +static int busreg_rc = -ENODEV; /* stores the result from bus registration */ + static int visorbus_uevent(struct device *xdev, struct kobj_uevent_env *env); static int visorbus_match(struct device *xdev, struct device_driver *xdrv); static void fix_vbus_dev_info(struct visor_device *visordev); @@ -863,6 +865,9 @@ int visorbus_register_visor_driver(struct visor_driver *drv) { int rc = 0; + if (busreg_rc < 0) + return -ENODEV; /*can't register on a nonexistent bus*/ + drv->driver.name = drv->name; drv->driver.bus = &visorbus_type; drv->driver.probe = visordriver_probe_device; @@ -1262,10 +1267,8 @@ remove_bus_instance(struct visor_device *dev) static int create_bus_type(void) { - int rc = 0; - - rc = bus_register(&visorbus_type); - return rc; + busreg_rc = bus_register(&visorbus_type); + return busreg_rc; } /** Remove the one-and-only one instance of the visor bus type (visorbus_type). -- cgit v1.2.3 From 8b5081c876bde9b1df5e96ee6990d5acd20c128b Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Fri, 4 Sep 2015 12:01:33 -0400 Subject: staging: unisys: visornic: handle error return from device registration There is no code to handle an error return in visornic, when it tries to register with visorbus. This patch handles an error return from visorbus_register_visor_driver() by dropping out of initialization. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visornic/visornic_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/unisys/visornic/visornic_main.c b/drivers/staging/unisys/visornic/visornic_main.c index 7b08a8998a6d..9d3c1e282062 100644 --- a/drivers/staging/unisys/visornic/visornic_main.c +++ b/drivers/staging/unisys/visornic/visornic_main.c @@ -2131,8 +2131,9 @@ static int visornic_init(void) if (!dev_num_pool) goto cleanup_workqueue; - visorbus_register_visor_driver(&visornic_driver); - return 0; + err = visorbus_register_visor_driver(&visornic_driver); + if (!err) + return 0; cleanup_workqueue: if (visornic_timeout_reset_workqueue) { -- cgit v1.2.3 From 19ab6bc5674a30fdb6a2436b068d19a3c17dc73e Mon Sep 17 00:00:00 2001 From: "Liu.Zhao" Date: Mon, 24 Aug 2015 08:36:12 -0700 Subject: USB: option: add ZTE PIDs This is intended to add ZTE device PIDs on kernel. Signed-off-by: Liu.Zhao Cc: stable [johan: sort the new entries ] Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 6d1941a2396a..6956c4f62216 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -278,6 +278,10 @@ static void option_instat_callback(struct urb *urb); #define ZTE_PRODUCT_MF622 0x0001 #define ZTE_PRODUCT_MF628 0x0015 #define ZTE_PRODUCT_MF626 0x0031 +#define ZTE_PRODUCT_ZM8620_X 0x0396 +#define ZTE_PRODUCT_ME3620_MBIM 0x0426 +#define ZTE_PRODUCT_ME3620_X 0x1432 +#define ZTE_PRODUCT_ME3620_L 0x1433 #define ZTE_PRODUCT_AC2726 0xfff1 #define ZTE_PRODUCT_MG880 0xfffd #define ZTE_PRODUCT_CDMA_TECH 0xfffe @@ -544,6 +548,18 @@ static const struct option_blacklist_info zte_mc2716_z_blacklist = { .sendsetup = BIT(1) | BIT(2) | BIT(3), }; +static const struct option_blacklist_info zte_me3620_mbim_blacklist = { + .reserved = BIT(2) | BIT(3) | BIT(4), +}; + +static const struct option_blacklist_info zte_me3620_xl_blacklist = { + .reserved = BIT(3) | BIT(4) | BIT(5), +}; + +static const struct option_blacklist_info zte_zm8620_x_blacklist = { + .reserved = BIT(3) | BIT(4) | BIT(5), +}; + static const struct option_blacklist_info huawei_cdc12_blacklist = { .reserved = BIT(1) | BIT(2), }; @@ -1591,6 +1607,14 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_L), + .driver_info = (kernel_ulong_t)&zte_me3620_xl_blacklist }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_MBIM), + .driver_info = (kernel_ulong_t)&zte_me3620_mbim_blacklist }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_X), + .driver_info = (kernel_ulong_t)&zte_me3620_xl_blacklist }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ZM8620_X), + .driver_info = (kernel_ulong_t)&zte_zm8620_x_blacklist }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, -- cgit v1.2.3 From e4c1b1ba7f663fd77204201eef83baf58e2e5777 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Fri, 21 Aug 2015 11:01:29 +0200 Subject: usb: gadget: fix possible regression introduced with ep->claimed This patch fixes possible regression introduced by patch reworking endpoint claiming mechanism. It restores setring ep->driver_data to NULL in usb_ep_autoconfig_reset(), which was removed by patch commit cc476b42a39d. Fixes: cc476b42a39d ("usb: gadget: encapsulate endpoint claiming mechanism") Reported-by: Felipe Balbi Signed-off-by: Robert Baldyga Signed-off-by: Felipe Balbi --- drivers/usb/gadget/epautoconf.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 978435a51038..6399c106a3a5 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -186,6 +186,7 @@ void usb_ep_autoconfig_reset (struct usb_gadget *gadget) list_for_each_entry (ep, &gadget->ep_list, ep_list) { ep->claimed = false; + ep->driver_data = NULL; } gadget->in_epnum = 0; gadget->out_epnum = 0; -- cgit v1.2.3 From e2ae0692bf6f71c8b841889b655d0dc08413e4e3 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 25 Aug 2015 12:07:45 -0500 Subject: usb: dwc3: omap: enable irqs lately If we enable IRQs before requesting our extcon device, we might fall into a situation where and IRQ fires before we're ready to handle it. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index a5a1b7c45743..22e9606d8e08 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -514,8 +514,6 @@ static int dwc3_omap_probe(struct platform_device *pdev) goto err1; } - dwc3_omap_enable_irqs(omap); - ret = dwc3_omap_extcon_register(omap); if (ret < 0) goto err2; @@ -526,6 +524,8 @@ static int dwc3_omap_probe(struct platform_device *pdev) goto err3; } + dwc3_omap_enable_irqs(omap); + return 0; err3: -- cgit v1.2.3 From 40af177efc9385af15c49a40976f71e58e6af418 Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Mon, 14 Sep 2015 09:12:34 -0500 Subject: usb: musb: ensure in peripheral mode when checking session The change ensures otg is not in a A- state when checking for VBUS in peripheral mode. musb_start() where VBUS checking is in can be called in many situations. One example is in babble recovery routine, in which otg is transitioning from A-HOST to A-WAIT-BCON, but VBUS discharge takes time, so musb->is_active could be set to 1 due to this improper checking, then it causes musb_bus_suspend() failed which leads to warning log message flooding. Signed-off-by: Bin Liu Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 514a6cdaeff6..d105c6dcbbec 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1051,6 +1051,7 @@ void musb_start(struct musb *musb) * (c) peripheral initiates, using SRP */ if (musb->port_mode != MUSB_PORT_MODE_HOST && + musb->xceiv->otg->state != OTG_STATE_A_WAIT_BCON && (devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS) { musb->is_active = 1; } else { -- cgit v1.2.3 From 88ccdbd5fc59ce8c69261a20746ca2533be7e358 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 10 Sep 2015 10:37:39 -0700 Subject: usb: phy: fix phy-qcom-8x16-usb build Fix build errors that happen when USB_QCOM_8X16_PHY=y and EXTCON=m: drivers/built-in.o: In function `phy_8x16_init': phy-qcom-8x16-usb.c:(.text+0x86ef4): undefined reference to `extcon_get_cable_state' drivers/built-in.o: In function `phy_8x16_probe': phy-qcom-8x16-usb.c:(.text+0x870bf): undefined reference to `extcon_get_edev_by_phandle' phy-qcom-8x16-usb.c:(.text+0x87133): undefined reference to `extcon_register_interest' phy-qcom-8x16-usb.c:(.text+0x87151): undefined reference to `extcon_unregister_interest' drivers/built-in.o: In function `phy_8x16_remove': phy-qcom-8x16-usb.c:(.text+0x872ec): undefined reference to `extcon_unregister_interest' Signed-off-by: Randy Dunlap Cc: Felipe Balbi Signed-off-by: Felipe Balbi --- drivers/usb/phy/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 7d3beee2a587..173132416170 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -155,7 +155,7 @@ config USB_MSM_OTG config USB_QCOM_8X16_PHY tristate "Qualcomm APQ8016/MSM8916 on-chip USB PHY controller support" depends on ARCH_QCOM || COMPILE_TEST - depends on RESET_CONTROLLER + depends on RESET_CONTROLLER && EXTCON select USB_PHY select USB_ULPI_VIEWPORT help -- cgit v1.2.3 From 6527cc27761a124de8c08e6488ce17fdcc74dbba Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Sun, 6 Sep 2015 01:11:51 +0300 Subject: usb: gadget: amd5536udc: fix error handling in udc_pci_probe() If a failure happens early in udc_pci_probe(), error handling code just kfree(dev) and returns. The patch adds proper resource deallocations in udc_pci_probe() itself, since udc_pci_remove() is not suitabe to be called so early in initialization process. By the way, iounmap(dev->regs) is replaced by iounmap(dev->virt_addr) in udc_pci_remove() for clarity. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/amd5536udc.c | 43 +++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/amd5536udc.c b/drivers/usb/gadget/udc/amd5536udc.c index fdacddb18c00..175ca93fe5e2 100644 --- a/drivers/usb/gadget/udc/amd5536udc.c +++ b/drivers/usb/gadget/udc/amd5536udc.c @@ -3138,8 +3138,8 @@ static void udc_pci_remove(struct pci_dev *pdev) writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg); if (dev->irq_registered) free_irq(pdev->irq, dev); - if (dev->regs) - iounmap(dev->regs); + if (dev->virt_addr) + iounmap(dev->virt_addr); if (dev->mem_region) release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); @@ -3226,17 +3226,13 @@ static int udc_pci_probe( /* init */ dev = kzalloc(sizeof(struct udc), GFP_KERNEL); - if (!dev) { - retval = -ENOMEM; - goto finished; - } + if (!dev) + return -ENOMEM; /* pci setup */ if (pci_enable_device(pdev) < 0) { - kfree(dev); - dev = NULL; retval = -ENODEV; - goto finished; + goto err_pcidev; } dev->active = 1; @@ -3246,28 +3242,22 @@ static int udc_pci_probe( if (!request_mem_region(resource, len, name)) { dev_dbg(&pdev->dev, "pci device used already\n"); - kfree(dev); - dev = NULL; retval = -EBUSY; - goto finished; + goto err_memreg; } dev->mem_region = 1; dev->virt_addr = ioremap_nocache(resource, len); if (dev->virt_addr == NULL) { dev_dbg(&pdev->dev, "start address cannot be mapped\n"); - kfree(dev); - dev = NULL; retval = -EFAULT; - goto finished; + goto err_ioremap; } if (!pdev->irq) { dev_err(&pdev->dev, "irq not set\n"); - kfree(dev); - dev = NULL; retval = -ENODEV; - goto finished; + goto err_irq; } spin_lock_init(&dev->lock); @@ -3283,10 +3273,8 @@ static int udc_pci_probe( if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) { dev_dbg(&pdev->dev, "request_irq(%d) fail\n", pdev->irq); - kfree(dev); - dev = NULL; retval = -EBUSY; - goto finished; + goto err_irq; } dev->irq_registered = 1; @@ -3314,8 +3302,17 @@ static int udc_pci_probe( return 0; finished: - if (dev) - udc_pci_remove(pdev); + udc_pci_remove(pdev); + return retval; + +err_irq: + iounmap(dev->virt_addr); +err_ioremap: + release_mem_region(resource, len); +err_memreg: + pci_disable_device(pdev); +err_pcidev: + kfree(dev); return retval; } -- cgit v1.2.3 From 6fc6f4b87cb32fcd0bf5e5bce434301958a3b624 Mon Sep 17 00:00:00 2001 From: Pascal Huerst Date: Thu, 3 Sep 2015 10:50:58 +0200 Subject: usb: musb: Disable interrupts on suspend, enable them on resume In certain situations, an interrupt triggers on resume, before musb_start() has been called. This has been observed to cause enumeration issues after suspend/resume cycles with AM335x. Signed-off-by: Pascal Huerst Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index d105c6dcbbec..4a518ff12310 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2449,6 +2449,9 @@ static int musb_suspend(struct device *dev) struct musb *musb = dev_to_musb(dev); unsigned long flags; + musb_platform_disable(musb); + musb_generic_disable(musb); + spin_lock_irqsave(&musb->lock, flags); if (is_peripheral_active(musb)) { @@ -2502,6 +2505,9 @@ static int musb_resume(struct device *dev) pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); + + musb_start(musb); + return 0; } -- cgit v1.2.3 From 523d5daf86e5e8b540bdc91e090197b5665f0519 Mon Sep 17 00:00:00 2001 From: Luis de Bethencourt Date: Thu, 27 Aug 2015 17:45:37 +0200 Subject: usb: musb: ux500: Fix module autoload for OF platform driver This platform driver has a OF device ID table but the OF module alias information is not created so module autoloading won't work. Signed-off-by: Luis de Bethencourt Signed-off-by: Felipe Balbi --- drivers/usb/musb/ux500.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index 39168fe9b406..b2685e75a683 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -379,6 +379,8 @@ static const struct of_device_id ux500_match[] = { {} }; +MODULE_DEVICE_TABLE(of, ux500_match); + static struct platform_driver ux500_driver = { .probe = ux500_probe, .remove = ux500_remove, -- cgit v1.2.3 From 762982db33b23029e98c844611e2e8beeb75bc0d Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Thu, 13 Aug 2015 13:28:42 +0300 Subject: usb: phy: phy-generic: Fix reset behaviour on legacy boot The gpio-desc migration done in v4.0 caused a regression with legacy boots due to reversed reset logic. e.g. omap3-beagle USB host breaks on legacy boot. Request the reset GPIO with GPIOF_ACTIVE_LOW flag so that it matches the driver logic and pin behaviour. Fixes: e9f2cefb0cdc ("usb: phy: generic: migrate to gpio_desc") Cc: # 4.0+ Tested-by: Fabio Estevam Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-generic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index ec6ecd03269c..5320cb8642cb 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -232,7 +232,8 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop, clk_rate = pdata->clk_rate; needs_vcc = pdata->needs_vcc; if (gpio_is_valid(pdata->gpio_reset)) { - err = devm_gpio_request_one(dev, pdata->gpio_reset, 0, + err = devm_gpio_request_one(dev, pdata->gpio_reset, + GPIOF_ACTIVE_LOW, dev_name(dev)); if (!err) nop->gpiod_reset = -- cgit v1.2.3 From 56ffa1d154c7e12af16273f0cdc42690dd05caf5 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Mon, 24 Aug 2015 14:10:07 +0800 Subject: usb: chipidea: udc: using the correct stall implementation According to spec, there are functional and protocol stalls. For functional stall, it is for bulk and interrupt endpoints, below are cases for it: - Host sends SET_FEATURE request for Set-Halt, the udc driver needs to set stall, and return true unconditionally. - The gadget driver may call usb_ep_set_halt to stall certain endpoints, if there is a transfer in pending, the udc driver should not set stall, and return -EAGAIN accordingly. These two kinds of stall need to be cleared by host using CLEAR_FEATURE request (Clear-Halt). For protocol stall, it is for control endpoint, this stall will be set if the control request has failed. This stall will be cleared by next setup request (hardware will do it). It fixed usbtest (drivers/usb/misc/usbtest.c) Test 13 "set/clear halt" test failure, meanwhile, this change has been verified by USB2 CV Compliance Test and MSC Tests. Cc: #3.10+ Cc: Alan Stern Cc: Felipe Balbi Signed-off-by: Peter Chen --- drivers/usb/chipidea/udc.c | 84 ++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index a637da25dda0..8223fe73ea85 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -656,6 +656,44 @@ __acquires(hwep->lock) return 0; } +static int _ep_set_halt(struct usb_ep *ep, int value, bool check_transfer) +{ + struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep); + int direction, retval = 0; + unsigned long flags; + + if (ep == NULL || hwep->ep.desc == NULL) + return -EINVAL; + + if (usb_endpoint_xfer_isoc(hwep->ep.desc)) + return -EOPNOTSUPP; + + spin_lock_irqsave(hwep->lock, flags); + + if (value && hwep->dir == TX && check_transfer && + !list_empty(&hwep->qh.queue) && + !usb_endpoint_xfer_control(hwep->ep.desc)) { + spin_unlock_irqrestore(hwep->lock, flags); + return -EAGAIN; + } + + direction = hwep->dir; + do { + retval |= hw_ep_set_halt(hwep->ci, hwep->num, hwep->dir, value); + + if (!value) + hwep->wedge = 0; + + if (hwep->type == USB_ENDPOINT_XFER_CONTROL) + hwep->dir = (hwep->dir == TX) ? RX : TX; + + } while (hwep->dir != direction); + + spin_unlock_irqrestore(hwep->lock, flags); + return retval; +} + + /** * _gadget_stop_activity: stops all USB activity, flushes & disables all endpts * @gadget: gadget @@ -1051,7 +1089,7 @@ __acquires(ci->lock) num += ci->hw_ep_max / 2; spin_unlock(&ci->lock); - err = usb_ep_set_halt(&ci->ci_hw_ep[num].ep); + err = _ep_set_halt(&ci->ci_hw_ep[num].ep, 1, false); spin_lock(&ci->lock); if (!err) isr_setup_status_phase(ci); @@ -1117,8 +1155,8 @@ delegate: if (err < 0) { spin_unlock(&ci->lock); - if (usb_ep_set_halt(&hwep->ep)) - dev_err(ci->dev, "error: ep_set_halt\n"); + if (_ep_set_halt(&hwep->ep, 1, false)) + dev_err(ci->dev, "error: _ep_set_halt\n"); spin_lock(&ci->lock); } } @@ -1149,9 +1187,9 @@ __acquires(ci->lock) err = isr_setup_status_phase(ci); if (err < 0) { spin_unlock(&ci->lock); - if (usb_ep_set_halt(&hwep->ep)) + if (_ep_set_halt(&hwep->ep, 1, false)) dev_err(ci->dev, - "error: ep_set_halt\n"); + "error: _ep_set_halt\n"); spin_lock(&ci->lock); } } @@ -1397,41 +1435,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) */ static int ep_set_halt(struct usb_ep *ep, int value) { - struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep); - int direction, retval = 0; - unsigned long flags; - - if (ep == NULL || hwep->ep.desc == NULL) - return -EINVAL; - - if (usb_endpoint_xfer_isoc(hwep->ep.desc)) - return -EOPNOTSUPP; - - spin_lock_irqsave(hwep->lock, flags); - -#ifndef STALL_IN - /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */ - if (value && hwep->type == USB_ENDPOINT_XFER_BULK && hwep->dir == TX && - !list_empty(&hwep->qh.queue)) { - spin_unlock_irqrestore(hwep->lock, flags); - return -EAGAIN; - } -#endif - - direction = hwep->dir; - do { - retval |= hw_ep_set_halt(hwep->ci, hwep->num, hwep->dir, value); - - if (!value) - hwep->wedge = 0; - - if (hwep->type == USB_ENDPOINT_XFER_CONTROL) - hwep->dir = (hwep->dir == TX) ? RX : TX; - - } while (hwep->dir != direction); - - spin_unlock_irqrestore(hwep->lock, flags); - return retval; + return _ep_set_halt(ep, value, true); } /** -- cgit v1.2.3 From 84bc70f94d81f1d3107dbcdafc1b193169e82131 Mon Sep 17 00:00:00 2001 From: Nathan Sullivan Date: Mon, 31 Aug 2015 09:49:51 -0500 Subject: usb: chipidea: add xilinx zynq platform data Due to having hardware tx buffers less than 512 bytes in size, streaming must be enabled on the Zynq for the udc to work at all. Add platform data specific to the Zynq udc, which does not set the CI_HDRC_DISABLE_STREAMING flag. Based on a patch by the same name from the Xilinx vendor tree. Signed-off-by: Nathan Sullivan Signed-off-by: Peter Chen --- drivers/usb/chipidea/ci_hdrc_usb2.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/chipidea/ci_hdrc_usb2.c b/drivers/usb/chipidea/ci_hdrc_usb2.c index 9eae1a16cef9..4456d2cf80ff 100644 --- a/drivers/usb/chipidea/ci_hdrc_usb2.c +++ b/drivers/usb/chipidea/ci_hdrc_usb2.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -30,18 +31,36 @@ static const struct ci_hdrc_platform_data ci_default_pdata = { .flags = CI_HDRC_DISABLE_STREAMING, }; +static struct ci_hdrc_platform_data ci_zynq_pdata = { + .capoffset = DEF_CAPOFFSET, +}; + +static const struct of_device_id ci_hdrc_usb2_of_match[] = { + { .compatible = "chipidea,usb2"}, + { .compatible = "xlnx,zynq-usb-2.20a", .data = &ci_zynq_pdata}, + { } +}; +MODULE_DEVICE_TABLE(of, ci_hdrc_usb2_of_match); + static int ci_hdrc_usb2_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct ci_hdrc_usb2_priv *priv; struct ci_hdrc_platform_data *ci_pdata = dev_get_platdata(dev); int ret; + const struct of_device_id *match; if (!ci_pdata) { ci_pdata = devm_kmalloc(dev, sizeof(*ci_pdata), GFP_KERNEL); *ci_pdata = ci_default_pdata; /* struct copy */ } + match = of_match_device(ci_hdrc_usb2_of_match, &pdev->dev); + if (match && match->data) { + /* struct copy */ + *ci_pdata = *(struct ci_hdrc_platform_data *)match->data; + } + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -96,12 +115,6 @@ static int ci_hdrc_usb2_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id ci_hdrc_usb2_of_match[] = { - { .compatible = "chipidea,usb2" }, - { } -}; -MODULE_DEVICE_TABLE(of, ci_hdrc_usb2_of_match); - static struct platform_driver ci_hdrc_usb2_driver = { .probe = ci_hdrc_usb2_probe, .remove = ci_hdrc_usb2_remove, -- cgit v1.2.3 From a4c15cd957cbd728f685645de7a150df5912591a Mon Sep 17 00:00:00 2001 From: Jenny Derzhavetz Date: Sun, 6 Sep 2015 14:52:20 +0300 Subject: iser-target: remove command with state ISTATE_REMOVE As documented in iscsit_sequence_cmd: /* * Existing callers for iscsit_sequence_cmd() will silently * ignore commands with CMDSN_LOWER_THAN_EXP, so force this * return for CMDSN_MAXCMDSN_OVERRUN as well.. */ We need to silently finish a command when it's in ISTATE_REMOVE. This fixes an teardown hang we were seeing where a mis-behaved initiator (triggered by allocation error injections) sent us a cmdsn which was lower than expected. Signed-off-by: Jenny Derzhavetz Signed-off-by: Sagi Grimberg Cc: # v3.10+ Signed-off-by: Nicholas Bellinger --- drivers/infiniband/ulp/isert/ib_isert.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 403bd29443b8..443ef33fbf30 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -2999,9 +2999,16 @@ isert_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd, bool recovery) static int isert_immediate_queue(struct iscsi_conn *conn, struct iscsi_cmd *cmd, int state) { - int ret; + struct isert_cmd *isert_cmd = iscsit_priv_cmd(cmd); + int ret = 0; switch (state) { + case ISTATE_REMOVE: + spin_lock_bh(&conn->cmd_lock); + list_del_init(&cmd->i_conn_node); + spin_unlock_bh(&conn->cmd_lock); + isert_put_cmd(isert_cmd, true); + break; case ISTATE_SEND_NOPIN_WANT_RESPONSE: ret = isert_put_nopin(cmd, conn, false); break; -- cgit v1.2.3 From 3e03c4b01da3e6a5f3081eb0aa252490fe83e352 Mon Sep 17 00:00:00 2001 From: Jenny Derzhavetz Date: Sun, 6 Sep 2015 14:52:21 +0300 Subject: iser-target: Put the reference on commands waiting for unsol data The iscsi target core teardown sequence calls wait_conn for all active commands to finish gracefully by: - move the queue-pair to error state - drain all the completions - wait for the core to finish handling all session commands However, when tearing down a session while there are sequenced commands that are still waiting for unsolicited data outs, we can block forever as these are missing an extra reference put. We basically need the equivalent of iscsit_free_queue_reqs_for_conn() which is called after wait_conn has returned. Address this by an explicit walk on conn_cmd_list and put the extra reference. Signed-off-by: Jenny Derzhavetz Signed-off-by: Sagi Grimberg Cc: # v3.10+ Signed-off-by: Nicholas Bellinger --- drivers/infiniband/ulp/isert/ib_isert.c | 38 ++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index 443ef33fbf30..c8749a9e1ccd 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -3352,6 +3352,41 @@ isert_wait4flush(struct isert_conn *isert_conn) wait_for_completion(&isert_conn->wait_comp_err); } +/** + * isert_put_unsol_pending_cmds() - Drop commands waiting for + * unsolicitate dataout + * @conn: iscsi connection + * + * We might still have commands that are waiting for unsolicited + * dataouts messages. We must put the extra reference on those + * before blocking on the target_wait_for_session_cmds + */ +static void +isert_put_unsol_pending_cmds(struct iscsi_conn *conn) +{ + struct iscsi_cmd *cmd, *tmp; + static LIST_HEAD(drop_cmd_list); + + spin_lock_bh(&conn->cmd_lock); + list_for_each_entry_safe(cmd, tmp, &conn->conn_cmd_list, i_conn_node) { + if ((cmd->cmd_flags & ICF_NON_IMMEDIATE_UNSOLICITED_DATA) && + (cmd->write_data_done < conn->sess->sess_ops->FirstBurstLength) && + (cmd->write_data_done < cmd->se_cmd.data_length)) + list_move_tail(&cmd->i_conn_node, &drop_cmd_list); + } + spin_unlock_bh(&conn->cmd_lock); + + list_for_each_entry_safe(cmd, tmp, &drop_cmd_list, i_conn_node) { + list_del_init(&cmd->i_conn_node); + if (cmd->i_state != ISTATE_REMOVE) { + struct isert_cmd *isert_cmd = iscsit_priv_cmd(cmd); + + isert_info("conn %p dropping cmd %p\n", conn, cmd); + isert_put_cmd(isert_cmd, true); + } + } +} + static void isert_wait_conn(struct iscsi_conn *conn) { struct isert_conn *isert_conn = conn->context; @@ -3370,8 +3405,9 @@ static void isert_wait_conn(struct iscsi_conn *conn) isert_conn_terminate(isert_conn); mutex_unlock(&isert_conn->mutex); - isert_wait4cmds(conn); isert_wait4flush(isert_conn); + isert_put_unsol_pending_cmds(conn); + isert_wait4cmds(conn); isert_wait4logout(isert_conn); queue_work(isert_release_wq, &isert_conn->release_work); -- cgit v1.2.3 From f27dfa1f0eb91494577a395e6b8a9aac2832e9cf Mon Sep 17 00:00:00 2001 From: Jenny Derzhavetz Date: Sun, 6 Sep 2015 14:52:22 +0300 Subject: iser-target: Remove unused variables Signed-off-by: Jenny Derzhavetz Signed-off-by: Sagi Grimberg Signed-off-by: Nicholas Bellinger --- drivers/infiniband/ulp/isert/ib_isert.c | 1 - drivers/infiniband/ulp/isert/ib_isert.h | 5 ----- 2 files changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index c8749a9e1ccd..97475b2eecb7 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -3116,7 +3116,6 @@ isert_setup_np(struct iscsi_np *np, sema_init(&isert_np->np_sem, 0); mutex_init(&isert_np->np_accept_mutex); INIT_LIST_HEAD(&isert_np->np_accept_list); - init_completion(&isert_np->np_login_comp); isert_np->np = np; /* diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h index 6a04ba3c0f72..0480ab89ea40 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.h +++ b/drivers/infiniband/ulp/isert/ib_isert.h @@ -113,7 +113,6 @@ enum { }; struct isert_rdma_wr { - struct list_head wr_list; struct isert_cmd *isert_cmd; enum iser_ib_op_code iser_ib_op; struct ib_sge *ib_sge; @@ -134,9 +133,6 @@ struct isert_cmd { uint64_t write_va; u64 pdu_buf_dma; u32 pdu_buf_len; - u32 read_va_off; - u32 write_va_off; - u32 rdma_wr_num; struct isert_conn *conn; struct iscsi_cmd *iscsi_cmd; struct iser_tx_desc tx_desc; @@ -226,5 +222,4 @@ struct isert_np { struct rdma_cm_id *np_cm_id; struct mutex np_accept_mutex; struct list_head np_accept_list; - struct completion np_login_comp; }; -- cgit v1.2.3 From ed8cb0a4378c0e7035db047987fe0e7309020ab5 Mon Sep 17 00:00:00 2001 From: Jenny Derzhavetz Date: Sun, 6 Sep 2015 14:52:23 +0300