Merge tag 'v3.2.95' into v3.2-rt
This is the 3.2.95 stable release
Conflicts:
mm/page_alloc.c
diff --git a/Makefile b/Makefile
index f86a857..d31fe7b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 3
PATCHLEVEL = 2
-SUBLEVEL = 94
+SUBLEVEL = 95
EXTRAVERSION =
NAME = Saber-toothed Squirrel
diff --git a/arch/alpha/include/asm/types.h b/arch/alpha/include/asm/types.h
index 8815443..5993b2a 100644
--- a/arch/alpha/include/asm/types.h
+++ b/arch/alpha/include/asm/types.h
@@ -9,10 +9,18 @@
* need to be careful to avoid a name clashes.
*/
-#ifdef __KERNEL__
-#include <asm-generic/int-ll64.h>
-#else
+/*
+ * This is here because we used to use l64 for alpha
+ * and we don't want to impact user mode with our change to ll64
+ * in the kernel.
+ *
+ * However, some user programs are fine with this. They can
+ * flag __SANE_USERSPACE_TYPES__ to get int-ll64.h here.
+ */
+#if !defined(__SANE_USERSPACE_TYPES__) && !defined(__KERNEL__)
#include <asm-generic/int-l64.h>
+#else
+#include <asm-generic/int-ll64.h>
#endif
#ifndef __ASSEMBLY__
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
index 8085417..0697db6 100644
--- a/arch/arm/kernel/return_address.c
+++ b/arch/arm/kernel/return_address.c
@@ -58,10 +58,6 @@
#else /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */
-#if defined(CONFIG_ARM_UNWIND)
-#warning "TODO: return_address should use unwind tables"
-#endif
-
void *return_address(unsigned int level)
{
return NULL;
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 61d3c72..c4100aa 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -563,6 +563,7 @@
bool "PXA based Toshiba e-series PDAs"
select PXA25x
select FB_W100
+ select FB
config MACH_E330
bool "Toshiba e330"
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 479d03c..6532d91 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -952,6 +952,14 @@
struct mpc_intsrc mp_irq;
/*
+ * Check bus_irq boundary.
+ */
+ if (bus_irq >= NR_IRQS_LEGACY) {
+ pr_warn("Invalid bus_irq %u for legacy override\n", bus_irq);
+ return;
+ }
+
+ /*
* Convert 'gsi' to 'ioapic.pin'.
*/
ioapic = mp_find_ioapic(gsi);
diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
index 2783fda..2d9cc6d 100644
--- a/arch/xtensa/kernel/pci-dma.c
+++ b/arch/xtensa/kernel/pci-dma.c
@@ -21,6 +21,7 @@
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/gfp.h>
+#include <linux/module.h>
#include <asm/io.h>
#include <asm/cacheflush.h>
@@ -62,6 +63,7 @@
return (void*)uncached;
}
+EXPORT_SYMBOL(dma_alloc_coherent);
void dma_free_coherent(struct device *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle)
@@ -73,6 +75,7 @@
free_pages(addr, get_order(size));
}
+EXPORT_SYMBOL(dma_free_coherent);
void consistent_sync(void *vaddr, size_t size, int direction)
@@ -92,3 +95,4 @@
break;
}
}
+EXPORT_SYMBOL(consistent_sync);
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
index c9a7c5b..20425ef 100644
--- a/arch/xtensa/kernel/xtensa_ksyms.c
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -39,8 +39,12 @@
EXPORT_SYMBOL(memset);
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(__strncpy_user);
+EXPORT_SYMBOL(clear_page);
+EXPORT_SYMBOL(copy_page);
EXPORT_SYMBOL(kernel_thread);
+EXPORT_SYMBOL(empty_zero_page);
/*
* gcc internal math functions
@@ -69,12 +73,11 @@
EXPORT_SYMBOL(__udivdi3);
EXPORT_SYMBOL(__umoddi3);
-#ifdef CONFIG_NET
/*
* Networking support
*/
+EXPORT_SYMBOL(csum_partial);
EXPORT_SYMBOL(csum_partial_copy_generic);
-#endif /* CONFIG_NET */
/*
* Architecture-specific symbols
diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c
index 85df465..1b62461 100644
--- a/arch/xtensa/mm/cache.c
+++ b/arch/xtensa/mm/cache.c
@@ -59,7 +59,7 @@
*
*/
-#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+#if (DCACHE_WAY_SIZE > PAGE_SIZE)
/*
* Any time the kernel writes to a user page cache page, or it is about to
@@ -112,7 +112,7 @@
/* There shouldn't be an entry in the cache for this page anymore. */
}
-
+EXPORT_SYMBOL(flush_dcache_page);
/*
* For now, flush the whole cache. FIXME??
@@ -124,6 +124,7 @@
__flush_invalidate_dcache_all();
__invalidate_icache_all();
}
+EXPORT_SYMBOL(local_flush_cache_range);
/*
* Remove any entry in the cache for this page.
@@ -143,8 +144,9 @@
__flush_invalidate_dcache_page_alias(virt, phys);
__invalidate_icache_page_alias(virt, phys);
}
+EXPORT_SYMBOL(local_flush_cache_page);
-#endif
+#endif /* DCACHE_WAY_SIZE > PAGE_SIZE */
void
update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep)
@@ -162,7 +164,7 @@
invalidate_itlb_mapping(addr);
invalidate_dtlb_mapping(addr);
-#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+#if (DCACHE_WAY_SIZE > PAGE_SIZE)
if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) {
@@ -193,7 +195,7 @@
* flush_dcache_page() on the page.
*/
-#if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK
+#if (DCACHE_WAY_SIZE > PAGE_SIZE)
void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
unsigned long vaddr, void *dst, const void *src,
diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c
index ac7b854..9d1a5da 100644
--- a/drivers/acpi/acpica/nsrepair.c
+++ b/drivers/acpi/acpica/nsrepair.c
@@ -121,7 +121,7 @@
union acpi_operand_object **return_object_ptr)
{
union acpi_operand_object *return_object = *return_object_ptr;
- union acpi_operand_object *new_object;
+ union acpi_operand_object *new_object = NULL;
acpi_status status;
ACPI_FUNCTION_NAME(ns_repair_object);
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 01a019e..c6f7fa4 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2755,10 +2755,12 @@
static struct ata_device *ata_find_dev(struct ata_port *ap, int devno)
{
if (!sata_pmp_attached(ap)) {
- if (likely(devno < ata_link_max_devices(&ap->link)))
+ if (likely(devno >= 0 &&
+ devno < ata_link_max_devices(&ap->link)))
return &ap->link.device[devno];
} else {
- if (likely(devno < ap->nr_pmp_links))
+ if (likely(devno >= 0 &&
+ devno < ap->nr_pmp_links))
return &ap->pmp_link[devno].device[0];
}
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index e086fbb..8db9089 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -1177,7 +1177,8 @@
int TimeoutCounter;
int i;
-
+ memset(&CommandMailbox, 0, sizeof(DAC960_V1_CommandMailbox_T));
+
if (pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(32)))
return DAC960_Failure(Controller, "DMA mask out of range");
Controller->BounceBufferLimit = DMA_BIT_MASK(32);
@@ -4627,7 +4628,8 @@
DAC960_Controller_T *Controller = Command->Controller;
DAC960_CommandType_T CommandType = Command->CommandType;
DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
- DAC960_V2_IOCTL_Opcode_T CommandOpcode = CommandMailbox->Common.IOCTL_Opcode;
+ DAC960_V2_IOCTL_Opcode_T IOCTLOpcode = CommandMailbox->Common.IOCTL_Opcode;
+ DAC960_V2_CommandOpcode_T CommandOpcode = CommandMailbox->SCSI_10.CommandOpcode;
DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus;
if (CommandType == DAC960_ReadCommand ||
@@ -4699,7 +4701,7 @@
{
if (Controller->ShutdownMonitoringTimer)
return;
- if (CommandOpcode == DAC960_V2_GetControllerInfo)
+ if (IOCTLOpcode == DAC960_V2_GetControllerInfo)
{
DAC960_V2_ControllerInfo_T *NewControllerInfo =
Controller->V2.NewControllerInformation;
@@ -4719,14 +4721,14 @@
memcpy(ControllerInfo, NewControllerInfo,
sizeof(DAC960_V2_ControllerInfo_T));
}
- else if (CommandOpcode == DAC960_V2_GetEvent)
+ else if (IOCTLOpcode == DAC960_V2_GetEvent)
{
if (CommandStatus == DAC960_V2_NormalCompletion) {
DAC960_V2_ReportEvent(Controller, Controller->V2.Event);
}
Controller->V2.NextEventSequenceNumber++;
}
- else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid &&
+ else if (IOCTLOpcode == DAC960_V2_GetPhysicalDeviceInfoValid &&
CommandStatus == DAC960_V2_NormalCompletion)
{
DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
@@ -4915,7 +4917,7 @@
NewPhysicalDeviceInfo->LogicalUnit++;
Controller->V2.PhysicalDeviceIndex++;
}
- else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid)
+ else if (IOCTLOpcode == DAC960_V2_GetPhysicalDeviceInfoValid)
{
unsigned int DeviceIndex;
for (DeviceIndex = Controller->V2.PhysicalDeviceIndex;
@@ -4938,7 +4940,7 @@
}
Controller->V2.NeedPhysicalDeviceInformation = false;
}
- else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid &&
+ else if (IOCTLOpcode == DAC960_V2_GetLogicalDeviceInfoValid &&
CommandStatus == DAC960_V2_NormalCompletion)
{
DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
@@ -5065,7 +5067,7 @@
[LogicalDeviceNumber] = true;
NewLogicalDeviceInfo->LogicalDeviceNumber++;
}
- else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid)
+ else if (IOCTLOpcode == DAC960_V2_GetLogicalDeviceInfoValid)
{
int LogicalDriveNumber;
for (LogicalDriveNumber = 0;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 0358e55..a6ad652 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -4183,12 +4183,11 @@
static char buildtag[38] = "\0uilt-in";
if (buildtag[0] == 0) {
-#ifdef CONFIG_MODULES
- if (THIS_MODULE != NULL)
- sprintf(buildtag, "srcversion: %-24s", THIS_MODULE->srcversion);
- else
+#ifdef MODULE
+ sprintf(buildtag, "srcversion: %-24s", THIS_MODULE->srcversion);
+#else
+ buildtag[0] = 'b';
#endif
- buildtag[0] = 'b';
}
return buildtag;
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c
index 1e08426..9afb598 100644
--- a/drivers/edac/i7300_edac.c
+++ b/drivers/edac/i7300_edac.c
@@ -803,6 +803,7 @@
}
/* Get the set of MTR[0-7] regs by each branch */
+ nr_pages = 0;
for (slot = 0; slot < MAX_SLOTS; slot++) {
int where = mtr_regs[slot];
for (branch = 0; branch < MAX_BRANCHES; branch++) {
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 61044c8..9c84ad5 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -230,7 +230,7 @@
struct tegra_gpio_bank *bank;
int port;
int pin;
- int unmasked = 0;
+ bool unmasked = false;
struct irq_chip *chip = irq_desc_get_chip(desc);
chained_irq_enter(chip, desc);
@@ -250,8 +250,8 @@
* before executing the hander so that we don't
* miss edges
*/
- if (lvl & (0x100 << pin)) {
- unmasked = 1;
+ if (!unmasked && lvl & (0x100 << pin)) {
+ unmasked = true;
chained_irq_exit(chip, desc);
}
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index e216c21..ba62ada 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -971,13 +971,6 @@
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL and additional rights");
-/* We give fast paths for the really cool registers */
-#define NEEDS_FORCE_WAKE(dev_priv, reg) \
- ((HAS_FORCE_WAKE((dev_priv)->dev)) && \
- ((reg) < 0x40000) && \
- ((reg) != FORCEWAKE) && \
- ((reg) != ECOBUS))
-
#define __i915_read(x, y) \
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
u##x val = 0; \
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 61274bf..783153a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1369,10 +1369,9 @@
/* We give fast paths for the really cool registers */
#define NEEDS_FORCE_WAKE(dev_priv, reg) \
- (((dev_priv)->info->gen >= 6) && \
+ ((HAS_FORCE_WAKE((dev_priv)->dev)) && \
((reg) < 0x40000) && \
- ((reg) != FORCEWAKE) && \
- ((reg) != ECOBUS))
+ ((reg) != FORCEWAKE))
#define __i915_read(x, y) \
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c7b5428..4a7d597 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8699,9 +8699,15 @@
if (IS_IVYBRIDGE(dev)) {
u32 ecobus;
+ /* A small trick here - if the bios hasn't configured MT forcewake,
+ * and if the device is in RC6, then force_wake_mt_get will not wake
+ * the device and the ECOBUS read will return zero. Which will be
+ * (correctly) interpreted by the test below as MT forcewake being
+ * disabled.
+ */
mutex_lock(&dev->struct_mutex);
__gen6_gt_force_wake_mt_get(dev_priv);
- ecobus = I915_READ(ECOBUS);
+ ecobus = I915_READ_NOTRACE(ECOBUS);
__gen6_gt_force_wake_mt_put(dev_priv);
mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 831e20dd..e873c0b 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -912,6 +912,8 @@
unsigned int rsize = 0;
char *rdesc;
int ret, n;
+ int num_descriptors;
+ size_t offset = offsetof(struct hid_descriptor, desc);
quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
@@ -934,10 +936,18 @@
return -ENODEV;
}
+ if (hdesc->bLength < sizeof(struct hid_descriptor)) {
+ dbg_hid("hid descriptor is too short\n");
+ return -EINVAL;
+ }
+
hid->version = le16_to_cpu(hdesc->bcdHID);
hid->country = hdesc->bCountryCode;
- for (n = 0; n < hdesc->bNumDescriptors; n++)
+ num_descriptors = min_t(int, hdesc->bNumDescriptors,
+ (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor));
+
+ for (n = 0; n < num_descriptors; n++)
if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index 65b685e..56a69c1 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -826,6 +826,7 @@
struct i2c_adapter *adapter = new_client->adapter;
struct w83781d_data *data = i2c_get_clientdata(new_client);
enum chips kind = data->type;
+ int num_sc = 1;
id = i2c_adapter_id(adapter);
@@ -850,6 +851,7 @@
}
if (kind != w83783s) {
+ num_sc = 2;
if (force_subclients[0] == id &&
force_subclients[1] == address) {
sc_addr[1] = force_subclients[3];
@@ -865,7 +867,7 @@
}
}
- for (i = 0; i <= 1; i++) {
+ for (i = 0; i < num_sc; i++) {
data->lm75[i] = i2c_new_dummy(adapter, sc_addr[i]);
if (!data->lm75[i]) {
dev_err(&new_client->dev, "Subclient %d "
@@ -876,8 +878,6 @@
goto ERROR_SC_3;
goto ERROR_SC_2;
}
- if (kind == w83783s)
- break;
}
return 0;
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 44fde43..2a81c88 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -229,7 +229,7 @@
.enter = &intel_idle },
};
-static int get_driver_data(int cstate)
+static long get_driver_data(int cstate)
{
int driver_data;
switch (cstate) {
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 09cc0fc..87c1e05 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -661,6 +661,8 @@
} else
ret = iw_cm_init_qp_attr(id_priv->cm_id.iw, qp_attr,
qp_attr_mask);
+ qp_attr->port_num = id_priv->id.port_num;
+ *qp_attr_mask |= IB_QP_PORT;
break;
default:
ret = -ENOSYS;
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index a5a7f47..29c01fc 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -1192,7 +1192,7 @@
int out_len)
{
struct ib_uverbs_resize_cq cmd;
- struct ib_uverbs_resize_cq_resp resp;
+ struct ib_uverbs_resize_cq_resp resp = {};
struct ib_udata udata;
struct ib_cq *cq;
int ret = -EINVAL;
@@ -1790,7 +1790,8 @@
goto out;
}
- if (!rdma_is_port_valid(qp->device, cmd.port_num)) {
+ if ((cmd.attr_mask & IB_QP_PORT) &&
+ !rdma_is_port_valid(qp->device, cmd.port_num)) {
ret = -EINVAL;
goto release_qp;
}
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index 1661650..a17f0fa 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -290,6 +290,7 @@
if (atomic_dec_and_test(&file->device->refcount))
ib_uverbs_comp_dev(file->device);
+ kobject_put(&file->device->kobj);
kfree(file);
}
@@ -671,7 +672,6 @@
static int ib_uverbs_close(struct inode *inode, struct file *filp)
{
struct ib_uverbs_file *file = filp->private_data;
- struct ib_uverbs_device *dev = file->device;
ib_uverbs_cleanup_ucontext(file, file->ucontext);
@@ -679,7 +679,6 @@
kref_put(&file->async_file->ref, ib_uverbs_release_event_file);
kref_put(&file->ref, ib_uverbs_release_file);
- kobject_put(&dev->kobj);
return 0;
}
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index 37c224f..35fa4e7 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -795,7 +795,7 @@
struct iwch_mr *mhp;
u32 mmid;
u32 stag = 0;
- int ret = 0;
+ int ret = -ENOMEM;
php = to_iwch_pd(pd);
rhp = php->rhp;
@@ -818,7 +818,8 @@
mhp->attr.state = 1;
mmid = (stag) >> 8;
mhp->ibmr.rkey = mhp->ibmr.lkey = stag;
- if (insert_handle(rhp, &rhp->mmidr, mhp, mmid))
+ ret = insert_handle(rhp, &rhp->mmidr, mhp, mmid);
+ if (ret)
goto err3;
PDBG("%s mmid 0x%x mhp %p stag 0x%x\n", __func__, mmid, mhp, stag);
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c
index 3bd6b69..3e5f576 100644
--- a/drivers/infiniband/hw/cxgb4/cq.c
+++ b/drivers/infiniband/hw/cxgb4/cq.c
@@ -826,6 +826,7 @@
goto err2;
if (ucontext) {
+ ret = -ENOMEM;
mm = kmalloc(sizeof *mm, GFP_KERNEL);
if (!mm)
goto err3;
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 1165949..df1a2de 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -1363,7 +1363,7 @@
int is_eth;
int is_vlan = 0;
int is_grh;
- u16 vlan;
+ u16 vlan = 0xffff;
send_size = 0;
for (i = 0; i < wr->num_sge; ++i)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 74aa131..80c9a29 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -506,7 +506,6 @@
case IB_CM_REQ_RECEIVED:
return ipoib_cm_req_handler(cm_id, event);
case IB_CM_DREQ_RECEIVED:
- p = cm_id->context;
ib_send_cm_drep(cm_id, NULL, 0);
/* Fall through */
case IB_CM_REJ_RECEIVED:
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index ae3b1d2..c3d96e8 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -1366,6 +1366,7 @@
ipoib_sendq_size = max3(ipoib_sendq_size, 2 * MAX_SEND_CQE, IPOIB_MIN_QUEUE_SIZE);
#ifdef CONFIG_INFINIBAND_IPOIB_CM
ipoib_max_conn_qp = min(ipoib_max_conn_qp, IPOIB_CM_MAX_CONN_QP);
+ ipoib_max_conn_qp = max(ipoib_max_conn_qp, 0);
#endif
/*
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index 54b2fa8..7836450 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -186,7 +186,8 @@
if (ps2_command(&psmouse->ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID)))
return -1;
- if (param[0] != TP_MAGIC_IDENT)
+ /* add new TP ID. */
+ if (!(param[0] & TP_MAGIC_IDENT))
return -1;
if (firmware_id)
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h
index e558a70..bdee131 100644
--- a/drivers/input/mouse/trackpoint.h
+++ b/drivers/input/mouse/trackpoint.h
@@ -21,8 +21,9 @@
#define TP_COMMAND 0xE2 /* Commands start with this */
#define TP_READ_ID 0xE1 /* Sent for device identification */
-#define TP_MAGIC_IDENT 0x01 /* Sent after a TP_READ_ID followed */
+#define TP_MAGIC_IDENT 0x03 /* Sent after a TP_READ_ID followed */
/* by the firmware ID */
+ /* Firmware ID includes 0x1, 0x2, 0x3 */
/*
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index 08c2329..ba45c77 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -306,6 +306,7 @@
* format CAPI IE as string
*/
+#ifdef CONFIG_GIGASET_DEBUG
static const char *format_ie(const char *ie)
{
static char result[3*MAX_FMT_IE_LEN];
@@ -331,6 +332,7 @@
*--pout = 0;
return result;
}
+#endif
/*
* emit DATA_B3_CONF message
diff --git a/drivers/isdn/hardware/eicon/capi20.h b/drivers/isdn/hardware/eicon/capi20.h
index 7ebcccd..27ecd61 100644
--- a/drivers/isdn/hardware/eicon/capi20.h
+++ b/drivers/isdn/hardware/eicon/capi20.h
@@ -117,7 +117,7 @@
/*------------------------------------------------------------------*/
/* ALERT-REQUEST */
typedef struct {
- byte structs[1]; /* Additional Info */
+ byte structs[0]; /* Additional Info */
} _ALT_REQP;
/* ALERT-CONFIRM */
typedef struct {
@@ -126,7 +126,7 @@
/* CONNECT-REQUEST */
typedef struct {
word CIP_Value;
- byte structs[1]; /* Called party number,
+ byte structs[0]; /* Called party number,
Called party subaddress,
Calling party number,
Calling party subaddress,
@@ -143,7 +143,7 @@
/* CONNECT-INDICATION */
typedef struct {
word CIP_Value;
- byte structs[1]; /* Called party number,
+ byte structs[0]; /* Called party number,
Called party subaddress,
Calling party number,
Calling party subaddress,
@@ -155,24 +155,24 @@
/* CONNECT-RESPONSE */
typedef struct {
word Accept;
- byte structs[1]; /* B_protocol,
+ byte structs[0]; /* B_protocol,
Connected party number,
Connected party subaddress,
LLC */
} _CON_RESP;
/* CONNECT-ACTIVE-INDICATION */
typedef struct {
- byte structs[1]; /* Connected party number,
+ byte structs[0]; /* Connected party number,
Connected party subaddress,
LLC */
} _CON_A_INDP;
/* CONNECT-ACTIVE-RESPONSE */
typedef struct {
- byte structs[1]; /* empty */
+ byte structs[0]; /* empty */
} _CON_A_RESP;
/* DISCONNECT-REQUEST */
typedef struct {
- byte structs[1]; /* Additional Info */
+ byte structs[0]; /* Additional Info */
} _DIS_REQP;
/* DISCONNECT-CONFIRM */
typedef struct {
@@ -184,13 +184,13 @@
} _DIS_INDP;
/* DISCONNECT-RESPONSE */
typedef struct {
- byte structs[1]; /* empty */
+ byte structs[0]; /* empty */
} _DIS_RESP;
/* LISTEN-REQUEST */
typedef struct {
dword Info_Mask;
dword CIP_Mask;
- byte structs[1]; /* Calling party number,
+ byte structs[0]; /* Calling party number,
Calling party subaddress */
} _LIS_REQP;
/* LISTEN-CONFIRM */
@@ -199,7 +199,7 @@
} _LIS_CONP;
/* INFO-REQUEST */
typedef struct {
- byte structs[1]; /* Called party number,
+ byte structs[0]; /* Called party number,
Additional Info */
} _INF_REQP;
/* INFO-CONFIRM */
@@ -209,15 +209,15 @@
/* INFO-INDICATION */
typedef struct {
word Number;
- byte structs[1]; /* Info element */
+ byte structs[0]; /* Info element */
} _INF_INDP;
/* INFO-RESPONSE */
typedef struct {
- byte structs[1]; /* empty */
+ byte structs[0]; /* empty */
} _INF_RESP;
/* SELECT-B-REQUEST */
typedef struct {
- byte structs[1]; /* B-protocol */
+ byte structs[0]; /* B-protocol */
} _SEL_B_REQP;
/* SELECT-B-CONFIRM */
typedef struct {
@@ -226,7 +226,7 @@
/* FACILITY-REQUEST */
typedef struct {
word Selector;
- byte structs[1]; /* Facility parameters */
+ byte structs[0]; /* Facility parameters */
} _FAC_REQP;
/* FACILITY-CONFIRM STRUCT FOR SUPPLEMENT. SERVICES */
typedef struct {
@@ -240,21 +240,21 @@
typedef struct {
word Info;
word Selector;
- byte structs[1]; /* Facility parameters */
+ byte structs[0]; /* Facility parameters */
} _FAC_CONP;
/* FACILITY-INDICATION */
typedef struct {
word Selector;
- byte structs[1]; /* Facility parameters */
+ byte structs[0]; /* Facility parameters */
} _FAC_INDP;
/* FACILITY-RESPONSE */
typedef struct {
word Selector;
- byte structs[1]; /* Facility parameters */
+ byte structs[0]; /* Facility parameters */
} _FAC_RESP;
/* CONNECT-B3-REQUEST */
typedef struct {
- byte structs[1]; /* NCPI */
+ byte structs[0]; /* NCPI */
} _CON_B3_REQP;
/* CONNECT-B3-CONFIRM */
typedef struct {
@@ -262,24 +262,24 @@
} _CON_B3_CONP;
/* CONNECT-B3-INDICATION */
typedef struct {
- byte structs[1]; /* NCPI */
+ byte structs[0]; /* NCPI */
} _CON_B3_INDP;
/* CONNECT-B3-RESPONSE */
typedef struct {
word Accept;
- byte structs[1]; /* NCPI */
+ byte structs[0]; /* NCPI */
} _CON_B3_RESP;
/* CONNECT-B3-ACTIVE-INDICATION */
typedef struct {
- byte structs[1]; /* NCPI */
+ byte structs[0]; /* NCPI */
} _CON_B3_A_INDP;
/* CONNECT-B3-ACTIVE-RESPONSE */
typedef struct {
- byte structs[1]; /* empty */
+ byte structs[0]; /* empty */
} _CON_B3_A_RESP;
/* DISCONNECT-B3-REQUEST */
typedef struct {
- byte structs[1]; /* NCPI */
+ byte structs[0]; /* NCPI */
} _DIS_B3_REQP;
/* DISCONNECT-B3-CONFIRM */
typedef struct {
@@ -288,11 +288,11 @@
/* DISCONNECT-B3-INDICATION */
typedef struct {
word Info;
- byte structs[1]; /* NCPI */
+ byte structs[0]; /* NCPI */
} _DIS_B3_INDP;
/* DISCONNECT-B3-RESPONSE */
typedef struct {
- byte structs[1]; /* empty */
+ byte structs[0]; /* empty */
} _DIS_B3_RESP;
/* DATA-B3-REQUEST */
typedef struct {
@@ -335,7 +335,7 @@
} _DAT_B3_RESP;
/* RESET-B3-REQUEST */
typedef struct {
- byte structs[1]; /* NCPI */
+ byte structs[0]; /* NCPI */
} _RES_B3_REQP;
/* RESET-B3-CONFIRM */
typedef struct {
@@ -343,20 +343,20 @@
} _RES_B3_CONP;
/* RESET-B3-INDICATION */
typedef struct {
- byte structs[1]; /* NCPI */
+ byte structs[0]; /* NCPI */
} _RES_B3_INDP;
/* RESET-B3-RESPONSE */
typedef struct {
- byte structs[1]; /* empty */
+ byte structs[0]; /* empty */
} _RES_B3_RESP;
/* CONNECT-B3-T90-ACTIVE-INDICATION */
typedef struct {
- byte structs[1]; /* NCPI */
+ byte structs[0]; /* NCPI */
} _CON_B3_T90_A_INDP;
/* CONNECT-B3-T90-ACTIVE-RESPONSE */
typedef struct {
word Reject;
- byte structs[1]; /* NCPI */
+ byte structs[0]; /* NCPI */
} _CON_B3_T90_A_RESP;
/*------------------------------------------------------------------*/
/* message structure */
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index 3261de1..d5db9ace 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -2316,8 +2316,8 @@
static void
hfcpci_softirq(void *arg)
{
- (void) driver_for_each_device(&hfc_driver.driver, NULL, arg,
- _hfcpci_softirq);
+ WARN_ON_ONCE(driver_for_each_device(&hfc_driver.driver, NULL, arg,
+ _hfcpci_softirq) != 0);
/* if next event would be in the past ... */
if ((s32)(hfc_jiffies + tics - jiffies) <= 0)
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 7a5c0a2..8d35ef4 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -25,16 +25,6 @@
#define DM_MSG_PREFIX "core"
-#ifdef CONFIG_PRINTK
-/*
- * ratelimit state to be used in DMXXX_LIMIT().
- */
-DEFINE_RATELIMIT_STATE(dm_ratelimit_state,
- DEFAULT_RATELIMIT_INTERVAL,
- DEFAULT_RATELIMIT_BURST);
-EXPORT_SYMBOL(dm_ratelimit_state);
-#endif
-
/*
* Cookies are numeric values sent with CHANGE and REMOVE
* uevents while resuming, removing or renaming the device.
diff --git a/drivers/media/common/tuners/tda18212.c b/drivers/media/common/tuners/tda18212.c
index e29cc2bc1..27c1861 100644
--- a/drivers/media/common/tuners/tda18212.c
+++ b/drivers/media/common/tuners/tda18212.c
@@ -241,7 +241,7 @@
{
struct tda18212_priv *priv = NULL;
int ret;
- u8 val;
+ u8 uninitialized_var(val);
priv = kzalloc(sizeof(struct tda18212_priv), GFP_KERNEL);
if (priv == NULL)
diff --git a/drivers/media/common/tuners/tda18218.c b/drivers/media/common/tuners/tda18218.c
index 4fc2973..361a31f 100644
--- a/drivers/media/common/tuners/tda18218.c
+++ b/drivers/media/common/tuners/tda18218.c
@@ -274,7 +274,7 @@
struct i2c_adapter *i2c, struct tda18218_config *cfg)
{
struct tda18218_priv *priv = NULL;
- u8 val;
+ u8 uninitialized_var(val);
int ret;
/* chip default registers values */
static u8 def_regs[] = {
diff --git a/drivers/media/common/tuners/xc4000.c b/drivers/media/common/tuners/xc4000.c
index 634f4d9..3b9fdba 100644
--- a/drivers/media/common/tuners/xc4000.c
+++ b/drivers/media/common/tuners/xc4000.c
@@ -923,7 +923,7 @@
int rc = 0, is_retry = 0;
u16 hwmodel;
v4l2_std_id std0;
- u8 hw_major, hw_minor, fw_major, fw_minor;
+ u8 hw_major = 0, hw_minor = 0, fw_major = 0, fw_minor = 0;
dprintk(1, "%s called\n", __func__);
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.c b/drivers/media/dvb/dvb-usb/mxl111sf.c
index bc6ea9f..738f7b0 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf.c
+++ b/drivers/media/dvb/dvb-usb/mxl111sf.c
@@ -340,7 +340,6 @@
struct mxl111sf_state *state = d->priv;
struct mxl111sf_adap_state *adap_state = adap->fe_adap[adap->active_fe].priv;
int ret = 0;
- u8 tmp;
deb_info("%s(%d)\n", __func__, onoff);
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index 61287fc..9bff23c 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -286,12 +286,6 @@
rr3_ftr(rr3->dev, "Entering %s\n", __func__);
- if (!rr3->det_enabled) {
- dev_warn(rr3->dev, "not issuing async read, "
- "detector not enabled\n");
- return;
- }
-
memset(rr3->bulk_in_buf, 0, rr3->ep_in->wMaxPacketSize);
res = usb_submit_urb(rr3->read_urb, GFP_ATOMIC);
if (res)
@@ -827,6 +821,7 @@
static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs)
{
struct redrat3_dev *rr3;
+ int ret;
if (!urb)
return;
@@ -840,15 +835,13 @@
rr3_ftr(rr3->dev, "Entering %s\n", __func__);
- if (!rr3->det_enabled) {
- rr3_dbg(rr3->dev, "received a read callback but detector "
- "disabled - ignoring\n");
- return;
- }
-
switch (urb->status) {
case 0:
- redrat3_get_ir_data(rr3, urb->actual_length);
+ ret = redrat3_get_ir_data(rr3, urb->actual_length);
+ if (!ret) {
+ /* no error, prepare to read more */
+ redrat3_issue_async(rr3);
+ }
break;
case -ECONNRESET:
@@ -865,11 +858,6 @@
rr3->pkttype = 0;
break;
}
-
- if (!rr3->transmitting)
- redrat3_issue_async(rr3);
- else
- rr3_dbg(rr3->dev, "IR transmit in progress\n");
}
static void redrat3_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
@@ -896,21 +884,24 @@
return (u16)(65536 - (mult / mod_freq));
}
-static int redrat3_set_tx_carrier(struct rc_dev *dev, u32 carrier)
+static int redrat3_set_tx_carrier(struct rc_dev *rcdev, u32 carrier)
{
- struct redrat3_dev *rr3 = dev->priv;
+ struct redrat3_dev *rr3 = rcdev->priv;
+ struct device *dev = rr3->dev;
+ rr3_dbg(dev, "Setting modulation frequency to %u", carrier);
rr3->carrier = carrier;
return carrier;
}
-static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n)
+static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf,
+ unsigned count)
{
struct redrat3_dev *rr3 = rcdev->priv;
struct device *dev = rr3->dev;
struct redrat3_signal_header header;
- int i, j, count, ret, ret_len, offset;
+ int i, j, ret, ret_len, offset;
int lencheck, cur_sample_len, pipe;
char *buffer = NULL, *sigdata = NULL;
int *sample_lens = NULL;
@@ -928,20 +919,13 @@
return -EAGAIN;
}
- count = n / sizeof(int);
if (count > (RR3_DRIVER_MAXLENS * 2))
return -EINVAL;
+ /* rr3 will disable rc detector on transmit */
+ rr3->det_enabled = false;
rr3->transmitting = true;
- redrat3_disable_detector(rr3);
-
- if (rr3->det_enabled) {
- dev_err(dev, "%s: cannot tx while rx is enabled\n", __func__);
- ret = -EIO;
- goto out;
- }
-
sample_lens = kzalloc(sizeof(int) * RR3_DRIVER_MAXLENS, GFP_KERNEL);
if (!sample_lens) {
ret = -ENOMEM;
@@ -1055,7 +1039,7 @@
if (ret < 0)
dev_err(dev, "Error: control msg send failed, rc %d\n", ret);
else
- ret = n;
+ ret = count;
out:
kfree(sample_lens);
@@ -1063,8 +1047,8 @@
kfree(sigdata);
rr3->transmitting = false;
-
- redrat3_enable_detector(rr3);
+ /* rr3 re-enables rc detector because it was enabled before */
+ rr3->det_enabled = true;
return ret;
}
diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c
index cd41d40..cb56e27 100644
--- a/drivers/misc/vmw_balloon.c
+++ b/drivers/misc/vmw_balloon.c
@@ -314,7 +314,7 @@
* fear that guest will need it. Host may reject some pages, we need to
* check the return value and maybe submit a different page.
*/
-static bool vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn,
+static int vmballoon_send_lock_page(struct vmballoon *b, unsigned long pfn,
unsigned int *hv_status)
{
unsigned long status, dummy;
@@ -322,17 +322,17 @@
pfn32 = (u32)pfn;
if (pfn32 != pfn)
- return false;
+ return -1;
STATS_INC(b->stats.lock);
*hv_status = status = VMWARE_BALLOON_CMD(LOCK, pfn, dummy);
if (vmballoon_check_status(b, status))
- return true;
+ return 0;
pr_debug("%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
STATS_INC(b->stats.lock_fail);
- return false;
+ return 1;
}
/*
@@ -411,7 +411,7 @@
struct page *page;
gfp_t flags;
unsigned int hv_status;
- bool locked = false;
+ int locked;
flags = can_sleep ? VMW_PAGE_ALLOC_CANSLEEP : VMW_PAGE_ALLOC_NOSLEEP;
do {
@@ -431,7 +431,7 @@
/* inform monitor */
locked = vmballoon_send_lock_page(b, page_to_pfn(page), &hv_status);
- if (!locked) {
+ if (locked > 0) {
STATS_INC(b->stats.refused_alloc);
if (hv_status == VMW_BALLOON_ERROR_RESET ||
@@ -449,7 +449,7 @@
if (++b->n_refused_pages >= VMW_BALLOON_MAX_REFUSED)
return -EIO;
}
- } while (!locked);
+ } while (locked != 0);
/* track allocated page */
list_add(&page->lru, &b->pages);
diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c
index 9c35250..077d88a 100644
--- a/drivers/mtd/devices/sst25l.c
+++ b/drivers/mtd/devices/sst25l.c
@@ -378,7 +378,7 @@
struct flash_info *flash_info;
struct sst25l_flash *flash;
struct flash_platform_data *data;
- int ret, i;
+ int ret;
flash_info = sst25l_match_device(spi);
if (!flash_info)
diff --git a/drivers/net/ethernet/amd/nmclan_cs.c b/drivers/net/ethernet/amd/nmclan_cs.c
index 3accd5d..3279a1a 100644
--- a/drivers/net/ethernet/amd/nmclan_cs.c
+++ b/drivers/net/ethernet/amd/nmclan_cs.c
@@ -625,7 +625,7 @@
ret = pcmcia_request_io(link);
if (ret)
goto failed;
- ret = pcmcia_request_exclusive_irq(link, mace_interrupt);
+ ret = pcmcia_request_irq(link, mace_interrupt);
if (ret)
goto failed;
ret = pcmcia_enable_device(link);
@@ -955,6 +955,8 @@
do {
/* WARNING: MACE_IR is a READ/CLEAR port! */
status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR);
+ if (!(status & ~MACE_IMR_DEFAULT) && IntrCnt == MACE_MAX_IR_ITERATIONS)
+ return IRQ_NONE;
pr_debug("mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index 74e2a2a..26d080a 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -101,27 +101,28 @@
struct ethtool_wolinfo *wol)
{
struct mlx4_en_priv *priv = netdev_priv(netdev);
+ struct mlx4_caps *caps = &priv->mdev->dev->caps;
int err = 0;
u64 config = 0;
- if (!(priv->mdev->dev->caps.flags & MLX4_DEV_CAP_FLAG_WOL)) {
+ if (!(caps->flags & MLX4_DEV_CAP_FLAG_WOL)) {
wol->supported = 0;
wol->wolopts = 0;
return;
}
+ if (caps->wol_port[priv->port])
+ wol->supported = WAKE_MAGIC;
+ else
+ wol->supported = 0;
+
err = mlx4_wol_read(priv->mdev->dev, &config, priv->port);
if (err) {
en_err(priv, "Failed to get WoL information\n");
return;
}
- if (config & MLX4_EN_WOL_MAGIC)
- wol->supported = WAKE_MAGIC;
- else
- wol->supported = 0;
-
- if (config & MLX4_EN_WOL_ENABLED)
+ if ((config & MLX4_EN_WOL_ENABLED) && (config & MLX4_EN_WOL_MAGIC))
wol->wolopts = WAKE_MAGIC;
else
wol->wolopts = 0;
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 435ca6e..8892348 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -189,6 +189,7 @@
#define QUERY_DEV_CAP_RATE_SUPPORT_OFFSET 0x3c
#define QUERY_DEV_CAP_MAX_PKEY_OFFSET 0x3f
#define QUERY_DEV_CAP_EXT_FLAGS_OFFSET 0x40
+#define QUERY_DEV_CAP_WOL_OFFSET 0x43
#define QUERY_DEV_CAP_FLAGS_OFFSET 0x44
#define QUERY_DEV_CAP_RSVD_UAR_OFFSET 0x48
#define QUERY_DEV_CAP_UAR_SZ_OFFSET 0x49
@@ -285,6 +286,9 @@
MLX4_GET(ext_flags, outbox, QUERY_DEV_CAP_EXT_FLAGS_OFFSET);
MLX4_GET(flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET);
dev_cap->flags = flags | (u64)ext_flags << 32;
+ MLX4_GET(field, outbox, QUERY_DEV_CAP_WOL_OFFSET);
+ dev_cap->wol_port[1] = !!(field & 0x20);
+ dev_cap->wol_port[2] = !!(field & 0x40);
MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET);
dev_cap->reserved_uars = field >> 4;
MLX4_GET(field, outbox, QUERY_DEV_CAP_UAR_SZ_OFFSET);
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.h b/drivers/net/ethernet/mellanox/mlx4/fw.h
index bf5ec22..bd6e404 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.h
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.h
@@ -114,6 +114,7 @@
u8 log_max_macs[MLX4_MAX_PORTS + 1];
u8 log_max_vlans[MLX4_MAX_PORTS + 1];
u32 max_counters;
+ bool wol_port[MLX4_MAX_PORTS + 1];
};
struct mlx4_adapter {
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index b02adbc..ca46ea3 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -234,6 +234,8 @@
dev->caps.reserved_lkey = dev_cap->reserved_lkey;
dev->caps.stat_rate_support = dev_cap->stat_rate_support;
dev->caps.max_gso_sz = dev_cap->max_gso_sz;
+ dev->caps.wol_port[1] = dev_cap->wol_port[1];
+ dev->caps.wol_port[2] = dev_cap->wol_port[2];
dev->caps.log_num_macs = log_num_mac;
dev->caps.log_num_vlans = MLX4_LOG_NUM_VLANS;
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
index fca804f..a11195f 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c
@@ -724,7 +724,7 @@
seg_hdr->cookie = MPI_COREDUMP_COOKIE;
seg_hdr->segNum = seg_number;
seg_hdr->segSize = seg_size;
- memcpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
+ strncpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
}
/*
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
index 0c26787..356b7d4 100644
--- a/drivers/net/ethernet/realtek/r8169.c
+++ b/drivers/net/ethernet/realtek/r8169.c
@@ -5371,7 +5371,6 @@
rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb,
tp->TxDescArray + entry);
if (skb) {
- tp->dev->stats.tx_dropped++;
dev_kfree_skb_any(skb);
tx_skb->skb = NULL;
}
diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c
index da269d7..738589f 100644
--- a/drivers/net/ethernet/sfc/mcdi_mac.c
+++ b/drivers/net/ethernet/sfc/mcdi_mac.c
@@ -54,7 +54,7 @@
NULL, 0, NULL);
}
-static int efx_mcdi_get_mac_faults(struct efx_nic *efx, u32 *faults)
+static bool efx_mcdi_mac_check_fault(struct efx_nic *efx)
{
u8 outbuf[MC_CMD_GET_LINK_OUT_LEN];
size_t outlength;
@@ -64,16 +64,13 @@
rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0,
outbuf, sizeof(outbuf), &outlength);
- if (rc)
- goto fail;
+ if (rc) {
+ netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n",
+ __func__, rc);
+ return true;
+ }
- *faults = MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT);
- return 0;
-
-fail:
- netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n",
- __func__, rc);
- return rc;
+ return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0;
}
int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
@@ -132,14 +129,6 @@
}
-static bool efx_mcdi_mac_check_fault(struct efx_nic *efx)
-{
- u32 faults;
- int rc = efx_mcdi_get_mac_faults(efx, &faults);
- return (rc != 0) || (faults != 0);
-}
-
-
const struct efx_mac_operations efx_mcdi_mac_operations = {
.reconfigure = efx_mcdi_mac_reconfigure,
.update_stats = efx_port_dummy_op_void,
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 0021e49..04fec1f 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -2426,7 +2426,7 @@
unsigned int pkt_addr, int rx_len)
{
UCHAR buff[256];
- struct rx_msg *msg = (struct rx_msg *)buff;
+ struct ray_rx_msg *msg = (struct ray_rx_msg *) buff;
del_timer(&local->timer);
@@ -2513,7 +2513,7 @@
unsigned int pkt_addr, int rx_len)
{
/* UCHAR buff[256];
- struct rx_msg *msg = (struct rx_msg *)buff;
+ struct ray_rx_msg *msg = (struct ray_rx_msg *) buff;
*/
pr_debug("Deauthentication frame received\n");
local->authentication_state = UNAUTHENTICATED;
diff --git a/drivers/net/wireless/rayctl.h b/drivers/net/wireless/rayctl.h
index d7646f2..3c3b98b1 100644
--- a/drivers/net/wireless/rayctl.h
+++ b/drivers/net/wireless/rayctl.h
@@ -566,9 +566,9 @@
UCHAR hdr_3;
UCHAR hdr_4;
};
-struct rx_msg {
+struct ray_rx_msg {
struct mac_header mac;
- UCHAR var[1];
+ UCHAR var[0];
};
struct tx_msg {
diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c
index 40c1574..4563891 100644
--- a/drivers/net/wireless/wl1251/main.c
+++ b/drivers/net/wireless/wl1251/main.c
@@ -1428,6 +1428,7 @@
wl->state = WL1251_STATE_OFF;
mutex_init(&wl->mutex);
+ spin_lock_init(&wl->wl_lock);
wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index bcd5d54..d12d272 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -988,7 +988,7 @@
dino_dev->hba.dev = dev;
dino_dev->hba.base_addr = ioremap_nocache(hpa, 4096);
- dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */
+ dino_dev->hba.lmmio_space_offset = PCI_F_EXTEND;
spin_lock_init(&dino_dev->dinosaur_pen);
dino_dev->hba.iommu = ccio_get_iommu(dev);
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c
index 64e1f2d..7ec43a5 100644
--- a/drivers/platform/x86/samsung-laptop.c
+++ b/drivers/platform/x86/samsung-laptop.c
@@ -601,7 +601,7 @@
struct sabi_retval sretval;
unsigned int ifaceP;
int i;
- int loca;
+ int loca = 0xffff;
int retval;
if (efi_enabled(EFI_BOOT))
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 64aedd8..a3511e7 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -213,163 +213,14 @@
return m41t80_set_datetime(to_i2c_client(dev), tm);
}
-static int m41t80_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
-{
- struct i2c_client *client = to_i2c_client(dev);
- int rc;
-
- rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
- if (rc < 0)
- goto err;
-
- if (enabled)
- rc |= M41T80_ALMON_AFE;
- else
- rc &= ~M41T80_ALMON_AFE;
-
- if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, rc) < 0)
- goto err;
-
- return 0;
-err:
- return -EIO;
-}
-
-static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
-{
- struct i2c_client *client = to_i2c_client(dev);
- u8 wbuf[1 + M41T80_ALARM_REG_SIZE];
- u8 *buf = &wbuf[1];
- u8 *reg = buf - M41T80_REG_ALARM_MON;
- u8 dt_addr[1] = { M41T80_REG_ALARM_MON };
- struct i2c_msg msgs_in[] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = 1,
- .buf = dt_addr,
- },
- {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = M41T80_ALARM_REG_SIZE,
- .buf = buf,
- },
- };
- struct i2c_msg msgs[] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = 1 + M41T80_ALARM_REG_SIZE,
- .buf = wbuf,
- },
- };
-
- if (i2c_transfer(client->adapter, msgs_in, 2) < 0) {
- dev_err(&client->dev, "read error\n");
- return -EIO;
- }
- reg[M41T80_REG_ALARM_MON] &= ~(0x1f | M41T80_ALMON_AFE);
- reg[M41T80_REG_ALARM_DAY] = 0;
- reg[M41T80_REG_ALARM_HOUR] &= ~(0x3f | 0x80);
- reg[M41T80_REG_ALARM_MIN] = 0;
- reg[M41T80_REG_ALARM_SEC] = 0;
-
- wbuf[0] = M41T80_REG_ALARM_MON; /* offset into rtc's regs */
- reg[M41T80_REG_ALARM_SEC] |= t->time.tm_sec >= 0 ?
- bin2bcd(t->time.tm_sec) : 0x80;
- reg[M41T80_REG_ALARM_MIN] |= t->time.tm_min >= 0 ?
- bin2bcd(t->time.tm_min) : 0x80;
- reg[M41T80_REG_ALARM_HOUR] |= t->time.tm_hour >= 0 ?
- bin2bcd(t->time.tm_hour) : 0x80;
- reg[M41T80_REG_ALARM_DAY] |= t->time.tm_mday >= 0 ?
- bin2bcd(t->time.tm_mday) : 0x80;
- if (t->time.tm_mon >= 0)
- reg[M41T80_REG_ALARM_MON] |= bin2bcd(t->time.tm_mon + 1);
- else
- reg[M41T80_REG_ALARM_DAY] |= 0x40;
-
- if (i2c_transfer(client->adapter, msgs, 1) != 1) {
- dev_err(&client->dev, "write error\n");
- return -EIO;
- }
-
- if (t->enabled) {
- reg[M41T80_REG_ALARM_MON] |= M41T80_ALMON_AFE;
- if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
- reg[M41T80_REG_ALARM_MON]) < 0) {
- dev_err(&client->dev, "write error\n");
- return -EIO;
- }
- }
- return 0;
-}
-
-static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t)
-{
- struct i2c_client *client = to_i2c_client(dev);
- u8 buf[M41T80_ALARM_REG_SIZE + 1]; /* all alarm regs and flags */
- u8 dt_addr[1] = { M41T80_REG_ALARM_MON };
- u8 *reg = buf - M41T80_REG_ALARM_MON;
- struct i2c_msg msgs[] = {
- {
- .addr = client->addr,
- .flags = 0,
- .len = 1,
- .buf = dt_addr,
- },
- {
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = M41T80_ALARM_REG_SIZE + 1,
- .buf = buf,
- },
- };
-
- if (i2c_transfer(client->adapter, msgs, 2) < 0) {
- dev_err(&client->dev, "read error\n");
- return -EIO;
- }
- t->time.tm_sec = -1;
- t->time.tm_min = -1;
- t->time.tm_hour = -1;
- t->time.tm_mday = -1;
- t->time.tm_mon = -1;
- if (!(reg[M41T80_REG_ALARM_SEC] & 0x80))
- t->time.tm_sec = bcd2bin(reg[M41T80_REG_ALARM_SEC] & 0x7f);
- if (!(reg[M41T80_REG_ALARM_MIN] & 0x80))
- t->time.tm_min = bcd2bin(reg[M41T80_REG_ALARM_MIN] & 0x7f);
- if (!(reg[M41T80_REG_ALARM_HOUR] & 0x80))
- t->time.tm_hour = bcd2bin(reg[M41T80_REG_ALARM_HOUR] & 0x3f);
- if (!(reg[M41T80_REG_ALARM_DAY] & 0x80))
- t->time.tm_mday = bcd2bin(reg[M41T80_REG_ALARM_DAY] & 0x3f);
- if (!(reg[M41T80_REG_ALARM_DAY] & 0x40))
- t->time.tm_mon = bcd2bin(reg[M41T80_REG_ALARM_MON] & 0x1f) - 1;
- t->time.tm_year = -1;
- t->time.tm_wday = -1;
- t->time.tm_yday = -1;
- t->time.tm_isdst = -1;
- t->enabled = !!(reg[M41T80_REG_ALARM_MON] & M41T80_ALMON_AFE);
- t->pending = !!(reg[M41T80_REG_FLAGS] & M41T80_FLAGS_AF);
- return 0;
-}
-
+/*
+ * XXX - m41t80 alarm functionality is reported broken.
+ * until it is fixed, don't register alarm functions.
+ */
static struct rtc_class_ops m41t80_rtc_ops = {
.read_time = m41t80_rtc_read_time,
.set_time = m41t80_rtc_set_time,
- /*
- * XXX - m41t80 alarm functionality is reported broken.
- * until it is fixed, don't register alarm functions.
- *
- .read_alarm = m41t80_rtc_read_alarm,
- .set_alarm = m41t80_rtc_set_alarm,
- */
.proc = m41t80_rtc_proc,
- /*
- * See above comment on broken alarm
- *
- .alarm_irq_enable = m41t80_rtc_alarm_irq_enable,
- */
};
#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index bfd618a..52f7f3a 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -50,7 +50,7 @@
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
-/* FIXME:
+/* Fixed in linux-4.2, not backported to 3.2:
*
* 1. Although all of the necessary command mapping places have the
* appropriate dma_map.. APIs, the driver still processes its internal
@@ -69,7 +69,6 @@
* 7. advansys_info is not safe against multiple simultaneous callers
* 8. Add module_param to override ISA/VLB ioport array
*/
-#warning this driver is still not properly converted to the DMA API
/* Enable driver /proc statistics. */
#define ADVANSYS_STATS
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c
index edb43fd..c831e30 100644
--- a/drivers/scsi/aic94xx/aic94xx_sds.c
+++ b/drivers/scsi/aic94xx/aic94xx_sds.c
@@ -983,7 +983,7 @@
{
int err, i;
u32 offs, size;
- struct asd_ll_el *el;
+ struct asd_ll_el *el = NULL;
struct asd_ctrla_phy_settings *ps;
struct asd_ctrla_phy_settings dflt_ps;
@@ -1004,6 +1004,7 @@
size = sizeof(struct asd_ctrla_phy_settings);
ps = &dflt_ps;
+ goto out_process;
}
if (size == 0)
@@ -1028,7 +1029,7 @@
ASD_DPRINTK("couldn't find ctrla phy settings struct\n");
goto out2;
}
-
+out_process:
err = asd_process_ctrla_phy_settings(asd_ha, ps);
if (err) {
ASD_DPRINTK("couldn't process ctrla phy settings\n");
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index b6e233d..e6f0a48 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -49,27 +49,12 @@
#include <linux/scatterlist.h>
#include <linux/libata.h>
-/* ---------- SCSI Host glue ---------- */
-
-static void sas_scsi_task_done(struct sas_task *task)
+/* record final status and free the task */
+static void sas_end_task(struct scsi_cmnd *sc, struct sas_task *task)
{
struct task_status_struct *ts = &task->task_status;
- struct scsi_cmnd *sc = task->uldd_task;
int hs = 0, stat = 0;
- if (unlikely(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
- /* Aborted tasks will be completed by the error handler */
- SAS_DPRINTK("task done but aborted\n");
- return;
- }
-
- if (unlikely(!sc)) {
- SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n");
- list_del_init(&task->list);
- sas_free_task(task);
- return;
- }
-
if (ts->resp == SAS_TASK_UNDELIVERED) {
/* transport error */
hs = DID_NO_CONNECT;
@@ -124,10 +109,32 @@
break;
}
}
- ASSIGN_SAS_TASK(sc, NULL);
+
sc->result = (hs << 16) | stat;
+ ASSIGN_SAS_TASK(sc, NULL);
list_del_init(&task->list);
sas_free_task(task);
+}
+
+static void sas_scsi_task_done(struct sas_task *task)
+{
+ struct scsi_cmnd *sc = task->uldd_task;
+
+ if (unlikely(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
+ /* Aborted tasks will be completed by the error handler */
+ SAS_DPRINTK("task done but aborted\n");
+ return;
+ }
+
+ if (unlikely(!sc)) {
+ SAS_DPRINTK("task_done called with non existing SCSI cmnd!\n");
+ list_del_init(&task->list);
+ sas_free_task(task);
+ return;
+ }
+
+ ASSIGN_SAS_TASK(sc, NULL);
+ sas_end_task(sc, task);
sc->scsi_done(sc);
}
@@ -238,18 +245,16 @@
struct sas_task *task = TO_SAS_TASK(cmd);
struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host);
- /* remove the aborted task flag to allow the task to be
- * completed now. At this point, we only get called following
- * an actual abort of the task, so we should be guaranteed not
- * to be racing with any completions from the LLD (hence we
- * don't need the task state lock to clear the flag) */
- task->task_state_flags &= ~SAS_TASK_STATE_ABORTED;
- /* Now call task_done. However, task will be free'd after
- * this */
- task->task_done(task);
+ /* At this point, we only get called following an actual abort
+ * of the task, so we should be guaranteed not to be racing with
+ * any completions from the LLD. Task is freed after this.
+ */
+ sas_end_task(cmd, task);
+
/* now finish the command and move it on to the error
* handler done list, this also takes it off the
- * error handler pending list */
+ * error handler pending list.
+ */
scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q);
}
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 01780a9..044c702 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -5734,9 +5734,10 @@
u8 task_abort_retries;
mutex_lock(&ioc->tm_cmds.mutex);
- dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter: phy number(%d), "
- "width(%d)\n", ioc->name, __func__, event_data->PhyNum,
- event_data->PortWidth));
+ pr_info(MPT2SAS_FMT
+ "%s: enter: phy number(%d), width(%d)\n",
+ ioc->name, __func__, event_data->PhyNum,
+ event_data->PortWidth);
_scsih_block_io_all_device(ioc);
diff --git a/drivers/staging/bcm/Kconfig b/drivers/staging/bcm/Kconfig
index 96adb10..22f5aa4 100644
--- a/drivers/staging/bcm/Kconfig
+++ b/drivers/staging/bcm/Kconfig
@@ -1,6 +1,7 @@
config BCM_WIMAX
tristate "Beceem BCS200/BCS220-3 and BCSM250 wimax support"
depends on USB && NET && EXPERIMENTAL
+ depends on !64BIT
default N
help
This is an experimental driver for the Beceem WIMAX chipset used
diff --git a/drivers/staging/comedi/drivers/vmk80xx.c b/drivers/staging/comedi/drivers/vmk80xx.c
index 3d13ca6e1..c7ff0cc 100644
--- a/drivers/staging/comedi/drivers/vmk80xx.c
+++ b/drivers/staging/comedi/drivers/vmk80xx.c
@@ -605,6 +605,7 @@
reg[0] = VMK8055_AI2_REG;
break;
case VMK8061_MODEL:
+ default:
reg[0] = VMK8061_AI_REG1;
reg[1] = VMK8061_AI_REG2;
dev->usb_tx_buf[0] = VMK8061_CMD_RD_AI;
@@ -979,6 +980,7 @@
reg[0] = VMK8055_CNT2_REG;
break;
case VMK8061_MODEL:
+ default:
reg[0] = VMK8061_CNT_REG;
reg[1] = VMK8061_CNT_REG;
dev->usb_tx_buf[0] = VMK8061_CMD_RD_CNT;
diff --git a/drivers/staging/cxt1e1/functions.c b/drivers/staging/cxt1e1/functions.c
index d9a9aa3..a98729e 100644
--- a/drivers/staging/cxt1e1/functions.c
+++ b/drivers/staging/cxt1e1/functions.c
@@ -270,15 +270,6 @@
extern ci_t *CI; /* dummy pointer to board ZERO's data */
void
-VMETRO_TRACE (void *x)
-{
- u_int32_t y = (u_int32_t) x;
-
- pci_write_32 ((u_int32_t *) &CI->cpldbase->leds, y);
-}
-
-
-void
VMETRO_TRIGGER (ci_t * ci, int x)
{
comet_t *comet;
diff --git a/drivers/staging/cxt1e1/pmcc4.h b/drivers/staging/cxt1e1/pmcc4.h
index e046b87..d92ea7d 100644
--- a/drivers/staging/cxt1e1/pmcc4.h
+++ b/drivers/staging/cxt1e1/pmcc4.h
@@ -138,7 +138,6 @@
void sbeid_set_hdwbid (ci_t * ci);
u_int32_t sbeCrc (u_int8_t *, u_int32_t, u_int32_t, u_int32_t *);
-void VMETRO_TRACE (void *); /* put data into 8 LEDs */
void VMETRO_TRIGGER (ci_t *, int); /* Note: int = 0(default)
* thru 15 */
diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c
index 559545a..84145a4 100644
--- a/drivers/staging/iio/accel/lis3l02dq_core.c
+++ b/drivers/staging/iio/accel/lis3l02dq_core.c
@@ -534,7 +534,7 @@
};
-static ssize_t lis3l02dq_read_event_config(struct iio_dev *indio_dev,
+static int lis3l02dq_read_event_config(struct iio_dev *indio_dev,
u64 event_code)
{
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c
index 47630d5..76dad99 100644
--- a/drivers/staging/iio/adc/ad7298_ring.c
+++ b/drivers/staging/iio/adc/ad7298_ring.c
@@ -120,7 +120,7 @@
struct iio_dev *indio_dev = pf->indio_dev;
struct ad7298_state *st = iio_priv(indio_dev);
struct iio_buffer *ring = indio_dev->buffer;
- s64 time_ns;
+ s64 time_ns = 0;
__u16 buf[16];
int b_sent, i;
diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c
index 5d7a906..b9dc422 100644
--- a/drivers/staging/iio/gyro/adis16080_core.c
+++ b/drivers/staging/iio/gyro/adis16080_core.c
@@ -82,7 +82,7 @@
long mask)
{
int ret = -EINVAL;
- u16 ut;
+ u16 ut = 0;
/* Take the iio_dev status lock */
mutex_lock(&indio_dev->mlock);
diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c
index 7e984bc..ee83ccb 100644
--- a/drivers/staging/iio/light/tsl2563.c
+++ b/drivers/staging/iio/light/tsl2563.c
@@ -606,7 +606,7 @@
struct tsl2563_chip *chip = iio_priv(dev_info);
iio_push_event(dev_info,
- IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
+ IIO_UNMOD_EVENT_CODE(IIO_INTENSITY,
0,
IIO_EV_TYPE_THRESH,
IIO_EV_DIR_EITHER),
diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c
index 6401a62..0ed8c0b 100644
--- a/drivers/staging/iio/resolver/ad2s1210.c
+++ b/drivers/staging/iio/resolver/ad2s1210.c
@@ -480,7 +480,7 @@
long m)
{
struct ad2s1210_state *st = iio_priv(indio_dev);
- bool negative;
+ u16 negative;
int ret = 0;
u16 pos;
s16 vel;
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c
index 77a0751..f54057b 100644
--- a/drivers/staging/slicoss/slicoss.c
+++ b/drivers/staging/slicoss/slicoss.c
@@ -1490,7 +1490,7 @@
slic_reg64_write(adapter, &adapter->slic_regs->slic_rbar64,
(rspq->paddr[rspq->pageindex] | SLIC_RSPQ_BUFSINPAGE),
&adapter->slic_regs->slic_addr_upper, 0, DONT_FLUSH);
- rspq->pageindex = (++rspq->pageindex) % rspq->num_pages;
+ rspq->pageindex = (rspq->pageindex + 1) % rspq->num_pages;
rspq->offset = 0;
rspq->rspbuf = (struct slic_rspbuf *)
rspq->vaddr[rspq->pageindex];
diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c
index 077c506..5765bb9 100644
--- a/drivers/staging/vt6655/device_main.c
+++ b/drivers/staging/vt6655/device_main.c
@@ -3387,9 +3387,12 @@
case SIOCGIWAPLIST:
{
- char buffer[IW_MAX_AP * (sizeof(struct sockaddr) + sizeof(struct iw_quality))];
+ char *buffer = kzalloc(IW_MAX_AP * (sizeof(struct sockaddr) +
+ sizeof(struct iw_quality)), GFP_KERNEL);
- if (wrq->u.data.pointer) {
+ if (!buffer) {
+ rc = -ENOMEM;
+ } else if (wrq->u.data.pointer) {
rc = iwctl_giwaplist(dev, NULL, &(wrq->u.data), buffer);
if (rc == 0) {
if (copy_to_user(wrq->u.data.pointer,
@@ -3399,6 +3402,7 @@
rc = -EFAULT;
}
}
+ kfree(buffer);
}
break;
diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c
index 3c40096..80e959d 100644
--- a/drivers/staging/wlan-ng/prism2fw.c
+++ b/drivers/staging/wlan-ng/prism2fw.c
@@ -765,30 +765,35 @@
int read_cardpda(struct pda *pda, wlandevice_t *wlandev)
{
int result = 0;
- struct p80211msg_p2req_readpda msg;
+ struct p80211msg_p2req_readpda *msg;
+
+ msg = kzalloc(sizeof(*msg), GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
/* set up the msg */
- msg.msgcode = DIDmsg_p2req_readpda;
- msg.msglen = sizeof(msg);
- strcpy(msg.devname, wlandev->name);
- msg.pda.did = DIDmsg_p2req_readpda_pda;
- msg.pda.len = HFA384x_PDA_LEN_MAX;
- msg.pda.status = P80211ENUM_msgitem_status_no_value;
- msg.resultcode.did = DIDmsg_p2req_readpda_resultcode;
- msg.resultcode.len = sizeof(u32);
- msg.resultcode.status = P80211ENUM_msgitem_status_no_value;
+ msg->msgcode = DIDmsg_p2req_readpda;
+ msg->msglen = sizeof(msg);
+ strcpy(msg->devname, wlandev->name);
+ msg->pda.did = DIDmsg_p2req_readpda_pda;
+ msg->pda.len = HFA384x_PDA_LEN_MAX;
+ msg->pda.status = P80211ENUM_msgitem_status_no_value;
+ msg->resultcode.did = DIDmsg_p2req_readpda_resultcode;
+ msg->resultcode.len = sizeof(u32);
+ msg->resultcode.status = P80211ENUM_msgitem_status_no_value;
- if (prism2mgmt_readpda(wlandev, &msg) != 0) {
+ if (prism2mgmt_readpda(wlandev, msg) != 0) {
/* prism2mgmt_readpda prints an errno if appropriate */
result = -1;
- } else if (msg.resultcode.data == P80211ENUM_resultcode_success) {
- memcpy(pda->buf, msg.pda.data, HFA384x_PDA_LEN_MAX);
+ } else if (msg->resultcode.data == P80211ENUM_resultcode_success) {
+ memcpy(pda->buf, msg->pda.data, HFA384x_PDA_LEN_MAX);
result = mkpdrlist(pda);
} else {
/* resultcode must've been something other than success */
result = -1;
}
+ kfree(msg);
return result;
}
@@ -980,9 +985,8 @@
unsigned int nfchunks)
{
int result = 0;
- struct p80211msg_p2req_ramdl_state rstatemsg;
- struct p80211msg_p2req_ramdl_write rwritemsg;
- struct p80211msg *msgp;
+ struct p80211msg_p2req_ramdl_state *rstmsg;
+ struct p80211msg_p2req_ramdl_write *rwrmsg;
u32 resultcode;
int i;
int j;
@@ -991,57 +995,68 @@
u32 currlen;
u32 currdaddr;
- /* Initialize the messages */
- memset(&rstatemsg, 0, sizeof(rstatemsg));
- strcpy(rstatemsg.devname, wlandev->name);
- rstatemsg.msgcode = DIDmsg_p2req_ramdl_state;
- rstatemsg.msglen = sizeof(rstatemsg);
- rstatemsg.enable.did = DIDmsg_p2req_ramdl_state_enable;
- rstatemsg.exeaddr.did = DIDmsg_p2req_ramdl_state_exeaddr;
- rstatemsg.resultcode.did = DIDmsg_p2req_ramdl_state_resultcode;
- rstatemsg.enable.status = P80211ENUM_msgitem_status_data_ok;
- rstatemsg.exeaddr.status = P80211ENUM_msgitem_status_data_ok;
- rstatemsg.resultcode.status = P80211ENUM_msgitem_status_no_value;
- rstatemsg.enable.len = sizeof(u32);
- rstatemsg.exeaddr.len = sizeof(u32);
- rstatemsg.resultcode.len = sizeof(u32);
+ rstmsg = kmalloc(sizeof(*rstmsg), GFP_KERNEL);
+ rwrmsg = kmalloc(sizeof(*rwrmsg), GFP_KERNEL);
+ if (!rstmsg || !rwrmsg) {
+ kfree(rstmsg);
+ kfree(rwrmsg);
+ printk(KERN_ERR
+ "writeimage: no memory for firmware download, "
+ "aborting download\n");
+ return -ENOMEM;
+ }
- memset(&rwritemsg, 0, sizeof(rwritemsg));
- strcpy(rwritemsg.devname, wlandev->name);
- rwritemsg.msgcode = DIDmsg_p2req_ramdl_write;
- rwritemsg.msglen = sizeof(rwritemsg);
- rwritemsg.addr.did = DIDmsg_p2req_ramdl_write_addr;
- rwritemsg.len.did = DIDmsg_p2req_ramdl_write_len;
- rwritemsg.data.did = DIDmsg_p2req_ramdl_write_data;
- rwritemsg.resultcode.did = DIDmsg_p2req_ramdl_write_resultcode;
- rwritemsg.addr.status = P80211ENUM_msgitem_status_data_ok;
- rwritemsg.len.status = P80211ENUM_msgitem_status_data_ok;
- rwritemsg.data.status = P80211ENUM_msgitem_status_data_ok;
- rwritemsg.resultcode.status = P80211ENUM_msgitem_status_no_value;
- rwritemsg.addr.len = sizeof(u32);
- rwritemsg.len.len = sizeof(u32);
- rwritemsg.data.len = WRITESIZE_MAX;
- rwritemsg.resultcode.len = sizeof(u32);
+ /* Initialize the messages */
+ memset(rstmsg, 0, sizeof(*rstmsg));
+ strcpy(rstmsg->devname, wlandev->name);
+ rstmsg->msgcode = DIDmsg_p2req_ramdl_state;
+ rstmsg->msglen = sizeof(*rstmsg);
+ rstmsg->enable.did = DIDmsg_p2req_ramdl_state_enable;
+ rstmsg->exeaddr.did = DIDmsg_p2req_ramdl_state_exeaddr;
+ rstmsg->resultcode.did = DIDmsg_p2req_ramdl_state_resultcode;
+ rstmsg->enable.status = P80211ENUM_msgitem_status_data_ok;
+ rstmsg->exeaddr.status = P80211ENUM_msgitem_status_data_ok;
+ rstmsg->resultcode.status = P80211ENUM_msgitem_status_no_value;
+ rstmsg->enable.len = sizeof(u32);
+ rstmsg->exeaddr.len = sizeof(u32);
+ rstmsg->resultcode.len = sizeof(u32);
+
+ memset(rwrmsg, 0, sizeof(*rwrmsg));
+ strcpy(rwrmsg->devname, wlandev->name);
+ rwrmsg->msgcode = DIDmsg_p2req_ramdl_write;
+ rwrmsg->msglen = sizeof(*rwrmsg);
+ rwrmsg->addr.did = DIDmsg_p2req_ramdl_write_addr;
+ rwrmsg->len.did = DIDmsg_p2req_ramdl_write_len;
+ rwrmsg->data.did = DIDmsg_p2req_ramdl_write_data;
+ rwrmsg->resultcode.did = DIDmsg_p2req_ramdl_write_resultcode;
+ rwrmsg->addr.status = P80211ENUM_msgitem_status_data_ok;
+ rwrmsg->len.status = P80211ENUM_msgitem_status_data_ok;
+ rwrmsg->data.status = P80211ENUM_msgitem_status_data_ok;
+ rwrmsg->resultcode.status = P80211ENUM_msgitem_status_no_value;
+ rwrmsg->addr.len = sizeof(u32);
+ rwrmsg->len.len = sizeof(u32);
+ rwrmsg->data.len = WRITESIZE_MAX;
+ rwrmsg->resultcode.len = sizeof(u32);
/* Send xxx_state(enable) */
pr_debug("Sending dl_state(enable) message.\n");
- rstatemsg.enable.data = P80211ENUM_truth_true;
- rstatemsg.exeaddr.data = startaddr;
+ rstmsg->enable.data = P80211ENUM_truth_true;
+ rstmsg->exeaddr.data = startaddr;
- msgp = (struct p80211msg *) &rstatemsg;
- result = prism2mgmt_ramdl_state(wlandev, msgp);
+ result = prism2mgmt_ramdl_state(wlandev, rstmsg);
if (result) {
printk(KERN_ERR
"writeimage state enable failed w/ result=%d, "
"aborting download\n", result);
- return result;
+ goto free_result;
}
- resultcode = rstatemsg.resultcode.data;
+ resultcode = rstmsg->resultcode.data;
if (resultcode != P80211ENUM_resultcode_success) {
printk(KERN_ERR
"writeimage()->xxxdl_state msg indicates failure, "
"w/ resultcode=%d, aborting download.\n", resultcode);
- return 1;
+ result = 1;
+ goto free_result;
}
/* Now, loop through the data chunks and send WRITESIZE_MAX data */
@@ -1059,9 +1074,9 @@
curroff = j * WRITESIZE_MAX;
currdaddr = fchunk[i].addr + curroff;
/* Setup the message */
- rwritemsg.addr.data = currdaddr;
- rwritemsg.len.data = currlen;
- memcpy(rwritemsg.data.data,
+ rwrmsg->addr.data = currdaddr;
+ rwrmsg->len.data = currlen;
+ memcpy(rwrmsg->data.data,
fchunk[i].data + curroff, currlen);
/* Send flashdl_write(pda) */
@@ -1069,23 +1084,23 @@
("Sending xxxdl_write message addr=%06x len=%d.\n",
currdaddr, currlen);
- msgp = (struct p80211msg *) &rwritemsg;
- result = prism2mgmt_ramdl_write(wlandev, msgp);
+ result = prism2mgmt_ramdl_write(wlandev, rwrmsg);
/* Check the results */
if (result) {
printk(KERN_ERR
"writeimage chunk write failed w/ result=%d, "
"aborting download\n", result);
- return result;
+ goto free_result;
}
- resultcode = rstatemsg.resultcode.data;
+ resultcode = rstmsg->resultcode.data;
if (resultcode != P80211ENUM_resultcode_success) {
printk(KERN_ERR
"writeimage()->xxxdl_write msg indicates failure, "
"w/ resultcode=%d, aborting download.\n",
resultcode);
- return 1;
+ result = 1;
+ goto free_result;
}
}
@@ -1093,24 +1108,28 @@
/* Send xxx_state(disable) */
pr_debug("Sending dl_state(disable) message.\n");
- rstatemsg.enable.data = P80211ENUM_truth_false;
- rstatemsg.exeaddr.data = 0;
+ rstmsg->enable.data = P80211ENUM_truth_false;
+ rstmsg->exeaddr.data = 0;
- msgp = (struct p80211msg *) &rstatemsg;
- result = prism2mgmt_ramdl_state(wlandev, msgp);
+ result = prism2mgmt_ramdl_state(wlandev, rstmsg);
if (result) {
printk(KERN_ERR
"writeimage state disable failed w/ result=%d, "
"aborting download\n", result);
- return result;
+ goto free_result;
}
- resultcode = rstatemsg.resultcode.data;
+ resultcode = rstmsg->resultcode.data;
if (resultcode != P80211ENUM_resultcode_success) {
printk(KERN_ERR
"writeimage()->xxxdl_state msg indicates failure, "
"w/ resultcode=%d, aborting download.\n", resultcode);
- return 1;
+ result = 1;
+ goto free_result;
}
+
+free_result:
+ kfree(rstmsg);
+ kfree(rwrmsg);
return result;
}
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 210b533..bcadc2e 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1592,6 +1592,9 @@
{ USB_DEVICE(0x1576, 0x03b1), /* Maretron USB100 */
.driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
},
+ { USB_DEVICE(0xfff0, 0x0100), /* DATECS FP-2000 */
+ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
+ },
{ USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */
.driver_info = CLEAR_HALT_CONDITIONS,
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 989256e..ea15bcc 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -609,15 +609,23 @@
} else if (header->bDescriptorType ==
USB_DT_INTERFACE_ASSOCIATION) {
+ struct usb_interface_assoc_descriptor *d;
+
+ d = (struct usb_interface_assoc_descriptor *)header;
+ if (d->bLength < USB_DT_INTERFACE_ASSOCIATION_SIZE) {
+ dev_warn(ddev,
+ "config %d has an invalid interface association descriptor of length %d, skipping\n",
+ cfgno, d->bLength);
+ continue;
+ }
+
if (iad_num == USB_MAXIADS) {
dev_warn(ddev, "found more Interface "
"Association Descriptors "
"than allocated for in "
"configuration %d\n", cfgno);
} else {
- config->intf_assoc[iad_num] =
- (struct usb_interface_assoc_descriptor
- *)header;
+ config->intf_assoc[iad_num] = d;
iad_num++;
}
@@ -923,10 +931,12 @@
for (i = 0; i < num; i++) {
buffer += length;
cap = (struct usb_dev_cap_header *)buffer;
- length = cap->bLength;
- if (total_len < length)
+ if (total_len < sizeof(*cap) || total_len < cap->bLength) {
+ dev->bos->desc->bNumDeviceCaps = i;
break;
+ }
+ length = cap->bLength;
total_len -= length;
if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) {
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 0b4ece1..b68252d 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2194,6 +2194,8 @@
}
if (usb_hcd_is_primary_hcd(hcd) && hcd->shared_hcd) {
hcd = hcd->shared_hcd;
+ clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
+ set_bit(HCD_FLAG_DEAD, &hcd->flags);
if (hcd->rh_registered) {
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 2a38a17..9e387ec 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -152,12 +152,13 @@
return tmp;
}
- if (in) {
+ if (in)
dev->in_pipe = usb_rcvbulkpipe(udev,
in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ if (out)
dev->out_pipe = usb_sndbulkpipe(udev,
out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
- }
+
if (iso_in) {
dev->iso_in = &iso_in->desc;
dev->in_iso_pipe = usb_rcvisocpipe(udev,
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c
index 08c679c..71f4dae 100644
--- a/drivers/usb/renesas_usbhs/common.c
+++ b/drivers/usb/renesas_usbhs/common.c
@@ -599,12 +599,14 @@
struct usbhs_priv *priv = dev_get_drvdata(dev);
struct platform_device *pdev = usbhs_priv_to_pdev(priv);
+ if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) {
+ usbhsc_power_ctrl(priv, 1);
+ usbhs_mod_autonomy_mode(priv);
+ }
+
usbhs_platform_call(priv, phy_reset, pdev);
- if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL))
- usbhsc_power_ctrl(priv, 1);
-
- usbhsc_hotplug(priv);
+ usbhsc_drvcllbck_notify_hotplug(pdev);
return 0;
}
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index fe2c410..2de2053 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -141,6 +141,7 @@
{ USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */
{ USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */
{ USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */
+ { USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index ed8694b..8901b8d 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -449,7 +449,7 @@
/* check first to simplify error handling */
if (!serial->port[1] || !serial->port[1]->interrupt_in_urb) {
- dev_err(&port->dev, "expected endpoint missing\n");
+ dev_err(&serial->dev->dev, "expected endpoint missing\n");
return -ENODEV;
}
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index ffc4193..36f18b5 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -1522,8 +1522,11 @@
/* Make sure driver was initialized */
- if (us->extra == NULL)
+ if (us->extra == NULL) {
US_DEBUGP("ERROR Driver not initialized\n");
+ srb->result = DID_ERROR << 16;
+ return;
+ }
scsi_set_resid(srb, 0);
/* scsi_bufflen might change in protocol translation to ata */
diff --git a/fs/bio.c b/fs/bio.c
index 55b5188..1fa6b82 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1027,6 +1027,7 @@
offset = uaddr & ~PAGE_MASK;
for (j = cur_page; j < page_limit; j++) {
unsigned int bytes = PAGE_SIZE - offset;
+ unsigned short prev_bi_vcnt = bio->bi_vcnt;
if (len <= 0)
break;
@@ -1041,6 +1042,13 @@
bytes)
break;
+ /*
+ * check if vector was merged with previous
+ * drop page reference if needed
+ */
+ if (bio->bi_vcnt == prev_bi_vcnt)
+ put_page(pages[j]);
+
len -= bytes;
offset = 0;
}
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 48db02d..c6b8cbc 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -3909,13 +3909,12 @@
int rc = 0;
int bytes_returned = 0;
SET_SEC_DESC_REQ *pSMB = NULL;
- NTRANSACT_RSP *pSMBr = NULL;
+ void *pSMBr;
setCifsAclRetry:
- rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB,
- (void **) &pSMBr);
+ rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
if (rc)
- return (rc);
+ return rc;
pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0;
@@ -3943,9 +3942,8 @@
pSMB->AclFlags = cpu_to_le32(aclflag);
if (pntsd && acllen) {
- memcpy((char *) &pSMBr->hdr.Protocol + data_offset,
- (char *) pntsd,
- acllen);
+ memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
+ data_offset, pntsd, acllen);
inc_rfc1001_len(pSMB, byte_count + data_count);
} else
inc_rfc1001_len(pSMB, byte_count);
@@ -5724,7 +5722,8 @@
param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
offset = param_offset + params;
- data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
+ data_offset = (char *)pSMB +
+ offsetof(struct smb_hdr, Protocol) + offset;
count = sizeof(FILE_BASIC_INFO);
pSMB->MaxParameterCount = cpu_to_le16(2);
@@ -5993,7 +5992,7 @@
u16 fid, u32 pid_of_opener)
{
struct smb_com_transaction2_sfi_req *pSMB = NULL;
- FILE_UNIX_BASIC_INFO *data_offset;
+ char *data_offset;
int rc = 0;
u16 params, param_offset, offset, byte_count, count;
@@ -6015,8 +6014,9 @@
param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
offset = param_offset + params;
- data_offset = (FILE_UNIX_BASIC_INFO *)
- ((char *)(&pSMB->hdr.Protocol) + offset);
+ data_offset = (char *)pSMB +
+ offsetof(struct smb_hdr, Protocol) + offset;
+
count = sizeof(FILE_UNIX_BASIC_INFO);
pSMB->MaxParameterCount = cpu_to_le16(2);
@@ -6038,7 +6038,7 @@
inc_rfc1001_len(pSMB, byte_count);
pSMB->ByteCount = cpu_to_le16(byte_count);
- cifs_fill_unix_set_info(data_offset, args);
+ cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
if (rc)
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 6937e7c..22758b1 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -520,6 +520,14 @@
oplock = pTcon->ses->server->oplocks ? REQ_OPLOCK : 0;
+ /* Don't allow path components longer than the server max. */
+ if (unlikely(pTcon->fsAttrInfo.MaxPathNameComponentLength &&
+ direntry->d_name.len >
+ le32_to_cpu(pTcon->fsAttrInfo.MaxPathNameComponentLength))) {
+ rc = -ENAMETOOLONG;
+ goto lookup_out;
+ }
+
/*
* Don't allow the separator character in a path component.
* The VFS will not allow "/", but "\" is allowed by posix.
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 5ce56e7..848b303 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1152,7 +1152,7 @@
struct ecryptfs_message *msg = NULL;
char *auth_tok_sig;
char *payload = NULL;
- size_t payload_len;
+ size_t payload_len = 0;
int rc;
rc = ecryptfs_get_auth_tok_sig(&auth_tok_sig, auth_tok);
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 3ed4aca..6c8ab33 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -477,8 +477,14 @@
wait_queue_head_t *whead;
rcu_read_lock();
- /* If it is cleared by POLLFREE, it should be rcu-safe */
- whead = rcu_dereference(pwq->whead);
+ /*
+ * If it is cleared by POLLFREE, it should be rcu-safe.
+ * If we read NULL we need a barrier paired with
+ * smp_store_release() in ep_poll_callback(), otherwise
+ * we rely on whead->lock.
+ */
+ whead = ACCESS_ONCE(pwq->whead);
+ smp_mb();
if (whead)
remove_wait_queue(whead, &pwq->wait);
rcu_read_unlock();
@@ -859,17 +865,6 @@
struct epitem *epi = ep_item_from_wait(wait);
struct eventpoll *ep = epi->ep;
- if ((unsigned long)key & POLLFREE) {
- ep_pwq_from_wait(wait)->whead = NULL;
- /*
- * whead = NULL above can race with ep_remove_wait_queue()
- * which can do another remove_wait_queue() after us, so we
- * can't use __remove_wait_queue(). whead->lock is held by
- * the caller.
- */
- list_del_init(&wait->task_list);
- }
-
spin_lock_irqsave(&ep->lock, flags);
/*
@@ -924,6 +919,23 @@
if (pwake)
ep_poll_safewake(&ep->poll_wait);
+ if ((unsigned long)key & POLLFREE) {
+ /*
+ * If we race with ep_remove_wait_queue() it can miss
+ * ->whead = NULL and do another remove_wait_queue() after
+ * us, so we can't use __remove_wait_queue().
+ */
+ list_del_init(&wait->task_list);
+ /*
+ * ->whead != NULL protects us from the race with ep_free()
+ * or ep_remove(), ep_remove_wait_queue() takes whead->lock
+ * held by the caller. Once we nullify it, nothing protects
+ * ep/epi or even wait.
+ */
+ smp_mb();
+ ACCESS_ONCE(ep_pwq_from_wait(wait)->whead) = NULL;
+ }
+
return 1;
}
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c
index 3426521..406352c 100644
--- a/fs/fuse/cuse.c
+++ b/fs/fuse/cuse.c
@@ -267,7 +267,7 @@
static int cuse_parse_devinfo(char *p, size_t len, struct cuse_devinfo *devinfo)
{
char *end = p + len;
- char *key, *val;
+ char *uninitialized_var(key), *uninitialized_var(val);
int rc;
while (true) {
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 1f78f91..7be4719 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -52,7 +52,7 @@
{
struct fuse_file *ff;
- ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
+ ff = kzalloc(sizeof(struct fuse_file), GFP_KERNEL);
if (unlikely(!ff))
return NULL;
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index d03a400..4ba011d 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -1018,6 +1018,7 @@
target->acdirmax = source->acdirmax;
target->caps = source->caps;
target->options = source->options;
+ target->port = source->port;
}
static void nfs_server_insert_lists(struct nfs_server *server)
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index 090d8ce..250db08 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -1797,7 +1797,7 @@
__u64 key, __u64 ptr,
const __u64 *keys, const __u64 *ptrs, int n)
{
- struct buffer_head *bh;
+ struct buffer_head *bh = NULL;
union nilfs_bmap_ptr_req dreq, nreq, *di, *ni;
struct nilfs_bmap_stats stats;
int ret;
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index a604ac0..7fe6773 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -581,7 +581,7 @@
struct nilfs_recovery_info *ri)
{
struct buffer_head *bh_sum = NULL;
- struct nilfs_segment_summary *sum;
+ struct nilfs_segment_summary *sum = NULL;
sector_t pseg_start;
sector_t seg_start, seg_end; /* Starting/ending DBN of full segment */
unsigned long nsalvaged_blocks = 0;
@@ -813,7 +813,7 @@
struct nilfs_recovery_info *ri)
{
struct buffer_head *bh_sum = NULL;
- struct nilfs_segment_summary *sum;
+ struct nilfs_segment_summary *sum = NULL;
sector_t pseg_start, pseg_end, sr_pseg_start = 0;
sector_t seg_start, seg_end; /* range of full segment (block number) */
sector_t b, end;
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 97bfbddd..8715fbc 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -360,7 +360,7 @@
struct nilfs_super_block *nsbp;
sector_t blocknr, newblocknr;
unsigned long offset;
- int sb2i = -1; /* array index of the secondary superblock */
+ int sb2i; /* array index of the secondary superblock */
int ret = 0;
/* nilfs->ns_sem must be locked by the caller. */
@@ -371,6 +371,9 @@
} else if (nilfs->ns_sbh[0]->b_blocknr > nilfs->ns_first_data_block) {
sb2i = 0;
blocknr = nilfs->ns_sbh[0]->b_blocknr;
+ } else {
+ sb2i = -1;
+ blocknr = 0;
}
if (sb2i >= 0 && (u64)blocknr << nilfs->ns_blocksize_bits == sb2off)
goto out; /* super block location is unchanged */
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
index 7e6e1f8..06a5027 100644
--- a/fs/ocfs2/acl.c
+++ b/fs/ocfs2/acl.c
@@ -246,19 +246,6 @@
switch (type) {
case ACL_TYPE_ACCESS:
name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
- if (acl) {
- umode_t mode;
- ret = posix_acl_update_mode(inode, &mode, &acl);
- if (ret)
- return ret;
- else {
- ret = ocfs2_acl_set_mode(inode, di_bh,
- handle, mode);
- if (ret)
- return ret;
-
- }
- }
break;
case ACL_TYPE_DEFAULT:
name_index = OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT;
@@ -483,6 +470,17 @@
} else
acl = NULL;
+ if (type == ACL_TYPE_ACCESS && acl) {
+ umode_t mode;
+
+ ret = posix_acl_update_mode(inode, &mode, &acl);
+ if (ret)
+ goto cleanup;
+
+ ret = ocfs2_acl_set_mode(inode, NULL, NULL, mode);
+ if (ret)
+ goto cleanup;
+ }
ret = ocfs2_set_acl(NULL, inode, NULL, type, acl, NULL, NULL);
cleanup:
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index 169380e..24675e3 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -894,13 +894,13 @@
/* free inodes to the left? */
if (useleft && trec.ir_freecount) {
- rec = trec;
xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
cur = tcur;
pag->pagl_leftrec = trec.ir_startino;
pag->pagl_rightrec = rec.ir_startino;
pag->pagl_pagino = pagino;
+ rec = trec;
goto alloc_inode;
}
diff --git a/include/asm-generic/topology.h b/include/asm-generic/topology.h
index fc824e2..5d2add1 100644
--- a/include/asm-generic/topology.h
+++ b/include/asm-generic/topology.h
@@ -48,7 +48,11 @@
#define parent_node(node) ((void)(node),0)
#endif
#ifndef cpumask_of_node
-#define cpumask_of_node(node) ((void)node, cpu_online_mask)
+ #ifdef CONFIG_NEED_MULTIPLE_NODES
+ #define cpumask_of_node(node) ((node) == 0 ? cpu_online_mask : cpu_none_mask)
+ #else
+ #define cpumask_of_node(node) ((void)node, cpu_online_mask)
+ #endif
#endif
#ifndef pcibus_to_node
#define pcibus_to_node(bus) ((void)(bus), -1)
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 213a870..45bf2dd 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -398,56 +398,32 @@
*---------------------------------------------------------------*/
#define DM_NAME "device-mapper"
-#ifdef CONFIG_PRINTK
-extern struct ratelimit_state dm_ratelimit_state;
+#define DM_RATELIMIT(pr_func, fmt, ...) \
+do { \
+ static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, \
+ DEFAULT_RATELIMIT_BURST); \
+ \
+ if (__ratelimit(&rs)) \
+ pr_func(DM_FMT(fmt), ##__VA_ARGS__); \
+} while (0)
-#define dm_ratelimit() __ratelimit(&dm_ratelimit_state)
-#else
-#define dm_ratelimit() 0
-#endif
+#define DM_FMT(fmt) DM_NAME ": " DM_MSG_PREFIX ": " fmt "\n"
-#define DMCRIT(f, arg...) \
- printk(KERN_CRIT DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
+#define DMCRIT(fmt, ...) pr_crit(DM_FMT(fmt), ##__VA_ARGS__)
-#define DMERR(f, arg...) \
- printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
-#define DMERR_LIMIT(f, arg...) \
- do { \
- if (dm_ratelimit()) \
- printk(KERN_ERR DM_NAME ": " DM_MSG_PREFIX ": " \
- f "\n", ## arg); \
- } while (0)
-
-#define DMWARN(f, arg...) \
- printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
-#define DMWARN_LIMIT(f, arg...) \
- do { \
- if (dm_ratelimit()) \
- printk(KERN_WARNING DM_NAME ": " DM_MSG_PREFIX ": " \
- f "\n", ## arg); \
- } while (0)
-
-#define DMINFO(f, arg...) \
- printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f "\n", ## arg)
-#define DMINFO_LIMIT(f, arg...) \
- do { \
- if (dm_ratelimit()) \
- printk(KERN_INFO DM_NAME ": " DM_MSG_PREFIX ": " f \
- "\n", ## arg); \
- } while (0)
+#define DMERR(fmt, ...) pr_err(DM_FMT(fmt), ##__VA_ARGS__)
+#define DMERR_LIMIT(fmt, ...) DM_RATELIMIT(pr_err, fmt, ##__VA_ARGS__)
+#define DMWARN(fmt, ...) pr_warn(DM_FMT(fmt), ##__VA_ARGS__)
+#define DMWARN_LIMIT(fmt, ...) DM_RATELIMIT(pr_warn, fmt, ##__VA_ARGS__)
+#define DMINFO(fmt, ...) pr_info(DM_FMT(fmt), ##__VA_ARGS__)
+#define DMINFO_LIMIT(fmt, ...) DM_RATELIMIT(pr_info, fmt, ##__VA_ARGS__)
#ifdef CONFIG_DM_DEBUG
-# define DMDEBUG(f, arg...) \
- printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX " DEBUG: " f "\n", ## arg)
-# define DMDEBUG_LIMIT(f, arg...) \
- do { \
- if (dm_ratelimit()) \
- printk(KERN_DEBUG DM_NAME ": " DM_MSG_PREFIX ": " f \
- "\n", ## arg); \
- } while (0)
+#define DMDEBUG(fmt, ...) printk(KERN_DEBUG DM_FMT(fmt), ##__VA_ARGS__)
+#define DMDEBUG_LIMIT(fmt, ...) DM_RATELIMIT(pr_debug, fmt, ##__VA_ARGS__)
#else
-# define DMDEBUG(f, arg...) do {} while (0)
-# define DMDEBUG_LIMIT(f, arg...) do {} while (0)
+#define DMDEBUG(fmt, ...) no_printk(fmt, ##__VA_ARGS__)
+#define DMDEBUG_LIMIT(fmt, ...) no_printk(fmt, ##__VA_ARGS__)
#endif
#define DMEMIT(x...) sz += ((sz >= maxlen) ? \
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 84b0b18..081f038 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -287,6 +287,7 @@
enum mlx4_port_type possible_type[MLX4_MAX_PORTS + 1];
u32 max_counters;
u8 ext_port_cap[MLX4_MAX_PORTS + 1];
+ bool wol_port[MLX4_MAX_PORTS + 1];
};
struct mlx4_buf_list {
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 3887901..ec69d76 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -327,7 +327,7 @@
static inline map_word map_word_load(struct map_info *map, const void *ptr)
{
- map_word r;
+ map_word r = {{0} };
if (map_bankwidth_is_1(map))
r.x[0] = *(unsigned char *)ptr;
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 8d5b91e..0aa2c4f 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -859,11 +859,6 @@
#endif /* CONFIG_PERF_EVENTS */
};
-enum perf_event_context_type {
- task_context,
- cpu_context,
-};
-
/**
* struct perf_event_context - event context structure
*
@@ -871,7 +866,6 @@
*/
struct perf_event_context {
struct pmu *pmu;
- enum perf_event_context_type type;
/*
* Protect the states of the events in the list,
* nr_active, and the list:
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index 3b6f628..046b1f4 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -686,6 +686,7 @@
__u8 iFunction;
} __attribute__ ((packed));
+#define USB_DT_INTERFACE_ASSOCIATION_SIZE 8
/*-------------------------------------------------------------------------*/
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 3907358..852f2ce 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -63,6 +63,7 @@
__u16 fn_flags;
__u32 fn_sernum;
struct rt6_info *rr_ptr;
+ struct rcu_head rcu;
};
#ifndef CONFIG_IPV6_SUBTREES
@@ -95,7 +96,7 @@
* the same cache line.
*/
struct fib6_table *rt6i_table;
- struct fib6_node *rt6i_node;
+ struct fib6_node __rcu *rt6i_node;
struct in6_addr rt6i_gateway;
@@ -126,6 +127,38 @@
return ((struct rt6_info *)dst)->rt6i_idev;
}
+/* Function to safely get fn->sernum for passed in rt
+ * and store result in passed in cookie.
+ * Return true if we can get cookie safely
+ * Return false if not
+ */
+static inline bool rt6_get_cookie_safe(const struct rt6_info *rt,
+ u32 *cookie)
+{
+ struct fib6_node *fn;
+ bool status = false;
+
+ rcu_read_lock();
+ fn = rcu_dereference(rt->rt6i_node);
+
+ if (fn) {
+ *cookie = fn->fn_sernum;
+ status = true;
+ }
+
+ rcu_read_unlock();
+ return status;
+}
+
+static inline u32 rt6_get_cookie(const struct rt6_info *rt)
+{
+ u32 cookie = 0;
+
+ rt6_get_cookie_safe(rt, &cookie);
+
+ return cookie;
+}
+
struct fib6_walker_t {
struct list_head lh;
struct fib6_node *root, *node;
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 4913dac..67bfec1 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -167,7 +167,7 @@
#ifdef CONFIG_IPV6_SUBTREES
np->saddr_cache = saddr;
#endif
- np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
+ np->dst_cookie = rt6_get_cookie(rt);
}
static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index e0f1c91..505eca3 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -538,6 +538,8 @@
#define _sctp_walk_params(pos, chunk, end, member)\
for (pos.v = chunk->member;\
+ (pos.v + offsetof(struct sctp_paramhdr, length) + sizeof(pos.p->length) <=\
+ (void *)chunk + end) &&\
pos.v <= (void *)chunk + end - ntohs(pos.p->length) &&\
ntohs(pos.p->length) >= sizeof(sctp_paramhdr_t);\
pos.v += WORD_ROUND(ntohs(pos.p->length)))
@@ -548,6 +550,8 @@
#define _sctp_walk_errors(err, chunk_hdr, end)\
for (err = (sctp_errhdr_t *)((void *)chunk_hdr + \
sizeof(sctp_chunkhdr_t));\
+ ((void *)err + offsetof(sctp_errhdr_t, length) + sizeof(err->length) <=\
+ (void *)chunk_hdr + end) &&\
(void *)err <= (void *)chunk_hdr + end - ntohs(err->length) &&\
ntohs(err->length) >= sizeof(sctp_errhdr_t); \
err = (sctp_errhdr_t *)((void *)err + WORD_ROUND(ntohs(err->length))))
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index 1e100c6..9cc517a 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -449,7 +449,10 @@
};
enum exec_status {
- /* The SAM_STAT_.. codes fit in the lower 6 bits */
+ /* The SAM_STAT_.. codes fit in the lower 6 bits, alias some of
+ * them here to silence 'case value not in enumerated type' warnings
+ */
+ __SAM_STAT_CHECK_CONDITION = SAM_STAT_CHECK_CONDITION,
SAS_DEV_NO_RESPONSE = 0x80,
SAS_DATA_UNDERRUN,
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index e683869..4b4b9d5 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -471,13 +471,15 @@
list_del(&krule->rlist);
if (list_empty(&watch->rules)) {
+ /*
+ * audit_remove_watch() drops our reference to 'parent' which
+ * can get freed. Grab our own reference to be safe.
+ */
+ audit_get_parent(parent);
audit_remove_watch(watch);
-
- if (list_empty(&parent->watches)) {
- audit_get_parent(parent);
+ if (list_empty(&parent->watches))
fsnotify_destroy_mark(&parent->mark);
- audit_put_parent(parent);
- }
+ audit_put_parent(parent);
}
}
diff --git a/kernel/events/core.c b/kernel/events/core.c
index f6797c6..ffe4cba 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3277,51 +3277,78 @@
}
EXPORT_SYMBOL_GPL(perf_event_read_value);
-static int perf_event_read_group(struct perf_event *event,
- u64 read_format, char __user *buf)
+static void __perf_read_group_add(struct perf_event *leader,
+ u64 read_format, u64 *values)
{
- struct perf_event *leader = event->group_leader, *sub;
struct perf_event_context *ctx = leader->ctx;
- int n = 0, size = 0, ret;
+ struct perf_event *sub;
+ unsigned long flags;
+ int n = 1; /* skip @nr */
u64 count, enabled, running;
- u64 values[5];
-
- lockdep_assert_held(&ctx->mutex);
count = perf_event_read_value(leader, &enabled, &running);
- values[n++] = 1 + leader->nr_siblings;
+ /*
+ * Since we co-schedule groups, {enabled,running} times of siblings
+ * will be identical to those of the leader, so we only publish one
+ * set.
+ */
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
values[n++] = enabled;
if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
values[n++] = running;
- values[n++] = count;
+
+ /*
+ * Write {count,id} tuples for every sibling.
+ */
+ values[n++] += count;
if (read_format & PERF_FORMAT_ID)
values[n++] = primary_event_id(leader);
- size = n * sizeof(u64);
-
- if (copy_to_user(buf, values, size))
- return -EFAULT;
-
- ret = size;
+ raw_spin_lock_irqsave(&ctx->lock, flags);
list_for_each_entry(sub, &leader->sibling_list, group_entry) {
- n = 0;
-
values[n++] = perf_event_read_value(sub, &enabled, &running);
if (read_format & PERF_FORMAT_ID)
values[n++] = primary_event_id(sub);
-
- size = n * sizeof(u64);
-
- if (copy_to_user(buf + ret, values, size)) {
- return -EFAULT;
- }
-
- ret += size;
}
+ raw_spin_unlock_irqrestore(&ctx->lock, flags);
+}
+
+static int perf_event_read_group(struct perf_event *event,
+ u64 read_format, char __user *buf)
+{
+ struct perf_event *leader = event->group_leader, *child;
+ struct perf_event_context *ctx = leader->ctx;
+ int ret = event->read_size;
+ u64 *values;
+
+ lockdep_assert_held(&ctx->mutex);
+
+ values = kzalloc(event->read_size, GFP_KERNEL);
+ if (!values)
+ return -ENOMEM;
+
+ values[0] = 1 + leader->nr_siblings;
+
+ /*
+ * By locking the child_mutex of the leader we effectively
+ * lock the child list of all siblings.. XXX explain how.
+ */
+ mutex_lock(&leader->child_mutex);
+
+ __perf_read_group_add(leader, read_format, values);
+ list_for_each_entry(child, &leader->child_list, child_list)
+ __perf_read_group_add(child, read_format, values);
+
+ mutex_unlock(&leader->child_mutex);
+
+ if (copy_to_user(buf, values, event->read_size))
+ ret = -EFAULT;
+
+ kfree(values);
+
return ret;
}
@@ -6090,7 +6117,6 @@
__perf_event_init_context(&cpuctx->ctx);
lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex);
lockdep_set_class(&cpuctx->ctx.lock, &cpuctx_lock);
- cpuctx->ctx.type = cpu_context;
cpuctx->ctx.pmu = pmu;
cpuctx->jiffies_interval = 1;
INIT_LIST_HEAD(&cpuctx->rotation_list);
@@ -6667,16 +6693,27 @@
if (group_leader->group_leader != group_leader)
goto err_context;
/*
- * Do not allow to attach to a group in a different
- * task or CPU context:
+ * Make sure we're both events for the same CPU;
+ * grouping events for different CPUs is broken; since
+ * you can never concurrently schedule them anyhow.
*/
- if (move_group) {
- if (group_leader->ctx->type != ctx->type)
- goto err_context;
- } else {
- if (group_leader->ctx != ctx)
- goto err_context;
- }
+ if (group_leader->cpu != event->cpu)
+ goto err_context;
+
+ /*
+ * Make sure we're both on the same task, or both
+ * per-CPU events.
+ */
+ if (group_leader->ctx->task != ctx->task)
+ goto err_context;
+
+ /*
+ * Do not allow to attach to a group in a different task
+ * or CPU context. If we're moving SW events, we'll fix
+ * this up later, so allow that.
+ */
+ if (!move_group && group_leader->ctx != ctx)
+ goto err_context;
/*
* Only a group leader can be exclusive or pinned
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index d6e6caf..94ef2af 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1009,7 +1009,6 @@
if (flags & FOLL_GET)
get_page_foll(page);
-out:
return page;
}
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index c8e4ebe..1ea67ad 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -885,11 +885,6 @@
*policy |= (pol->flags & MPOL_MODE_FLAGS);
}
- if (vma) {
- up_read(¤t->mm->mmap_sem);
- vma = NULL;
- }
-
err = 0;
if (nmask) {
if (mpol_store_user_nodemask(pol)) {
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index bd02179..0ce66f7 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -58,6 +58,7 @@
#include <linux/memcontrol.h>
#include <linux/prefetch.h>
#include <linux/locallock.h>
+#include <linux/nmi.h>
#include <asm/tlbflush.h>
#include <asm/div64.h>
@@ -1174,9 +1175,14 @@
#ifdef CONFIG_HIBERNATION
+/*
+ * Touch the watchdog for every WD_PAGE_COUNT pages.
+ */
+#define WD_PAGE_COUNT (128*1024)
+
void mark_free_pages(struct zone *zone)
{
- unsigned long pfn, max_zone_pfn;
+ unsigned long pfn, max_zone_pfn, page_count = WD_PAGE_COUNT;
unsigned long flags;
int order, t;
struct list_head *curr;
@@ -1191,6 +1197,11 @@
if (pfn_valid(pfn)) {
struct page *page = pfn_to_page(pfn);
+ if (!--page_count) {
+ touch_nmi_watchdog();
+ page_count = WD_PAGE_COUNT;
+ }
+
if (!swsusp_page_is_forbidden(page))
swsusp_unset_page_free(page);
}
@@ -1200,8 +1211,13 @@
unsigned long i;
pfn = page_to_pfn(list_entry(curr, struct page, lru));
- for (i = 0; i < (1UL << order); i++)
+ for (i = 0; i < (1UL << order); i++) {
+ if (!--page_count) {
+ touch_nmi_watchdog();
+ page_count = WD_PAGE_COUNT;
+ }
swsusp_set_page_free(pfn_to_page(pfn + i));
+ }
}
}
spin_unlock_irqrestore(&zone->lock, flags);
diff --git a/net/dccp/probe.c b/net/dccp/probe.c
index 33d0e62..0a8d6eb 100644
--- a/net/dccp/probe.c
+++ b/net/dccp/probe.c
@@ -152,6 +152,17 @@
.llseek = noop_llseek,
};
+static __init int setup_jprobe(void)
+{
+ int ret = register_jprobe(&dccp_send_probe);
+
+ if (ret) {
+ request_module("dccp");
+ ret = register_jprobe(&dccp_send_probe);
+ }
+ return ret;
+}
+
static __init int dccpprobe_init(void)
{
int ret = -ENOMEM;
@@ -163,8 +174,7 @@
if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops))
goto err0;
- try_then_request_module((ret = register_jprobe(&dccp_send_probe)) == 0,
- "dccp");
+ ret = setup_jprobe();
if (ret)
goto err1;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 76784c7..003a814 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -1128,13 +1128,14 @@
void __init ip_fib_init(void)
{
- rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL, NULL);
- rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL, NULL);
- rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib, NULL);
+ fib_trie_init();
register_pernet_subsys(&fib_net_ops);
+
register_netdevice_notifier(&fib_netdev_notifier);
register_inetaddr_notifier(&fib_inetaddr_notifier);
- fib_trie_init();
+ rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL, NULL);
+ rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL, NULL);
+ rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib, NULL);
}
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index cd4f45b..9d74f44 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4284,7 +4284,7 @@
* our DAD process, so we don't need
* to do it again
*/
- if (!(ifp->rt->rt6i_node))
+ if (!rcu_access_pointer(ifp->rt->rt6i_node))
ip6_ins_rt(ifp->rt);
if (ifp->idev->cnf.forwarding)
addrconf_join_anycast(ifp);
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 785e62d..8b1f0f9 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -153,11 +153,23 @@
return fn;
}
-static __inline__ void node_free(struct fib6_node * fn)
+static void node_free_immediate(struct fib6_node *fn)
{
kmem_cache_free(fib6_node_kmem, fn);
}
+static void node_free_rcu(struct rcu_head *head)
+{
+ struct fib6_node *fn = container_of(head, struct fib6_node, rcu);
+
+ kmem_cache_free(fib6_node_kmem, fn);
+}
+
+static void node_free(struct fib6_node *fn)
+{
+ call_rcu(&fn->rcu, node_free_rcu);
+}
+
static __inline__ void rt6_release(struct rt6_info *rt)
{
if (atomic_dec_and_test(&rt->rt6i_ref))
@@ -529,9 +541,9 @@
if (in == NULL || ln == NULL) {
if (in)
- node_free(in);
+ node_free_immediate(in);
if (ln)
- node_free(ln);
+ node_free_immediate(ln);
return NULL;
}
@@ -658,7 +670,7 @@
rt->dst.rt6_next = iter;
*ins = rt;
- rt->rt6i_node = fn;
+ rcu_assign_pointer(rt->rt6i_node, fn);
atomic_inc(&rt->rt6i_ref);
inet6_rt_notify(RTM_NEWROUTE, rt, info);
info->nl_net->ipv6.rt6_stats->fib_rt_entries++;
@@ -743,7 +755,7 @@
root, and then (in st_failure) stale node
in main tree.
*/
- node_free(sfn);
+ node_free_immediate(sfn);
goto st_failure;
}
@@ -1169,8 +1181,9 @@
int fib6_del(struct rt6_info *rt, struct nl_info *info)
{
+ struct fib6_node *fn = rcu_dereference_protected(rt->rt6i_node,
+ lockdep_is_held(&rt->rt6i_table->tb6_lock));
struct net *net = info->nl_net;
- struct fib6_node *fn = rt->rt6i_node;
struct rt6_info **rtp;
#if RT6_DEBUG >= 2
@@ -1348,7 +1361,10 @@
res = fib6_del(rt, &info);
if (res) {
#if RT6_DEBUG >= 2
- printk(KERN_DEBUG "fib6_clean_node: del failed: rt=%p@%p err=%d\n", rt, rt->rt6i_node, res);
+ pr_debug("%s: del failed: rt=%p@%p err=%d\n",
+ __func__, rt,
+ rcu_access_pointer(rt->rt6i_node),
+ res);
#endif
continue;
}
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index a2a0852..c7568ce 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -568,7 +568,6 @@
while (offset <= packet_len) {
struct ipv6_opt_hdr *exthdr;
- unsigned int len;
switch (**nexthdr) {
@@ -594,10 +593,9 @@
exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) +
offset);
- len = ipv6_optlen(exthdr);
- if (len + offset >= IPV6_MAXPLEN)
+ offset += ipv6_optlen(exthdr);
+ if (offset > IPV6_MAXPLEN)
return -EINVAL;
- offset += len;
*nexthdr = &exthdr->nexthdr;
}
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 2b4b4e3..55f5a1a 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -143,7 +143,7 @@
static inline void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst)
{
struct rt6_info *rt = (struct rt6_info *) dst;
- t->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
+ t->dst_cookie = rt6_get_cookie(rt);
dst_release(t->dst_cache);
t->dst_cache = dst;
}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index cda5cfe..6fc91f9 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -964,10 +964,11 @@
static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
{
struct rt6_info *rt;
+ u32 rt_cookie = 0;
rt = (struct rt6_info *) dst;
- if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) {
+ if (rt6_get_cookie_safe(rt, &rt_cookie) && rt_cookie == cookie) {
if (rt->rt6i_peer_genid != rt6_peer_genid()) {
if (!rt->rt6i_peer)
rt6_bind_peer(rt, 0);
@@ -1007,8 +1008,15 @@
if (rt->rt6i_flags&RTF_CACHE) {
dst_set_expires(&rt->dst, 0);
rt->rt6i_flags |= RTF_EXPIRES;
- } else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT))
- rt->rt6i_node->fn_sernum = -1;
+ } else {
+ struct fib6_node *fn;
+
+ rcu_read_lock();
+ fn = rcu_dereference(rt->rt6i_node);
+ if (fn && (rt->rt6i_flags & RTF_DEFAULT))
+ fn->fn_sernum = -1;
+ rcu_read_unlock();
+ }
}
}
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index db78e7d..353ce00 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -78,8 +78,7 @@
{
if (dst->ops->family == AF_INET6) {
struct rt6_info *rt = (struct rt6_info*)dst;
- if (rt->rt6i_node)
- path->path_cookie = rt->rt6i_node->fn_sernum;
+ path->path_cookie = rt6_get_cookie(rt);
}
path->u.rt6.rt6i_nfheader_len = nfheader_len;
@@ -111,8 +110,7 @@
RTF_LOCAL);
xdst->u.rt6.rt6i_metric = rt->rt6i_metric;
xdst->u.rt6.rt6i_node = rt->rt6i_node;
- if (rt->rt6i_node)
- xdst->route_cookie = rt->rt6i_node->fn_sernum;
+ xdst->route_cookie = rt6_get_cookie(rt);
xdst->u.rt6.rt6i_gateway = rt->rt6i_gateway;
xdst->u.rt6.rt6i_dst = rt->rt6i_dst;
xdst->u.rt6.rt6i_src = rt->rt6i_src;
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 35fc5ba..c839f2d 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -225,7 +225,7 @@
#define BROADCAST_ONE 1
#define BROADCAST_REGISTERED 2
#define BROADCAST_PROMISC_ONLY 4
-static int pfkey_broadcast(struct sk_buff *skb,
+static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
int broadcast_flags, struct sock *one_sk,
struct net *net)
{
@@ -276,7 +276,7 @@
rcu_read_unlock();
if (one_sk != NULL)
- err = pfkey_broadcast_one(skb, &skb2, GFP_KERNEL, one_sk);
+ err = pfkey_broadcast_one(skb, &skb2, allocation, one_sk);
kfree_skb(skb2);
kfree_skb(skb);
@@ -309,7 +309,7 @@
hdr = (struct sadb_msg *) pfk->dump.skb->data;
hdr->sadb_msg_seq = 0;
hdr->sadb_msg_errno = rc;
- pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE,
+ pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
&pfk->sk, sock_net(&pfk->sk));
pfk->dump.skb = NULL;
}
@@ -353,7 +353,7 @@
hdr->sadb_msg_len = (sizeof(struct sadb_msg) /
sizeof(uint64_t));
- pfkey_broadcast(skb, BROADCAST_ONE, sk, sock_net(sk));
+ pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ONE, sk, sock_net(sk));
return 0;
}
@@ -1388,7 +1388,7 @@
xfrm_state_put(x);
- pfkey_broadcast(resp_skb, BROADCAST_ONE, sk, net);
+ pfkey_broadcast(resp_skb, GFP_KERNEL, BROADCAST_ONE, sk, net);
return 0;
}
@@ -1476,7 +1476,7 @@
hdr->sadb_msg_seq = c->seq;
hdr->sadb_msg_pid = c->pid;
- pfkey_broadcast(skb, BROADCAST_ALL, NULL, xs_net(x));
+ pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xs_net(x));
return 0;
}
@@ -1593,7 +1593,7 @@
out_hdr->sadb_msg_reserved = 0;
out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
- pfkey_broadcast(out_skb, BROADCAST_ONE, sk, sock_net(sk));
+ pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, sock_net(sk));
return 0;
}
@@ -1694,8 +1694,8 @@
return -ENOBUFS;
}
- pfkey_broadcast(supp_skb, BROADCAST_REGISTERED, sk, sock_net(sk));
-
+ pfkey_broadcast(supp_skb, GFP_KERNEL, BROADCAST_REGISTERED, sk,
+ sock_net(sk));
return 0;
}
@@ -1713,7 +1713,8 @@
hdr->sadb_msg_errno = (uint8_t) 0;
hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
- return pfkey_broadcast(skb, BROADCAST_ONE, sk, sock_net(sk));
+ return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ONE, sk,
+ sock_net(sk));
}
static int key_notify_sa_flush(const struct km_event *c)
@@ -1734,7 +1735,7 @@
hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
hdr->sadb_msg_reserved = 0;
- pfkey_broadcast(skb, BROADCAST_ALL, NULL, c->net);
+ pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net);
return 0;
}
@@ -1795,7 +1796,7 @@
out_hdr->sadb_msg_pid = pfk->dump.msg_pid;
if (pfk->dump.skb)
- pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE,
+ pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
&pfk->sk, sock_net(&pfk->sk));
pfk->dump.skb = out_skb;
@@ -1862,7 +1863,7 @@
new_hdr->sadb_msg_errno = 0;
}
- pfkey_broadcast(skb, BROADCAST_ALL, NULL, sock_net(sk));
+ pfkey_broadcast(skb, GFP_KERNEL, BROADCAST_ALL, NULL, sock_net(sk));
return 0;
}
@@ -2193,7 +2194,7 @@
out_hdr->sadb_msg_errno = 0;
out_hdr->sadb_msg_seq = c->seq;
out_hdr->sadb_msg_pid = c->pid;
- pfkey_broadcast(out_skb, BROADCAST_ALL, NULL, xp_net(xp));
+ pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ALL, NULL, xp_net(xp));
return 0;
}
@@ -2419,7 +2420,7 @@
out_hdr->sadb_msg_errno = 0;
out_hdr->sadb_msg_seq = hdr->sadb_msg_seq;
out_hdr->sadb_msg_pid = hdr->sadb_msg_pid;
- pfkey_broadcast(out_skb, BROADCAST_ONE, sk, xp_net(xp));
+ pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, sk, xp_net(xp));
err = 0;
out:
@@ -2672,7 +2673,7 @@
out_hdr->sadb_msg_pid = pfk->dump.msg_pid;
if (pfk->dump.skb)
- pfkey_broadcast(pfk->dump.skb, BROADCAST_ONE,
+ pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
&pfk->sk, sock_net(&pfk->sk));
pfk->dump.skb = out_skb;
@@ -2727,7 +2728,7 @@
hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC;
hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t));
hdr->sadb_msg_reserved = 0;
- pfkey_broadcast(skb_out, BROADCAST_ALL, NULL, c->net);
+ pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net);
return 0;
}
@@ -2793,7 +2794,7 @@
void *ext_hdrs[SADB_EXT_MAX];
int err;
- pfkey_broadcast(skb_clone(skb, GFP_KERNEL),
+ pfkey_broadcast(skb_clone(skb, GFP_KERNEL), GFP_KERNEL,
BROADCAST_PROMISC_ONLY, NULL, sock_net(sk));
memset(ext_hdrs, 0, sizeof(ext_hdrs));
@@ -2999,7 +3000,8 @@
out_hdr->sadb_msg_seq = 0;
out_hdr->sadb_msg_pid = 0;
- pfkey_broadcast(out_skb, BROADCAST_REGISTERED, NULL, xs_net(x));
+ pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL,
+ xs_net(x));
return 0;
}
@@ -3171,7 +3173,8 @@
xfrm_ctx->ctx_len);
}
- return pfkey_broadcast(skb, BROADCAST_REGISTERED, NULL, xs_net(x));
+ return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL,
+ xs_net(x));
}
static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt,
@@ -3369,7 +3372,8 @@
n_port->sadb_x_nat_t_port_port = sport;
n_port->sadb_x_nat_t_port_reserved = 0;
- return pfkey_broadcast(skb, BROADCAST_REGISTERED, NULL, xs_net(x));
+ return pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_REGISTERED, NULL,
+ xs_net(x));
}
#ifdef CONFIG_NET_KEY_MIGRATE
@@ -3561,7 +3565,7 @@
}
/* broadcast migrate message to sockets */
- pfkey_broadcast(skb, BROADCAST_ALL, NULL, &init_net);
+ pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL, &init_net);
return 0;
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 3954b18..b539c78 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -112,10 +112,9 @@
};
static void l2tp_session_set_header_len(struct l2tp_session *session, int version);
-static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel);
static void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel);
-static inline struct l2tp_net *l2tp_pernet(struct net *net)
+static inline struct l2tp_net *l2tp_pernet(const struct net *net)
{
BUG_ON(!net);
@@ -123,33 +122,6 @@
}
-/* Tunnel reference counts. Incremented per session that is added to
- * the tunnel.
- */
-static inline void l2tp_tunnel_inc_refcount_1(struct l2tp_tunnel *tunnel)
-{
- atomic_inc(&tunnel->ref_count);
-}
-
-static inline void l2tp_tunnel_dec_refcount_1(struct l2tp_tunnel *tunnel)
-{
- if (atomic_dec_and_test(&tunnel->ref_count))
- l2tp_tunnel_free(tunnel);
-}
-#ifdef L2TP_REFCNT_DEBUG
-#define l2tp_tunnel_inc_refcount(_t) do { \
- printk(KERN_DEBUG "l2tp_tunnel_inc_refcount: %s:%d %s: cnt=%d\n", __func__, __LINE__, (_t)->name, atomic_read(&_t->ref_count)); \
- l2tp_tunnel_inc_refcount_1(_t); \
- } while (0)
-#define l2tp_tunnel_dec_refcount(_t) do { \
- printk(KERN_DEBUG "l2tp_tunnel_dec_refcount: %s:%d %s: cnt=%d\n", __func__, __LINE__, (_t)->name, atomic_read(&_t->ref_count)); \
- l2tp_tunnel_dec_refcount_1(_t); \
- } while (0)
-#else
-#define l2tp_tunnel_inc_refcount(t) l2tp_tunnel_inc_refcount_1(t)
-#define l2tp_tunnel_dec_refcount(t) l2tp_tunnel_dec_refcount_1(t)
-#endif
-
/* Session hash global list for L2TPv3.
* The session_id SHOULD be random according to RFC3931, but several
* L2TP implementations use incrementing session_ids. So we do a real
@@ -225,10 +197,31 @@
}
EXPORT_SYMBOL_GPL(l2tp_session_find);
+/* Lookup a tunnel. A new reference is held on the returned tunnel. */
+struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id)
+{
+ const struct l2tp_net *pn = l2tp_pernet(net);
+ struct l2tp_tunnel *tunnel;
+
+ rcu_read_lock_bh();
+ list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) {
+ if (tunnel->tunnel_id == tunnel_id) {
+ l2tp_tunnel_inc_refcount(tunnel);
+ rcu_read_unlock_bh();
+
+ return tunnel;
+ }
+ }
+ rcu_read_unlock_bh();
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(l2tp_tunnel_get);
+
/* Like l2tp_session_find() but takes a reference on the returned session.
* Optionally calls session->ref() too if do_ref is true.
*/
-struct l2tp_session *l2tp_session_get(struct net *net,
+struct l2tp_session *l2tp_session_get(const struct net *net,
struct l2tp_tunnel *tunnel,
u32 session_id, bool do_ref)
{
@@ -305,7 +298,8 @@
/* Lookup a session by interface name.
* This is very inefficient but is only used by management interfaces.
*/
-struct l2tp_session *l2tp_session_get_by_ifname(struct net *net, char *ifname,
+struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net,
+ const char *ifname,
bool do_ref)
{
struct l2tp_net *pn = l2tp_pernet(net);
@@ -1340,7 +1334,7 @@
/* Really kill the tunnel.
* Come here only when all sessions have been cleared from the tunnel.
*/
-static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel)
+void l2tp_tunnel_free(struct l2tp_tunnel *tunnel)
{
struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);
@@ -1358,6 +1352,7 @@
atomic_dec(&l2tp_tunnel_count);
}
+EXPORT_SYMBOL_GPL(l2tp_tunnel_free);
/* Create a socket for the tunnel, if one isn't set up by
* userspace. This is used for static tunnels where there is no
@@ -1715,6 +1710,8 @@
l2tp_session_set_header_len(session, tunnel->version);
+ l2tp_session_inc_refcount(session);
+
err = l2tp_session_add_to_tunnel(tunnel, session);
if (err) {
kfree(session);
@@ -1722,10 +1719,6 @@
return ERR_PTR(err);
}
- /* Bump the reference count. The session context is deleted
- * only when this drops to zero.
- */
- l2tp_session_inc_refcount(session);
l2tp_tunnel_inc_refcount(tunnel);
/* Ensure tunnel socket isn't deleted */
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index 1caf21e..2066d23 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -222,13 +222,17 @@
return tunnel;
}
-struct l2tp_session *l2tp_session_get(struct net *net,
+struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id);
+void l2tp_tunnel_free(struct l2tp_tunnel *tunnel);
+
+struct l2tp_session *l2tp_session_get(const struct net *net,
struct l2tp_tunnel *tunnel,
u32 session_id, bool do_ref);
extern struct l2tp_session *l2tp_session_find(struct net *net, struct l2tp_tunnel *tunnel, u32 session_id);
struct l2tp_session *l2tp_session_get_nth(struct l2tp_tunnel *tunnel, int nth,
bool do_ref);
-struct l2tp_session *l2tp_session_get_by_ifname(struct net *net, char *ifname,
+struct l2tp_session *l2tp_session_get_by_ifname(const struct net *net,
+ const char *ifname,
bool do_ref);
extern struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id);
extern struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth);
@@ -247,6 +251,17 @@
extern void l2tp_nl_unregister_ops(enum l2tp_pwtype pw_type);
int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg);
+static inline void l2tp_tunnel_inc_refcount(struct l2tp_tunnel *tunnel)
+{
+ atomic_inc(&tunnel->ref_count);
+}
+
+static inline void l2tp_tunnel_dec_refcount(struct l2tp_tunnel *tunnel)
+{
+ if (atomic_dec_and_test(&tunnel->ref_count))
+ l2tp_tunnel_free(tunnel);
+}
+
/* Session reference counts. Incremented when code obtains a reference
* to a session.
*/
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index 6fd6322..aefb6a2 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -57,10 +57,12 @@
(info->attrs[L2TP_ATTR_CONN_ID])) {
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
- tunnel = l2tp_tunnel_find(net, tunnel_id);
- if (tunnel)
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
+ if (tunnel) {
session = l2tp_session_get(net, tunnel, session_id,
do_ref);
+ l2tp_tunnel_dec_refcount(tunnel);
+ }
}
return session;
@@ -182,14 +184,16 @@
}
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
- tunnel = l2tp_tunnel_find(net, tunnel_id);
- if (tunnel == NULL) {
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
+ if (!tunnel) {
ret = -ENODEV;
goto out;
}
(void) l2tp_tunnel_delete(tunnel);
+ l2tp_tunnel_dec_refcount(tunnel);
+
out:
return ret;
}
@@ -207,8 +211,8 @@
}
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
- tunnel = l2tp_tunnel_find(net, tunnel_id);
- if (tunnel == NULL) {
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
+ if (!tunnel) {
ret = -ENODEV;
goto out;
}
@@ -216,6 +220,8 @@
if (info->attrs[L2TP_ATTR_DEBUG])
tunnel->debug = nla_get_u32(info->attrs[L2TP_ATTR_DEBUG]);
+ l2tp_tunnel_dec_refcount(tunnel);
+
out:
return ret;
}
@@ -289,34 +295,37 @@
if (!info->attrs[L2TP_ATTR_CONN_ID]) {
ret = -EINVAL;
- goto out;
+ goto err;
}
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
- tunnel = l2tp_tunnel_find(net, tunnel_id);
- if (tunnel == NULL) {
- ret = -ENODEV;
- goto out;
- }
-
msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (!msg) {
ret = -ENOMEM;
- goto out;
+ goto err;
+ }
+
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
+ if (!tunnel) {
+ ret = -ENODEV;
+ goto err_nlmsg;
}
ret = l2tp_nl_tunnel_send(msg, info->snd_pid, info->snd_seq,
NLM_F_ACK, tunnel);
if (ret < 0)
- goto err_out;
+ goto err_nlmsg_tunnel;
+
+ l2tp_tunnel_dec_refcount(tunnel);
return genlmsg_unicast(net, msg, info->snd_pid);
-err_out:
+err_nlmsg_tunnel:
+ l2tp_tunnel_dec_refcount(tunnel);
+err_nlmsg:
nlmsg_free(msg);
-
-out:
+err:
return ret;
}
@@ -352,7 +361,6 @@
u32 peer_session_id;
int ret = 0;
struct l2tp_tunnel *tunnel;
- struct l2tp_session *session;
struct l2tp_session_cfg cfg = { 0, };
struct net *net = genl_info_net(info);
@@ -360,8 +368,9 @@
ret = -EINVAL;
goto out;
}
+
tunnel_id = nla_get_u32(info->attrs[L2TP_ATTR_CONN_ID]);
- tunnel = l2tp_tunnel_find(net, tunnel_id);
+ tunnel = l2tp_tunnel_get(net, tunnel_id);
if (!tunnel) {
ret = -ENODEV;
goto out;
@@ -369,29 +378,24 @@
if (!info->attrs[L2TP_ATTR_SESSION_ID]) {
ret = -EINVAL;
- goto out;
+ goto out_tunnel;
}
session_id = nla_get_u32(info->attrs[L2TP_ATTR_SESSION_ID]);
- session = l2tp_session_find(net, tunnel, session_id);
- if (session) {
- ret = -EEXIST;
- goto out;
- }
if (!info->attrs[L2TP_ATTR_PEER_SESSION_ID]) {
ret = -EINVAL;
- goto out;
+ goto out_tunnel;
}
peer_session_id = nla_get_u32(info->attrs[L2TP_ATTR_PEER_SESSION_ID]);
if (!info->attrs[L2TP_ATTR_PW_TYPE]) {
ret = -EINVAL;
- goto out;
+ goto out_tunnel;
}
cfg.pw_type = nla_get_u16(info->attrs[L2TP_ATTR_PW_TYPE]);
if (cfg.pw_type >= __L2TP_PWTYPE_MAX) {
ret = -EINVAL;
- goto out;
+ goto out_tunnel;
}
if (tunnel->version > 2) {
@@ -413,7 +417,7 @@
u16 len = nla_len(info->attrs[L2TP_ATTR_COOKIE]);
if (len > 8) {
ret = -EINVAL;
- goto out;
+ goto out_tunnel;
}
cfg.cookie_len = len;
memcpy(&cfg.cookie[0], nla_data(info->attrs[L2TP_ATTR_COOKIE]), len);
@@ -422,7 +426,7 @@
u16 len = nla_len(info->attrs[L2TP_ATTR_PEER_COOKIE]);
if (len > 8) {
ret = -EINVAL;
- goto out;
+ goto out_tunnel;
}
cfg.peer_cookie_len = len;
memcpy(&cfg.peer_cookie[0], nla_data(info->attrs[L2TP_ATTR_PEER_COOKIE]), len);
@@ -458,7 +462,7 @@
if ((l2tp_nl_cmd_ops[cfg.pw_type] == NULL) ||
(l2tp_nl_cmd_ops[cfg.pw_type]->session_create == NULL)) {
ret = -EPROTONOSUPPORT;
- goto out;
+ goto out_tunnel;
}
/* Check that pseudowire-specific params are present */
@@ -468,7 +472,7 @@
case L2TP_PWTYPE_ETH_VLAN:
if (!info->attrs[L2TP_ATTR_VLAN_ID]) {
ret = -EINVAL;
- goto out;
+ goto out_tunnel;
}
break;
case L2TP_PWTYPE_ETH:
@@ -487,6 +491,8 @@
ret = (*l2tp_nl_cmd_ops[cfg.pw_type]->session_create)(net, tunnel_id,
session_id, peer_session_id, &cfg);
+out_tunnel:
+ l2tp_tunnel_dec_refcount(tunnel);
out:
return ret;
}
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index fb02ea5..f2bdd6f 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -3,6 +3,7 @@
* Copyright 2005-2006, Devicescape Software, Inc.
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
* Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2017 Intel Deutschland GmbH
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -456,9 +457,6 @@
pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE;
idx = key->conf.keyidx;
- key->local = sdata->local;
- key->sdata = sdata;
- key->sta = sta;
if (sta) {
/*
@@ -495,6 +493,21 @@
else
old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]);
+ /*
+ * Silently accept key re-installation without really installing the
+ * new version of the key to avoid nonce reuse or replay issues.
+ */
+ if (old_key && key->conf.keylen == old_key->conf.keylen &&
+ !memcmp(key->conf.key, old_key->conf.key, key->conf.keylen)) {
+ __ieee80211_key_free(key);
+ ret = 0;
+ goto out;
+ }
+
+ key->local = sdata->local;
+ key->sdata = sdata;
+ key->sta = sta;
+
increment_tailroom_need_count(sdata);
__ieee80211_key_replace(sdata, sta, pairwise, old_key, key);
@@ -504,6 +517,7 @@
ret = ieee80211_key_enable_hw_accel(key);
+ out:
mutex_unlock(&sdata->local->key_mtx);
return ret;
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index cc8f8b4..a6cbb7a 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -272,7 +272,7 @@
return NULL;
}
rt = (struct rt6_info *) dst;
- cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
+ cookie = rt6_get_cookie(rt);
__ip_vs_dst_set(dest, 0, dst_clone(&rt->dst), cookie);
IP_VS_DBG(10, "new dst %pI6, src %pI6, refcnt=%d\n",
&dest->addr.in6, &dest->dst_saddr.in6,
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c
index c4706be..1baf173 100644
--- a/net/netfilter/xt_socket.c
+++ b/net/netfilter/xt_socket.c
@@ -108,9 +108,9 @@
const struct iphdr *iph = ip_hdr(skb);
struct udphdr _hdr, *hp = NULL;
struct sock *sk;
- __be32 daddr, saddr;
- __be16 dport, sport;
- u8 protocol;
+ __be32 uninitialized_var(daddr), uninitialized_var(saddr);
+ __be16 uninitialized_var(dport), uninitialized_var(sport);
+ u8 uninitialized_var(protocol);
#ifdef XT_SOCKET_HAVE_CONNTRACK
struct nf_conn const *ct;
enum ip_conntrack_info ctinfo;
@@ -263,9 +263,9 @@
struct ipv6hdr ipv6_var, *iph = ipv6_hdr(skb);
struct udphdr _hdr, *hp = NULL;
struct sock *sk;
- const struct in6_addr *daddr, *saddr;
- __be16 dport, sport;
- int thoff, tproto;
+ const struct in6_addr *daddr = NULL, *saddr = NULL;
+ __be16 uninitialized_var(dport), uninitialized_var(sport);
+ int thoff, uninitialized_var(tproto);
const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo;
tproto = ipv6_find_hdr(skb, &thoff, -1, NULL);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 7e3661b..3433582 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1295,10 +1295,6 @@
mutex_lock(&fanout_mutex);
- err = -EINVAL;
- if (!po->running)
- goto out;
-
err = -EALREADY;
if (po->fanout)
goto out;
@@ -1335,7 +1331,10 @@
list_add(&match->list, &fanout_list);
}
err = -EINVAL;
- if (match->type == type &&
+
+ spin_lock(&po->bind_lock);
+ if (po->running &&
+ match->type == type &&
match->prot_hook.type == po->prot_hook.type &&
match->prot_hook.dev == po->prot_hook.dev) {
err = -ENOSPC;
@@ -1347,6 +1346,13 @@
err = 0;
}
}
+ spin_unlock(&po->bind_lock);
+
+ if (err && !atomic_read(&match->sk_ref)) {
+ list_del(&match->list);
+ kfree(match);
+ }
+
out:
mutex_unlock(&fanout_mutex);
return err;
@@ -2469,33 +2475,72 @@
* Attach a packet hook.
*/
-static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protocol)
+static int packet_do_bind(struct sock *sk, const char *name, int ifindex,
+ __be16 protocol)
{
struct packet_sock *po = pkt_sk(sk);
-
- if (po->fanout) {
- if (dev)
- dev_put(dev);
-
- return -EINVAL;
- }
+ struct net_device *dev_curr;
+ struct net_device *dev = NULL;
+ int ret = 0;
+ bool unlisted = false;
lock_sock(sk);
spin_lock(&po->bind_lock);
- unregister_prot_hook(sk, true);
+ rcu_read_lock();
+
+ if (po->fanout) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ if (name) {
+ dev = dev_get_by_name_rcu(sock_net(sk), name);
+ if (!dev) {
+ ret = -ENODEV;
+ goto out_unlock;
+ }
+ } else if (ifindex) {
+ dev = dev_get_by_index_rcu(sock_net(sk), ifindex);
+ if (!dev) {
+ ret = -ENODEV;
+ goto out_unlock;
+ }
+ }
+
+ if (dev)
+ dev_hold(dev);
+
+ dev_curr = po->prot_hook.dev;
+
+ if (po->running) {
+ rcu_read_unlock();
+ __unregister_prot_hook(sk, true);
+ rcu_read_lock();
+ dev_curr = po->prot_hook.dev;
+ if (dev)
+ unlisted = !dev_get_by_index_rcu(sock_net(sk),
+ dev->ifindex);
+ }
po->num = protocol;
po->prot_hook.type = protocol;
- if (po->prot_hook.dev)
- dev_put(po->prot_hook.dev);
- po->prot_hook.dev = dev;
- po->ifindex = dev ? dev->ifindex : 0;
+ if (unlikely(unlisted)) {
+ dev_put(dev);
+ po->prot_hook.dev = NULL;
+ po->ifindex = -1;
+ } else {
+ po->prot_hook.dev = dev;
+ po->ifindex = dev ? dev->ifindex : 0;
+ }
+
+ if (dev_curr)
+ dev_put(dev_curr);
if (protocol == 0)
goto out_unlock;
- if (!dev || (dev->flags & IFF_UP)) {
+ if (!unlisted && (!dev || (dev->flags & IFF_UP))) {
register_prot_hook(sk);
} else {
sk->sk_err = ENETDOWN;
@@ -2504,9 +2549,10 @@
}
out_unlock:
+ rcu_read_unlock();
spin_unlock(&po->bind_lock);
release_sock(sk);
- return 0;
+ return ret;
}
/*
@@ -2518,8 +2564,6 @@
{
struct sock *sk = sock->sk;
char name[15];
- struct net_device *dev;
- int err = -ENODEV;
/*
* Check legality
@@ -2529,19 +2573,13 @@
return -EINVAL;
strlcpy(name, uaddr->sa_data, sizeof(name));
- dev = dev_get_by_name(sock_net(sk), name);
- if (dev)
- err = packet_do_bind(sk, dev, pkt_sk(sk)->num);
- return err;
+ return packet_do_bind(sk, name, 0, pkt_sk(sk)->num);
}
static int packet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
struct sockaddr_ll *sll = (struct sockaddr_ll *)uaddr;
struct sock *sk = sock->sk;
- struct net_device *dev = NULL;
- int err;
-
/*
* Check legality
@@ -2552,16 +2590,8 @@
if (sll->sll_family != AF_PACKET)
return -EINVAL;
- if (sll->sll_ifindex) {
- err = -ENODEV;
- dev = dev_get_by_index(sock_net(sk), sll->sll_ifindex);
- if (dev == NULL)
- goto out;
- }
- err = packet_do_bind(sk, dev, sll->sll_protocol ? : pkt_sk(sk)->num);
-
-out:
- return err;
+ return packet_do_bind(sk, NULL, sll->sll_ifindex,
+ sll->sll_protocol ? : pkt_sk(sk)->num);
}
static struct proto packet_proto = {
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index dca6c1a..2751bd8 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -866,6 +866,8 @@
return sch;
}
+ /* ops->init() failed, we call ->destroy() like qdisc_create_dflt() */
+ ops->destroy(sch);
err_out3:
dev_put(dev);
kfree((char *) sch - sch->padded);
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 7f59944..407ffa7 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1367,6 +1367,13 @@
struct tc_ratespec *r;
int err;
+ qdisc_watchdog_init(&q->watchdog, sch);
+ hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+ q->delay_timer.function = cbq_undelay;
+
+ if (!opt)
+ return -EINVAL;
+
err = nla_parse_nested(tb, TCA_CBQ_MAX, opt, cbq_policy);
if (err < 0)
return err;
@@ -1405,9 +1412,6 @@
q->link.avpkt = q->link.allot/2;
q->link.minidle = -0x7FFFFFFF;
- qdisc_watchdog_init(&q->watchdog, sch);
- hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
- q->delay_timer.function = cbq_undelay;
q->toplevel = TC_CBQ_MAXLEVEL;
q->now = psched_get_time();
q->now_rt = q->now;
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index 6b7fe4a..7ce8acc 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -351,7 +351,7 @@
{
struct drr_sched *q = qdisc_priv(sch);
struct drr_class *cl;
- int err;
+ int err = 0;
cl = drr_classify(skb, sch, &err);
if (cl == NULL) {
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 6488e64..a239d0a 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1435,6 +1435,8 @@
struct tc_hfsc_qopt *qopt;
int err;
+ qdisc_watchdog_init(&q->watchdog, sch);
+
if (opt == NULL || nla_len(opt) < sizeof(*qopt))
return -EINVAL;
qopt = nla_data(opt);
@@ -1460,8 +1462,6 @@
qdisc_class_hash_insert(&q->clhash, &q->root.cl_common);
qdisc_class_hash_grow(sch, &q->clhash);
- qdisc_watchdog_init(&q->watchdog, sch);
-
return 0;
}
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 92f0c1f..3f93a5c 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -997,6 +997,9 @@
int err;
int i;
+ qdisc_watchdog_init(&q->watchdog, sch);
+ INIT_WORK(&q->work, htb_work_func);
+
if (!opt)
return -EINVAL;
@@ -1021,8 +1024,6 @@
for (i = 0; i < TC_HTB_NUMPRIO; i++)
INIT_LIST_HEAD(q->drops + i);
- qdisc_watchdog_init(&q->watchdog, sch);
- INIT_WORK(&q->work, htb_work_func);
skb_queue_head_init(&q->direct_queue);
q->direct_qlen = qdisc_dev(sch)->tx_queue_len;
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index 0a4b2f9..7cf451f 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -52,7 +52,7 @@
/* pre-allocate qdiscs, attachment can't fail */
priv->qdiscs = kcalloc(dev->num_tx_queues, sizeof(priv->qdiscs[0]),
GFP_KERNEL);
- if (priv->qdiscs == NULL)
+ if (!priv->qdiscs)
return -ENOMEM;
for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
@@ -60,17 +60,13 @@
qdisc = qdisc_create_dflt(dev_queue, &pfifo_fast_ops,
TC_H_MAKE(TC_H_MAJ(sch->handle),
TC_H_MIN(ntx + 1)));
- if (qdisc == NULL)
- goto err;
+ if (!qdisc)
+ return -ENOMEM;
priv->qdiscs[ntx] = qdisc;
}
sch->flags |= TCQ_F_MQROOT;
return 0;
-
-err:
- mq_destroy(sch);
- return -ENOMEM;
}
static void mq_attach(struct Qdisc *sch)
diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
index 28de430..b4a388b 100644
--- a/net/sched/sch_mqprio.c
+++ b/net/sched/sch_mqprio.c
@@ -117,20 +117,17 @@
/* pre-allocate qdisc, attachment can't fail */
priv->qdiscs = kcalloc(dev->num_tx_queues, sizeof(priv->qdiscs[0]),
GFP_KERNEL);
- if (priv->qdiscs == NULL) {
- err = -ENOMEM;
- goto err;
- }
+ if (!priv->qdiscs)
+ return -ENOMEM;
for (i = 0; i < dev->num_tx_queues; i++) {
dev_queue = netdev_get_tx_queue(dev, i);
qdisc = qdisc_create_dflt(dev_queue, &pfifo_fast_ops,
TC_H_MAKE(TC_H_MAJ(sch->handle),
TC_H_MIN(i + 1)));
- if (qdisc == NULL) {
- err = -ENOMEM;
- goto err;
- }
+ if (!qdisc)
+ return -ENOMEM;
+
priv->qdiscs[i] = qdisc;
}
@@ -142,7 +139,7 @@
priv->hw_owned = 1;
err = dev->netdev_ops->ndo_setup_tc(dev, qopt->num_tc);
if (err)
- goto err;
+ return err;
} else {
netdev_set_num_tc(dev, qopt->num_tc);
for (i = 0; i < qopt->num_tc; i++)
@@ -156,10 +153,6 @@
sch->flags |= TCQ_F_MQROOT;
return 0;
-
-err:
- mqprio_destroy(sch);
- return err;
}
static void mqprio_attach(struct Qdisc *sch)
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index edc1950..a8f8dc1 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -250,7 +250,7 @@
static int multiq_init(struct Qdisc *sch, struct nlattr *opt)
{
struct multiq_sched_data *q = qdisc_priv(sch);
- int i, err;
+ int i;
q->queues = NULL;
@@ -265,12 +265,7 @@
for (i = 0; i < q->max_bands; i++)
q->queues[i] = &noop_qdisc;
- err = multiq_tune(sch, opt);
-
- if (err)
- kfree(q->queues);
-
- return err;
+ return multiq_tune(sch, opt);
}
static int multiq_dump(struct Qdisc *sch, struct sk_buff *skb)
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index a489d8b..5856ce5 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -758,11 +758,11 @@
struct netem_sched_data *q = qdisc_priv(sch);
int ret;
+ qdisc_watchdog_init(&q->watchdog, sch);
+
if (!opt)
return -EINVAL;
- qdisc_watchdog_init(&q->watchdog, sch);
-
q->loss_model = CLG_RANDOM;
q->qdisc = qdisc_create_dflt(sch->dev_queue, &tfifo_qdisc_ops,
TC_H_MAKE(sch->handle, 1));
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index ca0fb48..4ade918 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -846,7 +846,7 @@
struct qfq_sched *q = qdisc_priv(sch);
struct qfq_group *grp;
struct qfq_class *cl;
- int err;
+ int err = 0;
u64 roundedS;
int s;
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 1dcfb52..e24dfbe 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -316,12 +316,13 @@
{
struct tbf_sched_data *q = qdisc_priv(sch);
+ qdisc_watchdog_init(&q->watchdog, sch);
+ q->qdisc = &noop_qdisc;
+
if (opt == NULL)
return -EINVAL;
q->t_c = psched_get_time();
- qdisc_watchdog_init(&q->watchdog, sch);
- q->qdisc = &noop_qdisc;
return tbf_change(sch, opt);
}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index bd26a97..963222e 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1719,6 +1719,7 @@
return -EMSGSIZE;
id = nlmsg_data(nlh);
+ memset(&id->sa_id, 0, sizeof(id->sa_id));
memcpy(&id->sa_id.daddr, &x->id.daddr,sizeof(x->id.daddr));
id->sa_id.spi = x->id.spi;
id->sa_id.family = x->props.family;
@@ -2507,6 +2508,7 @@
struct nlattr *attr;
id = nlmsg_data(nlh);
+ memset(id, 0, sizeof(*id));
memcpy(&id->daddr, &x->id.daddr, sizeof(id->daddr));
id->spi = x->id.spi;
id->family = x->props.family;
diff --git a/security/keys/key.c b/security/keys/key.c
index d3b2f6e..04c809f 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -847,6 +847,16 @@
__key_link_end(keyring, ktype, prealloc);
key_type_put(ktype);
+ key = key_ref_to_ptr(key_ref);
+ if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) {
+ ret = wait_for_key_construction(key, true);
+ if (ret < 0) {
+ key_ref_put(key_ref);
+ key_ref = ERR_PTR(ret);
+ goto error;
+ }
+ }
+
key_ref = __key_update(key_ref, payload, plen);
goto error;
}
diff --git a/sound/core/control.c b/sound/core/control.c
index 132856b..fd2de93 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1084,7 +1084,7 @@
mutex_lock(&ue->card->user_ctl_lock);
change = ue->tlv_data_size != size;
if (!change)
- change = memcmp(ue->tlv_data, new_data, size);
+ change = memcmp(ue->tlv_data, new_data, size) != 0;
kfree(ue->tlv_data);
ue->tlv_data = new_data;
ue->tlv_data_size = size;
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index d449dde..7b5a790 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -1248,6 +1248,7 @@
struct snd_seq_client_port *port;
struct snd_seq_port_info info;
struct snd_seq_port_callback *callback;
+ int port_idx;
if (copy_from_user(&info, arg, sizeof(info)))
return -EFAULT;
@@ -1261,7 +1262,9 @@
return -ENOMEM;
if (client->type == USER_CLIENT && info.kernel) {
- snd_seq_delete_port(client, port->addr.port);
+ port_idx = port->addr.port;
+ snd_seq_port_unlock(port);
+ snd_seq_delete_port(client, port_idx);
return -EINVAL;
}
if (client->type == KERNEL_CLIENT) {
@@ -1283,6 +1286,7 @@
snd_seq_set_port_info(port, &info);
snd_seq_system_client_ev_port_start(port->addr.client, port->addr.port);
+ snd_seq_port_unlock(port);
if (copy_to_user(arg, &info, sizeof(info)))
return -EFAULT;
diff --git a/sound/core/seq/seq_lock.c b/sound/core/seq/seq_lock.c
index 8a6b7ba..d8405d3 100644
--- a/sound/core/seq/seq_lock.c
+++ b/sound/core/seq/seq_lock.c
@@ -23,8 +23,6 @@
#include <sound/core.h>
#include "seq_lock.h"
-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
-
/* wait until all locks are released */
void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
{
@@ -42,5 +40,3 @@
}
EXPORT_SYMBOL(snd_use_lock_sync_helper);
-
-#endif
diff --git a/sound/core/seq/seq_lock.h b/sound/core/seq/seq_lock.h
index 54044bc..ac38031 100644
--- a/sound/core/seq/seq_lock.h
+++ b/sound/core/seq/seq_lock.h
@@ -3,8 +3,6 @@
#include <linux/sched.h>
-#if defined(CONFIG_SMP) || defined(CONFIG_SND_DEBUG)
-
typedef atomic_t snd_use_lock_t;
/* initialize lock */
@@ -20,14 +18,4 @@
void snd_use_lock_sync_helper(snd_use_lock_t *lock, const char *file, int line);
#define snd_use_lock_sync(lockp) snd_use_lock_sync_helper(lockp, __BASE_FILE__, __LINE__)
-#else /* SMP || CONFIG_SND_DEBUG */
-
-typedef spinlock_t snd_use_lock_t; /* dummy */
-#define snd_use_lock_init(lockp) /**/
-#define snd_use_lock_use(lockp) /**/
-#define snd_use_lock_free(lockp) /**/
-#define snd_use_lock_sync(lockp) /**/
-
-#endif /* SMP || CONFIG_SND_DEBUG */
-
#endif /* __SND_SEQ_LOCK_H */
diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
index ee0522a..a28d1ac 100644
--- a/sound/core/seq/seq_ports.c
+++ b/sound/core/seq/seq_ports.c
@@ -122,7 +122,9 @@
}
-/* create a port, port number is returned (-1 on failure) */
+/* create a port, port number is returned (-1 on failure);
+ * the caller needs to unref the port via snd_seq_port_unlock() appropriately
+ */
struct snd_seq_client_port *snd_seq_create_port(struct snd_seq_client *client,
int port)
{
@@ -153,6 +155,7 @@
snd_use_lock_init(&new_port->use_lock);
port_subs_info_init(&new_port->c_src);
port_subs_info_init(&new_port->c_dest);
+ snd_use_lock_use(&new_port->use_lock);
num = port >= 0 ? port : 0;
mutex_lock(&client->ports_mutex);
@@ -167,9 +170,9 @@
list_add_tail(&new_port->list, &p->list);
client->num_ports++;
new_port->addr.port = num; /* store the port number in the port */
+ sprintf(new_port->name, "port-%d", num);
write_unlock_irqrestore(&client->ports_lock, flags);
mutex_unlock(&client->ports_mutex);
- sprintf(new_port->name, "port-%d", num);
return new_port;
}
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index de51abcb..81ac4c1 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -4498,6 +4498,7 @@
SND_PCI_QUIRK(0x17aa, 0x390b, "Lenovo G50-80", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
+ SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo G50-70", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
{}
};
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 45c6302..396f356 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -133,6 +133,8 @@
#define ADAU1373_DAI_FORMAT_DSP 0x3
#define ADAU1373_BCLKDIV_SOURCE BIT(5)
+#define ADAU1373_BCLKDIV_SR_MASK (0x07 << 2)
+#define ADAU1373_BCLKDIV_BCLK_MASK 0x03
#define ADAU1373_BCLKDIV_32 0x03
#define ADAU1373_BCLKDIV_64 0x02
#define ADAU1373_BCLKDIV_128 0x01
@@ -937,7 +939,8 @@
adau1373_dai->enable_src = (div != 0);
snd_soc_update_bits(codec, ADAU1373_BCLKDIV(dai->id),
- ~ADAU1373_BCLKDIV_SOURCE, (div << 2) | ADAU1373_BCLKDIV_64);
+ ADAU1373_BCLKDIV_SR_MASK | ADAU1373_BCLKDIV_BCLK_MASK,
+ (div << 2) | ADAU1373_BCLKDIV_64);
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
index 93ee284..f23944d 100644
--- a/sound/soc/codecs/wm8983.c
+++ b/sound/soc/codecs/wm8983.c
@@ -855,30 +855,33 @@
struct pll_div pll_div;
codec = dai->codec;
- if (freq_in && freq_out) {
+ if (!freq_in || !freq_out) {
+ /* disable the PLL */
+ snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
+ WM8983_PLLEN_MASK, 0);
+ return 0;
+ } else {
ret = pll_factors(&pll_div, freq_out * 4 * 2, freq_in);
if (ret)
return ret;
+
+ /* disable the PLL before re-programming it */
+ snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
+ WM8983_PLLEN_MASK, 0);
+
+ /* set PLLN and PRESCALE */
+ snd_soc_write(codec, WM8983_PLL_N,
+ (pll_div.div2 << WM8983_PLL_PRESCALE_SHIFT)
+ | pll_div.n);
+ /* set PLLK */
+ snd_soc_write(codec, WM8983_PLL_K_3, pll_div.k & 0x1ff);
+ snd_soc_write(codec, WM8983_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
+ snd_soc_write(codec, WM8983_PLL_K_1, (pll_div.k >> 18));
+ /* enable the PLL */
+ snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
+ WM8983_PLLEN_MASK, WM8983_PLLEN);
}
- /* disable the PLL before re-programming it */
- snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
- WM8983_PLLEN_MASK, 0);
-
- if (!freq_in || !freq_out)
- return 0;
-
- /* set PLLN and PRESCALE */
- snd_soc_write(codec, WM8983_PLL_N,
- (pll_div.div2 << WM8983_PLL_PRESCALE_SHIFT)
- | pll_div.n);
- /* set PLLK */
- snd_soc_write(codec, WM8983_PLL_K_3, pll_div.k & 0x1ff);
- snd_soc_write(codec, WM8983_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
- snd_soc_write(codec, WM8983_PLL_K_1, (pll_div.k >> 18));
- /* enable the PLL */
- snd_soc_update_bits(codec, WM8983_POWER_MANAGEMENT_1,
- WM8983_PLLEN_MASK, WM8983_PLLEN);
return 0;
}
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
index bae510a..9d79cc7 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -785,33 +785,30 @@
struct pll_div pll_div;
codec = dai->codec;
- if (freq_in && freq_out) {
+ if (!freq_in || !freq_out) {
+ /* disable the PLL */
+ snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
+ WM8985_PLLEN_MASK, 0);
+ } else {
ret = pll_factors(&pll_div, freq_out * 4 * 2, freq_in);
if (ret)
return ret;
+
+ /* set PLLN and PRESCALE */
+ snd_soc_write(codec, WM8985_PLL_N,
+ (pll_div.div2 << WM8985_PLL_PRESCALE_SHIFT)
+ | pll_div.n);
+ /* set PLLK */
+ snd_soc_write(codec, WM8985_PLL_K_3, pll_div.k & 0x1ff);
+ snd_soc_write(codec, WM8985_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
+ snd_soc_write(codec, WM8985_PLL_K_1, (pll_div.k >> 18));
+ /* set the source of the clock to be the PLL */
+ snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
+ WM8985_CLKSEL_MASK, WM8985_CLKSEL);
+ /* enable the PLL */
+ snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
+ WM8985_PLLEN_MASK, WM8985_PLLEN);
}
-
- /* disable the PLL before reprogramming it */
- snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
- WM8985_PLLEN_MASK, 0);
-
- if (!freq_in || !freq_out)
- return 0;
-
- /* set PLLN and PRESCALE */
- snd_soc_write(codec, WM8985_PLL_N,
- (pll_div.div2 << WM8985_PLL_PRESCALE_SHIFT)
- | pll_div.n);
- /* set PLLK */
- snd_soc_write(codec, WM8985_PLL_K_3, pll_div.k & 0x1ff);
- snd_soc_write(codec, WM8985_PLL_K_2, (pll_div.k >> 9) & 0x1ff);
- snd_soc_write(codec, WM8985_PLL_K_1, (pll_div.k >> 18));
- /* set the source of the clock to be the PLL */
- snd_soc_update_bits(codec, WM8985_CLOCK_GEN_CONTROL,
- WM8985_CLKSEL_MASK, WM8985_CLKSEL);
- /* enable the PLL */
- snd_soc_update_bits(codec, WM8985_POWER_MANAGEMENT_1,
- WM8985_PLLEN_MASK, WM8985_PLLEN);
return 0;
}
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index e44c0e3..3b26d44 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -173,7 +173,7 @@
break;
default:
WARN(1, "Unknown DCS readback method\n");
- break;
+ return;
}
dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index 3eb605b..88e3f81 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -485,7 +485,7 @@
const struct usb_device_id *id)
{
int ret;
- struct snd_card *card;
+ struct snd_card *card = NULL;
struct usb_device *device = interface_to_usbdev(intf);
ret = create_card(device, intf, &card);
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 413b32d..aefb62e 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -222,6 +222,7 @@
struct usb_interface_descriptor *altsd;
void *control_header;
int i, protocol;
+ int rest_bytes;
/* find audiocontrol interface */
host_iface = &usb_ifnum_to_if(dev, ctrlif)->altsetting[0];
@@ -236,6 +237,15 @@
return -EINVAL;
}
+ rest_bytes = (void *)(host_iface->extra + host_iface->extralen) -
+ control_header;
+
+ /* just to be sure -- this shouldn't hit at all */
+ if (rest_bytes <= 0) {
+ dev_err(&dev->dev, "invalid control header\n");
+ return -EINVAL;
+ }
+
switch (protocol) {
default:
snd_printdd(KERN_WARNING "unknown interface protocol %#02x, assuming v1\n",
@@ -245,11 +255,21 @@
case UAC_VERSION_1: {
struct uac1_ac_header_descriptor *h1 = control_header;
+ if (rest_bytes < sizeof(*h1)) {
+ dev_err(&dev->dev, "too short v1 buffer descriptor\n");
+ return -EINVAL;
+ }
+
if (!h1->bInCollection) {
snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
return -EINVAL;
}
+ if (rest_bytes < h1->bLength) {
+ dev_err(&dev->dev, "invalid buffer length (v1)\n");
+ return -EINVAL;
+ }
+
if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n");
return -EINVAL;
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 9c36a1f..a489f2f 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -515,6 +515,8 @@
if (size < sizeof(scale))
return -ENOMEM;
+ if (cval->min_mute)
+ scale[0] = SNDRV_CTL_TLVT_DB_MINMAX_MUTE;
scale[2] = cval->dBmin;
scale[3] = cval->dBmax;
if (copy_to_user(_tlv, scale, sizeof(scale)))
@@ -1983,6 +1985,9 @@
static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
{
+ /* kill pending URBs */
+ snd_usb_mixer_disconnect(&mixer->list);
+
kfree(mixer->id_elems);
if (mixer->urb) {
kfree(mixer->urb->transfer_buffer);
@@ -2329,6 +2334,11 @@
struct usb_mixer_interface *mixer;
mixer = list_entry(p, struct usb_mixer_interface, list);
- usb_kill_urb(mixer->urb);
- usb_kill_urb(mixer->rc_urb);
+ if (mixer->disconnected)
+ return;
+ if (mixer->urb)
+ usb_kill_urb(mixer->urb);
+ if (mixer->rc_urb)
+ usb_kill_urb(mixer->rc_urb);
+ mixer->disconnected = true;
}
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index 81b2d8a..7b6b683 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -23,6 +23,8 @@
u8 audigy2nx_leds[3];
u8 xonar_u1_status;
+
+ bool disconnected;
};
#define MAX_CHANNELS 16 /* max logical channels */
@@ -52,6 +54,7 @@
int cached;
int cache_val[MAX_CHANNELS];
u8 initialized;
+ u8 min_mute;
};
int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index d422d16..ee1a148 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -726,6 +726,12 @@
if (unitid == 7 && cval->control == UAC_FU_VOLUME)
snd_dragonfly_quirk_db_scale(mixer, cval, kctl);
break;
+ /* lowest playback value is muted on C-Media devices */
+ case USB_ID(0x0d8c, 0x000c):
+ case USB_ID(0x0d8c, 0x0014):
+ if (strstr(kctl->id.name, "Playback"))
+ cval->min_mute = 1;
+ break;
}
}