mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 14:42:37 +02:00
This is the 3.10.13 stable release
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJSRM7zAAoJEDjbvchgkmk+Z5kQAMc4SZhh0xlSJCsdQ18LECTE 9wpNicjy1KgarAudg23H5y4UkfA/VLVQigyuWMJyRUnL8dxs7rc8no/t1Pl6XydV Bs+2JM6sHL34+N2YGFeUfoILkY5770N4nmcjISRwUnkikvqqwZZACsTTdd//JnEJ EBmRTXftlqMAQsNyeAx9Gvtvc7gWw4mQZLYRipSsUmtTJfbjIY7VJ1uC/VZ/F0/P NDjgjNipgbPUz8aTlRhBWknjt4hK0VXoIIsW3vcN1DfUg6sMgfQJG9Kd+4uCpJ5X 38N1w/jYRMOw8sVnnaftoZYSaTOCd2vPD+ngMLP616ucd1t27TgvGdMmq2r0oIs+ j0rWDagtPCfex11LI+XhcAabfwZ0JCfTMLWPJG5E86GBoLtHv5fAAqLYaZhWBeqC oEJyKp1Nu/9luiEfXbU+UW153BZLI0b9loRFva4NJyKLNCMvVTKMaNu4VEzlNI2e FaQTumG3jRMhA2HXufXF+FeaU2NQczXdKeftZJZ9FeZLKsCJnag7A2JR6z0zHoPZ xuDoFmRWovUlk0SgB/ReuOT9vLgmNPzvl6SyBYiy+PqoXZAOe3ztRrpRTSzh56WR uDm5Y9ECp85F66ewd4aNX13gX1nzrxA4f7rWfzlRlC7TeHtV/97vcRCqK12+jqSg ySPiwMHSAULElexQoNiG =9inU -----END PGP SIGNATURE----- Merge tag 'v3.10.13' into linux-linaro-lsk This is the 3.10.13 stable release
This commit is contained in:
commit
2a04587736
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||
<!ENTITY % media-entities SYSTEM "./media-entities.tmpl"> %media-entities;
|
||||
<!ENTITY media-indices SYSTEM "./media-indices.tmpl">
|
||||
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -1,6 +1,6 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 12
|
||||
SUBLEVEL = 13
|
||||
EXTRAVERSION =
|
||||
NAME = TOSSUG Baby Fish
|
||||
|
||||
|
|
|
|||
|
|
@ -35,8 +35,12 @@ aliases {
|
|||
ssc2 = &ssc2;
|
||||
};
|
||||
cpus {
|
||||
cpu@0 {
|
||||
#address-cells = <0>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu {
|
||||
compatible = "arm,arm920t";
|
||||
device_type = "cpu";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -32,8 +32,12 @@ aliases {
|
|||
ssc0 = &ssc0;
|
||||
};
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "arm,arm926ejs";
|
||||
#address-cells = <0>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu {
|
||||
compatible = "arm,arm926ej-s";
|
||||
device_type = "cpu";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -29,8 +29,12 @@ aliases {
|
|||
ssc1 = &ssc1;
|
||||
};
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "arm,arm926ejs";
|
||||
#address-cells = <0>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu {
|
||||
compatible = "arm,arm926ej-s";
|
||||
device_type = "cpu";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -35,8 +35,12 @@ aliases {
|
|||
ssc1 = &ssc1;
|
||||
};
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "arm,arm926ejs";
|
||||
#address-cells = <0>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu {
|
||||
compatible = "arm,arm926ej-s";
|
||||
device_type = "cpu";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,12 @@ aliases {
|
|||
ssc0 = &ssc0;
|
||||
};
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "arm,arm926ejs";
|
||||
#address-cells = <0>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu {
|
||||
compatible = "arm,arm926ej-s";
|
||||
device_type = "cpu";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -33,8 +33,12 @@ aliases {
|
|||
ssc0 = &ssc0;
|
||||
};
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "arm,arm926ejs";
|
||||
#address-cells = <0>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu {
|
||||
compatible = "arm,arm926ej-s";
|
||||
device_type = "cpu";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -35,8 +35,12 @@ aliases {
|
|||
ssc1 = &ssc1;
|
||||
};
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a5";
|
||||
reg = <0x0>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,12 @@ / {
|
|||
interrupt-parent = <&intc>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a8";
|
||||
reg = <0x0>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,12 @@ / {
|
|||
interrupt-parent = <&intc>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a8";
|
||||
reg = <0x0>;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -146,7 +146,11 @@ static bool pm_fake(struct kvm_vcpu *vcpu,
|
|||
#define access_pmintenclr pm_fake
|
||||
|
||||
/* Architected CP15 registers.
|
||||
* Important: Must be sorted ascending by CRn, CRM, Op1, Op2
|
||||
* CRn denotes the primary register number, but is copied to the CRm in the
|
||||
* user space API for 64-bit register access in line with the terminology used
|
||||
* in the ARM ARM.
|
||||
* Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit
|
||||
* registers preceding 32-bit ones.
|
||||
*/
|
||||
static const struct coproc_reg cp15_regs[] = {
|
||||
/* CSSELR: swapped by interrupt.S. */
|
||||
|
|
@ -154,8 +158,8 @@ static const struct coproc_reg cp15_regs[] = {
|
|||
NULL, reset_unknown, c0_CSSELR },
|
||||
|
||||
/* TTBR0/TTBR1: swapped by interrupt.S. */
|
||||
{ CRm( 2), Op1( 0), is64, NULL, reset_unknown64, c2_TTBR0 },
|
||||
{ CRm( 2), Op1( 1), is64, NULL, reset_unknown64, c2_TTBR1 },
|
||||
{ CRm64( 2), Op1( 0), is64, NULL, reset_unknown64, c2_TTBR0 },
|
||||
{ CRm64( 2), Op1( 1), is64, NULL, reset_unknown64, c2_TTBR1 },
|
||||
|
||||
/* TTBCR: swapped by interrupt.S. */
|
||||
{ CRn( 2), CRm( 0), Op1( 0), Op2( 2), is32,
|
||||
|
|
@ -182,7 +186,7 @@ static const struct coproc_reg cp15_regs[] = {
|
|||
NULL, reset_unknown, c6_IFAR },
|
||||
|
||||
/* PAR swapped by interrupt.S */
|
||||
{ CRn( 7), Op1( 0), is64, NULL, reset_unknown64, c7_PAR },
|
||||
{ CRm64( 7), Op1( 0), is64, NULL, reset_unknown64, c7_PAR },
|
||||
|
||||
/*
|
||||
* DC{C,I,CI}SW operations:
|
||||
|
|
@ -399,12 +403,13 @@ static bool index_to_params(u64 id, struct coproc_params *params)
|
|||
| KVM_REG_ARM_OPC1_MASK))
|
||||
return false;
|
||||
params->is_64bit = true;
|
||||
params->CRm = ((id & KVM_REG_ARM_CRM_MASK)
|
||||
/* CRm to CRn: see cp15_to_index for details */
|
||||
params->CRn = ((id & KVM_REG_ARM_CRM_MASK)
|
||||
>> KVM_REG_ARM_CRM_SHIFT);
|
||||
params->Op1 = ((id & KVM_REG_ARM_OPC1_MASK)
|
||||
>> KVM_REG_ARM_OPC1_SHIFT);
|
||||
params->Op2 = 0;
|
||||
params->CRn = 0;
|
||||
params->CRm = 0;
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
@ -898,7 +903,14 @@ static u64 cp15_to_index(const struct coproc_reg *reg)
|
|||
if (reg->is_64) {
|
||||
val |= KVM_REG_SIZE_U64;
|
||||
val |= (reg->Op1 << KVM_REG_ARM_OPC1_SHIFT);
|
||||
val |= (reg->CRm << KVM_REG_ARM_CRM_SHIFT);
|
||||
/*
|
||||
* CRn always denotes the primary coproc. reg. nr. for the
|
||||
* in-kernel representation, but the user space API uses the
|
||||
* CRm for the encoding, because it is modelled after the
|
||||
* MRRC/MCRR instructions: see the ARM ARM rev. c page
|
||||
* B3-1445
|
||||
*/
|
||||
val |= (reg->CRn << KVM_REG_ARM_CRM_SHIFT);
|
||||
} else {
|
||||
val |= KVM_REG_SIZE_U32;
|
||||
val |= (reg->Op1 << KVM_REG_ARM_OPC1_SHIFT);
|
||||
|
|
|
|||
|
|
@ -135,6 +135,8 @@ static inline int cmp_reg(const struct coproc_reg *i1,
|
|||
return -1;
|
||||
if (i1->CRn != i2->CRn)
|
||||
return i1->CRn - i2->CRn;
|
||||
if (i1->is_64 != i2->is_64)
|
||||
return i2->is_64 - i1->is_64;
|
||||
if (i1->CRm != i2->CRm)
|
||||
return i1->CRm - i2->CRm;
|
||||
if (i1->Op1 != i2->Op1)
|
||||
|
|
@ -145,6 +147,7 @@ static inline int cmp_reg(const struct coproc_reg *i1,
|
|||
|
||||
#define CRn(_x) .CRn = _x
|
||||
#define CRm(_x) .CRm = _x
|
||||
#define CRm64(_x) .CRn = _x, .CRm = 0
|
||||
#define Op1(_x) .Op1 = _x
|
||||
#define Op2(_x) .Op2 = _x
|
||||
#define is64 .is_64 = true
|
||||
|
|
|
|||
|
|
@ -114,7 +114,11 @@ static bool access_l2ectlr(struct kvm_vcpu *vcpu,
|
|||
|
||||
/*
|
||||
* A15-specific CP15 registers.
|
||||
* Important: Must be sorted ascending by CRn, CRM, Op1, Op2
|
||||
* CRn denotes the primary register number, but is copied to the CRm in the
|
||||
* user space API for 64-bit register access in line with the terminology used
|
||||
* in the ARM ARM.
|
||||
* Important: Must be sorted ascending by CRn, CRM, Op1, Op2 and with 64-bit
|
||||
* registers preceding 32-bit ones.
|
||||
*/
|
||||
static const struct coproc_reg a15_regs[] = {
|
||||
/* MPIDR: we use VMPIDR for guest access. */
|
||||
|
|
|
|||
|
|
@ -231,12 +231,14 @@
|
|||
/* PCI space */
|
||||
#define VERSATILE_PCI_BASE 0x41000000 /* PCI Interface */
|
||||
#define VERSATILE_PCI_CFG_BASE 0x42000000
|
||||
#define VERSATILE_PCI_IO_BASE 0x43000000
|
||||
#define VERSATILE_PCI_MEM_BASE0 0x44000000
|
||||
#define VERSATILE_PCI_MEM_BASE1 0x50000000
|
||||
#define VERSATILE_PCI_MEM_BASE2 0x60000000
|
||||
/* Sizes of above maps */
|
||||
#define VERSATILE_PCI_BASE_SIZE 0x01000000
|
||||
#define VERSATILE_PCI_CFG_BASE_SIZE 0x02000000
|
||||
#define VERSATILE_PCI_IO_BASE_SIZE 0x01000000
|
||||
#define VERSATILE_PCI_MEM_BASE0_SIZE 0x0c000000 /* 32Mb */
|
||||
#define VERSATILE_PCI_MEM_BASE1_SIZE 0x10000000 /* 256Mb */
|
||||
#define VERSATILE_PCI_MEM_BASE2_SIZE 0x10000000 /* 256Mb */
|
||||
|
|
|
|||
|
|
@ -43,9 +43,9 @@
|
|||
#define PCI_IMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x0)
|
||||
#define PCI_IMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x4)
|
||||
#define PCI_IMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x8)
|
||||
#define PCI_SMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x10)
|
||||
#define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14)
|
||||
#define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18)
|
||||
#define PCI_SMAP0 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x14)
|
||||
#define PCI_SMAP1 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x18)
|
||||
#define PCI_SMAP2 __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0x1c)
|
||||
#define PCI_SELFID __IO_ADDRESS(VERSATILE_PCI_CORE_BASE+0xc)
|
||||
|
||||
#define DEVICE_ID_OFFSET 0x00
|
||||
|
|
@ -170,8 +170,8 @@ static struct pci_ops pci_versatile_ops = {
|
|||
.write = versatile_write_config,
|
||||
};
|
||||
|
||||
static struct resource io_mem = {
|
||||
.name = "PCI I/O space",
|
||||
static struct resource unused_mem = {
|
||||
.name = "PCI unused",
|
||||
.start = VERSATILE_PCI_MEM_BASE0,
|
||||
.end = VERSATILE_PCI_MEM_BASE0+VERSATILE_PCI_MEM_BASE0_SIZE-1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
|
|
@ -195,9 +195,9 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys)
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = request_resource(&iomem_resource, &io_mem);
|
||||
ret = request_resource(&iomem_resource, &unused_mem);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "PCI: unable to allocate I/O "
|
||||
printk(KERN_ERR "PCI: unable to allocate unused "
|
||||
"memory region (%d)\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -205,7 +205,7 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys)
|
|||
if (ret) {
|
||||
printk(KERN_ERR "PCI: unable to allocate non-prefetchable "
|
||||
"memory region (%d)\n", ret);
|
||||
goto release_io_mem;
|
||||
goto release_unused_mem;
|
||||
}
|
||||
ret = request_resource(&iomem_resource, &pre_mem);
|
||||
if (ret) {
|
||||
|
|
@ -225,8 +225,8 @@ static int __init pci_versatile_setup_resources(struct pci_sys_data *sys)
|
|||
|
||||
release_non_mem:
|
||||
release_resource(&non_mem);
|
||||
release_io_mem:
|
||||
release_resource(&io_mem);
|
||||
release_unused_mem:
|
||||
release_resource(&unused_mem);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -246,7 +246,7 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = pci_ioremap_io(0, VERSATILE_PCI_MEM_BASE0);
|
||||
ret = pci_ioremap_io(0, VERSATILE_PCI_IO_BASE);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
|
@ -294,6 +294,19 @@ int __init pci_versatile_setup(int nr, struct pci_sys_data *sys)
|
|||
__raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_1);
|
||||
__raw_writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_2);
|
||||
|
||||
/*
|
||||
* For many years the kernel and QEMU were symbiotically buggy
|
||||
* in that they both assumed the same broken IRQ mapping.
|
||||
* QEMU therefore attempts to auto-detect old broken kernels
|
||||
* so that they still work on newer QEMU as they did on old
|
||||
* QEMU. Since we now use the correct (ie matching-hardware)
|
||||
* IRQ mapping we write a definitely different value to a
|
||||
* PCI_INTERRUPT_LINE register to tell QEMU that we expect
|
||||
* real hardware behaviour and it need not be backwards
|
||||
* compatible for us. This write is harmless on real hardware.
|
||||
*/
|
||||
__raw_writel(0, VERSATILE_PCI_VIRT_BASE+PCI_INTERRUPT_LINE);
|
||||
|
||||
/*
|
||||
* Do not to map Versatile FPGA PCI device into memory space
|
||||
*/
|
||||
|
|
@ -327,13 +340,13 @@ static int __init versatile_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
|||
{
|
||||
int irq;
|
||||
|
||||
/* slot, pin, irq
|
||||
* 24 1 IRQ_SIC_PCI0
|
||||
* 25 1 IRQ_SIC_PCI1
|
||||
* 26 1 IRQ_SIC_PCI2
|
||||
* 27 1 IRQ_SIC_PCI3
|
||||
/*
|
||||
* Slot INTA INTB INTC INTD
|
||||
* 31 PCI1 PCI2 PCI3 PCI0
|
||||
* 30 PCI0 PCI1 PCI2 PCI3
|
||||
* 29 PCI3 PCI0 PCI1 PCI2
|
||||
*/
|
||||
irq = IRQ_SIC_PCI0 + ((slot - 24 + pin - 1) & 3);
|
||||
irq = IRQ_SIC_PCI0 + ((slot + 2 + pin - 1) & 3);
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,12 +273,15 @@ core_initcall(xen_guest_init);
|
|||
|
||||
static int __init xen_pm_init(void)
|
||||
{
|
||||
if (!xen_domain())
|
||||
return -ENODEV;
|
||||
|
||||
pm_power_off = xen_power_off;
|
||||
arm_pm_restart = xen_restart;
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(xen_pm_init);
|
||||
late_initcall(xen_pm_init);
|
||||
|
||||
static irqreturn_t xen_arm_callback(int irq, void *arg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -325,7 +325,10 @@ validate_event(struct pmu_hw_events *hw_events,
|
|||
if (is_software_event(event))
|
||||
return 1;
|
||||
|
||||
if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF)
|
||||
if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF)
|
||||
return 1;
|
||||
|
||||
if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec)
|
||||
return 1;
|
||||
|
||||
return armpmu->get_event_idx(hw_events, &fake_event) >= 0;
|
||||
|
|
@ -781,7 +784,7 @@ static const unsigned armv8_pmuv3_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
|
|||
/*
|
||||
* PMXEVTYPER: Event selection reg
|
||||
*/
|
||||
#define ARMV8_EVTYPE_MASK 0xc00000ff /* Mask for writable bits */
|
||||
#define ARMV8_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */
|
||||
#define ARMV8_EVTYPE_EVENT 0xff /* Mask for EVENT bits */
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ static void __init ar933x_clocks_init(void)
|
|||
ath79_ahb_clk.rate = freq / t;
|
||||
}
|
||||
|
||||
ath79_wdt_clk.rate = ath79_ref_clk.rate;
|
||||
ath79_wdt_clk.rate = ath79_ahb_clk.rate;
|
||||
ath79_uart_clk.rate = ath79_ref_clk.rate;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -764,6 +764,16 @@ int fix_alignment(struct pt_regs *regs)
|
|||
nb = aligninfo[instr].len;
|
||||
flags = aligninfo[instr].flags;
|
||||
|
||||
/* ldbrx/stdbrx overlap lfs/stfs in the DSISR unfortunately */
|
||||
if (IS_XFORM(instruction) && ((instruction >> 1) & 0x3ff) == 532) {
|
||||
nb = 8;
|
||||
flags = LD+SW;
|
||||
} else if (IS_XFORM(instruction) &&
|
||||
((instruction >> 1) & 0x3ff) == 660) {
|
||||
nb = 8;
|
||||
flags = ST+SW;
|
||||
}
|
||||
|
||||
/* Byteswap little endian loads and stores */
|
||||
swiz = 0;
|
||||
if (regs->msr & MSR_LE) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include <asm/hvcall.h>
|
||||
#include <asm/xics.h>
|
||||
#include <asm/debug.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ static int alloc_dispatch_log_kmem_cache(void)
|
|||
}
|
||||
early_initcall(alloc_dispatch_log_kmem_cache);
|
||||
|
||||
static void pSeries_idle(void)
|
||||
static void pseries_lpar_idle(void)
|
||||
{
|
||||
/* This would call on the cpuidle framework, and the back-end pseries
|
||||
* driver to go to idle states
|
||||
|
|
@ -362,10 +362,22 @@ static void pSeries_idle(void)
|
|||
if (cpuidle_idle_call()) {
|
||||
/* On error, execute default handler
|
||||
* to go into low thread priority and possibly
|
||||
* low power mode.
|
||||
* low power mode by cedeing processor to hypervisor
|
||||
*/
|
||||
HMT_low();
|
||||
HMT_very_low();
|
||||
|
||||
/* Indicate to hypervisor that we are idle. */
|
||||
get_lppaca()->idle = 1;
|
||||
|
||||
/*
|
||||
* Yield the processor to the hypervisor. We return if
|
||||
* an external interrupt occurs (which are driven prior
|
||||
* to returning here) or if a prod occurs from another
|
||||
* processor. When returning here, external interrupts
|
||||
* are enabled.
|
||||
*/
|
||||
cede_processor();
|
||||
|
||||
get_lppaca()->idle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -456,15 +468,14 @@ static void __init pSeries_setup_arch(void)
|
|||
|
||||
pSeries_nvram_init();
|
||||
|
||||
if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
|
||||
if (firmware_has_feature(FW_FEATURE_LPAR)) {
|
||||
vpa_init(boot_cpuid);
|
||||
ppc_md.power_save = pSeries_idle;
|
||||
}
|
||||
|
||||
if (firmware_has_feature(FW_FEATURE_LPAR))
|
||||
ppc_md.power_save = pseries_lpar_idle;
|
||||
ppc_md.enable_pmcs = pseries_lpar_enable_pmcs;
|
||||
else
|
||||
} else {
|
||||
/* No special idle routine */
|
||||
ppc_md.enable_pmcs = power4_enable_pmcs;
|
||||
}
|
||||
|
||||
ppc_md.pcibios_root_bridge_prepare = pseries_root_bridge_prepare;
|
||||
|
||||
|
|
|
|||
|
|
@ -200,6 +200,7 @@ extern int os_unmap_memory(void *addr, int len);
|
|||
extern int os_drop_memory(void *addr, int length);
|
||||
extern int can_drop_memory(void);
|
||||
extern void os_flush_stdout(void);
|
||||
extern int os_mincore(void *addr, unsigned long len);
|
||||
|
||||
/* execvp.c */
|
||||
extern int execvp_noalloc(char *buf, const char *file, char *const argv[]);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ clean-files :=
|
|||
obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \
|
||||
physmem.o process.o ptrace.o reboot.o sigio.o \
|
||||
signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o \
|
||||
um_arch.o umid.o skas/
|
||||
um_arch.o umid.o maccess.o skas/
|
||||
|
||||
obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
|
||||
obj-$(CONFIG_GPROF) += gprof_syms.o
|
||||
|
|
|
|||
24
arch/um/kernel/maccess.c
Normal file
24
arch/um/kernel/maccess.c
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Richard Weinberger <richrd@nod.at>
|
||||
*
|
||||
* 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
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <os.h>
|
||||
|
||||
long probe_kernel_read(void *dst, const void *src, size_t size)
|
||||
{
|
||||
void *psrc = (void *)rounddown((unsigned long)src, PAGE_SIZE);
|
||||
|
||||
if ((unsigned long)src < PAGE_SIZE || size <= 0)
|
||||
return -EFAULT;
|
||||
|
||||
if (os_mincore(psrc, size + src - psrc) <= 0)
|
||||
return -EFAULT;
|
||||
|
||||
return __probe_kernel_read(dst, src, size);
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
|
@ -232,6 +233,57 @@ int __init can_drop_memory(void)
|
|||
return ok;
|
||||
}
|
||||
|
||||
static int os_page_mincore(void *addr)
|
||||
{
|
||||
char vec[2];
|
||||
int ret;
|
||||
|
||||
ret = mincore(addr, UM_KERN_PAGE_SIZE, vec);
|
||||
if (ret < 0) {
|
||||
if (errno == ENOMEM || errno == EINVAL)
|
||||
return 0;
|
||||
else
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return vec[0] & 1;
|
||||
}
|
||||
|
||||
int os_mincore(void *addr, unsigned long len)
|
||||
{
|
||||
char *vec;
|
||||
int ret, i;
|
||||
|
||||
if (len <= UM_KERN_PAGE_SIZE)
|
||||
return os_page_mincore(addr);
|
||||
|
||||
vec = calloc(1, (len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE);
|
||||
if (!vec)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = mincore(addr, UM_KERN_PAGE_SIZE, vec);
|
||||
if (ret < 0) {
|
||||
if (errno == ENOMEM || errno == EINVAL)
|
||||
ret = 0;
|
||||
else
|
||||
ret = -errno;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < ((len + UM_KERN_PAGE_SIZE - 1) / UM_KERN_PAGE_SIZE); i++) {
|
||||
if (!(vec[i] & 1)) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
out:
|
||||
free(vec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void init_new_thread_signals(void)
|
||||
{
|
||||
set_handler(SIGSEGV);
|
||||
|
|
|
|||
|
|
@ -459,7 +459,7 @@ int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
|
|||
else
|
||||
put_user_ex(0, &frame->uc.uc_flags);
|
||||
put_user_ex(0, &frame->uc.uc_link);
|
||||
err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
|
||||
compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp);
|
||||
|
||||
if (ksig->ka.sa.sa_flags & SA_RESTORER)
|
||||
restorer = ksig->ka.sa.sa_restorer;
|
||||
|
|
|
|||
|
|
@ -49,9 +49,15 @@ static inline __wsum csum_partial_copy_from_user(const void __user *src,
|
|||
int len, __wsum sum,
|
||||
int *err_ptr)
|
||||
{
|
||||
__wsum ret;
|
||||
|
||||
might_sleep();
|
||||
return csum_partial_copy_generic((__force void *)src, dst,
|
||||
len, sum, err_ptr, NULL);
|
||||
stac();
|
||||
ret = csum_partial_copy_generic((__force void *)src, dst,
|
||||
len, sum, err_ptr, NULL);
|
||||
clac();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -176,10 +182,16 @@ static inline __wsum csum_and_copy_to_user(const void *src,
|
|||
int len, __wsum sum,
|
||||
int *err_ptr)
|
||||
{
|
||||
__wsum ret;
|
||||
|
||||
might_sleep();
|
||||
if (access_ok(VERIFY_WRITE, dst, len))
|
||||
return csum_partial_copy_generic(src, (__force void *)dst,
|
||||
len, sum, NULL, err_ptr);
|
||||
if (access_ok(VERIFY_WRITE, dst, len)) {
|
||||
stac();
|
||||
ret = csum_partial_copy_generic(src, (__force void *)dst,
|
||||
len, sum, NULL, err_ptr);
|
||||
clac();
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (len)
|
||||
*err_ptr = -EFAULT;
|
||||
|
|
|
|||
|
|
@ -32,11 +32,20 @@
|
|||
#define MCI_STATUS_PCC (1ULL<<57) /* processor context corrupt */
|
||||
#define MCI_STATUS_S (1ULL<<56) /* Signaled machine check */
|
||||
#define MCI_STATUS_AR (1ULL<<55) /* Action required */
|
||||
#define MCACOD 0xffff /* MCA Error Code */
|
||||
|
||||
/*
|
||||
* Note that the full MCACOD field of IA32_MCi_STATUS MSR is
|
||||
* bits 15:0. But bit 12 is the 'F' bit, defined for corrected
|
||||
* errors to indicate that errors are being filtered by hardware.
|
||||
* We should mask out bit 12 when looking for specific signatures
|
||||
* of uncorrected errors - so the F bit is deliberately skipped
|
||||
* in this #define.
|
||||
*/
|
||||
#define MCACOD 0xefff /* MCA Error Code */
|
||||
|
||||
/* Architecturally defined codes from SDM Vol. 3B Chapter 15 */
|
||||
#define MCACOD_SCRUB 0x00C0 /* 0xC0-0xCF Memory Scrubbing */
|
||||
#define MCACOD_SCRUBMSK 0xfff0
|
||||
#define MCACOD_SCRUBMSK 0xeff0 /* Skip bit 12 ('F' bit) */
|
||||
#define MCACOD_L3WB 0x017A /* L3 Explicit Writeback */
|
||||
#define MCACOD_DATA 0x0134 /* Data Load */
|
||||
#define MCACOD_INSTR 0x0150 /* Instruction Fetch */
|
||||
|
|
|
|||
|
|
@ -45,22 +45,28 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
|||
/* Re-load page tables */
|
||||
load_cr3(next->pgd);
|
||||
|
||||
/* stop flush ipis for the previous mm */
|
||||
/* Stop flush ipis for the previous mm */
|
||||
cpumask_clear_cpu(cpu, mm_cpumask(prev));
|
||||
|
||||
/*
|
||||
* load the LDT, if the LDT is different:
|
||||
*/
|
||||
/* Load the LDT, if the LDT is different: */
|
||||
if (unlikely(prev->context.ldt != next->context.ldt))
|
||||
load_LDT_nolock(&next->context);
|
||||
}
|
||||
#ifdef CONFIG_SMP
|
||||
else {
|
||||
else {
|
||||
this_cpu_write(cpu_tlbstate.state, TLBSTATE_OK);
|
||||
BUG_ON(this_cpu_read(cpu_tlbstate.active_mm) != next);
|
||||
|
||||
if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next))) {
|
||||
/* We were in lazy tlb mode and leave_mm disabled
|
||||
if (!cpumask_test_cpu(cpu, mm_cpumask(next))) {
|
||||
/*
|
||||
* On established mms, the mm_cpumask is only changed
|
||||
* from irq context, from ptep_clear_flush() while in
|
||||
* lazy tlb mode, and here. Irqs are blocked during
|
||||
* schedule, protecting us from simultaneous changes.
|
||||
*/
|
||||
cpumask_set_cpu(cpu, mm_cpumask(next));
|
||||
/*
|
||||
* We were in lazy tlb mode and leave_mm disabled
|
||||
* tlb flush IPI delivery. We must reload CR3
|
||||
* to make sure to use no freed page tables.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ const struct pci_device_id amd_nb_misc_ids[] = {
|
|||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M10H_F3) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F3) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F3) },
|
||||
{}
|
||||
};
|
||||
|
|
@ -27,6 +28,7 @@ EXPORT_SYMBOL(amd_nb_misc_ids);
|
|||
|
||||
static const struct pci_device_id amd_nb_link_ids[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_15H_M30H_NB_F4) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_16H_NB_F4) },
|
||||
{}
|
||||
};
|
||||
|
|
@ -81,12 +83,19 @@ int amd_cache_northbridges(void)
|
|||
next_northbridge(misc, amd_nb_misc_ids);
|
||||
node_to_amd_nb(i)->link = link =
|
||||
next_northbridge(link, amd_nb_link_ids);
|
||||
}
|
||||
}
|
||||
|
||||
/* GART present only on Fam15h upto model 0fh */
|
||||
if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10 ||
|
||||
boot_cpu_data.x86 == 0x15)
|
||||
(boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model < 0x10))
|
||||
amd_northbridges.flags |= AMD_NB_GART;
|
||||
|
||||
/*
|
||||
* Check for L3 cache presence.
|
||||
*/
|
||||
if (!cpuid_edx(0x80000006))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Some CPU families support L3 Cache Index Disable. There are some
|
||||
* limitations because of E382 and E388 on family 0x10.
|
||||
|
|
|
|||
|
|
@ -364,7 +364,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
|
|||
else
|
||||
put_user_ex(0, &frame->uc.uc_flags);
|
||||
put_user_ex(0, &frame->uc.uc_link);
|
||||
err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
|
||||
save_altstack_ex(&frame->uc.uc_stack, regs->sp);
|
||||
|
||||
/* Set up to return from userspace. */
|
||||
restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
|
||||
|
|
@ -429,7 +429,7 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
|
|||
else
|
||||
put_user_ex(0, &frame->uc.uc_flags);
|
||||
put_user_ex(0, &frame->uc.uc_link);
|
||||
err |= __save_altstack(&frame->uc.uc_stack, regs->sp);
|
||||
save_altstack_ex(&frame->uc.uc_stack, regs->sp);
|
||||
|
||||
/* Set up to return from userspace. If provided, use a stub
|
||||
already in userspace. */
|
||||
|
|
@ -496,7 +496,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig,
|
|||
else
|
||||
put_user_ex(0, &frame->uc.uc_flags);
|
||||
put_user_ex(0, &frame->uc.uc_link);
|
||||
err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
|
||||
compat_save_altstack_ex(&frame->uc.uc_stack, regs->sp);
|
||||
put_user_ex(0, &frame->uc.uc__pad0);
|
||||
|
||||
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
#include <asm/checksum.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/smap.h>
|
||||
|
||||
/**
|
||||
* csum_partial_copy_from_user - Copy and checksum from user space.
|
||||
|
|
@ -52,8 +53,10 @@ csum_partial_copy_from_user(const void __user *src, void *dst,
|
|||
len -= 2;
|
||||
}
|
||||
}
|
||||
stac();
|
||||
isum = csum_partial_copy_generic((__force const void *)src,
|
||||
dst, len, isum, errp, NULL);
|
||||
clac();
|
||||
if (unlikely(*errp))
|
||||
goto out_err;
|
||||
|
||||
|
|
@ -82,6 +85,8 @@ __wsum
|
|||
csum_partial_copy_to_user(const void *src, void __user *dst,
|
||||
int len, __wsum isum, int *errp)
|
||||
{
|
||||
__wsum ret;
|
||||
|
||||
might_sleep();
|
||||
|
||||
if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) {
|
||||
|
|
@ -105,8 +110,11 @@ csum_partial_copy_to_user(const void *src, void __user *dst,
|
|||
}
|
||||
|
||||
*errp = 0;
|
||||
return csum_partial_copy_generic(src, (void __force *)dst,
|
||||
len, isum, NULL, errp);
|
||||
stac();
|
||||
ret = csum_partial_copy_generic(src, (void __force *)dst,
|
||||
len, isum, NULL, errp);
|
||||
clac();
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(csum_partial_copy_to_user);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ EXPORT_SYMBOL_GPL(crypto_alg_sem);
|
|||
BLOCKING_NOTIFIER_HEAD(crypto_chain);
|
||||
EXPORT_SYMBOL_GPL(crypto_chain);
|
||||
|
||||
static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg);
|
||||
|
||||
struct crypto_alg *crypto_mod_get(struct crypto_alg *alg)
|
||||
{
|
||||
return try_module_get(alg->cra_module) ? crypto_alg_get(alg) : NULL;
|
||||
|
|
@ -144,8 +146,11 @@ static struct crypto_alg *crypto_larval_add(const char *name, u32 type,
|
|||
}
|
||||
up_write(&crypto_alg_sem);
|
||||
|
||||
if (alg != &larval->alg)
|
||||
if (alg != &larval->alg) {
|
||||
kfree(larval);
|
||||
if (crypto_is_larval(alg))
|
||||
alg = crypto_larval_wait(alg);
|
||||
}
|
||||
|
||||
return alg;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,12 +155,13 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
|
|||
pdata->mmio_size = resource_size(&rentry->res);
|
||||
pdata->mmio_base = ioremap(rentry->res.start,
|
||||
pdata->mmio_size);
|
||||
pdata->dev_desc = dev_desc;
|
||||
break;
|
||||
}
|
||||
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
|
||||
pdata->dev_desc = dev_desc;
|
||||
|
||||
if (dev_desc->clk_required) {
|
||||
ret = register_device_clock(adev, pdata);
|
||||
if (ret) {
|
||||
|
|
|
|||
|
|
@ -1565,11 +1565,12 @@ rbd_img_obj_request_read_callback(struct rbd_obj_request *obj_request)
|
|||
obj_request, obj_request->img_request, obj_request->result,
|
||||
xferred, length);
|
||||
/*
|
||||
* ENOENT means a hole in the image. We zero-fill the
|
||||
* entire length of the request. A short read also implies
|
||||
* zero-fill to the end of the request. Either way we
|
||||
* update the xferred count to indicate the whole request
|
||||
* was satisfied.
|
||||
* ENOENT means a hole in the image. We zero-fill the entire
|
||||
* length of the request. A short read also implies zero-fill
|
||||
* to the end of the request. An error requires the whole
|
||||
* length of the request to be reported finished with an error
|
||||
* to the block layer. In each case we update the xferred
|
||||
* count to indicate the whole request was satisfied.
|
||||
*/
|
||||
rbd_assert(obj_request->type != OBJ_REQUEST_NODATA);
|
||||
if (obj_request->result == -ENOENT) {
|
||||
|
|
@ -1578,14 +1579,13 @@ rbd_img_obj_request_read_callback(struct rbd_obj_request *obj_request)
|
|||
else
|
||||
zero_pages(obj_request->pages, 0, length);
|
||||
obj_request->result = 0;
|
||||
obj_request->xferred = length;
|
||||
} else if (xferred < length && !obj_request->result) {
|
||||
if (obj_request->type == OBJ_REQUEST_BIO)
|
||||
zero_bio_chain(obj_request->bio_list, xferred);
|
||||
else
|
||||
zero_pages(obj_request->pages, xferred, length);
|
||||
obj_request->xferred = length;
|
||||
}
|
||||
obj_request->xferred = length;
|
||||
obj_request_done_set(obj_request);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -360,6 +360,8 @@ static int wm831x_clk_probe(struct platform_device *pdev)
|
|||
if (!clkdata)
|
||||
return -ENOMEM;
|
||||
|
||||
clkdata->wm831x = wm831x;
|
||||
|
||||
/* XTAL_ENA can only be set via OTP/InstantConfig so just read once */
|
||||
ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2);
|
||||
if (ret < 0) {
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ struct cpuidle_coupled {
|
|||
cpumask_t coupled_cpus;
|
||||
int requested_state[NR_CPUS];
|
||||
atomic_t ready_waiting_counts;
|
||||
atomic_t abort_barrier;
|
||||
int online_count;
|
||||
int refcnt;
|
||||
int prevent;
|
||||
|
|
@ -122,12 +123,19 @@ static DEFINE_MUTEX(cpuidle_coupled_lock);
|
|||
static DEFINE_PER_CPU(struct call_single_data, cpuidle_coupled_poke_cb);
|
||||
|
||||
/*
|
||||
* The cpuidle_coupled_poked_mask mask is used to avoid calling
|
||||
* The cpuidle_coupled_poke_pending mask is used to avoid calling
|
||||
* __smp_call_function_single with the per cpu call_single_data struct already
|
||||
* in use. This prevents a deadlock where two cpus are waiting for each others
|
||||
* call_single_data struct to be available
|
||||
*/
|
||||
static cpumask_t cpuidle_coupled_poked_mask;
|
||||
static cpumask_t cpuidle_coupled_poke_pending;
|
||||
|
||||
/*
|
||||
* The cpuidle_coupled_poked mask is used to ensure that each cpu has been poked
|
||||
* once to minimize entering the ready loop with a poke pending, which would
|
||||
* require aborting and retrying.
|
||||
*/
|
||||
static cpumask_t cpuidle_coupled_poked;
|
||||
|
||||
/**
|
||||
* cpuidle_coupled_parallel_barrier - synchronize all online coupled cpus
|
||||
|
|
@ -291,10 +299,11 @@ static inline int cpuidle_coupled_get_state(struct cpuidle_device *dev,
|
|||
return state;
|
||||
}
|
||||
|
||||
static void cpuidle_coupled_poked(void *info)
|
||||
static void cpuidle_coupled_handle_poke(void *info)
|
||||
{
|
||||
int cpu = (unsigned long)info;
|
||||
cpumask_clear_cpu(cpu, &cpuidle_coupled_poked_mask);
|
||||
cpumask_set_cpu(cpu, &cpuidle_coupled_poked);
|
||||
cpumask_clear_cpu(cpu, &cpuidle_coupled_poke_pending);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -313,7 +322,7 @@ static void cpuidle_coupled_poke(int cpu)
|
|||
{
|
||||
struct call_single_data *csd = &per_cpu(cpuidle_coupled_poke_cb, cpu);
|
||||
|
||||
if (!cpumask_test_and_set_cpu(cpu, &cpuidle_coupled_poked_mask))
|
||||
if (!cpumask_test_and_set_cpu(cpu, &cpuidle_coupled_poke_pending))
|
||||
__smp_call_function_single(cpu, csd, 0);
|
||||
}
|
||||
|
||||
|
|
@ -340,30 +349,19 @@ static void cpuidle_coupled_poke_others(int this_cpu,
|
|||
* @coupled: the struct coupled that contains the current cpu
|
||||
* @next_state: the index in drv->states of the requested state for this cpu
|
||||
*
|
||||
* Updates the requested idle state for the specified cpuidle device,
|
||||
* poking all coupled cpus out of idle if necessary to let them see the new
|
||||
* state.
|
||||
* Updates the requested idle state for the specified cpuidle device.
|
||||
* Returns the number of waiting cpus.
|
||||
*/
|
||||
static void cpuidle_coupled_set_waiting(int cpu,
|
||||
static int cpuidle_coupled_set_waiting(int cpu,
|
||||
struct cpuidle_coupled *coupled, int next_state)
|
||||
{
|
||||
int w;
|
||||
|
||||
coupled->requested_state[cpu] = next_state;
|
||||
|
||||
/*
|
||||
* If this is the last cpu to enter the waiting state, poke
|
||||
* all the other cpus out of their waiting state so they can
|
||||
* enter a deeper state. This can race with one of the cpus
|
||||
* exiting the waiting state due to an interrupt and
|
||||
* decrementing waiting_count, see comment below.
|
||||
*
|
||||
* The atomic_inc_return provides a write barrier to order the write
|
||||
* to requested_state with the later write that increments ready_count.
|
||||
*/
|
||||
w = atomic_inc_return(&coupled->ready_waiting_counts) & WAITING_MASK;
|
||||
if (w == coupled->online_count)
|
||||
cpuidle_coupled_poke_others(cpu, coupled);
|
||||
return atomic_inc_return(&coupled->ready_waiting_counts) & WAITING_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -410,19 +408,33 @@ static void cpuidle_coupled_set_done(int cpu, struct cpuidle_coupled *coupled)
|
|||
* been processed and the poke bit has been cleared.
|
||||
*
|
||||
* Other interrupts may also be processed while interrupts are enabled, so
|
||||
* need_resched() must be tested after turning interrupts off again to make sure
|
||||
* need_resched() must be tested after this function returns to make sure
|
||||
* the interrupt didn't schedule work that should take the cpu out of idle.
|
||||
*
|
||||
* Returns 0 if need_resched was false, -EINTR if need_resched was true.
|
||||
* Returns 0 if no poke was pending, 1 if a poke was cleared.
|
||||
*/
|
||||
static int cpuidle_coupled_clear_pokes(int cpu)
|
||||
{
|
||||
if (!cpumask_test_cpu(cpu, &cpuidle_coupled_poke_pending))
|
||||
return 0;
|
||||
|
||||
local_irq_enable();
|
||||
while (cpumask_test_cpu(cpu, &cpuidle_coupled_poked_mask))
|
||||
while (cpumask_test_cpu(cpu, &cpuidle_coupled_poke_pending))
|
||||
cpu_relax();
|
||||
local_irq_disable();
|
||||
|
||||
return need_resched() ? -EINTR : 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool cpuidle_coupled_any_pokes_pending(struct cpuidle_coupled *coupled)
|
||||
{
|
||||
cpumask_t cpus;
|
||||
int ret;
|
||||
|
||||
cpumask_and(&cpus, cpu_online_mask, &coupled->coupled_cpus);
|
||||
ret = cpumask_and(&cpus, &cpuidle_coupled_poke_pending, &cpus);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -449,12 +461,14 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
|
|||
{
|
||||
int entered_state = -1;
|
||||
struct cpuidle_coupled *coupled = dev->coupled;
|
||||
int w;
|
||||
|
||||
if (!coupled)
|
||||
return -EINVAL;
|
||||
|
||||
while (coupled->prevent) {
|
||||
if (cpuidle_coupled_clear_pokes(dev->cpu)) {
|
||||
cpuidle_coupled_clear_pokes(dev->cpu);
|
||||
if (need_resched()) {
|
||||
local_irq_enable();
|
||||
return entered_state;
|
||||
}
|
||||
|
|
@ -465,15 +479,37 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
|
|||
/* Read barrier ensures online_count is read after prevent is cleared */
|
||||
smp_rmb();
|
||||
|
||||
cpuidle_coupled_set_waiting(dev->cpu, coupled, next_state);
|
||||
reset:
|
||||
cpumask_clear_cpu(dev->cpu, &cpuidle_coupled_poked);
|
||||
|
||||
w = cpuidle_coupled_set_waiting(dev->cpu, coupled, next_state);
|
||||
/*
|
||||
* If this is the last cpu to enter the waiting state, poke
|
||||
* all the other cpus out of their waiting state so they can
|
||||
* enter a deeper state. This can race with one of the cpus
|
||||
* exiting the waiting state due to an interrupt and
|
||||
* decrementing waiting_count, see comment below.
|
||||
*/
|
||||
if (w == coupled->online_count) {
|
||||
cpumask_set_cpu(dev->cpu, &cpuidle_coupled_poked);
|
||||
cpuidle_coupled_poke_others(dev->cpu, coupled);
|
||||
}
|
||||
|
||||
retry:
|
||||
/*
|
||||
* Wait for all coupled cpus to be idle, using the deepest state
|
||||
* allowed for a single cpu.
|
||||
* allowed for a single cpu. If this was not the poking cpu, wait
|
||||
* for at least one poke before leaving to avoid a race where
|
||||
* two cpus could arrive at the waiting loop at the same time,
|
||||
* but the first of the two to arrive could skip the loop without
|
||||
* processing the pokes from the last to arrive.
|
||||
*/
|
||||
while (!cpuidle_coupled_cpus_waiting(coupled)) {
|
||||
if (cpuidle_coupled_clear_pokes(dev->cpu)) {
|
||||
while (!cpuidle_coupled_cpus_waiting(coupled) ||
|
||||
!cpumask_test_cpu(dev->cpu, &cpuidle_coupled_poked)) {
|
||||
if (cpuidle_coupled_clear_pokes(dev->cpu))
|
||||
continue;
|
||||
|
||||
if (need_resched()) {
|
||||
cpuidle_coupled_set_not_waiting(dev->cpu, coupled);
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -487,11 +523,18 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
|
|||
dev->safe_state_index);
|
||||
}
|
||||
|
||||
if (cpuidle_coupled_clear_pokes(dev->cpu)) {
|
||||
cpuidle_coupled_clear_pokes(dev->cpu);
|
||||
if (need_resched()) {
|
||||
cpuidle_coupled_set_not_waiting(dev->cpu, coupled);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure final poke status for this cpu is visible before setting
|
||||
* cpu as ready.
|
||||
*/
|
||||
smp_wmb();
|
||||
|
||||
/*
|
||||
* All coupled cpus are probably idle. There is a small chance that
|
||||
* one of the other cpus just became active. Increment the ready count,
|
||||
|
|
@ -511,6 +554,28 @@ int cpuidle_enter_state_coupled(struct cpuidle_device *dev,
|
|||
cpu_relax();
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure read of all cpus ready is done before reading pending pokes
|
||||
*/
|
||||
smp_rmb();
|
||||
|
||||
/*
|
||||
* There is a small chance that a cpu left and reentered idle after this
|
||||
* cpu saw that all cpus were waiting. The cpu that reentered idle will
|
||||
* have sent this cpu a poke, which will still be pending after the
|
||||
* ready loop. The pending interrupt may be lost by the interrupt
|
||||
* controller when entering the deep idle state. It's not possible to
|
||||
* clear a pending interrupt without turning interrupts on and handling
|
||||
* it, and it's too late to turn on interrupts here, so reset the
|
||||
* coupled idle state of all cpus and retry.
|
||||
*/
|
||||
if (cpuidle_coupled_any_pokes_pending(coupled)) {
|
||||
cpuidle_coupled_set_done(dev->cpu, coupled);
|
||||
/* Wait for all cpus to see the pending pokes */
|
||||
cpuidle_coupled_parallel_barrier(dev, &coupled->abort_barrier);
|
||||
goto reset;
|
||||
}
|
||||
|
||||
/* all cpus have acked the coupled state */
|
||||
next_state = cpuidle_coupled_get_state(dev, coupled);
|
||||
|
||||
|
|
@ -596,7 +661,7 @@ int cpuidle_coupled_register_device(struct cpuidle_device *dev)
|
|||
coupled->refcnt++;
|
||||
|
||||
csd = &per_cpu(cpuidle_coupled_poke_cb, dev->cpu);
|
||||
csd->func = cpuidle_coupled_poked;
|
||||
csd->func = cpuidle_coupled_handle_poke;
|
||||
csd->info = (void *)(unsigned long)dev->cpu;
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -2470,8 +2470,15 @@ static int amd64_init_one_instance(struct pci_dev *F2)
|
|||
layers[0].size = pvt->csels[0].b_cnt;
|
||||
layers[0].is_virt_csrow = true;
|
||||
layers[1].type = EDAC_MC_LAYER_CHANNEL;
|
||||
layers[1].size = pvt->channel_count;
|
||||
|
||||
/*
|
||||
* Always allocate two channels since we can have setups with DIMMs on
|
||||
* only one channel. Also, this simplifies handling later for the price
|
||||
* of a couple of KBs tops.
|
||||
*/
|
||||
layers[1].size = 2;
|
||||
layers[1].is_virt_csrow = false;
|
||||
|
||||
mci = edac_mc_alloc(nid, ARRAY_SIZE(layers), layers, 0);
|
||||
if (!mci)
|
||||
goto err_siblings;
|
||||
|
|
|
|||
|
|
@ -125,6 +125,9 @@ static struct edid_quirk {
|
|||
|
||||
/* ViewSonic VA2026w */
|
||||
{ "VSC", 5020, EDID_QUIRK_FORCE_REDUCED_BLANKING },
|
||||
|
||||
/* Medion MD 30217 PG */
|
||||
{ "MED", 0x7b8, EDID_QUIRK_PREFER_LARGE_75 },
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type,
|
|||
struct hid_report_enum *report_enum = device->report_enum + type;
|
||||
struct hid_report *report;
|
||||
|
||||
if (id >= HID_MAX_IDS)
|
||||
return NULL;
|
||||
if (report_enum->report_id_hash[id])
|
||||
return report_enum->report_id_hash[id];
|
||||
|
||||
|
|
@ -404,8 +406,10 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
|
|||
|
||||
case HID_GLOBAL_ITEM_TAG_REPORT_ID:
|
||||
parser->global.report_id = item_udata(item);
|
||||
if (parser->global.report_id == 0) {
|
||||
hid_err(parser->device, "report_id 0 is invalid\n");
|
||||
if (parser->global.report_id == 0 ||
|
||||
parser->global.report_id >= HID_MAX_IDS) {
|
||||
hid_err(parser->device, "report_id %u is invalid\n",
|
||||
parser->global.report_id);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -575,7 +579,7 @@ static void hid_close_report(struct hid_device *device)
|
|||
for (i = 0; i < HID_REPORT_TYPES; i++) {
|
||||
struct hid_report_enum *report_enum = device->report_enum + i;
|
||||
|
||||
for (j = 0; j < 256; j++) {
|
||||
for (j = 0; j < HID_MAX_IDS; j++) {
|
||||
struct hid_report *report = report_enum->report_id_hash[j];
|
||||
if (report)
|
||||
hid_free_report(report);
|
||||
|
|
@ -1152,7 +1156,12 @@ EXPORT_SYMBOL_GPL(hid_output_report);
|
|||
|
||||
int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
|
||||
{
|
||||
unsigned size = field->report_size;
|
||||
unsigned size;
|
||||
|
||||
if (!field)
|
||||
return -1;
|
||||
|
||||
size = field->report_size;
|
||||
|
||||
hid_dump_input(field->report->device, field->usage + offset, value);
|
||||
|
||||
|
|
|
|||
|
|
@ -135,9 +135,9 @@
|
|||
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b
|
||||
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI 0x0255
|
||||
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0291
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0292
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0293
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292
|
||||
#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
|
||||
#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
|
||||
#define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240
|
||||
|
|
@ -646,6 +646,7 @@
|
|||
#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_16 0x0012
|
||||
#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17 0x0013
|
||||
#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18 0x0014
|
||||
#define USB_DEVICE_ID_NTRIG_DUOSENSE 0x1500
|
||||
|
||||
#define USB_VENDOR_ID_ONTRAK 0x0a07
|
||||
#define USB_DEVICE_ID_ONTRAK_ADU100 0x0064
|
||||
|
|
|
|||
|
|
@ -340,7 +340,7 @@ static int hidinput_get_battery_property(struct power_supply *psy,
|
|||
{
|
||||
struct hid_device *dev = container_of(psy, struct hid_device, battery);
|
||||
int ret = 0;
|
||||
__u8 buf[2] = {};
|
||||
__u8 *buf;
|
||||
|
||||
switch (prop) {
|
||||
case POWER_SUPPLY_PROP_PRESENT:
|
||||
|
|
@ -349,13 +349,20 @@ static int hidinput_get_battery_property(struct power_supply *psy,
|
|||
break;
|
||||
|
||||
case POWER_SUPPLY_PROP_CAPACITY:
|
||||
|
||||
buf = kmalloc(2 * sizeof(__u8), GFP_KERNEL);
|
||||
if (!buf) {
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
}
|
||||
ret = dev->hid_get_raw_report(dev, dev->battery_report_id,
|
||||
buf, sizeof(buf),
|
||||
buf, 2,
|
||||
dev->battery_report_type);
|
||||
|
||||
if (ret != 2) {
|
||||
if (ret >= 0)
|
||||
ret = -EINVAL;
|
||||
kfree(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -364,6 +371,7 @@ static int hidinput_get_battery_property(struct power_supply *psy,
|
|||
buf[1] <= dev->battery_max)
|
||||
val->intval = (100 * (buf[1] - dev->battery_min)) /
|
||||
(dev->battery_max - dev->battery_min);
|
||||
kfree(buf);
|
||||
break;
|
||||
|
||||
case POWER_SUPPLY_PROP_MODEL_NAME:
|
||||
|
|
|
|||
|
|
@ -115,7 +115,8 @@ static inline int ntrig_get_mode(struct hid_device *hdev)
|
|||
struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT].
|
||||
report_id_hash[0x0d];
|
||||
|
||||
if (!report)
|
||||
if (!report || report->maxfield < 1 ||
|
||||
report->field[0]->report_count < 1)
|
||||
return -EINVAL;
|
||||
|
||||
hid_hw_request(hdev, report, HID_REQ_GET_REPORT);
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ void picolcd_exit_cir(struct picolcd_data *data)
|
|||
struct rc_dev *rdev = data->rc_dev;
|
||||
|
||||
data->rc_dev = NULL;
|
||||
rc_unregister_device(rdev);
|
||||
if (rdev)
|
||||
rc_unregister_device(rdev);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -290,7 +290,7 @@ static ssize_t picolcd_operation_mode_store(struct device *dev,
|
|||
buf += 10;
|
||||
cnt -= 10;
|
||||
}
|
||||
if (!report)
|
||||
if (!report || report->maxfield != 1)
|
||||
return -EINVAL;
|
||||
|
||||
while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r'))
|
||||
|
|
|
|||
|
|
@ -593,10 +593,14 @@ int picolcd_init_framebuffer(struct picolcd_data *data)
|
|||
void picolcd_exit_framebuffer(struct picolcd_data *data)
|
||||
{
|
||||
struct fb_info *info = data->fb_info;
|
||||
struct picolcd_fb_data *fbdata = info->par;
|
||||
struct picolcd_fb_data *fbdata;
|
||||
unsigned long flags;
|
||||
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate);
|
||||
fbdata = info->par;
|
||||
|
||||
/* disconnect framebuffer from HID dev */
|
||||
spin_lock_irqsave(&fbdata->lock, flags);
|
||||
|
|
|
|||
|
|
@ -132,8 +132,14 @@ static int plff_init(struct hid_device *hid)
|
|||
strong = &report->field[0]->value[2];
|
||||
weak = &report->field[0]->value[3];
|
||||
debug("detected single-field device");
|
||||
} else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 &&
|
||||
report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) {
|
||||
} else if (report->field[0]->maxusage == 1 &&
|
||||
report->field[0]->usage[0].hid ==
|
||||
(HID_UP_LED | 0x43) &&
|
||||
report->maxfield >= 4 &&
|
||||
report->field[0]->report_count >= 1 &&
|
||||
report->field[1]->report_count >= 1 &&
|
||||
report->field[2]->report_count >= 1 &&
|
||||
report->field[3]->report_count >= 1) {
|
||||
report->field[0]->value[0] = 0x00;
|
||||
report->field[1]->value[0] = 0x00;
|
||||
strong = &report->field[2]->value[0];
|
||||
|
|
|
|||
|
|
@ -221,7 +221,8 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
|
|||
|
||||
mutex_lock(&data->mutex);
|
||||
report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
|
||||
if (!report || (field_index >= report->maxfield)) {
|
||||
if (!report || (field_index >= report->maxfield) ||
|
||||
report->field[field_index]->report_count < 1) {
|
||||
ret = -EINVAL;
|
||||
goto done_proc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* Fixes "jumpy" cursor and removes nonexistent keyboard LEDS from
|
||||
* the HID descriptor.
|
||||
*
|
||||
* Copyright (c) 2011 Stefan Kriwanek <mail@stefankriwanek.de>
|
||||
* Copyright (c) 2011, 2013 Stefan Kriwanek <dev@stefankriwanek.de>
|
||||
*/
|
||||
|
||||
/*
|
||||
|
|
@ -46,8 +46,13 @@ static int speedlink_event(struct hid_device *hdev, struct hid_field *field,
|
|||
struct hid_usage *usage, __s32 value)
|
||||
{
|
||||
/* No other conditions due to usage_table. */
|
||||
/* Fix "jumpy" cursor (invalid events sent by device). */
|
||||
if (value == 256)
|
||||
|
||||
/* This fixes the "jumpy" cursor occuring due to invalid events sent
|
||||
* by the device. Some devices only send them with value==+256, others
|
||||
* don't. However, catching abs(value)>=256 is restrictive enough not
|
||||
* to interfere with devices that were bug-free (has been tested).
|
||||
*/
|
||||
if (abs(value) >= 256)
|
||||
return 1;
|
||||
/* Drop useless distance 0 events (on button clicks etc.) as well */
|
||||
if (value == 0)
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer,
|
|||
__u8 *buf;
|
||||
int ret = 0;
|
||||
|
||||
if (!hidraw_table[minor]) {
|
||||
if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -261,7 +261,7 @@ static int hidraw_open(struct inode *inode, struct file *file)
|
|||
}
|
||||
|
||||
mutex_lock(&minors_lock);
|
||||
if (!hidraw_table[minor]) {
|
||||
if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
|
||||
err = -ENODEV;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
|
@ -302,39 +302,38 @@ static int hidraw_fasync(int fd, struct file *file, int on)
|
|||
return fasync_helper(fd, file, on, &list->fasync);
|
||||
}
|
||||
|
||||
static void drop_ref(struct hidraw *hidraw, int exists_bit)
|
||||
{
|
||||
if (exists_bit) {
|
||||
hid_hw_close(hidraw->hid);
|
||||
hidraw->exist = 0;
|
||||
if (hidraw->open)
|
||||
wake_up_interruptible(&hidraw->wait);
|
||||
} else {
|
||||
--hidraw->open;
|
||||
}
|
||||
|
||||
if (!hidraw->open && !hidraw->exist) {
|
||||
device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
|
||||
hidraw_table[hidraw->minor] = NULL;
|
||||
kfree(hidraw);
|
||||
}
|
||||
}
|
||||
|
||||
static int hidraw_release(struct inode * inode, struct file * file)
|
||||
{
|
||||
unsigned int minor = iminor(inode);
|
||||
struct hidraw *dev;
|
||||
struct hidraw_list *list = file->private_data;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
mutex_lock(&minors_lock);
|
||||
if (!hidraw_table[minor]) {
|
||||
ret = -ENODEV;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
list_del(&list->node);
|
||||
dev = hidraw_table[minor];
|
||||
if (!--dev->open) {
|
||||
if (list->hidraw->exist) {
|
||||
hid_hw_power(dev->hid, PM_HINT_NORMAL);
|
||||
hid_hw_close(dev->hid);
|
||||
} else {
|
||||
kfree(list->hidraw);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i)
|
||||
kfree(list->buffer[i].value);
|
||||
kfree(list);
|
||||
ret = 0;
|
||||
unlock:
|
||||
mutex_unlock(&minors_lock);
|
||||
|
||||
return ret;
|
||||
drop_ref(hidraw_table[minor], 0);
|
||||
|
||||
mutex_unlock(&minors_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long hidraw_ioctl(struct file *file, unsigned int cmd,
|
||||
|
|
@ -539,18 +538,9 @@ void hidraw_disconnect(struct hid_device *hid)
|
|||
struct hidraw *hidraw = hid->hidraw;
|
||||
|
||||
mutex_lock(&minors_lock);
|
||||
hidraw->exist = 0;
|
||||
|
||||
device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
|
||||
drop_ref(hidraw, 1);
|
||||
|
||||
hidraw_table[hidraw->minor] = NULL;
|
||||
|
||||
if (hidraw->open) {
|
||||
hid_hw_close(hid);
|
||||
wake_up_interruptible(&hidraw->wait);
|
||||
} else {
|
||||
kfree(hidraw);
|
||||
}
|
||||
mutex_unlock(&minors_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hidraw_disconnect);
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@ static const struct hid_blacklist {
|
|||
{ USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },
|
||||
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT },
|
||||
{ USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_DUOSENSE, HID_QUIRK_NO_INIT_REPORTS },
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -89,9 +89,9 @@
|
|||
#define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b
|
||||
/* MacbookAir6,2 (unibody, June 2013) */
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0291
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0292
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0293
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291
|
||||
#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292
|
||||
|
||||
#define BCM5974_DEVICE(prod) { \
|
||||
.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \
|
||||
|
|
|
|||
|
|
@ -890,56 +890,54 @@ static int dma_pte_clear_range(struct dmar_domain *domain,
|
|||
return order;
|
||||
}
|
||||
|
||||
static void dma_pte_free_level(struct dmar_domain *domain, int level,
|
||||
struct dma_pte *pte, unsigned long pfn,
|
||||
unsigned long start_pfn, unsigned long last_pfn)
|
||||
{
|
||||
pfn = max(start_pfn, pfn);
|
||||
pte = &pte[pfn_level_offset(pfn, level)];
|
||||
|
||||
do {
|
||||
unsigned long level_pfn;
|
||||
struct dma_pte *level_pte;
|
||||
|
||||
if (!dma_pte_present(pte) || dma_pte_superpage(pte))
|
||||
goto next;
|
||||
|
||||
level_pfn = pfn & level_mask(level - 1);
|
||||
level_pte = phys_to_virt(dma_pte_addr(pte));
|
||||
|
||||
if (level > 2)
|
||||
dma_pte_free_level(domain, level - 1, level_pte,
|
||||
level_pfn, start_pfn, last_pfn);
|
||||
|
||||
/* If range covers entire pagetable, free it */
|
||||
if (!(start_pfn > level_pfn ||
|
||||
last_pfn < level_pfn + level_size(level))) {
|
||||
dma_clear_pte(pte);
|
||||
domain_flush_cache(domain, pte, sizeof(*pte));
|
||||
free_pgtable_page(level_pte);
|
||||
}
|
||||
next:
|
||||
pfn += level_size(level);
|
||||
} while (!first_pte_in_page(++pte) && pfn <= last_pfn);
|
||||
}
|
||||
|
||||
/* free page table pages. last level pte should already be cleared */
|
||||
static void dma_pte_free_pagetable(struct dmar_domain *domain,
|
||||
unsigned long start_pfn,
|
||||
unsigned long last_pfn)
|
||||
{
|
||||
int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
|
||||
struct dma_pte *first_pte, *pte;
|
||||
int total = agaw_to_level(domain->agaw);
|
||||
int level;
|
||||
unsigned long tmp;
|
||||
int large_page = 2;
|
||||
|
||||
BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width);
|
||||
BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width);
|
||||
BUG_ON(start_pfn > last_pfn);
|
||||
|
||||
/* We don't need lock here; nobody else touches the iova range */
|
||||
level = 2;
|
||||
while (level <= total) {
|
||||
tmp = align_to_level(start_pfn, level);
|
||||
dma_pte_free_level(domain, agaw_to_level(domain->agaw),
|
||||
domain->pgd, 0, start_pfn, last_pfn);
|
||||
|
||||
/* If we can't even clear one PTE at this level, we're done */
|
||||
if (tmp + level_size(level) - 1 > last_pfn)
|
||||
return;
|
||||
|
||||
do {
|
||||
large_page = level;
|
||||
first_pte = pte = dma_pfn_level_pte(domain, tmp, level, &large_page);
|
||||
if (large_page > level)
|
||||
level = large_page + 1;
|
||||
if (!pte) {
|
||||
tmp = align_to_level(tmp + 1, level + 1);
|
||||
continue;
|
||||
}
|
||||
do {
|
||||
if (dma_pte_present(pte)) {
|
||||
free_pgtable_page(phys_to_virt(dma_pte_addr(pte)));
|
||||
dma_clear_pte(pte);
|
||||
}
|
||||
pte++;
|
||||
tmp += level_size(level);
|
||||
} while (!first_pte_in_page(pte) &&
|
||||
tmp + level_size(level) - 1 <= last_pfn);
|
||||
|
||||
domain_flush_cache(domain, first_pte,
|
||||
(void *)pte - (void *)first_pte);
|
||||
|
||||
} while (tmp && tmp + level_size(level) - 1 <= last_pfn);
|
||||
level++;
|
||||
}
|
||||
/* free pgd */
|
||||
if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) {
|
||||
free_pgtable_page(domain->pgd);
|
||||
|
|
|
|||
|
|
@ -230,9 +230,9 @@ static int wm831x_status_probe(struct platform_device *pdev)
|
|||
int id = pdev->id % ARRAY_SIZE(chip_pdata->status);
|
||||
int ret;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
|
||||
res = platform_get_resource(pdev, IORESOURCE_REG, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "No I/O resource\n");
|
||||
dev_err(&pdev->dev, "No register resource\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -275,7 +275,8 @@ static void smsdvb_update_per_slices(struct smsdvb_client_t *client,
|
|||
|
||||
/* Legacy PER/BER */
|
||||
tmp = p->ets_packets * 65535;
|
||||
do_div(tmp, p->ts_packets + p->ets_packets);
|
||||
if (p->ts_packets + p->ets_packets)
|
||||
do_div(tmp, p->ts_packets + p->ets_packets);
|
||||
client->legacy_per = tmp;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -157,7 +157,6 @@ static struct regdata mb86a20s_init2[] = {
|
|||
{ 0x45, 0x04 }, /* CN symbol 4 */
|
||||
{ 0x48, 0x04 }, /* CN manual mode */
|
||||
|
||||
{ 0x50, 0xd5 }, { 0x51, 0x01 }, /* Serial */
|
||||
{ 0x50, 0xd6 }, { 0x51, 0x1f },
|
||||
{ 0x50, 0xd2 }, { 0x51, 0x03 },
|
||||
{ 0x50, 0xd7 }, { 0x51, 0xbf },
|
||||
|
|
@ -1860,16 +1859,15 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
|
|||
dev_dbg(&state->i2c->dev, "%s: IF=%d, IF reg=0x%06llx\n",
|
||||
__func__, state->if_freq, (long long)pll);
|
||||
|
||||
if (!state->config->is_serial) {
|
||||
if (!state->config->is_serial)
|
||||
regD5 &= ~1;
|
||||
|
||||
rc = mb86a20s_writereg(state, 0x50, 0xd5);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
rc = mb86a20s_writereg(state, 0x51, regD5);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
}
|
||||
rc = mb86a20s_writereg(state, 0x50, 0xd5);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
rc = mb86a20s_writereg(state, 0x51, regD5);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
|
||||
rc = mb86a20s_writeregdata(state, mb86a20s_init2);
|
||||
if (rc < 0)
|
||||
|
|
|
|||
|
|
@ -1933,7 +1933,7 @@ MODULE_DEVICE_TABLE(platform, coda_platform_ids);
|
|||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id coda_dt_ids[] = {
|
||||
{ .compatible = "fsl,imx27-vpu", .data = &coda_platform_ids[CODA_IMX27] },
|
||||
{ .compatible = "fsl,imx27-vpu", .data = &coda_devdata[CODA_IMX27] },
|
||||
{ .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1122,10 +1122,14 @@ static int gsc_probe(struct platform_device *pdev)
|
|||
goto err_clk;
|
||||
}
|
||||
|
||||
ret = gsc_register_m2m_device(gsc);
|
||||
ret = v4l2_device_register(dev, &gsc->v4l2_dev);
|
||||
if (ret)
|
||||
goto err_clk;
|
||||
|
||||
ret = gsc_register_m2m_device(gsc);
|
||||
if (ret)
|
||||
goto err_v4l2;
|
||||
|
||||
platform_set_drvdata(pdev, gsc);
|
||||
pm_runtime_enable(dev);
|
||||
ret = pm_runtime_get_sync(&pdev->dev);
|
||||
|
|
@ -1147,6 +1151,8 @@ static int gsc_probe(struct platform_device *pdev)
|
|||
pm_runtime_put(dev);
|
||||
err_m2m:
|
||||
gsc_unregister_m2m_device(gsc);
|
||||
err_v4l2:
|
||||
v4l2_device_unregister(&gsc->v4l2_dev);
|
||||
err_clk:
|
||||
gsc_clk_put(gsc);
|
||||
return ret;
|
||||
|
|
@ -1157,6 +1163,7 @@ static int gsc_remove(struct platform_device *pdev)
|
|||
struct gsc_dev *gsc = platform_get_drvdata(pdev);
|
||||
|
||||
gsc_unregister_m2m_device(gsc);
|
||||
v4l2_device_unregister(&gsc->v4l2_dev);
|
||||
|
||||
vb2_dma_contig_cleanup_ctx(gsc->alloc_ctx);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
|
|
|||
|
|
@ -343,6 +343,7 @@ struct gsc_dev {
|
|||
unsigned long state;
|
||||
struct vb2_alloc_ctx *alloc_ctx;
|
||||
struct video_device vdev;
|
||||
struct v4l2_device v4l2_dev;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -751,6 +751,7 @@ int gsc_register_m2m_device(struct gsc_dev *gsc)
|
|||
gsc->vdev.release = video_device_release_empty;
|
||||
gsc->vdev.lock = &gsc->lock;
|
||||
gsc->vdev.vfl_dir = VFL_DIR_M2M;
|
||||
gsc->vdev.v4l2_dev = &gsc->v4l2_dev;
|
||||
snprintf(gsc->vdev.name, sizeof(gsc->vdev.name), "%s.%d:m2m",
|
||||
GSC_MODULE_NAME, gsc->id);
|
||||
|
||||
|
|
|
|||
|
|
@ -1441,9 +1441,9 @@ static int fimc_md_probe(struct platform_device *pdev)
|
|||
err_unlock:
|
||||
mutex_unlock(&fmd->media_dev.graph_mutex);
|
||||
err_clk:
|
||||
media_device_unregister(&fmd->media_dev);
|
||||
fimc_md_put_clocks(fmd);
|
||||
fimc_md_unregister_entities(fmd);
|
||||
media_device_unregister(&fmd->media_dev);
|
||||
err_md:
|
||||
v4l2_device_unregister(&fmd->v4l2_dev);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -784,6 +784,7 @@ static int g2d_probe(struct platform_device *pdev)
|
|||
}
|
||||
*vfd = g2d_videodev;
|
||||
vfd->lock = &dev->mutex;
|
||||
vfd->v4l2_dev = &dev->v4l2_dev;
|
||||
ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
|
||||
if (ret) {
|
||||
v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
|
||||
|
|
|
|||
|
|
@ -311,6 +311,11 @@ static int hdpvr_probe(struct usb_interface *interface,
|
|||
|
||||
dev->workqueue = 0;
|
||||
|
||||
/* init video transfer queues first of all */
|
||||
/* to prevent oops in hdpvr_delete() on error paths */
|
||||
INIT_LIST_HEAD(&dev->free_buff_list);
|
||||
INIT_LIST_HEAD(&dev->rec_buff_list);
|
||||
|
||||
/* register v4l2_device early so it can be used for printks */
|
||||
if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
|
||||
dev_err(&interface->dev, "v4l2_device_register failed\n");
|
||||
|
|
@ -333,10 +338,6 @@ static int hdpvr_probe(struct usb_interface *interface,
|
|||
if (!dev->workqueue)
|
||||
goto error;
|
||||
|
||||
/* init video transfer queues */
|
||||
INIT_LIST_HEAD(&dev->free_buff_list);
|
||||
INIT_LIST_HEAD(&dev->rec_buff_list);
|
||||
|
||||
dev->options = hdpvr_default_options;
|
||||
|
||||
if (default_video_input < HDPVR_VIDEO_INPUTS)
|
||||
|
|
@ -413,7 +414,7 @@ static int hdpvr_probe(struct usb_interface *interface,
|
|||
video_nr[atomic_inc_return(&dev_nr)]);
|
||||
if (retval < 0) {
|
||||
v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
|
||||
goto error;
|
||||
goto reg_fail;
|
||||
}
|
||||
|
||||
/* let the user know what node this device is now attached to */
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
|
|||
pio:
|
||||
if (!desc) {
|
||||
/* DMA failed, fall back to PIO */
|
||||
tmio_mmc_enable_dma(host, false);
|
||||
if (ret >= 0)
|
||||
ret = -EIO;
|
||||
host->chan_rx = NULL;
|
||||
|
|
@ -116,7 +117,6 @@ static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
|
|||
}
|
||||
dev_warn(&host->pdev->dev,
|
||||
"DMA failed: %d, falling back to PIO\n", ret);
|
||||
tmio_mmc_enable_dma(host, false);
|
||||
}
|
||||
|
||||
dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__,
|
||||
|
|
@ -185,6 +185,7 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
|
|||
pio:
|
||||
if (!desc) {
|
||||
/* DMA failed, fall back to PIO */
|
||||
tmio_mmc_enable_dma(host, false);
|
||||
if (ret >= 0)
|
||||
ret = -EIO;
|
||||
host->chan_tx = NULL;
|
||||
|
|
@ -197,7 +198,6 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
|
|||
}
|
||||
dev_warn(&host->pdev->dev,
|
||||
"DMA failed: %d, falling back to PIO\n", ret);
|
||||
tmio_mmc_enable_dma(host, false);
|
||||
}
|
||||
|
||||
dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d\n", __func__,
|
||||
|
|
|
|||
|
|
@ -2793,7 +2793,9 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
|
|||
|
||||
if (!chip->select_chip)
|
||||
chip->select_chip = nand_select_chip;
|
||||
if (!chip->read_byte)
|
||||
|
||||
/* If called twice, pointers that depend on busw may need to be reset */
|
||||
if (!chip->read_byte || chip->read_byte == nand_read_byte)
|
||||
chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;
|
||||
if (!chip->read_word)
|
||||
chip->read_word = nand_read_word;
|
||||
|
|
@ -2801,9 +2803,9 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
|
|||
chip->block_bad = nand_block_bad;
|
||||
if (!chip->block_markbad)
|
||||
chip->block_markbad = nand_default_block_markbad;
|
||||
if (!chip->write_buf)
|
||||
if (!chip->write_buf || chip->write_buf == nand_write_buf)
|
||||
chip->write_buf = busw ? nand_write_buf16 : nand_write_buf;
|
||||
if (!chip->read_buf)
|
||||
if (!chip->read_buf || chip->read_buf == nand_read_buf)
|
||||
chip->read_buf = busw ? nand_read_buf16 : nand_read_buf;
|
||||
if (!chip->scan_bbt)
|
||||
chip->scan_bbt = nand_default_bbt;
|
||||
|
|
|
|||
|
|
@ -1069,6 +1069,9 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
|
|||
if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) {
|
||||
dbg_wl("no WL needed: min used EC %d, max free EC %d",
|
||||
e1->ec, e2->ec);
|
||||
|
||||
/* Give the unused PEB back */
|
||||
wl_tree_add(e2, &ubi->free);
|
||||
goto out_cancel;
|
||||
}
|
||||
self_check_in_wl_tree(ubi, e1, &ubi->used);
|
||||
|
|
|
|||
|
|
@ -1076,6 +1076,10 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah,
|
|||
* is_on == 0 means MRC CCK is OFF (more noise imm)
|
||||
*/
|
||||
bool is_on = param ? 1 : 0;
|
||||
|
||||
if (ah->caps.rx_chainmask == 1)
|
||||
break;
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
|
||||
AR_PHY_MRC_CCK_ENABLE, is_on);
|
||||
REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
|
||||
|
|
|
|||
|
|
@ -79,10 +79,6 @@ struct ath_config {
|
|||
sizeof(struct ath_buf_state)); \
|
||||
} while (0)
|
||||
|
||||
#define ATH_RXBUF_RESET(_bf) do { \
|
||||
(_bf)->bf_stale = false; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* enum buffer_type - Buffer type flags
|
||||
*
|
||||
|
|
@ -316,6 +312,7 @@ struct ath_rx {
|
|||
struct ath_descdma rxdma;
|
||||
struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
|
||||
|
||||
struct ath_buf *buf_hold;
|
||||
struct sk_buff *frag;
|
||||
|
||||
u32 ampdu_ref;
|
||||
|
|
|
|||
|
|
@ -42,8 +42,6 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
|
|||
struct ath_desc *ds;
|
||||
struct sk_buff *skb;
|
||||
|
||||
ATH_RXBUF_RESET(bf);
|
||||
|
||||
ds = bf->bf_desc;
|
||||
ds->ds_link = 0; /* link to null */
|
||||
ds->ds_data = bf->bf_buf_addr;
|
||||
|
|
@ -70,6 +68,14 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
|
|||
sc->rx.rxlink = &ds->ds_link;
|
||||
}
|
||||
|
||||
static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_buf *bf)
|
||||
{
|
||||
if (sc->rx.buf_hold)
|
||||
ath_rx_buf_link(sc, sc->rx.buf_hold);
|
||||
|
||||
sc->rx.buf_hold = bf;
|
||||
}
|
||||
|
||||
static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
|
||||
{
|
||||
/* XXX block beacon interrupts */
|
||||
|
|
@ -117,7 +123,6 @@ static bool ath_rx_edma_buf_link(struct ath_softc *sc,
|
|||
|
||||
skb = bf->bf_mpdu;
|
||||
|
||||
ATH_RXBUF_RESET(bf);
|
||||
memset(skb->data, 0, ah->caps.rx_status_len);
|
||||
dma_sync_single_for_device(sc->dev, bf->bf_buf_addr,
|
||||
ah->caps.rx_status_len, DMA_TO_DEVICE);
|
||||
|
|
@ -432,6 +437,7 @@ int ath_startrecv(struct ath_softc *sc)
|
|||
if (list_empty(&sc->rx.rxbuf))
|
||||
goto start_recv;
|
||||
|
||||
sc->rx.buf_hold = NULL;
|
||||
sc->rx.rxlink = NULL;
|
||||
list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
|
||||
ath_rx_buf_link(sc, bf);
|
||||
|
|
@ -677,6 +683,9 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
|
|||
}
|
||||
|
||||
bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
|
||||
if (bf == sc->rx.buf_hold)
|
||||
return NULL;
|
||||
|
||||
ds = bf->bf_desc;
|
||||
|
||||
/*
|
||||
|
|
@ -1378,7 +1387,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
|
|||
if (edma) {
|
||||
ath_rx_edma_buf_link(sc, qtype);
|
||||
} else {
|
||||
ath_rx_buf_link(sc, bf);
|
||||
ath_rx_buf_relink(sc, bf);
|
||||
ath9k_hw_rxena(ah);
|
||||
}
|
||||
} while (1);
|
||||
|
|
|
|||
|
|
@ -2387,6 +2387,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
|
|||
for (acno = 0, ac = &an->ac[acno];
|
||||
acno < IEEE80211_NUM_ACS; acno++, ac++) {
|
||||
ac->sched = false;
|
||||
ac->clear_ps_filter = true;
|
||||
ac->txq = sc->tx.txq_map[acno];
|
||||
INIT_LIST_HEAD(&ac->tid_q);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1015,9 +1015,10 @@ static bool dma64_txidle(struct dma_info *di)
|
|||
|
||||
/*
|
||||
* post receive buffers
|
||||
* return false is refill failed completely and ring is empty this will stall
|
||||
* the rx dma and user might want to call rxfill again asap. This unlikely
|
||||
* happens on memory-rich NIC, but often on memory-constrained dongle
|
||||
* Return false if refill failed completely or dma mapping failed. The ring
|
||||
* is empty, which will stall the rx dma and user might want to call rxfill
|
||||
* again asap. This is unlikely to happen on a memory-rich NIC, but often on
|
||||
* memory-constrained dongle.
|
||||
*/
|
||||
bool dma_rxfill(struct dma_pub *pub)
|
||||
{
|
||||
|
|
@ -1078,6 +1079,8 @@ bool dma_rxfill(struct dma_pub *pub)
|
|||
|
||||
pa = dma_map_single(di->dmadev, p->data, di->rxbufsize,
|
||||
DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(di->dmadev, pa))
|
||||
return false;
|
||||
|
||||
/* save the free packet pointer */
|
||||
di->rxp[rxout] = p;
|
||||
|
|
@ -1284,7 +1287,11 @@ static void dma_txenq(struct dma_info *di, struct sk_buff *p)
|
|||
|
||||
/* get physical address of buffer start */
|
||||
pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE);
|
||||
|
||||
/* if mapping failed, free skb */
|
||||
if (dma_mapping_error(di->dmadev, pa)) {
|
||||
brcmu_pkt_buf_free_skb(p);
|
||||
return;
|
||||
}
|
||||
/* With a DMA segment list, Descriptor table is filled
|
||||
* using the segment list instead of looping over
|
||||
* buffers in multi-chain DMA. Therefore, EOF for SGLIST
|
||||
|
|
|
|||
|
|
@ -1629,6 +1629,7 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
|
|||
ap = dt_alloc(sizeof(*ap) + len + 1, 4);
|
||||
if (!ap)
|
||||
continue;
|
||||
memset(ap, 0, sizeof(*ap) + len + 1);
|
||||
ap->alias = start;
|
||||
of_alias_add(ap, np, id, start, len);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ static void at91_mux_disable_interrupt(void __iomem *pio, unsigned mask)
|
|||
|
||||
static unsigned at91_mux_get_pullup(void __iomem *pio, unsigned pin)
|
||||
{
|
||||
return (readl_relaxed(pio + PIO_PUSR) >> pin) & 0x1;
|
||||
return !((readl_relaxed(pio + PIO_PUSR) >> pin) & 0x1);
|
||||
}
|
||||
|
||||
static void at91_mux_set_pullup(void __iomem *pio, unsigned mask, bool on)
|
||||
|
|
@ -445,7 +445,7 @@ static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask,
|
|||
|
||||
static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin)
|
||||
{
|
||||
return (__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1;
|
||||
return !((__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1);
|
||||
}
|
||||
|
||||
static void at91_mux_pio3_set_pulldown(void __iomem *pio, unsigned mask, bool is_on)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# mpt3sas makefile
|
||||
obj-m += mpt3sas.o
|
||||
obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas.o
|
||||
mpt3sas-y += mpt3sas_base.o \
|
||||
mpt3sas_config.o \
|
||||
mpt3sas_scsih.o \
|
||||
|
|
|
|||
|
|
@ -2409,14 +2409,9 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
|
|||
}
|
||||
}
|
||||
|
||||
if (modepage == 0x3F) {
|
||||
sd_printk(KERN_ERR, sdkp, "No Caching mode page "
|
||||
"present\n");
|
||||
goto defaults;
|
||||
} else if ((buffer[offset] & 0x3f) != modepage) {
|
||||
sd_printk(KERN_ERR, sdkp, "Got wrong page\n");
|
||||
goto defaults;
|
||||
}
|
||||
sd_printk(KERN_ERR, sdkp, "No Caching mode page found\n");
|
||||
goto defaults;
|
||||
|
||||
Page_found:
|
||||
if (modepage == 8) {
|
||||
sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0);
|
||||
|
|
|
|||
|
|
@ -269,8 +269,9 @@ struct dt282x_private {
|
|||
} \
|
||||
udelay(5); \
|
||||
} \
|
||||
if (_i) \
|
||||
if (_i) { \
|
||||
b \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static int prep_ai_dma(struct comedi_device *dev, int chan, int size);
|
||||
|
|
|
|||
|
|
@ -234,7 +234,6 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
|
|||
{
|
||||
struct mxs_lradc *lradc = iio_priv(iio_dev);
|
||||
int ret;
|
||||
unsigned long mask;
|
||||
|
||||
if (m != IIO_CHAN_INFO_RAW)
|
||||
return -EINVAL;
|
||||
|
|
@ -243,12 +242,6 @@ static int mxs_lradc_read_raw(struct iio_dev *iio_dev,
|
|||
if (chan->channel > LRADC_MAX_TOTAL_CHANS)
|
||||
return -EINVAL;
|
||||
|
||||
/* Validate the channel if it doesn't intersect with reserved chans. */
|
||||
bitmap_set(&mask, chan->channel, 1);
|
||||
ret = iio_validate_scan_mask_onehot(iio_dev, &mask);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* See if there is no buffered operation in progess. If there is, simply
|
||||
* bail out. This can be improved to support both buffered and raw IO at
|
||||
|
|
@ -661,12 +654,13 @@ static int mxs_lradc_trigger_init(struct iio_dev *iio)
|
|||
{
|
||||
int ret;
|
||||
struct iio_trigger *trig;
|
||||
struct mxs_lradc *lradc = iio_priv(iio);
|
||||
|
||||
trig = iio_trigger_alloc("%s-dev%i", iio->name, iio->id);
|
||||
if (trig == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
trig->dev.parent = iio->dev.parent;
|
||||
trig->dev.parent = lradc->dev;
|
||||
iio_trigger_set_drvdata(trig, iio);
|
||||
trig->ops = &mxs_lradc_trigger_ops;
|
||||
|
||||
|
|
@ -676,15 +670,17 @@ static int mxs_lradc_trigger_init(struct iio_dev *iio)
|
|||
return ret;
|
||||
}
|
||||
|
||||
iio->trig = trig;
|
||||
lradc->trig = trig;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mxs_lradc_trigger_remove(struct iio_dev *iio)
|
||||
{
|
||||
iio_trigger_unregister(iio->trig);
|
||||
iio_trigger_free(iio->trig);
|
||||
struct mxs_lradc *lradc = iio_priv(iio);
|
||||
|
||||
iio_trigger_unregister(lradc->trig);
|
||||
iio_trigger_free(lradc->trig);
|
||||
}
|
||||
|
||||
static int mxs_lradc_buffer_preenable(struct iio_dev *iio)
|
||||
|
|
|
|||
|
|
@ -730,7 +730,7 @@ static int core_alua_write_tpg_metadata(
|
|||
if (ret < 0)
|
||||
pr_err("Error writing ALUA metadata file: %s\n", path);
|
||||
fput(file);
|
||||
return ret ? -EIO : 0;
|
||||
return (ret < 0) ? -EIO : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1987,7 +1987,7 @@ static int __core_scsi3_write_aptpl_to_file(
|
|||
pr_debug("Error writing APTPL metadata file: %s\n", path);
|
||||
fput(file);
|
||||
|
||||
return ret ? -EIO : 0;
|
||||
return (ret < 0) ? -EIO : 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
|||
|
|
@ -850,7 +850,8 @@ void disassociate_ctty(int on_exit)
|
|||
struct pid *tty_pgrp = tty_get_pgrp(tty);
|
||||
if (tty_pgrp) {
|
||||
kill_pgrp(tty_pgrp, SIGHUP, on_exit);
|
||||
kill_pgrp(tty_pgrp, SIGCONT, on_exit);
|
||||
if (!on_exit)
|
||||
kill_pgrp(tty_pgrp, SIGCONT, on_exit);
|
||||
put_pid(tty_pgrp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -209,6 +209,7 @@ static void wdm_in_callback(struct urb *urb)
|
|||
static void wdm_int_callback(struct urb *urb)
|
||||
{
|
||||
int rv = 0;
|
||||
int responding;
|
||||
int status = urb->status;
|
||||
struct wdm_device *desc;
|
||||
struct usb_cdc_notification *dr;
|
||||
|
|
@ -262,8 +263,8 @@ static void wdm_int_callback(struct urb *urb)
|
|||
|
||||
spin_lock(&desc->iuspin);
|
||||
clear_bit(WDM_READ, &desc->flags);
|
||||
set_bit(WDM_RESPONDING, &desc->flags);
|
||||
if (!test_bit(WDM_DISCONNECTING, &desc->flags)
|
||||
responding = test_and_set_bit(WDM_RESPONDING, &desc->flags);
|
||||
if (!responding && !test_bit(WDM_DISCONNECTING, &desc->flags)
|
||||
&& !test_bit(WDM_SUSPENDING, &desc->flags)) {
|
||||
rv = usb_submit_urb(desc->response, GFP_ATOMIC);
|
||||
dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d",
|
||||
|
|
@ -685,16 +686,20 @@ static void wdm_rxwork(struct work_struct *work)
|
|||
{
|
||||
struct wdm_device *desc = container_of(work, struct wdm_device, rxwork);
|
||||
unsigned long flags;
|
||||
int rv;
|
||||
int rv = 0;
|
||||
int responding;
|
||||
|
||||
spin_lock_irqsave(&desc->iuspin, flags);
|
||||
if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
|
||||
spin_unlock_irqrestore(&desc->iuspin, flags);
|
||||
} else {
|
||||
responding = test_and_set_bit(WDM_RESPONDING, &desc->flags);
|
||||
spin_unlock_irqrestore(&desc->iuspin, flags);
|
||||
rv = usb_submit_urb(desc->response, GFP_KERNEL);
|
||||
if (!responding)
|
||||
rv = usb_submit_urb(desc->response, GFP_KERNEL);
|
||||
if (rv < 0 && rv != -EPERM) {
|
||||
spin_lock_irqsave(&desc->iuspin, flags);
|
||||
clear_bit(WDM_RESPONDING, &desc->flags);
|
||||
if (!test_bit(WDM_DISCONNECTING, &desc->flags))
|
||||
schedule_work(&desc->rxwork);
|
||||
spin_unlock_irqrestore(&desc->iuspin, flags);
|
||||
|
|
|
|||
|
|
@ -424,7 +424,8 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx,
|
|||
|
||||
memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
|
||||
if (config->desc.bDescriptorType != USB_DT_CONFIG ||
|
||||
config->desc.bLength < USB_DT_CONFIG_SIZE) {
|
||||
config->desc.bLength < USB_DT_CONFIG_SIZE ||
|
||||
config->desc.bLength > size) {
|
||||
dev_err(ddev, "invalid descriptor for config index %d: "
|
||||
"type = 0x%X, length = %d\n", cfgidx,
|
||||
config->desc.bDescriptorType, config->desc.bLength);
|
||||
|
|
|
|||
|
|
@ -2916,7 +2916,6 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
|
|||
{
|
||||
struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
|
||||
struct usb_port *port_dev = hub->ports[udev->portnum - 1];
|
||||
enum pm_qos_flags_status pm_qos_stat;
|
||||
int port1 = udev->portnum;
|
||||
int status;
|
||||
bool really_suspend = true;
|
||||
|
|
@ -2954,7 +2953,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
|
|||
status);
|
||||
/* bail if autosuspend is requested */
|
||||
if (PMSG_IS_AUTO(msg))
|
||||
return status;
|
||||
goto err_wakeup;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2963,14 +2962,16 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
|
|||
usb_set_usb2_hardware_lpm(udev, 0);
|
||||
|
||||
if (usb_disable_ltm(udev)) {
|
||||
dev_err(&udev->dev, "%s Failed to disable LTM before suspend\n.",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
dev_err(&udev->dev, "Failed to disable LTM before suspend\n.");
|
||||
status = -ENOMEM;
|
||||
if (PMSG_IS_AUTO(msg))
|
||||
goto err_ltm;
|
||||
}
|
||||
if (usb_unlocked_disable_lpm(udev)) {
|
||||
dev_err(&udev->dev, "%s Failed to disable LPM before suspend\n.",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
dev_err(&udev->dev, "Failed to disable LPM before suspend\n.");
|
||||
status = -ENOMEM;
|
||||
if (PMSG_IS_AUTO(msg))
|
||||
goto err_lpm3;
|
||||
}
|
||||
|
||||
/* see 7.1.7.6 */
|
||||
|
|
@ -2998,28 +2999,31 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
|
|||
if (status) {
|
||||
dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n",
|
||||
port1, status);
|
||||
/* paranoia: "should not happen" */
|
||||
if (udev->do_remote_wakeup) {
|
||||
if (!hub_is_superspeed(hub->hdev)) {
|
||||
(void) usb_control_msg(udev,
|
||||
usb_sndctrlpipe(udev, 0),
|
||||
USB_REQ_CLEAR_FEATURE,
|
||||
USB_RECIP_DEVICE,
|
||||
USB_DEVICE_REMOTE_WAKEUP, 0,
|
||||
NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
} else
|
||||
(void) usb_disable_function_remotewakeup(udev);
|
||||
|
||||
}
|
||||
|
||||
/* Try to enable USB3 LPM and LTM again */
|
||||
usb_unlocked_enable_lpm(udev);
|
||||
err_lpm3:
|
||||
usb_enable_ltm(udev);
|
||||
err_ltm:
|
||||
/* Try to enable USB2 hardware LPM again */
|
||||
if (udev->usb2_hw_lpm_capable == 1)
|
||||
usb_set_usb2_hardware_lpm(udev, 1);
|
||||
|
||||
/* Try to enable USB3 LTM and LPM again */
|
||||
usb_enable_ltm(udev);
|
||||
usb_unlocked_enable_lpm(udev);
|
||||
if (udev->do_remote_wakeup) {
|
||||
if (udev->speed < USB_SPEED_SUPER)
|
||||
usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
USB_REQ_CLEAR_FEATURE,
|
||||
USB_RECIP_DEVICE,
|
||||
USB_DEVICE_REMOTE_WAKEUP, 0,
|
||||
NULL, 0, USB_CTRL_SET_TIMEOUT);
|
||||
else
|
||||
usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
USB_REQ_CLEAR_FEATURE,
|
||||
USB_RECIP_INTERFACE,
|
||||
USB_INTRF_FUNC_SUSPEND, 0,
|
||||
NULL, 0, USB_CTRL_SET_TIMEOUT);
|
||||
}
|
||||
err_wakeup:
|
||||
|
||||
/* System sleep transitions should never fail */
|
||||
if (!PMSG_IS_AUTO(msg))
|
||||
|
|
@ -3037,16 +3041,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
|
|||
usb_set_device_state(udev, USB_STATE_SUSPENDED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether current status meets the requirement of
|
||||
* usb port power off mechanism
|
||||
*/
|
||||
pm_qos_stat = dev_pm_qos_flags(&port_dev->dev,
|
||||
PM_QOS_FLAG_NO_POWER_OFF);
|
||||
if (!udev->do_remote_wakeup
|
||||
&& pm_qos_stat != PM_QOS_FLAGS_ALL
|
||||
&& udev->persist_enabled
|
||||
&& !status) {
|
||||
if (status == 0 && !udev->do_remote_wakeup && udev->persist_enabled) {
|
||||
pm_runtime_put_sync(&port_dev->dev);
|
||||
port_dev->did_runtime_put = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,22 +89,19 @@ static int usb_port_runtime_resume(struct device *dev)
|
|||
retval = usb_hub_set_port_power(hdev, port1, true);
|
||||
if (port_dev->child && !retval) {
|
||||
/*
|
||||
* Wait for usb hub port to be reconnected in order to make
|
||||
* the resume procedure successful.
|
||||
* Attempt to wait for usb hub port to be reconnected in order
|
||||
* to make the resume procedure successful. The device may have
|
||||
* disconnected while the port was powered off, so ignore the
|
||||
* return status.
|
||||
*/
|
||||
retval = hub_port_debounce_be_connected(hub, port1);
|
||||
if (retval < 0) {
|
||||
if (retval < 0)
|
||||
dev_dbg(&port_dev->dev, "can't get reconnection after setting port power on, status %d\n",
|
||||
retval);
|
||||
goto out;
|
||||
}
|
||||
usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE);
|
||||
|
||||
/* Set return value to 0 if debounce successful */
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
clear_bit(port1, hub->busy_bits);
|
||||
usb_autopm_put_interface(intf);
|
||||
return retval;
|
||||
|
|
|
|||
|
|
@ -1508,6 +1508,15 @@ static int dwc3_gadget_start(struct usb_gadget *g,
|
|||
int irq;
|
||||
u32 reg;
|
||||
|
||||
irq = platform_get_irq(to_platform_device(dwc->dev), 0);
|
||||
ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
|
||||
IRQF_SHARED | IRQF_ONESHOT, "dwc3", dwc);
|
||||
if (ret) {
|
||||
dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
|
||||
irq, ret);
|
||||
goto err0;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&dwc->lock, flags);
|
||||
|
||||
if (dwc->gadget_driver) {
|
||||
|
|
@ -1515,7 +1524,7 @@ static int dwc3_gadget_start(struct usb_gadget *g,
|
|||
dwc->gadget.name,
|
||||
dwc->gadget_driver->driver.name);
|
||||
ret = -EBUSY;
|
||||
goto err0;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
dwc->gadget_driver = driver;
|
||||
|
|
@ -1551,42 +1560,38 @@ static int dwc3_gadget_start(struct usb_gadget *g,
|
|||
ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false);
|
||||
if (ret) {
|
||||
dev_err(dwc->dev, "failed to enable %s\n", dep->name);
|
||||
goto err0;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
dep = dwc->eps[1];
|
||||
ret = __dwc3_gadget_ep_enable(dep, &dwc3_gadget_ep0_desc, NULL, false);
|
||||
if (ret) {
|
||||
dev_err(dwc->dev, "failed to enable %s\n", dep->name);
|
||||
goto err1;
|
||||
goto err3;
|
||||
}
|
||||
|
||||
/* begin to receive SETUP packets */
|
||||
dwc->ep0state = EP0_SETUP_PHASE;
|
||||
dwc3_ep0_out_start(dwc);
|
||||
|
||||
irq = platform_get_irq(to_platform_device(dwc->dev), 0);
|
||||
ret = request_threaded_irq(irq, dwc3_interrupt, dwc3_thread_interrupt,
|
||||
IRQF_SHARED | IRQF_ONESHOT, "dwc3", dwc);
|
||||
if (ret) {
|
||||
dev_err(dwc->dev, "failed to request irq #%d --> %d\n",
|
||||
irq, ret);
|
||||
goto err1;
|
||||
}
|
||||
|
||||
dwc3_gadget_enable_irq(dwc);
|
||||
|
||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||
|
||||
return 0;
|
||||
|
||||
err1:
|
||||
err3:
|
||||
__dwc3_gadget_ep_disable(dwc->eps[0]);
|
||||
|
||||
err0:
|
||||
err2:
|
||||
dwc->gadget_driver = NULL;
|
||||
|
||||
err1:
|
||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||
|
||||
free_irq(irq, dwc);
|
||||
|
||||
err0:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1600,9 +1605,6 @@ static int dwc3_gadget_stop(struct usb_gadget *g,
|
|||
spin_lock_irqsave(&dwc->lock, flags);
|
||||
|
||||
dwc3_gadget_disable_irq(dwc);
|
||||
irq = platform_get_irq(to_platform_device(dwc->dev), 0);
|
||||
free_irq(irq, dwc);
|
||||
|
||||
__dwc3_gadget_ep_disable(dwc->eps[0]);
|
||||
__dwc3_gadget_ep_disable(dwc->eps[1]);
|
||||
|
||||
|
|
@ -1610,6 +1612,9 @@ static int dwc3_gadget_stop(struct usb_gadget *g,
|
|||
|
||||
spin_unlock_irqrestore(&dwc->lock, flags);
|
||||
|
||||
irq = platform_get_irq(to_platform_device(dwc->dev), 0);
|
||||
free_irq(irq, dwc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -177,12 +177,16 @@ static int uvc_queue_buffer(struct uvc_video_queue *queue,
|
|||
|
||||
mutex_lock(&queue->mutex);
|
||||
ret = vb2_qbuf(&queue->queue, buf);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
spin_lock_irqsave(&queue->irqlock, flags);
|
||||
ret = (queue->flags & UVC_QUEUE_PAUSED) != 0;
|
||||
queue->flags &= ~UVC_QUEUE_PAUSED;
|
||||
spin_unlock_irqrestore(&queue->irqlock, flags);
|
||||
mutex_unlock(&queue->mutex);
|
||||
|
||||
done:
|
||||
mutex_unlock(&queue->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ static int ehci_mxc_drv_remove(struct platform_device *pdev)
|
|||
if (pdata && pdata->exit)
|
||||
pdata->exit(pdev);
|
||||
|
||||
if (pdata->otg)
|
||||
if (pdata && pdata->otg)
|
||||
usb_phy_shutdown(pdata->otg);
|
||||
|
||||
clk_disable_unprepare(priv->usbclk);
|
||||
|
|
|
|||
|
|
@ -371,7 +371,7 @@ static struct pci_driver ohci_pci_driver = {
|
|||
.remove = usb_hcd_pci_remove,
|
||||
.shutdown = usb_hcd_pci_shutdown,
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_PM
|
||||
.driver = {
|
||||
.pm = &usb_hcd_pci_pm_ops
|
||||
},
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)
|
|||
* here that the generic code does not try to make a pci_dev from our
|
||||
* dev struct in order to setup MSI
|
||||
*/
|
||||
xhci->quirks |= XHCI_BROKEN_MSI;
|
||||
xhci->quirks |= XHCI_PLAT;
|
||||
}
|
||||
|
||||
/* called during probe() after chip reset completes */
|
||||
|
|
|
|||
|
|
@ -342,9 +342,14 @@ static void xhci_msix_sync_irqs(struct xhci_hcd *xhci)
|
|||
static int xhci_try_enable_msi(struct usb_hcd *hcd)
|
||||
{
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
|
||||
struct pci_dev *pdev;
|
||||
int ret;
|
||||
|
||||
/* The xhci platform device has set up IRQs through usb_add_hcd. */
|
||||
if (xhci->quirks & XHCI_PLAT)
|
||||
return 0;
|
||||
|
||||
pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
|
||||
/*
|
||||
* Some Fresco Logic host controllers advertise MSI, but fail to
|
||||
* generate interrupts. Don't even try to enable MSI.
|
||||
|
|
@ -3506,10 +3511,21 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
|
|||
{
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
struct xhci_virt_device *virt_dev;
|
||||
struct device *dev = hcd->self.controller;
|
||||
unsigned long flags;
|
||||
u32 state;
|
||||
int i, ret;
|
||||
|
||||
#ifndef CONFIG_USB_DEFAULT_PERSIST
|
||||
/*
|
||||
* We called pm_runtime_get_noresume when the device was attached.
|
||||
* Decrement the counter here to allow controller to runtime suspend
|
||||
* if no devices remain.
|
||||
*/
|
||||
if (xhci->quirks & XHCI_RESET_ON_RESUME)
|
||||
pm_runtime_put_noidle(dev);
|
||||
#endif
|
||||
|
||||
ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
|
||||
/* If the host is halted due to driver unload, we still need to free the
|
||||
* device.
|
||||
|
|
@ -3581,6 +3597,7 @@ static int xhci_reserve_host_control_ep_resources(struct xhci_hcd *xhci)
|
|||
int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
{
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
struct device *dev = hcd->self.controller;
|
||||
unsigned long flags;
|
||||
int timeleft;
|
||||
int ret;
|
||||
|
|
@ -3633,6 +3650,16 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
|
|||
goto disable_slot;
|
||||
}
|
||||
udev->slot_id = xhci->slot_id;
|
||||
|
||||
#ifndef CONFIG_USB_DEFAULT_PERSIST
|
||||
/*
|
||||
* If resetting upon resume, we can't put the controller into runtime
|
||||
* suspend if there is a device attached.
|
||||
*/
|
||||
if (xhci->quirks & XHCI_RESET_ON_RESUME)
|
||||
pm_runtime_get_noresume(dev);
|
||||
#endif
|
||||
|
||||
/* Is this a LS or FS device under a HS hub? */
|
||||
/* Hub or peripherial? */
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -1516,6 +1516,7 @@ struct xhci_hcd {
|
|||
#define XHCI_SPURIOUS_REBOOT (1 << 13)
|
||||
#define XHCI_COMP_MODE_QUIRK (1 << 14)
|
||||
#define XHCI_AVOID_BEI (1 << 15)
|
||||
#define XHCI_PLAT (1 << 16)
|
||||
unsigned int num_active_eps;
|
||||
unsigned int limit_active_eps;
|
||||
/* There are two roothubs to keep track of bus suspend info for */
|
||||
|
|
|
|||
|
|
@ -374,7 +374,7 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
|
|||
kfree(urbtrack);
|
||||
return -ENOMEM;
|
||||
}
|
||||
urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL);
|
||||
urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_ATOMIC);
|
||||
if (!urbtrack->setup) {
|
||||
usb_free_urb(urbtrack->urb);
|
||||
kfree(urbtrack);
|
||||
|
|
@ -382,8 +382,8 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport,
|
|||
}
|
||||
urbtrack->setup->bRequestType = (__u8)0x40;
|
||||
urbtrack->setup->bRequest = (__u8)0x0e;
|
||||
urbtrack->setup->wValue = get_reg_value(reg, dummy);
|
||||
urbtrack->setup->wIndex = get_reg_index(reg);
|
||||
urbtrack->setup->wValue = cpu_to_le16(get_reg_value(reg, dummy));
|
||||
urbtrack->setup->wIndex = cpu_to_le16(get_reg_index(reg));
|
||||
urbtrack->setup->wLength = 0;
|
||||
usb_fill_control_urb(urbtrack->urb, usbdev,
|
||||
usb_sndctrlpipe(usbdev, 0),
|
||||
|
|
|
|||
|
|
@ -729,9 +729,18 @@ void gnttab_request_free_callback(struct gnttab_free_callback *callback,
|
|||
void (*fn)(void *), void *arg, u16 count)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct gnttab_free_callback *cb;
|
||||
|
||||
spin_lock_irqsave(&gnttab_list_lock, flags);
|
||||
if (callback->next)
|
||||
goto out;
|
||||
|
||||
/* Check if the callback is already on the list */
|
||||
cb = gnttab_free_callback_list;
|
||||
while (cb) {
|
||||
if (cb == callback)
|
||||
goto out;
|
||||
cb = cb->next;
|
||||
}
|
||||
|
||||
callback->fn = fn;
|
||||
callback->arg = arg;
|
||||
callback->count = count;
|
||||
|
|
|
|||
|
|
@ -3299,6 +3299,9 @@ static long btrfs_ioctl_dev_replace(struct btrfs_root *root, void __user *arg)
|
|||
|
||||
switch (p->cmd) {
|
||||
case BTRFS_IOCTL_DEV_REPLACE_CMD_START:
|
||||
if (root->fs_info->sb->s_flags & MS_RDONLY)
|
||||
return -EROFS;
|
||||
|
||||
if (atomic_xchg(
|
||||
&root->fs_info->mutually_exclusive_operation_running,
|
||||
1)) {
|
||||
|
|
|
|||
|
|
@ -196,8 +196,10 @@ static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg)
|
|||
r = ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, len,
|
||||
&dl.object_no, &dl.object_offset,
|
||||
&olen);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
up_read(&osdc->map_sem);
|
||||
return -EIO;
|
||||
}
|
||||
dl.file_offset -= dl.object_offset;
|
||||
dl.object_size = ceph_file_layout_object_size(ci->i_layout);
|
||||
dl.block_size = ceph_file_layout_su(ci->i_layout);
|
||||
|
|
|
|||
|
|
@ -377,6 +377,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
|
|||
try_to_freeze();
|
||||
|
||||
/* we should try only the port we connected to before */
|
||||
mutex_lock(&server->srv_mutex);
|
||||
rc = generic_ip_connect(server);
|
||||
if (rc) {
|
||||
cifs_dbg(FYI, "reconnect error %d\n", rc);
|
||||
|
|
@ -388,6 +389,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
|
|||
server->tcpStatus = CifsNeedNegotiate;
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
}
|
||||
mutex_unlock(&server->srv_mutex);
|
||||
} while (server->tcpStatus == CifsNeedReconnect);
|
||||
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -413,19 +413,76 @@ cifs_ses_oplock_break(struct work_struct *work)
|
|||
}
|
||||
|
||||
static bool
|
||||
smb2_is_valid_lease_break(char *buffer, struct TCP_Server_Info *server)
|
||||
smb2_tcon_has_lease(struct cifs_tcon *tcon, struct smb2_lease_break *rsp,
|
||||
struct smb2_lease_break_work *lw)
|
||||
{
|
||||
bool found;
|
||||
__u8 lease_state;
|
||||
struct list_head *tmp;
|
||||
struct cifsFileInfo *cfile;
|
||||
struct cifs_pending_open *open;
|
||||
struct cifsInodeInfo *cinode;
|
||||
int ack_req = le32_to_cpu(rsp->Flags &
|
||||
SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED);
|
||||
|
||||
lease_state = smb2_map_lease_to_oplock(rsp->NewLeaseState);
|
||||
|
||||
list_for_each(tmp, &tcon->openFileList) {
|
||||
cfile = list_entry(tmp, struct cifsFileInfo, tlist);
|
||||
cinode = CIFS_I(cfile->dentry->d_inode);
|
||||
|
||||
if (memcmp(cinode->lease_key, rsp->LeaseKey,
|
||||
SMB2_LEASE_KEY_SIZE))
|
||||
continue;
|
||||
|
||||
cifs_dbg(FYI, "found in the open list\n");
|
||||
cifs_dbg(FYI, "lease key match, lease break 0x%d\n",
|
||||
le32_to_cpu(rsp->NewLeaseState));
|
||||
|
||||
smb2_set_oplock_level(cinode, lease_state);
|
||||
|
||||
if (ack_req)
|
||||
cfile->oplock_break_cancelled = false;
|
||||
else
|
||||
cfile->oplock_break_cancelled = true;
|
||||
|
||||
queue_work(cifsiod_wq, &cfile->oplock_break);
|
||||
kfree(lw);
|
||||
return true;
|
||||
}
|
||||
|
||||
found = false;
|
||||
list_for_each_entry(open, &tcon->pending_opens, olist) {
|
||||
if (memcmp(open->lease_key, rsp->LeaseKey,
|
||||
SMB2_LEASE_KEY_SIZE))
|
||||
continue;
|
||||
|
||||
if (!found && ack_req) {
|
||||
found = true;
|
||||
memcpy(lw->lease_key, open->lease_key,
|
||||
SMB2_LEASE_KEY_SIZE);
|
||||
lw->tlink = cifs_get_tlink(open->tlink);
|
||||
queue_work(cifsiod_wq, &lw->lease_break);
|
||||
}
|
||||
|
||||
cifs_dbg(FYI, "found in the pending open list\n");
|
||||
cifs_dbg(FYI, "lease key match, lease break 0x%d\n",
|
||||
le32_to_cpu(rsp->NewLeaseState));
|
||||
|
||||
open->oplock = lease_state;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
static bool
|
||||
smb2_is_valid_lease_break(char *buffer)
|
||||
{
|
||||
struct smb2_lease_break *rsp = (struct smb2_lease_break *)buffer;
|
||||
struct list_head *tmp, *tmp1, *tmp2;
|
||||
struct TCP_Server_Info *server;
|
||||
struct cifs_ses *ses;
|
||||
struct cifs_tcon *tcon;
|
||||
struct cifsInodeInfo *cinode;
|
||||
struct cifsFileInfo *cfile;
|
||||
struct cifs_pending_open *open;
|
||||
struct smb2_lease_break_work *lw;
|
||||
bool found;
|
||||
int ack_req = le32_to_cpu(rsp->Flags &
|
||||
SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED);
|
||||
|
||||
lw = kmalloc(sizeof(struct smb2_lease_break_work), GFP_KERNEL);
|
||||
if (!lw)
|
||||
|
|
@ -438,71 +495,26 @@ smb2_is_valid_lease_break(char *buffer, struct TCP_Server_Info *server)
|
|||
|
||||
/* look up tcon based on tid & uid */
|
||||
spin_lock(&cifs_tcp_ses_lock);
|
||||
list_for_each(tmp, &server->smb_ses_list) {
|
||||
ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
|
||||
list_for_each(tmp, &cifs_tcp_ses_list) {
|
||||
server = list_entry(tmp, struct TCP_Server_Info, tcp_ses_list);
|
||||
|
||||
spin_lock(&cifs_file_list_lock);
|
||||
list_for_each(tmp1, &ses->tcon_list) {
|
||||
tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
|
||||
list_for_each(tmp1, &server->smb_ses_list) {
|
||||
ses = list_entry(tmp1, struct cifs_ses, smb_ses_list);
|
||||
|
||||
cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);
|
||||
list_for_each(tmp2, &tcon->openFileList) {
|
||||
cfile = list_entry(tmp2, struct cifsFileInfo,
|
||||
tlist);
|
||||
cinode = CIFS_I(cfile->dentry->d_inode);
|
||||
|
||||
if (memcmp(cinode->lease_key, rsp->LeaseKey,
|
||||
SMB2_LEASE_KEY_SIZE))
|
||||
continue;
|
||||
|
||||
cifs_dbg(FYI, "found in the open list\n");
|
||||
cifs_dbg(FYI, "lease key match, lease break 0x%d\n",
|
||||
le32_to_cpu(rsp->NewLeaseState));
|
||||
|
||||
smb2_set_oplock_level(cinode,
|
||||
smb2_map_lease_to_oplock(rsp->NewLeaseState));
|
||||
|
||||
if (ack_req)
|
||||
cfile->oplock_break_cancelled = false;
|
||||
else
|
||||
cfile->oplock_break_cancelled = true;
|
||||
|
||||
queue_work(cifsiod_wq, &cfile->oplock_break);
|
||||
|
||||
spin_unlock(&cifs_file_list_lock);
|
||||
spin_unlock(&cifs_tcp_ses_lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
found = false;
|
||||
list_for_each_entry(open, &tcon->pending_opens, olist) {
|
||||
if (memcmp(open->lease_key, rsp->LeaseKey,
|
||||
SMB2_LEASE_KEY_SIZE))
|
||||
continue;
|
||||
|
||||
if (!found && ack_req) {
|
||||
found = true;
|
||||
memcpy(lw->lease_key, open->lease_key,
|
||||
SMB2_LEASE_KEY_SIZE);
|
||||
lw->tlink = cifs_get_tlink(open->tlink);
|
||||
queue_work(cifsiod_wq,
|
||||
&lw->lease_break);
|
||||
spin_lock(&cifs_file_list_lock);
|
||||
list_for_each(tmp2, &ses->tcon_list) {
|
||||
tcon = list_entry(tmp2, struct cifs_tcon,
|
||||
tcon_list);
|
||||
cifs_stats_inc(
|
||||
&tcon->stats.cifs_stats.num_oplock_brks);
|
||||
if (smb2_tcon_has_lease(tcon, rsp, lw)) {
|
||||
spin_unlock(&cifs_file_list_lock);
|
||||
spin_unlock(&cifs_tcp_ses_lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
cifs_dbg(FYI, "found in the pending open list\n");
|
||||
cifs_dbg(FYI, "lease key match, lease break 0x%d\n",
|
||||
le32_to_cpu(rsp->NewLeaseState));
|
||||
|
||||
open->oplock =
|
||||
smb2_map_lease_to_oplock(rsp->NewLeaseState);
|
||||
}
|
||||
if (found) {
|
||||
spin_unlock(&cifs_file_list_lock);
|
||||
spin_unlock(&cifs_tcp_ses_lock);
|
||||
return true;
|
||||
}
|
||||
spin_unlock(&cifs_file_list_lock);
|
||||
}
|
||||
spin_unlock(&cifs_file_list_lock);
|
||||
}
|
||||
spin_unlock(&cifs_tcp_ses_lock);
|
||||
kfree(lw);
|
||||
|
|
@ -528,7 +540,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
|
|||
if (rsp->StructureSize !=
|
||||
smb2_rsp_struct_sizes[SMB2_OPLOCK_BREAK_HE]) {
|
||||
if (le16_to_cpu(rsp->StructureSize) == 44)
|
||||
return smb2_is_valid_lease_break(buffer, server);
|
||||
return smb2_is_valid_lease_break(buffer);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
109
fs/ext4/inode.c
109
fs/ext4/inode.c
|
|
@ -4706,7 +4706,9 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
ext4_journal_stop(handle);
|
||||
}
|
||||
|
||||
if (attr->ia_valid & ATTR_SIZE) {
|
||||
if (attr->ia_valid & ATTR_SIZE && attr->ia_size != inode->i_size) {
|
||||
handle_t *handle;
|
||||
loff_t oldsize = inode->i_size;
|
||||
|
||||
if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
|
||||
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
|
||||
|
|
@ -4714,73 +4716,60 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
|
|||
if (attr->ia_size > sbi->s_bitmap_maxbytes)
|
||||
return -EFBIG;
|
||||
}
|
||||
}
|
||||
|
||||
if (S_ISREG(inode->i_mode) &&
|
||||
attr->ia_valid & ATTR_SIZE &&
|
||||
(attr->ia_size < inode->i_size)) {
|
||||
handle_t *handle;
|
||||
|
||||
handle = ext4_journal_start(inode, EXT4_HT_INODE, 3);
|
||||
if (IS_ERR(handle)) {
|
||||
error = PTR_ERR(handle);
|
||||
goto err_out;
|
||||
}
|
||||
if (ext4_handle_valid(handle)) {
|
||||
error = ext4_orphan_add(handle, inode);
|
||||
orphan = 1;
|
||||
}
|
||||
EXT4_I(inode)->i_disksize = attr->ia_size;
|
||||
rc = ext4_mark_inode_dirty(handle, inode);
|
||||
if (!error)
|
||||
error = rc;
|
||||
ext4_journal_stop(handle);
|
||||
|
||||
if (ext4_should_order_data(inode)) {
|
||||
error = ext4_begin_ordered_truncate(inode,
|
||||
if (S_ISREG(inode->i_mode) &&
|
||||
(attr->ia_size < inode->i_size)) {
|
||||
if (ext4_should_order_data(inode)) {
|
||||
error = ext4_begin_ordered_truncate(inode,
|
||||
attr->ia_size);
|
||||
if (error) {
|
||||
/* Do as much error cleanup as possible */
|
||||
handle = ext4_journal_start(inode,
|
||||
EXT4_HT_INODE, 3);
|
||||
if (IS_ERR(handle)) {
|
||||
ext4_orphan_del(NULL, inode);
|
||||
if (error)
|
||||
goto err_out;
|
||||
}
|
||||
ext4_orphan_del(handle, inode);
|
||||
orphan = 0;
|
||||
ext4_journal_stop(handle);
|
||||
}
|
||||
handle = ext4_journal_start(inode, EXT4_HT_INODE, 3);
|
||||
if (IS_ERR(handle)) {
|
||||
error = PTR_ERR(handle);
|
||||
goto err_out;
|
||||
}
|
||||
if (ext4_handle_valid(handle)) {
|
||||
error = ext4_orphan_add(handle, inode);
|
||||
orphan = 1;
|
||||
}
|
||||
EXT4_I(inode)->i_disksize = attr->ia_size;
|
||||
rc = ext4_mark_inode_dirty(handle, inode);
|
||||
if (!error)
|
||||
error = rc;
|
||||
ext4_journal_stop(handle);
|
||||
if (error) {
|
||||
ext4_orphan_del(NULL, inode);
|
||||
goto err_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (attr->ia_valid & ATTR_SIZE) {
|
||||
if (attr->ia_size != inode->i_size) {
|
||||
loff_t oldsize = inode->i_size;
|
||||
|
||||
i_size_write(inode, attr->ia_size);
|
||||
/*
|
||||
* Blocks are going to be removed from the inode. Wait
|
||||
* for dio in flight. Temporarily disable
|
||||
* dioread_nolock to prevent livelock.
|
||||
*/
|
||||
if (orphan) {
|
||||
if (!ext4_should_journal_data(inode)) {
|
||||
ext4_inode_block_unlocked_dio(inode);
|
||||
inode_dio_wait(inode);
|
||||
ext4_inode_resume_unlocked_dio(inode);
|
||||
} else
|
||||
ext4_wait_for_tail_page_commit(inode);
|
||||
}
|
||||
/*
|
||||
* Truncate pagecache after we've waited for commit
|
||||
* in data=journal mode to make pages freeable.
|
||||
*/
|
||||
truncate_pagecache(inode, oldsize, inode->i_size);
|
||||
i_size_write(inode, attr->ia_size);
|
||||
/*
|
||||
* Blocks are going to be removed from the inode. Wait
|
||||
* for dio in flight. Temporarily disable
|
||||
* dioread_nolock to prevent livelock.
|
||||
*/
|
||||
if (orphan) {
|
||||
if (!ext4_should_journal_data(inode)) {
|
||||
ext4_inode_block_unlocked_dio(inode);
|
||||
inode_dio_wait(inode);
|
||||
ext4_inode_resume_unlocked_dio(inode);
|
||||
} else
|
||||
ext4_wait_for_tail_page_commit(inode);
|
||||
}
|
||||
ext4_truncate(inode);
|
||||
/*
|
||||
* Truncate pagecache after we've waited for commit
|
||||
* in data=journal mode to make pages freeable.
|
||||
*/
|
||||
truncate_pagecache(inode, oldsize, inode->i_size);
|
||||
}
|
||||
/*
|
||||
* We want to call ext4_truncate() even if attr->ia_size ==
|
||||
* inode->i_size for cases like truncation of fallocated space
|
||||
*/
|
||||
if (attr->ia_valid & ATTR_SIZE)
|
||||
ext4_truncate(inode);
|
||||
|
||||
if (!rc) {
|
||||
setattr_copy(inode, attr);
|
||||
|
|
|
|||
|
|
@ -1175,6 +1175,8 @@ static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
|
|||
return -EIO;
|
||||
if (reclen > nbytes)
|
||||
break;
|
||||
if (memchr(dirent->name, '/', dirent->namelen) != NULL)
|
||||
return -EIO;
|
||||
|
||||
over = filldir(dstbuf, dirent->name, dirent->namelen,
|
||||
file->f_pos, dirent->ino, dirent->type);
|
||||
|
|
@ -1323,6 +1325,8 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
|
|||
return -EIO;
|
||||
if (reclen > nbytes)
|
||||
break;
|
||||
if (memchr(dirent->name, '/', dirent->namelen) != NULL)
|
||||
return -EIO;
|
||||
|
||||
if (!over) {
|
||||
/* We fill entries into dstbuf only as much as
|
||||
|
|
@ -1594,6 +1598,7 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
|
|||
struct file *file)
|
||||
{
|
||||
struct fuse_conn *fc = get_fuse_conn(inode);
|
||||
struct fuse_inode *fi = get_fuse_inode(inode);
|
||||
struct fuse_req *req;
|
||||
struct fuse_setattr_in inarg;
|
||||
struct fuse_attr_out outarg;
|
||||
|
|
@ -1621,8 +1626,10 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
|
|||
if (IS_ERR(req))
|
||||
return PTR_ERR(req);
|
||||
|
||||
if (is_truncate)
|
||||
if (is_truncate) {
|
||||
fuse_set_nowrite(inode);
|
||||
set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
|
||||
}
|
||||
|
||||
memset(&inarg, 0, sizeof(inarg));
|
||||
memset(&outarg, 0, sizeof(outarg));
|
||||
|
|
@ -1684,12 +1691,14 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
|
|||
invalidate_inode_pages2(inode->i_mapping);
|
||||
}
|
||||
|
||||
clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (is_truncate)
|
||||
fuse_release_nowrite(inode);
|
||||
|
||||
clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -1753,6 +1762,8 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
|
|||
fc->no_setxattr = 1;
|
||||
err = -EOPNOTSUPP;
|
||||
}
|
||||
if (!err)
|
||||
fuse_invalidate_attr(inode);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -1882,6 +1893,8 @@ static int fuse_removexattr(struct dentry *entry, const char *name)
|
|||
fc->no_removexattr = 1;
|
||||
err = -EOPNOTSUPP;
|
||||
}
|
||||
if (!err)
|
||||
fuse_invalidate_attr(inode);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user