mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
Merge tag 'v4.9.242' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into odroidg12-4.9.y
This is the 4.9.242 stable release
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 241
|
||||
SUBLEVEL = 242
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
||||
@@ -156,6 +156,7 @@ END(EV_Extension)
|
||||
tracesys:
|
||||
; save EFA in case tracer wants the PC of traced task
|
||||
; using ERET won't work since next-PC has already committed
|
||||
lr r12, [efa]
|
||||
GET_CURR_TASK_FIELD_PTR TASK_THREAD, r11
|
||||
st r12, [r11, THREAD_FAULT_ADDR] ; thread.fault_address
|
||||
|
||||
@@ -198,9 +199,15 @@ tracesys_exit:
|
||||
; Breakpoint TRAP
|
||||
; ---------------------------------------------
|
||||
trap_with_param:
|
||||
mov r0, r12 ; EFA in case ptracer/gdb wants stop_pc
|
||||
|
||||
; stop_pc info by gdb needs this info
|
||||
lr r0, [efa]
|
||||
mov r1, sp
|
||||
|
||||
; Now that we have read EFA, it is safe to do "fake" rtie
|
||||
; and get out of CPU exception mode
|
||||
FAKE_RET_FROM_EXCPN
|
||||
|
||||
; Save callee regs in case gdb wants to have a look
|
||||
; SP will grow up by size of CALLEE Reg-File
|
||||
; NOTE: clobbers r12
|
||||
@@ -227,10 +234,6 @@ ENTRY(EV_Trap)
|
||||
|
||||
EXCEPTION_PROLOGUE
|
||||
|
||||
lr r12, [efa]
|
||||
|
||||
FAKE_RET_FROM_EXCPN
|
||||
|
||||
;============ TRAP 1 :breakpoints
|
||||
; Check ECR for trap with arg (PROLOGUE ensures r9 has ECR)
|
||||
bmsk.f 0, r9, 7
|
||||
@@ -238,6 +241,9 @@ ENTRY(EV_Trap)
|
||||
|
||||
;============ TRAP (no param): syscall top level
|
||||
|
||||
; First return from Exception to pure K mode (Exception/IRQs renabled)
|
||||
FAKE_RET_FROM_EXCPN
|
||||
|
||||
; If syscall tracing ongoing, invoke pre-post-hooks
|
||||
GET_CURR_THR_INFO_FLAGS r10
|
||||
btst r10, TIF_SYSCALL_TRACE
|
||||
|
||||
@@ -113,7 +113,7 @@ arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs,
|
||||
int (*consumer_fn) (unsigned int, void *), void *arg)
|
||||
{
|
||||
#ifdef CONFIG_ARC_DW2_UNWIND
|
||||
int ret = 0;
|
||||
int ret = 0, cnt = 0;
|
||||
unsigned int address;
|
||||
struct unwind_frame_info frame_info;
|
||||
|
||||
@@ -133,6 +133,11 @@ arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs,
|
||||
break;
|
||||
|
||||
frame_info.regs.r63 = frame_info.regs.r31;
|
||||
|
||||
if (cnt++ > 128) {
|
||||
printk("unwinder looping too long, aborting !\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return address; /* return the last address it saw */
|
||||
|
||||
@@ -600,7 +600,9 @@ config ARCH_S3C24XX
|
||||
select HAVE_S3C_RTC if RTC_CLASS
|
||||
select MULTI_IRQ_HANDLER
|
||||
select NEED_MACH_IO_H
|
||||
select S3C2410_WATCHDOG
|
||||
select SAMSUNG_ATAGS
|
||||
select WATCHDOG
|
||||
help
|
||||
Samsung S3C2410, S3C2412, S3C2413, S3C2416, S3C2440, S3C2442, S3C2443
|
||||
and S3C2450 SoCs based systems, such as the Simtec Electronics BAST
|
||||
|
||||
@@ -101,19 +101,16 @@
|
||||
};
|
||||
|
||||
clocks: clock-controller@e0100000 {
|
||||
compatible = "samsung,s5pv210-clock", "simple-bus";
|
||||
compatible = "samsung,s5pv210-clock";
|
||||
reg = <0xe0100000 0x10000>;
|
||||
clock-names = "xxti", "xusbxti";
|
||||
clocks = <&xxti>, <&xusbxti>;
|
||||
#clock-cells = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
};
|
||||
|
||||
pmu_syscon: syscon@e0108000 {
|
||||
compatible = "samsung-s5pv210-pmu", "syscon";
|
||||
reg = <0xe0108000 0x8000>;
|
||||
};
|
||||
pmu_syscon: syscon@e0108000 {
|
||||
compatible = "samsung-s5pv210-pmu", "syscon";
|
||||
reg = <0xe0108000 0x8000>;
|
||||
};
|
||||
|
||||
pinctrl0: pinctrl@e0200000 {
|
||||
@@ -129,35 +126,28 @@
|
||||
};
|
||||
};
|
||||
|
||||
amba {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
pdma0: dma@e0900000 {
|
||||
compatible = "arm,pl330", "arm,primecell";
|
||||
reg = <0xe0900000 0x1000>;
|
||||
interrupt-parent = <&vic0>;
|
||||
interrupts = <19>;
|
||||
clocks = <&clocks CLK_PDMA0>;
|
||||
clock-names = "apb_pclk";
|
||||
#dma-cells = <1>;
|
||||
#dma-channels = <8>;
|
||||
#dma-requests = <32>;
|
||||
};
|
||||
|
||||
pdma0: dma@e0900000 {
|
||||
compatible = "arm,pl330", "arm,primecell";
|
||||
reg = <0xe0900000 0x1000>;
|
||||
interrupt-parent = <&vic0>;
|
||||
interrupts = <19>;
|
||||
clocks = <&clocks CLK_PDMA0>;
|
||||
clock-names = "apb_pclk";
|
||||
#dma-cells = <1>;
|
||||
#dma-channels = <8>;
|
||||
#dma-requests = <32>;
|
||||
};
|
||||
|
||||
pdma1: dma@e0a00000 {
|
||||
compatible = "arm,pl330", "arm,primecell";
|
||||
reg = <0xe0a00000 0x1000>;
|
||||
interrupt-parent = <&vic0>;
|
||||
interrupts = <20>;
|
||||
clocks = <&clocks CLK_PDMA1>;
|
||||
clock-names = "apb_pclk";
|
||||
#dma-cells = <1>;
|
||||
#dma-channels = <8>;
|
||||
#dma-requests = <32>;
|
||||
};
|
||||
pdma1: dma@e0a00000 {
|
||||
compatible = "arm,pl330", "arm,primecell";
|
||||
reg = <0xe0a00000 0x1000>;
|
||||
interrupt-parent = <&vic0>;
|
||||
interrupts = <20>;
|
||||
clocks = <&clocks CLK_PDMA1>;
|
||||
clock-names = "apb_pclk";
|
||||
#dma-cells = <1>;
|
||||
#dma-channels = <8>;
|
||||
#dma-requests = <32>;
|
||||
};
|
||||
|
||||
spi0: spi@e1300000 {
|
||||
@@ -230,43 +220,36 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
audio-subsystem {
|
||||
compatible = "samsung,s5pv210-audss", "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
clk_audss: clock-controller@eee10000 {
|
||||
compatible = "samsung,s5pv210-audss-clock";
|
||||
reg = <0xeee10000 0x1000>;
|
||||
clock-names = "hclk", "xxti",
|
||||
"fout_epll",
|
||||
"sclk_audio0";
|
||||
clocks = <&clocks DOUT_HCLKP>, <&xxti>,
|
||||
<&clocks FOUT_EPLL>,
|
||||
<&clocks SCLK_AUDIO0>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
clk_audss: clock-controller@eee10000 {
|
||||
compatible = "samsung,s5pv210-audss-clock";
|
||||
reg = <0xeee10000 0x1000>;
|
||||
clock-names = "hclk", "xxti",
|
||||
"fout_epll",
|
||||
"sclk_audio0";
|
||||
clocks = <&clocks DOUT_HCLKP>, <&xxti>,
|
||||
<&clocks FOUT_EPLL>,
|
||||
<&clocks SCLK_AUDIO0>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
i2s0: i2s@eee30000 {
|
||||
compatible = "samsung,s5pv210-i2s";
|
||||
reg = <0xeee30000 0x1000>;
|
||||
interrupt-parent = <&vic2>;
|
||||
interrupts = <16>;
|
||||
dma-names = "rx", "tx", "tx-sec";
|
||||
dmas = <&pdma1 9>, <&pdma1 10>, <&pdma1 11>;
|
||||
clock-names = "iis",
|
||||
"i2s_opclk0",
|
||||
"i2s_opclk1";
|
||||
clocks = <&clk_audss CLK_I2S>,
|
||||
<&clk_audss CLK_I2S>,
|
||||
<&clk_audss CLK_DOUT_AUD_BUS>;
|
||||
samsung,idma-addr = <0xc0010000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2s0_bus>;
|
||||
#sound-dai-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
i2s0: i2s@eee30000 {
|
||||
compatible = "samsung,s5pv210-i2s";
|
||||
reg = <0xeee30000 0x1000>;
|
||||
interrupt-parent = <&vic2>;
|
||||
interrupts = <16>;
|
||||
dma-names = "rx", "tx", "tx-sec";
|
||||
dmas = <&pdma1 9>, <&pdma1 10>, <&pdma1 11>;
|
||||
clock-names = "iis",
|
||||
"i2s_opclk0",
|
||||
"i2s_opclk1";
|
||||
clocks = <&clk_audss CLK_I2S>,
|
||||
<&clk_audss CLK_I2S>,
|
||||
<&clk_audss CLK_DOUT_AUD_BUS>;
|
||||
samsung,idma-addr = <0xc0010000>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2s0_bus>;
|
||||
#sound-dai-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2s1: i2s@e2100000 {
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
trips {
|
||||
cpu_alert0: cpu_alert0 {
|
||||
/* milliCelsius */
|
||||
temperature = <850000>;
|
||||
temperature = <85000>;
|
||||
hysteresis = <2000>;
|
||||
type = "passive";
|
||||
};
|
||||
|
||||
@@ -695,6 +695,40 @@ static void disable_single_step(struct perf_event *bp)
|
||||
arch_install_hw_breakpoint(bp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Arm32 hardware does not always report a watchpoint hit address that matches
|
||||
* one of the watchpoints set. It can also report an address "near" the
|
||||
* watchpoint if a single instruction access both watched and unwatched
|
||||
* addresses. There is no straight-forward way, short of disassembling the
|
||||
* offending instruction, to map that address back to the watchpoint. This
|
||||
* function computes the distance of the memory access from the watchpoint as a
|
||||
* heuristic for the likelyhood that a given access triggered the watchpoint.
|
||||
*
|
||||
* See this same function in the arm64 platform code, which has the same
|
||||
* problem.
|
||||
*
|
||||
* The function returns the distance of the address from the bytes watched by
|
||||
* the watchpoint. In case of an exact match, it returns 0.
|
||||
*/
|
||||
static u32 get_distance_from_watchpoint(unsigned long addr, u32 val,
|
||||
struct arch_hw_breakpoint_ctrl *ctrl)
|
||||
{
|
||||
u32 wp_low, wp_high;
|
||||
u32 lens, lene;
|
||||
|
||||
lens = __ffs(ctrl->len);
|
||||
lene = __fls(ctrl->len);
|
||||
|
||||
wp_low = val + lens;
|
||||
wp_high = val + lene;
|
||||
if (addr < wp_low)
|
||||
return wp_low - addr;
|
||||
else if (addr > wp_high)
|
||||
return addr - wp_high;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int watchpoint_fault_on_uaccess(struct pt_regs *regs,
|
||||
struct arch_hw_breakpoint *info)
|
||||
{
|
||||
@@ -704,23 +738,25 @@ static int watchpoint_fault_on_uaccess(struct pt_regs *regs,
|
||||
static void watchpoint_handler(unsigned long addr, unsigned int fsr,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
int i, access;
|
||||
u32 val, ctrl_reg, alignment_mask;
|
||||
int i, access, closest_match = 0;
|
||||
u32 min_dist = -1, dist;
|
||||
u32 val, ctrl_reg;
|
||||
struct perf_event *wp, **slots;
|
||||
struct arch_hw_breakpoint *info;
|
||||
struct arch_hw_breakpoint_ctrl ctrl;
|
||||
|
||||
slots = this_cpu_ptr(wp_on_reg);
|
||||
|
||||
/*
|
||||
* Find all watchpoints that match the reported address. If no exact
|
||||
* match is found. Attribute the hit to the closest watchpoint.
|
||||
*/
|
||||
rcu_read_lock();
|
||||
for (i = 0; i < core_num_wrps; ++i) {
|
||||
rcu_read_lock();
|
||||
|
||||
wp = slots[i];
|
||||
|
||||
if (wp == NULL)
|
||||
goto unlock;
|
||||
continue;
|
||||
|
||||
info = counter_arch_bp(wp);
|
||||
/*
|
||||
* The DFAR is an unknown value on debug architectures prior
|
||||
* to 7.1. Since we only allow a single watchpoint on these
|
||||
@@ -729,33 +765,31 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
|
||||
*/
|
||||
if (debug_arch < ARM_DEBUG_ARCH_V7_1) {
|
||||
BUG_ON(i > 0);
|
||||
info = counter_arch_bp(wp);
|
||||
info->trigger = wp->attr.bp_addr;
|
||||
} else {
|
||||
if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
|
||||
alignment_mask = 0x7;
|
||||
else
|
||||
alignment_mask = 0x3;
|
||||
|
||||
/* Check if the watchpoint value matches. */
|
||||
val = read_wb_reg(ARM_BASE_WVR + i);
|
||||
if (val != (addr & ~alignment_mask))
|
||||
goto unlock;
|
||||
|
||||
/* Possible match, check the byte address select. */
|
||||
ctrl_reg = read_wb_reg(ARM_BASE_WCR + i);
|
||||
decode_ctrl_reg(ctrl_reg, &ctrl);
|
||||
if (!((1 << (addr & alignment_mask)) & ctrl.len))
|
||||
goto unlock;
|
||||
|
||||
/* Check that the access type matches. */
|
||||
if (debug_exception_updates_fsr()) {
|
||||
access = (fsr & ARM_FSR_ACCESS_MASK) ?
|
||||
HW_BREAKPOINT_W : HW_BREAKPOINT_R;
|
||||
if (!(access & hw_breakpoint_type(wp)))
|
||||
goto unlock;
|
||||
continue;
|
||||
}
|
||||
|
||||
val = read_wb_reg(ARM_BASE_WVR + i);
|
||||
ctrl_reg = read_wb_reg(ARM_BASE_WCR + i);
|
||||
decode_ctrl_reg(ctrl_reg, &ctrl);
|
||||
dist = get_distance_from_watchpoint(addr, val, &ctrl);
|
||||
if (dist < min_dist) {
|
||||
min_dist = dist;
|
||||
closest_match = i;
|
||||
}
|
||||
/* Is this an exact match? */
|
||||
if (dist != 0)
|
||||
continue;
|
||||
|
||||
/* We have a winner. */
|
||||
info = counter_arch_bp(wp);
|
||||
info->trigger = addr;
|
||||
}
|
||||
|
||||
@@ -777,13 +811,23 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
|
||||
* we can single-step over the watchpoint trigger.
|
||||
*/
|
||||
if (!is_default_overflow_handler(wp))
|
||||
goto unlock;
|
||||
|
||||
continue;
|
||||
step:
|
||||
enable_single_step(wp, instruction_pointer(regs));
|
||||
unlock:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
if (min_dist > 0 && min_dist != -1) {
|
||||
/* No exact match found. */
|
||||
wp = slots[closest_match];
|
||||
info = counter_arch_bp(wp);
|
||||
info->trigger = addr;
|
||||
pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);
|
||||
perf_bp_event(wp, regs);
|
||||
if (is_default_overflow_handler(wp))
|
||||
enable_single_step(wp, instruction_pointer(regs));
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static void watchpoint_single_step_handler(unsigned long pc)
|
||||
|
||||
@@ -242,6 +242,7 @@ config SAMSUNG_PM_DEBUG
|
||||
bool "Samsung PM Suspend debug"
|
||||
depends on PM && DEBUG_KERNEL
|
||||
depends on DEBUG_EXYNOS_UART || DEBUG_S3C24XX_UART || DEBUG_S3C2410_UART
|
||||
depends on DEBUG_LL && MMU
|
||||
help
|
||||
Say Y here if you want verbose debugging from the PM Suspend and
|
||||
Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
|
||||
|
||||
@@ -41,6 +41,7 @@ config ARCH_BCM_IPROC
|
||||
config ARCH_BERLIN
|
||||
bool "Marvell Berlin SoC Family"
|
||||
select DW_APB_ICTL
|
||||
select DW_APB_TIMER_OF
|
||||
select GPIOLIB
|
||||
select PINCTRL
|
||||
help
|
||||
|
||||
@@ -188,6 +188,7 @@ enum vcpu_sysreg {
|
||||
#define cp14_DBGWCR0 (DBGWCR0_EL1 * 2)
|
||||
#define cp14_DBGWVR0 (DBGWVR0_EL1 * 2)
|
||||
#define cp14_DBGDCCINT (MDCCINT_EL1 * 2)
|
||||
#define cp14_DBGVCR (DBGVCR32_EL2 * 2)
|
||||
|
||||
#define NR_COPRO_REGS (NR_SYS_REGS * 2)
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ const struct cpumask *cpumask_of_node(int node);
|
||||
/* Returns a pointer to the cpumask of CPUs on Node 'node'. */
|
||||
static inline const struct cpumask *cpumask_of_node(int node)
|
||||
{
|
||||
if (node == NUMA_NO_NODE)
|
||||
return cpu_all_mask;
|
||||
|
||||
return node_to_cpumask_map[node];
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1207,9 +1207,9 @@ static const struct sys_reg_desc cp14_regs[] = {
|
||||
{ Op1( 0), CRn( 0), CRm( 1), Op2( 0), trap_raz_wi },
|
||||
DBG_BCR_BVR_WCR_WVR(1),
|
||||
/* DBGDCCINT */
|
||||
{ Op1( 0), CRn( 0), CRm( 2), Op2( 0), trap_debug32 },
|
||||
{ Op1( 0), CRn( 0), CRm( 2), Op2( 0), trap_debug32, NULL, cp14_DBGDCCINT },
|
||||
/* DBGDSCRext */
|
||||
{ Op1( 0), CRn( 0), CRm( 2), Op2( 2), trap_debug32 },
|
||||
{ Op1( 0), CRn( 0), CRm( 2), Op2( 2), trap_debug32, NULL, cp14_DBGDSCRext },
|
||||
DBG_BCR_BVR_WCR_WVR(2),
|
||||
/* DBGDTR[RT]Xint */
|
||||
{ Op1( 0), CRn( 0), CRm( 3), Op2( 0), trap_raz_wi },
|
||||
@@ -1224,7 +1224,7 @@ static const struct sys_reg_desc cp14_regs[] = {
|
||||
{ Op1( 0), CRn( 0), CRm( 6), Op2( 2), trap_raz_wi },
|
||||
DBG_BCR_BVR_WCR_WVR(6),
|
||||
/* DBGVCR */
|
||||
{ Op1( 0), CRn( 0), CRm( 7), Op2( 0), trap_debug32 },
|
||||
{ Op1( 0), CRn( 0), CRm( 7), Op2( 0), trap_debug32, NULL, cp14_DBGVCR },
|
||||
DBG_BCR_BVR_WCR_WVR(7),
|
||||
DBG_BCR_BVR_WCR_WVR(8),
|
||||
DBG_BCR_BVR_WCR_WVR(9),
|
||||
|
||||
@@ -58,7 +58,11 @@ EXPORT_SYMBOL(node_to_cpumask_map);
|
||||
*/
|
||||
const struct cpumask *cpumask_of_node(int node)
|
||||
{
|
||||
if (WARN_ON(node >= nr_node_ids))
|
||||
|
||||
if (node == NUMA_NO_NODE)
|
||||
return cpu_all_mask;
|
||||
|
||||
if (WARN_ON(node < 0 || node >= nr_node_ids))
|
||||
return cpu_none_mask;
|
||||
|
||||
if (WARN_ON(node_to_cpumask_map[node] == NULL))
|
||||
|
||||
@@ -42,7 +42,7 @@ endif
|
||||
obj-$(CONFIG_INTEL_IOMMU) += pci-dma.o
|
||||
obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
|
||||
|
||||
obj-$(CONFIG_BINFMT_ELF) += elfcore.o
|
||||
obj-$(CONFIG_ELF_CORE) += elfcore.o
|
||||
|
||||
# fp_emulate() expects f2-f5,f16-f31 to contain the user-level state.
|
||||
CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31
|
||||
|
||||
@@ -28,29 +28,27 @@
|
||||
|
||||
static DEFINE_PER_CPU(struct cpu, cpu_devices);
|
||||
|
||||
/*
|
||||
* SMT snooze delay stuff, 64-bit only for now
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
|
||||
/* Time in microseconds we delay before sleeping in the idle loop */
|
||||
static DEFINE_PER_CPU(long, smt_snooze_delay) = { 100 };
|
||||
/*
|
||||
* Snooze delay has not been hooked up since 3fa8cad82b94 ("powerpc/pseries/cpuidle:
|
||||
* smt-snooze-delay cleanup.") and has been broken even longer. As was foretold in
|
||||
* 2014:
|
||||
*
|
||||
* "ppc64_util currently utilises it. Once we fix ppc64_util, propose to clean
|
||||
* up the kernel code."
|
||||
*
|
||||
* powerpc-utils stopped using it as of 1.3.8. At some point in the future this
|
||||
* code should be removed.
|
||||
*/
|
||||
|
||||
static ssize_t store_smt_snooze_delay(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf,
|
||||
size_t count)
|
||||
{
|
||||
struct cpu *cpu = container_of(dev, struct cpu, dev);
|
||||
ssize_t ret;
|
||||
long snooze;
|
||||
|
||||
ret = sscanf(buf, "%ld", &snooze);
|
||||
if (ret != 1)
|
||||
return -EINVAL;
|
||||
|
||||
per_cpu(smt_snooze_delay, cpu->dev.id) = snooze;
|
||||
pr_warn_once("%s (%d) stored to unsupported smt_snooze_delay, which has no effect.\n",
|
||||
current->comm, current->pid);
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -58,9 +56,9 @@ static ssize_t show_smt_snooze_delay(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct cpu *cpu = container_of(dev, struct cpu, dev);
|
||||
|
||||
return sprintf(buf, "%ld\n", per_cpu(smt_snooze_delay, cpu->dev.id));
|
||||
pr_warn_once("%s (%d) read from unsupported smt_snooze_delay\n",
|
||||
current->comm, current->pid);
|
||||
return sprintf(buf, "100\n");
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay,
|
||||
@@ -68,16 +66,10 @@ static DEVICE_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay,
|
||||
|
||||
static int __init setup_smt_snooze_delay(char *str)
|
||||
{
|
||||
unsigned int cpu;
|
||||
long snooze;
|
||||
|
||||
if (!cpu_has_feature(CPU_FTR_SMT))
|
||||
return 1;
|
||||
|
||||
snooze = simple_strtol(str, NULL, 10);
|
||||
for_each_possible_cpu(cpu)
|
||||
per_cpu(smt_snooze_delay, cpu) = snooze;
|
||||
|
||||
pr_warn("smt-snooze-delay command line option has no effect\n");
|
||||
return 1;
|
||||
}
|
||||
__setup("smt-snooze-delay=", setup_smt_snooze_delay);
|
||||
|
||||
@@ -385,13 +385,12 @@ static irqreturn_t process_dump(int irq, void *data)
|
||||
{
|
||||
int rc;
|
||||
uint32_t dump_id, dump_size, dump_type;
|
||||
struct dump_obj *dump;
|
||||
char name[22];
|
||||
struct kobject *kobj;
|
||||
|
||||
rc = dump_read_info(&dump_id, &dump_size, &dump_type);
|
||||
if (rc != OPAL_SUCCESS)
|
||||
return rc;
|
||||
return IRQ_HANDLED;
|
||||
|
||||
sprintf(name, "0x%x-0x%x", dump_type, dump_id);
|
||||
|
||||
@@ -403,12 +402,10 @@ static irqreturn_t process_dump(int irq, void *data)
|
||||
if (kobj) {
|
||||
/* Drop reference added by kset_find_obj() */
|
||||
kobject_put(kobj);
|
||||
return 0;
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
dump = create_dump_obj(dump_id, dump_size, dump_type);
|
||||
if (!dump)
|
||||
return -1;
|
||||
create_dump_obj(dump_id, dump_size, dump_type);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@@ -183,14 +183,14 @@ static ssize_t raw_attr_read(struct file *filep, struct kobject *kobj,
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type)
|
||||
static void create_elog_obj(uint64_t id, size_t size, uint64_t type)
|
||||
{
|
||||
struct elog_obj *elog;
|
||||
int rc;
|
||||
|
||||
elog = kzalloc(sizeof(*elog), GFP_KERNEL);
|
||||
if (!elog)
|
||||
return NULL;
|
||||
return;
|
||||
|
||||
elog->kobj.kset = elog_kset;
|
||||
|
||||
@@ -223,18 +223,37 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type)
|
||||
rc = kobject_add(&elog->kobj, NULL, "0x%llx", id);
|
||||
if (rc) {
|
||||
kobject_put(&elog->kobj);
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* As soon as the sysfs file for this elog is created/activated there is
|
||||
* a chance the opal_errd daemon (or any userspace) might read and
|
||||
* acknowledge the elog before kobject_uevent() is called. If that
|
||||
* happens then there is a potential race between
|
||||
* elog_ack_store->kobject_put() and kobject_uevent() which leads to a
|
||||
* use-after-free of a kernfs object resulting in a kernel crash.
|
||||
*
|
||||
* To avoid that, we need to take a reference on behalf of the bin file,
|
||||
* so that our reference remains valid while we call kobject_uevent().
|
||||
* We then drop our reference before exiting the function, leaving the
|
||||
* bin file to drop the last reference (if it hasn't already).
|
||||
*/
|
||||
|
||||
/* Take a reference for the bin file */
|
||||
kobject_get(&elog->kobj);
|
||||
rc = sysfs_create_bin_file(&elog->kobj, &elog->raw_attr);
|
||||
if (rc) {
|
||||
if (rc == 0) {
|
||||
kobject_uevent(&elog->kobj, KOBJ_ADD);
|
||||
} else {
|
||||
/* Drop the reference taken for the bin file */
|
||||
kobject_put(&elog->kobj);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kobject_uevent(&elog->kobj, KOBJ_ADD);
|
||||
/* Drop our reference */
|
||||
kobject_put(&elog->kobj);
|
||||
|
||||
return elog;
|
||||
return;
|
||||
}
|
||||
|
||||
static irqreturn_t elog_event(int irq, void *data)
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#include <asm/udbg.h>
|
||||
#define DBG(fmt...) udbg_printf(fmt)
|
||||
#else
|
||||
#define DBG(fmt...)
|
||||
#define DBG(fmt...) do { } while (0)
|
||||
#endif
|
||||
|
||||
static void pnv_smp_setup_cpu(int cpu)
|
||||
|
||||
@@ -1034,38 +1034,9 @@ void smp_fetch_global_pmu(void)
|
||||
* are flush_tlb_*() routines, and these run after flush_cache_*()
|
||||
* which performs the flushw.
|
||||
*
|
||||
* The SMP TLB coherency scheme we use works as follows:
|
||||
*
|
||||
* 1) mm->cpu_vm_mask is a bit mask of which cpus an address
|
||||
* space has (potentially) executed on, this is the heuristic
|
||||
* we use to avoid doing cross calls.
|
||||
*
|
||||
* Also, for flushing from kswapd and also for clones, we
|
||||
* use cpu_vm_mask as the list of cpus to make run the TLB.
|
||||
*
|
||||
* 2) TLB context numbers are shared globally across all processors
|
||||
* in the system, this allows us to play several games to avoid
|
||||
* cross calls.
|
||||
*
|
||||
* One invariant is that when a cpu switches to a process, and
|
||||
* that processes tsk->active_mm->cpu_vm_mask does not have the
|
||||
* current cpu's bit set, that tlb context is flushed locally.
|
||||
*
|
||||
* If the address space is non-shared (ie. mm->count == 1) we avoid
|
||||
* cross calls when we want to flush the currently running process's
|
||||
* tlb state. This is done by clearing all cpu bits except the current
|
||||
* processor's in current->mm->cpu_vm_mask and performing the
|
||||
* flush locally only. This will force any subsequent cpus which run
|
||||
* this task to flush the context from the local tlb if the process
|
||||
* migrates to another cpu (again).
|
||||
*
|
||||
* 3) For shared address spaces (threads) and swapping we bite the
|
||||
* bullet for most cases and perform the cross call (but only to
|
||||
* the cpus listed in cpu_vm_mask).
|
||||
*
|
||||
* The performance gain from "optimizing" away the cross call for threads is
|
||||
* questionable (in theory the big win for threads is the massive sharing of
|
||||
* address space state across processors).
|
||||
* mm->cpu_vm_mask is a bit mask of which cpus an address
|
||||
* space has (potentially) executed on, this is the heuristic
|
||||
* we use to limit cross calls.
|
||||
*/
|
||||
|
||||
/* This currently is only used by the hugetlb arch pre-fault
|
||||
@@ -1075,18 +1046,13 @@ void smp_fetch_global_pmu(void)
|
||||
void smp_flush_tlb_mm(struct mm_struct *mm)
|
||||
{
|
||||
u32 ctx = CTX_HWBITS(mm->context);
|
||||
int cpu = get_cpu();
|
||||
|
||||
if (atomic_read(&mm->mm_users) == 1) {
|
||||
cpumask_copy(mm_cpumask(mm), cpumask_of(cpu));
|
||||
goto local_flush_and_out;
|
||||
}
|
||||
get_cpu();
|
||||
|
||||
smp_cross_call_masked(&xcall_flush_tlb_mm,
|
||||
ctx, 0, 0,
|
||||
mm_cpumask(mm));
|
||||
|
||||
local_flush_and_out:
|
||||
__flush_tlb_mm(ctx, SECONDARY_CONTEXT);
|
||||
|
||||
put_cpu();
|
||||
@@ -1109,17 +1075,15 @@ void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long
|
||||
{
|
||||
u32 ctx = CTX_HWBITS(mm->context);
|
||||
struct tlb_pending_info info;
|
||||
int cpu = get_cpu();
|
||||
|
||||
get_cpu();
|
||||
|
||||
info.ctx = ctx;
|
||||
info.nr = nr;
|
||||
info.vaddrs = vaddrs;
|
||||
|
||||
if (mm == current->mm && atomic_read(&mm->mm_users) == 1)
|
||||
cpumask_copy(mm_cpumask(mm), cpumask_of(cpu));
|
||||
else
|
||||
smp_call_function_many(mm_cpumask(mm), tlb_pending_func,
|
||||
&info, 1);
|
||||
smp_call_function_many(mm_cpumask(mm), tlb_pending_func,
|
||||
&info, 1);
|
||||
|
||||
__flush_tlb_pending(ctx, nr, vaddrs);
|
||||
|
||||
@@ -1129,14 +1093,13 @@ void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long
|
||||
void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr)
|
||||
{
|
||||
unsigned long context = CTX_HWBITS(mm->context);
|
||||
int cpu = get_cpu();
|
||||
|
||||
if (mm == current->mm && atomic_read(&mm->mm_users) == 1)
|
||||
cpumask_copy(mm_cpumask(mm), cpumask_of(cpu));
|
||||
else
|
||||
smp_cross_call_masked(&xcall_flush_tlb_page,
|
||||
context, vaddr, 0,
|
||||
mm_cpumask(mm));
|
||||
get_cpu();
|
||||
|
||||
smp_cross_call_masked(&xcall_flush_tlb_page,
|
||||
context, vaddr, 0,
|
||||
mm_cpumask(mm));
|
||||
|
||||
__flush_tlb_page(context, vaddr);
|
||||
|
||||
put_cpu();
|
||||
|
||||
@@ -36,14 +36,14 @@ int write_sigio_irq(int fd)
|
||||
}
|
||||
|
||||
/* These are called from os-Linux/sigio.c to protect its pollfds arrays. */
|
||||
static DEFINE_SPINLOCK(sigio_spinlock);
|
||||
static DEFINE_MUTEX(sigio_mutex);
|
||||
|
||||
void sigio_lock(void)
|
||||
{
|
||||
spin_lock(&sigio_spinlock);
|
||||
mutex_lock(&sigio_mutex);
|
||||
}
|
||||
|
||||
void sigio_unlock(void)
|
||||
{
|
||||
spin_unlock(&sigio_spinlock);
|
||||
mutex_unlock(&sigio_mutex);
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ struct perf_ibs {
|
||||
u64 max_period;
|
||||
unsigned long offset_mask[1];
|
||||
int offset_max;
|
||||
unsigned int fetch_count_reset_broken : 1;
|
||||
struct cpu_perf_ibs __percpu *pcpu;
|
||||
|
||||
struct attribute **format_attrs;
|
||||
@@ -345,11 +346,15 @@ static u64 get_ibs_op_count(u64 config)
|
||||
{
|
||||
u64 count = 0;
|
||||
|
||||
/*
|
||||
* If the internal 27-bit counter rolled over, the count is MaxCnt
|
||||
* and the lower 7 bits of CurCnt are randomized.
|
||||
* Otherwise CurCnt has the full 27-bit current counter value.
|
||||
*/
|
||||
if (config & IBS_OP_VAL)
|
||||
count += (config & IBS_OP_MAX_CNT) << 4; /* cnt rolled over */
|
||||
|
||||
if (ibs_caps & IBS_CAPS_RDWROPCNT)
|
||||
count += (config & IBS_OP_CUR_CNT) >> 32;
|
||||
count = (config & IBS_OP_MAX_CNT) << 4;
|
||||
else if (ibs_caps & IBS_CAPS_RDWROPCNT)
|
||||
count = (config & IBS_OP_CUR_CNT) >> 32;
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -374,7 +379,12 @@ perf_ibs_event_update(struct perf_ibs *perf_ibs, struct perf_event *event,
|
||||
static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs,
|
||||
struct hw_perf_event *hwc, u64 config)
|
||||
{
|
||||
wrmsrl(hwc->config_base, hwc->config | config | perf_ibs->enable_mask);
|
||||
u64 tmp = hwc->config | config;
|
||||
|
||||
if (perf_ibs->fetch_count_reset_broken)
|
||||
wrmsrl(hwc->config_base, tmp & ~perf_ibs->enable_mask);
|
||||
|
||||
wrmsrl(hwc->config_base, tmp | perf_ibs->enable_mask);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -636,18 +646,24 @@ fail:
|
||||
perf_ibs->offset_max,
|
||||
offset + 1);
|
||||
} while (offset < offset_max);
|
||||
/*
|
||||
* Read IbsBrTarget, IbsOpData4, and IbsExtdCtl separately
|
||||
* depending on their availability.
|
||||
* Can't add to offset_max as they are staggered
|
||||
*/
|
||||
if (event->attr.sample_type & PERF_SAMPLE_RAW) {
|
||||
/*
|
||||
* Read IbsBrTarget and IbsOpData4 separately
|
||||
* depending on their availability.
|
||||
* Can't add to offset_max as they are staggered
|
||||
*/
|
||||
if (ibs_caps & IBS_CAPS_BRNTRGT) {
|
||||
rdmsrl(MSR_AMD64_IBSBRTARGET, *buf++);
|
||||
size++;
|
||||
if (perf_ibs == &perf_ibs_op) {
|
||||
if (ibs_caps & IBS_CAPS_BRNTRGT) {
|
||||
rdmsrl(MSR_AMD64_IBSBRTARGET, *buf++);
|
||||
size++;
|
||||
}
|
||||
if (ibs_caps & IBS_CAPS_OPDATA4) {
|
||||
rdmsrl(MSR_AMD64_IBSOPDATA4, *buf++);
|
||||
size++;
|
||||
}
|
||||
}
|
||||
if (ibs_caps & IBS_CAPS_OPDATA4) {
|
||||
rdmsrl(MSR_AMD64_IBSOPDATA4, *buf++);
|
||||
if (perf_ibs == &perf_ibs_fetch && (ibs_caps & IBS_CAPS_FETCHCTLEXTD)) {
|
||||
rdmsrl(MSR_AMD64_ICIBSEXTDCTL, *buf++);
|
||||
size++;
|
||||
}
|
||||
}
|
||||
@@ -743,6 +759,13 @@ static __init void perf_event_ibs_init(void)
|
||||
{
|
||||
struct attribute **attr = ibs_op_format_attrs;
|
||||
|
||||
/*
|
||||
* Some chips fail to reset the fetch count when it is written; instead
|
||||
* they need a 0-1 transition of IbsFetchEn.
|
||||
*/
|
||||
if (boot_cpu_data.x86 >= 0x16 && boot_cpu_data.x86 <= 0x18)
|
||||
perf_ibs_fetch.fetch_count_reset_broken = 1;
|
||||
|
||||
perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch");
|
||||
|
||||
if (ibs_caps & IBS_CAPS_OPCNT) {
|
||||
|
||||
@@ -356,6 +356,7 @@
|
||||
#define MSR_AMD64_IBSOP_REG_MASK ((1UL<<MSR_AMD64_IBSOP_REG_COUNT)-1)
|
||||
#define MSR_AMD64_IBSCTL 0xc001103a
|
||||
#define MSR_AMD64_IBSBRTARGET 0xc001103b
|
||||
#define MSR_AMD64_ICIBSEXTDCTL 0xc001103c
|
||||
#define MSR_AMD64_IBSOPDATA4 0xc001103d
|
||||
#define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */
|
||||
|
||||
|
||||
@@ -211,8 +211,7 @@ setup_boot_parameters(struct kimage *image, struct boot_params *params,
|
||||
params->hdr.hardware_subarch = boot_params.hdr.hardware_subarch;
|
||||
|
||||
/* Copying screen_info will do? */
|
||||
memcpy(¶ms->screen_info, &boot_params.screen_info,
|
||||
sizeof(struct screen_info));
|
||||
memcpy(¶ms->screen_info, &screen_info, sizeof(struct screen_info));
|
||||
|
||||
/* Fill in memsize later */
|
||||
params->screen_info.ext_mem_k = 0;
|
||||
|
||||
@@ -757,6 +757,9 @@ int __init acpi_aml_init(void)
|
||||
goto err_exit;
|
||||
}
|
||||
|
||||
if (acpi_disabled)
|
||||
return -ENODEV;
|
||||
|
||||
/* Initialize AML IO interface */
|
||||
mutex_init(&acpi_aml_io.lock);
|
||||
init_waitqueue_head(&acpi_aml_io.wait);
|
||||
|
||||
@@ -223,9 +223,9 @@ static int __init extlog_init(void)
|
||||
u64 cap;
|
||||
int rc;
|
||||
|
||||
rdmsrl(MSR_IA32_MCG_CAP, cap);
|
||||
|
||||
if (!(cap & MCG_ELOG_P) || !extlog_get_l1addr())
|
||||
if (rdmsrl_safe(MSR_IA32_MCG_CAP, &cap) ||
|
||||
!(cap & MCG_ELOG_P) ||
|
||||
!extlog_get_l1addr())
|
||||
return -ENODEV;
|
||||
|
||||
if (get_edac_report_status() == EDAC_REPORTING_FORCE) {
|
||||
|
||||
@@ -1219,7 +1219,7 @@ static ssize_t format1_show(struct device *dev,
|
||||
le16_to_cpu(nfit_dcr->dcr->code));
|
||||
break;
|
||||
}
|
||||
if (rc != ENXIO)
|
||||
if (rc != -ENXIO)
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&acpi_desc->init_mutex);
|
||||
|
||||
@@ -268,6 +268,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "530U4E/540U4E"),
|
||||
},
|
||||
},
|
||||
/* https://bugs.launchpad.net/bugs/1894667 */
|
||||
{
|
||||
.callback = video_detect_force_video,
|
||||
.ident = "HP 635 Notebook",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "HP 635 Notebook PC"),
|
||||
},
|
||||
},
|
||||
|
||||
/* Non win8 machines which need native backlight nevertheless */
|
||||
{
|
||||
|
||||
@@ -122,7 +122,7 @@
|
||||
/* Descriptor table word 0 bit (when DTA32M = 1) */
|
||||
#define SATA_RCAR_DTEND BIT(0)
|
||||
|
||||
#define SATA_RCAR_DMA_BOUNDARY 0x1FFFFFFEUL
|
||||
#define SATA_RCAR_DMA_BOUNDARY 0x1FFFFFFFUL
|
||||
|
||||
/* Gen2 Physical Layer Control Registers */
|
||||
#define RCAR_GEN2_PHY_CTL1_REG 0x1704
|
||||
|
||||
@@ -2348,6 +2348,7 @@ static inline bool fwnode_is_primary(struct fwnode_handle *fwnode)
|
||||
*/
|
||||
void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
|
||||
{
|
||||
struct device *parent = dev->parent;
|
||||
struct fwnode_handle *fn = dev->fwnode;
|
||||
|
||||
if (fwnode) {
|
||||
@@ -2362,7 +2363,8 @@ void set_primary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
|
||||
} else {
|
||||
if (fwnode_is_primary(fn)) {
|
||||
dev->fwnode = fn->secondary;
|
||||
fn->secondary = NULL;
|
||||
if (!(parent && fn == parent->fwnode))
|
||||
fn->secondary = ERR_PTR(-ENODEV);
|
||||
} else {
|
||||
dev->fwnode = NULL;
|
||||
}
|
||||
|
||||
@@ -124,10 +124,12 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
|
||||
if (clk_hw_get_flags(clk_hw) & CLK_IS_BASIC) {
|
||||
pr_warn("can't setup clkdm for basic clk %s\n",
|
||||
__clk_get_name(clk));
|
||||
clk_put(clk);
|
||||
continue;
|
||||
}
|
||||
to_clk_hw_omap(clk_hw)->clkdm_name = clkdm_name;
|
||||
omap2_init_clk_clkdm(clk_hw);
|
||||
clk_put(clk);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -720,7 +720,8 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
||||
cpumask_copy(policy->cpus, topology_core_cpumask(cpu));
|
||||
}
|
||||
|
||||
if (check_amd_hwpstate_cpu(cpu) && !acpi_pstate_strict) {
|
||||
if (check_amd_hwpstate_cpu(cpu) && boot_cpu_data.x86 < 0x19 &&
|
||||
!acpi_pstate_strict) {
|
||||
cpumask_clear(policy->cpus);
|
||||
cpumask_set_cpu(cpu, policy->cpus);
|
||||
cpumask_copy(data->freqdomain_cpus,
|
||||
|
||||
@@ -144,7 +144,8 @@ static const struct reg_field sti_stih407_dvfs_regfields[DVFS_MAX_REGFIELDS] = {
|
||||
static const struct reg_field *sti_cpufreq_match(void)
|
||||
{
|
||||
if (of_machine_is_compatible("st,stih407") ||
|
||||
of_machine_is_compatible("st,stih410"))
|
||||
of_machine_is_compatible("st,stih410") ||
|
||||
of_machine_is_compatible("st,stih418"))
|
||||
return sti_stih407_dvfs_regfields;
|
||||
|
||||
return NULL;
|
||||
@@ -260,7 +261,8 @@ static int sti_cpufreq_init(void)
|
||||
int ret;
|
||||
|
||||
if ((!of_machine_is_compatible("st,stih407")) &&
|
||||
(!of_machine_is_compatible("st,stih410")))
|
||||
(!of_machine_is_compatible("st,stih410")) &&
|
||||
(!of_machine_is_compatible("st,stih418")))
|
||||
return -ENODEV;
|
||||
|
||||
ddata.cpu = get_cpu_device(0);
|
||||
|
||||
@@ -567,11 +567,11 @@ static enum dma_status jz4780_dma_tx_status(struct dma_chan *chan,
|
||||
enum dma_status status;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&jzchan->vchan.lock, flags);
|
||||
|
||||
status = dma_cookie_status(chan, cookie, txstate);
|
||||
if ((status == DMA_COMPLETE) || (txstate == NULL))
|
||||
return status;
|
||||
|
||||
spin_lock_irqsave(&jzchan->vchan.lock, flags);
|
||||
goto out_unlock_irqrestore;
|
||||
|
||||
vdesc = vchan_find_desc(&jzchan->vchan, cookie);
|
||||
if (vdesc) {
|
||||
@@ -588,6 +588,7 @@ static enum dma_status jz4780_dma_tx_status(struct dma_chan *chan,
|
||||
&& jzchan->desc->status & (JZ_DMA_DCS_AR | JZ_DMA_DCS_HLT))
|
||||
status = DMA_ERROR;
|
||||
|
||||
out_unlock_irqrestore:
|
||||
spin_unlock_irqrestore(&jzchan->vchan.lock, flags);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,12 @@ struct adc12138 {
|
||||
struct completion complete;
|
||||
/* The number of cclk periods for the S/H's acquisition time */
|
||||
unsigned int acquisition_time;
|
||||
/*
|
||||
* Maximum size needed: 16x 2 bytes ADC data + 8 bytes timestamp.
|
||||
* Less may be need if not all channels are enabled, as long as
|
||||
* the 8 byte alignment of the timestamp is maintained.
|
||||
*/
|
||||
__be16 data[20] __aligned(8);
|
||||
|
||||
u8 tx_buf[2] ____cacheline_aligned;
|
||||
u8 rx_buf[2];
|
||||
@@ -333,7 +339,6 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p)
|
||||
struct iio_poll_func *pf = p;
|
||||
struct iio_dev *indio_dev = pf->indio_dev;
|
||||
struct adc12138 *adc = iio_priv(indio_dev);
|
||||
__be16 data[20] = { }; /* 16x 2 bytes ADC data + 8 bytes timestamp */
|
||||
__be16 trash;
|
||||
int ret;
|
||||
int scan_index;
|
||||
@@ -349,7 +354,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p)
|
||||
reinit_completion(&adc->complete);
|
||||
|
||||
ret = adc12138_start_and_read_conv(adc, scan_chan,
|
||||
i ? &data[i - 1] : &trash);
|
||||
i ? &adc->data[i - 1] : &trash);
|
||||
if (ret) {
|
||||
dev_warn(&adc->spi->dev,
|
||||
"failed to start conversion\n");
|
||||
@@ -366,7 +371,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p)
|
||||
}
|
||||
|
||||
if (i) {
|
||||
ret = adc12138_read_conv_data(adc, &data[i - 1]);
|
||||
ret = adc12138_read_conv_data(adc, &adc->data[i - 1]);
|
||||
if (ret) {
|
||||
dev_warn(&adc->spi->dev,
|
||||
"failed to get conversion data\n");
|
||||
@@ -374,7 +379,7 @@ static irqreturn_t adc12138_trigger_handler(int irq, void *p)
|
||||
}
|
||||
}
|
||||
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, data,
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, adc->data,
|
||||
iio_get_time_ns(indio_dev));
|
||||
out:
|
||||
mutex_unlock(&adc->lock);
|
||||
|
||||
@@ -49,13 +49,20 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p)
|
||||
struct iio_poll_func *pf = p;
|
||||
struct iio_dev *indio_dev = pf->indio_dev;
|
||||
struct itg3200 *st = iio_priv(indio_dev);
|
||||
__be16 buf[ITG3200_SCAN_ELEMENTS + sizeof(s64)/sizeof(u16)];
|
||||
/*
|
||||
* Ensure correct alignment and padding including for the
|
||||
* timestamp that may be inserted.
|
||||
*/
|
||||
struct {
|
||||
__be16 buf[ITG3200_SCAN_ELEMENTS];
|
||||
s64 ts __aligned(8);
|
||||
} scan;
|
||||
|
||||
int ret = itg3200_read_all_channels(st->i2c, buf);
|
||||
int ret = itg3200_read_all_channels(st->i2c, scan.buf);
|
||||
if (ret < 0)
|
||||
goto error_ret;
|
||||
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp);
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, &scan, pf->timestamp);
|
||||
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
|
||||
|
||||
@@ -172,6 +172,7 @@ struct si1145_part_info {
|
||||
* @part_info: Part information
|
||||
* @trig: Pointer to iio trigger
|
||||
* @meas_rate: Value of MEAS_RATE register. Only set in HW in auto mode
|
||||
* @buffer: Used to pack data read from sensor.
|
||||
*/
|
||||
struct si1145_data {
|
||||
struct i2c_client *client;
|
||||
@@ -183,6 +184,14 @@ struct si1145_data {
|
||||
bool autonomous;
|
||||
struct iio_trigger *trig;
|
||||
int meas_rate;
|
||||
/*
|
||||
* Ensure timestamp will be naturally aligned if present.
|
||||
* Maximum buffer size (may be only partly used if not all
|
||||
* channels are enabled):
|
||||
* 6*2 bytes channels data + 4 bytes alignment +
|
||||
* 8 bytes timestamp
|
||||
*/
|
||||
u8 buffer[24] __aligned(8);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -444,12 +453,6 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private)
|
||||
struct iio_poll_func *pf = private;
|
||||
struct iio_dev *indio_dev = pf->indio_dev;
|
||||
struct si1145_data *data = iio_priv(indio_dev);
|
||||
/*
|
||||
* Maximum buffer size:
|
||||
* 6*2 bytes channels data + 4 bytes alignment +
|
||||
* 8 bytes timestamp
|
||||
*/
|
||||
u8 buffer[24];
|
||||
int i, j = 0;
|
||||
int ret;
|
||||
u8 irq_status = 0;
|
||||
@@ -482,7 +485,7 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private)
|
||||
|
||||
ret = i2c_smbus_read_i2c_block_data_or_emulated(
|
||||
data->client, indio_dev->channels[i].address,
|
||||
sizeof(u16) * run, &buffer[j]);
|
||||
sizeof(u16) * run, &data->buffer[j]);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
j += run * sizeof(u16);
|
||||
@@ -497,7 +500,7 @@ static irqreturn_t si1145_trigger_handler(int irq, void *private)
|
||||
goto done;
|
||||
}
|
||||
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, buffer,
|
||||
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
|
||||
iio_get_time_ns(indio_dev));
|
||||
|
||||
done:
|
||||
|
||||
@@ -74,7 +74,7 @@ EXPORT_SYMBOL(hil_mlc_unregister);
|
||||
static LIST_HEAD(hil_mlcs);
|
||||
static DEFINE_RWLOCK(hil_mlcs_lock);
|
||||
static struct timer_list hil_mlcs_kicker;
|
||||
static int hil_mlcs_probe;
|
||||
static int hil_mlcs_probe, hil_mlc_stop;
|
||||
|
||||
static void hil_mlcs_process(unsigned long unused);
|
||||
static DECLARE_TASKLET_DISABLED(hil_mlcs_tasklet, hil_mlcs_process, 0);
|
||||
@@ -704,9 +704,13 @@ static int hilse_donode(hil_mlc *mlc)
|
||||
if (!mlc->ostarted) {
|
||||
mlc->ostarted = 1;
|
||||
mlc->opacket = pack;
|
||||
mlc->out(mlc);
|
||||
rc = mlc->out(mlc);
|
||||
nextidx = HILSEN_DOZE;
|
||||
write_unlock_irqrestore(&mlc->lock, flags);
|
||||
if (rc) {
|
||||
hil_mlc_stop = 1;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
mlc->ostarted = 0;
|
||||
@@ -717,8 +721,13 @@ static int hilse_donode(hil_mlc *mlc)
|
||||
|
||||
case HILSE_CTS:
|
||||
write_lock_irqsave(&mlc->lock, flags);
|
||||
nextidx = mlc->cts(mlc) ? node->bad : node->good;
|
||||
rc = mlc->cts(mlc);
|
||||
nextidx = rc ? node->bad : node->good;
|
||||
write_unlock_irqrestore(&mlc->lock, flags);
|
||||
if (rc) {
|
||||
hil_mlc_stop = 1;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -786,6 +795,12 @@ static void hil_mlcs_process(unsigned long unused)
|
||||
|
||||
static void hil_mlcs_timer(unsigned long data)
|
||||
{
|
||||
if (hil_mlc_stop) {
|
||||
/* could not send packet - stop immediately. */
|
||||
pr_warn(PREFIX "HIL seems stuck - Disabling HIL MLC.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hil_mlcs_probe = 1;
|
||||
tasklet_schedule(&hil_mlcs_tasklet);
|
||||
/* Re-insert the periodic task. */
|
||||
|
||||
@@ -213,7 +213,7 @@ static int hp_sdc_mlc_cts(hil_mlc *mlc)
|
||||
priv->tseq[2] = 1;
|
||||
priv->tseq[3] = 0;
|
||||
priv->tseq[4] = 0;
|
||||
__hp_sdc_enqueue_transaction(&priv->trans);
|
||||
return __hp_sdc_enqueue_transaction(&priv->trans);
|
||||
busy:
|
||||
return 1;
|
||||
done:
|
||||
@@ -222,7 +222,7 @@ static int hp_sdc_mlc_cts(hil_mlc *mlc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hp_sdc_mlc_out(hil_mlc *mlc)
|
||||
static int hp_sdc_mlc_out(hil_mlc *mlc)
|
||||
{
|
||||
struct hp_sdc_mlc_priv_s *priv;
|
||||
|
||||
@@ -237,7 +237,7 @@ static void hp_sdc_mlc_out(hil_mlc *mlc)
|
||||
do_data:
|
||||
if (priv->emtestmode) {
|
||||
up(&mlc->osem);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
/* Shouldn't be sending commands when loop may be busy */
|
||||
BUG_ON(down_trylock(&mlc->csem));
|
||||
@@ -299,7 +299,7 @@ static void hp_sdc_mlc_out(hil_mlc *mlc)
|
||||
BUG_ON(down_trylock(&mlc->csem));
|
||||
}
|
||||
enqueue:
|
||||
hp_sdc_enqueue_transaction(&priv->trans);
|
||||
return hp_sdc_enqueue_transaction(&priv->trans);
|
||||
}
|
||||
|
||||
static int __init hp_sdc_mlc_init(void)
|
||||
|
||||
@@ -336,7 +336,7 @@ static int bcm6328_led(struct device *dev, struct device_node *nc, u32 reg,
|
||||
led->cdev.brightness_set = bcm6328_led_set;
|
||||
led->cdev.blink_set = bcm6328_blink_set;
|
||||
|
||||
rc = led_classdev_register(dev, &led->cdev);
|
||||
rc = devm_led_classdev_register(dev, &led->cdev);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ static int bcm6358_led(struct device *dev, struct device_node *nc, u32 reg,
|
||||
|
||||
led->cdev.brightness_set = bcm6358_led_set;
|
||||
|
||||
rc = led_classdev_register(dev, &led->cdev);
|
||||
rc = devm_led_classdev_register(dev, &led->cdev);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
|
||||
@@ -1339,7 +1339,7 @@ __acquires(bitmap->lock)
|
||||
if (bitmap->bp[page].hijacked ||
|
||||
bitmap->bp[page].map == NULL)
|
||||
csize = ((sector_t)1) << (bitmap->chunkshift +
|
||||
PAGE_COUNTER_SHIFT - 1);
|
||||
PAGE_COUNTER_SHIFT);
|
||||
else
|
||||
csize = ((sector_t)1) << bitmap->chunkshift;
|
||||
*blocks = csize - (offset & (csize - 1));
|
||||
|
||||
@@ -2259,8 +2259,6 @@ static int resize_stripes(struct r5conf *conf, int newsize)
|
||||
} else
|
||||
err = -ENOMEM;
|
||||
|
||||
mutex_unlock(&conf->cache_size_mutex);
|
||||
|
||||
conf->slab_cache = sc;
|
||||
conf->active_name = 1-conf->active_name;
|
||||
|
||||
@@ -2283,6 +2281,8 @@ static int resize_stripes(struct r5conf *conf, int newsize)
|
||||
|
||||
if (!err)
|
||||
conf->pool_size = newsize;
|
||||
mutex_unlock(&conf->cache_size_mutex);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -767,6 +767,9 @@ static int tw5864_enum_frameintervals(struct file *file, void *priv,
|
||||
fintv->type = V4L2_FRMIVAL_TYPE_STEPWISE;
|
||||
|
||||
ret = tw5864_frameinterval_get(input, &frameinterval);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
fintv->stepwise.step = frameinterval;
|
||||
fintv->stepwise.min = frameinterval;
|
||||
fintv->stepwise.max = frameinterval;
|
||||
@@ -785,6 +788,9 @@ static int tw5864_g_parm(struct file *file, void *priv,
|
||||
cp->capability = V4L2_CAP_TIMEPERFRAME;
|
||||
|
||||
ret = tw5864_frameinterval_get(input, &cp->timeperframe);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
cp->timeperframe.numerator *= input->frame_interval;
|
||||
cp->capturemode = 0;
|
||||
cp->readbuffers = 2;
|
||||
|
||||
@@ -165,35 +165,12 @@ static const struct file_operations emif_mr4_fops = {
|
||||
|
||||
static int __init_or_module emif_debugfs_init(struct emif_data *emif)
|
||||
{
|
||||
struct dentry *dentry;
|
||||
int ret;
|
||||
|
||||
dentry = debugfs_create_dir(dev_name(emif->dev), NULL);
|
||||
if (!dentry) {
|
||||
ret = -ENOMEM;
|
||||
goto err0;
|
||||
}
|
||||
emif->debugfs_root = dentry;
|
||||
|
||||
dentry = debugfs_create_file("regcache_dump", S_IRUGO,
|
||||
emif->debugfs_root, emif, &emif_regdump_fops);
|
||||
if (!dentry) {
|
||||
ret = -ENOMEM;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
dentry = debugfs_create_file("mr4", S_IRUGO,
|
||||
emif->debugfs_root, emif, &emif_mr4_fops);
|
||||
if (!dentry) {
|
||||
ret = -ENOMEM;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
emif->debugfs_root = debugfs_create_dir(dev_name(emif->dev), NULL);
|
||||
debugfs_create_file("regcache_dump", S_IRUGO, emif->debugfs_root, emif,
|
||||
&emif_regdump_fops);
|
||||
debugfs_create_file("mr4", S_IRUGO, emif->debugfs_root, emif,
|
||||
&emif_mr4_fops);
|
||||
return 0;
|
||||
err1:
|
||||
debugfs_remove_recursive(emif->debugfs_root);
|
||||
err0:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit emif_debugfs_exit(struct emif_data *emif)
|
||||
|
||||
@@ -1176,8 +1176,10 @@ mptscsih_remove(struct pci_dev *pdev)
|
||||
|
||||
scsi_remove_host(host);
|
||||
|
||||
if((hd = shost_priv(host)) == NULL)
|
||||
return;
|
||||
if (host == NULL)
|
||||
hd = NULL;
|
||||
else
|
||||
hd = shost_priv(host);
|
||||
|
||||
mptscsih_shutdown(pdev);
|
||||
|
||||
@@ -1193,14 +1195,15 @@ mptscsih_remove(struct pci_dev *pdev)
|
||||
"Free'd ScsiLookup (%d) memory\n",
|
||||
ioc->name, sz1));
|
||||
|
||||
kfree(hd->info_kbuf);
|
||||
if (hd)
|
||||
kfree(hd->info_kbuf);
|
||||
|
||||
/* NULL the Scsi_Host pointer
|
||||
*/
|
||||
ioc->sh = NULL;
|
||||
|
||||
scsi_host_put(host);
|
||||
|
||||
if (host)
|
||||
scsi_host_put(host);
|
||||
mpt_detach(pdev);
|
||||
|
||||
}
|
||||
|
||||
@@ -1269,11 +1269,14 @@ static void via_init_sdc_pm(struct via_crdr_mmc_host *host)
|
||||
static int via_sd_suspend(struct pci_dev *pcidev, pm_message_t state)
|
||||
{
|
||||
struct via_crdr_mmc_host *host;
|
||||
unsigned long flags;
|
||||
|
||||
host = pci_get_drvdata(pcidev);
|
||||
|
||||
spin_lock_irqsave(&host->lock, flags);
|
||||
via_save_pcictrlreg(host);
|
||||
via_save_sdcreg(host);
|
||||
spin_unlock_irqrestore(&host->lock, flags);
|
||||
|
||||
pci_save_state(pcidev);
|
||||
pci_enable_wake(pcidev, pci_choose_state(pcidev, state), 0);
|
||||
|
||||
@@ -1478,6 +1478,19 @@ int ubi_thread(void *u)
|
||||
!ubi->thread_enabled || ubi_dbg_is_bgt_disabled(ubi)) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
spin_unlock(&ubi->wl_lock);
|
||||
|
||||
/*
|
||||
* Check kthread_should_stop() after we set the task
|
||||
* state to guarantee that we either see the stop bit
|
||||
* and exit or the task state is reset to runnable such
|
||||
* that it's not scheduled out indefinitely and detects
|
||||
* the stop bit at kthread_should_stop().
|
||||
*/
|
||||
if (kthread_should_stop()) {
|
||||
set_current_state(TASK_RUNNING);
|
||||
break;
|
||||
}
|
||||
|
||||
schedule();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1385,7 +1385,7 @@ static int gfar_probe(struct platform_device *ofdev)
|
||||
|
||||
if (dev->features & NETIF_F_IP_CSUM ||
|
||||
priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
|
||||
dev->needed_headroom = GMAC_FCB_LEN;
|
||||
dev->needed_headroom = GMAC_FCB_LEN + GMAC_TXPAL_LEN;
|
||||
|
||||
/* Initializing some of the rx/tx queue level parameters */
|
||||
for (i = 0; i < priv->num_tx_queues; i++) {
|
||||
@@ -2367,20 +2367,12 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
fcb_len = GMAC_FCB_LEN + GMAC_TXPAL_LEN;
|
||||
|
||||
/* make space for additional header when fcb is needed */
|
||||
if (fcb_len && unlikely(skb_headroom(skb) < fcb_len)) {
|
||||
struct sk_buff *skb_new;
|
||||
|
||||
skb_new = skb_realloc_headroom(skb, fcb_len);
|
||||
if (!skb_new) {
|
||||
if (fcb_len) {
|
||||
if (unlikely(skb_cow_head(skb, fcb_len))) {
|
||||
dev->stats.tx_errors++;
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
if (skb->sk)
|
||||
skb_set_owner_w(skb_new, skb->sk);
|
||||
dev_consume_skb_any(skb);
|
||||
skb = skb_new;
|
||||
}
|
||||
|
||||
/* total number of fragments in the SKB */
|
||||
|
||||
@@ -485,6 +485,9 @@ static void mlxsw_emad_transmit_retry(struct mlxsw_core *mlxsw_core,
|
||||
err = mlxsw_emad_transmit(trans->core, trans);
|
||||
if (err == 0)
|
||||
return;
|
||||
|
||||
if (!atomic_dec_and_test(&trans->active))
|
||||
return;
|
||||
} else {
|
||||
err = -EIO;
|
||||
}
|
||||
|
||||
@@ -1729,12 +1729,16 @@ static int ravb_hwtstamp_get(struct net_device *ndev, struct ifreq *req)
|
||||
config.flags = 0;
|
||||
config.tx_type = priv->tstamp_tx_ctrl ? HWTSTAMP_TX_ON :
|
||||
HWTSTAMP_TX_OFF;
|
||||
if (priv->tstamp_rx_ctrl & RAVB_RXTSTAMP_TYPE_V2_L2_EVENT)
|
||||
switch (priv->tstamp_rx_ctrl & RAVB_RXTSTAMP_TYPE) {
|
||||
case RAVB_RXTSTAMP_TYPE_V2_L2_EVENT:
|
||||
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
|
||||
else if (priv->tstamp_rx_ctrl & RAVB_RXTSTAMP_TYPE_ALL)
|
||||
break;
|
||||
case RAVB_RXTSTAMP_TYPE_ALL:
|
||||
config.rx_filter = HWTSTAMP_FILTER_ALL;
|
||||
else
|
||||
break;
|
||||
default:
|
||||
config.rx_filter = HWTSTAMP_FILTER_NONE;
|
||||
}
|
||||
|
||||
return copy_to_user(req->ifr_data, &config, sizeof(config)) ?
|
||||
-EFAULT : 0;
|
||||
|
||||
@@ -275,63 +275,69 @@ static inline struct net_device **get_dev_p(struct pvc_device *pvc,
|
||||
|
||||
static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
|
||||
{
|
||||
u16 head_len;
|
||||
struct sk_buff *skb = *skb_p;
|
||||
|
||||
switch (skb->protocol) {
|
||||
case cpu_to_be16(NLPID_CCITT_ANSI_LMI):
|
||||
head_len = 4;
|
||||
skb_push(skb, head_len);
|
||||
skb->data[3] = NLPID_CCITT_ANSI_LMI;
|
||||
break;
|
||||
if (!skb->dev) { /* Control packets */
|
||||
switch (dlci) {
|
||||
case LMI_CCITT_ANSI_DLCI:
|
||||
skb_push(skb, 4);
|
||||
skb->data[3] = NLPID_CCITT_ANSI_LMI;
|
||||
break;
|
||||
|
||||
case cpu_to_be16(NLPID_CISCO_LMI):
|
||||
head_len = 4;
|
||||
skb_push(skb, head_len);
|
||||
skb->data[3] = NLPID_CISCO_LMI;
|
||||
break;
|
||||
case LMI_CISCO_DLCI:
|
||||
skb_push(skb, 4);
|
||||
skb->data[3] = NLPID_CISCO_LMI;
|
||||
break;
|
||||
|
||||
case cpu_to_be16(ETH_P_IP):
|
||||
head_len = 4;
|
||||
skb_push(skb, head_len);
|
||||
skb->data[3] = NLPID_IP;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
case cpu_to_be16(ETH_P_IPV6):
|
||||
head_len = 4;
|
||||
skb_push(skb, head_len);
|
||||
skb->data[3] = NLPID_IPV6;
|
||||
break;
|
||||
} else if (skb->dev->type == ARPHRD_DLCI) {
|
||||
switch (skb->protocol) {
|
||||
case htons(ETH_P_IP):
|
||||
skb_push(skb, 4);
|
||||
skb->data[3] = NLPID_IP;
|
||||
break;
|
||||
|
||||
case cpu_to_be16(ETH_P_802_3):
|
||||
head_len = 10;
|
||||
if (skb_headroom(skb) < head_len) {
|
||||
struct sk_buff *skb2 = skb_realloc_headroom(skb,
|
||||
head_len);
|
||||
case htons(ETH_P_IPV6):
|
||||
skb_push(skb, 4);
|
||||
skb->data[3] = NLPID_IPV6;
|
||||
break;
|
||||
|
||||
default:
|
||||
skb_push(skb, 10);
|
||||
skb->data[3] = FR_PAD;
|
||||
skb->data[4] = NLPID_SNAP;
|
||||
/* OUI 00-00-00 indicates an Ethertype follows */
|
||||
skb->data[5] = 0x00;
|
||||
skb->data[6] = 0x00;
|
||||
skb->data[7] = 0x00;
|
||||
/* This should be an Ethertype: */
|
||||
*(__be16 *)(skb->data + 8) = skb->protocol;
|
||||
}
|
||||
|
||||
} else if (skb->dev->type == ARPHRD_ETHER) {
|
||||
if (skb_headroom(skb) < 10) {
|
||||
struct sk_buff *skb2 = skb_realloc_headroom(skb, 10);
|
||||
if (!skb2)
|
||||
return -ENOBUFS;
|
||||
dev_kfree_skb(skb);
|
||||
skb = *skb_p = skb2;
|
||||
}
|
||||
skb_push(skb, head_len);
|
||||
skb_push(skb, 10);
|
||||
skb->data[3] = FR_PAD;
|
||||
skb->data[4] = NLPID_SNAP;
|
||||
skb->data[5] = FR_PAD;
|
||||
/* OUI 00-80-C2 stands for the 802.1 organization */
|
||||
skb->data[5] = 0x00;
|
||||
skb->data[6] = 0x80;
|
||||
skb->data[7] = 0xC2;
|
||||
/* PID 00-07 stands for Ethernet frames without FCS */
|
||||
skb->data[8] = 0x00;
|
||||
skb->data[9] = 0x07; /* bridged Ethernet frame w/out FCS */
|
||||
break;
|
||||
skb->data[9] = 0x07;
|
||||
|
||||
default:
|
||||
head_len = 10;
|
||||
skb_push(skb, head_len);
|
||||
skb->data[3] = FR_PAD;
|
||||
skb->data[4] = NLPID_SNAP;
|
||||
skb->data[5] = FR_PAD;
|
||||
skb->data[6] = FR_PAD;
|
||||
skb->data[7] = FR_PAD;
|
||||
*(__be16*)(skb->data + 8) = skb->protocol;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dlci_to_q922(skb->data, dlci);
|
||||
@@ -427,8 +433,8 @@ static netdev_tx_t pvc_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
skb_put(skb, pad);
|
||||
memset(skb->data + len, 0, pad);
|
||||
}
|
||||
skb->protocol = cpu_to_be16(ETH_P_802_3);
|
||||
}
|
||||
skb->dev = dev;
|
||||
if (!fr_hard_header(&skb, pvc->dlci)) {
|
||||
dev->stats.tx_bytes += skb->len;
|
||||
dev->stats.tx_packets++;
|
||||
@@ -496,10 +502,8 @@ static void fr_lmi_send(struct net_device *dev, int fullrep)
|
||||
memset(skb->data, 0, len);
|
||||
skb_reserve(skb, 4);
|
||||
if (lmi == LMI_CISCO) {
|
||||
skb->protocol = cpu_to_be16(NLPID_CISCO_LMI);
|
||||
fr_hard_header(&skb, LMI_CISCO_DLCI);
|
||||
} else {
|
||||
skb->protocol = cpu_to_be16(NLPID_CCITT_ANSI_LMI);
|
||||
fr_hard_header(&skb, LMI_CCITT_ANSI_DLCI);
|
||||
}
|
||||
data = skb_tail_pointer(skb);
|
||||
|
||||
@@ -620,6 +620,7 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
|
||||
u8 preamble = 0;
|
||||
u8 group_id;
|
||||
u32 info1, info2, info3;
|
||||
u32 stbc, nsts_su;
|
||||
|
||||
info1 = __le32_to_cpu(rxd->ppdu_start.info1);
|
||||
info2 = __le32_to_cpu(rxd->ppdu_start.info2);
|
||||
@@ -663,11 +664,16 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
|
||||
TODO check this */
|
||||
bw = info2 & 3;
|
||||
sgi = info3 & 1;
|
||||
stbc = (info2 >> 3) & 1;
|
||||
group_id = (info2 >> 4) & 0x3F;
|
||||
|
||||
if (GROUP_ID_IS_SU_MIMO(group_id)) {
|
||||
mcs = (info3 >> 4) & 0x0F;
|
||||
nss = ((info2 >> 10) & 0x07) + 1;
|
||||
nsts_su = ((info2 >> 10) & 0x07);
|
||||
if (stbc)
|
||||
nss = (nsts_su >> 2) + 1;
|
||||
else
|
||||
nss = (nsts_su + 1);
|
||||
} else {
|
||||
/* Hardware doesn't decode VHT-SIG-B into Rx descriptor
|
||||
* so it's impossible to decode MCS. Also since
|
||||
|
||||
@@ -332,10 +332,12 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
|
||||
struct p54p_desc *desc;
|
||||
dma_addr_t mapping;
|
||||
u32 idx, i;
|
||||
__le32 device_addr;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
idx = le32_to_cpu(ring_control->host_idx[1]);
|
||||
i = idx % ARRAY_SIZE(ring_control->tx_data);
|
||||
device_addr = ((struct p54_hdr *)skb->data)->req_id;
|
||||
|
||||
mapping = pci_map_single(priv->pdev, skb->data, skb->len,
|
||||
PCI_DMA_TODEVICE);
|
||||
@@ -349,7 +351,7 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
|
||||
|
||||
desc = &ring_control->tx_data[i];
|
||||
desc->host_addr = cpu_to_le32(mapping);
|
||||
desc->device_addr = ((struct p54_hdr *)skb->data)->req_id;
|
||||
desc->device_addr = device_addr;
|
||||
desc->len = cpu_to_le16(skb->len);
|
||||
desc->flags = 0;
|
||||
|
||||
|
||||
@@ -261,6 +261,16 @@ static int __init __rmem_cmp(const void *a, const void *b)
|
||||
if (ra->base > rb->base)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Put the dynamic allocations (address == 0, size == 0) before static
|
||||
* allocations at address 0x0 so that overlap detection works
|
||||
* correctly.
|
||||
*/
|
||||
if (ra->size < rb->size)
|
||||
return -1;
|
||||
if (ra->size > rb->size)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -278,8 +288,7 @@ static void __init __rmem_check_for_overlap(void)
|
||||
|
||||
this = &reserved_mem[i];
|
||||
next = &reserved_mem[i + 1];
|
||||
if (!(this->base && next->base))
|
||||
continue;
|
||||
|
||||
if (this->base + this->size > next->base) {
|
||||
phys_addr_t this_end, next_end;
|
||||
|
||||
|
||||
@@ -344,6 +344,7 @@ static int param_set_ac_online(const char *key, const struct kernel_param *kp)
|
||||
static int param_get_ac_online(char *buffer, const struct kernel_param *kp)
|
||||
{
|
||||
strcpy(buffer, map_get_key(map_ac_online, ac_online, "unknown"));
|
||||
strcat(buffer, "\n");
|
||||
return strlen(buffer);
|
||||
}
|
||||
|
||||
@@ -357,6 +358,7 @@ static int param_set_usb_online(const char *key, const struct kernel_param *kp)
|
||||
static int param_get_usb_online(char *buffer, const struct kernel_param *kp)
|
||||
{
|
||||
strcpy(buffer, map_get_key(map_ac_online, usb_online, "unknown"));
|
||||
strcat(buffer, "\n");
|
||||
return strlen(buffer);
|
||||
}
|
||||
|
||||
@@ -371,6 +373,7 @@ static int param_set_battery_status(const char *key,
|
||||
static int param_get_battery_status(char *buffer, const struct kernel_param *kp)
|
||||
{
|
||||
strcpy(buffer, map_get_key(map_status, battery_status, "unknown"));
|
||||
strcat(buffer, "\n");
|
||||
return strlen(buffer);
|
||||
}
|
||||
|
||||
@@ -385,6 +388,7 @@ static int param_set_battery_health(const char *key,
|
||||
static int param_get_battery_health(char *buffer, const struct kernel_param *kp)
|
||||
{
|
||||
strcpy(buffer, map_get_key(map_health, battery_health, "unknown"));
|
||||
strcat(buffer, "\n");
|
||||
return strlen(buffer);
|
||||
}
|
||||
|
||||
@@ -400,6 +404,7 @@ static int param_get_battery_present(char *buffer,
|
||||
const struct kernel_param *kp)
|
||||
{
|
||||
strcpy(buffer, map_get_key(map_present, battery_present, "unknown"));
|
||||
strcat(buffer, "\n");
|
||||
return strlen(buffer);
|
||||
}
|
||||
|
||||
@@ -417,6 +422,7 @@ static int param_get_battery_technology(char *buffer,
|
||||
{
|
||||
strcpy(buffer,
|
||||
map_get_key(map_technology, battery_technology, "unknown"));
|
||||
strcat(buffer, "\n");
|
||||
return strlen(buffer);
|
||||
}
|
||||
|
||||
|
||||
@@ -423,16 +423,26 @@ static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||
}
|
||||
}
|
||||
|
||||
static struct rtc_class_ops rx8010_rtc_ops = {
|
||||
static const struct rtc_class_ops rx8010_rtc_ops_default = {
|
||||
.read_time = rx8010_get_time,
|
||||
.set_time = rx8010_set_time,
|
||||
.ioctl = rx8010_ioctl,
|
||||
};
|
||||
|
||||
static const struct rtc_class_ops rx8010_rtc_ops_alarm = {
|
||||
.read_time = rx8010_get_time,
|
||||
.set_time = rx8010_set_time,
|
||||
.ioctl = rx8010_ioctl,
|
||||
.read_alarm = rx8010_read_alarm,
|
||||
.set_alarm = rx8010_set_alarm,
|
||||
.alarm_irq_enable = rx8010_alarm_irq_enable,
|
||||
};
|
||||
|
||||
static int rx8010_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
|
||||
const struct rtc_class_ops *rtc_ops;
|
||||
struct rx8010_data *rx8010;
|
||||
int err = 0;
|
||||
|
||||
@@ -463,16 +473,16 @@ static int rx8010_probe(struct i2c_client *client,
|
||||
|
||||
if (err) {
|
||||
dev_err(&client->dev, "unable to request IRQ\n");
|
||||
client->irq = 0;
|
||||
} else {
|
||||
rx8010_rtc_ops.read_alarm = rx8010_read_alarm;
|
||||
rx8010_rtc_ops.set_alarm = rx8010_set_alarm;
|
||||
rx8010_rtc_ops.alarm_irq_enable = rx8010_alarm_irq_enable;
|
||||
return err;
|
||||
}
|
||||
|
||||
rtc_ops = &rx8010_rtc_ops_alarm;
|
||||
} else {
|
||||
rtc_ops = &rx8010_rtc_ops_default;
|
||||
}
|
||||
|
||||
rx8010->rtc = devm_rtc_device_register(&client->dev, client->name,
|
||||
&rx8010_rtc_ops, THIS_MODULE);
|
||||
rtc_ops, THIS_MODULE);
|
||||
|
||||
if (IS_ERR(rx8010->rtc)) {
|
||||
dev_err(&client->dev, "unable to register the class device\n");
|
||||
|
||||
@@ -1734,15 +1734,16 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
|
||||
*/
|
||||
static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
|
||||
{
|
||||
struct async_scan_data *data;
|
||||
struct async_scan_data *data = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
if (strncmp(scsi_scan_type, "sync", 4) == 0)
|
||||
return NULL;
|
||||
|
||||
mutex_lock(&shost->scan_mutex);
|
||||
if (shost->async_scan) {
|
||||
shost_printk(KERN_DEBUG, shost, "%s called twice\n", __func__);
|
||||
return NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
data = kmalloc(sizeof(*data), GFP_KERNEL);
|
||||
@@ -1753,7 +1754,6 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
|
||||
goto err;
|
||||
init_completion(&data->prev_finished);
|
||||
|
||||
mutex_lock(&shost->scan_mutex);
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
shost->async_scan = 1;
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
@@ -1768,6 +1768,7 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
|
||||
return data;
|
||||
|
||||
err:
|
||||
mutex_unlock(&shost->scan_mutex);
|
||||
kfree(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1351,6 +1351,7 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev,
|
||||
if (dev->irq && board->has_ao_fifo) {
|
||||
dev->write_subdev = s;
|
||||
s->subdev_flags |= SDF_CMD_WRITE;
|
||||
s->len_chanlist = s->n_chan;
|
||||
s->do_cmdtest = cb_pcidas_ao_cmdtest;
|
||||
s->do_cmd = cb_pcidas_ao_cmd;
|
||||
s->cancel = cb_pcidas_ao_cancel;
|
||||
|
||||
@@ -167,7 +167,12 @@ error_destroy_mc_io:
|
||||
*/
|
||||
void fsl_destroy_mc_io(struct fsl_mc_io *mc_io)
|
||||
{
|
||||
struct fsl_mc_device *dpmcp_dev = mc_io->dpmcp_dev;
|
||||
struct fsl_mc_device *dpmcp_dev;
|
||||
|
||||
if (!mc_io)
|
||||
return;
|
||||
|
||||
dpmcp_dev = mc_io->dpmcp_dev;
|
||||
|
||||
if (dpmcp_dev)
|
||||
fsl_mc_io_unset_dpmcp(mc_io);
|
||||
|
||||
@@ -155,12 +155,6 @@ int cvm_oct_phy_setup_device(struct net_device *dev)
|
||||
|
||||
phy_node = of_parse_phandle(priv->of_node, "phy-handle", 0);
|
||||
if (!phy_node && of_phy_is_fixed_link(priv->of_node)) {
|
||||
int rc;
|
||||
|
||||
rc = of_phy_register_fixed_link(priv->of_node);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
phy_node = of_node_get(priv->of_node);
|
||||
}
|
||||
if (!phy_node)
|
||||
|
||||
@@ -83,15 +83,17 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
|
||||
else
|
||||
port = work->word1.cn38xx.ipprt;
|
||||
|
||||
if ((work->word2.snoip.err_code == 10) && (work->word1.len <= 64)) {
|
||||
if ((work->word2.snoip.err_code == 10) && (work->word1.len <= 64))
|
||||
/*
|
||||
* Ignore length errors on min size packets. Some
|
||||
* equipment incorrectly pads packets to 64+4FCS
|
||||
* instead of 60+4FCS. Note these packets still get
|
||||
* counted as frame errors.
|
||||
*/
|
||||
} else if (work->word2.snoip.err_code == 5 ||
|
||||
work->word2.snoip.err_code == 7) {
|
||||
return 0;
|
||||
|
||||
if (work->word2.snoip.err_code == 5 ||
|
||||
work->word2.snoip.err_code == 7) {
|
||||
/*
|
||||
* We received a packet with either an alignment error
|
||||
* or a FCS error. This may be signalling that we are
|
||||
@@ -122,7 +124,10 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
|
||||
/* Port received 0xd5 preamble */
|
||||
work->packet_ptr.s.addr += i + 1;
|
||||
work->word1.len -= i + 5;
|
||||
} else if ((*ptr & 0xf) == 0xd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((*ptr & 0xf) == 0xd) {
|
||||
/* Port received 0xd preamble */
|
||||
work->packet_ptr.s.addr += i;
|
||||
work->word1.len -= i + 4;
|
||||
@@ -132,21 +137,20 @@ static inline int cvm_oct_check_rcv_error(cvmx_wqe_t *work)
|
||||
((*(ptr + 1) & 0xf) << 4);
|
||||
ptr++;
|
||||
}
|
||||
} else {
|
||||
printk_ratelimited("Port %d unknown preamble, packet dropped\n",
|
||||
port);
|
||||
cvm_oct_free_work(work);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
printk_ratelimited("Port %d unknown preamble, packet dropped\n",
|
||||
port);
|
||||
cvm_oct_free_work(work);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
printk_ratelimited("Port %d receive error code %d, packet dropped\n",
|
||||
port, work->word2.snoip.err_code);
|
||||
cvm_oct_free_work(work);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
printk_ratelimited("Port %d receive error code %d, packet dropped\n",
|
||||
port, work->word2.snoip.err_code);
|
||||
cvm_oct_free_work(work);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int cvm_oct_poll(struct oct_rx_group *rx_group, int budget)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/phy.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of_mdio.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_vlan.h>
|
||||
@@ -880,6 +881,14 @@ static int cvm_oct_probe(struct platform_device *pdev)
|
||||
break;
|
||||
}
|
||||
|
||||
if (priv->of_node && of_phy_is_fixed_link(priv->of_node)) {
|
||||
if (of_phy_register_fixed_link(priv->of_node)) {
|
||||
netdev_err(dev, "Failed to register fixed link for interface %d, port %d\n",
|
||||
interface, priv->port);
|
||||
dev->netdev_ops = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dev->netdev_ops) {
|
||||
free_netdev(dev);
|
||||
} else if (register_netdev(dev) < 0) {
|
||||
|
||||
@@ -56,7 +56,7 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
*/
|
||||
baud = tty_termios_baud_rate(termios);
|
||||
|
||||
serial8250_do_set_termios(port, termios, old);
|
||||
serial8250_do_set_termios(port, termios, NULL);
|
||||
|
||||
tty_termios_encode_baud_rate(termios, baud, baud);
|
||||
|
||||
|
||||
@@ -1287,6 +1287,9 @@ static int __init serial_txx9_init(void)
|
||||
|
||||
#ifdef ENABLE_SERIAL_TXX9_PCI
|
||||
ret = pci_register_driver(&serial_txx9_pci_driver);
|
||||
if (ret) {
|
||||
platform_driver_unregister(&serial_txx9_plat_driver);
|
||||
}
|
||||
#endif
|
||||
if (ret == 0)
|
||||
goto out;
|
||||
|
||||
@@ -712,8 +712,13 @@ static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
|
||||
return;
|
||||
|
||||
if ((unsigned)value < ARRAY_SIZE(func_table)) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&func_buf_lock, flags);
|
||||
if (func_table[value])
|
||||
puts_queue(vc, func_table[value]);
|
||||
spin_unlock_irqrestore(&func_buf_lock, flags);
|
||||
|
||||
} else
|
||||
pr_err("k_fn called with value=%d\n", value);
|
||||
}
|
||||
@@ -1959,13 +1964,11 @@ out:
|
||||
#undef s
|
||||
#undef v
|
||||
|
||||
/* FIXME: This one needs untangling and locking */
|
||||
/* FIXME: This one needs untangling */
|
||||
int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
|
||||
{
|
||||
struct kbsentry *kbs;
|
||||
char *p;
|
||||
u_char *q;
|
||||
u_char __user *up;
|
||||
int sz, fnw_sz;
|
||||
int delta;
|
||||
char *first_free, *fj, *fnw;
|
||||
@@ -1991,23 +1994,19 @@ int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
|
||||
i = kbs->kb_func;
|
||||
|
||||
switch (cmd) {
|
||||
case KDGKBSENT:
|
||||
sz = sizeof(kbs->kb_string) - 1; /* sz should have been
|
||||
a struct member */
|
||||
up = user_kdgkb->kb_string;
|
||||
p = func_table[i];
|
||||
if(p)
|
||||
for ( ; *p && sz; p++, sz--)
|
||||
if (put_user(*p, up++)) {
|
||||
ret = -EFAULT;
|
||||
goto reterr;
|
||||
}
|
||||
if (put_user('\0', up)) {
|
||||
ret = -EFAULT;
|
||||
goto reterr;
|
||||
}
|
||||
kfree(kbs);
|
||||
return ((p && *p) ? -EOVERFLOW : 0);
|
||||
case KDGKBSENT: {
|
||||
/* size should have been a struct member */
|
||||
ssize_t len = sizeof(user_kdgkb->kb_string);
|
||||
|
||||
spin_lock_irqsave(&func_buf_lock, flags);
|
||||
len = strlcpy(kbs->kb_string, func_table[i] ? : "", len);
|
||||
spin_unlock_irqrestore(&func_buf_lock, flags);
|
||||
|
||||
ret = copy_to_user(user_kdgkb->kb_string, kbs->kb_string,
|
||||
len + 1) ? -EFAULT : 0;
|
||||
|
||||
goto reterr;
|
||||
}
|
||||
case KDSKBSENT:
|
||||
if (!perm) {
|
||||
ret = -EPERM;
|
||||
|
||||
@@ -4235,27 +4235,6 @@ static int con_font_default(struct vc_data *vc, struct console_font_op *op)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int con_font_copy(struct vc_data *vc, struct console_font_op *op)
|
||||
{
|
||||
int con = op->height;
|
||||
int rc;
|
||||
|
||||
|
||||
console_lock();
|
||||
if (vc->vc_mode != KD_TEXT)
|
||||
rc = -EINVAL;
|
||||
else if (!vc->vc_sw->con_font_copy)
|
||||
rc = -ENOSYS;
|
||||
else if (con < 0 || !vc_cons_allocated(con))
|
||||
rc = -ENOTTY;
|
||||
else if (con == vc->vc_num) /* nothing to do */
|
||||
rc = 0;
|
||||
else
|
||||
rc = vc->vc_sw->con_font_copy(vc, con);
|
||||
console_unlock();
|
||||
return rc;
|
||||
}
|
||||
|
||||
int con_font_op(struct vc_data *vc, struct console_font_op *op)
|
||||
{
|
||||
switch (op->op) {
|
||||
@@ -4266,7 +4245,8 @@ int con_font_op(struct vc_data *vc, struct console_font_op *op)
|
||||
case KD_FONT_OP_SET_DEFAULT:
|
||||
return con_font_default(vc, op);
|
||||
case KD_FONT_OP_COPY:
|
||||
return con_font_copy(vc, op);
|
||||
/* was buggy and never really used */
|
||||
return -EINVAL;
|
||||
}
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ int vt_waitactive(int n)
|
||||
|
||||
|
||||
static inline int
|
||||
do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op)
|
||||
do_fontx_ioctl(struct vc_data *vc, int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op)
|
||||
{
|
||||
struct consolefontdesc cfdarg;
|
||||
int i;
|
||||
@@ -261,15 +261,16 @@ do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struc
|
||||
op->height = cfdarg.charheight;
|
||||
op->charcount = cfdarg.charcount;
|
||||
op->data = cfdarg.chardata;
|
||||
return con_font_op(vc_cons[fg_console].d, op);
|
||||
case GIO_FONTX: {
|
||||
return con_font_op(vc, op);
|
||||
|
||||
case GIO_FONTX:
|
||||
op->op = KD_FONT_OP_GET;
|
||||
op->flags = KD_FONT_FLAG_OLD;
|
||||
op->width = 8;
|
||||
op->height = cfdarg.charheight;
|
||||
op->charcount = cfdarg.charcount;
|
||||
op->data = cfdarg.chardata;
|
||||
i = con_font_op(vc_cons[fg_console].d, op);
|
||||
i = con_font_op(vc, op);
|
||||
if (i)
|
||||
return i;
|
||||
cfdarg.charheight = op->height;
|
||||
@@ -277,7 +278,6 @@ do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struc
|
||||
if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -927,7 +927,7 @@ int vt_ioctl(struct tty_struct *tty,
|
||||
op.height = 0;
|
||||
op.charcount = 256;
|
||||
op.data = up;
|
||||
ret = con_font_op(vc_cons[fg_console].d, &op);
|
||||
ret = con_font_op(vc, &op);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -938,7 +938,7 @@ int vt_ioctl(struct tty_struct *tty,
|
||||
op.height = 32;
|
||||
op.charcount = 256;
|
||||
op.data = up;
|
||||
ret = con_font_op(vc_cons[fg_console].d, &op);
|
||||
ret = con_font_op(vc, &op);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -955,7 +955,7 @@ int vt_ioctl(struct tty_struct *tty,
|
||||
|
||||
case PIO_FONTX:
|
||||
case GIO_FONTX:
|
||||
ret = do_fontx_ioctl(cmd, up, perm, &op);
|
||||
ret = do_fontx_ioctl(vc, cmd, up, perm, &op);
|
||||
break;
|
||||
|
||||
case PIO_FONTRESET:
|
||||
@@ -972,11 +972,11 @@ int vt_ioctl(struct tty_struct *tty,
|
||||
{
|
||||
op.op = KD_FONT_OP_SET_DEFAULT;
|
||||
op.data = NULL;
|
||||
ret = con_font_op(vc_cons[fg_console].d, &op);
|
||||
ret = con_font_op(vc, &op);
|
||||
if (ret)
|
||||
break;
|
||||
console_lock();
|
||||
con_set_default_unimap(vc_cons[fg_console].d);
|
||||
con_set_default_unimap(vc);
|
||||
console_unlock();
|
||||
break;
|
||||
}
|
||||
@@ -1103,8 +1103,9 @@ struct compat_consolefontdesc {
|
||||
};
|
||||
|
||||
static inline int
|
||||
compat_fontx_ioctl(int cmd, struct compat_consolefontdesc __user *user_cfd,
|
||||
int perm, struct console_font_op *op)
|
||||
compat_fontx_ioctl(struct vc_data *vc, int cmd,
|
||||
struct compat_consolefontdesc __user *user_cfd,
|
||||
int perm, struct console_font_op *op)
|
||||
{
|
||||
struct compat_consolefontdesc cfdarg;
|
||||
int i;
|
||||
@@ -1122,7 +1123,8 @@ compat_fontx_ioctl(int cmd, struct compat_consolefontdesc __user *user_cfd,
|
||||
op->height = cfdarg.charheight;
|
||||
op->charcount = cfdarg.charcount;
|
||||
op->data = compat_ptr(cfdarg.chardata);
|
||||
return con_font_op(vc_cons[fg_console].d, op);
|
||||
return con_font_op(vc, op);
|
||||
|
||||
case GIO_FONTX:
|
||||
op->op = KD_FONT_OP_GET;
|
||||
op->flags = KD_FONT_FLAG_OLD;
|
||||
@@ -1130,7 +1132,7 @@ compat_fontx_ioctl(int cmd, struct compat_consolefontdesc __user *user_cfd,
|
||||
op->height = cfdarg.charheight;
|
||||
op->charcount = cfdarg.charcount;
|
||||
op->data = compat_ptr(cfdarg.chardata);
|
||||
i = con_font_op(vc_cons[fg_console].d, op);
|
||||
i = con_font_op(vc, op);
|
||||
if (i)
|
||||
return i;
|
||||
cfdarg.charheight = op->height;
|
||||
@@ -1225,7 +1227,7 @@ long vt_compat_ioctl(struct tty_struct *tty,
|
||||
*/
|
||||
case PIO_FONTX:
|
||||
case GIO_FONTX:
|
||||
ret = compat_fontx_ioctl(cmd, up, perm, &op);
|
||||
ret = compat_fontx_ioctl(vc, cmd, up, perm, &op);
|
||||
break;
|
||||
|
||||
case KDFONTOP:
|
||||
|
||||
@@ -217,6 +217,9 @@ static const struct usb_device_id usb_quirk_list[] = {
|
||||
{ USB_DEVICE(0x0926, 0x3333), .driver_info =
|
||||
USB_QUIRK_CONFIG_INTF_STRINGS },
|
||||
|
||||
/* Kingston DataTraveler 3.0 */
|
||||
{ USB_DEVICE(0x0951, 0x1666), .driver_info = USB_QUIRK_NO_LPM },
|
||||
|
||||
/* X-Rite/Gretag-Macbeth Eye-One Pro display colorimeter */
|
||||
{ USB_DEVICE(0x0971, 0x2000), .driver_info = USB_QUIRK_NO_SET_INTF },
|
||||
|
||||
|
||||
@@ -1283,6 +1283,17 @@ static int dwc3_probe(struct platform_device *pdev)
|
||||
|
||||
err5:
|
||||
dwc3_event_buffers_cleanup(dwc);
|
||||
|
||||
usb_phy_shutdown(dwc->usb2_phy);
|
||||
usb_phy_shutdown(dwc->usb3_phy);
|
||||
phy_exit(dwc->usb2_generic_phy);
|
||||
phy_exit(dwc->usb3_generic_phy);
|
||||
|
||||
usb_phy_set_suspend(dwc->usb2_phy, 1);
|
||||
usb_phy_set_suspend(dwc->usb3_phy, 1);
|
||||
phy_power_off(dwc->usb2_generic_phy);
|
||||
phy_power_off(dwc->usb3_generic_phy);
|
||||
|
||||
dwc3_ulpi_exit(dwc);
|
||||
|
||||
err4:
|
||||
@@ -1340,9 +1351,9 @@ static int dwc3_remove(struct platform_device *pdev)
|
||||
dwc3_core_exit(dwc);
|
||||
dwc3_ulpi_exit(dwc);
|
||||
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
pm_runtime_allow(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
pm_runtime_put_noidle(&pdev->dev);
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
|
||||
dwc3_free_event_buffers(dwc);
|
||||
dwc3_free_scratch_buffers(dwc);
|
||||
|
||||
@@ -98,10 +98,13 @@ static struct platform_device *fsl_usb2_device_register(
|
||||
|
||||
pdev->dev.coherent_dma_mask = ofdev->dev.coherent_dma_mask;
|
||||
|
||||
if (!pdev->dev.dma_mask)
|
||||
if (!pdev->dev.dma_mask) {
|
||||
pdev->dev.dma_mask = &ofdev->dev.coherent_dma_mask;
|
||||
else
|
||||
dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
|
||||
} else {
|
||||
retval = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
|
||||
if (retval)
|
||||
goto error;
|
||||
}
|
||||
|
||||
retval = platform_device_add_data(pdev, pdata, sizeof(*pdata));
|
||||
if (retval)
|
||||
|
||||
@@ -210,6 +210,7 @@ static void adu_interrupt_out_callback(struct urb *urb)
|
||||
|
||||
if (status != 0) {
|
||||
if ((status != -ENOENT) &&
|
||||
(status != -ESHUTDOWN) &&
|
||||
(status != -ECONNRESET)) {
|
||||
dev_dbg(&dev->udev->dev,
|
||||
"%s :nonzero status received: %d\n", __func__,
|
||||
|
||||
@@ -367,11 +367,12 @@ static void cyberjack_write_bulk_callback(struct urb *urb)
|
||||
struct cyberjack_private *priv = usb_get_serial_port_data(port);
|
||||
struct device *dev = &port->dev;
|
||||
int status = urb->status;
|
||||
bool resubmitted = false;
|
||||
|
||||
set_bit(0, &port->write_urbs_free);
|
||||
if (status) {
|
||||
dev_dbg(dev, "%s - nonzero write bulk status received: %d\n",
|
||||
__func__, status);
|
||||
set_bit(0, &port->write_urbs_free);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -404,6 +405,8 @@ static void cyberjack_write_bulk_callback(struct urb *urb)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
resubmitted = true;
|
||||
|
||||
dev_dbg(dev, "%s - priv->wrsent=%d\n", __func__, priv->wrsent);
|
||||
dev_dbg(dev, "%s - priv->wrfilled=%d\n", __func__, priv->wrfilled);
|
||||
|
||||
@@ -420,6 +423,8 @@ static void cyberjack_write_bulk_callback(struct urb *urb)
|
||||
|
||||
exit:
|
||||
spin_unlock(&priv->lock);
|
||||
if (!resubmitted)
|
||||
set_bit(0, &port->write_urbs_free);
|
||||
usb_serial_port_softint(port);
|
||||
}
|
||||
|
||||
|
||||
@@ -1174,6 +1174,8 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = NCTRL(0) | RSVD(1) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1054, 0xff), /* Telit FT980-KS */
|
||||
.driver_info = NCTRL(2) | RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1055, 0xff), /* Telit FN980 (PCIe) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
|
||||
@@ -1186,6 +1188,8 @@ static const struct usb_device_id option_ids[] = {
|
||||
.driver_info = NCTRL(0) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910),
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1203, 0xff), /* Telit LE910Cx (RNDIS) */
|
||||
.driver_info = NCTRL(2) | RSVD(3) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4),
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
|
||||
@@ -1200,6 +1204,10 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1213, 0xff) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1214),
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1230, 0xff), /* Telit LE910Cx (rmnet) */
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
|
||||
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1231, 0xff), /* Telit LE910Cx (RNDIS) */
|
||||
.driver_info = NCTRL(2) | RSVD(3) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, 0x1260),
|
||||
.driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
|
||||
{ USB_DEVICE(TELIT_VENDOR_ID, 0x1261),
|
||||
|
||||
@@ -272,13 +272,14 @@ __vringh_iov(struct vringh *vrh, u16 i,
|
||||
desc_max = vrh->vring.num;
|
||||
up_next = -1;
|
||||
|
||||
/* You must want something! */
|
||||
if (WARN_ON(!riov && !wiov))
|
||||
return -EINVAL;
|
||||
|
||||
if (riov)
|
||||
riov->i = riov->used = 0;
|
||||
else if (wiov)
|
||||
if (wiov)
|
||||
wiov->i = wiov->used = 0;
|
||||
else
|
||||
/* You must want something! */
|
||||
BUG();
|
||||
|
||||
for (;;) {
|
||||
void *addr;
|
||||
|
||||
@@ -1029,6 +1029,8 @@ static int __init pvr2fb_setup(char *options)
|
||||
if (!options || !*options)
|
||||
return 0;
|
||||
|
||||
cable_arg[0] = output_arg[0] = 0;
|
||||
|
||||
while ((this_opt = strsep(&options, ","))) {
|
||||
if (!*this_opt)
|
||||
continue;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
@@ -48,12 +48,12 @@ struct mxc_w1_device {
|
||||
static u8 mxc_w1_ds2_reset_bus(void *data)
|
||||
{
|
||||
struct mxc_w1_device *dev = data;
|
||||
unsigned long timeout;
|
||||
ktime_t timeout;
|
||||
|
||||
writeb(MXC_W1_CONTROL_RPP, dev->regs + MXC_W1_CONTROL);
|
||||
|
||||
/* Wait for reset sequence 511+512us, use 1500us for sure */
|
||||
timeout = jiffies + usecs_to_jiffies(1500);
|
||||
timeout = ktime_add_us(ktime_get(), 1500);
|
||||
|
||||
udelay(511 + 512);
|
||||
|
||||
@@ -63,7 +63,7 @@ static u8 mxc_w1_ds2_reset_bus(void *data)
|
||||
/* PST bit is valid after the RPP bit is self-cleared */
|
||||
if (!(ctrl & MXC_W1_CONTROL_RPP))
|
||||
return !(ctrl & MXC_W1_CONTROL_PST);
|
||||
} while (time_is_after_jiffies(timeout));
|
||||
} while (ktime_before(ktime_get(), timeout));
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -76,12 +76,12 @@ static u8 mxc_w1_ds2_reset_bus(void *data)
|
||||
static u8 mxc_w1_ds2_touch_bit(void *data, u8 bit)
|
||||
{
|
||||
struct mxc_w1_device *dev = data;
|
||||
unsigned long timeout;
|
||||
ktime_t timeout;
|
||||
|
||||
writeb(MXC_W1_CONTROL_WR(bit), dev->regs + MXC_W1_CONTROL);
|
||||
|
||||
/* Wait for read/write bit (60us, Max 120us), use 200us for sure */
|
||||
timeout = jiffies + usecs_to_jiffies(200);
|
||||
timeout = ktime_add_us(ktime_get(), 200);
|
||||
|
||||
udelay(60);
|
||||
|
||||
@@ -91,7 +91,7 @@ static u8 mxc_w1_ds2_touch_bit(void *data, u8 bit)
|
||||
/* RDST bit is valid after the WR1/RD bit is self-cleared */
|
||||
if (!(ctrl & MXC_W1_CONTROL_WR(bit)))
|
||||
return !!(ctrl & MXC_W1_CONTROL_RDST);
|
||||
} while (time_is_after_jiffies(timeout));
|
||||
} while (ktime_before(ktime_get(), timeout));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -244,6 +244,8 @@ static int rdc321x_wdt_probe(struct platform_device *pdev)
|
||||
|
||||
rdc321x_wdt_device.sb_pdev = pdata->sb_pdev;
|
||||
rdc321x_wdt_device.base_reg = r->start;
|
||||
rdc321x_wdt_device.queue = 0;
|
||||
rdc321x_wdt_device.default_ticks = ticks;
|
||||
|
||||
err = misc_register(&rdc321x_wdt_misc);
|
||||
if (err < 0) {
|
||||
@@ -258,14 +260,11 @@ static int rdc321x_wdt_probe(struct platform_device *pdev)
|
||||
rdc321x_wdt_device.base_reg, RDC_WDT_RST);
|
||||
|
||||
init_completion(&rdc321x_wdt_device.stop);
|
||||
rdc321x_wdt_device.queue = 0;
|
||||
|
||||
clear_bit(0, &rdc321x_wdt_device.inuse);
|
||||
|
||||
setup_timer(&rdc321x_wdt_device.timer, rdc321x_wdt_trigger, 0);
|
||||
|
||||
rdc321x_wdt_device.default_ticks = ticks;
|
||||
|
||||
dev_info(&pdev->dev, "watchdog init success\n");
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -91,6 +91,8 @@ static bool (*pirq_needs_eoi)(unsigned irq);
|
||||
/* Xen will never allocate port zero for any purpose. */
|
||||
#define VALID_EVTCHN(chn) ((chn) != 0)
|
||||
|
||||
static struct irq_info *legacy_info_ptrs[NR_IRQS_LEGACY];
|
||||
|
||||
static struct irq_chip xen_dynamic_chip;
|
||||
static struct irq_chip xen_percpu_chip;
|
||||
static struct irq_chip xen_pirq_chip;
|
||||
@@ -155,7 +157,18 @@ int get_evtchn_to_irq(unsigned evtchn)
|
||||
/* Get info for IRQ */
|
||||
struct irq_info *info_for_irq(unsigned irq)
|
||||
{
|
||||
return irq_get_chip_data(irq);
|
||||
if (irq < nr_legacy_irqs())
|
||||
return legacy_info_ptrs[irq];
|
||||
else
|
||||
return irq_get_chip_data(irq);
|
||||
}
|
||||
|
||||
static void set_info_for_irq(unsigned int irq, struct irq_info *info)
|
||||
{
|
||||
if (irq < nr_legacy_irqs())
|
||||
legacy_info_ptrs[irq] = info;
|
||||
else
|
||||
irq_set_chip_data(irq, info);
|
||||
}
|
||||
|
||||
/* Constructors for packed IRQ information. */
|
||||
@@ -384,7 +397,7 @@ static void xen_irq_init(unsigned irq)
|
||||
info->type = IRQT_UNBOUND;
|
||||
info->refcnt = -1;
|
||||
|
||||
irq_set_chip_data(irq, info);
|
||||
set_info_for_irq(irq, info);
|
||||
|
||||
list_add_tail(&info->list, &xen_irq_list_head);
|
||||
}
|
||||
@@ -433,14 +446,14 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi)
|
||||
|
||||
static void xen_free_irq(unsigned irq)
|
||||
{
|
||||
struct irq_info *info = irq_get_chip_data(irq);
|
||||
struct irq_info *info = info_for_irq(irq);
|
||||
|
||||
if (WARN_ON(!info))
|
||||
return;
|
||||
|
||||
list_del(&info->list);
|
||||
|
||||
irq_set_chip_data(irq, NULL);
|
||||
set_info_for_irq(irq, NULL);
|
||||
|
||||
WARN_ON(info->refcnt > 0);
|
||||
|
||||
@@ -610,7 +623,7 @@ EXPORT_SYMBOL_GPL(xen_irq_from_gsi);
|
||||
static void __unbind_from_irq(unsigned int irq)
|
||||
{
|
||||
int evtchn = evtchn_from_irq(irq);
|
||||
struct irq_info *info = irq_get_chip_data(irq);
|
||||
struct irq_info *info = info_for_irq(irq);
|
||||
|
||||
if (info->refcnt > 0) {
|
||||
info->refcnt--;
|
||||
@@ -1114,7 +1127,7 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi,
|
||||
|
||||
void unbind_from_irqhandler(unsigned int irq, void *dev_id)
|
||||
{
|
||||
struct irq_info *info = irq_get_chip_data(irq);
|
||||
struct irq_info *info = info_for_irq(irq);
|
||||
|
||||
if (WARN_ON(!info))
|
||||
return;
|
||||
@@ -1148,7 +1161,7 @@ int evtchn_make_refcounted(unsigned int evtchn)
|
||||
if (irq == -1)
|
||||
return -ENOENT;
|
||||
|
||||
info = irq_get_chip_data(irq);
|
||||
info = info_for_irq(irq);
|
||||
|
||||
if (!info)
|
||||
return -ENOENT;
|
||||
@@ -1176,7 +1189,7 @@ int evtchn_get(unsigned int evtchn)
|
||||
if (irq == -1)
|
||||
goto done;
|
||||
|
||||
info = irq_get_chip_data(irq);
|
||||
info = info_for_irq(irq);
|
||||
|
||||
if (!info)
|
||||
goto done;
|
||||
|
||||
@@ -624,9 +624,9 @@ static void v9fs_mmap_vm_close(struct vm_area_struct *vma)
|
||||
struct writeback_control wbc = {
|
||||
.nr_to_write = LONG_MAX,
|
||||
.sync_mode = WB_SYNC_ALL,
|
||||
.range_start = vma->vm_pgoff * PAGE_SIZE,
|
||||
.range_start = (loff_t)vma->vm_pgoff * PAGE_SIZE,
|
||||
/* absolute end, byte at end included */
|
||||
.range_end = vma->vm_pgoff * PAGE_SIZE +
|
||||
.range_end = (loff_t)vma->vm_pgoff * PAGE_SIZE +
|
||||
(vma->vm_end - vma->vm_start - 1),
|
||||
};
|
||||
|
||||
|
||||
@@ -1122,6 +1122,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
|
||||
|
||||
ret = update_ref_for_cow(trans, root, buf, cow, &last_ref);
|
||||
if (ret) {
|
||||
btrfs_tree_unlock(cow);
|
||||
free_extent_buffer(cow);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -1129,6 +1131,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
|
||||
if (test_bit(BTRFS_ROOT_REF_COWS, &root->state)) {
|
||||
ret = btrfs_reloc_cow_block(trans, root, buf, cow);
|
||||
if (ret) {
|
||||
btrfs_tree_unlock(cow);
|
||||
free_extent_buffer(cow);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
return ret;
|
||||
}
|
||||
@@ -1160,6 +1164,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
|
||||
if (last_ref) {
|
||||
ret = tree_mod_log_free_eb(root->fs_info, buf);
|
||||
if (ret) {
|
||||
btrfs_tree_unlock(cow);
|
||||
free_extent_buffer(cow);
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -456,6 +456,8 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root,
|
||||
}
|
||||
have_zone = 1;
|
||||
}
|
||||
if (!have_zone)
|
||||
radix_tree_delete(&fs_info->reada_tree, index);
|
||||
spin_unlock(&fs_info->reada_lock);
|
||||
btrfs_dev_replace_unlock(&fs_info->dev_replace, 0);
|
||||
|
||||
|
||||
@@ -3357,6 +3357,7 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans,
|
||||
* search and this search we'll not find the key again and can just
|
||||
* bail.
|
||||
*/
|
||||
search:
|
||||
ret = btrfs_search_slot(NULL, root, &min_key, path, 0, 0);
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
@@ -3376,6 +3377,13 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans,
|
||||
|
||||
if (min_key.objectid != ino || min_key.type != key_type)
|
||||
goto done;
|
||||
|
||||
if (need_resched()) {
|
||||
btrfs_release_path(path);
|
||||
cond_resched();
|
||||
goto search;
|
||||
}
|
||||
|
||||
ret = overwrite_item(trans, log, dst_path, src, i,
|
||||
&min_key);
|
||||
if (ret) {
|
||||
|
||||
16
fs/buffer.c
16
fs/buffer.c
@@ -2753,16 +2753,6 @@ int nobh_writepage(struct page *page, get_block_t *get_block,
|
||||
/* Is the page fully outside i_size? (truncate in progress) */
|
||||
offset = i_size & (PAGE_SIZE-1);
|
||||
if (page->index >= end_index+1 || !offset) {
|
||||
/*
|
||||
* The page may have dirty, unmapped buffers. For example,
|
||||
* they may have been added in ext3_writepage(). Make them
|
||||
* freeable here, so the page does not leak.
|
||||
*/
|
||||
#if 0
|
||||
/* Not really sure about this - do we need this ? */
|
||||
if (page->mapping->a_ops->invalidatepage)
|
||||
page->mapping->a_ops->invalidatepage(page, offset);
|
||||
#endif
|
||||
unlock_page(page);
|
||||
return 0; /* don't care */
|
||||
}
|
||||
@@ -2957,12 +2947,6 @@ int block_write_full_page(struct page *page, get_block_t *get_block,
|
||||
/* Is the page fully outside i_size? (truncate in progress) */
|
||||
offset = i_size & (PAGE_SIZE-1);
|
||||
if (page->index >= end_index+1 || !offset) {
|
||||
/*
|
||||
* The page may have dirty, unmapped buffers. For example,
|
||||
* they may have been added in ext3_writepage(). Make them
|
||||
* freeable here, so the page does not leak.
|
||||
*/
|
||||
do_invalidatepage(page, 0, PAGE_SIZE);
|
||||
unlock_page(page);
|
||||
return 0; /* don't care */
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ static int cachefiles_read_reissue(struct cachefiles_object *object,
|
||||
_debug("reissue read");
|
||||
ret = bmapping->a_ops->readpage(NULL, backpage);
|
||||
if (ret < 0)
|
||||
goto unlock_discard;
|
||||
goto discard;
|
||||
}
|
||||
|
||||
/* but the page may have been read before the monitor was installed, so
|
||||
@@ -142,6 +142,7 @@ static int cachefiles_read_reissue(struct cachefiles_object *object,
|
||||
|
||||
unlock_discard:
|
||||
unlock_page(backpage);
|
||||
discard:
|
||||
spin_lock_irq(&object->work_lock);
|
||||
list_del(&monitor->op_link);
|
||||
spin_unlock_irq(&object->work_lock);
|
||||
|
||||
@@ -1392,7 +1392,7 @@ static int ceph_filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
||||
struct ceph_inode_info *ci = ceph_inode(inode);
|
||||
struct ceph_file_info *fi = vma->vm_file->private_data;
|
||||
struct page *pinned_page = NULL;
|
||||
loff_t off = vmf->pgoff << PAGE_SHIFT;
|
||||
loff_t off = (loff_t)vmf->pgoff << PAGE_SHIFT;
|
||||
int want, got, ret;
|
||||
sigset_t oldset;
|
||||
|
||||
|
||||
@@ -61,6 +61,9 @@ int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg)
|
||||
int ret;
|
||||
struct fscrypt_context ctx;
|
||||
|
||||
if (copy_from_user(&policy, arg, sizeof(policy)))
|
||||
return -EFAULT;
|
||||
|
||||
if (copy_from_user(&policy, arg, sizeof(policy)))
|
||||
return -EFAULT;
|
||||
|
||||
@@ -154,8 +157,7 @@ EXPORT_SYMBOL(fscrypt_ioctl_get_policy);
|
||||
* malicious offline violations of this constraint, while the link and rename
|
||||
* checks are needed to prevent online violations of this constraint.
|
||||
*
|
||||
* Return: 1 if permitted, 0 if forbidden. If forbidden, the caller must fail
|
||||
* the filesystem operation with EPERM.
|
||||
* Return: 1 if permitted, 0 if forbidden.
|
||||
*/
|
||||
int fscrypt_has_permitted_context(struct inode *parent, struct inode *child)
|
||||
{
|
||||
|
||||
@@ -146,6 +146,9 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor,
|
||||
|
||||
name[len + EFI_VARIABLE_GUID_LEN+1] = '\0';
|
||||
|
||||
/* replace invalid slashes like kobject_set_name_vargs does for /sys/firmware/efi/vars. */
|
||||
strreplace(name, '/', '!');
|
||||
|
||||
inode = efivarfs_get_inode(sb, d_inode(root), S_IFREG | 0644, 0,
|
||||
is_removable);
|
||||
if (!inode)
|
||||
|
||||
@@ -2332,6 +2332,31 @@ static inline int ext4_fname_setup_filename(struct inode *dir,
|
||||
}
|
||||
static inline void ext4_fname_free_filename(struct ext4_filename *fname) { }
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
#define fscrypt_set_d_op(i)
|
||||
#define fscrypt_get_ctx fscrypt_notsupp_get_ctx
|
||||
#define fscrypt_release_ctx fscrypt_notsupp_release_ctx
|
||||
#define fscrypt_encrypt_page fscrypt_notsupp_encrypt_page
|
||||
#define fscrypt_decrypt_page fscrypt_notsupp_decrypt_page
|
||||
#define fscrypt_decrypt_bio_pages fscrypt_notsupp_decrypt_bio_pages
|
||||
#define fscrypt_pullback_bio_page fscrypt_notsupp_pullback_bio_page
|
||||
#define fscrypt_restore_control_page fscrypt_notsupp_restore_control_page
|
||||
#define fscrypt_zeroout_range fscrypt_notsupp_zeroout_range
|
||||
#define fscrypt_ioctl_set_policy fscrypt_notsupp_ioctl_set_policy
|
||||
#define fscrypt_ioctl_get_policy fscrypt_notsupp_ioctl_get_policy
|
||||
#define fscrypt_has_permitted_context fscrypt_notsupp_has_permitted_context
|
||||
#define fscrypt_inherit_context fscrypt_notsupp_inherit_context
|
||||
#define fscrypt_get_encryption_info fscrypt_notsupp_get_encryption_info
|
||||
#define fscrypt_put_encryption_info fscrypt_notsupp_put_encryption_info
|
||||
#define fscrypt_setup_filename fscrypt_notsupp_setup_filename
|
||||
#define fscrypt_free_filename fscrypt_notsupp_free_filename
|
||||
#define fscrypt_fname_encrypted_size fscrypt_notsupp_fname_encrypted_size
|
||||
#define fscrypt_fname_alloc_buffer fscrypt_notsupp_fname_alloc_buffer
|
||||
#define fscrypt_fname_free_buffer fscrypt_notsupp_fname_free_buffer
|
||||
#define fscrypt_fname_disk_to_usr fscrypt_notsupp_fname_disk_to_usr
|
||||
#define fscrypt_fname_usr_to_disk fscrypt_notsupp_fname_usr_to_disk
|
||||
>>>>>>> 84e8b2ae1f23cb05201a0797d312445761a204db
|
||||
#endif
|
||||
|
||||
/* dir.c */
|
||||
|
||||
@@ -3207,7 +3207,7 @@ static int ext4_link(struct dentry *old_dentry,
|
||||
return -EMLINK;
|
||||
if (ext4_encrypted_inode(dir) &&
|
||||
!fscrypt_has_permitted_context(dir, inode))
|
||||
return -EPERM;
|
||||
return -EXDEV;
|
||||
|
||||
if ((ext4_test_inode_flag(dir, EXT4_INODE_PROJINHERIT)) &&
|
||||
(!projid_eq(EXT4_I(dir)->i_projid,
|
||||
@@ -3545,7 +3545,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
if ((old.dir != new.dir) &&
|
||||
ext4_encrypted_inode(new.dir) &&
|
||||
!fscrypt_has_permitted_context(new.dir, old.inode)) {
|
||||
retval = -EPERM;
|
||||
retval = -EXDEV;
|
||||
goto end_rename;
|
||||
}
|
||||
|
||||
@@ -3724,7 +3724,7 @@ static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
|
||||
(old_dir != new_dir) &&
|
||||
(!fscrypt_has_permitted_context(new_dir, old.inode) ||
|
||||
!fscrypt_has_permitted_context(old_dir, new.inode)))
|
||||
return -EPERM;
|
||||
return -EXDEV;
|
||||
|
||||
if ((ext4_test_inode_flag(new_dir, EXT4_INODE_PROJINHERIT) &&
|
||||
!projid_eq(EXT4_I(new_dir)->i_projid,
|
||||
|
||||
@@ -5419,6 +5419,11 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
|
||||
/* Quotafile not on the same filesystem? */
|
||||
if (path->dentry->d_sb != sb)
|
||||
return -EXDEV;
|
||||
|
||||
/* Quota already enabled for this file? */
|
||||
if (IS_NOQUOTA(d_inode(path->dentry)))
|
||||
return -EBUSY;
|
||||
|
||||
/* Journaling quota? */
|
||||
if (EXT4_SB(sb)->s_qf_names[type]) {
|
||||
/* Quotafile not in fs root? */
|
||||
|
||||
@@ -201,6 +201,8 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
|
||||
blkno * NAT_ENTRY_PER_BLOCK);
|
||||
break;
|
||||
case META_SIT:
|
||||
if (unlikely(blkno >= TOTAL_SEGS(sbi)))
|
||||
goto out;
|
||||
/* get sit block addr */
|
||||
fio.new_blkaddr = current_sit_addr(sbi,
|
||||
blkno * SIT_ENTRY_PER_BLOCK);
|
||||
@@ -977,8 +979,12 @@ int sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
|
||||
get_pages(sbi, is_dir ?
|
||||
F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA));
|
||||
retry:
|
||||
if (unlikely(f2fs_cp_error(sbi)))
|
||||
if (unlikely(f2fs_cp_error(sbi))) {
|
||||
trace_f2fs_sync_dirty_inodes_exit(sbi->sb, is_dir,
|
||||
get_pages(sbi, is_dir ?
|
||||
F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
spin_lock(&sbi->inode_lock[type]);
|
||||
|
||||
|
||||
@@ -3367,4 +3367,28 @@ static inline bool f2fs_force_buffered_io(struct inode *inode, int rw)
|
||||
F2FS_I_SB(inode)->s_ndevs);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_F2FS_FS_ENCRYPTION
|
||||
#define fscrypt_set_d_op(i)
|
||||
#define fscrypt_get_ctx fscrypt_notsupp_get_ctx
|
||||
#define fscrypt_release_ctx fscrypt_notsupp_release_ctx
|
||||
#define fscrypt_encrypt_page fscrypt_notsupp_encrypt_page
|
||||
#define fscrypt_decrypt_page fscrypt_notsupp_decrypt_page
|
||||
#define fscrypt_decrypt_bio_pages fscrypt_notsupp_decrypt_bio_pages
|
||||
#define fscrypt_pullback_bio_page fscrypt_notsupp_pullback_bio_page
|
||||
#define fscrypt_restore_control_page fscrypt_notsupp_restore_control_page
|
||||
#define fscrypt_zeroout_range fscrypt_notsupp_zeroout_range
|
||||
#define fscrypt_ioctl_set_policy fscrypt_notsupp_ioctl_set_policy
|
||||
#define fscrypt_ioctl_get_policy fscrypt_notsupp_ioctl_get_policy
|
||||
#define fscrypt_has_permitted_context fscrypt_notsupp_has_permitted_context
|
||||
#define fscrypt_inherit_context fscrypt_notsupp_inherit_context
|
||||
#define fscrypt_get_encryption_info fscrypt_notsupp_get_encryption_info
|
||||
#define fscrypt_put_encryption_info fscrypt_notsupp_put_encryption_info
|
||||
#define fscrypt_setup_filename fscrypt_notsupp_setup_filename
|
||||
#define fscrypt_free_filename fscrypt_notsupp_free_filename
|
||||
#define fscrypt_fname_encrypted_size fscrypt_notsupp_fname_encrypted_size
|
||||
#define fscrypt_fname_alloc_buffer fscrypt_notsupp_fname_alloc_buffer
|
||||
#define fscrypt_fname_free_buffer fscrypt_notsupp_fname_free_buffer
|
||||
#define fscrypt_fname_disk_to_usr fscrypt_notsupp_fname_disk_to_usr
|
||||
#define fscrypt_fname_usr_to_disk fscrypt_notsupp_fname_usr_to_disk
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -850,15 +850,16 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
|
||||
struct page *newpage;
|
||||
struct pipe_buffer *buf = cs->pipebufs;
|
||||
|
||||
get_page(oldpage);
|
||||
err = unlock_request(cs->req);
|
||||
if (err)
|
||||
return err;
|
||||
goto out_put_old;
|
||||
|
||||
fuse_copy_finish(cs);
|
||||
|
||||
err = pipe_buf_confirm(cs->pipe, buf);
|
||||
if (err)
|
||||
return err;
|
||||
goto out_put_old;
|
||||
|
||||
BUG_ON(!cs->nr_segs);
|
||||
cs->currbuf = buf;
|
||||
@@ -898,7 +899,7 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
|
||||
err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL);
|
||||
if (err) {
|
||||
unlock_page(newpage);
|
||||
return err;
|
||||
goto out_put_old;
|
||||
}
|
||||
|
||||
get_page(newpage);
|
||||
@@ -917,14 +918,19 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
|
||||
if (err) {
|
||||
unlock_page(newpage);
|
||||
put_page(newpage);
|
||||
return err;
|
||||
goto out_put_old;
|
||||
}
|
||||
|
||||
unlock_page(oldpage);
|
||||
/* Drop ref for ap->pages[] array */
|
||||
put_page(oldpage);
|
||||
cs->len = 0;
|
||||
|
||||
return 0;
|
||||
err = 0;
|
||||
out_put_old:
|
||||
/* Drop ref obtained in this function */
|
||||
put_page(oldpage);
|
||||
return err;
|
||||
|
||||
out_fallback_unlock:
|
||||
unlock_page(newpage);
|
||||
@@ -933,10 +939,10 @@ out_fallback:
|
||||
cs->offset = buf->offset;
|
||||
|
||||
err = lock_request(cs->req);
|
||||
if (err)
|
||||
return err;
|
||||
if (!err)
|
||||
err = 1;
|
||||
|
||||
return 1;
|
||||
goto out_put_old;
|
||||
}
|
||||
|
||||
static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
|
||||
@@ -948,14 +954,16 @@ static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
|
||||
if (cs->nr_segs == cs->pipe->buffers)
|
||||
return -EIO;
|
||||
|
||||
get_page(page);
|
||||
err = unlock_request(cs->req);
|
||||
if (err)
|
||||
if (err) {
|
||||
put_page(page);
|
||||
return err;
|
||||
}
|
||||
|
||||
fuse_copy_finish(cs);
|
||||
|
||||
buf = cs->pipebufs;
|
||||
get_page(page);
|
||||
buf->page = page;
|
||||
buf->offset = offset;
|
||||
buf->len = count;
|
||||
|
||||
@@ -160,15 +160,19 @@ static int gfs2_check_sb(struct gfs2_sbd *sdp, int silent)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* If format numbers match exactly, we're done. */
|
||||
if (sb->sb_fs_format != GFS2_FORMAT_FS ||
|
||||
sb->sb_multihost_format != GFS2_FORMAT_MULTI) {
|
||||
fs_warn(sdp, "Unknown on-disk format, unable to mount\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (sb->sb_fs_format == GFS2_FORMAT_FS &&
|
||||
sb->sb_multihost_format == GFS2_FORMAT_MULTI)
|
||||
return 0;
|
||||
if (sb->sb_bsize < 512 || sb->sb_bsize > PAGE_SIZE ||
|
||||
(sb->sb_bsize & (sb->sb_bsize - 1))) {
|
||||
pr_warn("Invalid superblock size\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fs_warn(sdp, "Unknown on-disk format, unable to mount\n");
|
||||
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void end_bio_io_page(struct bio *bio)
|
||||
|
||||
@@ -30,9 +30,9 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
|
||||
/*
|
||||
* nfs_path - reconstruct the path given an arbitrary dentry
|
||||
* @base - used to return pointer to the end of devname part of path
|
||||
* @dentry - pointer to dentry
|
||||
* @dentry_in - pointer to dentry
|
||||
* @buffer - result buffer
|
||||
* @buflen - length of buffer
|
||||
* @buflen_in - length of buffer
|
||||
* @flags - options (see below)
|
||||
*
|
||||
* Helper function for constructing the server pathname
|
||||
@@ -47,15 +47,19 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
|
||||
* the original device (export) name
|
||||
* (if unset, the original name is returned verbatim)
|
||||
*/
|
||||
char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen,
|
||||
unsigned flags)
|
||||
char *nfs_path(char **p, struct dentry *dentry_in, char *buffer,
|
||||
ssize_t buflen_in, unsigned flags)
|
||||
{
|
||||
char *end;
|
||||
int namelen;
|
||||
unsigned seq;
|
||||
const char *base;
|
||||
struct dentry *dentry;
|
||||
ssize_t buflen;
|
||||
|
||||
rename_retry:
|
||||
buflen = buflen_in;
|
||||
dentry = dentry_in;
|
||||
end = buffer+buflen;
|
||||
*--end = '\0';
|
||||
buflen--;
|
||||
|
||||
@@ -1125,6 +1125,7 @@ int dbg_check_dir(struct ubifs_info *c, const struct inode *dir)
|
||||
err = PTR_ERR(dent);
|
||||
if (err == -ENOENT)
|
||||
break;
|
||||
kfree(pdent);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -1014,10 +1014,13 @@ xfs_growfs_rt(
|
||||
xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL);
|
||||
xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
|
||||
/*
|
||||
* Update the bitmap inode's size.
|
||||
* Update the bitmap inode's size ondisk and incore. We need
|
||||
* to update the incore size so that inode inactivation won't
|
||||
* punch what it thinks are "posteof" blocks.
|
||||
*/
|
||||
mp->m_rbmip->i_d.di_size =
|
||||
nsbp->sb_rbmblocks * nsbp->sb_blocksize;
|
||||
i_size_write(VFS_I(mp->m_rbmip), mp->m_rbmip->i_d.di_size);
|
||||
xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
|
||||
/*
|
||||
* Get the summary inode into the transaction.
|
||||
@@ -1025,9 +1028,12 @@ xfs_growfs_rt(
|
||||
xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL);
|
||||
xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL);
|
||||
/*
|
||||
* Update the summary inode's size.
|
||||
* Update the summary inode's size. We need to update the
|
||||
* incore size so that inode inactivation won't punch what it
|
||||
* thinks are "posteof" blocks.
|
||||
*/
|
||||
mp->m_rsumip->i_d.di_size = nmp->m_rsumsize;
|
||||
i_size_write(VFS_I(mp->m_rsumip), mp->m_rsumip->i_d.di_size);
|
||||
xfs_trans_log_inode(tp, mp->m_rsumip, XFS_ILOG_CORE);
|
||||
/*
|
||||
* Copy summary data from old to new sizes.
|
||||
|
||||
409
include/linux/fscrypto.h
Normal file
409
include/linux/fscrypto.h
Normal file
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* General per-file encryption definition
|
||||
*
|
||||
* Copyright (C) 2015, Google, Inc.
|
||||
*
|
||||
* Written by Michael Halcrow, 2015.
|
||||
* Modified by Jaegeuk Kim, 2015.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_FSCRYPTO_H
|
||||
#define _LINUX_FSCRYPTO_H
|
||||
|
||||
#include <linux/key.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/bio.h>
|
||||
#include <linux/dcache.h>
|
||||
#include <crypto/skcipher.h>
|
||||
#include <uapi/linux/fs.h>
|
||||
|
||||
#define FS_KEY_DERIVATION_NONCE_SIZE 16
|
||||
#define FS_ENCRYPTION_CONTEXT_FORMAT_V1 1
|
||||
|
||||
#define FS_POLICY_FLAGS_PAD_4 0x00
|
||||
#define FS_POLICY_FLAGS_PAD_8 0x01
|
||||
#define FS_POLICY_FLAGS_PAD_16 0x02
|
||||
#define FS_POLICY_FLAGS_PAD_32 0x03
|
||||
#define FS_POLICY_FLAGS_PAD_MASK 0x03
|
||||
#define FS_POLICY_FLAGS_VALID 0x03
|
||||
|
||||
/* Encryption algorithms */
|
||||
#define FS_ENCRYPTION_MODE_INVALID 0
|
||||
#define FS_ENCRYPTION_MODE_AES_256_XTS 1
|
||||
#define FS_ENCRYPTION_MODE_AES_256_GCM 2
|
||||
#define FS_ENCRYPTION_MODE_AES_256_CBC 3
|
||||
#define FS_ENCRYPTION_MODE_AES_256_CTS 4
|
||||
|
||||
/**
|
||||
* Encryption context for inode
|
||||
*
|
||||
* Protector format:
|
||||
* 1 byte: Protector format (1 = this version)
|
||||
* 1 byte: File contents encryption mode
|
||||
* 1 byte: File names encryption mode
|
||||
* 1 byte: Flags
|
||||
* 8 bytes: Master Key descriptor
|
||||
* 16 bytes: Encryption Key derivation nonce
|
||||
*/
|
||||
struct fscrypt_context {
|
||||
u8 format;
|
||||
u8 contents_encryption_mode;
|
||||
u8 filenames_encryption_mode;
|
||||
u8 flags;
|
||||
u8 master_key_descriptor[FS_KEY_DESCRIPTOR_SIZE];
|
||||
u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
|
||||
} __packed;
|
||||
|
||||
/* Encryption parameters */
|
||||
#define FS_XTS_TWEAK_SIZE 16
|
||||
#define FS_AES_128_ECB_KEY_SIZE 16
|
||||
#define FS_AES_256_GCM_KEY_SIZE 32
|
||||
#define FS_AES_256_CBC_KEY_SIZE 32
|
||||
#define FS_AES_256_CTS_KEY_SIZE 32
|
||||
#define FS_AES_256_XTS_KEY_SIZE 64
|
||||
#define FS_MAX_KEY_SIZE 64
|
||||
|
||||
#define FS_KEY_DESC_PREFIX "fscrypt:"
|
||||
#define FS_KEY_DESC_PREFIX_SIZE 8
|
||||
|
||||
/* This is passed in from userspace into the kernel keyring */
|
||||
struct fscrypt_key {
|
||||
u32 mode;
|
||||
u8 raw[FS_MAX_KEY_SIZE];
|
||||
u32 size;
|
||||
} __packed;
|
||||
|
||||
struct fscrypt_info {
|
||||
u8 ci_data_mode;
|
||||
u8 ci_filename_mode;
|
||||
u8 ci_flags;
|
||||
struct crypto_skcipher *ci_ctfm;
|
||||
u8 ci_master_key[FS_KEY_DESCRIPTOR_SIZE];
|
||||
};
|
||||
|
||||
#define FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001
|
||||
#define FS_WRITE_PATH_FL 0x00000002
|
||||
|
||||
struct fscrypt_ctx {
|
||||
union {
|
||||
struct {
|
||||
struct page *bounce_page; /* Ciphertext page */
|
||||
struct page *control_page; /* Original page */
|
||||
} w;
|
||||
struct {
|
||||
struct bio *bio;
|
||||
struct work_struct work;
|
||||
} r;
|
||||
struct list_head free_list; /* Free list */
|
||||
};
|
||||
u8 flags; /* Flags */
|
||||
u8 mode; /* Encryption mode for tfm */
|
||||
};
|
||||
|
||||
struct fscrypt_completion_result {
|
||||
struct completion completion;
|
||||
int res;
|
||||
};
|
||||
|
||||
#define DECLARE_FS_COMPLETION_RESULT(ecr) \
|
||||
struct fscrypt_completion_result ecr = { \
|
||||
COMPLETION_INITIALIZER((ecr).completion), 0 }
|
||||
|
||||
#define FS_FNAME_NUM_SCATTER_ENTRIES 4
|
||||
#define FS_CRYPTO_BLOCK_SIZE 16
|
||||
#define FS_FNAME_CRYPTO_DIGEST_SIZE 32
|
||||
|
||||
/**
|
||||
* For encrypted symlinks, the ciphertext length is stored at the beginning
|
||||
* of the string in little-endian format.
|
||||
*/
|
||||
struct fscrypt_symlink_data {
|
||||
__le16 len;
|
||||
char encrypted_path[1];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* This function is used to calculate the disk space required to
|
||||
* store a filename of length l in encrypted symlink format.
|
||||
*/
|
||||
static inline u32 fscrypt_symlink_data_len(u32 l)
|
||||
{
|
||||
if (l < FS_CRYPTO_BLOCK_SIZE)
|
||||
l = FS_CRYPTO_BLOCK_SIZE;
|
||||
return (l + sizeof(struct fscrypt_symlink_data) - 1);
|
||||
}
|
||||
|
||||
struct fscrypt_str {
|
||||
unsigned char *name;
|
||||
u32 len;
|
||||
};
|
||||
|
||||
struct fscrypt_name {
|
||||
const struct qstr *usr_fname;
|
||||
struct fscrypt_str disk_name;
|
||||
u32 hash;
|
||||
u32 minor_hash;
|
||||
struct fscrypt_str crypto_buf;
|
||||
};
|
||||
|
||||
#define FSTR_INIT(n, l) { .name = n, .len = l }
|
||||
#define FSTR_TO_QSTR(f) QSTR_INIT((f)->name, (f)->len)
|
||||
#define fname_name(p) ((p)->disk_name.name)
|
||||
#define fname_len(p) ((p)->disk_name.len)
|
||||
|
||||
/*
|
||||
* crypto opertions for filesystems
|
||||
*/
|
||||
struct fscrypt_operations {
|
||||
int (*get_context)(struct inode *, void *, size_t);
|
||||
int (*key_prefix)(struct inode *, u8 **);
|
||||
int (*prepare_context)(struct inode *);
|
||||
int (*set_context)(struct inode *, const void *, size_t, void *);
|
||||
int (*dummy_context)(struct inode *);
|
||||
bool (*is_encrypted)(struct inode *);
|
||||
bool (*empty_dir)(struct inode *);
|
||||
unsigned (*max_namelen)(struct inode *);
|
||||
};
|
||||
|
||||
static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
|
||||
{
|
||||
if (inode->i_sb->s_cop->dummy_context &&
|
||||
inode->i_sb->s_cop->dummy_context(inode))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool fscrypt_valid_contents_enc_mode(u32 mode)
|
||||
{
|
||||
return (mode == FS_ENCRYPTION_MODE_AES_256_XTS);
|
||||
}
|
||||
|
||||
static inline bool fscrypt_valid_filenames_enc_mode(u32 mode)
|
||||
{
|
||||
return (mode == FS_ENCRYPTION_MODE_AES_256_CTS);
|
||||
}
|
||||
|
||||
static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
|
||||
{
|
||||
if (str->len == 1 && str->name[0] == '.')
|
||||
return true;
|
||||
|
||||
if (str->len == 2 && str->name[0] == '.' && str->name[1] == '.')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline struct page *fscrypt_control_page(struct page *page)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
return ((struct fscrypt_ctx *)page_private(page))->w.control_page;
|
||||
#else
|
||||
WARN_ON_ONCE(1);
|
||||
return ERR_PTR(-EINVAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int fscrypt_has_encryption_key(struct inode *inode)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
return (inode->i_crypt_info != NULL);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void fscrypt_set_encrypted_dentry(struct dentry *dentry)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
spin_lock(&dentry->d_lock);
|
||||
dentry->d_flags |= DCACHE_ENCRYPTED_WITH_KEY;
|
||||
spin_unlock(&dentry->d_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
extern const struct dentry_operations fscrypt_d_ops;
|
||||
#endif
|
||||
|
||||
static inline void fscrypt_set_d_op(struct dentry *dentry)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
d_set_d_op(dentry, &fscrypt_d_ops);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
|
||||
/* crypto.c */
|
||||
extern struct kmem_cache *fscrypt_info_cachep;
|
||||
int fscrypt_initialize(void);
|
||||
|
||||
extern struct fscrypt_ctx *fscrypt_get_ctx(struct inode *, gfp_t);
|
||||
extern void fscrypt_release_ctx(struct fscrypt_ctx *);
|
||||
extern struct page *fscrypt_encrypt_page(struct inode *, struct page *, gfp_t);
|
||||
extern int fscrypt_decrypt_page(struct page *);
|
||||
extern void fscrypt_decrypt_bio_pages(struct fscrypt_ctx *, struct bio *);
|
||||
extern void fscrypt_pullback_bio_page(struct page **, bool);
|
||||
extern void fscrypt_restore_control_page(struct page *);
|
||||
extern int fscrypt_zeroout_range(struct inode *, pgoff_t, sector_t,
|
||||
unsigned int);
|
||||
/* policy.c */
|
||||
extern int fscrypt_ioctl_set_policy(struct file *, const void __user *);
|
||||
extern int fscrypt_ioctl_get_policy(struct file *, void __user *);
|
||||
extern int fscrypt_has_permitted_context(struct inode *, struct inode *);
|
||||
extern int fscrypt_inherit_context(struct inode *, struct inode *,
|
||||
void *, bool);
|
||||
/* keyinfo.c */
|
||||
extern int fscrypt_get_encryption_info(struct inode *);
|
||||
extern void fscrypt_put_encryption_info(struct inode *, struct fscrypt_info *);
|
||||
|
||||
/* fname.c */
|
||||
extern int fscrypt_setup_filename(struct inode *, const struct qstr *,
|
||||
int lookup, struct fscrypt_name *);
|
||||
extern void fscrypt_free_filename(struct fscrypt_name *);
|
||||
extern u32 fscrypt_fname_encrypted_size(struct inode *, u32);
|
||||
extern int fscrypt_fname_alloc_buffer(struct inode *, u32,
|
||||
struct fscrypt_str *);
|
||||
extern void fscrypt_fname_free_buffer(struct fscrypt_str *);
|
||||
extern int fscrypt_fname_disk_to_usr(struct inode *, u32, u32,
|
||||
const struct fscrypt_str *, struct fscrypt_str *);
|
||||
extern int fscrypt_fname_usr_to_disk(struct inode *, const struct qstr *,
|
||||
struct fscrypt_str *);
|
||||
#endif
|
||||
|
||||
/* crypto.c */
|
||||
static inline struct fscrypt_ctx *fscrypt_notsupp_get_ctx(struct inode *i,
|
||||
gfp_t f)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline void fscrypt_notsupp_release_ctx(struct fscrypt_ctx *c)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline struct page *fscrypt_notsupp_encrypt_page(struct inode *i,
|
||||
struct page *p, gfp_t f)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_decrypt_page(struct page *p)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void fscrypt_notsupp_decrypt_bio_pages(struct fscrypt_ctx *c,
|
||||
struct bio *b)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void fscrypt_notsupp_pullback_bio_page(struct page **p, bool b)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void fscrypt_notsupp_restore_control_page(struct page *p)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_zeroout_range(struct inode *i, pgoff_t p,
|
||||
sector_t s, unsigned int f)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* policy.c */
|
||||
static inline int fscrypt_notsupp_ioctl_set_policy(struct file *f,
|
||||
const void __user *arg)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_ioctl_get_policy(struct file *f,
|
||||
void __user *arg)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_has_permitted_context(struct inode *p,
|
||||
struct inode *i)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_inherit_context(struct inode *p,
|
||||
struct inode *i, void *v, bool b)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* keyinfo.c */
|
||||
static inline int fscrypt_notsupp_get_encryption_info(struct inode *i)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void fscrypt_notsupp_put_encryption_info(struct inode *i,
|
||||
struct fscrypt_info *f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* fname.c */
|
||||
static inline int fscrypt_notsupp_setup_filename(struct inode *dir,
|
||||
const struct qstr *iname,
|
||||
int lookup, struct fscrypt_name *fname)
|
||||
{
|
||||
if (dir->i_sb->s_cop->is_encrypted(dir))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
memset(fname, 0, sizeof(struct fscrypt_name));
|
||||
fname->usr_fname = iname;
|
||||
fname->disk_name.name = (unsigned char *)iname->name;
|
||||
fname->disk_name.len = iname->len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void fscrypt_notsupp_free_filename(struct fscrypt_name *fname)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline u32 fscrypt_notsupp_fname_encrypted_size(struct inode *i, u32 s)
|
||||
{
|
||||
/* never happens */
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_fname_alloc_buffer(struct inode *inode,
|
||||
u32 ilen, struct fscrypt_str *crypto_str)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void fscrypt_notsupp_fname_free_buffer(struct fscrypt_str *c)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_fname_disk_to_usr(struct inode *inode,
|
||||
u32 hash, u32 minor_hash,
|
||||
const struct fscrypt_str *iname,
|
||||
struct fscrypt_str *oname)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int fscrypt_notsupp_fname_usr_to_disk(struct inode *inode,
|
||||
const struct qstr *iname,
|
||||
struct fscrypt_str *oname)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
#endif /* _LINUX_FSCRYPTO_H */
|
||||
@@ -103,7 +103,7 @@ struct hilse_node {
|
||||
|
||||
/* Methods for back-end drivers, e.g. hp_sdc_mlc */
|
||||
typedef int (hil_mlc_cts) (hil_mlc *mlc);
|
||||
typedef void (hil_mlc_out) (hil_mlc *mlc);
|
||||
typedef int (hil_mlc_out) (hil_mlc *mlc);
|
||||
typedef int (hil_mlc_in) (hil_mlc *mlc, suseconds_t timeout);
|
||||
|
||||
struct hil_mlc_devinfo {
|
||||
|
||||
@@ -127,7 +127,7 @@ static inline void print_drs_error(unsigned dsr)
|
||||
|
||||
if (!(dsr & DSR_AVAILABLE))
|
||||
printk(KERN_NOTICE"DSR.15: (0) Device not Available\n");
|
||||
if (prog_status & 0x03)
|
||||
if ((prog_status & 0x03) == 0x03)
|
||||
printk(KERN_NOTICE"DSR.9,8: (11) Attempt to program invalid "
|
||||
"half with 41h command\n");
|
||||
else if (prog_status & 0x02)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user