mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
Merge branch 'android-4.9' into amlogic-4.9-dev
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 23
|
||||
SUBLEVEL = 26
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
||||
@@ -17,10 +17,11 @@
|
||||
#include <asm/barrier.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
|
||||
#ifndef CONFIG_ARC_PLAT_EZNPS
|
||||
|
||||
#define atomic_read(v) READ_ONCE((v)->counter)
|
||||
#define ATOMIC_INIT(i) { (i) }
|
||||
|
||||
#ifdef CONFIG_ARC_HAS_LLSC
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
;
|
||||
; Now manually save: r12, sp, fp, gp, r25
|
||||
|
||||
PUSH r30
|
||||
PUSH r12
|
||||
|
||||
; Saving pt_regs->sp correctly requires some extra work due to the way
|
||||
@@ -72,6 +73,7 @@
|
||||
POPAX AUX_USER_SP
|
||||
1:
|
||||
POP r12
|
||||
POP r30
|
||||
|
||||
.endm
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ struct pt_regs {
|
||||
unsigned long fp;
|
||||
unsigned long sp; /* user/kernel sp depending on where we came from */
|
||||
|
||||
unsigned long r12;
|
||||
unsigned long r12, r30;
|
||||
|
||||
/*------- Below list auto saved by h/w -----------*/
|
||||
unsigned long r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11;
|
||||
|
||||
@@ -80,7 +80,7 @@ static unsigned int calculate_min_delta(void)
|
||||
}
|
||||
|
||||
/* Sorted insert of 75th percentile into buf2 */
|
||||
for (k = 0; k < i; ++k) {
|
||||
for (k = 0; k < i && k < ARRAY_SIZE(buf2); ++k) {
|
||||
if (buf1[ARRAY_SIZE(buf1) - 1] < buf2[k]) {
|
||||
l = min_t(unsigned int,
|
||||
i, ARRAY_SIZE(buf2) - 1);
|
||||
|
||||
@@ -257,7 +257,7 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr,
|
||||
else if ((prog_req.fr1 && prog_req.frdefault) ||
|
||||
(prog_req.single && !prog_req.frdefault))
|
||||
/* Make sure 64-bit MIPS III/IV/64R1 will not pick FR1 */
|
||||
state->overall_fp_mode = ((current_cpu_data.fpu_id & MIPS_FPIR_F64) &&
|
||||
state->overall_fp_mode = ((raw_current_cpu_data.fpu_id & MIPS_FPIR_F64) &&
|
||||
cpu_has_mips_r2_r6) ?
|
||||
FP_FR1 : FP_FR0;
|
||||
else if (prog_req.fr1)
|
||||
|
||||
@@ -244,9 +244,6 @@ static int compute_signal(int tt)
|
||||
void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
|
||||
{
|
||||
int reg;
|
||||
struct thread_info *ti = task_thread_info(p);
|
||||
unsigned long ksp = (unsigned long)ti + THREAD_SIZE - 32;
|
||||
struct pt_regs *regs = (struct pt_regs *)ksp - 1;
|
||||
#if (KGDB_GDB_REG_SIZE == 32)
|
||||
u32 *ptr = (u32 *)gdb_regs;
|
||||
#else
|
||||
@@ -254,25 +251,46 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
|
||||
#endif
|
||||
|
||||
for (reg = 0; reg < 16; reg++)
|
||||
*(ptr++) = regs->regs[reg];
|
||||
*(ptr++) = 0;
|
||||
|
||||
/* S0 - S7 */
|
||||
for (reg = 16; reg < 24; reg++)
|
||||
*(ptr++) = regs->regs[reg];
|
||||
*(ptr++) = p->thread.reg16;
|
||||
*(ptr++) = p->thread.reg17;
|
||||
*(ptr++) = p->thread.reg18;
|
||||
*(ptr++) = p->thread.reg19;
|
||||
*(ptr++) = p->thread.reg20;
|
||||
*(ptr++) = p->thread.reg21;
|
||||
*(ptr++) = p->thread.reg22;
|
||||
*(ptr++) = p->thread.reg23;
|
||||
|
||||
for (reg = 24; reg < 28; reg++)
|
||||
*(ptr++) = 0;
|
||||
|
||||
/* GP, SP, FP, RA */
|
||||
for (reg = 28; reg < 32; reg++)
|
||||
*(ptr++) = regs->regs[reg];
|
||||
*(ptr++) = (long)p;
|
||||
*(ptr++) = p->thread.reg29;
|
||||
*(ptr++) = p->thread.reg30;
|
||||
*(ptr++) = p->thread.reg31;
|
||||
|
||||
*(ptr++) = regs->cp0_status;
|
||||
*(ptr++) = regs->lo;
|
||||
*(ptr++) = regs->hi;
|
||||
*(ptr++) = regs->cp0_badvaddr;
|
||||
*(ptr++) = regs->cp0_cause;
|
||||
*(ptr++) = regs->cp0_epc;
|
||||
*(ptr++) = p->thread.cp0_status;
|
||||
|
||||
/* lo, hi */
|
||||
*(ptr++) = 0;
|
||||
*(ptr++) = 0;
|
||||
|
||||
/*
|
||||
* BadVAddr, Cause
|
||||
* Ideally these would come from the last exception frame up the stack
|
||||
* but that requires unwinding, otherwise we can't know much for sure.
|
||||
*/
|
||||
*(ptr++) = 0;
|
||||
*(ptr++) = 0;
|
||||
|
||||
/*
|
||||
* PC
|
||||
* use return address (RA), i.e. the moment after return from resume()
|
||||
*/
|
||||
*(ptr++) = p->thread.reg31;
|
||||
}
|
||||
|
||||
void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
|
||||
|
||||
@@ -269,11 +269,6 @@ static void ltq_hw5_irqdispatch(void)
|
||||
DEFINE_HWx_IRQDISPATCH(5)
|
||||
#endif
|
||||
|
||||
static void ltq_hw_irq_handler(struct irq_desc *desc)
|
||||
{
|
||||
ltq_hw_irqdispatch(irq_desc_get_irq(desc) - 2);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MIPS_MT_SMP
|
||||
void __init arch_init_ipiirq(int irq, struct irqaction *action)
|
||||
{
|
||||
@@ -318,19 +313,23 @@ static struct irqaction irq_call = {
|
||||
asmlinkage void plat_irq_dispatch(void)
|
||||
{
|
||||
unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
|
||||
int irq;
|
||||
unsigned int i;
|
||||
|
||||
if (!pending) {
|
||||
spurious_interrupt();
|
||||
return;
|
||||
if ((MIPS_CPU_TIMER_IRQ == 7) && (pending & CAUSEF_IP7)) {
|
||||
do_IRQ(MIPS_CPU_TIMER_IRQ);
|
||||
goto out;
|
||||
} else {
|
||||
for (i = 0; i < MAX_IM; i++) {
|
||||
if (pending & (CAUSEF_IP2 << i)) {
|
||||
ltq_hw_irqdispatch(i);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
pr_alert("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status());
|
||||
|
||||
pending >>= CAUSEB_IP;
|
||||
while (pending) {
|
||||
irq = fls(pending) - 1;
|
||||
do_IRQ(MIPS_CPU_IRQ_BASE + irq);
|
||||
pending &= ~BIT(irq);
|
||||
}
|
||||
out:
|
||||
return;
|
||||
}
|
||||
|
||||
static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
|
||||
@@ -355,6 +354,11 @@ static const struct irq_domain_ops irq_domain_ops = {
|
||||
.map = icu_map,
|
||||
};
|
||||
|
||||
static struct irqaction cascade = {
|
||||
.handler = no_action,
|
||||
.name = "cascade",
|
||||
};
|
||||
|
||||
int __init icu_of_init(struct device_node *node, struct device_node *parent)
|
||||
{
|
||||
struct device_node *eiu_node;
|
||||
@@ -386,7 +390,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent)
|
||||
mips_cpu_irq_init();
|
||||
|
||||
for (i = 0; i < MAX_IM; i++)
|
||||
irq_set_chained_handler(i + 2, ltq_hw_irq_handler);
|
||||
setup_irq(i + 2, &cascade);
|
||||
|
||||
if (cpu_has_vint) {
|
||||
pr_info("Setting up vectored interrupts\n");
|
||||
|
||||
@@ -42,10 +42,10 @@ static inline long access_ok(int type, const void __user * addr,
|
||||
#define get_user __get_user
|
||||
|
||||
#if !defined(CONFIG_64BIT)
|
||||
#define LDD_USER(ptr) __get_user_asm64(ptr)
|
||||
#define LDD_USER(val, ptr) __get_user_asm64(val, ptr)
|
||||
#define STD_USER(x, ptr) __put_user_asm64(x, ptr)
|
||||
#else
|
||||
#define LDD_USER(ptr) __get_user_asm("ldd", ptr)
|
||||
#define LDD_USER(val, ptr) __get_user_asm(val, "ldd", ptr)
|
||||
#define STD_USER(x, ptr) __put_user_asm("std", x, ptr)
|
||||
#endif
|
||||
|
||||
@@ -100,63 +100,87 @@ struct exception_data {
|
||||
" mtsp %0,%%sr2\n\t" \
|
||||
: : "r"(get_fs()) : )
|
||||
|
||||
#define __get_user(x, ptr) \
|
||||
({ \
|
||||
register long __gu_err __asm__ ("r8") = 0; \
|
||||
register long __gu_val; \
|
||||
\
|
||||
load_sr2(); \
|
||||
switch (sizeof(*(ptr))) { \
|
||||
case 1: __get_user_asm("ldb", ptr); break; \
|
||||
case 2: __get_user_asm("ldh", ptr); break; \
|
||||
case 4: __get_user_asm("ldw", ptr); break; \
|
||||
case 8: LDD_USER(ptr); break; \
|
||||
default: BUILD_BUG(); break; \
|
||||
} \
|
||||
\
|
||||
(x) = (__force __typeof__(*(ptr))) __gu_val; \
|
||||
__gu_err; \
|
||||
#define __get_user_internal(val, ptr) \
|
||||
({ \
|
||||
register long __gu_err __asm__ ("r8") = 0; \
|
||||
\
|
||||
switch (sizeof(*(ptr))) { \
|
||||
case 1: __get_user_asm(val, "ldb", ptr); break; \
|
||||
case 2: __get_user_asm(val, "ldh", ptr); break; \
|
||||
case 4: __get_user_asm(val, "ldw", ptr); break; \
|
||||
case 8: LDD_USER(val, ptr); break; \
|
||||
default: BUILD_BUG(); \
|
||||
} \
|
||||
\
|
||||
__gu_err; \
|
||||
})
|
||||
|
||||
#define __get_user_asm(ldx, ptr) \
|
||||
#define __get_user(val, ptr) \
|
||||
({ \
|
||||
load_sr2(); \
|
||||
__get_user_internal(val, ptr); \
|
||||
})
|
||||
|
||||
#define __get_user_asm(val, ldx, ptr) \
|
||||
{ \
|
||||
register long __gu_val; \
|
||||
\
|
||||
__asm__("1: " ldx " 0(%%sr2,%2),%0\n" \
|
||||
"9:\n" \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
|
||||
: "=r"(__gu_val), "=r"(__gu_err) \
|
||||
: "r"(ptr), "1"(__gu_err));
|
||||
: "r"(ptr), "1"(__gu_err)); \
|
||||
\
|
||||
(val) = (__force __typeof__(*(ptr))) __gu_val; \
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_64BIT)
|
||||
|
||||
#define __get_user_asm64(ptr) \
|
||||
#define __get_user_asm64(val, ptr) \
|
||||
{ \
|
||||
union { \
|
||||
unsigned long long l; \
|
||||
__typeof__(*(ptr)) t; \
|
||||
} __gu_tmp; \
|
||||
\
|
||||
__asm__(" copy %%r0,%R0\n" \
|
||||
"1: ldw 0(%%sr2,%2),%0\n" \
|
||||
"2: ldw 4(%%sr2,%2),%R0\n" \
|
||||
"9:\n" \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 9b) \
|
||||
ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 9b) \
|
||||
: "=r"(__gu_val), "=r"(__gu_err) \
|
||||
: "r"(ptr), "1"(__gu_err));
|
||||
: "=&r"(__gu_tmp.l), "=r"(__gu_err) \
|
||||
: "r"(ptr), "1"(__gu_err)); \
|
||||
\
|
||||
(val) = __gu_tmp.t; \
|
||||
}
|
||||
|
||||
#endif /* !defined(CONFIG_64BIT) */
|
||||
|
||||
|
||||
#define __put_user(x, ptr) \
|
||||
#define __put_user_internal(x, ptr) \
|
||||
({ \
|
||||
register long __pu_err __asm__ ("r8") = 0; \
|
||||
__typeof__(*(ptr)) __x = (__typeof__(*(ptr)))(x); \
|
||||
\
|
||||
load_sr2(); \
|
||||
switch (sizeof(*(ptr))) { \
|
||||
case 1: __put_user_asm("stb", __x, ptr); break; \
|
||||
case 2: __put_user_asm("sth", __x, ptr); break; \
|
||||
case 4: __put_user_asm("stw", __x, ptr); break; \
|
||||
case 8: STD_USER(__x, ptr); break; \
|
||||
default: BUILD_BUG(); break; \
|
||||
} \
|
||||
case 1: __put_user_asm("stb", __x, ptr); break; \
|
||||
case 2: __put_user_asm("sth", __x, ptr); break; \
|
||||
case 4: __put_user_asm("stw", __x, ptr); break; \
|
||||
case 8: STD_USER(__x, ptr); break; \
|
||||
default: BUILD_BUG(); \
|
||||
} \
|
||||
\
|
||||
__pu_err; \
|
||||
})
|
||||
|
||||
#define __put_user(x, ptr) \
|
||||
({ \
|
||||
load_sr2(); \
|
||||
__put_user_internal(x, ptr); \
|
||||
})
|
||||
|
||||
|
||||
/*
|
||||
* The "__put_user/kernel_asm()" macros tell gcc they read from memory
|
||||
* instead of writing. This is because they do not write to any memory
|
||||
|
||||
@@ -201,7 +201,7 @@ ENTRY_CFI(pa_memcpy)
|
||||
add dst,len,end
|
||||
|
||||
/* short copy with less than 16 bytes? */
|
||||
cmpib,>>=,n 15,len,.Lbyte_loop
|
||||
cmpib,COND(>>=),n 15,len,.Lbyte_loop
|
||||
|
||||
/* same alignment? */
|
||||
xor src,dst,t0
|
||||
@@ -216,7 +216,7 @@ ENTRY_CFI(pa_memcpy)
|
||||
/* loop until we are 64-bit aligned */
|
||||
.Lalign_loop64:
|
||||
extru dst,31,3,t1
|
||||
cmpib,=,n 0,t1,.Lcopy_loop_16
|
||||
cmpib,=,n 0,t1,.Lcopy_loop_16_start
|
||||
20: ldb,ma 1(srcspc,src),t1
|
||||
21: stb,ma t1,1(dstspc,dst)
|
||||
b .Lalign_loop64
|
||||
@@ -225,6 +225,7 @@ ENTRY_CFI(pa_memcpy)
|
||||
ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done)
|
||||
ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
|
||||
|
||||
.Lcopy_loop_16_start:
|
||||
ldi 31,t0
|
||||
.Lcopy_loop_16:
|
||||
cmpb,COND(>>=),n t0,len,.Lword_loop
|
||||
@@ -267,7 +268,7 @@ ENTRY_CFI(pa_memcpy)
|
||||
/* loop until we are 32-bit aligned */
|
||||
.Lalign_loop32:
|
||||
extru dst,31,2,t1
|
||||
cmpib,=,n 0,t1,.Lcopy_loop_4
|
||||
cmpib,=,n 0,t1,.Lcopy_loop_8
|
||||
20: ldb,ma 1(srcspc,src),t1
|
||||
21: stb,ma t1,1(dstspc,dst)
|
||||
b .Lalign_loop32
|
||||
@@ -277,7 +278,7 @@ ENTRY_CFI(pa_memcpy)
|
||||
ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
|
||||
|
||||
|
||||
.Lcopy_loop_4:
|
||||
.Lcopy_loop_8:
|
||||
cmpib,COND(>>=),n 15,len,.Lbyte_loop
|
||||
|
||||
10: ldw 0(srcspc,src),t1
|
||||
@@ -299,7 +300,7 @@ ENTRY_CFI(pa_memcpy)
|
||||
ASM_EXCEPTIONTABLE_ENTRY(16b,.Lcopy_done)
|
||||
ASM_EXCEPTIONTABLE_ENTRY(17b,.Lcopy_done)
|
||||
|
||||
b .Lcopy_loop_4
|
||||
b .Lcopy_loop_8
|
||||
ldo -16(len),len
|
||||
|
||||
.Lbyte_loop:
|
||||
@@ -324,7 +325,7 @@ ENTRY_CFI(pa_memcpy)
|
||||
.Lunaligned_copy:
|
||||
/* align until dst is 32bit-word-aligned */
|
||||
extru dst,31,2,t1
|
||||
cmpib,COND(=),n 0,t1,.Lcopy_dstaligned
|
||||
cmpib,=,n 0,t1,.Lcopy_dstaligned
|
||||
20: ldb 0(srcspc,src),t1
|
||||
ldo 1(src),src
|
||||
21: stb,ma t1,1(dstspc,dst)
|
||||
@@ -362,7 +363,7 @@ ENTRY_CFI(pa_memcpy)
|
||||
cmpiclr,<> 1,t0,%r0
|
||||
b,n .Lcase1
|
||||
.Lcase0:
|
||||
cmpb,= %r0,len,.Lcda_finish
|
||||
cmpb,COND(=) %r0,len,.Lcda_finish
|
||||
nop
|
||||
|
||||
1: ldw,ma 4(srcspc,src), a3
|
||||
@@ -376,7 +377,7 @@ ENTRY_CFI(pa_memcpy)
|
||||
1: ldw,ma 4(srcspc,src), a3
|
||||
ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
|
||||
ldo -1(len),len
|
||||
cmpb,=,n %r0,len,.Ldo0
|
||||
cmpb,COND(=),n %r0,len,.Ldo0
|
||||
.Ldo4:
|
||||
1: ldw,ma 4(srcspc,src), a0
|
||||
ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
|
||||
@@ -402,7 +403,7 @@ ENTRY_CFI(pa_memcpy)
|
||||
1: stw,ma t0, 4(dstspc,dst)
|
||||
ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done)
|
||||
ldo -4(len),len
|
||||
cmpb,<> %r0,len,.Ldo4
|
||||
cmpb,COND(<>) %r0,len,.Ldo4
|
||||
nop
|
||||
.Ldo0:
|
||||
shrpw a2, a3, %sar, t0
|
||||
@@ -436,14 +437,14 @@ ENTRY_CFI(pa_memcpy)
|
||||
/* fault exception fixup handlers: */
|
||||
#ifdef CONFIG_64BIT
|
||||
.Lcopy16_fault:
|
||||
10: b .Lcopy_done
|
||||
std,ma t1,8(dstspc,dst)
|
||||
b .Lcopy_done
|
||||
10: std,ma t1,8(dstspc,dst)
|
||||
ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
|
||||
#endif
|
||||
|
||||
.Lcopy8_fault:
|
||||
10: b .Lcopy_done
|
||||
stw,ma t1,4(dstspc,dst)
|
||||
b .Lcopy_done
|
||||
10: stw,ma t1,4(dstspc,dst)
|
||||
ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
|
||||
|
||||
.exit
|
||||
|
||||
@@ -689,7 +689,7 @@ resume_kernel:
|
||||
|
||||
addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */
|
||||
|
||||
lwz r3,GPR1(r1)
|
||||
ld r3,GPR1(r1)
|
||||
subi r3,r3,INT_FRAME_SIZE /* dst: Allocate a trampoline exception frame */
|
||||
mr r4,r1 /* src: current exception frame */
|
||||
mr r1,r3 /* Reroute the trampoline frame to r1 */
|
||||
@@ -703,8 +703,8 @@ resume_kernel:
|
||||
addi r6,r6,8
|
||||
bdnz 2b
|
||||
|
||||
/* Do real store operation to complete stwu */
|
||||
lwz r5,GPR1(r1)
|
||||
/* Do real store operation to complete stdu */
|
||||
ld r5,GPR1(r1)
|
||||
std r8,0(r5)
|
||||
|
||||
/* Clear _TIF_EMULATE_STACK_STORE flag */
|
||||
|
||||
@@ -1029,6 +1029,8 @@ int get_guest_storage_key(struct mm_struct *mm, unsigned long addr,
|
||||
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep, pte_t entry)
|
||||
{
|
||||
if (pte_present(entry))
|
||||
pte_val(entry) &= ~_PAGE_UNUSED;
|
||||
if (mm_has_pgste(mm))
|
||||
ptep_set_pte_at(mm, addr, ptep, entry);
|
||||
else
|
||||
|
||||
@@ -673,6 +673,14 @@ static inline unsigned long pmd_pfn(pmd_t pmd)
|
||||
return pte_pfn(pte);
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_PMD_WRITE
|
||||
static inline unsigned long pmd_write(pmd_t pmd)
|
||||
{
|
||||
pte_t pte = __pte(pmd_val(pmd));
|
||||
|
||||
return pte_write(pte);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
static inline unsigned long pmd_dirty(pmd_t pmd)
|
||||
{
|
||||
@@ -688,13 +696,6 @@ static inline unsigned long pmd_young(pmd_t pmd)
|
||||
return pte_young(pte);
|
||||
}
|
||||
|
||||
static inline unsigned long pmd_write(pmd_t pmd)
|
||||
{
|
||||
pte_t pte = __pte(pmd_val(pmd));
|
||||
|
||||
return pte_write(pte);
|
||||
}
|
||||
|
||||
static inline unsigned long pmd_trans_huge(pmd_t pmd)
|
||||
{
|
||||
pte_t pte = __pte(pmd_val(pmd));
|
||||
|
||||
@@ -1495,7 +1495,7 @@ bool kern_addr_valid(unsigned long addr)
|
||||
if ((long)addr < 0L) {
|
||||
unsigned long pa = __pa(addr);
|
||||
|
||||
if ((addr >> max_phys_bits) != 0UL)
|
||||
if ((pa >> max_phys_bits) != 0UL)
|
||||
return false;
|
||||
|
||||
return pfn_valid(pa >> PAGE_SHIFT);
|
||||
|
||||
@@ -30,8 +30,10 @@ static int __init vdso32_setup(char *s)
|
||||
{
|
||||
vdso32_enabled = simple_strtoul(s, NULL, 0);
|
||||
|
||||
if (vdso32_enabled > 1)
|
||||
if (vdso32_enabled > 1) {
|
||||
pr_warn("vdso32 values other than 0 and 1 are no longer allowed; vdso disabled\n");
|
||||
vdso32_enabled = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -62,13 +64,18 @@ subsys_initcall(sysenter_setup);
|
||||
/* Register vsyscall32 into the ABI table */
|
||||
#include <linux/sysctl.h>
|
||||
|
||||
static const int zero;
|
||||
static const int one = 1;
|
||||
|
||||
static struct ctl_table abi_table2[] = {
|
||||
{
|
||||
.procname = "vsyscall32",
|
||||
.data = &vdso32_enabled,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = proc_dointvec
|
||||
.proc_handler = proc_dointvec_minmax,
|
||||
.extra1 = (int *)&zero,
|
||||
.extra2 = (int *)&one,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -507,6 +507,9 @@ static void intel_pmu_lbr_read_32(struct cpu_hw_events *cpuc)
|
||||
cpuc->lbr_entries[i].to = msr_lastbranch.to;
|
||||
cpuc->lbr_entries[i].mispred = 0;
|
||||
cpuc->lbr_entries[i].predicted = 0;
|
||||
cpuc->lbr_entries[i].in_tx = 0;
|
||||
cpuc->lbr_entries[i].abort = 0;
|
||||
cpuc->lbr_entries[i].cycles = 0;
|
||||
cpuc->lbr_entries[i].reserved = 0;
|
||||
}
|
||||
cpuc->lbr_stack.nr = i;
|
||||
|
||||
@@ -278,7 +278,7 @@ struct task_struct;
|
||||
|
||||
#define ARCH_DLINFO_IA32 \
|
||||
do { \
|
||||
if (vdso32_enabled) { \
|
||||
if (VDSO_CURRENT_BASE) { \
|
||||
NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \
|
||||
NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \
|
||||
} \
|
||||
|
||||
@@ -55,7 +55,8 @@ static inline int arch_memcpy_from_pmem(void *dst, const void *src, size_t n)
|
||||
* @size: number of bytes to write back
|
||||
*
|
||||
* Write back a cache range using the CLWB (cache line write back)
|
||||
* instruction.
|
||||
* instruction. Note that @size is internally rounded up to be cache
|
||||
* line size aligned.
|
||||
*/
|
||||
static inline void arch_wb_cache_pmem(void *addr, size_t size)
|
||||
{
|
||||
@@ -69,15 +70,6 @@ static inline void arch_wb_cache_pmem(void *addr, size_t size)
|
||||
clwb(p);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy_from_iter_nocache() on x86 only uses non-temporal stores for iovec
|
||||
* iterators, so for other types (bvec & kvec) we must do a cache write-back.
|
||||
*/
|
||||
static inline bool __iter_needs_pmem_wb(struct iov_iter *i)
|
||||
{
|
||||
return iter_is_iovec(i) == false;
|
||||
}
|
||||
|
||||
/**
|
||||
* arch_copy_from_iter_pmem - copy data from an iterator to PMEM
|
||||
* @addr: PMEM destination address
|
||||
@@ -94,7 +86,35 @@ static inline size_t arch_copy_from_iter_pmem(void *addr, size_t bytes,
|
||||
/* TODO: skip the write-back by always using non-temporal stores */
|
||||
len = copy_from_iter_nocache(addr, bytes, i);
|
||||
|
||||
if (__iter_needs_pmem_wb(i))
|
||||
/*
|
||||
* In the iovec case on x86_64 copy_from_iter_nocache() uses
|
||||
* non-temporal stores for the bulk of the transfer, but we need
|
||||
* to manually flush if the transfer is unaligned. A cached
|
||||
* memory copy is used when destination or size is not naturally
|
||||
* aligned. That is:
|
||||
* - Require 8-byte alignment when size is 8 bytes or larger.
|
||||
* - Require 4-byte alignment when size is 4 bytes.
|
||||
*
|
||||
* In the non-iovec case the entire destination needs to be
|
||||
* flushed.
|
||||
*/
|
||||
if (iter_is_iovec(i)) {
|
||||
unsigned long flushed, dest = (unsigned long) addr;
|
||||
|
||||
if (bytes < 8) {
|
||||
if (!IS_ALIGNED(dest, 4) || (bytes != 4))
|
||||
arch_wb_cache_pmem(addr, 1);
|
||||
} else {
|
||||
if (!IS_ALIGNED(dest, 8)) {
|
||||
dest = ALIGN(dest, boot_cpu_data.x86_clflush_size);
|
||||
arch_wb_cache_pmem(addr, 1);
|
||||
}
|
||||
|
||||
flushed = dest - (unsigned long) addr;
|
||||
if (bytes > flushed && !IS_ALIGNED(bytes - flushed, 8))
|
||||
arch_wb_cache_pmem(addr + bytes - 1, 1);
|
||||
}
|
||||
} else
|
||||
arch_wb_cache_pmem(addr, bytes);
|
||||
|
||||
return len;
|
||||
|
||||
@@ -85,7 +85,7 @@ void mce_gen_pool_process(void)
|
||||
head = llist_reverse_order(head);
|
||||
llist_for_each_entry_safe(node, tmp, head, llnode) {
|
||||
mce = &node->mce;
|
||||
atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce);
|
||||
blocking_notifier_call_chain(&x86_mce_decoder_chain, 0, mce);
|
||||
gen_pool_free(mce_evt_pool, (unsigned long)node, sizeof(*node));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ enum severity_level {
|
||||
MCE_PANIC_SEVERITY,
|
||||
};
|
||||
|
||||
extern struct atomic_notifier_head x86_mce_decoder_chain;
|
||||
extern struct blocking_notifier_head x86_mce_decoder_chain;
|
||||
|
||||
#define ATTR_LEN 16
|
||||
#define INITIAL_CHECK_INTERVAL 5 * 60 /* 5 minutes */
|
||||
|
||||
@@ -120,7 +120,7 @@ static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs);
|
||||
* CPU/chipset specific EDAC code can register a notifier call here to print
|
||||
* MCE errors in a human-readable form.
|
||||
*/
|
||||
ATOMIC_NOTIFIER_HEAD(x86_mce_decoder_chain);
|
||||
BLOCKING_NOTIFIER_HEAD(x86_mce_decoder_chain);
|
||||
|
||||
/* Do initial initialization of a struct mce */
|
||||
void mce_setup(struct mce *m)
|
||||
@@ -213,13 +213,13 @@ void mce_register_decode_chain(struct notifier_block *nb)
|
||||
if (nb != &mce_srao_nb && nb->priority == INT_MAX)
|
||||
nb->priority -= 1;
|
||||
|
||||
atomic_notifier_chain_register(&x86_mce_decoder_chain, nb);
|
||||
blocking_notifier_chain_register(&x86_mce_decoder_chain, nb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mce_register_decode_chain);
|
||||
|
||||
void mce_unregister_decode_chain(struct notifier_block *nb)
|
||||
{
|
||||
atomic_notifier_chain_unregister(&x86_mce_decoder_chain, nb);
|
||||
blocking_notifier_chain_unregister(&x86_mce_decoder_chain, nb);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mce_unregister_decode_chain);
|
||||
|
||||
@@ -272,8 +272,6 @@ struct mca_msr_regs msr_ops = {
|
||||
|
||||
static void print_mce(struct mce *m)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
pr_emerg(HW_ERR "CPU %d: Machine Check Exception: %Lx Bank %d: %016Lx\n",
|
||||
m->extcpu, m->mcgstatus, m->bank, m->status);
|
||||
|
||||
@@ -309,14 +307,6 @@ static void print_mce(struct mce *m)
|
||||
m->cpuvendor, m->cpuid, m->time, m->socketid, m->apicid,
|
||||
cpu_data(m->extcpu).microcode);
|
||||
|
||||
/*
|
||||
* Print out human-readable details about the MCE error,
|
||||
* (if the CPU has an implementation for that)
|
||||
*/
|
||||
ret = atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m);
|
||||
if (ret == NOTIFY_STOP)
|
||||
return;
|
||||
|
||||
pr_emerg_ratelimited(HW_ERR "Run the above through 'mcelog --ascii'\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ static const char * const th_names[] = {
|
||||
"load_store",
|
||||
"insn_fetch",
|
||||
"combined_unit",
|
||||
"",
|
||||
"decode_unit",
|
||||
"northbridge",
|
||||
"execution_unit",
|
||||
};
|
||||
|
||||
@@ -983,6 +983,18 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent,
|
||||
unsigned long return_hooker = (unsigned long)
|
||||
&return_to_handler;
|
||||
|
||||
/*
|
||||
* When resuming from suspend-to-ram, this function can be indirectly
|
||||
* called from early CPU startup code while the CPU is in real mode,
|
||||
* which would fail miserably. Make sure the stack pointer is a
|
||||
* virtual address.
|
||||
*
|
||||
* This check isn't as accurate as virt_addr_valid(), but it should be
|
||||
* good enough for this purpose, and it's fast.
|
||||
*/
|
||||
if (unlikely((long)__builtin_frame_address(0) >= 0))
|
||||
return;
|
||||
|
||||
if (unlikely(ftrace_graph_is_dead()))
|
||||
return;
|
||||
|
||||
|
||||
@@ -151,8 +151,8 @@ int __copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from,
|
||||
|
||||
if (from->si_signo == SIGSEGV) {
|
||||
if (from->si_code == SEGV_BNDERR) {
|
||||
compat_uptr_t lower = (unsigned long)&to->si_lower;
|
||||
compat_uptr_t upper = (unsigned long)&to->si_upper;
|
||||
compat_uptr_t lower = (unsigned long)from->si_lower;
|
||||
compat_uptr_t upper = (unsigned long)from->si_upper;
|
||||
put_user_ex(lower, &to->si_lower);
|
||||
put_user_ex(upper, &to->si_upper);
|
||||
}
|
||||
|
||||
@@ -6925,14 +6925,20 @@ static int nested_vmx_check_vmptr(struct kvm_vcpu *vcpu, int exit_reason,
|
||||
}
|
||||
|
||||
page = nested_get_page(vcpu, vmptr);
|
||||
if (page == NULL ||
|
||||
*(u32 *)kmap(page) != VMCS12_REVISION) {
|
||||
if (page == NULL) {
|
||||
nested_vmx_failInvalid(vcpu);
|
||||
skip_emulated_instruction(vcpu);
|
||||
return 1;
|
||||
}
|
||||
if (*(u32 *)kmap(page) != VMCS12_REVISION) {
|
||||
kunmap(page);
|
||||
nested_release_page_clean(page);
|
||||
nested_vmx_failInvalid(vcpu);
|
||||
skip_emulated_instruction(vcpu);
|
||||
return 1;
|
||||
}
|
||||
kunmap(page);
|
||||
nested_release_page_clean(page);
|
||||
vmx->nested.vmxon_ptr = vmptr;
|
||||
break;
|
||||
case EXIT_REASON_VMCLEAR:
|
||||
|
||||
@@ -643,21 +643,40 @@ void __init init_mem_mapping(void)
|
||||
* devmem_is_allowed() checks to see if /dev/mem access to a certain address
|
||||
* is valid. The argument is a physical page number.
|
||||
*
|
||||
*
|
||||
* On x86, access has to be given to the first megabyte of ram because that area
|
||||
* contains BIOS code and data regions used by X and dosemu and similar apps.
|
||||
* Access has to be given to non-kernel-ram areas as well, these contain the PCI
|
||||
* mmio resources as well as potential bios/acpi data regions.
|
||||
* On x86, access has to be given to the first megabyte of RAM because that
|
||||
* area traditionally contains BIOS code and data regions used by X, dosemu,
|
||||
* and similar apps. Since they map the entire memory range, the whole range
|
||||
* must be allowed (for mapping), but any areas that would otherwise be
|
||||
* disallowed are flagged as being "zero filled" instead of rejected.
|
||||
* Access has to be given to non-kernel-ram areas as well, these contain the
|
||||
* PCI mmio resources as well as potential bios/acpi data regions.
|
||||
*/
|
||||
int devmem_is_allowed(unsigned long pagenr)
|
||||
{
|
||||
if (pagenr < 256)
|
||||
return 1;
|
||||
if (iomem_is_exclusive(pagenr << PAGE_SHIFT))
|
||||
if (page_is_ram(pagenr)) {
|
||||
/*
|
||||
* For disallowed memory regions in the low 1MB range,
|
||||
* request that the page be shown as all zeros.
|
||||
*/
|
||||
if (pagenr < 256)
|
||||
return 2;
|
||||
|
||||
return 0;
|
||||
if (!page_is_ram(pagenr))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This must follow RAM test, since System RAM is considered a
|
||||
* restricted resource under CONFIG_STRICT_IOMEM.
|
||||
*/
|
||||
if (iomem_is_exclusive(pagenr << PAGE_SHIFT)) {
|
||||
/* Low 1MB bypasses iomem restrictions. */
|
||||
if (pagenr < 256)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void free_init_pages(char *what, unsigned long begin, unsigned long end)
|
||||
|
||||
@@ -201,6 +201,10 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
|
||||
return;
|
||||
}
|
||||
|
||||
/* No need to reserve regions that will never be freed. */
|
||||
if (md.attribute & EFI_MEMORY_RUNTIME)
|
||||
return;
|
||||
|
||||
size += addr % EFI_PAGE_SIZE;
|
||||
size = round_up(size, EFI_PAGE_SIZE);
|
||||
addr = round_down(addr, EFI_PAGE_SIZE);
|
||||
|
||||
@@ -145,7 +145,7 @@ static void xen_silent_inquire(int apicid)
|
||||
static int xen_cpu_present_to_apicid(int cpu)
|
||||
{
|
||||
if (cpu_present(cpu))
|
||||
return xen_get_apic_id(xen_apic_read(APIC_ID));
|
||||
return cpu_data(cpu).apicid;
|
||||
else
|
||||
return BAD_APICID;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ struct ahash_request_priv {
|
||||
crypto_completion_t complete;
|
||||
void *data;
|
||||
u8 *result;
|
||||
u32 flags;
|
||||
void *ubuf[] CRYPTO_MINALIGN_ATTR;
|
||||
};
|
||||
|
||||
@@ -252,6 +253,8 @@ static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt)
|
||||
priv->result = req->result;
|
||||
priv->complete = req->base.complete;
|
||||
priv->data = req->base.data;
|
||||
priv->flags = req->base.flags;
|
||||
|
||||
/*
|
||||
* WARNING: We do not backup req->priv here! The req->priv
|
||||
* is for internal use of the Crypto API and the
|
||||
@@ -266,38 +269,44 @@ static int ahash_save_req(struct ahash_request *req, crypto_completion_t cplt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ahash_restore_req(struct ahash_request *req)
|
||||
static void ahash_restore_req(struct ahash_request *req, int err)
|
||||
{
|
||||
struct ahash_request_priv *priv = req->priv;
|
||||
|
||||
if (!err)
|
||||
memcpy(priv->result, req->result,
|
||||
crypto_ahash_digestsize(crypto_ahash_reqtfm(req)));
|
||||
|
||||
/* Restore the original crypto request. */
|
||||
req->result = priv->result;
|
||||
req->base.complete = priv->complete;
|
||||
req->base.data = priv->data;
|
||||
|
||||
ahash_request_set_callback(req, priv->flags,
|
||||
priv->complete, priv->data);
|
||||
req->priv = NULL;
|
||||
|
||||
/* Free the req->priv.priv from the ADJUSTED request. */
|
||||
kzfree(priv);
|
||||
}
|
||||
|
||||
static void ahash_op_unaligned_finish(struct ahash_request *req, int err)
|
||||
static void ahash_notify_einprogress(struct ahash_request *req)
|
||||
{
|
||||
struct ahash_request_priv *priv = req->priv;
|
||||
struct crypto_async_request oreq;
|
||||
|
||||
if (err == -EINPROGRESS)
|
||||
return;
|
||||
oreq.data = priv->data;
|
||||
|
||||
if (!err)
|
||||
memcpy(priv->result, req->result,
|
||||
crypto_ahash_digestsize(crypto_ahash_reqtfm(req)));
|
||||
|
||||
ahash_restore_req(req);
|
||||
priv->complete(&oreq, -EINPROGRESS);
|
||||
}
|
||||
|
||||
static void ahash_op_unaligned_done(struct crypto_async_request *req, int err)
|
||||
{
|
||||
struct ahash_request *areq = req->data;
|
||||
|
||||
if (err == -EINPROGRESS) {
|
||||
ahash_notify_einprogress(areq);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore the original request, see ahash_op_unaligned() for what
|
||||
* goes where.
|
||||
@@ -308,7 +317,7 @@ static void ahash_op_unaligned_done(struct crypto_async_request *req, int err)
|
||||
*/
|
||||
|
||||
/* First copy req->result into req->priv.result */
|
||||
ahash_op_unaligned_finish(areq, err);
|
||||
ahash_restore_req(areq, err);
|
||||
|
||||
/* Complete the ORIGINAL request. */
|
||||
areq->base.complete(&areq->base, err);
|
||||
@@ -324,7 +333,12 @@ static int ahash_op_unaligned(struct ahash_request *req,
|
||||
return err;
|
||||
|
||||
err = op(req);
|
||||
ahash_op_unaligned_finish(req, err);
|
||||
if (err == -EINPROGRESS ||
|
||||
(err == -EBUSY && (ahash_request_flags(req) &
|
||||
CRYPTO_TFM_REQ_MAY_BACKLOG)))
|
||||
return err;
|
||||
|
||||
ahash_restore_req(req, err);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -359,25 +373,14 @@ int crypto_ahash_digest(struct ahash_request *req)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_ahash_digest);
|
||||
|
||||
static void ahash_def_finup_finish2(struct ahash_request *req, int err)
|
||||
{
|
||||
struct ahash_request_priv *priv = req->priv;
|
||||
|
||||
if (err == -EINPROGRESS)
|
||||
return;
|
||||
|
||||
if (!err)
|
||||
memcpy(priv->result, req->result,
|
||||
crypto_ahash_digestsize(crypto_ahash_reqtfm(req)));
|
||||
|
||||
ahash_restore_req(req);
|
||||
}
|
||||
|
||||
static void ahash_def_finup_done2(struct crypto_async_request *req, int err)
|
||||
{
|
||||
struct ahash_request *areq = req->data;
|
||||
|
||||
ahash_def_finup_finish2(areq, err);
|
||||
if (err == -EINPROGRESS)
|
||||
return;
|
||||
|
||||
ahash_restore_req(areq, err);
|
||||
|
||||
areq->base.complete(&areq->base, err);
|
||||
}
|
||||
@@ -388,11 +391,15 @@ static int ahash_def_finup_finish1(struct ahash_request *req, int err)
|
||||
goto out;
|
||||
|
||||
req->base.complete = ahash_def_finup_done2;
|
||||
req->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
err = crypto_ahash_reqtfm(req)->final(req);
|
||||
if (err == -EINPROGRESS ||
|
||||
(err == -EBUSY && (ahash_request_flags(req) &
|
||||
CRYPTO_TFM_REQ_MAY_BACKLOG)))
|
||||
return err;
|
||||
|
||||
out:
|
||||
ahash_def_finup_finish2(req, err);
|
||||
ahash_restore_req(req, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -400,7 +407,16 @@ static void ahash_def_finup_done1(struct crypto_async_request *req, int err)
|
||||
{
|
||||
struct ahash_request *areq = req->data;
|
||||
|
||||
if (err == -EINPROGRESS) {
|
||||
ahash_notify_einprogress(areq);
|
||||
return;
|
||||
}
|
||||
|
||||
areq->base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
|
||||
|
||||
err = ahash_def_finup_finish1(areq, err);
|
||||
if (areq->priv)
|
||||
return;
|
||||
|
||||
areq->base.complete(&areq->base, err);
|
||||
}
|
||||
@@ -415,6 +431,11 @@ static int ahash_def_finup(struct ahash_request *req)
|
||||
return err;
|
||||
|
||||
err = tfm->update(req);
|
||||
if (err == -EINPROGRESS ||
|
||||
(err == -EBUSY && (ahash_request_flags(req) &
|
||||
CRYPTO_TFM_REQ_MAY_BACKLOG)))
|
||||
return err;
|
||||
|
||||
return ahash_def_finup_finish1(req, err);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ struct aead_async_req {
|
||||
struct aead_async_rsgl first_rsgl;
|
||||
struct list_head list;
|
||||
struct kiocb *iocb;
|
||||
struct sock *sk;
|
||||
unsigned int tsgls;
|
||||
char iv[];
|
||||
};
|
||||
@@ -379,12 +380,10 @@ unlock:
|
||||
|
||||
static void aead_async_cb(struct crypto_async_request *_req, int err)
|
||||
{
|
||||
struct sock *sk = _req->data;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
struct aead_ctx *ctx = ask->private;
|
||||
struct crypto_aead *tfm = crypto_aead_reqtfm(&ctx->aead_req);
|
||||
struct aead_request *req = aead_request_cast(_req);
|
||||
struct aead_request *req = _req->data;
|
||||
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
|
||||
struct aead_async_req *areq = GET_ASYM_REQ(req, tfm);
|
||||
struct sock *sk = areq->sk;
|
||||
struct scatterlist *sg = areq->tsgl;
|
||||
struct aead_async_rsgl *rsgl;
|
||||
struct kiocb *iocb = areq->iocb;
|
||||
@@ -447,11 +446,12 @@ static int aead_recvmsg_async(struct socket *sock, struct msghdr *msg,
|
||||
memset(&areq->first_rsgl, '\0', sizeof(areq->first_rsgl));
|
||||
INIT_LIST_HEAD(&areq->list);
|
||||
areq->iocb = msg->msg_iocb;
|
||||
areq->sk = sk;
|
||||
memcpy(areq->iv, ctx->iv, crypto_aead_ivsize(tfm));
|
||||
aead_request_set_tfm(req, tfm);
|
||||
aead_request_set_ad(req, ctx->aead_assoclen);
|
||||
aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
aead_async_cb, sk);
|
||||
aead_async_cb, req);
|
||||
used -= ctx->aead_assoclen;
|
||||
|
||||
/* take over all tx sgls from ctx */
|
||||
|
||||
@@ -729,12 +729,12 @@ static void start_transaction(struct acpi_ec *ec)
|
||||
|
||||
static int ec_guard(struct acpi_ec *ec)
|
||||
{
|
||||
unsigned long guard = usecs_to_jiffies(ec_polling_guard);
|
||||
unsigned long guard = usecs_to_jiffies(ec->polling_guard);
|
||||
unsigned long timeout = ec->timestamp + guard;
|
||||
|
||||
/* Ensure guarding period before polling EC status */
|
||||
do {
|
||||
if (ec_busy_polling) {
|
||||
if (ec->busy_polling) {
|
||||
/* Perform busy polling */
|
||||
if (ec_transaction_completed(ec))
|
||||
return 0;
|
||||
@@ -998,6 +998,28 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending)
|
||||
spin_unlock_irqrestore(&ec->lock, flags);
|
||||
}
|
||||
|
||||
static void acpi_ec_enter_noirq(struct acpi_ec *ec)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ec->lock, flags);
|
||||
ec->busy_polling = true;
|
||||
ec->polling_guard = 0;
|
||||
ec_log_drv("interrupt blocked");
|
||||
spin_unlock_irqrestore(&ec->lock, flags);
|
||||
}
|
||||
|
||||
static void acpi_ec_leave_noirq(struct acpi_ec *ec)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ec->lock, flags);
|
||||
ec->busy_polling = ec_busy_polling;
|
||||
ec->polling_guard = ec_polling_guard;
|
||||
ec_log_drv("interrupt unblocked");
|
||||
spin_unlock_irqrestore(&ec->lock, flags);
|
||||
}
|
||||
|
||||
void acpi_ec_block_transactions(void)
|
||||
{
|
||||
struct acpi_ec *ec = first_ec;
|
||||
@@ -1278,7 +1300,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
|
||||
if (function != ACPI_READ && function != ACPI_WRITE)
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
if (ec_busy_polling || bits > 8)
|
||||
if (ec->busy_polling || bits > 8)
|
||||
acpi_ec_burst_enable(ec);
|
||||
|
||||
for (i = 0; i < bytes; ++i, ++address, ++value)
|
||||
@@ -1286,7 +1308,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
|
||||
acpi_ec_read(ec, address, value) :
|
||||
acpi_ec_write(ec, address, *value);
|
||||
|
||||
if (ec_busy_polling || bits > 8)
|
||||
if (ec->busy_polling || bits > 8)
|
||||
acpi_ec_burst_disable(ec);
|
||||
|
||||
switch (result) {
|
||||
@@ -1329,6 +1351,8 @@ static struct acpi_ec *acpi_ec_alloc(void)
|
||||
spin_lock_init(&ec->lock);
|
||||
INIT_WORK(&ec->work, acpi_ec_event_handler);
|
||||
ec->timestamp = jiffies;
|
||||
ec->busy_polling = true;
|
||||
ec->polling_guard = 0;
|
||||
return ec;
|
||||
}
|
||||
|
||||
@@ -1390,6 +1414,7 @@ static int ec_install_handlers(struct acpi_ec *ec, bool handle_events)
|
||||
acpi_ec_start(ec, false);
|
||||
|
||||
if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
|
||||
acpi_ec_enter_noirq(ec);
|
||||
status = acpi_install_address_space_handler(ec->handle,
|
||||
ACPI_ADR_SPACE_EC,
|
||||
&acpi_ec_space_handler,
|
||||
@@ -1429,6 +1454,7 @@ static int ec_install_handlers(struct acpi_ec *ec, bool handle_events)
|
||||
/* This is not fatal as we can poll EC events */
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
set_bit(EC_FLAGS_GPE_HANDLER_INSTALLED, &ec->flags);
|
||||
acpi_ec_leave_noirq(ec);
|
||||
if (test_bit(EC_FLAGS_STARTED, &ec->flags) &&
|
||||
ec->reference_count >= 1)
|
||||
acpi_ec_enable_gpe(ec, true);
|
||||
@@ -1839,34 +1865,6 @@ error:
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static void acpi_ec_enter_noirq(struct acpi_ec *ec)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (ec == first_ec) {
|
||||
spin_lock_irqsave(&ec->lock, flags);
|
||||
ec->saved_busy_polling = ec_busy_polling;
|
||||
ec->saved_polling_guard = ec_polling_guard;
|
||||
ec_busy_polling = true;
|
||||
ec_polling_guard = 0;
|
||||
ec_log_drv("interrupt blocked");
|
||||
spin_unlock_irqrestore(&ec->lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void acpi_ec_leave_noirq(struct acpi_ec *ec)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (ec == first_ec) {
|
||||
spin_lock_irqsave(&ec->lock, flags);
|
||||
ec_busy_polling = ec->saved_busy_polling;
|
||||
ec_polling_guard = ec->saved_polling_guard;
|
||||
ec_log_drv("interrupt unblocked");
|
||||
spin_unlock_irqrestore(&ec->lock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static int acpi_ec_suspend_noirq(struct device *dev)
|
||||
{
|
||||
struct acpi_ec *ec =
|
||||
|
||||
@@ -172,8 +172,8 @@ struct acpi_ec {
|
||||
struct work_struct work;
|
||||
unsigned long timestamp;
|
||||
unsigned long nr_pending_queries;
|
||||
bool saved_busy_polling;
|
||||
unsigned int saved_polling_guard;
|
||||
bool busy_polling;
|
||||
unsigned int polling_guard;
|
||||
};
|
||||
|
||||
extern struct acpi_ec *first_ec;
|
||||
|
||||
@@ -1617,7 +1617,11 @@ static int cmp_map(const void *m0, const void *m1)
|
||||
const struct nfit_set_info_map *map0 = m0;
|
||||
const struct nfit_set_info_map *map1 = m1;
|
||||
|
||||
return map0->region_offset - map1->region_offset;
|
||||
if (map0->region_offset < map1->region_offset)
|
||||
return -1;
|
||||
else if (map0->region_offset > map1->region_offset)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Retrieve the nth entry referencing this spa */
|
||||
|
||||
@@ -200,6 +200,7 @@ static int acpi_power_get_list_state(struct list_head *list, int *state)
|
||||
return -EINVAL;
|
||||
|
||||
/* The state of the list is 'on' IFF all resources are 'on'. */
|
||||
cur_state = 0;
|
||||
list_for_each_entry(entry, list, node) {
|
||||
struct acpi_power_resource *resource = entry->resource;
|
||||
acpi_handle handle = resource->device.handle;
|
||||
|
||||
@@ -1827,15 +1827,20 @@ static void acpi_bus_attach(struct acpi_device *device)
|
||||
return;
|
||||
|
||||
device->flags.match_driver = true;
|
||||
if (!ret) {
|
||||
ret = device_attach(&device->dev);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
if (!ret && device->pnp.type.platform_id)
|
||||
acpi_default_enumeration(device);
|
||||
if (ret > 0) {
|
||||
acpi_device_set_enumerated(device);
|
||||
goto ok;
|
||||
}
|
||||
|
||||
ret = device_attach(&device->dev);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
if (ret > 0 || !device->pnp.type.platform_id)
|
||||
acpi_device_set_enumerated(device);
|
||||
else
|
||||
acpi_default_enumeration(device);
|
||||
|
||||
ok:
|
||||
list_for_each_entry(child, &device->children, node)
|
||||
acpi_bus_attach(child);
|
||||
|
||||
@@ -54,7 +54,7 @@ struct nbd_device {
|
||||
|
||||
struct mutex tx_lock;
|
||||
struct gendisk *disk;
|
||||
int blksize;
|
||||
loff_t blksize;
|
||||
loff_t bytesize;
|
||||
|
||||
/* protects initialization and shutdown of the socket */
|
||||
@@ -126,7 +126,7 @@ static void nbd_size_update(struct nbd_device *nbd, struct block_device *bdev)
|
||||
}
|
||||
|
||||
static int nbd_size_set(struct nbd_device *nbd, struct block_device *bdev,
|
||||
int blocksize, int nr_blocks)
|
||||
loff_t blocksize, loff_t nr_blocks)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -135,7 +135,7 @@ static int nbd_size_set(struct nbd_device *nbd, struct block_device *bdev,
|
||||
return ret;
|
||||
|
||||
nbd->blksize = blocksize;
|
||||
nbd->bytesize = (loff_t)blocksize * (loff_t)nr_blocks;
|
||||
nbd->bytesize = blocksize * nr_blocks;
|
||||
|
||||
nbd_size_update(nbd, bdev);
|
||||
|
||||
@@ -648,7 +648,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
|
||||
|
||||
case NBD_SET_SIZE:
|
||||
return nbd_size_set(nbd, bdev, nbd->blksize,
|
||||
arg / nbd->blksize);
|
||||
div_s64(arg, nbd->blksize));
|
||||
|
||||
case NBD_SET_SIZE_BLOCKS:
|
||||
return nbd_size_set(nbd, bdev, nbd->blksize, arg);
|
||||
@@ -817,7 +817,7 @@ static int nbd_dev_dbg_init(struct nbd_device *nbd)
|
||||
debugfs_create_file("tasks", 0444, dir, nbd, &nbd_dbg_tasks_ops);
|
||||
debugfs_create_u64("size_bytes", 0444, dir, &nbd->bytesize);
|
||||
debugfs_create_u32("timeout", 0444, dir, &nbd->tag_set.timeout);
|
||||
debugfs_create_u32("blocksize", 0444, dir, &nbd->blksize);
|
||||
debugfs_create_u64("blocksize", 0444, dir, &nbd->blksize);
|
||||
debugfs_create_file("flags", 0444, dir, nbd, &nbd_dbg_flags_ops);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -582,13 +582,13 @@ static int zram_decompress_page(struct zram *zram, char *mem, u32 index)
|
||||
|
||||
if (!handle || zram_test_flag(meta, index, ZRAM_ZERO)) {
|
||||
bit_spin_unlock(ZRAM_ACCESS, &meta->table[index].value);
|
||||
clear_page(mem);
|
||||
memset(mem, 0, PAGE_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmem = zs_map_object(meta->mem_pool, handle, ZS_MM_RO);
|
||||
if (size == PAGE_SIZE) {
|
||||
copy_page(mem, cmem);
|
||||
memcpy(mem, cmem, PAGE_SIZE);
|
||||
} else {
|
||||
struct zcomp_strm *zstrm = zcomp_stream_get(zram->comp);
|
||||
|
||||
@@ -780,7 +780,7 @@ compress_again:
|
||||
|
||||
if ((clen == PAGE_SIZE) && !is_partial_io(bvec)) {
|
||||
src = kmap_atomic(page);
|
||||
copy_page(cmem, src);
|
||||
memcpy(cmem, src, PAGE_SIZE);
|
||||
kunmap_atomic(src);
|
||||
} else {
|
||||
memcpy(cmem, src, clen);
|
||||
|
||||
@@ -60,6 +60,10 @@ static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STRICT_DEVMEM
|
||||
static inline int page_is_allowed(unsigned long pfn)
|
||||
{
|
||||
return devmem_is_allowed(pfn);
|
||||
}
|
||||
static inline int range_is_allowed(unsigned long pfn, unsigned long size)
|
||||
{
|
||||
u64 from = ((u64)pfn) << PAGE_SHIFT;
|
||||
@@ -75,6 +79,10 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
static inline int page_is_allowed(unsigned long pfn)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
static inline int range_is_allowed(unsigned long pfn, unsigned long size)
|
||||
{
|
||||
return 1;
|
||||
@@ -122,23 +130,31 @@ static ssize_t read_mem(struct file *file, char __user *buf,
|
||||
|
||||
while (count > 0) {
|
||||
unsigned long remaining;
|
||||
int allowed;
|
||||
|
||||
sz = size_inside_page(p, count);
|
||||
|
||||
if (!range_is_allowed(p >> PAGE_SHIFT, count))
|
||||
allowed = page_is_allowed(p >> PAGE_SHIFT);
|
||||
if (!allowed)
|
||||
return -EPERM;
|
||||
if (allowed == 2) {
|
||||
/* Show zeros for restricted memory. */
|
||||
remaining = clear_user(buf, sz);
|
||||
} else {
|
||||
/*
|
||||
* On ia64 if a page has been mapped somewhere as
|
||||
* uncached, then it must also be accessed uncached
|
||||
* by the kernel or data corruption may occur.
|
||||
*/
|
||||
ptr = xlate_dev_mem_ptr(p);
|
||||
if (!ptr)
|
||||
return -EFAULT;
|
||||
|
||||
/*
|
||||
* On ia64 if a page has been mapped somewhere as uncached, then
|
||||
* it must also be accessed uncached by the kernel or data
|
||||
* corruption may occur.
|
||||
*/
|
||||
ptr = xlate_dev_mem_ptr(p);
|
||||
if (!ptr)
|
||||
return -EFAULT;
|
||||
remaining = copy_to_user(buf, ptr, sz);
|
||||
|
||||
unxlate_dev_mem_ptr(p, ptr);
|
||||
}
|
||||
|
||||
remaining = copy_to_user(buf, ptr, sz);
|
||||
unxlate_dev_mem_ptr(p, ptr);
|
||||
if (remaining)
|
||||
return -EFAULT;
|
||||
|
||||
@@ -181,30 +197,36 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
|
||||
#endif
|
||||
|
||||
while (count > 0) {
|
||||
int allowed;
|
||||
|
||||
sz = size_inside_page(p, count);
|
||||
|
||||
if (!range_is_allowed(p >> PAGE_SHIFT, sz))
|
||||
allowed = page_is_allowed(p >> PAGE_SHIFT);
|
||||
if (!allowed)
|
||||
return -EPERM;
|
||||
|
||||
/*
|
||||
* On ia64 if a page has been mapped somewhere as uncached, then
|
||||
* it must also be accessed uncached by the kernel or data
|
||||
* corruption may occur.
|
||||
*/
|
||||
ptr = xlate_dev_mem_ptr(p);
|
||||
if (!ptr) {
|
||||
if (written)
|
||||
break;
|
||||
return -EFAULT;
|
||||
}
|
||||
/* Skip actual writing when a page is marked as restricted. */
|
||||
if (allowed == 1) {
|
||||
/*
|
||||
* On ia64 if a page has been mapped somewhere as
|
||||
* uncached, then it must also be accessed uncached
|
||||
* by the kernel or data corruption may occur.
|
||||
*/
|
||||
ptr = xlate_dev_mem_ptr(p);
|
||||
if (!ptr) {
|
||||
if (written)
|
||||
break;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
copied = copy_from_user(ptr, buf, sz);
|
||||
unxlate_dev_mem_ptr(p, ptr);
|
||||
if (copied) {
|
||||
written += sz - copied;
|
||||
if (written)
|
||||
break;
|
||||
return -EFAULT;
|
||||
copied = copy_from_user(ptr, buf, sz);
|
||||
unxlate_dev_mem_ptr(p, ptr);
|
||||
if (copied) {
|
||||
written += sz - copied;
|
||||
if (written)
|
||||
break;
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
buf += sz;
|
||||
|
||||
@@ -1136,6 +1136,8 @@ static int put_chars(u32 vtermno, const char *buf, int count)
|
||||
{
|
||||
struct port *port;
|
||||
struct scatterlist sg[1];
|
||||
void *data;
|
||||
int ret;
|
||||
|
||||
if (unlikely(early_put_chars))
|
||||
return early_put_chars(vtermno, buf, count);
|
||||
@@ -1144,8 +1146,14 @@ static int put_chars(u32 vtermno, const char *buf, int count)
|
||||
if (!port)
|
||||
return -EPIPE;
|
||||
|
||||
sg_init_one(sg, buf, count);
|
||||
return __send_to_port(port, sg, 1, count, (void *)buf, false);
|
||||
data = kmemdup(buf, count, GFP_ATOMIC);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
sg_init_one(sg, data, count);
|
||||
ret = __send_to_port(port, sg, 1, count, data, false);
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -2469,6 +2469,20 @@ EXPORT_SYMBOL_GPL(cpufreq_boost_enabled);
|
||||
*********************************************************************/
|
||||
static enum cpuhp_state hp_online;
|
||||
|
||||
static int cpuhp_cpufreq_online(unsigned int cpu)
|
||||
{
|
||||
cpufreq_online(cpu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpuhp_cpufreq_offline(unsigned int cpu)
|
||||
{
|
||||
cpufreq_offline(cpu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cpufreq_register_driver - register a CPU Frequency driver
|
||||
* @driver_data: A struct cpufreq_driver containing the values#
|
||||
@@ -2531,8 +2545,8 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
|
||||
}
|
||||
|
||||
ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "cpufreq:online",
|
||||
cpufreq_online,
|
||||
cpufreq_offline);
|
||||
cpuhp_cpufreq_online,
|
||||
cpuhp_cpufreq_offline);
|
||||
if (ret < 0)
|
||||
goto err_if_unreg;
|
||||
hp_online = ret;
|
||||
|
||||
@@ -2,6 +2,7 @@ menuconfig DEV_DAX
|
||||
tristate "DAX: direct access to differentiated memory"
|
||||
default m if NVDIMM_DAX
|
||||
depends on TRANSPARENT_HUGEPAGE
|
||||
select SRCU
|
||||
help
|
||||
Support raw access to differentiated (persistence, bandwidth,
|
||||
latency...) memory via an mmap(2) capable character
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "dax.h"
|
||||
|
||||
static dev_t dax_devt;
|
||||
DEFINE_STATIC_SRCU(dax_srcu);
|
||||
static struct class *dax_class;
|
||||
static DEFINE_IDA(dax_minor_ida);
|
||||
static int nr_dax = CONFIG_NR_DEV_DAX;
|
||||
@@ -59,7 +60,7 @@ struct dax_region {
|
||||
* @region - parent region
|
||||
* @dev - device backing the character device
|
||||
* @cdev - core chardev data
|
||||
* @alive - !alive + rcu grace period == no new mappings can be established
|
||||
* @alive - !alive + srcu grace period == no new mappings can be established
|
||||
* @id - child id in the region
|
||||
* @num_resources - number of physical address extents in this device
|
||||
* @res - array of physical address ranges
|
||||
@@ -437,7 +438,7 @@ static int __dax_dev_pmd_fault(struct dax_dev *dax_dev,
|
||||
static int dax_dev_pmd_fault(struct vm_area_struct *vma, unsigned long addr,
|
||||
pmd_t *pmd, unsigned int flags)
|
||||
{
|
||||
int rc;
|
||||
int rc, id;
|
||||
struct file *filp = vma->vm_file;
|
||||
struct dax_dev *dax_dev = filp->private_data;
|
||||
|
||||
@@ -445,9 +446,9 @@ static int dax_dev_pmd_fault(struct vm_area_struct *vma, unsigned long addr,
|
||||
current->comm, (flags & FAULT_FLAG_WRITE)
|
||||
? "write" : "read", vma->vm_start, vma->vm_end);
|
||||
|
||||
rcu_read_lock();
|
||||
id = srcu_read_lock(&dax_srcu);
|
||||
rc = __dax_dev_pmd_fault(dax_dev, vma, addr, pmd, flags);
|
||||
rcu_read_unlock();
|
||||
srcu_read_unlock(&dax_srcu, id);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -563,11 +564,11 @@ static void unregister_dax_dev(void *dev)
|
||||
* Note, rcu is not protecting the liveness of dax_dev, rcu is
|
||||
* ensuring that any fault handlers that might have seen
|
||||
* dax_dev->alive == true, have completed. Any fault handlers
|
||||
* that start after synchronize_rcu() has started will abort
|
||||
* that start after synchronize_srcu() has started will abort
|
||||
* upon seeing dax_dev->alive == false.
|
||||
*/
|
||||
dax_dev->alive = false;
|
||||
synchronize_rcu();
|
||||
synchronize_srcu(&dax_srcu);
|
||||
unmap_mapping_range(dax_dev->inode->i_mapping, 0, 0, 1);
|
||||
cdev_del(cdev);
|
||||
device_unregister(dev);
|
||||
|
||||
@@ -149,7 +149,8 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si,
|
||||
|
||||
status = __gop_query32(sys_table_arg, gop32, &info, &size,
|
||||
¤t_fb_base);
|
||||
if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
|
||||
if (status == EFI_SUCCESS && (!first_gop || conout_found) &&
|
||||
info->pixel_format != PIXEL_BLT_ONLY) {
|
||||
/*
|
||||
* Systems that use the UEFI Console Splitter may
|
||||
* provide multiple GOP devices, not all of which are
|
||||
@@ -266,7 +267,8 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si,
|
||||
|
||||
status = __gop_query64(sys_table_arg, gop64, &info, &size,
|
||||
¤t_fb_base);
|
||||
if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
|
||||
if (status == EFI_SUCCESS && (!first_gop || conout_found) &&
|
||||
info->pixel_format != PIXEL_BLT_ONLY) {
|
||||
/*
|
||||
* Systems that use the UEFI Console Splitter may
|
||||
* provide multiple GOP devices, not all of which are
|
||||
|
||||
@@ -1305,7 +1305,7 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
|
||||
if (!fence) {
|
||||
event_free(gpu, event);
|
||||
ret = -ENOMEM;
|
||||
goto out_pm_put;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
gpu->event[event].fence = fence;
|
||||
@@ -1345,6 +1345,7 @@ int etnaviv_gpu_submit(struct etnaviv_gpu *gpu,
|
||||
hangcheck_timer_reset(gpu);
|
||||
ret = 0;
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&gpu->lock);
|
||||
|
||||
out_pm_put:
|
||||
|
||||
@@ -714,7 +714,7 @@ nv4a_chipset = {
|
||||
.i2c = nv04_i2c_new,
|
||||
.imem = nv40_instmem_new,
|
||||
.mc = nv44_mc_new,
|
||||
.mmu = nv44_mmu_new,
|
||||
.mmu = nv04_mmu_new,
|
||||
.pci = nv40_pci_new,
|
||||
.therm = nv40_therm_new,
|
||||
.timer = nv41_timer_new,
|
||||
|
||||
@@ -433,8 +433,6 @@ nv50_disp_dptmds_war(struct nvkm_device *device)
|
||||
case 0x94:
|
||||
case 0x96:
|
||||
case 0x98:
|
||||
case 0xaa:
|
||||
case 0xac:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -198,7 +198,7 @@ nv31_mpeg_intr(struct nvkm_engine *engine)
|
||||
}
|
||||
|
||||
if (type == 0x00000010) {
|
||||
if (!nv31_mpeg_mthd(mpeg, mthd, data))
|
||||
if (nv31_mpeg_mthd(mpeg, mthd, data))
|
||||
show &= ~0x01000000;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +172,7 @@ nv44_mpeg_intr(struct nvkm_engine *engine)
|
||||
}
|
||||
|
||||
if (type == 0x00000010) {
|
||||
if (!nv44_mpeg_mthd(subdev->device, mthd, data))
|
||||
if (nv44_mpeg_mthd(subdev->device, mthd, data))
|
||||
show &= ~0x01000000;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,6 +201,7 @@ static const struct xpad_device {
|
||||
{ 0x1430, 0x8888, "TX6500+ Dance Pad (first generation)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
|
||||
{ 0x146b, 0x0601, "BigBen Interactive XBOX 360 Controller", 0, XTYPE_XBOX360 },
|
||||
{ 0x1532, 0x0037, "Razer Sabertooth", 0, XTYPE_XBOX360 },
|
||||
{ 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE },
|
||||
{ 0x15e4, 0x3f00, "Power A Mini Pro Elite", 0, XTYPE_XBOX360 },
|
||||
{ 0x15e4, 0x3f0a, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
|
||||
{ 0x15e4, 0x3f10, "Batarang Xbox 360 controller", 0, XTYPE_XBOX360 },
|
||||
@@ -329,6 +330,7 @@ static struct usb_device_id xpad_table[] = {
|
||||
XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */
|
||||
XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA Controllers */
|
||||
XPAD_XBOX360_VENDOR(0x1532), /* Razer Sabertooth */
|
||||
XPAD_XBOXONE_VENDOR(0x1532), /* Razer Wildcat */
|
||||
XPAD_XBOX360_VENDOR(0x15e4), /* Numark X-Box 360 controllers */
|
||||
XPAD_XBOX360_VENDOR(0x162e), /* Joytech X-Box 360 controllers */
|
||||
{ }
|
||||
|
||||
@@ -1118,6 +1118,7 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse,
|
||||
* Asus UX32VD 0x361f02 00, 15, 0e clickpad
|
||||
* Avatar AVIU-145A2 0x361f00 ? clickpad
|
||||
* Fujitsu LIFEBOOK E544 0x470f00 d0, 12, 09 2 hw buttons
|
||||
* Fujitsu LIFEBOOK E547 0x470f00 50, 12, 09 2 hw buttons
|
||||
* Fujitsu LIFEBOOK E554 0x570f01 40, 14, 0c 2 hw buttons
|
||||
* Fujitsu T725 0x470f01 05, 12, 09 2 hw buttons
|
||||
* Fujitsu H730 0x570f00 c0, 14, 0c 3 hw buttons (**)
|
||||
@@ -1523,6 +1524,13 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E544"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Fujitsu LIFEBOOK E547 does not work with crc_enabled == 0 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E547"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Fujitsu LIFEBOOK E554 does not work with crc_enabled == 0 */
|
||||
.matches = {
|
||||
|
||||
@@ -685,6 +685,13 @@ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "20046"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Clevo P650RS, 650RP6, Sager NP8152-S, and others */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Notebook"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "P65xRP"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@@ -230,6 +230,8 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
raw_spin_lock_init(&cd->rlock);
|
||||
|
||||
cd->gpc_base = of_iomap(node, 0);
|
||||
if (!cd->gpc_base) {
|
||||
pr_err("fsl-gpcv2: unable to map gpc registers\n");
|
||||
|
||||
@@ -1013,8 +1013,8 @@ EXPORT_SYMBOL(dvb_usbv2_probe);
|
||||
void dvb_usbv2_disconnect(struct usb_interface *intf)
|
||||
{
|
||||
struct dvb_usb_device *d = usb_get_intfdata(intf);
|
||||
const char *name = d->name;
|
||||
struct device dev = d->udev->dev;
|
||||
const char *devname = kstrdup(dev_name(&d->udev->dev), GFP_KERNEL);
|
||||
const char *drvname = d->name;
|
||||
|
||||
dev_dbg(&d->udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
|
||||
intf->cur_altsetting->desc.bInterfaceNumber);
|
||||
@@ -1024,8 +1024,9 @@ void dvb_usbv2_disconnect(struct usb_interface *intf)
|
||||
|
||||
dvb_usbv2_exit(d);
|
||||
|
||||
dev_info(&dev, "%s: '%s' successfully deinitialized and disconnected\n",
|
||||
KBUILD_MODNAME, name);
|
||||
pr_info("%s: '%s:%s' successfully deinitialized and disconnected\n",
|
||||
KBUILD_MODNAME, drvname, devname);
|
||||
kfree(devname);
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_usbv2_disconnect);
|
||||
|
||||
|
||||
@@ -59,23 +59,24 @@ static int cxusb_ctrl_msg(struct dvb_usb_device *d,
|
||||
u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
|
||||
{
|
||||
struct cxusb_state *st = d->priv;
|
||||
int ret, wo;
|
||||
int ret;
|
||||
|
||||
if (1 + wlen > MAX_XFER_SIZE) {
|
||||
warn("i2c wr: len=%d is too big!\n", wlen);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
wo = (rbuf == NULL || rlen == 0); /* write-only */
|
||||
if (rlen > MAX_XFER_SIZE) {
|
||||
warn("i2c rd: len=%d is too big!\n", rlen);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
mutex_lock(&d->data_mutex);
|
||||
st->data[0] = cmd;
|
||||
memcpy(&st->data[1], wbuf, wlen);
|
||||
if (wo)
|
||||
ret = dvb_usb_generic_write(d, st->data, 1 + wlen);
|
||||
else
|
||||
ret = dvb_usb_generic_rw(d, st->data, 1 + wlen,
|
||||
rbuf, rlen, 0);
|
||||
ret = dvb_usb_generic_rw(d, st->data, 1 + wlen, st->data, rlen, 0);
|
||||
if (!ret && rbuf && rlen)
|
||||
memcpy(rbuf, st->data, rlen);
|
||||
|
||||
mutex_unlock(&d->data_mutex);
|
||||
return ret;
|
||||
|
||||
@@ -35,42 +35,51 @@ static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 le
|
||||
|
||||
int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type)
|
||||
{
|
||||
struct hexline hx;
|
||||
u8 reset;
|
||||
int ret,pos=0;
|
||||
struct hexline *hx;
|
||||
u8 *buf;
|
||||
int ret, pos = 0;
|
||||
u16 cpu_cs_register = cypress[type].cpu_cs_register;
|
||||
|
||||
buf = kmalloc(sizeof(*hx), GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
hx = (struct hexline *)buf;
|
||||
|
||||
/* stop the CPU */
|
||||
reset = 1;
|
||||
if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
|
||||
buf[0] = 1;
|
||||
if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1)
|
||||
err("could not stop the USB controller CPU.");
|
||||
|
||||
while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) {
|
||||
deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk);
|
||||
ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len);
|
||||
while ((ret = dvb_usb_get_hexline(fw, hx, &pos)) > 0) {
|
||||
deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n", hx->addr, hx->len, hx->chk);
|
||||
ret = usb_cypress_writemem(udev, hx->addr, hx->data, hx->len);
|
||||
|
||||
if (ret != hx.len) {
|
||||
if (ret != hx->len) {
|
||||
err("error while transferring firmware "
|
||||
"(transferred size: %d, block size: %d)",
|
||||
ret,hx.len);
|
||||
ret, hx->len);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret < 0) {
|
||||
err("firmware download failed at %d with %d",pos,ret);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* restart the CPU */
|
||||
reset = 0;
|
||||
if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
|
||||
buf[0] = 0;
|
||||
if (usb_cypress_writemem(udev, cpu_cs_register, buf, 1) != 1) {
|
||||
err("could not restart the USB controller CPU.");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
} else
|
||||
ret = -EIO;
|
||||
|
||||
kfree(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(usb_cypress_load_firmware);
|
||||
|
||||
@@ -96,9 +96,11 @@ static int uid_cputime_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct uid_entry *uid_entry;
|
||||
struct task_struct *task, *temp;
|
||||
struct user_namespace *user_ns = current_user_ns();
|
||||
cputime_t utime;
|
||||
cputime_t stime;
|
||||
unsigned long bkt;
|
||||
uid_t uid;
|
||||
|
||||
rt_mutex_lock(&uid_lock);
|
||||
|
||||
@@ -109,14 +111,13 @@ static int uid_cputime_show(struct seq_file *m, void *v)
|
||||
|
||||
read_lock(&tasklist_lock);
|
||||
do_each_thread(temp, task) {
|
||||
uid_entry = find_or_register_uid(from_kuid_munged(
|
||||
current_user_ns(), task_uid(task)));
|
||||
uid = from_kuid_munged(user_ns, task_uid(task));
|
||||
uid_entry = find_or_register_uid(uid);
|
||||
if (!uid_entry) {
|
||||
read_unlock(&tasklist_lock);
|
||||
rt_mutex_unlock(&uid_lock);
|
||||
pr_err("%s: failed to find the uid_entry for uid %d\n",
|
||||
__func__, from_kuid_munged(current_user_ns(),
|
||||
task_uid(task)));
|
||||
__func__, uid);
|
||||
return -ENOMEM;
|
||||
}
|
||||
task_cputime_adjusted(task, &utime, &stime);
|
||||
|
||||
@@ -830,6 +830,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
|
||||
|
||||
switch (uhs) {
|
||||
case MMC_TIMING_UHS_SDR50:
|
||||
case MMC_TIMING_UHS_DDR50:
|
||||
pinctrl = imx_data->pins_100mhz;
|
||||
break;
|
||||
case MMC_TIMING_UHS_SDR104:
|
||||
|
||||
@@ -524,9 +524,7 @@ static const struct sdhci_ops sdhci_msm_ops = {
|
||||
static const struct sdhci_pltfm_data sdhci_msm_pdata = {
|
||||
.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
|
||||
SDHCI_QUIRK_NO_CARD_NO_RESET |
|
||||
SDHCI_QUIRK_SINGLE_POWER_WRITE |
|
||||
SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
|
||||
.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
|
||||
SDHCI_QUIRK_SINGLE_POWER_WRITE,
|
||||
.ops = &sdhci_msm_ops,
|
||||
};
|
||||
|
||||
|
||||
@@ -148,11 +148,11 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol,
|
||||
return err;
|
||||
}
|
||||
|
||||
if (bytes == 0) {
|
||||
err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
|
||||
if (err)
|
||||
return err;
|
||||
err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (bytes == 0) {
|
||||
err = clear_update_marker(ubi, vol, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -557,7 +557,7 @@ static int ifi_canfd_poll(struct napi_struct *napi, int quota)
|
||||
int work_done = 0;
|
||||
|
||||
u32 stcmd = readl(priv->base + IFI_CANFD_STCMD);
|
||||
u32 rxstcmd = readl(priv->base + IFI_CANFD_STCMD);
|
||||
u32 rxstcmd = readl(priv->base + IFI_CANFD_RXSTCMD);
|
||||
u32 errctr = readl(priv->base + IFI_CANFD_ERROR_CTR);
|
||||
|
||||
/* Handle bus state changes */
|
||||
|
||||
@@ -740,13 +740,18 @@ static const struct net_device_ops gs_usb_netdev_ops = {
|
||||
static int gs_usb_set_identify(struct net_device *netdev, bool do_identify)
|
||||
{
|
||||
struct gs_can *dev = netdev_priv(netdev);
|
||||
struct gs_identify_mode imode;
|
||||
struct gs_identify_mode *imode;
|
||||
int rc;
|
||||
|
||||
imode = kmalloc(sizeof(*imode), GFP_KERNEL);
|
||||
|
||||
if (!imode)
|
||||
return -ENOMEM;
|
||||
|
||||
if (do_identify)
|
||||
imode.mode = GS_CAN_IDENTIFY_ON;
|
||||
imode->mode = GS_CAN_IDENTIFY_ON;
|
||||
else
|
||||
imode.mode = GS_CAN_IDENTIFY_OFF;
|
||||
imode->mode = GS_CAN_IDENTIFY_OFF;
|
||||
|
||||
rc = usb_control_msg(interface_to_usbdev(dev->iface),
|
||||
usb_sndctrlpipe(interface_to_usbdev(dev->iface),
|
||||
@@ -756,10 +761,12 @@ static int gs_usb_set_identify(struct net_device *netdev, bool do_identify)
|
||||
USB_RECIP_INTERFACE,
|
||||
dev->channel,
|
||||
0,
|
||||
&imode,
|
||||
sizeof(imode),
|
||||
imode,
|
||||
sizeof(*imode),
|
||||
100);
|
||||
|
||||
kfree(imode);
|
||||
|
||||
return (rc > 0) ? 0 : rc;
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
#define MLX5E_VALID_NUM_MTTS(num_mtts) (MLX5_MTT_OCTW(num_mtts) <= U16_MAX)
|
||||
|
||||
#define MLX5_UMR_ALIGN (2048)
|
||||
#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (128)
|
||||
#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD (256)
|
||||
|
||||
#define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ (64 * 1024)
|
||||
#define MLX5E_DEFAULT_LRO_TIMEOUT 32
|
||||
|
||||
@@ -563,6 +563,7 @@ int mlx5e_ethtool_get_all_flows(struct mlx5e_priv *priv, struct ethtool_rxnfc *i
|
||||
int idx = 0;
|
||||
int err = 0;
|
||||
|
||||
info->data = MAX_NUM_OF_ETHTOOL_RULES;
|
||||
while ((!err || err == -ENOENT) && idx < info->rule_cnt) {
|
||||
err = mlx5e_ethtool_get_flow(priv, info, location);
|
||||
if (!err)
|
||||
|
||||
@@ -294,7 +294,7 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
|
||||
struct netdev_notifier_changeupper_info *info)
|
||||
{
|
||||
struct net_device *upper = info->upper_dev, *ndev_tmp;
|
||||
struct netdev_lag_upper_info *lag_upper_info;
|
||||
struct netdev_lag_upper_info *lag_upper_info = NULL;
|
||||
bool is_bonded;
|
||||
int bond_status = 0;
|
||||
int num_slaves = 0;
|
||||
@@ -303,7 +303,8 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
|
||||
if (!netif_is_lag_master(upper))
|
||||
return 0;
|
||||
|
||||
lag_upper_info = info->upper_info;
|
||||
if (info->linking)
|
||||
lag_upper_info = info->upper_info;
|
||||
|
||||
/* The event may still be of interest if the slave does not belong to
|
||||
* us, but is enslaved to a master which has one or more of our netdevs
|
||||
|
||||
@@ -966,7 +966,7 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
|
||||
if (err) {
|
||||
dev_err(&dev->pdev->dev, "Firmware over %d MS in initializing state, aborting\n",
|
||||
FW_INIT_TIMEOUT_MILI);
|
||||
goto out_err;
|
||||
goto err_cmd_cleanup;
|
||||
}
|
||||
|
||||
err = mlx5_core_enable_hca(dev, 0);
|
||||
|
||||
@@ -1059,12 +1059,70 @@ static struct mdiobb_ops bb_ops = {
|
||||
.get_mdio_data = sh_get_mdio,
|
||||
};
|
||||
|
||||
/* free Tx skb function */
|
||||
static int sh_eth_tx_free(struct net_device *ndev, bool sent_only)
|
||||
{
|
||||
struct sh_eth_private *mdp = netdev_priv(ndev);
|
||||
struct sh_eth_txdesc *txdesc;
|
||||
int free_num = 0;
|
||||
int entry;
|
||||
bool sent;
|
||||
|
||||
for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
|
||||
entry = mdp->dirty_tx % mdp->num_tx_ring;
|
||||
txdesc = &mdp->tx_ring[entry];
|
||||
sent = !(txdesc->status & cpu_to_le32(TD_TACT));
|
||||
if (sent_only && !sent)
|
||||
break;
|
||||
/* TACT bit must be checked before all the following reads */
|
||||
dma_rmb();
|
||||
netif_info(mdp, tx_done, ndev,
|
||||
"tx entry %d status 0x%08x\n",
|
||||
entry, le32_to_cpu(txdesc->status));
|
||||
/* Free the original skb. */
|
||||
if (mdp->tx_skbuff[entry]) {
|
||||
dma_unmap_single(&ndev->dev, le32_to_cpu(txdesc->addr),
|
||||
le32_to_cpu(txdesc->len) >> 16,
|
||||
DMA_TO_DEVICE);
|
||||
dev_kfree_skb_irq(mdp->tx_skbuff[entry]);
|
||||
mdp->tx_skbuff[entry] = NULL;
|
||||
free_num++;
|
||||
}
|
||||
txdesc->status = cpu_to_le32(TD_TFP);
|
||||
if (entry >= mdp->num_tx_ring - 1)
|
||||
txdesc->status |= cpu_to_le32(TD_TDLE);
|
||||
|
||||
if (sent) {
|
||||
ndev->stats.tx_packets++;
|
||||
ndev->stats.tx_bytes += le32_to_cpu(txdesc->len) >> 16;
|
||||
}
|
||||
}
|
||||
return free_num;
|
||||
}
|
||||
|
||||
/* free skb and descriptor buffer */
|
||||
static void sh_eth_ring_free(struct net_device *ndev)
|
||||
{
|
||||
struct sh_eth_private *mdp = netdev_priv(ndev);
|
||||
int ringsize, i;
|
||||
|
||||
if (mdp->rx_ring) {
|
||||
for (i = 0; i < mdp->num_rx_ring; i++) {
|
||||
if (mdp->rx_skbuff[i]) {
|
||||
struct sh_eth_rxdesc *rxdesc = &mdp->rx_ring[i];
|
||||
|
||||
dma_unmap_single(&ndev->dev,
|
||||
le32_to_cpu(rxdesc->addr),
|
||||
ALIGN(mdp->rx_buf_sz, 32),
|
||||
DMA_FROM_DEVICE);
|
||||
}
|
||||
}
|
||||
ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
|
||||
dma_free_coherent(NULL, ringsize, mdp->rx_ring,
|
||||
mdp->rx_desc_dma);
|
||||
mdp->rx_ring = NULL;
|
||||
}
|
||||
|
||||
/* Free Rx skb ringbuffer */
|
||||
if (mdp->rx_skbuff) {
|
||||
for (i = 0; i < mdp->num_rx_ring; i++)
|
||||
@@ -1073,27 +1131,18 @@ static void sh_eth_ring_free(struct net_device *ndev)
|
||||
kfree(mdp->rx_skbuff);
|
||||
mdp->rx_skbuff = NULL;
|
||||
|
||||
/* Free Tx skb ringbuffer */
|
||||
if (mdp->tx_skbuff) {
|
||||
for (i = 0; i < mdp->num_tx_ring; i++)
|
||||
dev_kfree_skb(mdp->tx_skbuff[i]);
|
||||
}
|
||||
kfree(mdp->tx_skbuff);
|
||||
mdp->tx_skbuff = NULL;
|
||||
|
||||
if (mdp->rx_ring) {
|
||||
ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring;
|
||||
dma_free_coherent(NULL, ringsize, mdp->rx_ring,
|
||||
mdp->rx_desc_dma);
|
||||
mdp->rx_ring = NULL;
|
||||
}
|
||||
|
||||
if (mdp->tx_ring) {
|
||||
sh_eth_tx_free(ndev, false);
|
||||
|
||||
ringsize = sizeof(struct sh_eth_txdesc) * mdp->num_tx_ring;
|
||||
dma_free_coherent(NULL, ringsize, mdp->tx_ring,
|
||||
mdp->tx_desc_dma);
|
||||
mdp->tx_ring = NULL;
|
||||
}
|
||||
|
||||
/* Free Tx skb ringbuffer */
|
||||
kfree(mdp->tx_skbuff);
|
||||
mdp->tx_skbuff = NULL;
|
||||
}
|
||||
|
||||
/* format skb and descriptor buffer */
|
||||
@@ -1341,43 +1390,6 @@ static void sh_eth_dev_exit(struct net_device *ndev)
|
||||
update_mac_address(ndev);
|
||||
}
|
||||
|
||||
/* free Tx skb function */
|
||||
static int sh_eth_txfree(struct net_device *ndev)
|
||||
{
|
||||
struct sh_eth_private *mdp = netdev_priv(ndev);
|
||||
struct sh_eth_txdesc *txdesc;
|
||||
int free_num = 0;
|
||||
int entry;
|
||||
|
||||
for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
|
||||
entry = mdp->dirty_tx % mdp->num_tx_ring;
|
||||
txdesc = &mdp->tx_ring[entry];
|
||||
if (txdesc->status & cpu_to_le32(TD_TACT))
|
||||
break;
|
||||
/* TACT bit must be checked before all the following reads */
|
||||
dma_rmb();
|
||||
netif_info(mdp, tx_done, ndev,
|
||||
"tx entry %d status 0x%08x\n",
|
||||
entry, le32_to_cpu(txdesc->status));
|
||||
/* Free the original skb. */
|
||||
if (mdp->tx_skbuff[entry]) {
|
||||
dma_unmap_single(&ndev->dev, le32_to_cpu(txdesc->addr),
|
||||
le32_to_cpu(txdesc->len) >> 16,
|
||||
DMA_TO_DEVICE);
|
||||
dev_kfree_skb_irq(mdp->tx_skbuff[entry]);
|
||||
mdp->tx_skbuff[entry] = NULL;
|
||||
free_num++;
|
||||
}
|
||||
txdesc->status = cpu_to_le32(TD_TFP);
|
||||
if (entry >= mdp->num_tx_ring - 1)
|
||||
txdesc->status |= cpu_to_le32(TD_TDLE);
|
||||
|
||||
ndev->stats.tx_packets++;
|
||||
ndev->stats.tx_bytes += le32_to_cpu(txdesc->len) >> 16;
|
||||
}
|
||||
return free_num;
|
||||
}
|
||||
|
||||
/* Packet receive function */
|
||||
static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
|
||||
{
|
||||
@@ -1620,7 +1632,7 @@ ignore_link:
|
||||
intr_status, mdp->cur_tx, mdp->dirty_tx,
|
||||
(u32)ndev->state, edtrr);
|
||||
/* dirty buffer free */
|
||||
sh_eth_txfree(ndev);
|
||||
sh_eth_tx_free(ndev, true);
|
||||
|
||||
/* SH7712 BUG */
|
||||
if (edtrr ^ sh_eth_get_edtrr_trns(mdp)) {
|
||||
@@ -1679,7 +1691,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
|
||||
/* Clear Tx interrupts */
|
||||
sh_eth_write(ndev, intr_status & cd->tx_check, EESR);
|
||||
|
||||
sh_eth_txfree(ndev);
|
||||
sh_eth_tx_free(ndev, true);
|
||||
netif_wake_queue(ndev);
|
||||
}
|
||||
|
||||
@@ -2307,7 +2319,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
|
||||
spin_lock_irqsave(&mdp->lock, flags);
|
||||
if ((mdp->cur_tx - mdp->dirty_tx) >= (mdp->num_tx_ring - 4)) {
|
||||
if (!sh_eth_txfree(ndev)) {
|
||||
if (!sh_eth_tx_free(ndev, true)) {
|
||||
netif_warn(mdp, tx_queued, ndev, "TxFD exhausted.\n");
|
||||
netif_stop_queue(ndev);
|
||||
spin_unlock_irqrestore(&mdp->lock, flags);
|
||||
|
||||
@@ -2709,7 +2709,7 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
#define MACSEC_FEATURES \
|
||||
(NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST)
|
||||
(NETIF_F_SG | NETIF_F_HIGHDMA)
|
||||
static struct lock_class_key macsec_netdev_addr_lock_key;
|
||||
|
||||
static int macsec_dev_init(struct net_device *dev)
|
||||
|
||||
@@ -1140,6 +1140,7 @@ static int macvlan_port_create(struct net_device *dev)
|
||||
static void macvlan_port_destroy(struct net_device *dev)
|
||||
{
|
||||
struct macvlan_port *port = macvlan_port_get_rtnl(dev);
|
||||
struct sk_buff *skb;
|
||||
|
||||
dev->priv_flags &= ~IFF_MACVLAN_PORT;
|
||||
netdev_rx_handler_unregister(dev);
|
||||
@@ -1148,7 +1149,15 @@ static void macvlan_port_destroy(struct net_device *dev)
|
||||
* but we need to cancel it and purge left skbs if any.
|
||||
*/
|
||||
cancel_work_sync(&port->bc_work);
|
||||
__skb_queue_purge(&port->bc_queue);
|
||||
|
||||
while ((skb = __skb_dequeue(&port->bc_queue))) {
|
||||
const struct macvlan_dev *src = MACVLAN_SKB_CB(skb)->src;
|
||||
|
||||
if (src)
|
||||
dev_put(src->dev);
|
||||
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
kfree_rcu(port, rcu);
|
||||
}
|
||||
|
||||
@@ -1438,8 +1438,6 @@ static bool dp83640_rxtstamp(struct phy_device *phydev,
|
||||
skb_info->tmo = jiffies + SKB_TIMESTAMP_TIMEOUT;
|
||||
skb_queue_tail(&dp83640->rx_queue, skb);
|
||||
schedule_delayed_work(&dp83640->ts_work, SKB_TIMESTAMP_TIMEOUT);
|
||||
} else {
|
||||
netif_rx_ni(skb);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -552,16 +552,18 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
|
||||
EXPORT_SYMBOL(phy_mii_ioctl);
|
||||
|
||||
/**
|
||||
* phy_start_aneg - start auto-negotiation for this PHY device
|
||||
* phy_start_aneg_priv - start auto-negotiation for this PHY device
|
||||
* @phydev: the phy_device struct
|
||||
* @sync: indicate whether we should wait for the workqueue cancelation
|
||||
*
|
||||
* Description: Sanitizes the settings (if we're not autonegotiating
|
||||
* them), and then calls the driver's config_aneg function.
|
||||
* If the PHYCONTROL Layer is operating, we change the state to
|
||||
* reflect the beginning of Auto-negotiation or forcing.
|
||||
*/
|
||||
int phy_start_aneg(struct phy_device *phydev)
|
||||
static int phy_start_aneg_priv(struct phy_device *phydev, bool sync)
|
||||
{
|
||||
bool trigger = 0;
|
||||
int err;
|
||||
|
||||
mutex_lock(&phydev->lock);
|
||||
@@ -586,10 +588,40 @@ int phy_start_aneg(struct phy_device *phydev)
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-schedule a PHY state machine to check PHY status because
|
||||
* negotiation may already be done and aneg interrupt may not be
|
||||
* generated.
|
||||
*/
|
||||
if (phy_interrupt_is_valid(phydev) && (phydev->state == PHY_AN)) {
|
||||
err = phy_aneg_done(phydev);
|
||||
if (err > 0) {
|
||||
trigger = true;
|
||||
err = 0;
|
||||
}
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&phydev->lock);
|
||||
|
||||
if (trigger)
|
||||
phy_trigger_machine(phydev, sync);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* phy_start_aneg - start auto-negotiation for this PHY device
|
||||
* @phydev: the phy_device struct
|
||||
*
|
||||
* Description: Sanitizes the settings (if we're not autonegotiating
|
||||
* them), and then calls the driver's config_aneg function.
|
||||
* If the PHYCONTROL Layer is operating, we change the state to
|
||||
* reflect the beginning of Auto-negotiation or forcing.
|
||||
*/
|
||||
int phy_start_aneg(struct phy_device *phydev)
|
||||
{
|
||||
return phy_start_aneg_priv(phydev, true);
|
||||
}
|
||||
EXPORT_SYMBOL(phy_start_aneg);
|
||||
|
||||
/**
|
||||
@@ -617,7 +649,7 @@ void phy_start_machine(struct phy_device *phydev)
|
||||
* state machine runs.
|
||||
*/
|
||||
|
||||
static void phy_trigger_machine(struct phy_device *phydev, bool sync)
|
||||
void phy_trigger_machine(struct phy_device *phydev, bool sync)
|
||||
{
|
||||
if (sync)
|
||||
cancel_delayed_work_sync(&phydev->state_queue);
|
||||
@@ -639,7 +671,7 @@ void phy_stop_machine(struct phy_device *phydev)
|
||||
cancel_delayed_work_sync(&phydev->state_queue);
|
||||
|
||||
mutex_lock(&phydev->lock);
|
||||
if (phydev->state > PHY_UP)
|
||||
if (phydev->state > PHY_UP && phydev->state != PHY_HALTED)
|
||||
phydev->state = PHY_UP;
|
||||
mutex_unlock(&phydev->lock);
|
||||
}
|
||||
@@ -1100,7 +1132,7 @@ void phy_state_machine(struct work_struct *work)
|
||||
mutex_unlock(&phydev->lock);
|
||||
|
||||
if (needs_aneg)
|
||||
err = phy_start_aneg(phydev);
|
||||
err = phy_start_aneg_priv(phydev, false);
|
||||
else if (do_suspend)
|
||||
phy_suspend(phydev);
|
||||
|
||||
|
||||
@@ -206,7 +206,9 @@ static void pppolac_xmit_core(struct work_struct *delivery_work)
|
||||
while ((skb = skb_dequeue(&delivery_queue))) {
|
||||
struct sock *sk_udp = skb->sk;
|
||||
struct kvec iov = {.iov_base = skb->data, .iov_len = skb->len};
|
||||
struct msghdr msg = { 0 };
|
||||
struct msghdr msg = {
|
||||
.msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT,
|
||||
};
|
||||
|
||||
iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &iov, 1,
|
||||
skb->len);
|
||||
|
||||
@@ -189,7 +189,9 @@ static void pppopns_xmit_core(struct work_struct *delivery_work)
|
||||
while ((skb = skb_dequeue(&delivery_queue))) {
|
||||
struct sock *sk_raw = skb->sk;
|
||||
struct kvec iov = {.iov_base = skb->data, .iov_len = skb->len};
|
||||
struct msghdr msg = { 0 };
|
||||
struct msghdr msg = {
|
||||
.msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT,
|
||||
};
|
||||
|
||||
iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &iov, 1,
|
||||
skb->len);
|
||||
|
||||
@@ -1124,7 +1124,7 @@ static int vrf_fib_rule(const struct net_device *dev, __u8 family, bool add_it)
|
||||
goto nla_put_failure;
|
||||
|
||||
/* rule only needs to appear once */
|
||||
nlh->nlmsg_flags &= NLM_F_EXCL;
|
||||
nlh->nlmsg_flags |= NLM_F_EXCL;
|
||||
|
||||
frh = nlmsg_data(nlh);
|
||||
memset(frh, 0, sizeof(*frh));
|
||||
|
||||
@@ -528,6 +528,9 @@ int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_h
|
||||
if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK))
|
||||
return 0;
|
||||
|
||||
if (!spec_priv->rfs_chan_spec_scan)
|
||||
return 1;
|
||||
|
||||
/* Output buffers are full, no need to process anything
|
||||
* since there is no space to put the result anyway
|
||||
*/
|
||||
@@ -1072,7 +1075,7 @@ static struct rchan_callbacks rfs_spec_scan_cb = {
|
||||
|
||||
void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS)) {
|
||||
if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS) && spec_priv->rfs_chan_spec_scan) {
|
||||
relay_close(spec_priv->rfs_chan_spec_scan);
|
||||
spec_priv->rfs_chan_spec_scan = NULL;
|
||||
}
|
||||
@@ -1086,6 +1089,9 @@ void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv,
|
||||
debugfs_phy,
|
||||
1024, 256, &rfs_spec_scan_cb,
|
||||
NULL);
|
||||
if (!spec_priv->rfs_chan_spec_scan)
|
||||
return;
|
||||
|
||||
debugfs_create_file("spectral_scan_ctl",
|
||||
S_IRUSR | S_IWUSR,
|
||||
debugfs_phy, spec_priv,
|
||||
|
||||
@@ -934,8 +934,14 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
|
||||
rc = nd_desc->ndctl(nd_desc, nvdimm, cmd, buf, buf_len, NULL);
|
||||
if (rc < 0)
|
||||
goto out_unlock;
|
||||
nvdimm_bus_unlock(&nvdimm_bus->dev);
|
||||
|
||||
if (copy_to_user(p, buf, buf_len))
|
||||
rc = -EFAULT;
|
||||
|
||||
vfree(buf);
|
||||
return rc;
|
||||
|
||||
out_unlock:
|
||||
nvdimm_bus_unlock(&nvdimm_bus->dev);
|
||||
out:
|
||||
|
||||
@@ -388,7 +388,7 @@ EXPORT_SYMBOL_GPL(nvdimm_create);
|
||||
|
||||
int alias_dpa_busy(struct device *dev, void *data)
|
||||
{
|
||||
resource_size_t map_end, blk_start, new, busy;
|
||||
resource_size_t map_end, blk_start, new;
|
||||
struct blk_alloc_info *info = data;
|
||||
struct nd_mapping *nd_mapping;
|
||||
struct nd_region *nd_region;
|
||||
@@ -429,29 +429,19 @@ int alias_dpa_busy(struct device *dev, void *data)
|
||||
retry:
|
||||
/*
|
||||
* Find the free dpa from the end of the last pmem allocation to
|
||||
* the end of the interleave-set mapping that is not already
|
||||
* covered by a blk allocation.
|
||||
* the end of the interleave-set mapping.
|
||||
*/
|
||||
busy = 0;
|
||||
for_each_dpa_resource(ndd, res) {
|
||||
if (strncmp(res->name, "pmem", 4) != 0)
|
||||
continue;
|
||||
if ((res->start >= blk_start && res->start < map_end)
|
||||
|| (res->end >= blk_start
|
||||
&& res->end <= map_end)) {
|
||||
if (strncmp(res->name, "pmem", 4) == 0) {
|
||||
new = max(blk_start, min(map_end + 1,
|
||||
res->end + 1));
|
||||
if (new != blk_start) {
|
||||
blk_start = new;
|
||||
goto retry;
|
||||
}
|
||||
} else
|
||||
busy += min(map_end, res->end)
|
||||
- max(nd_mapping->start, res->start) + 1;
|
||||
} else if (nd_mapping->start > res->start
|
||||
&& map_end < res->end) {
|
||||
/* total eclipse of the PMEM region mapping */
|
||||
busy += nd_mapping->size;
|
||||
break;
|
||||
new = max(blk_start, min(map_end + 1, res->end + 1));
|
||||
if (new != blk_start) {
|
||||
blk_start = new;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,52 +453,11 @@ int alias_dpa_busy(struct device *dev, void *data)
|
||||
return 1;
|
||||
}
|
||||
|
||||
info->available -= blk_start - nd_mapping->start + busy;
|
||||
info->available -= blk_start - nd_mapping->start;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int blk_dpa_busy(struct device *dev, void *data)
|
||||
{
|
||||
struct blk_alloc_info *info = data;
|
||||
struct nd_mapping *nd_mapping;
|
||||
struct nd_region *nd_region;
|
||||
resource_size_t map_end;
|
||||
int i;
|
||||
|
||||
if (!is_nd_pmem(dev))
|
||||
return 0;
|
||||
|
||||
nd_region = to_nd_region(dev);
|
||||
for (i = 0; i < nd_region->ndr_mappings; i++) {
|
||||
nd_mapping = &nd_region->mapping[i];
|
||||
if (nd_mapping->nvdimm == info->nd_mapping->nvdimm)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= nd_region->ndr_mappings)
|
||||
return 0;
|
||||
|
||||
map_end = nd_mapping->start + nd_mapping->size - 1;
|
||||
if (info->res->start >= nd_mapping->start
|
||||
&& info->res->start < map_end) {
|
||||
if (info->res->end <= map_end) {
|
||||
info->busy = 0;
|
||||
return 1;
|
||||
} else {
|
||||
info->busy -= info->res->end - map_end;
|
||||
return 0;
|
||||
}
|
||||
} else if (info->res->end >= nd_mapping->start
|
||||
&& info->res->end <= map_end) {
|
||||
info->busy -= nd_mapping->start - info->res->start;
|
||||
return 0;
|
||||
} else {
|
||||
info->busy -= nd_mapping->size;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nd_blk_available_dpa - account the unused dpa of BLK region
|
||||
* @nd_mapping: container of dpa-resource-root + labels
|
||||
@@ -538,11 +487,7 @@ resource_size_t nd_blk_available_dpa(struct nd_region *nd_region)
|
||||
for_each_dpa_resource(ndd, res) {
|
||||
if (strncmp(res->name, "blk", 3) != 0)
|
||||
continue;
|
||||
|
||||
info.res = res;
|
||||
info.busy = resource_size(res);
|
||||
device_for_each_child(&nvdimm_bus->dev, &info, blk_dpa_busy);
|
||||
info.available -= info.busy;
|
||||
info.available -= resource_size(res);
|
||||
}
|
||||
|
||||
return info.available;
|
||||
|
||||
@@ -1846,11 +1846,24 @@ static int __init acer_wmi_enable_lm(void)
|
||||
return status;
|
||||
}
|
||||
|
||||
#define ACER_WMID_ACCEL_HID "BST0001"
|
||||
|
||||
static acpi_status __init acer_wmi_get_handle_cb(acpi_handle ah, u32 level,
|
||||
void *ctx, void **retval)
|
||||
{
|
||||
struct acpi_device *dev;
|
||||
|
||||
if (!strcmp(ctx, "SENR")) {
|
||||
if (acpi_bus_get_device(ah, &dev))
|
||||
return AE_OK;
|
||||
if (!strcmp(ACER_WMID_ACCEL_HID, acpi_device_hid(dev)))
|
||||
return AE_OK;
|
||||
} else
|
||||
return AE_OK;
|
||||
|
||||
*(acpi_handle *)retval = ah;
|
||||
return AE_OK;
|
||||
|
||||
return AE_CTRL_TERMINATE;
|
||||
}
|
||||
|
||||
static int __init acer_wmi_get_handle(const char *name, const char *prop,
|
||||
@@ -1877,7 +1890,7 @@ static int __init acer_wmi_accel_setup(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = acer_wmi_get_handle("SENR", "BST0001", &gsensor_handle);
|
||||
err = acer_wmi_get_handle("SENR", ACER_WMID_ACCEL_HID, &gsensor_handle);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -2233,10 +2246,11 @@ static int __init acer_wmi_init(void)
|
||||
err = acer_wmi_input_setup();
|
||||
if (err)
|
||||
return err;
|
||||
err = acer_wmi_accel_setup();
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
acer_wmi_accel_setup();
|
||||
|
||||
err = platform_driver_register(&acer_platform_driver);
|
||||
if (err) {
|
||||
pr_err("Unable to register platform driver\n");
|
||||
|
||||
@@ -191,6 +191,28 @@ static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_pwm_enable(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
bool enable,
|
||||
enum pwm_polarity polarity)
|
||||
{
|
||||
struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip);
|
||||
int ret;
|
||||
|
||||
if (enable) {
|
||||
ret = clk_enable(pc->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
pc->data->set_enable(chip, pwm, enable, polarity);
|
||||
|
||||
if (!enable)
|
||||
clk_disable(pc->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
@@ -207,22 +229,26 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
return ret;
|
||||
|
||||
if (state->polarity != curstate.polarity && enabled) {
|
||||
pc->data->set_enable(chip, pwm, false, state->polarity);
|
||||
ret = rockchip_pwm_enable(chip, pwm, false, state->polarity);
|
||||
if (ret)
|
||||
goto out;
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
ret = rockchip_pwm_config(chip, pwm, state->duty_cycle, state->period);
|
||||
if (ret) {
|
||||
if (enabled != curstate.enabled)
|
||||
pc->data->set_enable(chip, pwm, !enabled,
|
||||
state->polarity);
|
||||
|
||||
rockchip_pwm_enable(chip, pwm, !enabled,
|
||||
state->polarity);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (state->enabled != enabled)
|
||||
pc->data->set_enable(chip, pwm, state->enabled,
|
||||
state->polarity);
|
||||
if (state->enabled != enabled) {
|
||||
ret = rockchip_pwm_enable(chip, pwm, state->enabled,
|
||||
state->polarity);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the state with the real hardware, which can differ a bit
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -59,6 +60,7 @@ struct tegra_rtc_info {
|
||||
struct platform_device *pdev;
|
||||
struct rtc_device *rtc_dev;
|
||||
void __iomem *rtc_base; /* NULL if not initialized. */
|
||||
struct clk *clk;
|
||||
int tegra_rtc_irq; /* alarm and periodic irq */
|
||||
spinlock_t tegra_rtc_lock;
|
||||
};
|
||||
@@ -326,6 +328,14 @@ static int __init tegra_rtc_probe(struct platform_device *pdev)
|
||||
if (info->tegra_rtc_irq <= 0)
|
||||
return -EBUSY;
|
||||
|
||||
info->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(info->clk))
|
||||
return PTR_ERR(info->clk);
|
||||
|
||||
ret = clk_prepare_enable(info->clk);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* set context info. */
|
||||
info->pdev = pdev;
|
||||
spin_lock_init(&info->tegra_rtc_lock);
|
||||
@@ -346,7 +356,7 @@ static int __init tegra_rtc_probe(struct platform_device *pdev)
|
||||
ret = PTR_ERR(info->rtc_dev);
|
||||
dev_err(&pdev->dev, "Unable to register device (err=%d).\n",
|
||||
ret);
|
||||
return ret;
|
||||
goto disable_clk;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, info->tegra_rtc_irq,
|
||||
@@ -356,11 +366,24 @@ static int __init tegra_rtc_probe(struct platform_device *pdev)
|
||||
dev_err(&pdev->dev,
|
||||
"Unable to request interrupt for device (err=%d).\n",
|
||||
ret);
|
||||
return ret;
|
||||
goto disable_clk;
|
||||
}
|
||||
|
||||
dev_notice(&pdev->dev, "Tegra internal Real Time Clock\n");
|
||||
|
||||
return 0;
|
||||
|
||||
disable_clk:
|
||||
clk_disable_unprepare(info->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tegra_rtc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct tegra_rtc_info *info = platform_get_drvdata(pdev);
|
||||
|
||||
clk_disable_unprepare(info->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -413,6 +436,7 @@ static void tegra_rtc_shutdown(struct platform_device *pdev)
|
||||
|
||||
MODULE_ALIAS("platform:tegra_rtc");
|
||||
static struct platform_driver tegra_rtc_driver = {
|
||||
.remove = tegra_rtc_remove,
|
||||
.shutdown = tegra_rtc_shutdown,
|
||||
.driver = {
|
||||
.name = "tegra_rtc",
|
||||
|
||||
@@ -968,8 +968,13 @@ static inline
|
||||
uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
|
||||
{
|
||||
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
|
||||
struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82;
|
||||
|
||||
return ((RD_REG_DWORD(®->host_status)) == ISP_REG_DISCONNECT);
|
||||
if (IS_P3P_TYPE(ha))
|
||||
return ((RD_REG_DWORD(®82->host_int)) == ISP_REG_DISCONNECT);
|
||||
else
|
||||
return ((RD_REG_DWORD(®->host_status)) ==
|
||||
ISP_REG_DISCONNECT);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
||||
@@ -2057,6 +2057,22 @@ static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp,
|
||||
|
||||
#define READ_CAPACITY_RETRIES_ON_RESET 10
|
||||
|
||||
/*
|
||||
* Ensure that we don't overflow sector_t when CONFIG_LBDAF is not set
|
||||
* and the reported logical block size is bigger than 512 bytes. Note
|
||||
* that last_sector is a u64 and therefore logical_to_sectors() is not
|
||||
* applicable.
|
||||
*/
|
||||
static bool sd_addressable_capacity(u64 lba, unsigned int sector_size)
|
||||
{
|
||||
u64 last_sector = (lba + 1ULL) << (ilog2(sector_size) - 9);
|
||||
|
||||
if (sizeof(sector_t) == 4 && last_sector > U32_MAX)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
|
||||
unsigned char *buffer)
|
||||
{
|
||||
@@ -2122,7 +2138,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if ((sizeof(sdkp->capacity) == 4) && (lba >= 0xffffffffULL)) {
|
||||
if (!sd_addressable_capacity(lba, sector_size)) {
|
||||
sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a "
|
||||
"kernel compiled with support for large block "
|
||||
"devices.\n");
|
||||
@@ -2208,7 +2224,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
|
||||
return sector_size;
|
||||
}
|
||||
|
||||
if ((sizeof(sdkp->capacity) == 4) && (lba == 0xffffffff)) {
|
||||
if (!sd_addressable_capacity(lba, sector_size)) {
|
||||
sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use a "
|
||||
"kernel compiled with support for large block "
|
||||
"devices.\n");
|
||||
@@ -2877,7 +2893,8 @@ static int sd_revalidate_disk(struct gendisk *disk)
|
||||
q->limits.io_opt = logical_to_bytes(sdp, sdkp->opt_xfer_blocks);
|
||||
rw_max = logical_to_sectors(sdp, sdkp->opt_xfer_blocks);
|
||||
} else
|
||||
rw_max = BLK_DEF_MAX_SECTORS;
|
||||
rw_max = min_not_zero(logical_to_sectors(sdp, dev_max),
|
||||
(sector_t)BLK_DEF_MAX_SECTORS);
|
||||
|
||||
/* Combine with controller limits */
|
||||
q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q));
|
||||
|
||||
@@ -833,6 +833,7 @@ static void get_capabilities(struct scsi_cd *cd)
|
||||
unsigned char *buffer;
|
||||
struct scsi_mode_data data;
|
||||
struct scsi_sense_hdr sshdr;
|
||||
unsigned int ms_len = 128;
|
||||
int rc, n;
|
||||
|
||||
static const char *loadmech[] =
|
||||
@@ -859,10 +860,11 @@ static void get_capabilities(struct scsi_cd *cd)
|
||||
scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr);
|
||||
|
||||
/* ask for mode page 0x2a */
|
||||
rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128,
|
||||
rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, ms_len,
|
||||
SR_TIMEOUT, 3, &data, NULL);
|
||||
|
||||
if (!scsi_status_is_good(rc)) {
|
||||
if (!scsi_status_is_good(rc) || data.length > ms_len ||
|
||||
data.header_length + data.block_descriptor_length > data.length) {
|
||||
/* failed, drive doesn't have capabilities mode page */
|
||||
cd->cdi.speed = 1;
|
||||
cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R |
|
||||
|
||||
@@ -781,22 +781,6 @@ static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
|
||||
} else if (IS_TYPE_NUMBER(param)) {
|
||||
if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
|
||||
SET_PSTATE_REPLY_OPTIONAL(param);
|
||||
/*
|
||||
* The GlobalSAN iSCSI Initiator for MacOSX does
|
||||
* not respond to MaxBurstLength, FirstBurstLength,
|
||||
* DefaultTime2Wait or DefaultTime2Retain parameter keys.
|
||||
* So, we set them to 'reply optional' here, and assume the
|
||||
* the defaults from iscsi_parameters.h if the initiator
|
||||
* is not RFC compliant and the keys are not negotiated.
|
||||
*/
|
||||
if (!strcmp(param->name, MAXBURSTLENGTH))
|
||||
SET_PSTATE_REPLY_OPTIONAL(param);
|
||||
if (!strcmp(param->name, FIRSTBURSTLENGTH))
|
||||
SET_PSTATE_REPLY_OPTIONAL(param);
|
||||
if (!strcmp(param->name, DEFAULTTIME2WAIT))
|
||||
SET_PSTATE_REPLY_OPTIONAL(param);
|
||||
if (!strcmp(param->name, DEFAULTTIME2RETAIN))
|
||||
SET_PSTATE_REPLY_OPTIONAL(param);
|
||||
/*
|
||||
* Required for gPXE iSCSI boot client
|
||||
*/
|
||||
|
||||
@@ -735,21 +735,23 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown)
|
||||
{
|
||||
struct se_cmd *se_cmd = NULL;
|
||||
int rc;
|
||||
bool op_scsi = false;
|
||||
/*
|
||||
* Determine if a struct se_cmd is associated with
|
||||
* this struct iscsi_cmd.
|
||||
*/
|
||||
switch (cmd->iscsi_opcode) {
|
||||
case ISCSI_OP_SCSI_CMD:
|
||||
se_cmd = &cmd->se_cmd;
|
||||
__iscsit_free_cmd(cmd, true, shutdown);
|
||||
op_scsi = true;
|
||||
/*
|
||||
* Fallthrough
|
||||
*/
|
||||
case ISCSI_OP_SCSI_TMFUNC:
|
||||
rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown);
|
||||
if (!rc && shutdown && se_cmd && se_cmd->se_sess) {
|
||||
__iscsit_free_cmd(cmd, true, shutdown);
|
||||
se_cmd = &cmd->se_cmd;
|
||||
__iscsit_free_cmd(cmd, op_scsi, shutdown);
|
||||
rc = transport_generic_free_cmd(se_cmd, shutdown);
|
||||
if (!rc && shutdown && se_cmd->se_sess) {
|
||||
__iscsit_free_cmd(cmd, op_scsi, shutdown);
|
||||
target_put_sess_cmd(se_cmd);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -92,6 +92,11 @@ static int target_fabric_mappedlun_link(
|
||||
pr_err("Source se_lun->lun_se_dev does not exist\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (lun->lun_shutdown) {
|
||||
pr_err("Unable to create mappedlun symlink because"
|
||||
" lun->lun_shutdown=true\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
se_tpg = lun->lun_tpg;
|
||||
|
||||
nacl_ci = &lun_acl_ci->ci_parent->ci_group->cg_item;
|
||||
|
||||
@@ -640,6 +640,8 @@ void core_tpg_remove_lun(
|
||||
*/
|
||||
struct se_device *dev = rcu_dereference_raw(lun->lun_se_dev);
|
||||
|
||||
lun->lun_shutdown = true;
|
||||
|
||||
core_clear_lun_from_tpg(lun, tpg);
|
||||
/*
|
||||
* Wait for any active I/O references to percpu se_lun->lun_ref to
|
||||
@@ -661,6 +663,8 @@ void core_tpg_remove_lun(
|
||||
}
|
||||
if (!(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE))
|
||||
hlist_del_rcu(&lun->link);
|
||||
|
||||
lun->lun_shutdown = false;
|
||||
mutex_unlock(&tpg->tpg_lun_mutex);
|
||||
|
||||
percpu_ref_exit(&lun->lun_ref);
|
||||
|
||||
@@ -306,24 +306,50 @@ static void free_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd)
|
||||
DATA_BLOCK_BITS);
|
||||
}
|
||||
|
||||
static void gather_data_area(struct tcmu_dev *udev, unsigned long *cmd_bitmap,
|
||||
struct scatterlist *data_sg, unsigned int data_nents)
|
||||
static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd,
|
||||
bool bidi)
|
||||
{
|
||||
struct se_cmd *se_cmd = cmd->se_cmd;
|
||||
int i, block;
|
||||
int block_remaining = 0;
|
||||
void *from, *to;
|
||||
size_t copy_bytes, from_offset;
|
||||
struct scatterlist *sg;
|
||||
struct scatterlist *sg, *data_sg;
|
||||
unsigned int data_nents;
|
||||
DECLARE_BITMAP(bitmap, DATA_BLOCK_BITS);
|
||||
|
||||
bitmap_copy(bitmap, cmd->data_bitmap, DATA_BLOCK_BITS);
|
||||
|
||||
if (!bidi) {
|
||||
data_sg = se_cmd->t_data_sg;
|
||||
data_nents = se_cmd->t_data_nents;
|
||||
} else {
|
||||
uint32_t count;
|
||||
|
||||
/*
|
||||
* For bidi case, the first count blocks are for Data-Out
|
||||
* buffer blocks, and before gathering the Data-In buffer
|
||||
* the Data-Out buffer blocks should be discarded.
|
||||
*/
|
||||
count = DIV_ROUND_UP(se_cmd->data_length, DATA_BLOCK_SIZE);
|
||||
while (count--) {
|
||||
block = find_first_bit(bitmap, DATA_BLOCK_BITS);
|
||||
clear_bit(block, bitmap);
|
||||
}
|
||||
|
||||
data_sg = se_cmd->t_bidi_data_sg;
|
||||
data_nents = se_cmd->t_bidi_data_nents;
|
||||
}
|
||||
|
||||
for_each_sg(data_sg, sg, data_nents, i) {
|
||||
int sg_remaining = sg->length;
|
||||
to = kmap_atomic(sg_page(sg)) + sg->offset;
|
||||
while (sg_remaining > 0) {
|
||||
if (block_remaining == 0) {
|
||||
block = find_first_bit(cmd_bitmap,
|
||||
block = find_first_bit(bitmap,
|
||||
DATA_BLOCK_BITS);
|
||||
block_remaining = DATA_BLOCK_SIZE;
|
||||
clear_bit(block, cmd_bitmap);
|
||||
clear_bit(block, bitmap);
|
||||
}
|
||||
copy_bytes = min_t(size_t, sg_remaining,
|
||||
block_remaining);
|
||||
@@ -389,6 +415,27 @@ static bool is_ring_space_avail(struct tcmu_dev *udev, size_t cmd_size, size_t d
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline size_t tcmu_cmd_get_data_length(struct tcmu_cmd *tcmu_cmd)
|
||||
{
|
||||
struct se_cmd *se_cmd = tcmu_cmd->se_cmd;
|
||||
size_t data_length = round_up(se_cmd->data_length, DATA_BLOCK_SIZE);
|
||||
|
||||
if (se_cmd->se_cmd_flags & SCF_BIDI) {
|
||||
BUG_ON(!(se_cmd->t_bidi_data_sg && se_cmd->t_bidi_data_nents));
|
||||
data_length += round_up(se_cmd->t_bidi_data_sg->length,
|
||||
DATA_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
return data_length;
|
||||
}
|
||||
|
||||
static inline uint32_t tcmu_cmd_get_block_cnt(struct tcmu_cmd *tcmu_cmd)
|
||||
{
|
||||
size_t data_length = tcmu_cmd_get_data_length(tcmu_cmd);
|
||||
|
||||
return data_length / DATA_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
static sense_reason_t
|
||||
tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
|
||||
{
|
||||
@@ -402,7 +449,7 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
|
||||
uint32_t cmd_head;
|
||||
uint64_t cdb_off;
|
||||
bool copy_to_data_area;
|
||||
size_t data_length;
|
||||
size_t data_length = tcmu_cmd_get_data_length(tcmu_cmd);
|
||||
DECLARE_BITMAP(old_bitmap, DATA_BLOCK_BITS);
|
||||
|
||||
if (test_bit(TCMU_DEV_BIT_BROKEN, &udev->flags))
|
||||
@@ -416,8 +463,7 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
|
||||
* expensive to tell how many regions are freed in the bitmap
|
||||
*/
|
||||
base_command_size = max(offsetof(struct tcmu_cmd_entry,
|
||||
req.iov[se_cmd->t_bidi_data_nents +
|
||||
se_cmd->t_data_nents]),
|
||||
req.iov[tcmu_cmd_get_block_cnt(tcmu_cmd)]),
|
||||
sizeof(struct tcmu_cmd_entry));
|
||||
command_size = base_command_size
|
||||
+ round_up(scsi_command_size(se_cmd->t_task_cdb), TCMU_OP_ALIGN_SIZE);
|
||||
@@ -428,11 +474,6 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
|
||||
|
||||
mb = udev->mb_addr;
|
||||
cmd_head = mb->cmd_head % udev->cmdr_size; /* UAM */
|
||||
data_length = se_cmd->data_length;
|
||||
if (se_cmd->se_cmd_flags & SCF_BIDI) {
|
||||
BUG_ON(!(se_cmd->t_bidi_data_sg && se_cmd->t_bidi_data_nents));
|
||||
data_length += se_cmd->t_bidi_data_sg->length;
|
||||
}
|
||||
if ((command_size > (udev->cmdr_size / 2)) ||
|
||||
data_length > udev->data_size) {
|
||||
pr_warn("TCMU: Request of size %zu/%zu is too big for %u/%zu "
|
||||
@@ -502,11 +543,14 @@ tcmu_queue_cmd_ring(struct tcmu_cmd *tcmu_cmd)
|
||||
entry->req.iov_dif_cnt = 0;
|
||||
|
||||
/* Handle BIDI commands */
|
||||
iov_cnt = 0;
|
||||
alloc_and_scatter_data_area(udev, se_cmd->t_bidi_data_sg,
|
||||
se_cmd->t_bidi_data_nents, &iov, &iov_cnt, false);
|
||||
entry->req.iov_bidi_cnt = iov_cnt;
|
||||
|
||||
if (se_cmd->se_cmd_flags & SCF_BIDI) {
|
||||
iov_cnt = 0;
|
||||
iov++;
|
||||
alloc_and_scatter_data_area(udev, se_cmd->t_bidi_data_sg,
|
||||
se_cmd->t_bidi_data_nents, &iov, &iov_cnt,
|
||||
false);
|
||||
entry->req.iov_bidi_cnt = iov_cnt;
|
||||
}
|
||||
/* cmd's data_bitmap is what changed in process */
|
||||
bitmap_xor(tcmu_cmd->data_bitmap, old_bitmap, udev->data_bitmap,
|
||||
DATA_BLOCK_BITS);
|
||||
@@ -582,19 +626,11 @@ static void tcmu_handle_completion(struct tcmu_cmd *cmd, struct tcmu_cmd_entry *
|
||||
se_cmd->scsi_sense_length);
|
||||
free_data_area(udev, cmd);
|
||||
} else if (se_cmd->se_cmd_flags & SCF_BIDI) {
|
||||
DECLARE_BITMAP(bitmap, DATA_BLOCK_BITS);
|
||||
|
||||
/* Get Data-In buffer before clean up */
|
||||
bitmap_copy(bitmap, cmd->data_bitmap, DATA_BLOCK_BITS);
|
||||
gather_data_area(udev, bitmap,
|
||||
se_cmd->t_bidi_data_sg, se_cmd->t_bidi_data_nents);
|
||||
gather_data_area(udev, cmd, true);
|
||||
free_data_area(udev, cmd);
|
||||
} else if (se_cmd->data_direction == DMA_FROM_DEVICE) {
|
||||
DECLARE_BITMAP(bitmap, DATA_BLOCK_BITS);
|
||||
|
||||
bitmap_copy(bitmap, cmd->data_bitmap, DATA_BLOCK_BITS);
|
||||
gather_data_area(udev, bitmap,
|
||||
se_cmd->t_data_sg, se_cmd->t_data_nents);
|
||||
gather_data_area(udev, cmd, false);
|
||||
free_data_area(udev, cmd);
|
||||
} else if (se_cmd->data_direction == DMA_TO_DEVICE) {
|
||||
free_data_area(udev, cmd);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/usb/audio.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/pm_qos.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/pcm.h>
|
||||
@@ -268,6 +269,8 @@ struct audio_dev {
|
||||
/* number of frames sent since start_time */
|
||||
s64 frames_sent;
|
||||
struct audio_source_config *config;
|
||||
/* for creating and issuing QoS requests */
|
||||
struct pm_qos_request pm_qos;
|
||||
};
|
||||
|
||||
static inline struct audio_dev *func_to_audio(struct usb_function *f)
|
||||
@@ -740,6 +743,10 @@ static int audio_pcm_open(struct snd_pcm_substream *substream)
|
||||
runtime->hw.channels_max = 2;
|
||||
|
||||
audio->substream = substream;
|
||||
|
||||
/* Add the QoS request and set the latency to 0 */
|
||||
pm_qos_add_request(&audio->pm_qos, PM_QOS_CPU_DMA_LATENCY, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -749,6 +756,10 @@ static int audio_pcm_close(struct snd_pcm_substream *substream)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&audio->lock, flags);
|
||||
|
||||
/* Remove the QoS request */
|
||||
pm_qos_remove_request(&audio->pm_qos);
|
||||
|
||||
audio->substream = NULL;
|
||||
spin_unlock_irqrestore(&audio->lock, flags);
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#define MTP_BULK_BUFFER_SIZE 16384
|
||||
#define INTR_BUFFER_SIZE 28
|
||||
#define MAX_INST_NAME_LEN 40
|
||||
#define MTP_MAX_FILE_SIZE 0xFFFFFFFFL
|
||||
|
||||
/* String IDs */
|
||||
#define INTERFACE_STRING_INDEX 0
|
||||
@@ -766,7 +767,12 @@ static void send_file_work(struct work_struct *data)
|
||||
if (hdr_size) {
|
||||
/* prepend MTP data header */
|
||||
header = (struct mtp_data_header *)req->buf;
|
||||
header->length = __cpu_to_le32(count);
|
||||
/*
|
||||
* set file size with header according to
|
||||
* MTP Specification v1.0
|
||||
*/
|
||||
header->length = (count > MTP_MAX_FILE_SIZE) ?
|
||||
MTP_MAX_FILE_SIZE : __cpu_to_le32(count);
|
||||
header->type = __cpu_to_le16(2); /* data packet */
|
||||
header->command = __cpu_to_le16(dev->xfer_command);
|
||||
header->transaction_id =
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <linux/efi.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/screen_info.h>
|
||||
#include <video/vga.h>
|
||||
@@ -118,6 +119,8 @@ static inline bool fb_base_is_valid(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool pci_dev_disabled; /* FB base matches BAR of a disabled device */
|
||||
|
||||
static int efifb_probe(struct platform_device *dev)
|
||||
{
|
||||
struct fb_info *info;
|
||||
@@ -127,7 +130,7 @@ static int efifb_probe(struct platform_device *dev)
|
||||
unsigned int size_total;
|
||||
char *option = NULL;
|
||||
|
||||
if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
|
||||
if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
|
||||
return -ENODEV;
|
||||
|
||||
if (fb_get_options("efifb", &option))
|
||||
@@ -327,3 +330,64 @@ static struct platform_driver efifb_driver = {
|
||||
};
|
||||
|
||||
builtin_platform_driver(efifb_driver);
|
||||
|
||||
#if defined(CONFIG_PCI) && !defined(CONFIG_X86)
|
||||
|
||||
static bool pci_bar_found; /* did we find a BAR matching the efifb base? */
|
||||
|
||||
static void claim_efifb_bar(struct pci_dev *dev, int idx)
|
||||
{
|
||||
u16 word;
|
||||
|
||||
pci_bar_found = true;
|
||||
|
||||
pci_read_config_word(dev, PCI_COMMAND, &word);
|
||||
if (!(word & PCI_COMMAND_MEMORY)) {
|
||||
pci_dev_disabled = true;
|
||||
dev_err(&dev->dev,
|
||||
"BAR %d: assigned to efifb but device is disabled!\n",
|
||||
idx);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pci_claim_resource(dev, idx)) {
|
||||
pci_dev_disabled = true;
|
||||
dev_err(&dev->dev,
|
||||
"BAR %d: failed to claim resource for efifb!\n", idx);
|
||||
return;
|
||||
}
|
||||
|
||||
dev_info(&dev->dev, "BAR %d: assigned to efifb\n", idx);
|
||||
}
|
||||
|
||||
static void efifb_fixup_resources(struct pci_dev *dev)
|
||||
{
|
||||
u64 base = screen_info.lfb_base;
|
||||
u64 size = screen_info.lfb_size;
|
||||
int i;
|
||||
|
||||
if (pci_bar_found || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
|
||||
return;
|
||||
|
||||
if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
|
||||
base |= (u64)screen_info.ext_lfb_base << 32;
|
||||
|
||||
if (!base)
|
||||
return;
|
||||
|
||||
for (i = 0; i < PCI_STD_RESOURCE_END; i++) {
|
||||
struct resource *res = &dev->resource[i];
|
||||
|
||||
if (!(res->flags & IORESOURCE_MEM))
|
||||
continue;
|
||||
|
||||
if (res->start <= base && res->end >= base + size - 1) {
|
||||
claim_efifb_bar(dev, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY,
|
||||
16, efifb_fixup_resources);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -644,7 +644,6 @@ static void xenfb_backend_changed(struct xenbus_device *dev,
|
||||
break;
|
||||
|
||||
case XenbusStateInitWait:
|
||||
InitWait:
|
||||
xenbus_switch_state(dev, XenbusStateConnected);
|
||||
break;
|
||||
|
||||
@@ -655,7 +654,8 @@ InitWait:
|
||||
* get Connected twice here.
|
||||
*/
|
||||
if (dev->state != XenbusStateConnected)
|
||||
goto InitWait; /* no InitWait seen yet, fudge it */
|
||||
/* no InitWait seen yet, fudge it */
|
||||
xenbus_switch_state(dev, XenbusStateConnected);
|
||||
|
||||
if (xenbus_scanf(XBT_NIL, info->xbdev->otherend,
|
||||
"request-update", "%d", &val) < 0)
|
||||
|
||||
@@ -2080,11 +2080,6 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
|
||||
if (inode_dirty_flags)
|
||||
__mark_inode_dirty(inode, inode_dirty_flags);
|
||||
|
||||
if (ia_valid & ATTR_MODE) {
|
||||
err = posix_acl_chmod(inode, attr->ia_mode);
|
||||
if (err)
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
if (mask) {
|
||||
req->r_inode = inode;
|
||||
@@ -2098,13 +2093,11 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
|
||||
ceph_cap_string(dirtied), mask);
|
||||
|
||||
ceph_mdsc_put_request(req);
|
||||
if (mask & CEPH_SETATTR_SIZE)
|
||||
ceph_free_cap_flush(prealloc_cf);
|
||||
|
||||
if (err >= 0 && (mask & CEPH_SETATTR_SIZE))
|
||||
__ceph_do_pending_vmtruncate(inode);
|
||||
ceph_free_cap_flush(prealloc_cf);
|
||||
return err;
|
||||
out_put:
|
||||
ceph_mdsc_put_request(req);
|
||||
ceph_free_cap_flush(prealloc_cf);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -2123,7 +2116,12 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
|
||||
if (err != 0)
|
||||
return err;
|
||||
|
||||
return __ceph_setattr(inode, attr);
|
||||
err = __ceph_setattr(inode, attr);
|
||||
|
||||
if (err >= 0 && (attr->ia_valid & ATTR_MODE))
|
||||
err = posix_acl_chmod(inode, attr->ia_mode);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -930,7 +930,6 @@ struct cifs_tcon {
|
||||
bool use_persistent:1; /* use persistent instead of durable handles */
|
||||
#ifdef CONFIG_CIFS_SMB2
|
||||
bool print:1; /* set if connection to printer share */
|
||||
bool bad_network_name:1; /* set if ret status STATUS_BAD_NETWORK_NAME */
|
||||
__le32 capabilities;
|
||||
__u32 share_flags;
|
||||
__u32 maximal_access;
|
||||
|
||||
@@ -2597,7 +2597,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
|
||||
wdata->credits = credits;
|
||||
|
||||
if (!wdata->cfile->invalidHandle ||
|
||||
!cifs_reopen_file(wdata->cfile, false))
|
||||
!(rc = cifs_reopen_file(wdata->cfile, false)))
|
||||
rc = server->ops->async_writev(wdata,
|
||||
cifs_uncached_writedata_release);
|
||||
if (rc) {
|
||||
@@ -3002,7 +3002,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
|
||||
rdata->credits = credits;
|
||||
|
||||
if (!rdata->cfile->invalidHandle ||
|
||||
!cifs_reopen_file(rdata->cfile, true))
|
||||
!(rc = cifs_reopen_file(rdata->cfile, true)))
|
||||
rc = server->ops->async_readv(rdata);
|
||||
error:
|
||||
if (rc) {
|
||||
@@ -3577,7 +3577,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
|
||||
}
|
||||
|
||||
if (!rdata->cfile->invalidHandle ||
|
||||
!cifs_reopen_file(rdata->cfile, true))
|
||||
!(rc = cifs_reopen_file(rdata->cfile, true)))
|
||||
rc = server->ops->async_readv(rdata);
|
||||
if (rc) {
|
||||
add_credits_and_wake_if(server, rdata->credits, 0);
|
||||
|
||||
@@ -1015,6 +1015,15 @@ cifs_dir_needs_close(struct cifsFileInfo *cfile)
|
||||
return !cfile->srch_inf.endOfSearch && !cfile->invalidHandle;
|
||||
}
|
||||
|
||||
static bool
|
||||
cifs_can_echo(struct TCP_Server_Info *server)
|
||||
{
|
||||
if (server->tcpStatus == CifsGood)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct smb_version_operations smb1_operations = {
|
||||
.send_cancel = send_nt_cancel,
|
||||
.compare_fids = cifs_compare_fids,
|
||||
@@ -1049,6 +1058,7 @@ struct smb_version_operations smb1_operations = {
|
||||
.get_dfs_refer = CIFSGetDFSRefer,
|
||||
.qfs_tcon = cifs_qfs_tcon,
|
||||
.is_path_accessible = cifs_is_path_accessible,
|
||||
.can_echo = cifs_can_echo,
|
||||
.query_path_info = cifs_query_path_info,
|
||||
.query_file_info = cifs_query_file_info,
|
||||
.get_srv_inum = cifs_get_srv_inum,
|
||||
|
||||
@@ -1084,9 +1084,6 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
|
||||
else
|
||||
return -EIO;
|
||||
|
||||
if (tcon && tcon->bad_network_name)
|
||||
return -ENOENT;
|
||||
|
||||
if ((tcon && tcon->seal) &&
|
||||
((ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) == 0)) {
|
||||
cifs_dbg(VFS, "encryption requested but no server support");
|
||||
@@ -1188,8 +1185,6 @@ tcon_exit:
|
||||
tcon_error_exit:
|
||||
if (rsp->hdr.Status == STATUS_BAD_NETWORK_NAME) {
|
||||
cifs_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree);
|
||||
if (tcon)
|
||||
tcon->bad_network_name = true;
|
||||
}
|
||||
goto tcon_exit;
|
||||
}
|
||||
@@ -1987,6 +1982,9 @@ void smb2_reconnect_server(struct work_struct *work)
|
||||
struct cifs_tcon *tcon, *tcon2;
|
||||
struct list_head tmp_list;
|
||||
int tcon_exist = false;
|
||||
int rc;
|
||||
int resched = false;
|
||||
|
||||
|
||||
/* Prevent simultaneous reconnects that can corrupt tcon->rlist list */
|
||||
mutex_lock(&server->reconnect_mutex);
|
||||
@@ -2014,13 +2012,18 @@ void smb2_reconnect_server(struct work_struct *work)
|
||||
spin_unlock(&cifs_tcp_ses_lock);
|
||||
|
||||
list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) {
|
||||
if (!smb2_reconnect(SMB2_INTERNAL_CMD, tcon))
|
||||
rc = smb2_reconnect(SMB2_INTERNAL_CMD, tcon);
|
||||
if (!rc)
|
||||
cifs_reopen_persistent_handles(tcon);
|
||||
else
|
||||
resched = true;
|
||||
list_del_init(&tcon->rlist);
|
||||
cifs_put_tcon(tcon);
|
||||
}
|
||||
|
||||
cifs_dbg(FYI, "Reconnecting tcons finished\n");
|
||||
if (resched)
|
||||
queue_delayed_work(cifsiod_wq, &server->reconnect, 2 * HZ);
|
||||
mutex_unlock(&server->reconnect_mutex);
|
||||
|
||||
/* now we can safely release srv struct */
|
||||
|
||||
@@ -72,10 +72,9 @@ static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw,
|
||||
csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum,
|
||||
csum_size);
|
||||
offset += csum_size;
|
||||
csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset,
|
||||
EXT4_INODE_SIZE(inode->i_sb) -
|
||||
offset);
|
||||
}
|
||||
csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset,
|
||||
EXT4_INODE_SIZE(inode->i_sb) - offset);
|
||||
}
|
||||
|
||||
return csum;
|
||||
|
||||
@@ -358,6 +358,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
{
|
||||
unsigned int len, v, hdr, dlen;
|
||||
u32 max_blocksize = svc_max_payload(rqstp);
|
||||
struct kvec *head = rqstp->rq_arg.head;
|
||||
struct kvec *tail = rqstp->rq_arg.tail;
|
||||
|
||||
p = decode_fh(p, &args->fh);
|
||||
if (!p)
|
||||
@@ -367,6 +369,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
args->count = ntohl(*p++);
|
||||
args->stable = ntohl(*p++);
|
||||
len = args->len = ntohl(*p++);
|
||||
if ((void *)p > head->iov_base + head->iov_len)
|
||||
return 0;
|
||||
/*
|
||||
* The count must equal the amount of data passed.
|
||||
*/
|
||||
@@ -377,9 +381,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
* Check to make sure that we got the right number of
|
||||
* bytes.
|
||||
*/
|
||||
hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
|
||||
dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len
|
||||
+ rqstp->rq_arg.tail[0].iov_len - hdr;
|
||||
hdr = (void*)p - head->iov_base;
|
||||
dlen = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len - hdr;
|
||||
/*
|
||||
* Round the length of the data which was specified up to
|
||||
* the next multiple of XDR units and then compare that
|
||||
@@ -396,7 +399,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
len = args->len = max_blocksize;
|
||||
}
|
||||
rqstp->rq_vec[0].iov_base = (void*)p;
|
||||
rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
|
||||
rqstp->rq_vec[0].iov_len = head->iov_len - hdr;
|
||||
v = 0;
|
||||
while (len > rqstp->rq_vec[v].iov_len) {
|
||||
len -= rqstp->rq_vec[v].iov_len;
|
||||
@@ -471,6 +474,8 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
/* first copy and check from the first page */
|
||||
old = (char*)p;
|
||||
vec = &rqstp->rq_arg.head[0];
|
||||
if ((void *)old > vec->iov_base + vec->iov_len)
|
||||
return 0;
|
||||
avail = vec->iov_len - (old - (char*)vec->iov_base);
|
||||
while (len && avail && *old) {
|
||||
*new++ = *old++;
|
||||
|
||||
@@ -733,6 +733,37 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr)
|
||||
return nfserr;
|
||||
}
|
||||
|
||||
/*
|
||||
* A write procedure can have a large argument, and a read procedure can
|
||||
* have a large reply, but no NFSv2 or NFSv3 procedure has argument and
|
||||
* reply that can both be larger than a page. The xdr code has taken
|
||||
* advantage of this assumption to be a sloppy about bounds checking in
|
||||
* some cases. Pending a rewrite of the NFSv2/v3 xdr code to fix that
|
||||
* problem, we enforce these assumptions here:
|
||||
*/
|
||||
static bool nfs_request_too_big(struct svc_rqst *rqstp,
|
||||
struct svc_procedure *proc)
|
||||
{
|
||||
/*
|
||||
* The ACL code has more careful bounds-checking and is not
|
||||
* susceptible to this problem:
|
||||
*/
|
||||
if (rqstp->rq_prog != NFS_PROGRAM)
|
||||
return false;
|
||||
/*
|
||||
* Ditto NFSv4 (which can in theory have argument and reply both
|
||||
* more than a page):
|
||||
*/
|
||||
if (rqstp->rq_vers >= 4)
|
||||
return false;
|
||||
/* The reply will be small, we're OK: */
|
||||
if (proc->pc_xdrressize > 0 &&
|
||||
proc->pc_xdrressize < XDR_QUADLEN(PAGE_SIZE))
|
||||
return false;
|
||||
|
||||
return rqstp->rq_arg.len > PAGE_SIZE;
|
||||
}
|
||||
|
||||
int
|
||||
nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
|
||||
{
|
||||
@@ -745,6 +776,11 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
|
||||
rqstp->rq_vers, rqstp->rq_proc);
|
||||
proc = rqstp->rq_procinfo;
|
||||
|
||||
if (nfs_request_too_big(rqstp, proc)) {
|
||||
dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers);
|
||||
*statp = rpc_garbage_args;
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
* Give the xdr decoder a chance to change this if it wants
|
||||
* (necessary in the NFSv4.0 compound case)
|
||||
|
||||
@@ -280,6 +280,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
struct nfsd_writeargs *args)
|
||||
{
|
||||
unsigned int len, hdr, dlen;
|
||||
struct kvec *head = rqstp->rq_arg.head;
|
||||
int v;
|
||||
|
||||
p = decode_fh(p, &args->fh);
|
||||
@@ -300,9 +301,10 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
* Check to make sure that we got the right number of
|
||||
* bytes.
|
||||
*/
|
||||
hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
|
||||
dlen = rqstp->rq_arg.head[0].iov_len + rqstp->rq_arg.page_len
|
||||
- hdr;
|
||||
hdr = (void*)p - head->iov_base;
|
||||
if (hdr > head->iov_len)
|
||||
return 0;
|
||||
dlen = head->iov_len + rqstp->rq_arg.page_len - hdr;
|
||||
|
||||
/*
|
||||
* Round the length of the data which was specified up to
|
||||
@@ -316,7 +318,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p,
|
||||
return 0;
|
||||
|
||||
rqstp->rq_vec[0].iov_base = (void*)p;
|
||||
rqstp->rq_vec[0].iov_len = rqstp->rq_arg.head[0].iov_len - hdr;
|
||||
rqstp->rq_vec[0].iov_len = head->iov_len - hdr;
|
||||
v = 0;
|
||||
while (len > rqstp->rq_vec[v].iov_len) {
|
||||
len -= rqstp->rq_vec[v].iov_len;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user