From badc0e42604c4465facd81d2323e98b3b1eb9188 Mon Sep 17 00:00:00 2001 From: AndrĂ© Fabian Silva Delgado Date: Tue, 27 Oct 2015 13:37:40 -0300 Subject: Linux-libre 4.2.4-gnu --- drivers/base/cacheinfo.c | 10 ++- drivers/base/property.c | 5 +- drivers/base/regmap/regmap-debugfs.c | 5 +- drivers/block/xen-blkback/xenbus.c | 38 +++++---- drivers/clk/samsung/clk-cpu.c | 10 +-- drivers/clk/ti/clk-3xxx.c | 2 +- drivers/clk/ti/clk-7xx.c | 18 +--- drivers/cpufreq/acpi-cpufreq.c | 3 + drivers/cpufreq/cpufreq-dt.c | 3 +- drivers/crypto/marvell/cesa.h | 27 ++++++ drivers/crypto/marvell/cipher.c | 7 +- drivers/crypto/marvell/hash.c | 8 +- drivers/dma/at_xdmac.c | 20 +++-- drivers/dma/dw/core.c | 4 +- drivers/dma/pxa_dma.c | 1 + drivers/extcon/extcon.c | 10 +-- drivers/firmware/efi/libstub/arm-stub.c | 88 ++++++++++++++++---- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 68 +++++++++------ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 2 +- drivers/gpu/drm/amd/amdgpu/atombios_encoders.c | 3 +- drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 4 +- drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/vi.c | 3 +- drivers/gpu/drm/drm_dp_mst_topology.c | 41 +++++++--- drivers/gpu/drm/drm_lock.c | 6 ++ drivers/gpu/drm/i915/intel_bios.c | 12 ++- drivers/gpu/drm/qxl/qxl_display.c | 14 ++-- drivers/gpu/drm/radeon/atombios_encoders.c | 8 +- drivers/hv/hv_utils_transport.c | 2 +- drivers/hwmon/nct6775.c | 16 ++-- drivers/infiniband/ulp/isert/ib_isert.c | 47 ++++++++++- drivers/irqchip/irq-atmel-aic5.c | 24 ++++-- drivers/irqchip/irq-gic-v3-its.c | 6 +- drivers/leds/Kconfig | 2 +- drivers/leds/led-class.c | 7 +- drivers/macintosh/windfarm_core.c | 2 +- drivers/md/bitmap.c | 3 +- drivers/md/dm-cache-policy-cleaner.c | 2 +- drivers/md/dm-crypt.c | 17 +++- drivers/md/dm-raid.c | 3 +- drivers/md/dm-thin.c | 4 + drivers/md/dm.c | 6 +- drivers/md/raid0.c | 75 +++++++++-------- drivers/mmc/core/core.c | 6 +- drivers/mmc/core/host.c | 4 +- drivers/mmc/host/dw_mmc.c | 109 ++++++++++++++++--------- drivers/mmc/host/sdhci-pxav3.c | 6 +- drivers/mtd/nand/pxa3xx_nand.c | 3 + drivers/mtd/nand/sunxi_nand.c | 27 +++--- drivers/mtd/ubi/io.c | 5 ++ drivers/mtd/ubi/vtbl.c | 1 + drivers/mtd/ubi/wl.c | 1 + drivers/net/ethernet/intel/igb/igb_main.c | 2 +- drivers/net/ethernet/via/Kconfig | 2 +- drivers/net/wireless/ath/ath10k/htc.c | 4 +- drivers/net/wireless/ath/ath10k/htt_tx.c | 8 +- drivers/net/wireless/ath/ath10k/mac.c | 85 +++++++++++-------- drivers/net/wireless/ath/ath10k/mac.h | 6 +- drivers/net/wireless/ath/ath10k/pci.c | 8 +- drivers/net/wireless/ath/ath10k/wmi-tlv.c | 34 ++++++-- drivers/net/wireless/ath/ath10k/wmi.c | 1 + drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 8 +- drivers/net/wireless/rsi/rsi_91x_usb_ops.c | 8 +- drivers/net/xen-netfront.c | 3 +- drivers/nvdimm/pmem.c | 2 + drivers/pci/access.c | 27 +----- drivers/pci/bus.c | 2 + drivers/pci/quirks.c | 20 ++++- drivers/pcmcia/sa1100_generic.c | 1 - drivers/pcmcia/sa11xx_base.c | 3 +- drivers/platform/x86/toshiba_acpi.c | 8 +- drivers/power/avs/Kconfig | 2 +- drivers/regulator/axp20x-regulator.c | 4 +- drivers/regulator/core.c | 20 +++-- drivers/scsi/3w-9xxx.c | 28 +++++-- drivers/scsi/hpsa.c | 15 ++-- drivers/scsi/ipr.c | 2 +- drivers/scsi/scsi_error.c | 11 ++- drivers/spi/spi-bcm2835.c | 6 +- drivers/spi/spi-pxa2xx.c | 4 + drivers/spi/spi-xtensa-xtfpga.c | 4 +- drivers/spi/spi.c | 3 +- drivers/spi/spidev.c | 3 +- drivers/staging/android/ion/ion.c | 6 +- drivers/staging/speakup/fakekey.c | 1 + drivers/target/iscsi/iscsi_target.c | 33 ++++---- drivers/target/iscsi/iscsi_target.h | 2 +- drivers/target/iscsi/iscsi_target_configfs.c | 14 ++-- drivers/target/iscsi/iscsi_target_login.c | 8 +- drivers/target/iscsi/iscsi_target_parameters.c | 5 +- drivers/target/iscsi/iscsi_target_tpg.c | 15 ++-- drivers/target/iscsi/iscsi_target_tpg.h | 2 +- drivers/target/target_core_device.c | 5 +- drivers/target/target_core_pr.c | 91 +++++++++++++++------ drivers/target/target_core_xcopy.c | 6 +- drivers/thermal/cpu_cooling.c | 52 +++++++----- drivers/tty/n_tty.c | 15 ++-- drivers/tty/serial/8250/8250_core.c | 8 ++ drivers/tty/serial/atmel_serial.c | 2 +- drivers/tty/tty_io.c | 31 ++++++- drivers/usb/chipidea/ci_hdrc_imx.c | 2 +- drivers/usb/chipidea/udc.c | 84 ++++++++++--------- drivers/usb/core/config.c | 5 +- drivers/usb/core/quirks.c | 13 +++ drivers/usb/host/xhci-mem.c | 17 ++-- drivers/usb/host/xhci-pci.c | 90 ++++++++++---------- drivers/usb/host/xhci-ring.c | 79 ++++++++++++++---- drivers/usb/host/xhci.c | 29 ++++--- drivers/usb/misc/chaoskey.c | 2 +- drivers/usb/musb/musb_cppi41.c | 6 +- drivers/usb/musb/musb_dsps.c | 7 +- drivers/usb/phy/phy-generic.c | 3 +- drivers/usb/serial/option.c | 24 ++++++ drivers/usb/serial/whiteheat.c | 31 +++++++ drivers/watchdog/imgpdc_wdt.c | 1 + drivers/watchdog/sunxi_wdt.c | 2 +- drivers/xen/preempt.c | 2 +- 119 files changed, 1195 insertions(+), 640 deletions(-) (limited to 'drivers') diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index 764280a91..e9fd32e91 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -148,7 +148,11 @@ static void cache_shared_cpu_map_remove(unsigned int cpu) if (sibling == cpu) /* skip itself */ continue; + sib_cpu_ci = get_cpu_cacheinfo(sibling); + if (!sib_cpu_ci->info_list) + continue; + sib_leaf = sib_cpu_ci->info_list + index; cpumask_clear_cpu(cpu, &sib_leaf->shared_cpu_map); cpumask_clear_cpu(sibling, &this_leaf->shared_cpu_map); @@ -159,6 +163,9 @@ static void cache_shared_cpu_map_remove(unsigned int cpu) static void free_cache_attributes(unsigned int cpu) { + if (!per_cpu_cacheinfo(cpu)) + return; + cache_shared_cpu_map_remove(cpu); kfree(per_cpu_cacheinfo(cpu)); @@ -514,8 +521,7 @@ static int cacheinfo_cpu_callback(struct notifier_block *nfb, break; case CPU_DEAD: cache_remove_dev(cpu); - if (per_cpu_cacheinfo(cpu)) - free_cache_attributes(cpu); + free_cache_attributes(cpu); break; } return notifier_from_errno(rc); diff --git a/drivers/base/property.c b/drivers/base/property.c index f3f6d167f..37a7bb7b2 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -27,9 +27,10 @@ */ void device_add_property_set(struct device *dev, struct property_set *pset) { - if (pset) - pset->fwnode.type = FWNODE_PDATA; + if (!pset) + return; + pset->fwnode.type = FWNODE_PDATA; set_secondary_fwnode(dev, &pset->fwnode); } EXPORT_SYMBOL_GPL(device_add_property_set); diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 5799a0b9e..c8941f39c 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -32,8 +32,7 @@ static DEFINE_MUTEX(regmap_debugfs_early_lock); /* Calculate the length of a fixed format */ static size_t regmap_calc_reg_len(int max_val, char *buf, size_t buf_size) { - snprintf(buf, buf_size, "%x", max_val); - return strlen(buf); + return snprintf(NULL, 0, "%x", max_val); } static ssize_t regmap_name_read_file(struct file *file, @@ -432,7 +431,7 @@ static ssize_t regmap_access_read_file(struct file *file, /* If we're in the region the user is trying to read */ if (p >= *ppos) { /* ...but not beyond it */ - if (buf_pos >= count - 1 - tot_len) + if (buf_pos + tot_len + 1 >= count) break; /* Format the register */ diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index deb3f0017..767657565 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -212,6 +212,9 @@ static int xen_blkif_map(struct xen_blkif *blkif, grant_ref_t *gref, static int xen_blkif_disconnect(struct xen_blkif *blkif) { + struct pending_req *req, *n; + int i = 0, j; + if (blkif->xenblkd) { kthread_stop(blkif->xenblkd); wake_up(&blkif->shutdown_wq); @@ -238,13 +241,28 @@ static int xen_blkif_disconnect(struct xen_blkif *blkif) /* Remove all persistent grants and the cache of ballooned pages. */ xen_blkbk_free_caches(blkif); + /* Check that there is no request in use */ + list_for_each_entry_safe(req, n, &blkif->pending_free, free_list) { + list_del(&req->free_list); + + for (j = 0; j < MAX_INDIRECT_SEGMENTS; j++) + kfree(req->segments[j]); + + for (j = 0; j < MAX_INDIRECT_PAGES; j++) + kfree(req->indirect_pages[j]); + + kfree(req); + i++; + } + + WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages)); + blkif->nr_ring_pages = 0; + return 0; } static void xen_blkif_free(struct xen_blkif *blkif) { - struct pending_req *req, *n; - int i = 0, j; xen_blkif_disconnect(blkif); xen_vbd_free(&blkif->vbd); @@ -257,22 +275,6 @@ static void xen_blkif_free(struct xen_blkif *blkif) BUG_ON(!list_empty(&blkif->free_pages)); BUG_ON(!RB_EMPTY_ROOT(&blkif->persistent_gnts)); - /* Check that there is no request in use */ - list_for_each_entry_safe(req, n, &blkif->pending_free, free_list) { - list_del(&req->free_list); - - for (j = 0; j < MAX_INDIRECT_SEGMENTS; j++) - kfree(req->segments[j]); - - for (j = 0; j < MAX_INDIRECT_PAGES; j++) - kfree(req->indirect_pages[j]); - - kfree(req); - i++; - } - - WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages)); - kmem_cache_free(xen_blkif_cachep, blkif); } diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c index 3a1fe07cf..dd02356e2 100644 --- a/drivers/clk/samsung/clk-cpu.c +++ b/drivers/clk/samsung/clk-cpu.c @@ -161,7 +161,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata, * the values for DIV_COPY and DIV_HPM dividers need not be set. */ div0 = cfg_data->div0; - if (test_bit(CLK_CPU_HAS_DIV1, &cpuclk->flags)) { + if (cpuclk->flags & CLK_CPU_HAS_DIV1) { div1 = cfg_data->div1; if (readl(base + E4210_SRC_CPU) & E4210_MUX_HPM_MASK) div1 = readl(base + E4210_DIV_CPU1) & @@ -182,7 +182,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata, alt_div = DIV_ROUND_UP(alt_prate, tmp_rate) - 1; WARN_ON(alt_div >= MAX_DIV); - if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) { + if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) { /* * In Exynos4210, ATB clock parent is also mout_core. So * ATB clock also needs to be mantained at safe speed. @@ -203,7 +203,7 @@ static int exynos_cpuclk_pre_rate_change(struct clk_notifier_data *ndata, writel(div0, base + E4210_DIV_CPU0); wait_until_divider_stable(base + E4210_DIV_STAT_CPU0, DIV_MASK_ALL); - if (test_bit(CLK_CPU_HAS_DIV1, &cpuclk->flags)) { + if (cpuclk->flags & CLK_CPU_HAS_DIV1) { writel(div1, base + E4210_DIV_CPU1); wait_until_divider_stable(base + E4210_DIV_STAT_CPU1, DIV_MASK_ALL); @@ -222,7 +222,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata, unsigned long mux_reg; /* find out the divider values to use for clock data */ - if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) { + if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) { while ((cfg_data->prate * 1000) != ndata->new_rate) { if (cfg_data->prate == 0) return -EINVAL; @@ -237,7 +237,7 @@ static int exynos_cpuclk_post_rate_change(struct clk_notifier_data *ndata, writel(mux_reg & ~(1 << 16), base + E4210_SRC_CPU); wait_until_mux_stable(base + E4210_STAT_CPU, 16, 1); - if (test_bit(CLK_CPU_NEEDS_DEBUG_ALT_DIV, &cpuclk->flags)) { + if (cpuclk->flags & CLK_CPU_NEEDS_DEBUG_ALT_DIV) { div |= (cfg_data->div0 & E4210_DIV0_ATB_MASK); div_mask |= E4210_DIV0_ATB_MASK; } diff --git a/drivers/clk/ti/clk-3xxx.c b/drivers/clk/ti/clk-3xxx.c index 757636d16..4ab28cfb8 100644 --- a/drivers/clk/ti/clk-3xxx.c +++ b/drivers/clk/ti/clk-3xxx.c @@ -163,7 +163,6 @@ static struct ti_dt_clk omap3xxx_clks[] = { DT_CLK(NULL, "gpio2_ick", "gpio2_ick"), DT_CLK(NULL, "wdt3_ick", "wdt3_ick"), DT_CLK(NULL, "uart3_ick", "uart3_ick"), - DT_CLK(NULL, "uart4_ick", "uart4_ick"), DT_CLK(NULL, "gpt9_ick", "gpt9_ick"), DT_CLK(NULL, "gpt8_ick", "gpt8_ick"), DT_CLK(NULL, "gpt7_ick", "gpt7_ick"), @@ -308,6 +307,7 @@ static struct ti_dt_clk am35xx_clks[] = { static struct ti_dt_clk omap36xx_clks[] = { DT_CLK(NULL, "omap_192m_alwon_fck", "omap_192m_alwon_fck"), DT_CLK(NULL, "uart4_fck", "uart4_fck"), + DT_CLK(NULL, "uart4_ick", "uart4_ick"), { .node_name = NULL }, }; diff --git a/drivers/clk/ti/clk-7xx.c b/drivers/clk/ti/clk-7xx.c index 63b8323df..0eb82107c 100644 --- a/drivers/clk/ti/clk-7xx.c +++ b/drivers/clk/ti/clk-7xx.c @@ -16,7 +16,6 @@ #include #include -#define DRA7_DPLL_ABE_DEFFREQ 180633600 #define DRA7_DPLL_GMAC_DEFFREQ 1000000000 #define DRA7_DPLL_USB_DEFFREQ 960000000 @@ -312,27 +311,12 @@ static struct ti_dt_clk dra7xx_clks[] = { int __init dra7xx_dt_clk_init(void) { int rc; - struct clk *abe_dpll_mux, *sys_clkin2, *dpll_ck, *hdcp_ck; + struct clk *dpll_ck, *hdcp_ck; ti_dt_clocks_register(dra7xx_clks); omap2_clk_disable_autoidle_all(); - abe_dpll_mux = clk_get_sys(NULL, "abe_dpll_sys_clk_mux"); - sys_clkin2 = clk_get_sys(NULL, "sys_clkin2"); - dpll_ck = clk_get_sys(NULL, "dpll_abe_ck"); - - rc = clk_set_parent(abe_dpll_mux, sys_clkin2); - if (!rc) - rc = clk_set_rate(dpll_ck, DRA7_DPLL_ABE_DEFFREQ); - if (rc) - pr_err("%s: failed to configure ABE DPLL!\n", __func__); - - dpll_ck = clk_get_sys(NULL, "dpll_abe_m2x2_ck"); - rc = clk_set_rate(dpll_ck, DRA7_DPLL_ABE_DEFFREQ * 2); - if (rc) - pr_err("%s: failed to configure ABE DPLL m2x2!\n", __func__); - dpll_ck = clk_get_sys(NULL, "dpll_gmac_ck"); rc = clk_set_rate(dpll_ck, DRA7_DPLL_GMAC_DEFFREQ); if (rc) diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 0136dfcda..7c2a7385c 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -146,6 +146,9 @@ static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf) { struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu); + if (unlikely(!data)) + return -ENODEV; + return cpufreq_show_cpus(data->freqdomain_cpus, buf); } diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 528a82bf5..99a406501 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -255,7 +255,8 @@ static int cpufreq_init(struct cpufreq_policy *policy) rcu_read_unlock(); tol_uV = opp_uV * priv->voltage_tolerance / 100; - if (regulator_is_supported_voltage(cpu_reg, opp_uV, + if (regulator_is_supported_voltage(cpu_reg, + opp_uV - tol_uV, opp_uV + tol_uV)) { if (opp_uV < min_uV) min_uV = opp_uV; diff --git a/drivers/crypto/marvell/cesa.h b/drivers/crypto/marvell/cesa.h index b60698b30..bc2a55bc3 100644 --- a/drivers/crypto/marvell/cesa.h +++ b/drivers/crypto/marvell/cesa.h @@ -687,6 +687,33 @@ static inline u32 mv_cesa_get_int_mask(struct mv_cesa_engine *engine) int mv_cesa_queue_req(struct crypto_async_request *req); +/* + * Helper function that indicates whether a crypto request needs to be + * cleaned up or not after being enqueued using mv_cesa_queue_req(). + */ +static inline int mv_cesa_req_needs_cleanup(struct crypto_async_request *req, + int ret) +{ + /* + * The queue still had some space, the request was queued + * normally, so there's no need to clean it up. + */ + if (ret == -EINPROGRESS) + return false; + + /* + * The queue had not space left, but since the request is + * flagged with CRYPTO_TFM_REQ_MAY_BACKLOG, it was added to + * the backlog and will be processed later. There's no need to + * clean it up. + */ + if (ret == -EBUSY && req->flags & CRYPTO_TFM_REQ_MAY_BACKLOG) + return false; + + /* Request wasn't queued, we need to clean it up */ + return true; +} + /* TDMA functions */ static inline void mv_cesa_req_dma_iter_init(struct mv_cesa_dma_iter *iter, diff --git a/drivers/crypto/marvell/cipher.c b/drivers/crypto/marvell/cipher.c index 0745cf3b9..3df2f4e7a 100644 --- a/drivers/crypto/marvell/cipher.c +++ b/drivers/crypto/marvell/cipher.c @@ -189,7 +189,6 @@ static inline void mv_cesa_ablkcipher_prepare(struct crypto_async_request *req, { struct ablkcipher_request *ablkreq = ablkcipher_request_cast(req); struct mv_cesa_ablkcipher_req *creq = ablkcipher_request_ctx(ablkreq); - creq->req.base.engine = engine; if (creq->req.base.type == CESA_DMA_REQ) @@ -431,7 +430,7 @@ static int mv_cesa_des_op(struct ablkcipher_request *req, return ret; ret = mv_cesa_queue_req(&req->base); - if (ret && ret != -EINPROGRESS) + if (mv_cesa_req_needs_cleanup(&req->base, ret)) mv_cesa_ablkcipher_cleanup(req); return ret; @@ -551,7 +550,7 @@ static int mv_cesa_des3_op(struct ablkcipher_request *req, return ret; ret = mv_cesa_queue_req(&req->base); - if (ret && ret != -EINPROGRESS) + if (mv_cesa_req_needs_cleanup(&req->base, ret)) mv_cesa_ablkcipher_cleanup(req); return ret; @@ -693,7 +692,7 @@ static int mv_cesa_aes_op(struct ablkcipher_request *req, return ret; ret = mv_cesa_queue_req(&req->base); - if (ret && ret != -EINPROGRESS) + if (mv_cesa_req_needs_cleanup(&req->base, ret)) mv_cesa_ablkcipher_cleanup(req); return ret; diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c index ae9272eb9..e8d0d7128 100644 --- a/drivers/crypto/marvell/hash.c +++ b/drivers/crypto/marvell/hash.c @@ -739,10 +739,8 @@ static int mv_cesa_ahash_update(struct ahash_request *req) return 0; ret = mv_cesa_queue_req(&req->base); - if (ret && ret != -EINPROGRESS) { + if (mv_cesa_req_needs_cleanup(&req->base, ret)) mv_cesa_ahash_cleanup(req); - return ret; - } return ret; } @@ -766,7 +764,7 @@ static int mv_cesa_ahash_final(struct ahash_request *req) return 0; ret = mv_cesa_queue_req(&req->base); - if (ret && ret != -EINPROGRESS) + if (mv_cesa_req_needs_cleanup(&req->base, ret)) mv_cesa_ahash_cleanup(req); return ret; @@ -791,7 +789,7 @@ static int mv_cesa_ahash_finup(struct ahash_request *req) return 0; ret = mv_cesa_queue_req(&req->base); - if (ret && ret != -EINPROGRESS) + if (mv_cesa_req_needs_cleanup(&req->base, ret)) mv_cesa_ahash_cleanup(req); return ret; diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 40afa2a16..da7917a2e 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -455,6 +455,15 @@ static struct at_xdmac_desc *at_xdmac_alloc_desc(struct dma_chan *chan, return desc; } +void at_xdmac_init_used_desc(struct at_xdmac_desc *desc) +{ + memset(&desc->lld, 0, sizeof(desc->lld)); + INIT_LIST_HEAD(&desc->descs_list); + desc->direction = DMA_TRANS_NONE; + desc->xfer_size = 0; + desc->active_xfer = false; +} + /* Call must be protected by lock. */ static struct at_xdmac_desc *at_xdmac_get_desc(struct at_xdmac_chan *atchan) { @@ -466,7 +475,7 @@ static struct at_xdmac_desc *at_xdmac_get_desc(struct at_xdmac_chan *atchan) desc = list_first_entry(&atchan->free_descs_list, struct at_xdmac_desc, desc_node); list_del(&desc->desc_node); - desc->active_xfer = false; + at_xdmac_init_used_desc(desc); } return desc; @@ -797,10 +806,7 @@ at_xdmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, list_add_tail(&desc->desc_node, &first->descs_list); } - prev->lld.mbr_nda = first->tx_dma_desc.phys; - dev_dbg(chan2dev(chan), - "%s: chain lld: prev=0x%p, mbr_nda=%pad\n", - __func__, prev, &prev->lld.mbr_nda); + at_xdmac_queue_desc(chan, prev, first); first->tx_dma_desc.flags = flags; first->xfer_size = buf_len; first->direction = direction; @@ -878,14 +884,14 @@ at_xdmac_interleaved_queue_desc(struct dma_chan *chan, if (xt->src_inc) { if (xt->src_sgl) - chan_cc |= AT_XDMAC_CC_SAM_UBS_DS_AM; + chan_cc |= AT_XDMAC_CC_SAM_UBS_AM; else chan_cc |= AT_XDMAC_CC_SAM_INCREMENTED_AM; } if (xt->dst_inc) { if (xt->dst_sgl) - chan_cc |= AT_XDMAC_CC_DAM_UBS_DS_AM; + chan_cc |= AT_XDMAC_CC_DAM_UBS_AM; else chan_cc |= AT_XDMAC_CC_DAM_INCREMENTED_AM; } diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c index cf1c87fa1..bedce038c 100644 --- a/drivers/dma/dw/core.c +++ b/drivers/dma/dw/core.c @@ -1591,7 +1591,6 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) INIT_LIST_HEAD(&dw->dma.channels); for (i = 0; i < nr_channels; i++) { struct dw_dma_chan *dwc = &dw->chan[i]; - int r = nr_channels - i - 1; dwc->chan.device = &dw->dma; dma_cookie_init(&dwc->chan); @@ -1603,7 +1602,7 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) /* 7 is highest priority & 0 is lowest. */ if (pdata->chan_priority == CHAN_PRIORITY_ASCENDING) - dwc->priority = r; + dwc->priority = nr_channels - i - 1; else dwc->priority = i; @@ -1622,6 +1621,7 @@ int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata) /* Hardware configuration */ if (autocfg) { unsigned int dwc_params; + unsigned int r = DW_DMA_MAX_NR_CHANNELS - i - 1; void __iomem *addr = chip->regs + r * sizeof(u32); dwc_params = dma_read_byaddr(addr, DWC_PARAMS); diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c index ddcbbf5cd..95bdbbe2a 100644 --- a/drivers/dma/pxa_dma.c +++ b/drivers/dma/pxa_dma.c @@ -888,6 +888,7 @@ pxad_tx_prep(struct virt_dma_chan *vc, struct virt_dma_desc *vd, struct dma_async_tx_descriptor *tx; struct pxad_chan *chan = container_of(vc, struct pxad_chan, vc); + INIT_LIST_HEAD(&vd->node); tx = vchan_tx_prep(vc, vd, tx_flags); tx->tx_submit = pxad_tx_submit; dev_dbg(&chan->vc.chan.dev->device, diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index 43b57b02d..ca94f475f 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -126,7 +126,7 @@ static int find_cable_index_by_id(struct extcon_dev *edev, const unsigned int id static int find_cable_id_by_name(struct extcon_dev *edev, const char *name) { - unsigned int id = -EINVAL; + int id = -EINVAL; int i = 0; /* Find the id of extcon cable */ @@ -143,7 +143,7 @@ static int find_cable_id_by_name(struct extcon_dev *edev, const char *name) static int find_cable_index_by_name(struct extcon_dev *edev, const char *name) { - unsigned int id; + int id; if (edev->max_supported == 0) return -EINVAL; @@ -159,7 +159,7 @@ static int find_cable_index_by_name(struct extcon_dev *edev, const char *name) static bool is_extcon_changed(u32 prev, u32 new, int idx, bool *attached) { if (((prev >> idx) & 0x1) != ((new >> idx) & 0x1)) { - *attached = new ? true : false; + *attached = ((new >> idx) & 0x1) ? true : false; return true; } @@ -378,7 +378,7 @@ EXPORT_SYMBOL_GPL(extcon_get_cable_state_); */ int extcon_get_cable_state(struct extcon_dev *edev, const char *cable_name) { - unsigned int id; + int id; id = find_cable_id_by_name(edev, cable_name); if (id < 0) @@ -426,7 +426,7 @@ EXPORT_SYMBOL_GPL(extcon_set_cable_state_); int extcon_set_cable_state(struct extcon_dev *edev, const char *cable_name, bool cable_state) { - unsigned int id; + int id; id = find_cable_id_by_name(edev, cable_name); if (id < 0) diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c index e29560e6b..950c87f5d 100644 --- a/drivers/firmware/efi/libstub/arm-stub.c +++ b/drivers/firmware/efi/libstub/arm-stub.c @@ -13,6 +13,7 @@ */ #include +#include #include #include "efistub.h" @@ -305,6 +306,44 @@ fail: */ #define EFI_RT_VIRTUAL_BASE 0x40000000 +static int cmp_mem_desc(const void *l, const void *r) +{ + const efi_memory_desc_t *left = l, *right = r; + + return (left->phys_addr > right->phys_addr) ? 1 : -1; +} + +/* + * Returns whether region @left ends exactly where region @right starts, + * or false if either argument is NULL. + */ +static bool regions_are_adjacent(efi_memory_desc_t *left, + efi_memory_desc_t *right) +{ + u64 left_end; + + if (left == NULL || right == NULL) + return false; + + left_end = left->phys_addr + left->num_pages * EFI_PAGE_SIZE; + + return left_end == right->phys_addr; +} + +/* + * Returns whether region @left and region @right have compatible memory type + * mapping attributes, and are both EFI_MEMORY_RUNTIME regions. + */ +static bool regions_have_compatible_memory_type_attrs(efi_memory_desc_t *left, + efi_memory_desc_t *right) +{ + static const u64 mem_type_mask = EFI_MEMORY_WB | EFI_MEMORY_WT | + EFI_MEMORY_WC | EFI_MEMORY_UC | + EFI_MEMORY_RUNTIME; + + return ((left->attribute ^ right->attribute) & mem_type_mask) == 0; +} + /* * efi_get_virtmap() - create a virtual mapping for the EFI memory map * @@ -317,33 +356,52 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, int *count) { u64 efi_virt_base = EFI_RT_VIRTUAL_BASE; - efi_memory_desc_t *out = runtime_map; + efi_memory_desc_t *in, *prev = NULL, *out = runtime_map; int l; - for (l = 0; l < map_size; l += desc_size) { - efi_memory_desc_t *in = (void *)memory_map + l; + /* + * To work around potential issues with the Properties Table feature + * introduced in UEFI 2.5, which may split PE/COFF executable images + * in memory into several RuntimeServicesCode and RuntimeServicesData + * regions, we need to preserve the relative offsets between adjacent + * EFI_MEMORY_RUNTIME regions with the same memory type attributes. + * The easiest way to find adjacent regions is to sort the memory map + * before traversing it. + */ + sort(memory_map, map_size / desc_size, desc_size, cmp_mem_desc, NULL); + + for (l = 0; l < map_size; l += desc_size, prev = in) { u64 paddr, size; + in = (void *)memory_map + l; if (!(in->attribute & EFI_MEMORY_RUNTIME)) continue; + paddr = in->phys_addr; + size = in->num_pages * EFI_PAGE_SIZE; + /* * Make the mapping compatible with 64k pages: this allows * a 4k page size kernel to kexec a 64k page size kernel and * vice versa. */ - paddr = round_down(in->phys_addr, SZ_64K); - size = round_up(in->num_pages * EFI_PAGE_SIZE + - in->phys_addr - paddr, SZ_64K); - - /* - * Avoid wasting memory on PTEs by choosing a virtual base that - * is compatible with section mappings if this region has the - * appropriate size and physical alignment. (Sections are 2 MB - * on 4k granule kernels) - */ - if (IS_ALIGNED(in->phys_addr, SZ_2M) && size >= SZ_2M) - efi_virt_base = round_up(efi_virt_base, SZ_2M); + if (!regions_are_adjacent(prev, in) || + !regions_have_compatible_memory_type_attrs(prev, in)) { + + paddr = round_down(in->phys_addr, SZ_64K); + size += in->phys_addr - paddr; + + /* + * Avoid wasting memory on PTEs by choosing a virtual + * base that is compatible with section mappings if this + * region has the appropriate size and physical + * alignment. (Sections are 2 MB on 4k granule kernels) + */ + if (IS_ALIGNED(in->phys_addr, SZ_2M) && size >= SZ_2M) + efi_virt_base = round_up(efi_virt_base, SZ_2M); + else + efi_virt_base = round_up(efi_virt_base, SZ_64K); + } in->virt_addr = efi_virt_base + in->phys_addr - paddr; efi_virt_base += size; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index b4d36f0f2..c098d7620 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -140,7 +140,7 @@ void amdgpu_irq_preinstall(struct drm_device *dev) */ int amdgpu_irq_postinstall(struct drm_device *dev) { - dev->max_vblank_count = 0x001fffff; + dev->max_vblank_count = 0x00ffffff; return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index 6670ab7fa..5b7d80130 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -538,46 +538,60 @@ static int amdgpu_uvd_cs_msg(struct amdgpu_uvd_cs_ctx *ctx, return -EINVAL; } - if (msg_type == 1) { + switch (msg_type) { + case 0: + /* it's a create msg, calc image size (width * height) */ + amdgpu_bo_kunmap(bo); + + /* try to alloc a new handle */ + for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { + if (atomic_read(&adev->uvd.handles[i]) == handle) { + DRM_ERROR("Handle 0x%x already in use!\n", handle); + return -EINVAL; + } + + if (!atomic_cmpxchg(&adev->uvd.handles[i], 0, handle)) { + adev->uvd.filp[i] = ctx->parser->filp; + return 0; + } + } + + DRM_ERROR("No more free UVD handles!\n"); + return -EINVAL; + + case 1: /* it's a decode msg, calc buffer sizes */ r = amdgpu_uvd_cs_msg_decode(msg, ctx->buf_sizes); amdgpu_bo_kunmap(bo); if (r) return r; - } else if (msg_type == 2) { + /* validate the handle */ + for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { + if (atomic_read(&adev->uvd.handles[i]) == handle) { + if (adev->uvd.filp[i] != ctx->parser->filp) { + DRM_ERROR("UVD handle collision detected!\n"); + return -EINVAL; + } + return 0; + } + } + + DRM_ERROR("Invalid UVD handle 0x%x!\n", handle); + return -ENOENT; + + case 2: /* it's a destroy msg, free the handle */ for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) atomic_cmpxchg(&adev->uvd.handles[i], handle, 0); amdgpu_bo_kunmap(bo); return 0; - } else { - /* it's a create msg */ - amdgpu_bo_kunmap(bo); - - if (msg_type != 0) { - DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); - return -EINVAL; - } - - /* it's a create msg, no special handling needed */ - } - - /* create or decode, validate the handle */ - for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { - if (atomic_read(&adev->uvd.handles[i]) == handle) - return 0; - } - /* handle not found try to alloc a new one */ - for (i = 0; i < AMDGPU_MAX_UVD_HANDLES; ++i) { - if (!atomic_cmpxchg(&adev->uvd.handles[i], 0, handle)) { - adev->uvd.filp[i] = ctx->parser->filp; - return 0; - } + default: + DRM_ERROR("Illegal UVD message type (%d)!\n", msg_type); + return -EINVAL; } - - DRM_ERROR("No more free UVD handles!\n"); + BUG(); return -EINVAL; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 9a4e3b63f..b07402fc8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -787,7 +787,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, int r; if (mem) { - addr = mem->start << PAGE_SHIFT; + addr = (u64)mem->start << PAGE_SHIFT; if (mem->mem_type != TTM_PL_TT) addr += adev->vm_manager.vram_base_offset; } else { diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c index ae8caca61..e60557417 100644 --- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c +++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c @@ -1279,8 +1279,7 @@ amdgpu_atombios_encoder_setup_dig(struct drm_encoder *encoder, int action) amdgpu_atombios_encoder_setup_dig_encoder(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); } if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) - amdgpu_atombios_encoder_setup_dig_transmitter(encoder, - ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); + amdgpu_atombios_encoder_set_backlight_level(amdgpu_encoder, dig->backlight_level); if (ext_encoder) amdgpu_atombios_encoder_setup_external_encoder(encoder, ext_encoder, ATOM_ENABLE); } else { diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index 4efd671d7..9488ea6ea 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c @@ -224,11 +224,11 @@ static int uvd_v4_2_suspend(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = uvd_v4_2_hw_fini(adev); + r = amdgpu_uvd_suspend(adev); if (r) return r; - r = amdgpu_uvd_suspend(adev); + r = uvd_v4_2_hw_fini(adev); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c index b756bd99c..d0ed99822 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c @@ -220,11 +220,11 @@ static int uvd_v5_0_suspend(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = uvd_v5_0_hw_fini(adev); + r = amdgpu_uvd_suspend(adev); if (r) return r; - r = amdgpu_uvd_suspend(adev); + r = uvd_v5_0_hw_fini(adev); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 49aa931b2..345eb760f 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -214,11 +214,11 @@ static int uvd_v6_0_suspend(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; - r = uvd_v6_0_hw_fini(adev); + r = amdgpu_uvd_suspend(adev); if (r) return r; - r = amdgpu_uvd_suspend(adev); + r = uvd_v6_0_hw_fini(adev); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 68552da40..4f58a1e18 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -1290,7 +1290,8 @@ static int vi_common_early_init(void *handle) case CHIP_CARRIZO: adev->has_uvd = true; adev->cg_flags = 0; - adev->pg_flags = AMDGPU_PG_SUPPORT_UVD | AMDGPU_PG_SUPPORT_VCE; + /* Disable UVD pg */ + adev->pg_flags = /* AMDGPU_PG_SUPPORT_UVD | */AMDGPU_PG_SUPPORT_VCE; adev->external_rev_id = adev->rev_id + 0x1; if (amdgpu_smc_load_fw && smc_enabled) adev->firmware.smu_load = true; diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index eb603f1de..969e7898a 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -804,8 +804,6 @@ static void drm_dp_destroy_mst_branch_device(struct kref *kref) struct drm_dp_mst_port *port, *tmp; bool wake_tx = false; - cancel_work_sync(&mstb->mgr->work); - /* * destroy all ports - don't need lock * as there are no more references to the mst branch @@ -863,29 +861,33 @@ static void drm_dp_destroy_port(struct kref *kref) { struct drm_dp_mst_port *port = container_of(kref, struct drm_dp_mst_port, kref); struct drm_dp_mst_topology_mgr *mgr = port->mgr; + if (!port->input) { port->vcpi.num_slots = 0; kfree(port->cached_edid); - /* we can't destroy the connector here, as - we might be holding the mode_config.mutex - from an EDID retrieval */ + /* + * The only time we don't have a connector + * on an output port is if the connector init + * fails. + */ if (port->connector) { + /* we can't destroy the connector here, as + * we might be holding the mode_config.mutex + * from an EDID retrieval */ + mutex_lock(&mgr->destroy_connector_lock); list_add(&port->next, &mgr->destroy_connector_list); mutex_unlock(&mgr->destroy_connector_lock); schedule_work(&mgr->destroy_connector_work); return; } + /* no need to clean up vcpi + * as if we have no connector we never setup a vcpi */ drm_dp_port_teardown_pdt(port, port->pdt); - - if (!port->input && port->vcpi.vcpi > 0) - drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi); } kfree(port); - - (*mgr->cbs->hotplug)(mgr); } static void drm_dp_put_port(struct drm_dp_mst_port *port) @@ -1115,12 +1117,21 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb, char proppath[255]; build_mst_prop_path(port, mstb, proppath, sizeof(proppath)); port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port, proppath); - + if (!port->connector) { + /* remove it from the port list */ + mutex_lock(&mstb->mgr->lock); + list_del(&port->next); + mutex_unlock(&mstb->mgr->lock); + /* drop port list reference */ + drm_dp_put_port(port); + goto out; + } if (port->port_num >= 8) { port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc); } } +out: /* put reference to this port */ drm_dp_put_port(port); } @@ -1978,6 +1989,8 @@ void drm_dp_mst_topology_mgr_suspend(struct drm_dp_mst_topology_mgr *mgr) drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL, DP_MST_EN | DP_UPSTREAM_IS_SRC); mutex_unlock(&mgr->lock); + flush_work(&mgr->work); + flush_work(&mgr->destroy_connector_work); } EXPORT_SYMBOL(drm_dp_mst_topology_mgr_suspend); @@ -2661,7 +2674,7 @@ static void drm_dp_destroy_connector_work(struct work_struct *work) { struct drm_dp_mst_topology_mgr *mgr = container_of(work, struct drm_dp_mst_topology_mgr, destroy_connector_work); struct drm_dp_mst_port *port; - + bool send_hotplug = false; /* * Not a regular list traverse as we have to drop the destroy * connector lock before destroying the connector, to avoid AB->BA @@ -2684,7 +2697,10 @@ static void drm_dp_destroy_connector_work(struct work_struct *work) if (!port->input && port->vcpi.vcpi > 0) drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi); kfree(port); + send_hotplug = true; } + if (send_hotplug) + (*mgr->cbs->hotplug)(mgr); } /** @@ -2737,6 +2753,7 @@ EXPORT_SYMBOL(drm_dp_mst_topology_mgr_init); */ void drm_dp_mst_topology_mgr_destroy(struct drm_dp_mst_topology_mgr *mgr) { + flush_work(&mgr->work); flush_work(&mgr->destroy_connector_work); mutex_lock(&mgr->payload_lock); kfree(mgr->payloads); diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index f861361a6..4924d381b 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c @@ -61,6 +61,9 @@ int drm_legacy_lock(struct drm_device *dev, void *data, struct drm_master *master = file_priv->master; int ret = 0; + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return -EINVAL; + ++file_priv->lock_count; if (lock->context == DRM_KERNEL_CONTEXT) { @@ -153,6 +156,9 @@ int drm_legacy_unlock(struct drm_device *dev, void *data, struct drm_file *file_ struct drm_lock *lock = data; struct drm_master *master = file_priv->master; + if (drm_core_check_feature(dev, DRIVER_MODESET)) + return -EINVAL; + if (lock->context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", task_pid_nr(current), lock->context); diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 198fc3c32..17522f733 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -42,7 +42,7 @@ find_section(const void *_bdb, int section_id) const struct bdb_header *bdb = _bdb; const u8 *base = _bdb; int index = 0; - u16 total, current_size; + u32 total, current_size; u8 current_id; /* skip to first section */ @@ -57,6 +57,10 @@ find_section(const void *_bdb, int section_id) current_size = *((const u16 *)(base + index)); index += 2; + /* The MIPI Sequence Block v3+ has a separate size field. */ + if (current_id == BDB_MIPI_SEQUENCE && *(base + index) >= 3) + current_size = *((const u32 *)(base + index + 1)); + if (index + current_size > total) return NULL; @@ -859,6 +863,12 @@ parse_mipi(struct drm_i915_private *dev_priv, const struct bdb_header *bdb) return; } + /* Fail gracefully for forward incompatible sequence block. */ + if (sequence->version >= 3) { + DRM_ERROR("Unable to parse MIPI Sequence Block v3+\n"); + return; + } + DRM_DEBUG_DRIVER("Found MIPI sequence block\n"); block_size = get_blocksize(sequence); diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 7c6225c84..4649bd2ed 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -618,7 +618,7 @@ static int qxl_crtc_mode_set(struct drm_crtc *crtc, adjusted_mode->hdisplay, adjusted_mode->vdisplay); - if (qcrtc->index == 0) + if (bo->is_primary == false) recreate_primary = true; if (bo->surf.stride * bo->surf.height > qdev->vram_size) { @@ -886,13 +886,15 @@ static enum drm_connector_status qxl_conn_detect( drm_connector_to_qxl_output(connector); struct drm_device *ddev = connector->dev; struct qxl_device *qdev = ddev->dev_private; - int connected; + bool connected = false; /* The first monitor is always connected */ - connected = (output->index == 0) || - (qdev->client_monitors_config && - qdev->client_monitors_config->count > output->index && - qxl_head_enabled(&qdev->client_monitors_config->heads[output->index])); + if (!qdev->client_monitors_config) { + if (output->index == 0) + connected = true; + } else + connected = qdev->client_monitors_config->count > output->index && + qxl_head_enabled(&qdev->client_monitors_config->heads[output->index]); DRM_DEBUG("#%d connected: %d\n", output->index, connected); if (!connected) diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index c3872598b..65adb9c72 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -1624,8 +1624,9 @@ radeon_atom_encoder_dpms_avivo(struct drm_encoder *encoder, int mode) } else atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { - args.ucAction = ATOM_LCD_BLON; - atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + + atombios_set_backlight_level(radeon_encoder, dig->backlight_level); } break; case DRM_MODE_DPMS_STANDBY: @@ -1706,8 +1707,7 @@ radeon_atom_encoder_dpms_dig(struct drm_encoder *encoder, int mode) atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0); } if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) - atombios_dig_transmitter_setup(encoder, - ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0); + atombios_set_backlight_level(radeon_encoder, dig->backlight_level); if (ext_encoder) atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); break; diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c index ea7ba5ef1..6a9d80a53 100644 --- a/drivers/hv/hv_utils_transport.c +++ b/drivers/hv/hv_utils_transport.c @@ -186,7 +186,7 @@ int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len) return -EINVAL; } else if (hvt->mode == HVUTIL_TRANSPORT_NETLINK) { cn_msg = kzalloc(sizeof(*cn_msg) + len, GFP_ATOMIC); - if (!msg) + if (!cn_msg) return -ENOMEM; cn_msg->id.idx = hvt->cn_id.idx; cn_msg->id.val = hvt->cn_id.val; diff --git a/drivers/hwmon/nct6775.c b/drivers/hwmon/nct6775.c index bd1c99dea..2aaedbe0b 100644 --- a/drivers/hwmon/nct6775.c +++ b/drivers/hwmon/nct6775.c @@ -354,6 +354,10 @@ static const u16 NCT6775_REG_TEMP_CRIT[ARRAY_SIZE(nct6775_temp_label) - 1] /* NCT6776 specific data */ +/* STEP_UP_TIME and STEP_DOWN_TIME regs are swapped for all chips but NCT6775 */ +#define NCT6776_REG_FAN_STEP_UP_TIME NCT6775_REG_FAN_STEP_DOWN_TIME +#define NCT6776_REG_FAN_STEP_DOWN_TIME NCT6775_REG_FAN_STEP_UP_TIME + static const s8 NCT6776_ALARM_BITS[] = { 0, 1, 2, 3, 8, 21, 20, 16, /* in0.. in7 */ 17, -1, -1, -1, -1, -1, -1, /* in8..in14 */ @@ -3528,8 +3532,8 @@ static int nct6775_probe(struct platform_device *pdev) data->REG_FAN_PULSES = NCT6776_REG_FAN_PULSES; data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT; data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME; - data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME; - data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME; + data->REG_FAN_TIME[1] = NCT6776_REG_FAN_STEP_UP_TIME; + data->REG_FAN_TIME[2] = NCT6776_REG_FAN_STEP_DOWN_TIME; data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H; data->REG_PWM[0] = NCT6775_REG_PWM; data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT; @@ -3600,8 +3604,8 @@ static int nct6775_probe(struct platform_device *pdev) data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES; data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT; data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME; - data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME; - data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME; + data->REG_FAN_TIME[1] = NCT6776_REG_FAN_STEP_UP_TIME; + data->REG_FAN_TIME[2] = NCT6776_REG_FAN_STEP_DOWN_TIME; data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H; data->REG_PWM[0] = NCT6775_REG_PWM; data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT; @@ -3677,8 +3681,8 @@ static int nct6775_probe(struct platform_device *pdev) data->REG_FAN_PULSES = NCT6779_REG_FAN_PULSES; data->FAN_PULSE_SHIFT = NCT6775_FAN_PULSE_SHIFT; data->REG_FAN_TIME[0] = NCT6775_REG_FAN_STOP_TIME; - data->REG_FAN_TIME[1] = NCT6775_REG_FAN_STEP_UP_TIME; - data->REG_FAN_TIME[2] = NCT6775_REG_FAN_STEP_DOWN_TIME; + data->REG_FAN_TIME[1] = NCT6776_REG_FAN_STEP_UP_TIME; + data->REG_FAN_TIME[2] = NCT6776_REG_FAN_STEP_DOWN_TIME; data->REG_TOLERANCE_H = NCT6776_REG_TOLERANCE_H; data->REG_PWM[0] = NCT6775_REG_PWM; data->REG_PWM[1] = NCT6775_REG_FAN_START_OUTPUT; diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index d851e1828..85761b78b 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -3012,9 +3012,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; @@ -3379,6 +3386,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; @@ -3397,8 +3439,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); diff --git a/drivers/irqchip/irq-atmel-aic5.c b/drivers/irqchip/irq-atmel-aic5.c index 459bf4429..7e077bf13 100644 --- a/drivers/irqchip/irq-atmel-aic5.c +++ b/drivers/irqchip/irq-atmel-aic5.c @@ -88,28 +88,36 @@ static void aic5_mask(struct irq_data *d) { struct irq_domain *domain = d->domain; struct irq_domain_chip_generic *dgc = domain->gc; - struct irq_chip_generic *gc = dgc->gc[0]; + struct irq_chip_generic *bgc = dgc->gc[0]; + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - /* Disable interrupt on AIC5 */ - irq_gc_lock(gc); + /* + * Disable interrupt on AIC5. We always take the lock of the + * first irq chip as all chips share the same registers. + */ + irq_gc_lock(bgc); irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR); irq_reg_writel(gc, 1, AT91_AIC5_IDCR); gc->mask_cache &= ~d->mask; - irq_gc_unlock(gc); + irq_gc_unlock(bgc); } static void aic5_unmask(struct irq_data *d) { struct irq_domain *domain = d->domain; struct irq_domain_chip_generic *dgc = domain->gc; - struct irq_chip_generic *gc = dgc->gc[0]; + struct irq_chip_generic *bgc = dgc->gc[0]; + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); - /* Enable interrupt on AIC5 */ - irq_gc_lock(gc); + /* + * Enable interrupt on AIC5. We always take the lock of the + * first irq chip as all chips share the same registers. + */ + irq_gc_lock(bgc); irq_reg_writel(gc, d->hwirq, AT91_AIC5_SSR); irq_reg_writel(gc, 1, AT91_AIC5_IECR); gc->mask_cache |= d->mask; - irq_gc_unlock(gc); + irq_gc_unlock(bgc); } static int aic5_retrigger(struct irq_data *d) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index c00e2db35..9a791dd52 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -921,8 +921,10 @@ retry_baser: * non-cacheable as well. */ shr = tmp & GITS_BASER_SHAREABILITY_MASK; - if (!shr) + if (!shr) { cache = GITS_BASER_nC; + __flush_dcache_area(base, alloc_size); + } goto retry_baser; } @@ -1163,6 +1165,8 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, return NULL; } + __flush_dcache_area(itt, sz); + dev->its = its; dev->itt = itt; dev->nr_ites = nr_ites; diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 9ad35f72a..433fb9df8 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -229,7 +229,7 @@ config LEDS_LP55XX_COMMON tristate "Common Driver for TI/National LP5521/5523/55231/5562/8501" depends on LEDS_LP5521 || LEDS_LP5523 || LEDS_LP5562 || LEDS_LP8501 select FW_LOADER - select FW_LOADER_USER_HELPER_FALLBACK + select FW_LOADER_USER_HELPER help This option supports common operations for LP5521/5523/55231/5562/8501 devices. diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index beabfbc6f..ca51d58be 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -228,12 +228,15 @@ static int led_classdev_next_name(const char *init_name, char *name, { unsigned int i = 0; int ret = 0; + struct device *dev; strlcpy(name, init_name, len); - while (class_find_device(leds_class, NULL, name, match_name) && - (ret < len)) + while ((ret < len) && + (dev = class_find_device(leds_class, NULL, name, match_name))) { + put_device(dev); ret = snprintf(name, len, "%s_%u", init_name, ++i); + } if (ret >= len) return -ENOMEM; diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index 3ee198b65..cc7ece171 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c @@ -435,7 +435,7 @@ int wf_unregister_client(struct notifier_block *nb) { mutex_lock(&wf_lock); blocking_notifier_chain_unregister(&wf_client_list, nb); - wf_client_count++; + wf_client_count--; if (wf_client_count == 0) wf_stop_thread(); mutex_unlock(&wf_lock); diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index e51de52ee..48b5890c2 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c @@ -1997,7 +1997,8 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks, if (bitmap->mddev->bitmap_info.offset || bitmap->mddev->bitmap_info.file) ret = bitmap_storage_alloc(&store, chunks, !bitmap->mddev->bitmap_info.external, - bitmap->cluster_slot); + mddev_is_clustered(bitmap->mddev) + ? bitmap->cluster_slot : 0); if (ret) goto err; diff --git a/drivers/md/dm-cache-policy-cleaner.c b/drivers/md/dm-cache-policy-cleaner.c index 240c9f0e8..8a0964565 100644 --- a/drivers/md/dm-cache-policy-cleaner.c +++ b/drivers/md/dm-cache-policy-cleaner.c @@ -436,7 +436,7 @@ static struct dm_cache_policy *wb_create(dm_cblock_t cache_size, static struct dm_cache_policy_type wb_policy_type = { .name = "cleaner", .version = {1, 0, 0}, - .hint_size = 0, + .hint_size = 4, .owner = THIS_MODULE, .create = wb_create }; diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 0f48fed44..0d28c5b9d 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -968,7 +968,8 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone); /* * Generate a new unfragmented bio with the given size - * This should never violate the device limitations + * This should never violate the device limitations (but only because + * max_segment_size is being constrained to PAGE_SIZE). * * This function may be called concurrently. If we allocate from the mempool * concurrently, there is a possibility of deadlock. For example, if we have @@ -2058,9 +2059,20 @@ static int crypt_iterate_devices(struct dm_target *ti, return fn(ti, cc->dev, cc->start, ti->len, data); } +static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits) +{ + /* + * Unfortunate constraint that is required to avoid the potential + * for exceeding underlying device's max_segments limits -- due to + * crypt_alloc_buffer() possibly allocating pages for the encryption + * bio that are not as physically contiguous as the original bio. + */ + limits->max_segment_size = PAGE_SIZE; +} + static struct target_type crypt_target = { .name = "crypt", - .version = {1, 14, 0}, + .version = {1, 14, 1}, .module = THIS_MODULE, .ctr = crypt_ctr, .dtr = crypt_dtr, @@ -2072,6 +2084,7 @@ static struct target_type crypt_target = { .message = crypt_message, .merge = crypt_merge, .iterate_devices = crypt_iterate_devices, + .io_hints = crypt_io_hints, }; static int __init dm_crypt_init(void) diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 2daa67793..1257d4843 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -329,8 +329,7 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size) */ if (min_region_size > (1 << 13)) { /* If not a power of 2, make it the next power of 2 */ - if (min_region_size & (min_region_size - 1)) - region_size = 1 << fls(region_size); + region_size = roundup_pow_of_two(min_region_size); DMINFO("Choosing default region size of %lu sectors", region_size); } else { diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index d2bbe8cc1..75aef240c 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -4333,6 +4333,10 @@ static void thin_io_hints(struct dm_target *ti, struct queue_limits *limits) { struct thin_c *tc = ti->private; struct pool *pool = tc->pool; + struct queue_limits *pool_limits = dm_get_queue_limits(pool->pool_md); + + if (!pool_limits->discard_granularity) + return; /* pool's discard support is disabled */ limits->discard_granularity = pool->sectors_per_block << SECTOR_SHIFT; limits->max_discard_sectors = 2048 * 1024 * 16; /* 16G */ diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 0d7ab20c5..3e32f4e31 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -2952,8 +2952,6 @@ static void __dm_destroy(struct mapped_device *md, bool wait) might_sleep(); - map = dm_get_live_table(md, &srcu_idx); - spin_lock(&_minor_lock); idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(disk_devt(dm_disk(md)))); set_bit(DMF_FREEING, &md->flags); @@ -2967,14 +2965,14 @@ static void __dm_destroy(struct mapped_device *md, bool wait) * do not race with internal suspend. */ mutex_lock(&md->suspend_lock); + map = dm_get_live_table(md, &srcu_idx); if (!dm_suspended_md(md)) { dm_table_presuspend_targets(map); dm_table_postsuspend_targets(map); } - mutex_unlock(&md->suspend_lock); - /* dm_put_live_table must be before msleep, otherwise deadlock is possible */ dm_put_live_table(md, srcu_idx); + mutex_unlock(&md->suspend_lock); /* * Rare, but there may be I/O requests still going to complete, diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index efb654eb5..0875e5e7e 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -83,7 +83,7 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) char b[BDEVNAME_SIZE]; char b2[BDEVNAME_SIZE]; struct r0conf *conf = kzalloc(sizeof(*conf), GFP_KERNEL); - bool discard_supported = false; + unsigned short blksize = 512; if (!conf) return -ENOMEM; @@ -98,6 +98,9 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) sector_div(sectors, mddev->chunk_sectors); rdev1->sectors = sectors * mddev->chunk_sectors; + blksize = max(blksize, queue_logical_block_size( + rdev1->bdev->bd_disk->queue)); + rdev_for_each(rdev2, mddev) { pr_debug("md/raid0:%s: comparing %s(%llu)" " with %s(%llu)\n", @@ -134,6 +137,18 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) } pr_debug("md/raid0:%s: FINAL %d zones\n", mdname(mddev), conf->nr_strip_zones); + /* + * now since we have the hard sector sizes, we can make sure + * chunk size is a multiple of that sector size + */ + if ((mddev->chunk_sectors << 9) % blksize) { + printk(KERN_ERR "md/raid0:%s: chunk_size of %d not multiple of block size %d\n", + mdname(mddev), + mddev->chunk_sectors << 9, blksize); + err = -EINVAL; + goto abort; + } + err = -ENOMEM; conf->strip_zone = kzalloc(sizeof(struct strip_zone)* conf->nr_strip_zones, GFP_KERNEL); @@ -188,19 +203,12 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) } dev[j] = rdev1; - if (mddev->queue) - disk_stack_limits(mddev->gendisk, rdev1->bdev, - rdev1->data_offset << 9); - if (rdev1->bdev->bd_disk->queue->merge_bvec_fn) conf->has_merge_bvec = 1; if (!smallest || (rdev1->sectors < smallest->sectors)) smallest = rdev1; cnt++; - - if (blk_queue_discard(bdev_get_queue(rdev1->bdev))) - discard_supported = true; } if (cnt != mddev->raid_disks) { printk(KERN_ERR "md/raid0:%s: too few disks (%d of %d) - " @@ -261,28 +269,6 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) (unsigned long long)smallest->sectors); } - /* - * now since we have the hard sector sizes, we can make sure - * chunk size is a multiple of that sector size - */ - if ((mddev->chunk_sectors << 9) % queue_logical_block_size(mddev->queue)) { - printk(KERN_ERR "md/raid0:%s: chunk_size of %d not valid\n", - mdname(mddev), - mddev->chunk_sectors << 9); - goto abort; - } - - if (mddev->queue) { - blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9); - blk_queue_io_opt(mddev->queue, - (mddev->chunk_sectors << 9) * mddev->raid_disks); - - if (!discard_supported) - queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); - else - queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); - } - pr_debug("md/raid0:%s: done.\n", mdname(mddev)); *private_conf = conf; @@ -433,12 +419,6 @@ static int raid0_run(struct mddev *mddev) if (md_check_no_bitmap(mddev)) return -EINVAL; - if (mddev->queue) { - blk_queue_max_hw_sectors(mddev->queue, mddev->chunk_sectors); - blk_queue_max_write_same_sectors(mddev->queue, mddev->chunk_sectors); - blk_queue_max_discard_sectors(mddev->queue, mddev->chunk_sectors); - } - /* if private is not null, we are here after takeover */ if (mddev->private == NULL) { ret = create_strip_zones(mddev, &conf); @@ -447,6 +427,29 @@ static int raid0_run(struct mddev *mddev) mddev->private = conf; } conf = mddev->private; + if (mddev->queue) { + struct md_rdev *rdev; + bool discard_supported = false; + + blk_queue_max_hw_sectors(mddev->queue, mddev->chunk_sectors); + blk_queue_max_write_same_sectors(mddev->queue, mddev->chunk_sectors); + blk_queue_max_discard_sectors(mddev->queue, mddev->chunk_sectors); + + blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9); + blk_queue_io_opt(mddev->queue, + (mddev->chunk_sectors << 9) * mddev->raid_disks); + + rdev_for_each(rdev, mddev) { + disk_stack_limits(mddev->gendisk, rdev->bdev, + rdev->data_offset << 9); + if (blk_queue_discard(bdev_get_queue(rdev->bdev))) + discard_supported = true; + } + if (!discard_supported) + queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); + else + queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, mddev->queue); + } /* calculate array device size */ md_set_array_sectors(mddev, raid0_size(mddev, 0, 0)); diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 9e3fdbdc4..2f4503a7f 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -134,9 +134,11 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) int err = cmd->error; /* Flag re-tuning needed on CRC errors */ - if (err == -EILSEQ || (mrq->sbc && mrq->sbc->error == -EILSEQ) || + if ((cmd->opcode != MMC_SEND_TUNING_BLOCK && + cmd->opcode != MMC_SEND_TUNING_BLOCK_HS200) && + (err == -EILSEQ || (mrq->sbc && mrq->sbc->error == -EILSEQ) || (mrq->data && mrq->data->error == -EILSEQ) || - (mrq->stop && mrq->stop->error == -EILSEQ)) + (mrq->stop && mrq->stop->error == -EILSEQ))) mmc_retune_needed(host); if (err && cmd->retries && mmc_host_is_spi(host)) { diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 99a9c9011..79979e9d5 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -457,7 +457,7 @@ int mmc_of_parse(struct mmc_host *host) 0, &cd_gpio_invert); if (!ret) dev_info(host->parent, "Got CD GPIO\n"); - else if (ret != -ENOENT) + else if (ret != -ENOENT && ret != -ENOSYS) return ret; /* @@ -481,7 +481,7 @@ int mmc_of_parse(struct mmc_host *host) ret = mmc_gpiod_request_ro(host, "wp", 0, false, 0, &ro_gpio_invert); if (!ret) dev_info(host->parent, "Got WP GPIO\n"); - else if (ret != -ENOENT) + else if (ret != -ENOENT && ret != -ENOSYS) return ret; if (of_property_read_bool(np, "disable-wp")) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 40e9d8e45..e41fb7405 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -99,6 +99,9 @@ struct idmac_desc { __le32 des3; /* buffer 2 physical address */ }; + +/* Each descriptor can transfer up to 4KB of data in chained mode */ +#define DW_MCI_DESC_DATA_LENGTH 0x1000 #endif /* CONFIG_MMC_DW_IDMAC */ static bool dw_mci_reset(struct dw_mci *host); @@ -462,66 +465,96 @@ static void dw_mci_idmac_complete_dma(struct dw_mci *host) static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data, unsigned int sg_len) { + unsigned int desc_len; int i; if (host->dma_64bit_address == 1) { - struct idmac_desc_64addr *desc = host->sg_cpu; + struct idmac_desc_64addr *desc_first, *desc_last, *desc; + + desc_first = desc_last = desc = host->sg_cpu; - for (i = 0; i < sg_len; i++, desc++) { + for (i = 0; i < sg_len; i++) { unsigned int length = sg_dma_len(&data->sg[i]); u64 mem_addr = sg_dma_address(&data->sg[i]); - /* - * Set the OWN bit and disable interrupts for this - * descriptor - */ - desc->des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC | - IDMAC_DES0_CH; - /* Buffer length */ - IDMAC_64ADDR_SET_BUFFER1_SIZE(desc, length); - - /* Physical address to DMA to/from */ - desc->des4 = mem_addr & 0xffffffff; - desc->des5 = mem_addr >> 32; + for ( ; length ; desc++) { + desc_len = (length <= DW_MCI_DESC_DATA_LENGTH) ? + length : DW_MCI_DESC_DATA_LENGTH; + + length -= desc_len; + + /* + * Set the OWN bit and disable interrupts + * for this descriptor + */ + desc->des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC | + IDMAC_DES0_CH; + + /* Buffer length */ + IDMAC_64ADDR_SET_BUFFER1_SIZE(desc, desc_len); + + /* Physical address to DMA to/from */ + desc->des4 = mem_addr & 0xffffffff; + desc->des5 = mem_addr >> 32; + + /* Update physical address for the next desc */ + mem_addr += desc_len; + + /* Save pointer to the last descriptor */ + desc_last = desc; + } } /* Set first descriptor */ - desc = host->sg_cpu; - desc->des0 |= IDMAC_DES0_FD; + desc_first->des0 |= IDMAC_DES0_FD; /* Set last descriptor */ - desc = host->sg_cpu + (i - 1) * - sizeof(struct idmac_desc_64addr); - desc->des0 &= ~(IDMAC_DES0_CH | IDMAC_DES0_DIC); - desc->des0 |= IDMAC_DES0_LD; + desc_last->des0 &= ~(IDMAC_DES0_CH | IDMAC_DES0_DIC); + desc_last->des0 |= IDMAC_DES0_LD; } else { - struct idmac_desc *desc = host->sg_cpu; + struct idmac_desc *desc_first, *desc_last, *desc; + + desc_first = desc_last = desc = host->sg_cpu; - for (i = 0; i < sg_len; i++, desc++) { + for (i = 0; i < sg_len; i++) { unsigned int length = sg_dma_len(&data->sg[i]); u32 mem_addr = sg_dma_address(&data->sg[i]); - /* - * Set the OWN bit and disable interrupts for this - * descriptor - */ - desc->des0 = cpu_to_le32(IDMAC_DES0_OWN | - IDMAC_DES0_DIC | IDMAC_DES0_CH); - /* Buffer length */ - IDMAC_SET_BUFFER1_SIZE(desc, length); + for ( ; length ; desc++) { + desc_len = (length <= DW_MCI_DESC_DATA_LENGTH) ? + length : DW_MCI_DESC_DATA_LENGTH; + + length -= desc_len; + + /* + * Set the OWN bit and disable interrupts + * for this descriptor + */ + desc->des0 = cpu_to_le32(IDMAC_DES0_OWN | + IDMAC_DES0_DIC | + IDMAC_DES0_CH); + + /* Buffer length */ + IDMAC_SET_BUFFER1_SIZE(desc, desc_len); - /* Physical address to DMA to/from */ - desc->des2 = cpu_to_le32(mem_addr); + /* Physical address to DMA to/from */ + desc->des2 = cpu_to_le32(mem_addr); + + /* Update physical address for the next desc */ + mem_addr += desc_len; + + /* Save pointer to the last descriptor */ + desc_last = desc; + } } /* Set first descriptor */ - desc = host->sg_cpu; - desc->des0 |= cpu_to_le32(IDMAC_DES0_FD); + desc_first->des0 |= cpu_to_le32(IDMAC_DES0_FD); /* Set last descriptor */ - desc = host->sg_cpu + (i - 1) * sizeof(struct idmac_desc); - desc->des0 &= cpu_to_le32(~(IDMAC_DES0_CH | IDMAC_DES0_DIC)); - desc->des0 |= cpu_to_le32(IDMAC_DES0_LD); + desc_last->des0 &= cpu_to_le32(~(IDMAC_DES0_CH | + IDMAC_DES0_DIC)); + desc_last->des0 |= cpu_to_le32(IDMAC_DES0_LD); } wmb(); @@ -2394,7 +2427,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) #ifdef CONFIG_MMC_DW_IDMAC mmc->max_segs = host->ring_size; mmc->max_blk_size = 65536; - mmc->max_seg_size = 0x1000; + mmc->max_seg_size = DW_MCI_DESC_DATA_LENGTH; mmc->max_req_size = mmc->max_seg_size * host->ring_size; mmc->max_blk_count = mmc->max_req_size / 512; #else diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 946d37f94..f5edf9d3a 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c @@ -135,6 +135,7 @@ static int armada_38x_quirks(struct platform_device *pdev, struct sdhci_pxa *pxa = pltfm_host->priv; struct resource *res; + host->quirks &= ~SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN; host->quirks |= SDHCI_QUIRK_MISSING_CAPS; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "conf-sdio3"); @@ -290,6 +291,9 @@ static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs) uhs == MMC_TIMING_UHS_DDR50) { reg_val &= ~SDIO3_CONF_CLK_INV; reg_val |= SDIO3_CONF_SD_FB_CLK; + } else if (uhs == MMC_TIMING_MMC_HS) { + reg_val &= ~SDIO3_CONF_CLK_INV; + reg_val &= ~SDIO3_CONF_SD_FB_CLK; } else { reg_val |= SDIO3_CONF_CLK_INV; reg_val &= ~SDIO3_CONF_SD_FB_CLK; @@ -398,7 +402,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { ret = armada_38x_quirks(pdev, host); if (ret < 0) - goto err_clk_get; + goto err_mbus_win; ret = mv_conf_mbus_windows(pdev, mv_mbus_dram_info()); if (ret < 0) goto err_mbus_win; diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 1259cc558..5465fa439 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -1473,6 +1473,9 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) if (pdata->keep_config && !pxa3xx_nand_detect_config(info)) goto KEEP_CONFIG; + /* Set a default chunk size */ + info->chunk_size = 512; + ret = pxa3xx_nand_sensing(info); if (ret) { dev_info(&info->pdev->dev, "There is no chip on cs %d!\n", diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index 6f93b2990..499b8e433 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -138,6 +138,10 @@ #define NFC_ECC_MODE GENMASK(15, 12) #define NFC_RANDOM_SEED GENMASK(30, 16) +/* NFC_USER_DATA helper macros */ +#define NFC_BUF_TO_USER_DATA(buf) ((buf)[0] | ((buf)[1] << 8) | \ + ((buf)[2] << 16) | ((buf)[3] << 24)) + #define NFC_DEFAULT_TIMEOUT_MS 1000 #define NFC_SRAM_SIZE 1024 @@ -632,15 +636,9 @@ static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd, offset = layout->eccpos[i * ecc->bytes] - 4 + mtd->writesize; /* Fill OOB data in */ - if (oob_required) { - tmp = 0xffffffff; - memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, &tmp, - 4); - } else { - memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, - chip->oob_poi + offset - mtd->writesize, - 4); - } + writel(NFC_BUF_TO_USER_DATA(chip->oob_poi + + layout->oobfree[i].offset), + nfc->regs + NFC_REG_USER_DATA_BASE); chip->cmdfunc(mtd, NAND_CMD_RNDIN, offset, -1); @@ -770,14 +768,8 @@ static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd, offset += ecc->size; /* Fill OOB data in */ - if (oob_required) { - tmp = 0xffffffff; - memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, &tmp, - 4); - } else { - memcpy_toio(nfc->regs + NFC_REG_USER_DATA_BASE, oob, - 4); - } + writel(NFC_BUF_TO_USER_DATA(oob), + nfc->regs + NFC_REG_USER_DATA_BASE); tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ACCESS_DIR | (1 << 30); @@ -1312,6 +1304,7 @@ static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc) node); nand_release(&chip->mtd); sunxi_nand_ecc_cleanup(&chip->nand.ecc); + list_del(&chip->node); } } diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 5bbd1f094..1fc23e48f 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c @@ -926,6 +926,11 @@ static int validate_vid_hdr(const struct ubi_device *ubi, goto bad; } + if (data_size > ubi->leb_size) { + ubi_err(ubi, "bad data_size"); + goto bad; + } + if (vol_type == UBI_VID_STATIC) { /* * Although from high-level point of view static volumes may diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 80bdd5b88..d85c19762 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -649,6 +649,7 @@ static int init_volumes(struct ubi_device *ubi, if (ubi->corr_peb_count) ubi_err(ubi, "%d PEBs are corrupted and not used", ubi->corr_peb_count); + return -ENOSPC; } ubi->rsvd_pebs += reserved_pebs; ubi->avail_pebs -= reserved_pebs; diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 275d9fb6f..eb4489f90 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -1601,6 +1601,7 @@ int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai) if (ubi->corr_peb_count) ubi_err(ubi, "%d PEBs are corrupted and not used", ubi->corr_peb_count); + err = -ENOSPC; goto out_free; } ubi->avail_pebs -= reserved_pebs; diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 8d7b59689..5bc9fca67 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -2851,7 +2851,7 @@ static void igb_probe_vfs(struct igb_adapter *adapter) return; pci_sriov_set_totalvfs(pdev, 7); - igb_pci_enable_sriov(pdev, max_vfs); + igb_enable_sriov(pdev, max_vfs); #endif /* CONFIG_PCI_IOV */ } diff --git a/drivers/net/ethernet/via/Kconfig b/drivers/net/ethernet/via/Kconfig index 2f1264b88..d3d094742 100644 --- a/drivers/net/ethernet/via/Kconfig +++ b/drivers/net/ethernet/via/Kconfig @@ -17,7 +17,7 @@ if NET_VENDOR_VIA config VIA_RHINE tristate "VIA Rhine support" - depends on (PCI || OF_IRQ) + depends on PCI || (OF_IRQ && GENERIC_PCI_IOMAP) depends on HAS_DMA select CRC32 select MII diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c index 85bfa2acb..32d9ff1b1 100644 --- a/drivers/net/wireless/ath/ath10k/htc.c +++ b/drivers/net/wireless/ath/ath10k/htc.c @@ -145,8 +145,10 @@ int ath10k_htc_send(struct ath10k_htc *htc, skb_cb->eid = eid; skb_cb->paddr = dma_map_single(dev, skb->data, skb->len, DMA_TO_DEVICE); ret = dma_mapping_error(dev, skb_cb->paddr); - if (ret) + if (ret) { + ret = -EIO; goto err_credits; + } sg_item.transfer_id = ep->eid; sg_item.transfer_context = skb; diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index a60ef7d1d..7be3ce6e0 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -371,8 +371,10 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len, DMA_TO_DEVICE); res = dma_mapping_error(dev, skb_cb->paddr); - if (res) + if (res) { + res = -EIO; goto err_free_txdesc; + } skb_put(txdesc, len); cmd = (struct htt_cmd *)txdesc->data; @@ -456,8 +458,10 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len, DMA_TO_DEVICE); res = dma_mapping_error(dev, skb_cb->paddr); - if (res) + if (res) { + res = -EIO; goto err_free_txbuf; + } switch (skb_cb->txmode) { case ATH10K_HW_TXRX_RAW: diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 218b6af63..0d3c474ff 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -591,11 +591,19 @@ ath10k_mac_get_any_chandef_iter(struct ieee80211_hw *hw, static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr, enum wmi_peer_type peer_type) { + struct ath10k_vif *arvif; + int num_peers = 0; int ret; lockdep_assert_held(&ar->conf_mutex); - if (ar->num_peers >= ar->max_num_peers) + num_peers = ar->num_peers; + + /* Each vdev consumes a peer entry as well */ + list_for_each_entry(arvif, &ar->arvifs, list) + num_peers++; + + if (num_peers >= ar->max_num_peers) return -ENOBUFS; ret = ath10k_wmi_peer_create(ar, vdev_id, addr, peer_type); @@ -2995,6 +3003,8 @@ void ath10k_mac_tx_unlock(struct ath10k *ar, int reason) IEEE80211_IFACE_ITER_RESUME_ALL, ath10k_mac_tx_unlock_iter, ar); + + ieee80211_wake_queue(ar->hw, ar->hw->offchannel_tx_hw_queue); } void ath10k_mac_vif_tx_lock(struct ath10k_vif *arvif, int reason) @@ -3034,38 +3044,16 @@ static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif, lockdep_assert_held(&ar->htt.tx_lock); - switch (pause_id) { - case WMI_TLV_TX_PAUSE_ID_MCC: - case WMI_TLV_TX_PAUSE_ID_P2P_CLI_NOA: - case WMI_TLV_TX_PAUSE_ID_P2P_GO_PS: - case WMI_TLV_TX_PAUSE_ID_AP_PS: - case WMI_TLV_TX_PAUSE_ID_IBSS_PS: - switch (action) { - case WMI_TLV_TX_PAUSE_ACTION_STOP: - ath10k_mac_vif_tx_lock(arvif, pause_id); - break; - case WMI_TLV_TX_PAUSE_ACTION_WAKE: - ath10k_mac_vif_tx_unlock(arvif, pause_id); - break; - default: - ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n", - action, arvif->vdev_id); - break; - } + switch (action) { + case WMI_TLV_TX_PAUSE_ACTION_STOP: + ath10k_mac_vif_tx_lock(arvif, pause_id); + break; + case WMI_TLV_TX_PAUSE_ACTION_WAKE: + ath10k_mac_vif_tx_unlock(arvif, pause_id); break; - case WMI_TLV_TX_PAUSE_ID_AP_PEER_PS: - case WMI_TLV_TX_PAUSE_ID_AP_PEER_UAPSD: - case WMI_TLV_TX_PAUSE_ID_STA_ADD_BA: - case WMI_TLV_TX_PAUSE_ID_HOST: default: - /* FIXME: Some pause_ids aren't vdev specific. Instead they - * target peer_id and tid. Implementing these could improve - * traffic scheduling fairness across multiple connected - * stations in AP/IBSS modes. - */ - ath10k_dbg(ar, ATH10K_DBG_MAC, - "mac ignoring unsupported tx pause vdev %i id %d\n", - arvif->vdev_id, pause_id); + ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n", + action, arvif->vdev_id); break; } } @@ -3082,12 +3070,15 @@ static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac, struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); struct ath10k_mac_tx_pause *arg = data; + if (arvif->vdev_id != arg->vdev_id) + return; + ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action); } -void ath10k_mac_handle_tx_pause(struct ath10k *ar, u32 vdev_id, - enum wmi_tlv_tx_pause_id pause_id, - enum wmi_tlv_tx_pause_action action) +void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id, + enum wmi_tlv_tx_pause_id pause_id, + enum wmi_tlv_tx_pause_action action) { struct ath10k_mac_tx_pause arg = { .vdev_id = vdev_id, @@ -4080,6 +4071,11 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, sizeof(arvif->bitrate_mask.control[i].vht_mcs)); } + if (ar->num_peers >= ar->max_num_peers) { + ath10k_warn(ar, "refusing vdev creation due to insufficient peer entry resources in firmware\n"); + return -ENOBUFS; + } + if (ar->free_vdev_map == 0) { ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n"); ret = -EBUSY; @@ -4287,6 +4283,11 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, } } + spin_lock_bh(&ar->htt.tx_lock); + if (!ar->tx_paused) + ieee80211_wake_queue(ar->hw, arvif->vdev_id); + spin_unlock_bh(&ar->htt.tx_lock); + mutex_unlock(&ar->conf_mutex); return 0; @@ -5561,6 +5562,21 @@ static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value) return ret; } +static int ath10k_mac_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) +{ + /* Even though there's a WMI enum for fragmentation threshold no known + * firmware actually implements it. Moreover it is not possible to rely + * frame fragmentation to mac80211 because firmware clears the "more + * fragments" bit in frame control making it impossible for remote + * devices to reassemble frames. + * + * Hence implement a dummy callback just to say fragmentation isn't + * supported. This effectively prevents mac80211 from doing frame + * fragmentation in software. + */ + return -EOPNOTSUPP; +} + static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 queues, bool drop) { @@ -6395,6 +6411,7 @@ static const struct ieee80211_ops ath10k_ops = { .remain_on_channel = ath10k_remain_on_channel, .cancel_remain_on_channel = ath10k_cancel_remain_on_channel, .set_rts_threshold = ath10k_set_rts_threshold, + .set_frag_threshold = ath10k_mac_op_set_frag_threshold, .flush = ath10k_flush, .tx_last_beacon = ath10k_tx_last_beacon, .set_antenna = ath10k_set_antenna, diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h index b291f0637..e3cefe4c7 100644 --- a/drivers/net/wireless/ath/ath10k/mac.h +++ b/drivers/net/wireless/ath/ath10k/mac.h @@ -61,9 +61,9 @@ int ath10k_mac_vif_chan(struct ieee80211_vif *vif, void ath10k_mac_handle_beacon(struct ath10k *ar, struct sk_buff *skb); void ath10k_mac_handle_beacon_miss(struct ath10k *ar, u32 vdev_id); -void ath10k_mac_handle_tx_pause(struct ath10k *ar, u32 vdev_id, - enum wmi_tlv_tx_pause_id pause_id, - enum wmi_tlv_tx_pause_action action); +void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id, + enum wmi_tlv_tx_pause_id pause_id, + enum wmi_tlv_tx_pause_action action); u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband, u8 hw_rate); diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index ecc9ab57b..79b707138 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -1546,8 +1546,10 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, req_paddr = dma_map_single(ar->dev, treq, req_len, DMA_TO_DEVICE); ret = dma_mapping_error(ar->dev, req_paddr); - if (ret) + if (ret) { + ret = -EIO; goto err_dma; + } if (resp && resp_len) { tresp = kzalloc(*resp_len, GFP_KERNEL); @@ -1559,8 +1561,10 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, resp_paddr = dma_map_single(ar->dev, tresp, *resp_len, DMA_FROM_DEVICE); ret = dma_mapping_error(ar->dev, resp_paddr); - if (ret) + if (ret) { + ret = EIO; goto err_req; + } xfer.wait_for_resp = true; xfer.resp_len = 0; diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 8fdba3865..6f477e830 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -377,12 +377,34 @@ static int ath10k_wmi_tlv_event_tx_pause(struct ath10k *ar, "wmi tlv tx pause pause_id %u action %u vdev_map 0x%08x peer_id %u tid_map 0x%08x\n", pause_id, action, vdev_map, peer_id, tid_map); - for (vdev_id = 0; vdev_map; vdev_id++) { - if (!(vdev_map & BIT(vdev_id))) - continue; - - vdev_map &= ~BIT(vdev_id); - ath10k_mac_handle_tx_pause(ar, vdev_id, pause_id, action); + switch (pause_id) { + case WMI_TLV_TX_PAUSE_ID_MCC: + case WMI_TLV_TX_PAUSE_ID_P2P_CLI_NOA: + case WMI_TLV_TX_PAUSE_ID_P2P_GO_PS: + case WMI_TLV_TX_PAUSE_ID_AP_PS: + case WMI_TLV_TX_PAUSE_ID_IBSS_PS: + for (vdev_id = 0; vdev_map; vdev_id++) { + if (!(vdev_map & BIT(vdev_id))) + continue; + + vdev_map &= ~BIT(vdev_id); + ath10k_mac_handle_tx_pause_vdev(ar, vdev_id, pause_id, + action); + } + break; + case WMI_TLV_TX_PAUSE_ID_AP_PEER_PS: + case WMI_TLV_TX_PAUSE_ID_AP_PEER_UAPSD: + case WMI_TLV_TX_PAUSE_ID_STA_ADD_BA: + case WMI_TLV_TX_PAUSE_ID_HOST: + ath10k_dbg(ar, ATH10K_DBG_MAC, + "mac ignoring unsupported tx pause id %d\n", + pause_id); + break; + default: + ath10k_dbg(ar, ATH10K_DBG_MAC, + "mac ignoring unknown tx pause vdev %d\n", + pause_id); + break; } kfree(tb); diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index 6c046c244..8dd84c160 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -2391,6 +2391,7 @@ void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) ath10k_warn(ar, "failed to map beacon: %d\n", ret); dev_kfree_skb_any(bcn); + ret = -EIO; goto skip; } diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c index afd382417..6eb4d21e3 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c @@ -203,8 +203,10 @@ static int rsi_load_ta_instructions(struct rsi_common *common) /* Copy firmware into DMA-accessible memory */ fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); - if (!fw) - return -ENOMEM; + if (!fw) { + status = -ENOMEM; + goto out; + } len = fw_entry->size; if (len % 4) @@ -217,6 +219,8 @@ static int rsi_load_ta_instructions(struct rsi_common *common) status = rsi_copy_to_card(common, fw, len, num_blocks); kfree(fw); + +out: release_firmware(fw_entry); return status; } diff --git a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c index c8cfb4a1c..3bd8fba4f 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb_ops.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb_ops.c @@ -148,8 +148,10 @@ static int rsi_load_ta_instructions(struct rsi_common *common) /* Copy firmware into DMA-accessible memory */ fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); - if (!fw) - return -ENOMEM; + if (!fw) { + status = -ENOMEM; + goto out; + } len = fw_entry->size; if (len % 4) @@ -162,6 +164,8 @@ static int rsi_load_ta_instructions(struct rsi_common *common) status = rsi_copy_to_card(common, fw, len, num_blocks); kfree(fw); + +out: release_firmware(fw_entry); return status; } diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index f948c46d5..5ff0cfd14 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1348,7 +1348,8 @@ static void xennet_disconnect_backend(struct netfront_info *info) queue->tx_evtchn = queue->rx_evtchn = 0; queue->tx_irq = queue->rx_irq = 0; - napi_synchronize(&queue->napi); + if (netif_running(info->netdev)) + napi_synchronize(&queue->napi); xennet_release_tx_bufs(queue); xennet_release_rx_bufs(queue); diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index ade9eb917..b796d1bd8 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -86,6 +86,8 @@ static int pmem_rw_page(struct block_device *bdev, sector_t sector, struct pmem_device *pmem = bdev->bd_disk->private_data; pmem_do_bvec(pmem, page, PAGE_CACHE_SIZE, 0, rw, sector); + if (rw & WRITE) + wmb_pmem(); page_endio(page, rw & WRITE, 0); return 0; diff --git a/drivers/pci/access.c b/drivers/pci/access.c index b965c1216..502a82ca1 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -442,7 +442,8 @@ static const struct pci_vpd_ops pci_vpd_pci22_ops = { static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count, void *arg) { - struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn)); + struct pci_dev *tdev = pci_get_slot(dev->bus, + PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); ssize_t ret; if (!tdev) @@ -456,7 +457,8 @@ static ssize_t pci_vpd_f0_read(struct pci_dev *dev, loff_t pos, size_t count, static ssize_t pci_vpd_f0_write(struct pci_dev *dev, loff_t pos, size_t count, const void *arg) { - struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn)); + struct pci_dev *tdev = pci_get_slot(dev->bus, + PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); ssize_t ret; if (!tdev) @@ -473,22 +475,6 @@ static const struct pci_vpd_ops pci_vpd_f0_ops = { .release = pci_vpd_pci22_release, }; -static int pci_vpd_f0_dev_check(struct pci_dev *dev) -{ - struct pci_dev *tdev = pci_get_slot(dev->bus, PCI_SLOT(dev->devfn)); - int ret = 0; - - if (!tdev) - return -ENODEV; - if (!tdev->vpd || !tdev->multifunction || - dev->class != tdev->class || dev->vendor != tdev->vendor || - dev->device != tdev->device) - ret = -ENODEV; - - pci_dev_put(tdev); - return ret; -} - int pci_vpd_pci22_init(struct pci_dev *dev) { struct pci_vpd_pci22 *vpd; @@ -497,12 +483,7 @@ int pci_vpd_pci22_init(struct pci_dev *dev) cap = pci_find_capability(dev, PCI_CAP_ID_VPD); if (!cap) return -ENODEV; - if (dev->dev_flags & PCI_DEV_FLAGS_VPD_REF_F0) { - int ret = pci_vpd_f0_dev_check(dev); - if (ret) - return ret; - } vpd = kzalloc(sizeof(*vpd), GFP_ATOMIC); if (!vpd) return -ENOMEM; diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 6fbd3f2b5..d3346d239 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -256,6 +256,8 @@ bool pci_bus_clip_resource(struct pci_dev *dev, int idx) res->start = start; res->end = end; + res->flags &= ~IORESOURCE_UNSET; + orig_res.flags &= ~IORESOURCE_UNSET; dev_printk(KERN_DEBUG, &dev->dev, "%pR clipped to %pR\n", &orig_res, res); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index dbd13854f..6b1c6a915 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1906,11 +1906,27 @@ static void quirk_netmos(struct pci_dev *dev) DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos); +/* + * Quirk non-zero PCI functions to route VPD access through function 0 for + * devices that share VPD resources between functions. The functions are + * expected to be identical devices. + */ static void quirk_f0_vpd_link(struct pci_dev *dev) { - if (!dev->multifunction || !PCI_FUNC(dev->devfn)) + struct pci_dev *f0; + + if (!PCI_FUNC(dev->devfn)) return; - dev->dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0; + + f0 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0)); + if (!f0) + return; + + if (f0->vpd && dev->class == f0->class && + dev->vendor == f0->vendor && dev->device == f0->device) + dev->dev_flags |= PCI_DEV_FLAGS_VPD_REF_F0; + + pci_dev_put(f0); } DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_NETWORK_ETHERNET, 8, quirk_f0_vpd_link); diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index 803945259..42861cc70 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c @@ -93,7 +93,6 @@ static int sa11x0_drv_pcmcia_remove(struct platform_device *dev) for (i = 0; i < sinfo->nskt; i++) soc_pcmcia_remove_one(&sinfo->skt[i]); - clk_put(sinfo->clk); kfree(sinfo); return 0; } diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c index cf6de2c2b..553d70a67 100644 --- a/drivers/pcmcia/sa11xx_base.c +++ b/drivers/pcmcia/sa11xx_base.c @@ -222,7 +222,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int i, ret = 0; struct clk *clk; - clk = clk_get(dev, NULL); + clk = devm_clk_get(dev, NULL); if (IS_ERR(clk)) return PTR_ERR(clk); @@ -251,7 +251,6 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, if (ret) { while (--i >= 0) soc_pcmcia_remove_one(&sinfo->skt[i]); - clk_put(clk); kfree(sinfo); } else { dev_set_drvdata(dev, sinfo); diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 3ad7b1fa2..6f4f310de 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -2408,11 +2408,9 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) if (error) return error; - error = toshiba_hotkey_event_type_get(dev, &events_type); - if (error) { - pr_err("Unable to query Hotkey Event Type\n"); - return error; - } + if (toshiba_hotkey_event_type_get(dev, &events_type)) + pr_notice("Unable to query Hotkey Event Type\n"); + dev->hotkey_event_type = events_type; dev->hotkey_dev = input_allocate_device(); diff --git a/drivers/power/avs/Kconfig b/drivers/power/avs/Kconfig index 7f3d389bd..a67eeace6 100644 --- a/drivers/power/avs/Kconfig +++ b/drivers/power/avs/Kconfig @@ -13,7 +13,7 @@ menuconfig POWER_AVS config ROCKCHIP_IODOMAIN tristate "Rockchip IO domain support" - depends on ARCH_ROCKCHIP && OF + depends on POWER_AVS && ARCH_ROCKCHIP && OF help Say y here to enable support io domains on Rockchip SoCs. It is necessary for the io domain setting of the SoC to match the diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index 646829132..1dea0e835 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c @@ -192,9 +192,9 @@ static const struct regulator_desc axp22x_regulators[] = { AXP_DESC(AXP22X, DCDC3, "dcdc3", "vin3", 600, 1860, 20, AXP22X_DCDC3_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(3)), AXP_DESC(AXP22X, DCDC4, "dcdc4", "vin4", 600, 1540, 20, - AXP22X_DCDC4_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(3)), + AXP22X_DCDC4_V_OUT, 0x3f, AXP22X_PWR_OUT_CTRL1, BIT(4)), AXP_DESC(AXP22X, DCDC5, "dcdc5", "vin5", 1000, 2550, 50, - AXP22X_DCDC5_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(4)), + AXP22X_DCDC5_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL1, BIT(5)), /* secondary switchable output of DCDC1 */ AXP_DESC_SW(AXP22X, DC1SW, "dc1sw", "dcdc1", 1600, 3400, 100, AXP22X_DCDC1_V_OUT, 0x1f, AXP22X_PWR_OUT_CTRL2, BIT(7)), diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 78387a6cb..508153385 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1376,15 +1376,19 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) return 0; r = regulator_dev_lookup(dev, rdev->supply_name, &ret); - if (ret == -ENODEV) { - /* - * No supply was specified for this regulator and - * there will never be one. - */ - return 0; - } - if (!r) { + if (ret == -ENODEV) { + /* + * No supply was specified for this regulator and + * there will never be one. + */ + return 0; + } + + /* Did the lookup explicitly defer for us? */ + if (ret == -EPROBE_DEFER) + return ret; + if (have_full_constraints()) { r = dummy_regulator_rdev; } else { diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index add419d6f..a56a7b243 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -212,6 +212,17 @@ static const struct file_operations twa_fops = { .llseek = noop_llseek, }; +/* + * The controllers use an inline buffer instead of a mapped SGL for small, + * single entry buffers. Note that we treat a zero-length transfer like + * a mapped SGL. + */ +static bool twa_command_mapped(struct scsi_cmnd *cmd) +{ + return scsi_sg_count(cmd) != 1 || + scsi_bufflen(cmd) >= TW_MIN_SGL_LENGTH; +} + /* This function will complete an aen request from the isr */ static int twa_aen_complete(TW_Device_Extension *tw_dev, int request_id) { @@ -1339,7 +1350,8 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) } /* Now complete the io */ - scsi_dma_unmap(cmd); + if (twa_command_mapped(cmd)) + scsi_dma_unmap(cmd); cmd->scsi_done(cmd); tw_dev->state[request_id] = TW_S_COMPLETED; twa_free_request_id(tw_dev, request_id); @@ -1582,7 +1594,8 @@ static int twa_reset_device_extension(TW_Device_Extension *tw_dev) struct scsi_cmnd *cmd = tw_dev->srb[i]; cmd->result = (DID_RESET << 16); - scsi_dma_unmap(cmd); + if (twa_command_mapped(cmd)) + scsi_dma_unmap(cmd); cmd->scsi_done(cmd); } } @@ -1765,12 +1778,14 @@ static int twa_scsi_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_ retval = twa_scsiop_execute_scsi(tw_dev, request_id, NULL, 0, NULL); switch (retval) { case SCSI_MLQUEUE_HOST_BUSY: - scsi_dma_unmap(SCpnt); + if (twa_command_mapped(SCpnt)) + scsi_dma_unmap(SCpnt); twa_free_request_id(tw_dev, request_id); break; case 1: SCpnt->result = (DID_ERROR << 16); - scsi_dma_unmap(SCpnt); + if (twa_command_mapped(SCpnt)) + scsi_dma_unmap(SCpnt); done(SCpnt); tw_dev->state[request_id] = TW_S_COMPLETED; twa_free_request_id(tw_dev, request_id); @@ -1831,8 +1846,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, /* Map sglist from scsi layer to cmd packet */ if (scsi_sg_count(srb)) { - if ((scsi_sg_count(srb) == 1) && - (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) { + if (!twa_command_mapped(srb)) { if (srb->sc_data_direction == DMA_TO_DEVICE || srb->sc_data_direction == DMA_BIDIRECTIONAL) scsi_sg_copy_to_buffer(srb, @@ -1905,7 +1919,7 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re { struct scsi_cmnd *cmd = tw_dev->srb[request_id]; - if (scsi_bufflen(cmd) < TW_MIN_SGL_LENGTH && + if (!twa_command_mapped(cmd) && (cmd->sc_data_direction == DMA_FROM_DEVICE || cmd->sc_data_direction == DMA_BIDIRECTIONAL)) { if (scsi_sg_count(cmd) == 1) { diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 1dafeb433..cab4e98b2 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -5104,7 +5104,7 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd) int rc; struct ctlr_info *h; struct hpsa_scsi_dev_t *dev; - char msg[40]; + char msg[48]; /* find the controller to which the command to be aborted was sent */ h = sdev_to_hba(scsicmd->device); @@ -5122,16 +5122,18 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd) /* if controller locked up, we can guarantee command won't complete */ if (lockup_detected(h)) { - sprintf(msg, "cmd %d RESET FAILED, lockup detected", - hpsa_get_cmd_index(scsicmd)); + snprintf(msg, sizeof(msg), + "cmd %d RESET FAILED, lockup detected", + hpsa_get_cmd_index(scsicmd)); hpsa_show_dev_msg(KERN_WARNING, h, dev, msg); return FAILED; } /* this reset request might be the result of a lockup; check */ if (detect_controller_lockup(h)) { - sprintf(msg, "cmd %d RESET FAILED, new lockup detected", - hpsa_get_cmd_index(scsicmd)); + snprintf(msg, sizeof(msg), + "cmd %d RESET FAILED, new lockup detected", + hpsa_get_cmd_index(scsicmd)); hpsa_show_dev_msg(KERN_WARNING, h, dev, msg); return FAILED; } @@ -5145,7 +5147,8 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd) /* send a reset to the SCSI LUN which the command was sent to */ rc = hpsa_do_reset(h, dev, dev->scsi3addr, HPSA_RESET_TYPE_LUN, DEFAULT_REPLY_QUEUE); - sprintf(msg, "reset %s", rc == 0 ? "completed successfully" : "failed"); + snprintf(msg, sizeof(msg), "reset %s", + rc == 0 ? "completed successfully" : "failed"); hpsa_show_dev_msg(KERN_WARNING, h, dev, msg); return rc == 0 ? SUCCESS : FAILED; } diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index a9aa38903..cccab6188 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -4554,7 +4554,7 @@ static ssize_t ipr_store_raw_mode(struct device *dev, spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); res = (struct ipr_resource_entry *)sdev->hostdata; if (res) { - if (ioa_cfg->sis64 && ipr_is_af_dasd_device(res)) { + if (ipr_is_af_dasd_device(res)) { res->raw_mode = simple_strtoul(buf, NULL, 10); len = strlen(buf); if (res->sdev) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 6457a8a0d..bf3d801ac 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -2169,8 +2169,17 @@ int scsi_error_handler(void *data) * We never actually get interrupted because kthread_run * disables signal delivery for the created thread. */ - while (!kthread_should_stop()) { + while (true) { + /* + * The sequence in kthread_stop() sets the stop flag first + * then wakes the process. To avoid missed wakeups, the task + * should always be in a non running state before the stop + * flag is checked + */ set_current_state(TASK_INTERRUPTIBLE); + if (kthread_should_stop()) + break; + if ((shost->host_failed == 0 && shost->host_eh_scheduled == 0) || shost->host_failed != atomic_read(&shost->host_busy)) { SCSI_LOG_ERROR_RECOVERY(1, diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index c9357bb39..744596464 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -386,14 +386,14 @@ static bool bcm2835_spi_can_dma(struct spi_master *master, /* otherwise we only allow transfers within the same page * to avoid wasting time on dma_mapping when it is not practical */ - if (((size_t)tfr->tx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) { + if (((size_t)tfr->tx_buf & (PAGE_SIZE - 1)) + tfr->len > PAGE_SIZE) { dev_warn_once(&spi->dev, "Unaligned spi tx-transfer bridging page\n"); return false; } - if (((size_t)tfr->rx_buf & PAGE_MASK) + tfr->len > PAGE_SIZE) { + if (((size_t)tfr->rx_buf & (PAGE_SIZE - 1)) + tfr->len > PAGE_SIZE) { dev_warn_once(&spi->dev, - "Unaligned spi tx-transfer bridging page\n"); + "Unaligned spi rx-transfer bridging page\n"); return false; } diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 7293d6d87..8e4b1a7c3 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -643,6 +643,10 @@ static irqreturn_t ssp_int(int irq, void *dev_id) if (!(sccr1_reg & SSCR1_TIE)) mask &= ~SSSR_TFS; + /* Ignore RX timeout interrupt if it is disabled */ + if (!(sccr1_reg & SSCR1_TINTE)) + mask &= ~SSSR_TINT; + if (!(status & mask)) return IRQ_NONE; diff --git a/drivers/spi/spi-xtensa-xtfpga.c b/drivers/spi/spi-xtensa-xtfpga.c index 2e32ea2f1..be6155cba 100644 --- a/drivers/spi/spi-xtensa-xtfpga.c +++ b/drivers/spi/spi-xtensa-xtfpga.c @@ -34,13 +34,13 @@ struct xtfpga_spi { static inline void xtfpga_spi_write32(const struct xtfpga_spi *spi, unsigned addr, u32 val) { - iowrite32(val, spi->regs + addr); + __raw_writel(val, spi->regs + addr); } static inline unsigned int xtfpga_spi_read32(const struct xtfpga_spi *spi, unsigned addr) { - return ioread32(spi->regs + addr); + return __raw_readl(spi->regs + addr); } static inline void xtfpga_spi_wait_busy(struct xtfpga_spi *xspi) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index cf8b91b23..9ce2f156d 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -1437,8 +1437,7 @@ static struct class spi_master_class = { * * The caller is responsible for assigning the bus number and initializing * the master's methods before calling spi_register_master(); and (after errors - * adding the device) calling spi_master_put() and kfree() to prevent a memory - * leak. + * adding the device) calling spi_master_put() to prevent a memory leak. */ struct spi_master *spi_alloc_master(struct device *dev, unsigned size) { diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index c7de64171..97aad8f91 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -651,7 +651,8 @@ static int spidev_release(struct inode *inode, struct file *filp) kfree(spidev->rx_buffer); spidev->rx_buffer = NULL; - spidev->speed_hz = spidev->spi->max_speed_hz; + if (spidev->spi) + spidev->speed_hz = spidev->spi->max_speed_hz; /* ... after we unbound from the underlying device? */ spin_lock_irq(&spidev->spi_lock); diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 6f4811263..b71b1f2d9 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1179,13 +1179,13 @@ struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd) mutex_unlock(&client->lock); goto end; } - mutex_unlock(&client->lock); handle = ion_handle_create(client, buffer); - if (IS_ERR(handle)) + if (IS_ERR(handle)) { + mutex_unlock(&client->lock); goto end; + } - mutex_lock(&client->lock); ret = ion_handle_add(client, handle); mutex_unlock(&client->lock); if (ret) { diff --git a/drivers/staging/speakup/fakekey.c b/drivers/staging/speakup/fakekey.c index 4299cf45f..5e1f16c36 100644 --- a/drivers/staging/speakup/fakekey.c +++ b/drivers/staging/speakup/fakekey.c @@ -81,6 +81,7 @@ void speakup_fake_down_arrow(void) __this_cpu_write(reporting_keystroke, true); input_report_key(virt_keyboard, KEY_DOWN, PRESSED); input_report_key(virt_keyboard, KEY_DOWN, RELEASED); + input_sync(virt_keyboard); __this_cpu_write(reporting_keystroke, false); /* reenable preemption */ diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index fd092909a..56cf1996f 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -341,7 +341,6 @@ static struct iscsi_np *iscsit_get_np( struct iscsi_np *iscsit_add_np( struct __kernel_sockaddr_storage *sockaddr, - char *ip_str, int network_transport) { struct sockaddr_in *sock_in; @@ -370,11 +369,9 @@ struct iscsi_np *iscsit_add_np( np->np_flags |= NPF_IP_NETWORK; if (sockaddr->ss_family == AF_INET6) { sock_in6 = (struct sockaddr_in6 *)sockaddr; - snprintf(np->np_ip, IPV6_ADDRESS_SPACE, "%s", ip_str); np->np_port = ntohs(sock_in6->sin6_port); } else { sock_in = (struct sockaddr_in *)sockaddr; - sprintf(np->np_ip, "%s", ip_str); np->np_port = ntohs(sock_in->sin_port); } @@ -411,8 +408,8 @@ struct iscsi_np *iscsit_add_np( list_add_tail(&np->np_list, &g_np_list); mutex_unlock(&np_lock); - pr_debug("CORE[0] - Added Network Portal: %s:%hu on %s\n", - np->np_ip, np->np_port, np->np_transport->name); + pr_debug("CORE[0] - Added Network Portal: %pISc:%hu on %s\n", + &np->np_sockaddr, np->np_port, np->np_transport->name); return np; } @@ -481,8 +478,8 @@ int iscsit_del_np(struct iscsi_np *np) list_del(&np->np_list); mutex_unlock(&np_lock); - pr_debug("CORE[0] - Removed Network Portal: %s:%hu on %s\n", - np->np_ip, np->np_port, np->np_transport->name); + pr_debug("CORE[0] - Removed Network Portal: %pISc:%hu on %s\n", + &np->np_sockaddr, np->np_port, np->np_transport->name); iscsit_put_transport(np->np_transport); kfree(np); @@ -3464,7 +3461,6 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, tpg_np_list) { struct iscsi_np *np = tpg_np->tpg_np; bool inaddr_any = iscsit_check_inaddr_any(np); - char *fmt_str; if (np->np_network_transport != network_transport) continue; @@ -3492,15 +3488,18 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd, } } - if (np->np_sockaddr.ss_family == AF_INET6) - fmt_str = "TargetAddress=[%s]:%hu,%hu"; - else - fmt_str = "TargetAddress=%s:%hu,%hu"; - - len = sprintf(buf, fmt_str, - inaddr_any ? conn->local_ip : np->np_ip, - np->np_port, - tpg->tpgt); + if (inaddr_any) { + len = sprintf(buf, "TargetAddress=" + "%s:%hu,%hu", + conn->local_ip, + np->np_port, + tpg->tpgt); + } else { + len = sprintf(buf, "TargetAddress=" + "%pISpc,%hu", + &np->np_sockaddr, + tpg->tpgt); + } len += 1; if ((len + payload_len) > buffer_len) { diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h index 7d0f9c00d..d294f030a 100644 --- a/drivers/target/iscsi/iscsi_target.h +++ b/drivers/target/iscsi/iscsi_target.h @@ -13,7 +13,7 @@ extern int iscsit_deaccess_np(struct iscsi_np *, struct iscsi_portal_group *, extern bool iscsit_check_np_match(struct __kernel_sockaddr_storage *, struct iscsi_np *, int); extern struct iscsi_np *iscsit_add_np(struct __kernel_sockaddr_storage *, - char *, int); + int); extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *, struct iscsi_portal_group *, bool); extern int iscsit_del_np(struct iscsi_np *); diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index c1898c84b..db3b9b986 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -99,7 +99,7 @@ static ssize_t lio_target_np_store_sctp( * Use existing np->np_sockaddr for SCTP network portal reference */ tpg_np_sctp = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr, - np->np_ip, tpg_np, ISCSI_SCTP_TCP); + tpg_np, ISCSI_SCTP_TCP); if (!tpg_np_sctp || IS_ERR(tpg_np_sctp)) goto out; } else { @@ -177,7 +177,7 @@ static ssize_t lio_target_np_store_iser( } tpg_np_iser = iscsit_tpg_add_network_portal(tpg, &np->np_sockaddr, - np->np_ip, tpg_np, ISCSI_INFINIBAND); + tpg_np, ISCSI_INFINIBAND); if (IS_ERR(tpg_np_iser)) { rc = PTR_ERR(tpg_np_iser); goto out; @@ -248,8 +248,8 @@ static struct se_tpg_np *lio_target_call_addnptotpg( return ERR_PTR(-EINVAL); } str++; /* Skip over leading "[" */ - *str2 = '\0'; /* Terminate the IPv6 address */ - str2++; /* Skip over the "]" */ + *str2 = '\0'; /* Terminate the unbracketed IPv6 address */ + str2++; /* Skip over the \0 */ port_str = strstr(str2, ":"); if (!port_str) { pr_err("Unable to locate \":port\"" @@ -316,7 +316,7 @@ static struct se_tpg_np *lio_target_call_addnptotpg( * sys/kernel/config/iscsi/$IQN/$TPG/np/$IP:$PORT/ * */ - tpg_np = iscsit_tpg_add_network_portal(tpg, &sockaddr, str, NULL, + tpg_np = iscsit_tpg_add_network_portal(tpg, &sockaddr, NULL, ISCSI_TCP); if (IS_ERR(tpg_np)) { iscsit_put_tpg(tpg); @@ -344,8 +344,8 @@ static void lio_target_call_delnpfromtpg( se_tpg = &tpg->tpg_se_tpg; pr_debug("LIO_Target_ConfigFS: DEREGISTER -> %s TPGT: %hu" - " PORTAL: %s:%hu\n", config_item_name(&se_tpg->se_tpg_wwn->wwn_group.cg_item), - tpg->tpgt, tpg_np->tpg_np->np_ip, tpg_np->tpg_np->np_port); + " PORTAL: %pISc:%hu\n", config_item_name(&se_tpg->se_tpg_wwn->wwn_group.cg_item), + tpg->tpgt, &tpg_np->tpg_np->np_sockaddr, tpg_np->tpg_np->np_port); ret = iscsit_tpg_del_network_portal(tpg, tpg_np); if (ret < 0) diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 7e8f65e54..666c0739b 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -823,8 +823,8 @@ static void iscsi_handle_login_thread_timeout(unsigned long data) struct iscsi_np *np = (struct iscsi_np *) data; spin_lock_bh(&np->np_thread_lock); - pr_err("iSCSI Login timeout on Network Portal %s:%hu\n", - np->np_ip, np->np_port); + pr_err("iSCSI Login timeout on Network Portal %pISc:%hu\n", + &np->np_sockaddr, np->np_port); if (np->np_login_timer_flags & ISCSI_TF_STOP) { spin_unlock_bh(&np->np_thread_lock); @@ -1302,8 +1302,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) spin_lock_bh(&np->np_thread_lock); if (np->np_thread_state != ISCSI_NP_THREAD_ACTIVE) { spin_unlock_bh(&np->np_thread_lock); - pr_err("iSCSI Network Portal on %s:%hu currently not" - " active.\n", np->np_ip, np->np_port); + pr_err("iSCSI Network Portal on %pISc:%hu currently not" + " active.\n", &np->np_sockaddr, np->np_port); iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE); goto new_sess_out; diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index e8a52f7d6..51d1734d5 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c @@ -407,6 +407,7 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr) TYPERANGE_UTF8, USE_INITIAL_ONLY); if (!param) goto out; + /* * Extra parameters for ISER from RFC-5046 */ @@ -496,9 +497,9 @@ int iscsi_set_keys_to_negotiate( } else if (!strcmp(param->name, SESSIONTYPE)) { SET_PSTATE_NEGOTIATE(param); } else if (!strcmp(param->name, IFMARKER)) { - SET_PSTATE_NEGOTIATE(param); + SET_PSTATE_REJECT(param); } else if (!strcmp(param->name, OFMARKER)) { - SET_PSTATE_NEGOTIATE(param); + SET_PSTATE_REJECT(param); } else if (!strcmp(param->name, IFMARKINT)) { SET_PSTATE_REJECT(param); } else if (!strcmp(param->name, OFMARKINT)) { diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index 968068ffc..de26bee4b 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c @@ -460,7 +460,6 @@ static bool iscsit_tpg_check_network_portal( struct iscsi_tpg_np *iscsit_tpg_add_network_portal( struct iscsi_portal_group *tpg, struct __kernel_sockaddr_storage *sockaddr, - char *ip_str, struct iscsi_tpg_np *tpg_np_parent, int network_transport) { @@ -470,8 +469,8 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( if (!tpg_np_parent) { if (iscsit_tpg_check_network_portal(tpg->tpg_tiqn, sockaddr, network_transport)) { - pr_err("Network Portal: %s already exists on a" - " different TPG on %s\n", ip_str, + pr_err("Network Portal: %pISc already exists on a" + " different TPG on %s\n", sockaddr, tpg->tpg_tiqn->tiqn); return ERR_PTR(-EEXIST); } @@ -484,7 +483,7 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( return ERR_PTR(-ENOMEM); } - np = iscsit_add_np(sockaddr, ip_str, network_transport); + np = iscsit_add_np(sockaddr, network_transport); if (IS_ERR(np)) { kfree(tpg_np); return ERR_CAST(np); @@ -514,8 +513,8 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( spin_unlock(&tpg_np_parent->tpg_np_parent_lock); } - pr_debug("CORE[%s] - Added Network Portal: %s:%hu,%hu on %s\n", - tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt, + pr_debug("CORE[%s] - Added Network Portal: %pISc:%hu,%hu on %s\n", + tpg->tpg_tiqn->tiqn, &np->np_sockaddr, np->np_port, tpg->tpgt, np->np_transport->name); return tpg_np; @@ -528,8 +527,8 @@ static int iscsit_tpg_release_np( { iscsit_clear_tpg_np_login_thread(tpg_np, tpg, true); - pr_debug("CORE[%s] - Removed Network Portal: %s:%hu,%hu on %s\n", - tpg->tpg_tiqn->tiqn, np->np_ip, np->np_port, tpg->tpgt, + pr_debug("CORE[%s] - Removed Network Portal: %pISc:%hu,%hu on %s\n", + tpg->tpg_tiqn->tiqn, &np->np_sockaddr, np->np_port, tpg->tpgt, np->np_transport->name); tpg_np->tpg_np = NULL; diff --git a/drivers/target/iscsi/iscsi_target_tpg.h b/drivers/target/iscsi/iscsi_target_tpg.h index 95ff5bdec..28abda89e 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.h +++ b/drivers/target/iscsi/iscsi_target_tpg.h @@ -22,7 +22,7 @@ extern struct iscsi_node_attrib *iscsit_tpg_get_node_attrib(struct iscsi_session extern void iscsit_tpg_del_external_nps(struct iscsi_tpg_np *); extern struct iscsi_tpg_np *iscsit_tpg_locate_child_np(struct iscsi_tpg_np *, int); extern struct iscsi_tpg_np *iscsit_tpg_add_network_portal(struct iscsi_portal_group *, - struct __kernel_sockaddr_storage *, char *, struct iscsi_tpg_np *, + struct __kernel_sockaddr_storage *, struct iscsi_tpg_np *, int); extern int iscsit_tpg_del_network_portal(struct iscsi_portal_group *, struct iscsi_tpg_np *); diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 09e682b1c..8f1cd194f 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -427,8 +427,6 @@ void core_disable_device_list_for_node( hlist_del_rcu(&orig->link); clear_bit(DEF_PR_REG_ACTIVE, &orig->deve_flags); - rcu_assign_pointer(orig->se_lun, NULL); - rcu_assign_pointer(orig->se_lun_acl, NULL); orig->lun_flags = 0; orig->creation_time = 0; orig->attach_count--; @@ -439,6 +437,9 @@ void core_disable_device_list_for_node( kref_put(&orig->pr_kref, target_pr_kref_release); wait_for_completion(&orig->pr_comp); + rcu_assign_pointer(orig->se_lun, NULL); + rcu_assign_pointer(orig->se_lun_acl, NULL); + kfree_rcu(orig, rcu_head); core_scsi3_free_pr_reg_from_nacl(dev, nacl); diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 5ab7100de..e79331150 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -618,7 +618,7 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration( struct se_device *dev, struct se_node_acl *nacl, struct se_lun *lun, - struct se_dev_entry *deve, + struct se_dev_entry *dest_deve, u64 mapped_lun, unsigned char *isid, u64 sa_res_key, @@ -640,7 +640,29 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration( INIT_LIST_HEAD(&pr_reg->pr_reg_atp_mem_list); atomic_set(&pr_reg->pr_res_holders, 0); pr_reg->pr_reg_nacl = nacl; - pr_reg->pr_reg_deve = deve; + /* + * For destination registrations for ALL_TG_PT=1 and SPEC_I_PT=1, + * the se_dev_entry->pr_ref will have been already obtained by + * core_get_se_deve_from_rtpi() or __core_scsi3_alloc_registration(). + * + * Otherwise, locate se_dev_entry now and obtain a reference until + * registration completes in __core_scsi3_add_registration(). + */ + if (dest_deve) { + pr_reg->pr_reg_deve = dest_deve; + } else { + rcu_read_lock(); + pr_reg->pr_reg_deve = target_nacl_find_deve(nacl, mapped_lun); + if (!pr_reg->pr_reg_deve) { + rcu_read_unlock(); + pr_err("Unable to locate PR deve %s mapped_lun: %llu\n", + nacl->initiatorname, mapped_lun); + kmem_cache_free(t10_pr_reg_cache, pr_reg); + return NULL; + } + kref_get(&pr_reg->pr_reg_deve->pr_kref); + rcu_read_unlock(); + } pr_reg->pr_res_mapped_lun = mapped_lun; pr_reg->pr_aptpl_target_lun = lun->unpacked_lun; pr_reg->tg_pt_sep_rtpi = lun->lun_rtpi; @@ -936,17 +958,29 @@ static int __core_scsi3_check_aptpl_registration( !(strcmp(pr_reg->pr_tport, t_port)) && (pr_reg->pr_reg_tpgt == tpgt) && (pr_reg->pr_aptpl_target_lun == target_lun)) { + /* + * Obtain the ->pr_reg_deve pointer + reference, that + * is released by __core_scsi3_add_registration() below. + */ + rcu_read_lock(); + pr_reg->pr_reg_deve = target_nacl_find_deve(nacl, mapped_lun); + if (!pr_reg->pr_reg_deve) { + pr_err("Unable to locate PR APTPL %s mapped_lun:" + " %llu\n", nacl->initiatorname, mapped_lun); + rcu_read_unlock(); + continue; + } + kref_get(&pr_reg->pr_reg_deve->pr_kref); + rcu_read_unlock(); pr_reg->pr_reg_nacl = nacl; pr_reg->tg_pt_sep_rtpi = lun->lun_rtpi; - list_del(&pr_reg->pr_reg_aptpl_list); spin_unlock(&pr_tmpl->aptpl_reg_lock); /* * At this point all of the pointers in *pr_reg will * be setup, so go ahead and add the registration. */ - __core_scsi3_add_registration(dev, nacl, pr_reg, 0, 0); /* * If this registration is the reservation holder, @@ -1044,18 +1078,11 @@ static void __core_scsi3_add_registration( __core_scsi3_dump_registration(tfo, dev, nacl, pr_reg, register_type); spin_unlock(&pr_tmpl->registration_lock); - - rcu_read_lock(); - deve = pr_reg->pr_reg_deve; - if (deve) - set_bit(DEF_PR_REG_ACTIVE, &deve->deve_flags); - rcu_read_unlock(); - /* * Skip extra processing for ALL_TG_PT=0 or REGISTER_AND_MOVE. */ if (!pr_reg->pr_reg_all_tg_pt || register_move) - return; + goto out; /* * Walk pr_reg->pr_reg_atp_list and add registrations for ALL_TG_PT=1 * allocated in __core_scsi3_alloc_registration() @@ -1075,19 +1102,31 @@ static void __core_scsi3_add_registration( __core_scsi3_dump_registration(tfo, dev, nacl_tmp, pr_reg_tmp, register_type); spin_unlock(&pr_tmpl->registration_lock); - + /* + * Drop configfs group dependency reference and deve->pr_kref + * obtained from __core_scsi3_alloc_registration() code. + */ rcu_read_lock(); deve = pr_reg_tmp->pr_reg_deve; - if (deve) + if (deve) { set_bit(DEF_PR_REG_ACTIVE, &deve->deve_flags); + core_scsi3_lunacl_undepend_item(deve); + pr_reg_tmp->pr_reg_deve = NULL; + } rcu_read_unlock(); - - /* - * Drop configfs group dependency reference from - * __core_scsi3_alloc_registration() - */ - core_scsi3_lunacl_undepend_item(pr_reg_tmp->pr_reg_deve); } +out: + /* + * Drop deve->pr_kref obtained in __core_scsi3_do_alloc_registration() + */ + rcu_read_lock(); + deve = pr_reg->pr_reg_deve; + if (deve) { + set_bit(DEF_PR_REG_ACTIVE, &deve->deve_flags); + kref_put(&deve->pr_kref, target_pr_kref_release); + pr_reg->pr_reg_deve = NULL; + } + rcu_read_unlock(); } static int core_scsi3_alloc_registration( @@ -1785,9 +1824,11 @@ core_scsi3_decode_spec_i_port( dest_node_acl->initiatorname, i_buf, (dest_se_deve) ? dest_se_deve->mapped_lun : 0); - if (!dest_se_deve) + if (!dest_se_deve) { + kref_put(&local_pr_reg->pr_reg_deve->pr_kref, + target_pr_kref_release); continue; - + } core_scsi3_lunacl_undepend_item(dest_se_deve); core_scsi3_nodeacl_undepend_item(dest_node_acl); core_scsi3_tpg_undepend_item(dest_tpg); @@ -1823,9 +1864,11 @@ out: kmem_cache_free(t10_pr_reg_cache, dest_pr_reg); - if (!dest_se_deve) + if (!dest_se_deve) { + kref_put(&local_pr_reg->pr_reg_deve->pr_kref, + target_pr_kref_release); continue; - + } core_scsi3_lunacl_undepend_item(dest_se_deve); core_scsi3_nodeacl_undepend_item(dest_node_acl); core_scsi3_tpg_undepend_item(dest_tpg); diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c index 4515f5254..47fe94ee1 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c @@ -450,6 +450,8 @@ int target_xcopy_setup_pt(void) memset(&xcopy_pt_sess, 0, sizeof(struct se_session)); INIT_LIST_HEAD(&xcopy_pt_sess.sess_list); INIT_LIST_HEAD(&xcopy_pt_sess.sess_acl_list); + INIT_LIST_HEAD(&xcopy_pt_sess.sess_cmd_list); + spin_lock_init(&xcopy_pt_sess.sess_cmd_lock); xcopy_pt_nacl.se_tpg = &xcopy_pt_tpg; xcopy_pt_nacl.nacl_sess = &xcopy_pt_sess; @@ -644,7 +646,7 @@ static int target_xcopy_read_source( pr_debug("XCOPY: Built READ_16: LBA: %llu Sectors: %u Length: %u\n", (unsigned long long)src_lba, src_sectors, length); - transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, NULL, length, + transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length, DMA_FROM_DEVICE, 0, &xpt_cmd->sense_buffer[0]); xop->src_pt_cmd = xpt_cmd; @@ -704,7 +706,7 @@ static int target_xcopy_write_destination( pr_debug("XCOPY: Built WRITE_16: LBA: %llu Sectors: %u Length: %u\n", (unsigned long long)dst_lba, dst_sectors, length); - transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, NULL, length, + transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length, DMA_TO_DEVICE, 0, &xpt_cmd->sense_buffer[0]); xop->dst_pt_cmd = xpt_cmd; diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 620dcd405..42c6f71bd 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -262,7 +262,9 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb, * efficiently. Power is stored in mW, frequency in KHz. The * resulting table is in ascending order. * - * Return: 0 on success, -E* on error. + * Return: 0 on success, -EINVAL if there are no OPPs for any CPUs, + * -ENOMEM if we run out of memory or -EAGAIN if an OPP was + * added/enabled while the function was executing. */ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device, u32 capacitance) @@ -273,8 +275,6 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device, int num_opps = 0, cpu, i, ret = 0; unsigned long freq; - rcu_read_lock(); - for_each_cpu(cpu, &cpufreq_device->allowed_cpus) { dev = get_cpu_device(cpu); if (!dev) { @@ -284,24 +284,20 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device, } num_opps = dev_pm_opp_get_opp_count(dev); - if (num_opps > 0) { + if (num_opps > 0) break; - } else if (num_opps < 0) { - ret = num_opps; - goto unlock; - } + else if (num_opps < 0) + return num_opps; } - if (num_opps == 0) { - ret = -EINVAL; - goto unlock; - } + if (num_opps == 0) + return -EINVAL; power_table = kcalloc(num_opps, sizeof(*power_table), GFP_KERNEL); - if (!power_table) { - ret = -ENOMEM; - goto unlock; - } + if (!power_table) + return -ENOMEM; + + rcu_read_lock(); for (freq = 0, i = 0; opp = dev_pm_opp_find_freq_ceil(dev, &freq), !IS_ERR(opp); @@ -309,6 +305,12 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device, u32 freq_mhz, voltage_mv; u64 power; + if (i >= num_opps) { + rcu_read_unlock(); + ret = -EAGAIN; + goto free_power_table; + } + freq_mhz = freq / 1000000; voltage_mv = dev_pm_opp_get_voltage(opp) / 1000; @@ -326,17 +328,22 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device, power_table[i].power = power; } - if (i == 0) { + rcu_read_unlock(); + + if (i != num_opps) { ret = PTR_ERR(opp); - goto unlock; + goto free_power_table; } cpufreq_device->cpu_dev = dev; cpufreq_device->dyn_power_table = power_table; cpufreq_device->dyn_power_table_entries = i; -unlock: - rcu_read_unlock(); + return 0; + +free_power_table: + kfree(power_table); + return ret; } @@ -847,7 +854,7 @@ __cpufreq_cooling_register(struct device_node *np, ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); if (ret) { cool_dev = ERR_PTR(ret); - goto free_table; + goto free_power_table; } snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", @@ -889,6 +896,8 @@ __cpufreq_cooling_register(struct device_node *np, remove_idr: release_idr(&cpufreq_idr, cpufreq_dev->id); +free_power_table: + kfree(cpufreq_dev->dyn_power_table); free_table: kfree(cpufreq_dev->freq_table); free_time_in_idle_timestamp: @@ -1039,6 +1048,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) thermal_cooling_device_unregister(cpufreq_dev->cool_dev); release_idr(&cpufreq_idr, cpufreq_dev->id); + kfree(cpufreq_dev->dyn_power_table); kfree(cpufreq_dev->time_in_idle_timestamp); kfree(cpufreq_dev->time_in_idle); kfree(cpufreq_dev->freq_table); diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index ee8bfacf2..afc1879f6 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -343,8 +343,7 @@ static void n_tty_packet_mode_flush(struct tty_struct *tty) spin_lock_irqsave(&tty->ctrl_lock, flags); tty->ctrl_status |= TIOCPKT_FLUSHREAD; spin_unlock_irqrestore(&tty->ctrl_lock, flags); - if (waitqueue_active(&tty->link->read_wait)) - wake_up_interruptible(&tty->link->read_wait); + wake_up_interruptible(&tty->link->read_wait); } } @@ -1382,8 +1381,7 @@ handle_newline: put_tty_queue(c, ldata); smp_store_release(&ldata->canon_head, ldata->read_head); kill_fasync(&tty->fasync, SIGIO, POLL_IN); - if (waitqueue_active(&tty->read_wait)) - wake_up_interruptible_poll(&tty->read_wait, POLLIN); + wake_up_interruptible_poll(&tty->read_wait, POLLIN); return 0; } } @@ -1667,8 +1665,7 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp, if ((read_cnt(ldata) >= ldata->minimum_to_wake) || L_EXTPROC(tty)) { kill_fasync(&tty->fasync, SIGIO, POLL_IN); - if (waitqueue_active(&tty->read_wait)) - wake_up_interruptible_poll(&tty->read_wait, POLLIN); + wake_up_interruptible_poll(&tty->read_wait, POLLIN); } } @@ -1887,10 +1884,8 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) } /* The termios change make the tty ready for I/O */ - if (waitqueue_active(&tty->write_wait)) - wake_up_interruptible(&tty->write_wait); - if (waitqueue_active(&tty->read_wait)) - wake_up_interruptible(&tty->read_wait); + wake_up_interruptible(&tty->write_wait); + wake_up_interruptible(&tty->read_wait); } /** diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 2736eb262..a3a83164b 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -326,6 +326,14 @@ configured less than Maximum supported fifo bytes */ UART_FCR7_64BYTE, .flags = UART_CAP_FIFO, }, + [PORT_RT2880] = { + .name = "Palmchip BK-3103", + .fifo_size = 16, + .tx_loadsz = 16, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .rxtrig_bytes = {1, 4, 8, 14}, + .flags = UART_CAP_FIFO, + }, }; /* Uart divisor latch read */ diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index 2a8f52815..40326b342 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -2641,7 +2641,7 @@ static int atmel_serial_probe(struct platform_device *pdev) ret = atmel_init_gpios(port, &pdev->dev); if (ret < 0) { dev_err(&pdev->dev, "Failed to initialize GPIOs."); - goto err; + goto err_clear_bit; } ret = atmel_init_port(port, pdev); diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 57fc6ee12..774df354a 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2136,8 +2136,24 @@ retry_open: if (!noctty && current->signal->leader && !current->signal->tty && - tty->session == NULL) - __proc_set_tty(tty); + tty->session == NULL) { + /* + * Don't let a process that only has write access to the tty + * obtain the privileges associated with having a tty as + * controlling terminal (being able to reopen it with full + * access through /dev/tty, being able to perform pushback). + * Many distributions set the group of all ttys to "tty" and + * grant write-only access to all terminals for setgid tty + * binaries, which should not imply full privileges on all ttys. + * + * This could theoretically break old code that performs open() + * on a write-only file descriptor. In that case, it might be + * necessary to also permit this if + * inode_permission(inode, MAY_READ) == 0. + */ + if (filp->f_mode & FMODE_READ) + __proc_set_tty(tty); + } spin_unlock_irq(¤t->sighand->siglock); read_unlock(&tasklist_lock); tty_unlock(tty); @@ -2426,7 +2442,7 @@ static int fionbio(struct file *file, int __user *p) * Takes ->siglock() when updating signal->tty */ -static int tiocsctty(struct tty_struct *tty, int arg) +static int tiocsctty(struct tty_struct *tty, struct file *file, int arg) { int ret = 0; @@ -2460,6 +2476,13 @@ static int tiocsctty(struct tty_struct *tty, int arg) goto unlock; } } + + /* See the comment in tty_open(). */ + if ((file->f_mode & FMODE_READ) == 0 && !capable(CAP_SYS_ADMIN)) { + ret = -EPERM; + goto unlock; + } + proc_set_tty(tty); unlock: read_unlock(&tasklist_lock); @@ -2852,7 +2875,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) no_tty(); return 0; case TIOCSCTTY: - return tiocsctty(tty, arg); + return tiocsctty(tty, file, arg); case TIOCGPGRP: return tiocgpgrp(tty, real_tty, p); case TIOCSPGRP: diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index 389f0e034..fa774323e 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -56,7 +56,7 @@ static const struct of_device_id ci_hdrc_imx_dt_ids[] = { { .compatible = "fsl,imx27-usb", .data = &imx27_usb_data}, { .compatible = "fsl,imx6q-usb", .data = &imx6q_usb_data}, { .compatible = "fsl,imx6sl-usb", .data = &imx6sl_usb_data}, - { .compatible = "fsl,imx6sx-usb", .data = &imx6sl_usb_data}, + { .compatible = "fsl,imx6sx-usb", .data = &imx6sx_usb_data}, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ci_hdrc_imx_dt_ids); diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 764f668d4..6e53c24fa 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); @@ -1110,8 +1148,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); } } @@ -1142,9 +1180,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); } } @@ -1390,41 +1428,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); } /** diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index b2a540b43..b9ddf0c1f 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -112,7 +112,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bmAttributes = 16; } else if (usb_endpoint_xfer_isoc(&ep->desc) && - desc->bmAttributes > 2) { + USB_SS_MULT(desc->bmAttributes) > 3) { dev_warn(ddev, "Isoc endpoint has Mult of %d in " "config %d interface %d altsetting %d ep %d: " "setting to 3\n", desc->bmAttributes + 1, @@ -121,7 +121,8 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, } if (usb_endpoint_xfer_isoc(&ep->desc)) - max_tx = (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) * + max_tx = (desc->bMaxBurst + 1) * + (USB_SS_MULT(desc->bmAttributes)) * usb_endpoint_maxp(&ep->desc); else if (usb_endpoint_xfer_int(&ep->desc)) max_tx = usb_endpoint_maxp(&ep->desc) * diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index d85abfed8..f5a381945 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -54,6 +54,13 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT }, { USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT }, + /* Logitech ConferenceCam CC3000e */ + { USB_DEVICE(0x046d, 0x0847), .driver_info = USB_QUIRK_DELAY_INIT }, + { USB_DEVICE(0x046d, 0x0848), .driver_info = USB_QUIRK_DELAY_INIT }, + + /* Logitech PTZ Pro Camera */ + { USB_DEVICE(0x046d, 0x0853), .driver_info = USB_QUIRK_DELAY_INIT }, + /* Logitech Quickcam Fusion */ { USB_DEVICE(0x046d, 0x08c1), .driver_info = USB_QUIRK_RESET_RESUME }, @@ -78,6 +85,12 @@ static const struct usb_device_id usb_quirk_list[] = { /* Philips PSC805 audio device */ { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Plantronic Audio 655 DSP */ + { USB_DEVICE(0x047f, 0xc008), .driver_info = USB_QUIRK_RESET_RESUME }, + + /* Plantronic Audio 648 USB */ + { USB_DEVICE(0x047f, 0xc013), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Artisman Watchdog Dongle */ { USB_DEVICE(0x04b4, 0x0526), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 9a8c936cd..41f841fa6 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1498,10 +1498,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, * use Event Data TRBs, and we don't chain in a link TRB on short * transfers, we're basically dividing by 1. * - * xHCI 1.0 specification indicates that the Average TRB Length should - * be set to 8 for control endpoints. + * xHCI 1.0 and 1.1 specification indicates that the Average TRB Length + * should be set to 8 for control endpoints. */ - if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version == 0x100) + if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version >= 0x100) ep_ctx->tx_info |= cpu_to_le32(AVG_TRB_LENGTH_FOR_EP(8)); else ep_ctx->tx_info |= @@ -1792,8 +1792,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) int size; int i, j, num_ports; - if (timer_pending(&xhci->cmd_timer)) - del_timer_sync(&xhci->cmd_timer); + del_timer_sync(&xhci->cmd_timer); /* Free the Event Ring Segment Table and the actual Event Ring */ size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries); @@ -2321,6 +2320,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) INIT_LIST_HEAD(&xhci->cmd_list); + /* init command timeout timer */ + setup_timer(&xhci->cmd_timer, xhci_handle_command_timeout, + (unsigned long)xhci); + page_size = readl(&xhci->op_regs->page_size); xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Supported page size register = 0x%x", page_size); @@ -2505,10 +2508,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) "Wrote ERST address to ir_set 0."); xhci_print_ir_set(xhci, 0); - /* init command timeout timer */ - setup_timer(&xhci->cmd_timer, xhci_handle_command_timeout, - (unsigned long)xhci); - /* * XXX: Might need to set the Interrupter Moderation Register to * something other than the default (~1ms minimum between interrupts). diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 5590eac2b..c79d33676 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -180,51 +180,6 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) "QUIRK: Resetting on resume"); } -/* - * In some Intel xHCI controllers, in order to get D3 working, - * through a vendor specific SSIC CONFIG register at offset 0x883c, - * SSIC PORT need to be marked as "unused" before putting xHCI - * into D3. After D3 exit, the SSIC port need to be marked as "used". - * Without this change, xHCI might not enter D3 state. - * Make sure PME works on some Intel xHCI controllers by writing 1 to clear - * the Internal PME flag bit in vendor specific PMCTRL register at offset 0x80a4 - */ -static void xhci_pme_quirk(struct usb_hcd *hcd, bool suspend) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - struct pci_dev *pdev = to_pci_dev(hcd->self.controller); - u32 val; - void __iomem *reg; - - if (pdev->vendor == PCI_VENDOR_ID_INTEL && - pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) { - - reg = (void __iomem *) xhci->cap_regs + PORT2_SSIC_CONFIG_REG2; - - /* Notify SSIC that SSIC profile programming is not done */ - val = readl(reg) & ~PROG_DONE; - writel(val, reg); - - /* Mark SSIC port as unused(suspend) or used(resume) */ - val = readl(reg); - if (suspend) - val |= SSIC_PORT_UNUSED; - else - val &= ~SSIC_PORT_UNUSED; - writel(val, reg); - - /* Notify SSIC that SSIC profile programming is done */ - val = readl(reg) | PROG_DONE; - writel(val, reg); - readl(reg); - } - - reg = (void __iomem *) xhci->cap_regs + 0x80a4; - val = readl(reg); - writel(val | BIT(28), reg); - readl(reg); -} - #ifdef CONFIG_ACPI static void xhci_pme_acpi_rtd3_enable(struct pci_dev *dev) { @@ -345,6 +300,51 @@ static void xhci_pci_remove(struct pci_dev *dev) } #ifdef CONFIG_PM +/* + * In some Intel xHCI controllers, in order to get D3 working, + * through a vendor specific SSIC CONFIG register at offset 0x883c, + * SSIC PORT need to be marked as "unused" before putting xHCI + * into D3. After D3 exit, the SSIC port need to be marked as "used". + * Without this change, xHCI might not enter D3 state. + * Make sure PME works on some Intel xHCI controllers by writing 1 to clear + * the Internal PME flag bit in vendor specific PMCTRL register at offset 0x80a4 + */ +static void xhci_pme_quirk(struct usb_hcd *hcd, bool suspend) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + u32 val; + void __iomem *reg; + + if (pdev->vendor == PCI_VENDOR_ID_INTEL && + pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) { + + reg = (void __iomem *) xhci->cap_regs + PORT2_SSIC_CONFIG_REG2; + + /* Notify SSIC that SSIC profile programming is not done */ + val = readl(reg) & ~PROG_DONE; + writel(val, reg); + + /* Mark SSIC port as unused(suspend) or used(resume) */ + val = readl(reg); + if (suspend) + val |= SSIC_PORT_UNUSED; + else + val &= ~SSIC_PORT_UNUSED; + writel(val, reg); + + /* Notify SSIC that SSIC profile programming is done */ + val = readl(reg) | PROG_DONE; + writel(val, reg); + readl(reg); + } + + reg = (void __iomem *) xhci->cap_regs + 0x80a4; + val = readl(reg); + writel(val | BIT(28), reg); + readl(reg); +} + static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 32f4d5644..8aadf3def 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -302,6 +302,15 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) ret = xhci_handshake(&xhci->op_regs->cmd_ring, CMD_RING_RUNNING, 0, 5 * 1000 * 1000); if (ret < 0) { + /* we are about to kill xhci, give it one more chance */ + xhci_write_64(xhci, temp_64 | CMD_RING_ABORT, + &xhci->op_regs->cmd_ring); + udelay(1000); + ret = xhci_handshake(&xhci->op_regs->cmd_ring, + CMD_RING_RUNNING, 0, 3 * 1000 * 1000); + if (ret == 0) + return 0; + xhci_err(xhci, "Stopped the command ring failed, " "maybe the host is dead\n"); xhci->xhc_state |= XHCI_STATE_DYING; @@ -3041,9 +3050,11 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct xhci_td *td; struct scatterlist *sg; int num_sgs; - int trb_buff_len, this_sg_len, running_total; + int trb_buff_len, this_sg_len, running_total, ret; unsigned int total_packet_count; + bool zero_length_needed; bool first_trb; + int last_trb_num; u64 addr; bool more_trbs_coming; @@ -3059,13 +3070,27 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, total_packet_count = DIV_ROUND_UP(urb->transfer_buffer_length, usb_endpoint_maxp(&urb->ep->desc)); - trb_buff_len = prepare_transfer(xhci, xhci->devs[slot_id], + ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index, urb->stream_id, num_trbs, urb, 0, mem_flags); - if (trb_buff_len < 0) - return trb_buff_len; + if (ret < 0) + return ret; urb_priv = urb->hcpriv; + + /* Deal with URB_ZERO_PACKET - need one more td/trb */ + zero_length_needed = urb->transfer_flags & URB_ZERO_PACKET && + urb_priv->length == 2; + if (zero_length_needed) { + num_trbs++; + xhci_dbg(xhci, "Creating zero length td.\n"); + ret = prepare_transfer(xhci, xhci->devs[slot_id], + ep_index, urb->stream_id, + 1, urb, 1, mem_flags); + if (ret < 0) + return ret; + } + td = urb_priv->td[0]; /* @@ -3095,6 +3120,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, trb_buff_len = urb->transfer_buffer_length; first_trb = true; + last_trb_num = zero_length_needed ? 2 : 1; /* Queue the first TRB, even if it's zero-length */ do { u32 field = 0; @@ -3112,12 +3138,15 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, /* Chain all the TRBs together; clear the chain bit in the last * TRB to indicate it's the last TRB in the chain. */ - if (num_trbs > 1) { + if (num_trbs > last_trb_num) { field |= TRB_CHAIN; - } else { - /* FIXME - add check for ZERO_PACKET flag before this */ + } else if (num_trbs == last_trb_num) { td->last_trb = ep_ring->enqueue; field |= TRB_IOC; + } else if (zero_length_needed && num_trbs == 1) { + trb_buff_len = 0; + urb_priv->td[1]->last_trb = ep_ring->enqueue; + field |= TRB_IOC; } /* Only set interrupt on short packet for IN endpoints */ @@ -3179,7 +3208,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, if (running_total + trb_buff_len > urb->transfer_buffer_length) trb_buff_len = urb->transfer_buffer_length - running_total; - } while (running_total < urb->transfer_buffer_length); + } while (num_trbs > 0); check_trb_math(urb, num_trbs, running_total); giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, @@ -3197,7 +3226,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, int num_trbs; struct xhci_generic_trb *start_trb; bool first_trb; + int last_trb_num; bool more_trbs_coming; + bool zero_length_needed; int start_cycle; u32 field, length_field; @@ -3228,7 +3259,6 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, num_trbs++; running_total += TRB_MAX_BUFF_SIZE; } - /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */ ret = prepare_transfer(xhci, xhci->devs[slot_id], ep_index, urb->stream_id, @@ -3237,6 +3267,20 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, return ret; urb_priv = urb->hcpriv; + + /* Deal with URB_ZERO_PACKET - need one more td/trb */ + zero_length_needed = urb->transfer_flags & URB_ZERO_PACKET && + urb_priv->length == 2; + if (zero_length_needed) { + num_trbs++; + xhci_dbg(xhci, "Creating zero length td.\n"); + ret = prepare_transfer(xhci, xhci->devs[slot_id], + ep_index, urb->stream_id, + 1, urb, 1, mem_flags); + if (ret < 0) + return ret; + } + td = urb_priv->td[0]; /* @@ -3258,7 +3302,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, trb_buff_len = urb->transfer_buffer_length; first_trb = true; - + last_trb_num = zero_length_needed ? 2 : 1; /* Queue the first TRB, even if it's zero-length */ do { u32 remainder = 0; @@ -3275,12 +3319,15 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, /* Chain all the TRBs together; clear the chain bit in the last * TRB to indicate it's the last TRB in the chain. */ - if (num_trbs > 1) { + if (num_trbs > last_trb_num) { field |= TRB_CHAIN; - } else { - /* FIXME - add check for ZERO_PACKET flag before this */ + } else if (num_trbs == last_trb_num) { td->last_trb = ep_ring->enqueue; field |= TRB_IOC; + } else if (zero_length_needed && num_trbs == 1) { + trb_buff_len = 0; + urb_priv->td[1]->last_trb = ep_ring->enqueue; + field |= TRB_IOC; } /* Only set interrupt on short packet for IN endpoints */ @@ -3318,7 +3365,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, trb_buff_len = urb->transfer_buffer_length - running_total; if (trb_buff_len > TRB_MAX_BUFF_SIZE) trb_buff_len = TRB_MAX_BUFF_SIZE; - } while (running_total < urb->transfer_buffer_length); + } while (num_trbs > 0); check_trb_math(urb, num_trbs, running_total); giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, @@ -3385,8 +3432,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, if (start_cycle == 0) field |= 0x1; - /* xHCI 1.0 6.4.1.2.1: Transfer Type field */ - if (xhci->hci_version == 0x100) { + /* xHCI 1.0/1.1 6.4.1.2.1: Transfer Type field */ + if (xhci->hci_version >= 0x100) { if (urb->transfer_buffer_length > 0) { if (setup->bRequestType & USB_DIR_IN) field |= TRB_TX_TYPE(TRB_DATA_IN); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 526ebc0c7..d7b9f484d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -146,7 +146,8 @@ static int xhci_start(struct xhci_hcd *xhci) "waited %u microseconds.\n", XHCI_MAX_HALT_USEC); if (!ret) - xhci->xhc_state &= ~XHCI_STATE_HALTED; + xhci->xhc_state &= ~(XHCI_STATE_HALTED | XHCI_STATE_DYING); + return ret; } @@ -654,15 +655,6 @@ int xhci_run(struct usb_hcd *hcd) } EXPORT_SYMBOL_GPL(xhci_run); -static void xhci_only_stop_hcd(struct usb_hcd *hcd) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - - spin_lock_irq(&xhci->lock); - xhci_halt(xhci); - spin_unlock_irq(&xhci->lock); -} - /* * Stop xHCI driver. * @@ -677,12 +669,14 @@ void xhci_stop(struct usb_hcd *hcd) u32 temp; struct xhci_hcd *xhci = hcd_to_xhci(hcd); - if (!usb_hcd_is_primary_hcd(hcd)) { - xhci_only_stop_hcd(xhci->shared_hcd); + if (xhci->xhc_state & XHCI_STATE_HALTED) return; - } + mutex_lock(&xhci->mutex); spin_lock_irq(&xhci->lock); + xhci->xhc_state |= XHCI_STATE_HALTED; + xhci->cmd_ring_state = CMD_RING_STATE_STOPPED; + /* Make sure the xHC is halted for a USB3 roothub * (xhci_stop() could be called as part of failed init). */ @@ -717,6 +711,7 @@ void xhci_stop(struct usb_hcd *hcd) xhci_dbg_trace(xhci, trace_xhci_dbg_init, "xhci_stop completed - status = %x", readl(&xhci->op_regs->status)); + mutex_unlock(&xhci->mutex); } /* @@ -1340,6 +1335,11 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) if (usb_endpoint_xfer_isoc(&urb->ep->desc)) size = urb->number_of_packets; + else if (usb_endpoint_is_bulk_out(&urb->ep->desc) && + urb->transfer_buffer_length > 0 && + urb->transfer_flags & URB_ZERO_PACKET && + !(urb->transfer_buffer_length % usb_endpoint_maxp(&urb->ep->desc))) + size = 2; else size = 1; @@ -3788,6 +3788,9 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, mutex_lock(&xhci->mutex); + if (xhci->xhc_state) /* dying or halted */ + goto out; + if (!udev->slot_id) { xhci_dbg_trace(xhci, trace_xhci_dbg_address, "Bad Slot ID %d", udev->slot_id); diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c index 3ad5d19e4..23c794813 100644 --- a/drivers/usb/misc/chaoskey.c +++ b/drivers/usb/misc/chaoskey.c @@ -472,7 +472,7 @@ static int chaoskey_rng_read(struct hwrng *rng, void *data, if (this_time > max) this_time = max; - memcpy(data, dev->buf, this_time); + memcpy(data, dev->buf + dev->used, this_time); dev->used += this_time; diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index 4d1b44c23..d07cafb7d 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -614,7 +614,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) { struct musb *musb = controller->musb; struct device *dev = musb->controller; - struct device_node *np = dev->of_node; + struct device_node *np = dev->parent->of_node; struct cppi41_dma_channel *cppi41_channel; int count; int i; @@ -664,7 +664,7 @@ static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller) musb_dma->status = MUSB_DMA_STATUS_FREE; musb_dma->max_len = SZ_4M; - dc = dma_request_slave_channel(dev, str); + dc = dma_request_slave_channel(dev->parent, str); if (!dc) { dev_err(dev, "Failed to request %s.\n", str); ret = -EPROBE_DEFER; @@ -695,7 +695,7 @@ cppi41_dma_controller_create(struct musb *musb, void __iomem *base) struct cppi41_dma_controller *controller; int ret = 0; - if (!musb->controller->of_node) { + if (!musb->controller->parent->of_node) { dev_err(musb->controller, "Need DT for the DMA engine.\n"); return NULL; } diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 1334a3de3..67325ec94 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -225,8 +225,11 @@ static void dsps_musb_enable(struct musb *musb) dsps_writel(reg_base, wrp->epintr_set, epmask); dsps_writel(reg_base, wrp->coreintr_set, coremask); - /* start polling for ID change. */ - mod_timer(&glue->timer, jiffies + msecs_to_jiffies(wrp->poll_timeout)); + /* start polling for ID change in dual-role idle mode */ + if (musb->xceiv->otg->state == OTG_STATE_B_IDLE && + musb->port_mode == MUSB_PORT_MODE_DUAL_ROLE) + mod_timer(&glue->timer, jiffies + + msecs_to_jiffies(wrp->poll_timeout)); dsps_musb_try_idle(musb, 0); } diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index deee68eaf..0cd85f2cc 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -230,7 +230,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 = diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 876423b88..7c8eb4c4c 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) }, diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index b93131d8c..59cb91b2e 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -80,6 +80,8 @@ static int whiteheat_firmware_download(struct usb_serial *serial, static int whiteheat_firmware_attach(struct usb_serial *serial); /* function prototypes for the Connect Tech WhiteHEAT serial converter */ +static int whiteheat_probe(struct usb_serial *serial, + const struct usb_device_id *id); static int whiteheat_attach(struct usb_serial *serial); static void whiteheat_release(struct usb_serial *serial); static int whiteheat_port_probe(struct usb_serial_port *port); @@ -116,6 +118,7 @@ static struct usb_serial_driver whiteheat_device = { .description = "Connect Tech - WhiteHEAT", .id_table = id_table_std, .num_ports = 4, + .probe = whiteheat_probe, .attach = whiteheat_attach, .release = whiteheat_release, .port_probe = whiteheat_port_probe, @@ -217,6 +220,34 @@ static int whiteheat_firmware_attach(struct usb_serial *serial) /***************************************************************************** * Connect Tech's White Heat serial driver functions *****************************************************************************/ + +static int whiteheat_probe(struct usb_serial *serial, + const struct usb_device_id *id) +{ + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint; + size_t num_bulk_in = 0; + size_t num_bulk_out = 0; + size_t min_num_bulk; + unsigned int i; + + iface_desc = serial->interface->cur_altsetting; + + for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { + endpoint = &iface_desc->endpoint[i].desc; + if (usb_endpoint_is_bulk_in(endpoint)) + ++num_bulk_in; + if (usb_endpoint_is_bulk_out(endpoint)) + ++num_bulk_out; + } + + min_num_bulk = COMMAND_PORT + 1; + if (num_bulk_in < min_num_bulk || num_bulk_out < min_num_bulk) + return -ENODEV; + + return 0; +} + static int whiteheat_attach(struct usb_serial *serial) { struct usb_serial_port *command_port; diff --git a/drivers/watchdog/imgpdc_wdt.c b/drivers/watchdog/imgpdc_wdt.c index 0f7362182..15ab07230 100644 --- a/drivers/watchdog/imgpdc_wdt.c +++ b/drivers/watchdog/imgpdc_wdt.c @@ -316,6 +316,7 @@ static int pdc_wdt_remove(struct platform_device *pdev) { struct pdc_wdt_dev *pdc_wdt = platform_get_drvdata(pdev); + unregister_restart_handler(&pdc_wdt->restart_handler); pdc_wdt_stop(&pdc_wdt->wdt_dev); watchdog_unregister_device(&pdc_wdt->wdt_dev); clk_disable_unprepare(pdc_wdt->wdt_clk); diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c index a29afb37c..47bd8a14d 100644 --- a/drivers/watchdog/sunxi_wdt.c +++ b/drivers/watchdog/sunxi_wdt.c @@ -184,7 +184,7 @@ static int sunxi_wdt_start(struct watchdog_device *wdt_dev) /* Set system reset function */ reg = readl(wdt_base + regs->wdt_cfg); reg &= ~(regs->wdt_reset_mask); - reg |= ~(regs->wdt_reset_val); + reg |= regs->wdt_reset_val; writel(reg, wdt_base + regs->wdt_cfg); /* Enable watchdog */ diff --git a/drivers/xen/preempt.c b/drivers/xen/preempt.c index a1800c150..08cb419eb 100644 --- a/drivers/xen/preempt.c +++ b/drivers/xen/preempt.c @@ -31,7 +31,7 @@ EXPORT_SYMBOL_GPL(xen_in_preemptible_hcall); asmlinkage __visible void xen_maybe_preempt_hcall(void) { if (unlikely(__this_cpu_read(xen_in_preemptible_hcall) - && should_resched())) { + && need_resched())) { /* * Clear flag as we may be rescheduled on a different * cpu. -- cgit v1.2.3-54-g00ecf