aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/acpica/utxfinit.c10
-rw-r--r--drivers/ata/libata-core.c9
-rw-r--r--drivers/ata/libata-pmp.c7
-rw-r--r--drivers/ata/libata-scsi.c3
-rw-r--r--drivers/base/firmware_class.c16
-rw-r--r--drivers/base/regmap/regmap.c2
-rw-r--r--drivers/block/rbd.c4
-rw-r--r--drivers/bluetooth/btusb.c2
-rw-r--r--drivers/char/agp/intel-gtt.c2
-rw-r--r--drivers/char/tpm/tpm_ibmvtpm.c5
-rw-r--r--drivers/cpuidle/cpuidle.c3
-rw-r--r--drivers/cpuidle/governors/menu.c2
-rw-r--r--drivers/crypto/talitos.c4
-rw-r--r--drivers/dma/mv_xor.c72
-rw-r--r--drivers/dma/mv_xor.h1
-rw-r--r--drivers/gpu/drm/drm_crtc.c7
-rw-r--r--drivers/gpu/drm/qxl/qxl_cmd.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq_kms.c2
-rw-r--r--drivers/hwmon/mcp3021.c14
-rw-r--r--drivers/i2c/busses/i2c-at91.c70
-rw-r--r--drivers/iio/dac/ad5624r_spi.c4
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c32
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c3
-rw-r--r--drivers/md/md.c2
-rw-r--r--drivers/md/persistent-data/dm-btree-remove.c6
-rw-r--r--drivers/md/persistent-data/dm-btree.c2
-rw-r--r--drivers/md/raid1.c2
-rw-r--r--drivers/media/dvb-frontends/af9013.c4
-rw-r--r--drivers/media/dvb-frontends/cx24116.c8
-rw-r--r--drivers/media/dvb-frontends/s5h1420.c2
-rw-r--r--drivers/mmc/card/block.c10
-rw-r--r--drivers/mmc/host/sdhci-esdhc.h2
-rw-r--r--drivers/mmc/host/sdhci-pxav3.c1
-rw-r--r--drivers/mtd/maps/dc21285.c4
-rw-r--r--drivers/mtd/mtd_blkdevs.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c12
-rw-r--r--drivers/pcmcia/topic.h16
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-armada-370.c4
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-armada-xp.c37
-rw-r--r--drivers/regulator/core.c2
-rw-r--r--drivers/scsi/ipr.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c17
-rw-r--r--drivers/scsi/st.c2
-rw-r--r--drivers/staging/rtl8712/rtl8712_recv.c3
-rw-r--r--drivers/target/iscsi/iscsi_target.c130
-rw-r--r--drivers/target/iscsi/iscsi_target_core.h7
-rw-r--r--drivers/target/iscsi/iscsi_target_erl0.c13
-rw-r--r--drivers/target/iscsi/iscsi_target_login.c61
-rw-r--r--drivers/usb/core/devio.c65
-rw-r--r--drivers/usb/dwc3/ep0.c4
-rw-r--r--drivers/usb/dwc3/gadget.c4
-rw-r--r--drivers/usb/host/xhci-hub.c13
-rw-r--r--drivers/usb/host/xhci-mem.c2
-rw-r--r--drivers/usb/host/xhci-ring.c3
-rw-r--r--drivers/usb/host/xhci.c3
-rw-r--r--drivers/usb/host/xhci.h1
-rw-r--r--drivers/usb/serial/cp210x.c1
-rw-r--r--drivers/usb/serial/option.c1
-rw-r--r--drivers/usb/storage/unusual_devs.h12
-rw-r--r--drivers/vhost/vhost.c1
-rw-r--r--drivers/watchdog/omap_wdt.c7
62 files changed, 508 insertions, 250 deletions
diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c
index 41ebaaf8bb1a..ee58a62443bd 100644
--- a/drivers/acpi/acpica/utxfinit.c
+++ b/drivers/acpi/acpica/utxfinit.c
@@ -165,10 +165,12 @@ acpi_status acpi_enable_subsystem(u32 flags)
* Obtain a permanent mapping for the FACS. This is required for the
* Global Lock and the Firmware Waking Vector
*/
- status = acpi_tb_initialize_facs();
- if (ACPI_FAILURE(status)) {
- ACPI_WARNING((AE_INFO, "Could not map the FACS table"));
- return_ACPI_STATUS(status);
+ if (!(flags & ACPI_NO_FACS_INIT)) {
+ status = acpi_tb_initialize_facs();
+ if (ACPI_FAILURE(status)) {
+ ACPI_WARNING((AE_INFO, "Could not map the FACS table"));
+ return_ACPI_STATUS(status);
+ }
}
#endif /* !ACPI_REDUCED_HARDWARE */
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 5d47a040129a..53d35b6fd8bb 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4150,9 +4150,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "ST3320[68]13AS", "SD1[5-9]", ATA_HORKAGE_NONCQ |
ATA_HORKAGE_FIRMWARE_WARN },
- /* Seagate Momentus SpinPoint M8 seem to have FPMDA_AA issues */
+ /* drives which fail FPDMA_AA activation (some may freeze afterwards) */
{ "ST1000LM024 HN-M101MBB", "2AR10001", ATA_HORKAGE_BROKEN_FPDMA_AA },
{ "ST1000LM024 HN-M101MBB", "2BA30001", ATA_HORKAGE_BROKEN_FPDMA_AA },
+ { "VB0250EAVER", "HPG7", ATA_HORKAGE_BROKEN_FPDMA_AA },
/* Blacklist entries taken from Silicon Image 3124/3132
Windows driver .inf file - also several Linux problem reports */
@@ -4200,6 +4201,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
{ "PIONEER DVD-RW DVR-212D", NULL, ATA_HORKAGE_NOSETXFER },
{ "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER },
+ /* devices that don't properly handle TRIM commands */
+ { "SuperSSpeed S238*", NULL, ATA_HORKAGE_NOTRIM, },
+
/*
* Some WD SATA-I drives spin up and down erratically when the link
* is put into the slumber mode. We don't have full list of the
@@ -4504,7 +4508,8 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
else /* In the ancient relic department - skip all of this */
return 0;
- err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
+ /* On some disks, this command causes spin-up, so we need longer timeout */
+ err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 15000);
DPRINTK("EXIT, err_mask=%x\n", err_mask);
return err_mask;
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index 7ccc084bf1df..85aa76116a30 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -460,6 +460,13 @@ static void sata_pmp_quirks(struct ata_port *ap)
ATA_LFLAG_NO_SRST |
ATA_LFLAG_ASSUME_ATA;
}
+ } else if (vendor == 0x11ab && devid == 0x4140) {
+ /* Marvell 4140 quirks */
+ ata_for_each_link(link, ap, EDGE) {
+ /* port 4 is for SEMB device and it doesn't like SRST */
+ if (link->pmp == 4)
+ link->flags |= ATA_LFLAG_DISABLED;
+ }
}
}
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 9933b4db7caf..04e7db668362 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2512,7 +2512,8 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
rbuf[14] = (lowest_aligned >> 8) & 0x3f;
rbuf[15] = lowest_aligned;
- if (ata_id_has_trim(args->id)) {
+ if (ata_id_has_trim(args->id) &&
+ !(dev->horkage & ATA_HORKAGE_NOTRIM)) {
rbuf[14] |= 0x80; /* TPE */
if (ata_id_has_zero_after_trim(args->id))
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 00a565676583..8e08fab0ed2e 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -513,10 +513,8 @@ static void fw_dev_release(struct device *dev)
module_put(THIS_MODULE);
}
-static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env)
+static int do_firmware_uevent(struct firmware_priv *fw_priv, struct kobj_uevent_env *env)
{
- struct firmware_priv *fw_priv = to_firmware_priv(dev);
-
if (add_uevent_var(env, "FIRMWARE=%s", fw_priv->buf->fw_id))
return -ENOMEM;
if (add_uevent_var(env, "TIMEOUT=%i", loading_timeout))
@@ -527,6 +525,18 @@ static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env)
return 0;
}
+static int firmware_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ struct firmware_priv *fw_priv = to_firmware_priv(dev);
+ int err = 0;
+
+ mutex_lock(&fw_lock);
+ if (fw_priv->buf)
+ err = do_firmware_uevent(fw_priv, env);
+ mutex_unlock(&fw_lock);
+ return err;
+}
+
static struct class firmware_class = {
.name = "firmware",
.class_attrs = firmware_class_attrs,
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 6a66f0b7d3d4..4f3d70a9d721 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -1586,7 +1586,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
&ival);
if (ret != 0)
return ret;
- memcpy(val + (i * val_bytes), &ival, val_bytes);
+ map->format.format_val(val + (i * val_bytes), ival, 0);
}
}
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index dd297099c99d..f78cbbb88bd4 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -1851,11 +1851,11 @@ static struct rbd_obj_request *rbd_obj_request_create(const char *object_name,
rbd_assert(obj_request_type_valid(type));
size = strlen(object_name) + 1;
- name = kmalloc(size, GFP_KERNEL);
+ name = kmalloc(size, GFP_NOIO);
if (!name)
return NULL;
- obj_request = kmem_cache_zalloc(rbd_obj_request_cache, GFP_KERNEL);
+ obj_request = kmem_cache_zalloc(rbd_obj_request_cache, GFP_NOIO);
if (!obj_request) {
kfree(name);
return NULL;
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 92b985317770..537ad6897784 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1234,6 +1234,8 @@ static int btusb_setup_intel(struct hci_dev *hdev)
}
fw_ptr = fw->data;
+ kfree_skb(skb);
+
/* This Intel specific command enables the manufacturer mode of the
* controller.
*
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index b8e2014cb9cb..051aadb75e2c 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -583,7 +583,7 @@ static inline int needs_ilk_vtd_wa(void)
/* Query intel_iommu to see if we need the workaround. Presumably that
* was loaded first.
*/
- if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB ||
+ if ((gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG ||
gpu_devid == PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG) &&
intel_iommu_gfx_mapped)
return 1;
diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c
index 09df26f9621d..a6524c3efdf7 100644
--- a/drivers/char/tpm/tpm_ibmvtpm.c
+++ b/drivers/char/tpm/tpm_ibmvtpm.c
@@ -618,6 +618,9 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
goto cleanup;
}
+ ibmvtpm->dev = dev;
+ ibmvtpm->vdev = vio_dev;
+
crq_q = &ibmvtpm->crq_queue;
crq_q->crq_addr = (struct ibmvtpm_crq *)get_zeroed_page(GFP_KERNEL);
if (!crq_q->crq_addr) {
@@ -662,8 +665,6 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
crq_q->index = 0;
- ibmvtpm->dev = dev;
- ibmvtpm->vdev = vio_dev;
TPM_VPRIV(chip) = (void *)ibmvtpm;
spin_lock_init(&ibmvtpm->rtce_lock);
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index c3a93fece819..5b11022d7745 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -135,6 +135,9 @@ int cpuidle_idle_call(void)
/* ask the governor for the next state */
next_state = cpuidle_curr_governor->select(drv, dev);
+ if (next_state < 0)
+ return -EBUSY;
+
if (need_resched()) {
dev->last_residency = 0;
/* give the governor an opportunity to reflect on the outcome */
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
index bc580b67a652..67fd901f6fc9 100644
--- a/drivers/cpuidle/governors/menu.c
+++ b/drivers/cpuidle/governors/menu.c
@@ -269,7 +269,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev)
data->needs_update = 0;
}
- data->last_state_idx = 0;
+ data->last_state_idx = CPUIDLE_DRIVER_STATE_START - 1;
data->exit_us = 0;
/* Special case when user has set very strict latency requirement */
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 5b2b5e61e4f9..057d894eee66 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -935,7 +935,8 @@ static int sg_to_link_tbl(struct scatterlist *sg, int sg_count,
sg_count--;
link_tbl_ptr--;
}
- be16_add_cpu(&link_tbl_ptr->len, cryptlen);
+ link_tbl_ptr->len = cpu_to_be16(be16_to_cpu(link_tbl_ptr->len)
+ + cryptlen);
/* tag end of link table */
link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN;
@@ -2621,6 +2622,7 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
break;
default:
dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
+ kfree(t_alg);
return ERR_PTR(-EINVAL);
}
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index d64ae14f2706..43092c317897 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -393,7 +393,8 @@ static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan)
dma_cookie_t cookie = 0;
int busy = mv_chan_is_busy(mv_chan);
u32 current_desc = mv_chan_get_current_desc(mv_chan);
- int seen_current = 0;
+ int current_cleaned = 0;
+ struct mv_xor_desc *hw_desc;
dev_dbg(mv_chan_to_devp(mv_chan), "%s %d\n", __func__, __LINE__);
dev_dbg(mv_chan_to_devp(mv_chan), "current_desc %x\n", current_desc);
@@ -405,38 +406,57 @@ static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan)
list_for_each_entry_safe(iter, _iter, &mv_chan->chain,
chain_node) {
- prefetch(_iter);
- prefetch(&_iter->async_tx);
- /* do not advance past the current descriptor loaded into the
- * hardware channel, subsequent descriptors are either in
- * process or have not been submitted
- */
- if (seen_current)
- break;
+ /* clean finished descriptors */
+ hw_desc = iter->hw_desc;
+ if (hw_desc->status & XOR_DESC_SUCCESS) {
+ cookie = mv_xor_run_tx_complete_actions(iter, mv_chan,
+ cookie);
- /* stop the search if we reach the current descriptor and the
- * channel is busy
- */
- if (iter->async_tx.phys == current_desc) {
- seen_current = 1;
- if (busy)
+ /* done processing desc, clean slot */
+ mv_xor_clean_slot(iter, mv_chan);
+
+ /* break if we did cleaned the current */
+ if (iter->async_tx.phys == current_desc) {
+ current_cleaned = 1;
+ break;
+ }
+ } else {
+ if (iter->async_tx.phys == current_desc) {
+ current_cleaned = 0;
break;
+ }
}
-
- cookie = mv_xor_run_tx_complete_actions(iter, mv_chan, cookie);
-
- if (mv_xor_clean_slot(iter, mv_chan))
- break;
}
if ((busy == 0) && !list_empty(&mv_chan->chain)) {
- struct mv_xor_desc_slot *chain_head;
- chain_head = list_entry(mv_chan->chain.next,
- struct mv_xor_desc_slot,
- chain_node);
-
- mv_xor_start_new_chain(mv_chan, chain_head);
+ if (current_cleaned) {
+ /*
+ * current descriptor cleaned and removed, run
+ * from list head
+ */
+ iter = list_entry(mv_chan->chain.next,
+ struct mv_xor_desc_slot,
+ chain_node);
+ mv_xor_start_new_chain(mv_chan, iter);
+ } else {
+ if (!list_is_last(&iter->chain_node, &mv_chan->chain)) {
+ /*
+ * descriptors are still waiting after
+ * current, trigger them
+ */
+ iter = list_entry(iter->chain_node.next,
+ struct mv_xor_desc_slot,
+ chain_node);
+ mv_xor_start_new_chain(mv_chan, iter);
+ } else {
+ /*
+ * some descriptors are still waiting
+ * to be cleaned
+ */
+ tasklet_schedule(&mv_chan->irq_tasklet);
+ }
+ }
}
if (cookie > 0)
diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h
index c632a4761fcf..e003851cd4e5 100644
--- a/drivers/dma/mv_xor.h
+++ b/drivers/dma/mv_xor.h
@@ -32,6 +32,7 @@
#define XOR_OPERATION_MODE_XOR 0
#define XOR_OPERATION_MODE_MEMCPY 2
#define XOR_OPERATION_MODE_MEMSET 4
+#define XOR_DESC_SUCCESS 0x40000000
#define XOR_CURR_DESC(chan) (chan->mmr_base + 0x210 + (chan->idx * 4))
#define XOR_NEXT_DESC(chan) (chan->mmr_base + 0x200 + (chan->idx * 4))
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 8759d699bd8e..c24c35606836 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1955,8 +1955,11 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_MODESET))
return -EINVAL;
- /* For some reason crtc x/y offsets are signed internally. */
- if (crtc_req->x > INT_MAX || crtc_req->y > INT_MAX)
+ /*
+ * Universal plane src offsets are only 16.16, prevent havoc for
+ * drivers using universal plane code internally.
+ */
+ if (crtc_req->x & 0xffff0000 || crtc_req->y & 0xffff0000)
return -ERANGE;
drm_modeset_lock_all(dev);
diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c
index f86771481317..5a48d7419baf 100644
--- a/drivers/gpu/drm/qxl/qxl_cmd.c
+++ b/drivers/gpu/drm/qxl/qxl_cmd.c
@@ -500,6 +500,7 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev,
cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release);
cmd->type = QXL_SURFACE_CMD_CREATE;
+ cmd->flags = QXL_SURF_FLAG_KEEP_DATA;
cmd->u.surface_create.format = surf->surf.format;
cmd->u.surface_create.width = surf->surf.width;
cmd->u.surface_create.height = surf->surf.height;
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index 2915a1c56934..c4bb0bc2a1d9 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -251,8 +251,10 @@ void radeon_gart_unbind(struct radeon_device *rdev, unsigned offset,
}
}
}
- mb();
- radeon_gart_tlb_flush(rdev);
+ if (rdev->gart.ptr) {
+ mb();
+ radeon_gart_tlb_flush(rdev);
+ }
}
/**
@@ -294,8 +296,10 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset,
}
}
}
- mb();
- radeon_gart_tlb_flush(rdev);
+ if (rdev->gart.ptr) {
+ mb();
+ radeon_gart_tlb_flush(rdev);
+ }
return 0;
}
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c
index 1fe12ab5c5ea..db83d075606e 100644
--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -73,10 +73,12 @@ static void radeon_hotplug_work_func(struct work_struct *work)
struct drm_mode_config *mode_config = &dev->mode_config;
struct drm_connector *connector;
+ mutex_lock(&mode_config->mutex);
if (mode_config->num_connector) {
list_for_each_entry(connector, &mode_config->connector_list, head)
radeon_connector_hotplug(connector);
}
+ mutex_unlock(&mode_config->mutex);
/* Just fire off a uevent and let userspace tell us what to do */
drm_helper_hpd_irq_event(dev);
}
diff --git a/drivers/hwmon/mcp3021.c b/drivers/hwmon/mcp3021.c
index eedb32292d6d..f712cc785ef2 100644
--- a/drivers/hwmon/mcp3021.c
+++ b/drivers/hwmon/mcp3021.c
@@ -31,14 +31,11 @@
/* output format */
#define MCP3021_SAR_SHIFT 2
#define MCP3021_SAR_MASK 0x3ff
-
#define MCP3021_OUTPUT_RES 10 /* 10-bit resolution */
-#define MCP3021_OUTPUT_SCALE 4
#define MCP3221_SAR_SHIFT 0
#define MCP3221_SAR_MASK 0xfff
#define MCP3221_OUTPUT_RES 12 /* 12-bit resolution */
-#define MCP3221_OUTPUT_SCALE 1
enum chips {
mcp3021,
@@ -54,7 +51,6 @@ struct mcp3021_data {
u16 sar_shift;
u16 sar_mask;
u8 output_res;
- u8 output_scale;
};
static int mcp3021_read16(struct i2c_client *client)
@@ -84,13 +80,7 @@ static int mcp3021_read16(struct i2c_client *client)
static inline u16 volts_from_reg(struct mcp3021_data *data, u16 val)
{
- if (val == 0)
- return 0;
-
- val = val * data->output_scale - data->output_scale / 2;
-
- return val * DIV_ROUND_CLOSEST(data->vdd,
- (1 << data->output_res) * data->output_scale);
+ return DIV_ROUND_CLOSEST(data->vdd * val, 1 << data->output_res);
}
static ssize_t show_in_input(struct device *dev, struct device_attribute *attr,
@@ -132,14 +122,12 @@ static int mcp3021_probe(struct i2c_client *client,
data->sar_shift = MCP3021_SAR_SHIFT;
data->sar_mask = MCP3021_SAR_MASK;
data->output_res = MCP3021_OUTPUT_RES;
- data->output_scale = MCP3021_OUTPUT_SCALE;
break;
case mcp3221:
data->sar_shift = MCP3221_SAR_SHIFT;
data->sar_mask = MCP3221_SAR_MASK;
data->output_res = MCP3221_OUTPUT_RES;
- data->output_scale = MCP3221_OUTPUT_SCALE;
break;
}
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index 09324d0178d5..ceabcfeb587c 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -63,6 +63,9 @@
#define AT91_TWI_UNRE 0x0080 /* Underrun Error */
#define AT91_TWI_NACK 0x0100 /* Not Acknowledged */
+#define AT91_TWI_INT_MASK \
+ (AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY | AT91_TWI_NACK)
+
#define AT91_TWI_IER 0x0024 /* Interrupt Enable Register */
#define AT91_TWI_IDR 0x0028 /* Interrupt Disable Register */
#define AT91_TWI_IMR 0x002c /* Interrupt Mask Register */
@@ -118,13 +121,12 @@ static void at91_twi_write(struct at91_twi_dev *dev, unsigned reg, unsigned val)
static void at91_disable_twi_interrupts(struct at91_twi_dev *dev)
{
- at91_twi_write(dev, AT91_TWI_IDR,
- AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY);
+ at91_twi_write(dev, AT91_TWI_IDR, AT91_TWI_INT_MASK);
}
static void at91_twi_irq_save(struct at91_twi_dev *dev)
{
- dev->imr = at91_twi_read(dev, AT91_TWI_IMR) & 0x7;
+ dev->imr = at91_twi_read(dev, AT91_TWI_IMR) & AT91_TWI_INT_MASK;
at91_disable_twi_interrupts(dev);
}
@@ -214,6 +216,14 @@ static void at91_twi_write_data_dma_callback(void *data)
dma_unmap_single(dev->dev, sg_dma_address(&dev->dma.sg),
dev->buf_len, DMA_TO_DEVICE);
+ /*
+ * When this callback is called, THR/TX FIFO is likely not to be empty
+ * yet. So we have to wait for TXCOMP or NACK bits to be set into the
+ * Status Register to be sure that the STOP bit has been sent and the
+ * transfer is completed. The NACK interrupt has already been enabled,
+ * we just have to enable TXCOMP one.
+ */
+ at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP);
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP);
}
@@ -308,7 +318,7 @@ static void at91_twi_read_data_dma_callback(void *data)
/* The last two bytes have to be read without using dma */
dev->buf += dev->buf_len - 2;
dev->buf_len = 2;
- at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_RXRDY);
+ at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_RXRDY | AT91_TWI_TXCOMP);
}
static void at91_twi_read_data_dma(struct at91_twi_dev *dev)
@@ -369,7 +379,7 @@ static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id)
/* catch error flags */
dev->transfer_status |= status;
- if (irqstatus & AT91_TWI_TXCOMP) {
+ if (irqstatus & (AT91_TWI_TXCOMP | AT91_TWI_NACK)) {
at91_disable_twi_interrupts(dev);
complete(&dev->cmd_complete);
}
@@ -382,6 +392,34 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
int ret;
bool has_unre_flag = dev->pdata->has_unre_flag;
+ /*
+ * WARNING: the TXCOMP bit in the Status Register is NOT a clear on
+ * read flag but shows the state of the transmission at the time the
+ * Status Register is read. According to the programmer datasheet,
+ * TXCOMP is set when both holding register and internal shifter are
+ * empty and STOP condition has been sent.
+ * Consequently, we should enable NACK interrupt rather than TXCOMP to
+ * detect transmission failure.
+ *
+ * Besides, the TXCOMP bit is already set before the i2c transaction
+ * has been started. For read transactions, this bit is cleared when
+ * writing the START bit into the Control Register. So the
+ * corresponding interrupt can safely be enabled just after.
+ * However for write transactions managed by the CPU, we first write
+ * into THR, so TXCOMP is cleared. Then we can safely enable TXCOMP
+ * interrupt. If TXCOMP interrupt were enabled before writing into THR,
+ * the interrupt handler would be called immediately and the i2c command
+ * would be reported as completed.
+ * Also when a write transaction is managed by the DMA controller,
+ * enabling the TXCOMP interrupt in this function may lead to a race
+ * condition since we don't know whether the TXCOMP interrupt is enabled
+ * before or after the DMA has started to write into THR. So the TXCOMP
+ * interrupt is enabled later by at91_twi_write_data_dma_callback().
+ * Immediately after in that DMA callback, we still need to send the
+ * STOP condition manually writing the corresponding bit into the
+ * Control Register.
+ */
+
dev_dbg(dev->dev, "transfer: %s %d bytes.\n",
(dev->msg->flags & I2C_M_RD) ? "read" : "write", dev->buf_len);
@@ -412,26 +450,24 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
* seems to be the best solution.
*/
if (dev->use_dma && (dev->buf_len > AT91_I2C_DMA_THRESHOLD)) {
+ at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_NACK);
at91_twi_read_data_dma(dev);
- /*
- * It is important to enable TXCOMP irq here because
- * doing it only when transferring the last two bytes
- * will mask NACK errors since TXCOMP is set when a
- * NACK occurs.
- */
- at91_twi_write(dev, AT91_TWI_IER,
- AT91_TWI_TXCOMP);
- } else
+ } else {
at91_twi_write(dev, AT91_TWI_IER,
- AT91_TWI_TXCOMP | AT91_TWI_RXRDY);
+ AT91_TWI_TXCOMP |
+ AT91_TWI_NACK |
+ AT91_TWI_RXRDY);
+ }
} else {
if (dev->use_dma && (dev->buf_len > AT91_I2C_DMA_THRESHOLD)) {
+ at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_NACK);
at91_twi_write_data_dma(dev);
- at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP);
} else {
at91_twi_write_next_byte(dev);
at91_twi_write(dev, AT91_TWI_IER,
- AT91_TWI_TXCOMP | AT91_TWI_TXRDY);
+ AT91_TWI_TXCOMP |
+ AT91_TWI_NACK |
+ AT91_TWI_TXRDY);
}
}
diff --git a/drivers/iio/dac/ad5624r_spi.c b/drivers/iio/dac/ad5624r_spi.c
index bb298aaff321..6deac5af1cfd 100644
--- a/drivers/iio/dac/ad5624r_spi.c
+++ b/drivers/iio/dac/ad5624r_spi.c
@@ -22,7 +22,7 @@
#include "ad5624r.h"
static int ad5624r_spi_write(struct spi_device *spi,
- u8 cmd, u8 addr, u16 val, u8 len)
+ u8 cmd, u8 addr, u16 val, u8 shift)
{
u32 data;
u8 msg[3];
@@ -35,7 +35,7 @@ static int ad5624r_spi_write(struct spi_device *spi,
* 14-, 12-bit input code followed by 0, 2, or 4 don't care bits,
* for the AD5664R, AD5644R, and AD5624R, respectively.
*/
- data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << (16 - len));
+ data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << shift);
msg[0] = data >> 16;
msg[1] = data >> 8;
msg[2] = data;
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 8019e642d2f5..43aa807d78bd 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -49,6 +49,8 @@ static int
isert_rdma_accept(struct isert_conn *isert_conn);
struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np);
+static void isert_release_work(struct work_struct *work);
+
static void
isert_qp_event_callback(struct ib_event *e, void *context)
{
@@ -202,7 +204,7 @@ fail:
static void
isert_free_rx_descriptors(struct isert_conn *isert_conn)
{
- struct ib_device *ib_dev = isert_conn->conn_cm_id->device;
+ struct ib_device *ib_dev = isert_conn->conn_device->ib_device;
struct iser_rx_desc *rx_desc;
int i;
@@ -432,6 +434,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
init_completion(&isert_conn->conn_wait_comp_err);
kref_init(&isert_conn->conn_kref);
mutex_init(&isert_conn->conn_mutex);
+ INIT_WORK(&isert_conn->release_work, isert_release_work);
isert_conn->conn_cm_id = cma_id;
isert_conn->responder_resources = event->param.conn.responder_resources;
@@ -527,14 +530,15 @@ out:
static void
isert_connect_release(struct isert_conn *isert_conn)
{
- struct ib_device *ib_dev = isert_conn->conn_cm_id->device;
struct isert_device *device = isert_conn->conn_device;
int cq_index;
+ struct ib_device *ib_dev = device->ib_device;
pr_debug("Entering isert_connect_release(): >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
isert_free_rx_descriptors(isert_conn);
- rdma_destroy_id(isert_conn->conn_cm_id);
+ if (isert_conn->conn_cm_id)
+ rdma_destroy_id(isert_conn->conn_cm_id);
if (isert_conn->conn_qp) {
cq_index = ((struct isert_cq_desc *)
@@ -673,6 +677,7 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id,
{
struct isert_np *isert_np = cma_id->context;
struct isert_conn *isert_conn;
+ bool terminating = false;
if (isert_np->np_cm_id == cma_id)
return isert_np_cma_handler(cma_id->context, event);
@@ -680,21 +685,37 @@ isert_disconnected_handler(struct rdma_cm_id *cma_id,
isert_conn = cma_id->qp->qp_context;
mutex_lock(&isert_conn->conn_mutex);
+ terminating = (isert_conn->state == ISER_CONN_TERMINATING);
isert_conn_terminate(isert_conn);
mutex_unlock(&isert_conn->conn_mutex);
pr_info("conn %p completing conn_wait\n", isert_conn);
complete(&isert_conn->conn_wait);
+ if (terminating)
+ goto out;
+
+ mutex_lock(&isert_np->np_accept_mutex);
+ if (!list_empty(&isert_conn->conn_accept_node)) {
+ list_del_init(&isert_conn->conn_accept_node);
+ isert_put_conn(isert_conn);
+ queue_work(isert_release_wq, &isert_conn->release_work);
+ }
+ mutex_unlock(&isert_np->np_accept_mutex);
+
+out:
return 0;
}
-static void
+static int
isert_connect_error(struct rdma_cm_id *cma_id)
{
struct isert_conn *isert_conn = cma_id->qp->qp_context;
+ isert_conn->conn_cm_id = NULL;
isert_put_conn(isert_conn);
+
+ return -1;
}
static int
@@ -724,7 +745,7 @@ isert_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *event)
case RDMA_CM_EVENT_REJECTED: /* FALLTHRU */
case RDMA_CM_EVENT_UNREACHABLE: /* FALLTHRU */
case RDMA_CM_EVENT_CONNECT_ERROR:
- isert_connect_error(cma_id);
+ ret = isert_connect_error(cma_id);
break;
default:
pr_err("Unhandled RDMA CMA event: %d\n", event->event);
@@ -2418,7 +2439,6 @@ static void isert_wait_conn(struct iscsi_conn *conn)
wait_for_completion(&isert_conn->conn_wait_comp_err);
- INIT_WORK(&isert_conn->release_work, isert_release_work);
queue_work(isert_release_wq, &isert_conn->release_work);
}
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 5f87bed05467..20aef5d5a242 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -626,6 +626,9 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch)
goto err_out;
}
+ /* TSC-25 data sheet specifies a delay after the RESET command */
+ msleep(150);
+
/* set coordinate output rate */
buf[0] = buf[1] = 0xFF;
ret = usb_control_msg(dev, usb_rcvctrlpipe (dev, 0),
diff --git a/drivers/md/md.c b/drivers/md/md.c
index aaf77b07bb72..631fe3e9c6e5 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -6221,7 +6221,7 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info)
mddev->ctime != info->ctime ||
mddev->level != info->level ||
/* mddev->layout != info->layout || */
- !mddev->persistent != info->not_persistent||
+ mddev->persistent != !info->not_persistent ||
mddev->chunk_sectors != info->chunk_size >> 9 ||
/* ignore bottom 8 bits of state, and allow SB_BITMAP_PRESENT to change */
((state^info->state) & 0xfffffe00)
diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c
index b88757cd0d1d..a03178e91a79 100644
--- a/drivers/md/persistent-data/dm-btree-remove.c
+++ b/drivers/md/persistent-data/dm-btree-remove.c
@@ -309,8 +309,8 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent,
if (s < 0 && nr_center < -s) {
/* not enough in central node */
- shift(left, center, nr_center);
- s = nr_center - target;
+ shift(left, center, -nr_center);
+ s += nr_center;
shift(left, right, s);
nr_right += s;
} else
@@ -323,7 +323,7 @@ static void redistribute3(struct dm_btree_info *info, struct btree_node *parent,
if (s > 0 && nr_center < s) {
/* not enough in central node */
shift(center, right, nr_center);
- s = target - nr_center;
+ s -= nr_center;
shift(left, right, s);
nr_left -= s;
} else
diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c
index 0a7592e88811..e3ecb0b824b5 100644
--- a/drivers/md/persistent-data/dm-btree.c
+++ b/drivers/md/persistent-data/dm-btree.c
@@ -240,7 +240,7 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
int r;
struct del_stack *s;
- s = kmalloc(sizeof(*s), GFP_KERNEL);
+ s = kmalloc(sizeof(*s), GFP_NOIO);
if (!s)
return -ENOMEM;
s->tm = info->tm;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 86ac4a4ccc01..fa58438b298a 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -327,7 +327,7 @@ static void raid1_end_read_request(struct bio *bio, int error)
spin_lock_irqsave(&conf->device_lock, flags);
if (r1_bio->mddev->degraded == conf->raid_disks ||
(r1_bio->mddev->degraded == conf->raid_disks-1 &&
- !test_bit(Faulty, &conf->mirrors[mirror].rdev->flags)))
+ test_bit(In_sync, &conf->mirrors[mirror].rdev->flags)))
uptodate = 1;
spin_unlock_irqrestore(&conf->device_lock, flags);
}
diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c
index fb504f1e9125..5930aee6b5d0 100644
--- a/drivers/media/dvb-frontends/af9013.c
+++ b/drivers/media/dvb-frontends/af9013.c
@@ -606,6 +606,10 @@ static int af9013_set_frontend(struct dvb_frontend *fe)
}
}
+ /* Return an error if can't find bandwidth or the right clock */
+ if (i == ARRAY_SIZE(coeff_lut))
+ return -EINVAL;
+
ret = af9013_wr_regs(state, 0xae00, coeff_lut[i].val,
sizeof(coeff_lut[i].val));
}
diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c
index 2916d7c74a1d..7bc68b355c0b 100644
--- a/drivers/media/dvb-frontends/cx24116.c
+++ b/drivers/media/dvb-frontends/cx24116.c
@@ -963,6 +963,10 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
struct cx24116_state *state = fe->demodulator_priv;
int i, ret;
+ /* Validate length */
+ if (d->msg_len > sizeof(d->msg))
+ return -EINVAL;
+
/* Dump DiSEqC message */
if (debug) {
printk(KERN_INFO "cx24116: %s(", __func__);
@@ -974,10 +978,6 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
printk(") toneburst=%d\n", toneburst);
}
- /* Validate length */
- if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS))
- return -EINVAL;
-
/* DiSEqC message */
for (i = 0; i < d->msg_len; i++)
state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i];
diff --git a/drivers/media/dvb-frontends/s5h1420.c b/drivers/media/dvb-frontends/s5h1420.c
index 93eeaf7118fd..0b4f8fe6bf99 100644
--- a/drivers/media/dvb-frontends/s5h1420.c
+++ b/drivers/media/dvb-frontends/s5h1420.c
@@ -180,7 +180,7 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe,
int result = 0;
dprintk("enter %s\n", __func__);
- if (cmd->msg_len > 8)
+ if (cmd->msg_len > sizeof(cmd->msg))
return -EINVAL;
/* setup for DISEQC */
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 56998eca1a8d..885ba4a19a6c 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -202,6 +202,8 @@ static ssize_t power_ro_lock_show(struct device *dev,
ret = snprintf(buf, PAGE_SIZE, "%d\n", locked);
+ mmc_blk_put(md);
+
return ret;
}
@@ -1833,9 +1835,11 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
break;
case MMC_BLK_CMD_ERR:
ret = mmc_blk_cmd_err(md, card, brq, req, ret);
- if (!mmc_blk_reset(md, card->host, type))
- break;
- goto cmd_abort;
+ if (mmc_blk_reset(md, card->host, type))
+ goto cmd_abort;
+ if (!ret)
+ goto start_new_req;
+ break;
case MMC_BLK_RETRY:
if (retry++ < 5)
break;
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index d25f9ab9a54d..d33bb9522416 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -40,7 +40,7 @@
#define ESDHC_DMA_SYSCTL 0x40c
#define ESDHC_DMA_SNOOP 0x00000040
-#define ESDHC_HOST_CONTROL_RES 0x05
+#define ESDHC_HOST_CONTROL_RES 0x01
static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
{
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 4edb24bf56f8..c24fbc574cf1 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -255,6 +255,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev)
mmc_of_parse(host->mmc);
sdhci_get_of_property(pdev);
pdata = pxav3_get_mmc_pdata(dev);
+ pdev->dev.platform_data = pdata;
} else if (pdata) {
/* on-chip device */
if (pdata->flags & PXA_FLAG_CARD_PERMANENT)
diff --git a/drivers/mtd/maps/dc21285.c b/drivers/mtd/maps/dc21285.c
index f8a7dd14cee0..70a3db3ab856 100644
--- a/drivers/mtd/maps/dc21285.c
+++ b/drivers/mtd/maps/dc21285.c
@@ -38,9 +38,9 @@ static void nw_en_write(void)
* we want to write a bit pattern XXX1 to Xilinx to enable
* the write gate, which will be open for about the next 2ms.
*/
- spin_lock_irqsave(&nw_gpio_lock, flags);
+ raw_spin_lock_irqsave(&nw_gpio_lock, flags);
nw_cpld_modify(CPLD_FLASH_WR_ENABLE, CPLD_FLASH_WR_ENABLE);
- spin_unlock_irqrestore(&nw_gpio_lock, flags);
+ raw_spin_unlock_irqrestore(&nw_gpio_lock, flags);
/*
* let the ISA bus to catch on...
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 5073cbc796d8..32d5e40c6863 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -199,6 +199,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/
mutex_lock(&dev->lock);
+ mutex_lock(&mtd_table_mutex);
if (dev->open)
goto unlock;
@@ -222,6 +223,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode)
unlock:
dev->open++;
+ mutex_unlock(&mtd_table_mutex);
mutex_unlock(&dev->lock);
blktrans_dev_put(dev);
return ret;
@@ -232,6 +234,7 @@ error_release:
error_put:
module_put(dev->tr->owner);
kref_put(&dev->ref, blktrans_dev_release);
+ mutex_unlock(&mtd_table_mutex);
mutex_unlock(&dev->lock);
blktrans_dev_put(dev);
return ret;
@@ -245,6 +248,7 @@ static void blktrans_release(struct gendisk *disk, fmode_t mode)
return;
mutex_lock(&dev->lock);
+ mutex_lock(&mtd_table_mutex);
if (--dev->open)
goto unlock;
@@ -258,6 +262,7 @@ static void blktrans_release(struct gendisk *disk, fmode_t mode)
__put_mtd_device(dev->mtd);
}
unlock:
+ mutex_unlock(&mtd_table_mutex);
mutex_unlock(&dev->lock);
blktrans_dev_put(dev);
}
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 82a1b5b16b62..c7f23d271058 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -195,11 +195,13 @@ static bool ath_prepare_reset(struct ath_softc *sc)
ath9k_debug_samp_bb_mac(sc);
ath9k_hw_disable_interrupts(ah);
- if (!ath_drain_all_txq(sc))
- ret = false;
-
- if (!ath_stoprecv(sc))
- ret = false;
+ if (AR_SREV_9300_20_OR_LATER(ah)) {
+ ret &= ath_stoprecv(sc);
+ ret &= ath_drain_all_txq(sc);
+ } else {
+ ret &= ath_drain_all_txq(sc);
+ ret &= ath_stoprecv(sc);
+ }
return ret;
}
diff --git a/drivers/pcmcia/topic.h b/drivers/pcmcia/topic.h
index 615a45a8fe86..582688fe7505 100644
--- a/drivers/pcmcia/topic.h
+++ b/drivers/pcmcia/topic.h
@@ -104,6 +104,9 @@
#define TOPIC_EXCA_IF_CONTROL 0x3e /* 8 bit */
#define TOPIC_EXCA_IFC_33V_ENA 0x01
+#define TOPIC_PCI_CFG_PPBCN 0x3e /* 16-bit */
+#define TOPIC_PCI_CFG_PPBCN_WBEN 0x0400
+
static void topic97_zoom_video(struct pcmcia_socket *sock, int onoff)
{
struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
@@ -138,6 +141,7 @@ static int topic97_override(struct yenta_socket *socket)
static int topic95_override(struct yenta_socket *socket)
{
u8 fctrl;
+ u16 ppbcn;
/* enable 3.3V support for 16bit cards */
fctrl = exca_readb(socket, TOPIC_EXCA_IF_CONTROL);
@@ -146,6 +150,18 @@ static int topic95_override(struct yenta_socket *socket)
/* tell yenta to use exca registers to power 16bit cards */
socket->flags |= YENTA_16BIT_POWER_EXCA | YENTA_16BIT_POWER_DF;
+ /* Disable write buffers to prevent lockups under load with numerous
+ Cardbus cards, observed on Tecra 500CDT and reported elsewhere on the
+ net. This is not a power-on default according to the datasheet
+ but some BIOSes seem to set it. */
+ if (pci_read_config_word(socket->dev, TOPIC_PCI_CFG_PPBCN, &ppbcn) == 0
+ && socket->dev->revision <= 7
+ && (ppbcn & TOPIC_PCI_CFG_PPBCN_WBEN)) {
+ ppbcn &= ~TOPIC_PCI_CFG_PPBCN_WBEN;
+ pci_write_config_word(socket->dev, TOPIC_PCI_CFG_PPBCN, ppbcn);
+ dev_info(&socket->dev->dev, "Disabled ToPIC95 Cardbus write buffers.\n");
+ }
+
return 0;
}
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-370.c b/drivers/pinctrl/mvebu/pinctrl-armada-370.c
index 48e21a229483..c99e64ac8e08 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-370.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-370.c
@@ -358,11 +358,11 @@ static struct mvebu_mpp_mode mv88f6710_mpp_modes[] = {
MPP_MODE(64,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "spi0", "miso"),
- MPP_FUNCTION(0x2, "spi0-1", "cs1")),
+ MPP_FUNCTION(0x2, "spi0", "cs1")),
MPP_MODE(65,
MPP_FUNCTION(0x0, "gpio", NULL),
MPP_FUNCTION(0x1, "spi0", "mosi"),
- MPP_FUNCTION(0x2, "spi0-1", "cs2")),
+ MPP_FUNCTION(0x2, "spi0", "cs2")),
};
static struct mvebu_pinctrl_soc_info armada_370_pinctrl_info;
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
index ab5dc04b3e8a..5923a9ef70cc 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
@@ -14,10 +14,7 @@
* available: mv78230, mv78260 and mv78460. From a pin muxing
* perspective, the mv78230 has 49 MPP pins. The mv78260 and mv78460
* both have 67 MPP pins (more GPIOs and address lines for the memory
- * bus mainly). The only difference between the mv78260 and the
- * mv78460 in terms of pin muxing is the addition of two functions on
- * pins 43 and 56 to access the VDD of the CPU2 and 3 (mv78260 has two
- * cores, mv78460 has four cores).
+ * bus mainly).
*/
#include <linux/err.h>
@@ -159,20 +156,17 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = {
MPP_MODE(24,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x1, "sata1", "prsnt", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x2, "nf", "bootcs-re", V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x3, "tdm", "rst", V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x4, "lcd", "hsync", V_MV78230_PLUS)),
MPP_MODE(25,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x1, "sata0", "prsnt", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x2, "nf", "bootcs-we", V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x3, "tdm", "pclk", V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x4, "lcd", "vsync", V_MV78230_PLUS)),
MPP_MODE(26,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x3, "tdm", "fsync", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x4, "lcd", "clk", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x5, "vdd", "cpu1-pd", V_MV78230_PLUS)),
+ MPP_VAR_FUNCTION(0x4, "lcd", "clk", V_MV78230_PLUS)),
MPP_MODE(27,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x1, "ptp", "trig", V_MV78230_PLUS),
@@ -187,8 +181,7 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = {
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x1, "ptp", "clk", V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x3, "tdm", "int0", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x4, "lcd", "ref-clk", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)),
+ MPP_VAR_FUNCTION(0x4, "lcd", "ref-clk", V_MV78230_PLUS)),
MPP_MODE(30,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x1, "sd0", "clk", V_MV78230_PLUS),
@@ -196,13 +189,11 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = {
MPP_MODE(31,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x1, "sd0", "cmd", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x3, "tdm", "int2", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)),
+ MPP_VAR_FUNCTION(0x3, "tdm", "int2", V_MV78230_PLUS)),
MPP_MODE(32,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x1, "sd0", "d0", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x3, "tdm", "int3", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x5, "vdd", "cpu1-pd", V_MV78230_PLUS)),
+ MPP_VAR_FUNCTION(0x3, "tdm", "int3", V_MV78230_PLUS)),
MPP_MODE(33,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x1, "sd0", "d1", V_MV78230_PLUS),
@@ -234,7 +225,6 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = {
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x1, "spi", "cs1", V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x2, "uart2", "cts", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x3, "vdd", "cpu1-pd", V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x4, "lcd", "vga-hsync", V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x5, "pcie", "clkreq0", V_MV78230_PLUS)),
MPP_MODE(41,
@@ -249,15 +239,13 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = {
MPP_VAR_FUNCTION(0x1, "uart2", "rxd", V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x2, "uart0", "cts", V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x3, "tdm", "int7", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x4, "tdm-1", "timer", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x5, "vdd", "cpu0-pd", V_MV78230_PLUS)),
+ MPP_VAR_FUNCTION(0x4, "tdm-1", "timer", V_MV78230_PLUS)),
MPP_MODE(43,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x1, "uart2", "txd", V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x2, "uart0", "rts", V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x3, "spi", "cs3", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x4, "pcie", "rstout", V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x5, "vdd", "cpu2-3-pd", V_MV78460)),
+ MPP_VAR_FUNCTION(0x4, "pcie", "rstout", V_MV78230_PLUS)),
MPP_MODE(44,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x1, "uart2", "cts", V_MV78230_PLUS),
@@ -286,7 +274,7 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = {
MPP_VAR_FUNCTION(0x5, "pcie", "clkreq3", V_MV78230_PLUS)),
MPP_MODE(48,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78230_PLUS),
- MPP_VAR_FUNCTION(0x1, "tclk", NULL, V_MV78230_PLUS),
+ MPP_VAR_FUNCTION(0x1, "dev", "clkout", V_MV78230_PLUS),
MPP_VAR_FUNCTION(0x2, "dev", "burst/last", V_MV78230_PLUS)),
MPP_MODE(49,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
@@ -308,16 +296,13 @@ static struct mvebu_mpp_mode armada_xp_mpp_modes[] = {
MPP_VAR_FUNCTION(0x1, "dev", "ad19", V_MV78260_PLUS)),
MPP_MODE(55,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
- MPP_VAR_FUNCTION(0x1, "dev", "ad20", V_MV78260_PLUS),
- MPP_VAR_FUNCTION(0x2, "vdd", "cpu0-pd", V_MV78260_PLUS)),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad20", V_MV78260_PLUS)),
MPP_MODE(56,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
- MPP_VAR_FUNCTION(0x1, "dev", "ad21", V_MV78260_PLUS),
- MPP_VAR_FUNCTION(0x2, "vdd", "cpu1-pd", V_MV78260_PLUS)),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad21", V_MV78260_PLUS)),
MPP_MODE(57,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
- MPP_VAR_FUNCTION(0x1, "dev", "ad22", V_MV78260_PLUS),
- MPP_VAR_FUNCTION(0x2, "vdd", "cpu2-3-pd", V_MV78460)),
+ MPP_VAR_FUNCTION(0x1, "dev", "ad22", V_MV78260_PLUS)),
MPP_MODE(58,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_MV78260_PLUS),
MPP_VAR_FUNCTION(0x1, "dev", "ad23", V_MV78260_PLUS)),
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 73cc3bba0d78..eaaae3080802 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -769,7 +769,7 @@ static int suspend_prepare(struct regulator_dev *rdev, suspend_state_t state)
static void print_constraints(struct regulator_dev *rdev)
{
struct regulation_constraints *constraints = rdev->constraints;
- char buf[80] = "";
+ char buf[160] = "";
int count = 0;
int ret;
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 535f57328a72..c19911554036 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -257,7 +257,7 @@
#define IPR_RUNTIME_RESET 0x40000000
#define IPR_IPL_INIT_MIN_STAGE_TIME 5
-#define IPR_IPL_INIT_DEFAULT_STAGE_TIME 15
+#define IPR_IPL_INIT_DEFAULT_STAGE_TIME 30
#define IPR_IPL_INIT_STAGE_UNKNOWN 0x0
#define IPR_IPL_INIT_STAGE_TRANSOP 0xB0000000
#define IPR_IPL_INIT_STAGE_MASK 0xff000000
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index d2a4c75e5b8f..813e9d8ba351 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -523,8 +523,9 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82;
- uint32_t rscn_entry, host_pid;
+ uint32_t rscn_entry, host_pid, tmp_pid;
unsigned long flags;
+ fc_port_t *fcport = NULL;
/* Setup to process RIO completion. */
handle_cnt = 0;
@@ -918,6 +919,20 @@ skip_rio:
if (qla2x00_is_a_vp_did(vha, rscn_entry))
break;
+ /*
+ * Search for the rport related to this RSCN entry and mark it
+ * as lost.
+ */
+ list_for_each_entry(fcport, &vha->vp_fcports, list) {
+ if (atomic_read(&fcport->state) != FCS_ONLINE)
+ continue;
+ tmp_pid = fcport->d_id.b24;
+ if (fcport->d_id.b24 == rscn_entry) {
+ qla2x00_mark_device_lost(vha, fcport, 0, 0);
+ break;
+ }
+ }
+
atomic_set(&vha->loop_down_timer, 0);
vha->flags.management_server_logged_in = 0;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 2a32036a9404..fa9811200c9d 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -1262,9 +1262,9 @@ static int st_open(struct inode *inode, struct file *filp)
spin_lock(&st_use_lock);
STp->in_use = 0;
spin_unlock(&st_use_lock);
- scsi_tape_put(STp);
if (resumed)
scsi_autopm_put_device(STp->device);
+ scsi_tape_put(STp);
return retval;
}
diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c
index d59a74aa3048..4b25f3afb8dc 100644
--- a/drivers/staging/rtl8712/rtl8712_recv.c
+++ b/drivers/staging/rtl8712/rtl8712_recv.c
@@ -1075,7 +1075,8 @@ static int recvbuf2recvframe(struct _adapter *padapter, struct sk_buff *pskb)
/* for first fragment packet, driver need allocate 1536 +
* drvinfo_sz + RXDESC_SIZE to defrag packet. */
if ((mf == 1) && (frag == 0))
- alloc_sz = 1658;/*1658+6=1664, 1664 is 128 alignment.*/
+ /*1658+6=1664, 1664 is 128 alignment.*/
+ alloc_sz = max_t(u16, tmp_len, 1658);
else
alloc_sz = tmp_len;
/* 2 is for IP header 4 bytes alignment in QoS packet case.
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 5a3ea20e9cb5..efca110342cb 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -518,7 +518,7 @@ static struct iscsit_transport iscsi_target_transport = {
static int __init iscsi_target_init_module(void)
{
- int ret = 0;
+ int ret = 0, size;
pr_debug("iSCSI-Target "ISCSIT_VERSION"\n");
@@ -527,6 +527,7 @@ static int __init iscsi_target_init_module(void)
pr_err("Unable to allocate memory for iscsit_global\n");
return -1;
}
+ spin_lock_init(&iscsit_global->ts_bitmap_lock);
mutex_init(&auth_id_lock);
spin_lock_init(&sess_idr_lock);
idr_init(&tiqn_idr);
@@ -536,15 +537,11 @@ static int __init iscsi_target_init_module(void)
if (ret < 0)
goto out;
- ret = iscsi_thread_set_init();
- if (ret < 0)
+ size = BITS_TO_LONGS(ISCSIT_BITMAP_BITS) * sizeof(long);
+ iscsit_global->ts_bitmap = vzalloc(size);
+ if (!iscsit_global->ts_bitmap) {
+ pr_err("Unable to allocate iscsit_global->ts_bitmap\n");
goto configfs_out;
-
- if (iscsi_allocate_thread_sets(TARGET_THREAD_SET_COUNT) !=
- TARGET_THREAD_SET_COUNT) {
- pr_err("iscsi_allocate_thread_sets() returned"
- " unexpected value!\n");
- goto ts_out1;
}
lio_cmd_cache = kmem_cache_create("lio_cmd_cache",
@@ -553,7 +550,7 @@ static int __init iscsi_target_init_module(void)
if (!lio_cmd_cache) {
pr_err("Unable to kmem_cache_create() for"
" lio_cmd_cache\n");
- goto ts_out2;
+ goto bitmap_out;
}
lio_qr_cache = kmem_cache_create("lio_qr_cache",
@@ -608,10 +605,8 @@ qr_out:
kmem_cache_destroy(lio_qr_cache);
cmd_out:
kmem_cache_destroy(lio_cmd_cache);
-ts_out2:
- iscsi_deallocate_thread_sets();
-ts_out1:
- iscsi_thread_set_free();
+bitmap_out:
+ vfree(iscsit_global->ts_bitmap);
configfs_out:
iscsi_target_deregister_configfs();
out:
@@ -621,8 +616,6 @@ out:
static void __exit iscsi_target_cleanup_module(void)
{
- iscsi_deallocate_thread_sets();
- iscsi_thread_set_free();
iscsit_release_discovery_tpg();
iscsit_unregister_transport(&iscsi_target_transport);
kmem_cache_destroy(lio_cmd_cache);
@@ -633,6 +626,7 @@ static void __exit iscsi_target_cleanup_module(void)
iscsi_target_deregister_configfs();
+ vfree(iscsit_global->ts_bitmap);
kfree(iscsit_global);
}
@@ -3590,17 +3584,16 @@ static int iscsit_send_reject(
void iscsit_thread_get_cpumask(struct iscsi_conn *conn)
{
- struct iscsi_thread_set *ts = conn->thread_set;
int ord, cpu;
/*
- * thread_id is assigned from iscsit_global->ts_bitmap from
- * within iscsi_thread_set.c:iscsi_allocate_thread_sets()
+ * bitmap_id is assigned from iscsit_global->ts_bitmap from
+ * within iscsit_start_kthreads()
*
- * Here we use thread_id to determine which CPU that this
- * iSCSI connection's iscsi_thread_set will be scheduled to
+ * Here we use bitmap_id to determine which CPU that this
+ * iSCSI connection's RX/TX threads will be scheduled to
* execute upon.
*/
- ord = ts->thread_id % cpumask_weight(cpu_online_mask);
+ ord = conn->bitmap_id % cpumask_weight(cpu_online_mask);
for_each_online_cpu(cpu) {
if (ord-- == 0) {
cpumask_set_cpu(cpu, conn->conn_cpumask);
@@ -3792,7 +3785,7 @@ check_rsp_state:
switch (state) {
case ISTATE_SEND_LOGOUTRSP:
if (!iscsit_logout_post_handler(cmd, conn))
- goto restart;
+ return -ECONNRESET;
/* fall through */
case ISTATE_SEND_STATUS:
case ISTATE_SEND_ASYNCMSG:
@@ -3820,8 +3813,6 @@ check_rsp_state:
err:
return -1;
-restart:
- return -EAGAIN;
}
static int iscsit_handle_response_queue(struct iscsi_conn *conn)
@@ -3848,21 +3839,13 @@ static int iscsit_handle_response_queue(struct iscsi_conn *conn)
int iscsi_target_tx_thread(void *arg)
{
int ret = 0;
- struct iscsi_conn *conn;
- struct iscsi_thread_set *ts = arg;
+ struct iscsi_conn *conn = arg;
/*
* Allow ourselves to be interrupted by SIGINT so that a
* connection recovery / failure event can be triggered externally.
*/
allow_signal(SIGINT);
-restart:
- conn = iscsi_tx_thread_pre_handler(ts);
- if (!conn)
- goto out;
-
- ret = 0;
-
while (!kthread_should_stop()) {
/*
* Ensure that both TX and RX per connection kthreads
@@ -3871,11 +3854,9 @@ restart:
iscsit_thread_check_cpumask(conn, current, 1);
wait_event_interruptible(conn->queues_wq,
- !iscsit_conn_all_queues_empty(conn) ||
- ts->status == ISCSI_THREAD_SET_RESET);
+ !iscsit_conn_all_queues_empty(conn));
- if ((ts->status == ISCSI_THREAD_SET_RESET) ||
- signal_pending(current))
+ if (signal_pending(current))
goto transport_err;
get_immediate:
@@ -3886,15 +3867,14 @@ get_immediate:
ret = iscsit_handle_response_queue(conn);
if (ret == 1)
goto get_immediate;
- else if (ret == -EAGAIN)
- goto restart;
+ else if (ret == -ECONNRESET)
+ goto out;
else if (ret < 0)
goto transport_err;
}
transport_err:
iscsit_take_action_for_connection_exit(conn);
- goto restart;
out:
return 0;
}
@@ -3979,8 +3959,7 @@ int iscsi_target_rx_thread(void *arg)
int ret;
u8 buffer[ISCSI_HDR_LEN], opcode;
u32 checksum = 0, digest = 0;
- struct iscsi_conn *conn = NULL;
- struct iscsi_thread_set *ts = arg;
+ struct iscsi_conn *conn = arg;
struct kvec iov;
/*
* Allow ourselves to be interrupted by SIGINT so that a
@@ -3988,11 +3967,6 @@ int iscsi_target_rx_thread(void *arg)
*/
allow_signal(SIGINT);
-restart:
- conn = iscsi_rx_thread_pre_handler(ts);
- if (!conn)
- goto out;
-
if (conn->conn_transport->transport_type == ISCSI_INFINIBAND) {
struct completion comp;
int rc;
@@ -4002,7 +3976,7 @@ restart:
if (rc < 0)
goto transport_err;
- goto out;
+ goto transport_err;
}
while (!kthread_should_stop()) {
@@ -4085,8 +4059,6 @@ transport_err:
if (!signal_pending(current))
atomic_set(&conn->transport_failed, 1);
iscsit_take_action_for_connection_exit(conn);
- goto restart;
-out:
return 0;
}
@@ -4148,7 +4120,24 @@ int iscsit_close_connection(
if (conn->conn_transport->transport_type == ISCSI_TCP)
complete(&conn->conn_logout_comp);
- iscsi_release_thread_set(conn);
+ if (!strcmp(current->comm, ISCSI_RX_THREAD_NAME)) {
+ if (conn->tx_thread &&
+ cmpxchg(&conn->tx_thread_active, true, false)) {
+ send_sig(SIGINT, conn->tx_thread, 1);
+ kthread_stop(conn->tx_thread);
+ }
+ } else if (!strcmp(current->comm, ISCSI_TX_THREAD_NAME)) {
+ if (conn->rx_thread &&
+ cmpxchg(&conn->rx_thread_active, true, false)) {
+ send_sig(SIGINT, conn->rx_thread, 1);
+ kthread_stop(conn->rx_thread);
+ }
+ }
+
+ spin_lock(&iscsit_global->ts_bitmap_lock);
+ bitmap_release_region(iscsit_global->ts_bitmap, conn->bitmap_id,
+ get_order(1));
+ spin_unlock(&iscsit_global->ts_bitmap_lock);
iscsit_stop_timers_for_cmds(conn);
iscsit_stop_nopin_response_timer(conn);
@@ -4427,15 +4416,24 @@ static void iscsit_logout_post_handler_closesession(
struct iscsi_conn *conn)
{
struct iscsi_session *sess = conn->sess;
-
- iscsi_set_thread_clear(conn, ISCSI_CLEAR_TX_THREAD);
- iscsi_set_thread_set_signal(conn, ISCSI_SIGNAL_TX_THREAD);
+ int sleep = 1;
+ /*
+ * Traditional iscsi/tcp will invoke this logic from TX thread
+ * context during session logout, so clear tx_thread_active and
+ * sleep if iscsit_close_connection() has not already occured.
+ *
+ * Since iser-target invokes this logic from it's own workqueue,
+ * always sleep waiting for RX/TX thread shutdown to complete
+ * within iscsit_close_connection().
+ */
+ if (conn->conn_transport->transport_type == ISCSI_TCP)
+ sleep = cmpxchg(&conn->tx_thread_active, true, false);
atomic_set(&conn->conn_logout_remove, 0);
complete(&conn->conn_logout_comp);
iscsit_dec_conn_usage_count(conn);
- iscsit_stop_session(sess, 1, 1);
+ iscsit_stop_session(sess, sleep, sleep);
iscsit_dec_session_usage_count(sess);
target_put_session(sess->se_sess);
}
@@ -4443,13 +4441,15 @@ static void iscsit_logout_post_handler_closesession(
static void iscsit_logout_post_handler_samecid(
struct iscsi_conn *conn)
{
- iscsi_set_thread_clear(conn, ISCSI_CLEAR_TX_THREAD);
- iscsi_set_thread_set_signal(conn, ISCSI_SIGNAL_TX_THREAD);
+ int sleep = 1;
+
+ if (conn->conn_transport->transport_type == ISCSI_TCP)
+ sleep = cmpxchg(&conn->tx_thread_active, true, false);
atomic_set(&conn->conn_logout_remove, 0);
complete(&conn->conn_logout_comp);
- iscsit_cause_connection_reinstatement(conn, 1);
+ iscsit_cause_connection_reinstatement(conn, sleep);
iscsit_dec_conn_usage_count(conn);
}
@@ -4663,6 +4663,7 @@ int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force)
struct iscsi_session *sess;
struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
struct se_session *se_sess, *se_sess_tmp;
+ LIST_HEAD(free_list);
int session_count = 0;
spin_lock_bh(&se_tpg->session_lock);
@@ -4684,14 +4685,17 @@ int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force)
}
atomic_set(&sess->session_reinstatement, 1);
spin_unlock(&sess->conn_lock);
- spin_unlock_bh(&se_tpg->session_lock);
- iscsit_free_session(sess);
- spin_lock_bh(&se_tpg->session_lock);
+ list_move_tail(&se_sess->sess_list, &free_list);
+ }
+ spin_unlock_bh(&se_tpg->session_lock);
+ list_for_each_entry_safe(se_sess, se_sess_tmp, &free_list, sess_list) {
+ sess = (struct iscsi_session *)se_sess->fabric_sess_ptr;
+
+ iscsit_free_session(sess);
session_count++;
}
- spin_unlock_bh(&se_tpg->session_lock);
pr_debug("Released %d iSCSI Session(s) from Target Portal"
" Group: %hu\n", session_count, tpg->tpgt);
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h
index e117870eb445..815bf5b1a4ae 100644
--- a/drivers/target/iscsi/iscsi_target_core.h
+++ b/drivers/target/iscsi/iscsi_target_core.h
@@ -586,6 +586,11 @@ struct iscsi_conn {
struct iscsi_session *sess;
/* Pointer to thread_set in use for this conn's threads */
struct iscsi_thread_set *thread_set;
+ int bitmap_id;
+ int rx_thread_active;
+ struct task_struct *rx_thread;
+ int tx_thread_active;
+ struct task_struct *tx_thread;
/* list_head for session connection list */
struct list_head conn_list;
} ____cacheline_aligned;
@@ -862,10 +867,12 @@ struct iscsit_global {
/* Unique identifier used for the authentication daemon */
u32 auth_id;
u32 inactive_ts;
+#define ISCSIT_BITMAP_BITS 262144
/* Thread Set bitmap count */
int ts_bitmap_count;
/* Thread Set bitmap pointer */
unsigned long *ts_bitmap;
+ spinlock_t ts_bitmap_lock;
/* Used for iSCSI discovery session authentication */
struct iscsi_node_acl discovery_acl;
struct iscsi_portal_group *discovery_tpg;
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c
index 08bd87833321..fab67eea54c0 100644
--- a/drivers/target/iscsi/iscsi_target_erl0.c
+++ b/drivers/target/iscsi/iscsi_target_erl0.c
@@ -866,7 +866,10 @@ void iscsit_connection_reinstatement_rcfr(struct iscsi_conn *conn)
}
spin_unlock_bh(&conn->state_lock);
- iscsi_thread_set_force_reinstatement(conn);
+ if (conn->tx_thread && conn->tx_thread_active)
+ send_sig(SIGINT, conn->tx_thread, 1);
+ if (conn->rx_thread && conn->rx_thread_active)
+ send_sig(SIGINT, conn->rx_thread, 1);
sleep:
wait_for_completion(&conn->conn_wait_rcfr_comp);
@@ -891,10 +894,10 @@ void iscsit_cause_connection_reinstatement(struct iscsi_conn *conn, int sleep)
return;
}
- if (iscsi_thread_set_force_reinstatement(conn) < 0) {
- spin_unlock_bh(&conn->state_lock);
- return;
- }
+ if (conn->tx_thread && conn->tx_thread_active)
+ send_sig(SIGINT, conn->tx_thread, 1);
+ if (conn->rx_thread && conn->rx_thread_active)
+ send_sig(SIGINT, conn->rx_thread, 1);
atomic_set(&conn->connection_reinstatement, 1);
if (!sleep) {
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index 0493e8b1ba8f..797b2e2acc35 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -683,7 +683,52 @@ static void iscsi_post_login_start_timers(struct iscsi_conn *conn)
iscsit_start_nopin_timer(conn);
}
-static int iscsi_post_login_handler(
+int iscsit_start_kthreads(struct iscsi_conn *conn)
+{
+ int ret = 0;
+
+ spin_lock(&iscsit_global->ts_bitmap_lock);
+ conn->bitmap_id = bitmap_find_free_region(iscsit_global->ts_bitmap,
+ ISCSIT_BITMAP_BITS, get_order(1));
+ spin_unlock(&iscsit_global->ts_bitmap_lock);
+
+ if (conn->bitmap_id < 0) {
+ pr_err("bitmap_find_free_region() failed for"
+ " iscsit_start_kthreads()\n");
+ return -ENOMEM;
+ }
+
+ conn->tx_thread = kthread_run(iscsi_target_tx_thread, conn,
+ "%s", ISCSI_TX_THREAD_NAME);
+ if (IS_ERR(conn->tx_thread)) {
+ pr_err("Unable to start iscsi_target_tx_thread\n");
+ ret = PTR_ERR(conn->tx_thread);
+ goto out_bitmap;
+ }
+ conn->tx_thread_active = true;
+
+ conn->rx_thread = kthread_run(iscsi_target_rx_thread, conn,
+ "%s", ISCSI_RX_THREAD_NAME);
+ if (IS_ERR(conn->rx_thread)) {
+ pr_err("Unable to start iscsi_target_rx_thread\n");
+ ret = PTR_ERR(conn->rx_thread);
+ goto out_tx;
+ }
+ conn->rx_thread_active = true;
+
+ return 0;
+out_tx:
+ kthread_stop(conn->tx_thread);
+ conn->tx_thread_active = false;
+out_bitmap:
+ spin_lock(&iscsit_global->ts_bitmap_lock);
+ bitmap_release_region(iscsit_global->ts_bitmap, conn->bitmap_id,
+ get_order(1));
+ spin_unlock(&iscsit_global->ts_bitmap_lock);
+ return ret;
+}
+
+int iscsi_post_login_handler(
struct iscsi_np *np,
struct iscsi_conn *conn,
u8 zero_tsih)
@@ -693,7 +738,7 @@ static int iscsi_post_login_handler(
struct se_session *se_sess = sess->se_sess;
struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess);
struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
- struct iscsi_thread_set *ts;
+ int rc;
iscsit_inc_conn_usage_count(conn);
@@ -708,7 +753,6 @@ static int iscsi_post_login_handler(
/*
* SCSI Initiator -> SCSI Target Port Mapping
*/
- ts = iscsi_get_thread_set();
if (!zero_tsih) {
iscsi_set_session_parameters(sess->sess_ops,
conn->param_list, 0);
@@ -735,9 +779,11 @@ static int iscsi_post_login_handler(
sess->sess_ops->InitiatorName);
spin_unlock_bh(&sess->conn_lock);
- iscsi_post_login_start_timers(conn);
+ rc = iscsit_start_kthreads(conn);
+ if (rc)
+ return rc;
- iscsi_activate_thread_set(conn, ts);
+ iscsi_post_login_start_timers(conn);
/*
* Determine CPU mask to ensure connection's RX and TX kthreads
* are scheduled on the same CPU.
@@ -794,8 +840,11 @@ static int iscsi_post_login_handler(
" iSCSI Target Portal Group: %hu\n", tpg->nsessions, tpg->tpgt);
spin_unlock_bh(&se_tpg->session_lock);
+ rc = iscsit_start_kthreads(conn);
+ if (rc)
+ return rc;
+
iscsi_post_login_start_timers(conn);
- iscsi_activate_thread_set(conn, ts);
/*
* Determine CPU mask to ensure connection's RX and TX kthreads
* are scheduled on the same CPU.
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 78ddfb43750a..62e532fb82ad 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -513,7 +513,7 @@ static void async_completed(struct urb *urb)
snoop(&urb->dev->dev, "urb complete\n");
snoop_urb(urb->dev, as->userurb, urb->pipe, urb->actual_length,
as->status, COMPLETE, NULL, 0);
- if ((urb->transfer_flags & URB_DIR_MASK) == USB_DIR_IN)
+ if ((urb->transfer_flags & URB_DIR_MASK) == URB_DIR_IN)
snoop_urb_data(urb, urb->actual_length);
if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET &&
@@ -1593,7 +1593,7 @@ static struct async *reap_as(struct dev_state *ps)
for (;;) {
__set_current_state(TASK_INTERRUPTIBLE);
as = async_getcompleted(ps);
- if (as)
+ if (as || !connected(ps))
break;
if (signal_pending(current))
break;
@@ -1616,7 +1616,7 @@ static int proc_reapurb(struct dev_state *ps, void __user *arg)
}
if (signal_pending(current))
return -EINTR;
- return -EIO;
+ return -ENODEV;
}
static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg)
@@ -1625,10 +1625,11 @@ static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg)
struct async *as;
as = async_getcompleted(ps);
- retval = -EAGAIN;
if (as) {
retval = processcompl(as, (void __user * __user *)arg);
free_async(as);
+ } else {
+ retval = (connected(ps) ? -EAGAIN : -ENODEV);
}
return retval;
}
@@ -1758,7 +1759,7 @@ static int proc_reapurb_compat(struct dev_state *ps, void __user *arg)
}
if (signal_pending(current))
return -EINTR;
- return -EIO;
+ return -ENODEV;
}
static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg)
@@ -1766,11 +1767,12 @@ static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg)
int retval;
struct async *as;
- retval = -EAGAIN;
as = async_getcompleted(ps);
if (as) {
retval = processcompl_compat(as, (void __user * __user *)arg);
free_async(as);
+ } else {
+ retval = (connected(ps) ? -EAGAIN : -ENODEV);
}
return retval;
}
@@ -1941,7 +1943,8 @@ static int proc_get_capabilities(struct dev_state *ps, void __user *arg)
{
__u32 caps;
- caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM;
+ caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM |
+ USBDEVFS_CAP_REAP_AFTER_DISCONNECT;
if (!ps->dev->bus->no_stop_on_short)
caps |= USBDEVFS_CAP_BULK_CONTINUATION;
if (ps->dev->bus->sg_tablesize)
@@ -2002,6 +2005,32 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
return -EPERM;
usb_lock_device(dev);
+
+ /* Reap operations are allowed even after disconnection */
+ switch (cmd) {
+ case USBDEVFS_REAPURB:
+ snoop(&dev->dev, "%s: REAPURB\n", __func__);
+ ret = proc_reapurb(ps, p);
+ goto done;
+
+ case USBDEVFS_REAPURBNDELAY:
+ snoop(&dev->dev, "%s: REAPURBNDELAY\n", __func__);
+ ret = proc_reapurbnonblock(ps, p);
+ goto done;
+
+#ifdef CONFIG_COMPAT
+ case USBDEVFS_REAPURB32:
+ snoop(&dev->dev, "%s: REAPURB32\n", __func__);
+ ret = proc_reapurb_compat(ps, p);
+ goto done;
+
+ case USBDEVFS_REAPURBNDELAY32:
+ snoop(&dev->dev, "%s: REAPURBNDELAY32\n", __func__);
+ ret = proc_reapurbnonblock_compat(ps, p);
+ goto done;
+#endif
+ }
+
if (!connected(ps)) {
usb_unlock_device(dev);
return -ENODEV;
@@ -2095,16 +2124,6 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
inode->i_mtime = CURRENT_TIME;
break;
- case USBDEVFS_REAPURB32:
- snoop(&dev->dev, "%s: REAPURB32\n", __func__);
- ret = proc_reapurb_compat(ps, p);
- break;
-
- case USBDEVFS_REAPURBNDELAY32:
- snoop(&dev->dev, "%s: REAPURBNDELAY32\n", __func__);
- ret = proc_reapurbnonblock_compat(ps, p);
- break;
-
case USBDEVFS_IOCTL32:
snoop(&dev->dev, "%s: IOCTL32\n", __func__);
ret = proc_ioctl_compat(ps, ptr_to_compat(p));
@@ -2116,16 +2135,6 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
ret = proc_unlinkurb(ps, p);
break;
- case USBDEVFS_REAPURB:
- snoop(&dev->dev, "%s: REAPURB\n", __func__);
- ret = proc_reapurb(ps, p);
- break;
-
- case USBDEVFS_REAPURBNDELAY:
- snoop(&dev->dev, "%s: REAPURBNDELAY\n", __func__);
- ret = proc_reapurbnonblock(ps, p);
- break;
-
case USBDEVFS_DISCSIGNAL:
snoop(&dev->dev, "%s: DISCSIGNAL\n", __func__);
ret = proc_disconnectsignal(ps, p);
@@ -2162,6 +2171,8 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
ret = proc_disconnect_claim(ps, p);
break;
}
+
+ done:
usb_unlock_device(dev);
if (ret >= 0)
inode->i_atime = CURRENT_TIME;
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 6cd418f6ac07..57d7ec6c8090 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -718,6 +718,10 @@ static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
dev_vdbg(dwc->dev, "USB_REQ_SET_ISOCH_DELAY\n");
ret = dwc3_ep0_set_isoch_delay(dwc, ctrl);
break;
+ case USB_REQ_SET_INTERFACE:
+ dev_vdbg(dwc->dev, "USB_REQ_SET_INTERFACE\n");
+ dwc->start_config_issued = false;
+ /* Fall through */
default:
dev_vdbg(dwc->dev, "Forwarding to gadget driver\n");
ret = dwc3_ep0_delegate_req(dwc, ctrl);
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 87f8fc63b3e1..6e70c88b25fb 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -319,6 +319,8 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, int cmd, u32 param)
if (!(reg & DWC3_DGCMD_CMDACT)) {
dev_vdbg(dwc->dev, "Command Complete --> %d\n",
DWC3_DGCMD_STATUS(reg));
+ if (DWC3_DGCMD_STATUS(reg))
+ return -EINVAL;
return 0;
}
@@ -355,6 +357,8 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
if (!(reg & DWC3_DEPCMD_CMDACT)) {
dev_vdbg(dwc->dev, "Command Complete --> %d\n",
DWC3_DEPCMD_STATUS(reg));
+ if (DWC3_DEPCMD_STATUS(reg))
+ return -EINVAL;
return 0;
}
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index d939376c5dee..0f71c3a22507 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -468,10 +468,13 @@ static void xhci_hub_report_link_state(struct xhci_hcd *xhci,
u32 pls = status_reg & PORT_PLS_MASK;
/* resume state is a xHCI internal state.
- * Do not report it to usb core.
+ * Do not report it to usb core, instead, pretend to be U3,
+ * thus usb core knows it's not ready for transfer
*/
- if (pls == XDEV_RESUME)
+ if (pls == XDEV_RESUME) {
+ *status |= USB_SS_PORT_LS_U3;
return;
+ }
/* When the CAS bit is set then warm reset
* should be performed on port
@@ -1045,10 +1048,10 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
spin_lock_irqsave(&xhci->lock, flags);
if (hcd->self.root_hub->do_remote_wakeup) {
- if (bus_state->resuming_ports) {
+ if (bus_state->resuming_ports || /* USB2 */
+ bus_state->port_remote_wakeup) { /* USB3 */
spin_unlock_irqrestore(&xhci->lock, flags);
- xhci_dbg(xhci, "suspend failed because "
- "a port is resuming\n");
+ xhci_dbg(xhci, "suspend failed because a port is resuming\n");
return -EBUSY;
}
}
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 677f032482f7..31bed5f7d0eb 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1400,10 +1400,10 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
/* Attempt to use the ring cache */
if (virt_dev->num_rings_cached == 0)
return -ENOMEM;
+ virt_dev->num_rings_cached--;
virt_dev->eps[ep_index].new_ring =
virt_dev->ring_cache[virt_dev->num_rings_cached];
virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL;
- virt_dev->num_rings_cached--;
xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring,
1, type);
}
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 30533952b4a3..95fe1a432d29 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1669,6 +1669,9 @@ static void handle_port_status(struct xhci_hcd *xhci,
usb_hcd_resume_root_hub(hcd);
}
+ if (hcd->speed == HCD_USB3 && (temp & PORT_PLS_MASK) == XDEV_INACTIVE)
+ bus_state->port_remote_wakeup &= ~(1 << faked_port_index);
+
if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_RESUME) {
xhci_dbg(xhci, "port resume event for port %d\n", port_id);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 10223f2b18d2..1f901fc25590 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3356,6 +3356,9 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
return -EINVAL;
}
+ if (virt_dev->tt_info)
+ old_active_eps = virt_dev->tt_info->active_eps;
+
if (virt_dev->udev != udev) {
/* If the virt_dev and the udev does not match, this virt_dev
* may belong to another udev.
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index ed8de724b285..deb2537ae75c 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -280,6 +280,7 @@ struct xhci_op_regs {
#define XDEV_U0 (0x0 << 5)
#define XDEV_U2 (0x2 << 5)
#define XDEV_U3 (0x3 << 5)
+#define XDEV_INACTIVE (0x6 << 5)
#define XDEV_RESUME (0xf << 5)
/* true: port has power (see HCC_PPC) */
#define PORT_POWER (1 << 9)
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index ab1c5e8ac27f..dd84416a23cd 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -187,6 +187,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */
{ USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */
{ USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */
+ { USB_DEVICE(0x2626, 0xEA60) }, /* Aruba Networks 7xxx USB Serial Console */
{ USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
{ USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
{ USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 8b3484134ab0..096438e4fb0c 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1755,6 +1755,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) },
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
+ { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */
{ USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) },
{ USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) },
{ } /* Terminating entry */
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 821e1e2f70f6..da380a99c6b8 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -2032,6 +2032,18 @@ UNUSUAL_DEV( 0x1908, 0x3335, 0x0200, 0x0200,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_NO_READ_DISC_INFO ),
+/* Reported by Oliver Neukum <oneukum@suse.com>
+ * This device morphes spontaneously into another device if the access
+ * pattern of Windows isn't followed. Thus writable media would be dirty
+ * if the initial instance is used. So the device is limited to its
+ * virtual CD.
+ * And yes, the concept that BCD goes up to 9 is not heeded */
+UNUSUAL_DEV( 0x19d2, 0x1225, 0x0000, 0xffff,
+ "ZTE,Incorporated",
+ "ZTE WCDMA Technologies MSM",
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+ US_FL_SINGLE_LUN ),
+
/* Reported by Sven Geggus <sven-usbst@geggus.net>
* This encrypted pen drive returns bogus data for the initial READ(10).
*/
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 60aa5ad09a2f..3aabc652f1b9 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -855,6 +855,7 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp)
}
if (eventfp != d->log_file) {
filep = d->log_file;
+ d->log_file = eventfp;
ctx = d->log_ctx;
d->log_ctx = eventfp ?
eventfd_ctx_fileget(eventfp) : NULL;
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index af88ffd1068f..2b7e073f5e36 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -134,6 +134,13 @@ static int omap_wdt_start(struct watchdog_device *wdog)
pm_runtime_get_sync(wdev->dev);
+ /*
+ * Make sure the watchdog is disabled. This is unfortunately required
+ * because writing to various registers with the watchdog running has no
+ * effect.
+ */
+ omap_wdt_disable(wdev);
+
/* initialize prescaler */
while (__raw_readl(base + OMAP_WATCHDOG_WPS) & 0x01)
cpu_relax();