mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 14:04:54 +02:00
Merge 2d0f6b0aab ("Merge tag 'hyperv-next-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux") into android-mainline
Steps on the way to 5.10-rc1 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I1a4319d3921c77e672ffa5a0efec4882736a74f7
This commit is contained in:
commit
8bc601f293
|
|
@ -125,32 +125,41 @@ Note that some tests will require root privileges.
|
|||
Install selftests
|
||||
=================
|
||||
|
||||
You can use the kselftest_install.sh tool to install selftests in the
|
||||
default location, which is tools/testing/selftests/kselftest, or in a
|
||||
user specified location.
|
||||
You can use the "install" target of "make" (which calls the `kselftest_install.sh`
|
||||
tool) to install selftests in the default location (`tools/testing/selftests/kselftest_install`),
|
||||
or in a user specified location via the `INSTALL_PATH` "make" variable.
|
||||
|
||||
To install selftests in default location::
|
||||
|
||||
$ cd tools/testing/selftests
|
||||
$ ./kselftest_install.sh
|
||||
$ make -C tools/testing/selftests install
|
||||
|
||||
To install selftests in a user specified location::
|
||||
|
||||
$ cd tools/testing/selftests
|
||||
$ ./kselftest_install.sh install_dir
|
||||
$ make -C tools/testing/selftests install INSTALL_PATH=/some/other/path
|
||||
|
||||
Running installed selftests
|
||||
===========================
|
||||
|
||||
Kselftest install as well as the Kselftest tarball provide a script
|
||||
named "run_kselftest.sh" to run the tests.
|
||||
Found in the install directory, as well as in the Kselftest tarball,
|
||||
is a script named `run_kselftest.sh` to run the tests.
|
||||
|
||||
You can simply do the following to run the installed Kselftests. Please
|
||||
note some tests will require root privileges::
|
||||
|
||||
$ cd kselftest
|
||||
$ cd kselftest_install
|
||||
$ ./run_kselftest.sh
|
||||
|
||||
To see the list of available tests, the `-l` option can be used::
|
||||
|
||||
$ ./run_kselftest.sh -l
|
||||
|
||||
The `-c` option can be used to run all the tests from a test collection, or
|
||||
the `-t` option for specific single tests. Either can be used multiple times::
|
||||
|
||||
$ ./run_kselftest.sh -c bpf -c seccomp -t timers:posix_timers -t timer:nanosleep
|
||||
|
||||
For other features see the script usage output, seen with the `-h` option.
|
||||
|
||||
Packaging selftests
|
||||
===================
|
||||
|
||||
|
|
@ -160,9 +169,9 @@ different system. To package selftests, run::
|
|||
$ make -C tools/testing/selftests gen_tar
|
||||
|
||||
This generates a tarball in the `INSTALL_PATH/kselftest-packages` directory. By
|
||||
default, `.gz` format is used. The tar format can be overridden by specifying
|
||||
a `FORMAT` make variable. Any value recognized by `tar's auto-compress`_ option
|
||||
is supported, such as::
|
||||
default, `.gz` format is used. The tar compression format can be overridden by
|
||||
specifying a `FORMAT` make variable. Any value recognized by `tar's auto-compress`_
|
||||
option is supported, such as::
|
||||
|
||||
$ make -C tools/testing/selftests gen_tar FORMAT=.xz
|
||||
|
||||
|
|
|
|||
|
|
@ -4415,6 +4415,7 @@ S: Supported
|
|||
T: git git://git.infradead.org/users/hch/configfs.git
|
||||
F: fs/configfs/
|
||||
F: include/linux/configfs.h
|
||||
F: samples/configfs/
|
||||
|
||||
CONSOLE SUBSYSTEM
|
||||
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
|
@ -11708,7 +11709,7 @@ S: Odd Fixes
|
|||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lkundrak/linux-mmp.git
|
||||
F: arch/arm/boot/dts/mmp*
|
||||
F: arch/arm/mach-mmp/
|
||||
F: linux/soc/mmp/
|
||||
F: include/linux/soc/mmp/
|
||||
|
||||
MMP USB PHY DRIVERS
|
||||
R: Lubomir Rintel <lkundrak@v3.sk>
|
||||
|
|
|
|||
|
|
@ -375,5 +375,6 @@ config KEXEC_FILE
|
|||
|
||||
endmenu
|
||||
|
||||
source "drivers/firmware/Kconfig"
|
||||
|
||||
source "drivers/parisc/Kconfig"
|
||||
|
|
|
|||
|
|
@ -52,10 +52,6 @@ CONFIG_BLK_DEV_LOOP=y
|
|||
CONFIG_BLK_DEV_CRYPTOLOOP=y
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=6144
|
||||
CONFIG_IDE=y
|
||||
CONFIG_BLK_DEV_IDECD=y
|
||||
CONFIG_BLK_DEV_GENERIC=y
|
||||
CONFIG_BLK_DEV_NS87415=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_CHR_DEV_ST=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
|
|
@ -65,6 +61,8 @@ CONFIG_SCSI_SYM53C8XX_2=y
|
|||
CONFIG_SCSI_ZALON=y
|
||||
CONFIG_SCSI_DH=y
|
||||
CONFIG_ATA=y
|
||||
CONFIG_ATA_GENERIC=y
|
||||
CONFIG_PATA_NS87415=y
|
||||
CONFIG_MD=y
|
||||
CONFIG_BLK_DEV_MD=m
|
||||
CONFIG_MD_LINEAR=m
|
||||
|
|
|
|||
|
|
@ -58,11 +58,6 @@ CONFIG_PCI_IOV=y
|
|||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_DEVTMPFS_MOUNT=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_IDE=y
|
||||
CONFIG_IDE_GD=m
|
||||
CONFIG_IDE_GD_ATAPI=y
|
||||
CONFIG_BLK_DEV_IDECD=m
|
||||
CONFIG_BLK_DEV_NS87415=y
|
||||
# CONFIG_SCSI_PROC_FS is not set
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
CONFIG_BLK_DEV_SR=y
|
||||
|
|
@ -76,6 +71,7 @@ CONFIG_SCSI_ZALON=y
|
|||
CONFIG_SCSI_QLA_ISCSI=m
|
||||
CONFIG_SCSI_DH=y
|
||||
CONFIG_ATA=y
|
||||
CONFIG_PATA_NS87415=y
|
||||
CONFIG_PATA_SIL680=y
|
||||
CONFIG_ATA_GENERIC=y
|
||||
CONFIG_MD=y
|
||||
|
|
|
|||
|
|
@ -2,11 +2,15 @@
|
|||
#ifndef __ASM_BARRIER_H
|
||||
#define __ASM_BARRIER_H
|
||||
|
||||
#include <asm/alternative.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/* The synchronize caches instruction executes as a nop on systems in
|
||||
which all memory references are performed in order. */
|
||||
#define synchronize_caches() __asm__ __volatile__ ("sync" : : : "memory")
|
||||
#define synchronize_caches() asm volatile("sync" \
|
||||
ALTERNATIVE(ALT_COND_NO_SMP, INSN_NOP) \
|
||||
: : : "memory")
|
||||
|
||||
#if defined(CONFIG_SMP)
|
||||
#define mb() do { synchronize_caches(); } while (0)
|
||||
|
|
|
|||
|
|
@ -14,22 +14,22 @@
|
|||
extern void __xchg_called_with_bad_pointer(void);
|
||||
|
||||
/* __xchg32/64 defined in arch/parisc/lib/bitops.c */
|
||||
extern unsigned long __xchg8(char, char *);
|
||||
extern unsigned long __xchg32(int, int *);
|
||||
extern unsigned long __xchg8(char, volatile char *);
|
||||
extern unsigned long __xchg32(int, volatile int *);
|
||||
#ifdef CONFIG_64BIT
|
||||
extern unsigned long __xchg64(unsigned long, unsigned long *);
|
||||
extern unsigned long __xchg64(unsigned long, volatile unsigned long *);
|
||||
#endif
|
||||
|
||||
/* optimizer better get rid of switch since size is a constant */
|
||||
static inline unsigned long
|
||||
__xchg(unsigned long x, __volatile__ void *ptr, int size)
|
||||
__xchg(unsigned long x, volatile void *ptr, int size)
|
||||
{
|
||||
switch (size) {
|
||||
#ifdef CONFIG_64BIT
|
||||
case 8: return __xchg64(x, (unsigned long *) ptr);
|
||||
case 8: return __xchg64(x, (volatile unsigned long *) ptr);
|
||||
#endif
|
||||
case 4: return __xchg32((int) x, (int *) ptr);
|
||||
case 1: return __xchg8((char) x, (char *) ptr);
|
||||
case 4: return __xchg32((int) x, (volatile int *) ptr);
|
||||
case 1: return __xchg8((char) x, (volatile char *) ptr);
|
||||
}
|
||||
__xchg_called_with_bad_pointer();
|
||||
return x;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ static inline void
|
|||
_futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags)
|
||||
{
|
||||
extern u32 lws_lock_start[];
|
||||
long index = ((long)uaddr & 0xf0) >> 2;
|
||||
long index = ((long)uaddr & 0x3f8) >> 1;
|
||||
arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index];
|
||||
local_irq_save(*flags);
|
||||
arch_spin_lock(s);
|
||||
|
|
@ -26,7 +26,7 @@ static inline void
|
|||
_futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags)
|
||||
{
|
||||
extern u32 lws_lock_start[];
|
||||
long index = ((long)uaddr & 0xf0) >> 2;
|
||||
long index = ((long)uaddr & 0x3f8) >> 1;
|
||||
arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index];
|
||||
arch_spin_unlock(s);
|
||||
local_irq_restore(*flags);
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
#include <uapi/asm/socket.h>
|
||||
|
||||
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
|
||||
* have to define SOCK_NONBLOCK to a different value here.
|
||||
/* O_NONBLOCK clashed with the bits used for socket types. Therefore we
|
||||
* had to define SOCK_NONBLOCK to a different value here.
|
||||
*/
|
||||
#define SOCK_NONBLOCK 0x40000000
|
||||
|
||||
|
|
|
|||
|
|
@ -10,13 +10,21 @@
|
|||
static inline int arch_spin_is_locked(arch_spinlock_t *x)
|
||||
{
|
||||
volatile unsigned int *a = __ldcw_align(x);
|
||||
return *a == 0;
|
||||
return READ_ONCE(*a) == 0;
|
||||
}
|
||||
|
||||
#define arch_spin_lock(lock) arch_spin_lock_flags(lock, 0)
|
||||
static inline void arch_spin_lock(arch_spinlock_t *x)
|
||||
{
|
||||
volatile unsigned int *a;
|
||||
|
||||
a = __ldcw_align(x);
|
||||
while (__ldcw(a) == 0)
|
||||
while (*a == 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
static inline void arch_spin_lock_flags(arch_spinlock_t *x,
|
||||
unsigned long flags)
|
||||
unsigned long flags)
|
||||
{
|
||||
volatile unsigned int *a;
|
||||
|
||||
|
|
@ -25,10 +33,8 @@ static inline void arch_spin_lock_flags(arch_spinlock_t *x,
|
|||
while (*a == 0)
|
||||
if (flags & PSW_SM_I) {
|
||||
local_irq_enable();
|
||||
cpu_relax();
|
||||
local_irq_disable();
|
||||
} else
|
||||
cpu_relax();
|
||||
}
|
||||
}
|
||||
#define arch_spin_lock_flags arch_spin_lock_flags
|
||||
|
||||
|
|
@ -44,12 +50,9 @@ static inline void arch_spin_unlock(arch_spinlock_t *x)
|
|||
static inline int arch_spin_trylock(arch_spinlock_t *x)
|
||||
{
|
||||
volatile unsigned int *a;
|
||||
int ret;
|
||||
|
||||
a = __ldcw_align(x);
|
||||
ret = __ldcw(a) != 0;
|
||||
|
||||
return ret;
|
||||
return __ldcw(a) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -3,22 +3,19 @@
|
|||
#define _PARISC_FCNTL_H
|
||||
|
||||
#define O_APPEND 000000010
|
||||
#define O_BLKSEEK 000000100 /* HPUX only */
|
||||
#define O_CREAT 000000400 /* not fcntl */
|
||||
#define O_EXCL 000002000 /* not fcntl */
|
||||
#define O_LARGEFILE 000004000
|
||||
#define __O_SYNC 000100000
|
||||
#define O_SYNC (__O_SYNC|O_DSYNC)
|
||||
#define O_NONBLOCK 000200004 /* HPUX has separate NDELAY & NONBLOCK */
|
||||
#define O_NONBLOCK 000200000
|
||||
#define O_NOCTTY 000400000 /* not fcntl */
|
||||
#define O_DSYNC 001000000 /* HPUX only */
|
||||
#define O_RSYNC 002000000 /* HPUX only */
|
||||
#define O_DSYNC 001000000
|
||||
#define O_NOATIME 004000000
|
||||
#define O_CLOEXEC 010000000 /* set close_on_exec */
|
||||
|
||||
#define O_DIRECTORY 000010000 /* must be a directory */
|
||||
#define O_NOFOLLOW 000000200 /* don't follow links */
|
||||
#define O_INVISIBLE 004000000 /* invisible I/O, for DMAPI/XDSM */
|
||||
|
||||
#define O_PATH 020000000
|
||||
#define __O_TMPFILE 040000000
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#define MAP_STACK 0x40000 /* give out an address that is best suited for process/thread stacks */
|
||||
#define MAP_HUGETLB 0x80000 /* create a huge page mapping */
|
||||
#define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED which doesn't unmap underlying mapping */
|
||||
#define MAP_UNINITIALIZED 0 /* uninitialized anonymous mmap */
|
||||
|
||||
#define MS_SYNC 1 /* synchronous memory sync */
|
||||
#define MS_ASYNC 2 /* sync memory asynchronously */
|
||||
|
|
|
|||
|
|
@ -35,11 +35,11 @@
|
|||
#define SIGURG 29
|
||||
#define SIGXFSZ 30
|
||||
#define SIGUNUSED 31
|
||||
#define SIGSYS 31 /* Linux doesn't use this */
|
||||
#define SIGSYS 31
|
||||
|
||||
/* These should not be considered constants from userland. */
|
||||
#define SIGRTMIN 32
|
||||
#define SIGRTMAX _NSIG /* it's 44 under HP/UX */
|
||||
#define SIGRTMAX _NSIG
|
||||
|
||||
/*
|
||||
* SA_FLAGS values:
|
||||
|
|
@ -61,7 +61,6 @@
|
|||
#define SA_NODEFER 0x00000020
|
||||
#define SA_RESTART 0x00000040
|
||||
#define SA_NOCLDWAIT 0x00000080
|
||||
#define _SA_SIGGFAULT 0x00000100 /* HPUX */
|
||||
|
||||
#define SA_NOMASK SA_NODEFER
|
||||
#define SA_ONESHOT SA_RESETHAND
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ fi
|
|||
|
||||
# Default install
|
||||
|
||||
if [ "$(basename $2)" = "zImage" ]; then
|
||||
if [ "$(basename $2)" = "vmlinuz" ]; then
|
||||
# Compressed install
|
||||
echo "Installing compressed kernel"
|
||||
base=vmlinuz
|
||||
|
|
|
|||
|
|
@ -383,12 +383,12 @@ EXPORT_SYMBOL(flush_kernel_icache_range_asm);
|
|||
static unsigned long parisc_cache_flush_threshold __ro_after_init = FLUSH_THRESHOLD;
|
||||
|
||||
#define FLUSH_TLB_THRESHOLD (16*1024) /* 16 KiB minimum TLB threshold */
|
||||
static unsigned long parisc_tlb_flush_threshold __ro_after_init = FLUSH_TLB_THRESHOLD;
|
||||
static unsigned long parisc_tlb_flush_threshold __ro_after_init = ~0UL;
|
||||
|
||||
void __init parisc_setup_cache_timing(void)
|
||||
{
|
||||
unsigned long rangetime, alltime;
|
||||
unsigned long size, start;
|
||||
unsigned long size;
|
||||
unsigned long threshold;
|
||||
|
||||
alltime = mfctl(16);
|
||||
|
|
@ -422,14 +422,9 @@ void __init parisc_setup_cache_timing(void)
|
|||
goto set_tlb_threshold;
|
||||
}
|
||||
|
||||
size = 0;
|
||||
start = (unsigned long) _text;
|
||||
size = (unsigned long)_end - (unsigned long)_text;
|
||||
rangetime = mfctl(16);
|
||||
while (start < (unsigned long) _end) {
|
||||
flush_tlb_kernel_range(start, start + PAGE_SIZE);
|
||||
start += PAGE_SIZE;
|
||||
size += PAGE_SIZE;
|
||||
}
|
||||
flush_tlb_kernel_range((unsigned long)_text, (unsigned long)_end);
|
||||
rangetime = mfctl(16) - rangetime;
|
||||
|
||||
alltime = mfctl(16);
|
||||
|
|
@ -444,8 +439,11 @@ void __init parisc_setup_cache_timing(void)
|
|||
threshold/1024);
|
||||
|
||||
set_tlb_threshold:
|
||||
if (threshold > parisc_tlb_flush_threshold)
|
||||
if (threshold > FLUSH_TLB_THRESHOLD)
|
||||
parisc_tlb_flush_threshold = threshold;
|
||||
else
|
||||
parisc_tlb_flush_threshold = FLUSH_TLB_THRESHOLD;
|
||||
|
||||
printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
|
||||
parisc_tlb_flush_threshold/1024);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -899,20 +899,20 @@ intr_check_sig:
|
|||
* Only do signals if we are returning to user space
|
||||
*/
|
||||
LDREG PT_IASQ0(%r16), %r20
|
||||
cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* backward */
|
||||
cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* forward */
|
||||
LDREG PT_IASQ1(%r16), %r20
|
||||
cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* backward */
|
||||
|
||||
/* NOTE: We need to enable interrupts if we have to deliver
|
||||
* signals. We used to do this earlier but it caused kernel
|
||||
* stack overflows. */
|
||||
ssm PSW_SM_I, %r0
|
||||
cmpib,COND(=),n LINUX_GATEWAY_SPACE, %r20, intr_restore /* forward */
|
||||
|
||||
copy %r0, %r25 /* long in_syscall = 0 */
|
||||
#ifdef CONFIG_64BIT
|
||||
ldo -16(%r30),%r29 /* Reference param save area */
|
||||
#endif
|
||||
|
||||
/* NOTE: We need to enable interrupts if we have to deliver
|
||||
* signals. We used to do this earlier but it caused kernel
|
||||
* stack overflows. */
|
||||
ssm PSW_SM_I, %r0
|
||||
|
||||
BL do_notify_resume,%r2
|
||||
copy %r16, %r26 /* struct pt_regs *regs */
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/mmzone.h>
|
||||
|
|
@ -641,4 +642,33 @@ void __init do_device_inventory(void)
|
|||
if (pa_serialize_tlb_flushes)
|
||||
pr_info("Merced bus found: Enable PxTLB serialization.\n");
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FW_CFG_SYSFS)
|
||||
if (running_on_qemu) {
|
||||
struct resource res[3] = {0,};
|
||||
unsigned int base;
|
||||
|
||||
base = ((unsigned long long) PAGE0->pad0[2] << 32)
|
||||
| PAGE0->pad0[3]; /* SeaBIOS stored it here */
|
||||
|
||||
res[0].name = "fw_cfg";
|
||||
res[0].start = base;
|
||||
res[0].end = base + 8 - 1;
|
||||
res[0].flags = IORESOURCE_MEM;
|
||||
|
||||
res[1].name = "ctrl";
|
||||
res[1].start = 0;
|
||||
res[1].flags = IORESOURCE_REG;
|
||||
|
||||
res[2].name = "data";
|
||||
res[2].start = 4;
|
||||
res[2].flags = IORESOURCE_REG;
|
||||
|
||||
if (base) {
|
||||
pr_info("Found qemu fw_cfg interface at %#08x\n", base);
|
||||
platform_device_register_simple("fw_cfg",
|
||||
PLATFORM_DEVID_NONE, res, 3);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,9 +173,12 @@ ipi_interrupt(int irq, void *dev_id)
|
|||
this_cpu, which);
|
||||
return IRQ_NONE;
|
||||
} /* Switch */
|
||||
/* let in any pending interrupts */
|
||||
local_irq_enable();
|
||||
local_irq_disable();
|
||||
|
||||
/* before doing more, let in any pending interrupts */
|
||||
if (ops) {
|
||||
local_irq_enable();
|
||||
local_irq_disable();
|
||||
}
|
||||
} /* while (ops) */
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
|
|
|
|||
|
|
@ -571,8 +571,8 @@ lws_compare_and_swap:
|
|||
ldil L%lws_lock_start, %r20
|
||||
ldo R%lws_lock_start(%r20), %r28
|
||||
|
||||
/* Extract four bits from r26 and hash lock (Bits 4-7) */
|
||||
extru %r26, 27, 4, %r20
|
||||
/* Extract eight bits from r26 and hash lock (Bits 3-11) */
|
||||
extru %r26, 28, 8, %r20
|
||||
|
||||
/* Find lock to use, the hash is either one of 0 to
|
||||
15, multiplied by 16 (keep it 16-byte aligned)
|
||||
|
|
@ -761,8 +761,8 @@ cas2_lock_start:
|
|||
ldil L%lws_lock_start, %r20
|
||||
ldo R%lws_lock_start(%r20), %r28
|
||||
|
||||
/* Extract four bits from r26 and hash lock (Bits 4-7) */
|
||||
extru %r26, 27, 4, %r20
|
||||
/* Extract eight bits from r26 and hash lock (Bits 3-11) */
|
||||
extru %r26, 28, 8, %r20
|
||||
|
||||
/* Find lock to use, the hash is either one of 0 to
|
||||
15, multiplied by 16 (keep it 16-byte aligned)
|
||||
|
|
@ -950,7 +950,7 @@ END(sys_call_table64)
|
|||
.align L1_CACHE_BYTES
|
||||
ENTRY(lws_lock_start)
|
||||
/* lws locks */
|
||||
.rept 16
|
||||
.rept 256
|
||||
/* Keep locks aligned at 16-bytes */
|
||||
.word 1
|
||||
.word 0
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = {
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
unsigned long __xchg64(unsigned long x, unsigned long *ptr)
|
||||
unsigned long __xchg64(unsigned long x, volatile unsigned long *ptr)
|
||||
{
|
||||
unsigned long temp, flags;
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ unsigned long __xchg64(unsigned long x, unsigned long *ptr)
|
|||
}
|
||||
#endif
|
||||
|
||||
unsigned long __xchg32(int x, int *ptr)
|
||||
unsigned long __xchg32(int x, volatile int *ptr)
|
||||
{
|
||||
unsigned long flags;
|
||||
long temp;
|
||||
|
|
@ -43,7 +43,7 @@ unsigned long __xchg32(int x, int *ptr)
|
|||
}
|
||||
|
||||
|
||||
unsigned long __xchg8(char x, char *ptr)
|
||||
unsigned long __xchg8(char x, volatile char *ptr)
|
||||
{
|
||||
unsigned long flags;
|
||||
long temp;
|
||||
|
|
|
|||
|
|
@ -346,6 +346,16 @@ u64 ioread64be(const void __iomem *addr)
|
|||
return *((u64 *)addr);
|
||||
}
|
||||
|
||||
u64 ioread64_hi_lo(const void __iomem *addr)
|
||||
{
|
||||
u32 low, high;
|
||||
|
||||
high = ioread32(addr + sizeof(u32));
|
||||
low = ioread32(addr);
|
||||
|
||||
return low + ((u64)high << 32);
|
||||
}
|
||||
|
||||
void iowrite8(u8 datum, void __iomem *addr)
|
||||
{
|
||||
if (unlikely(INDIRECT_ADDR(addr))) {
|
||||
|
|
@ -409,6 +419,12 @@ void iowrite64be(u64 datum, void __iomem *addr)
|
|||
}
|
||||
}
|
||||
|
||||
void iowrite64_hi_lo(u64 val, void __iomem *addr)
|
||||
{
|
||||
iowrite32(val >> 32, addr + sizeof(u32));
|
||||
iowrite32(val, addr);
|
||||
}
|
||||
|
||||
/* Repeating interfaces */
|
||||
|
||||
void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count)
|
||||
|
|
@ -511,6 +527,7 @@ EXPORT_SYMBOL(ioread32);
|
|||
EXPORT_SYMBOL(ioread32be);
|
||||
EXPORT_SYMBOL(ioread64);
|
||||
EXPORT_SYMBOL(ioread64be);
|
||||
EXPORT_SYMBOL(ioread64_hi_lo);
|
||||
EXPORT_SYMBOL(iowrite8);
|
||||
EXPORT_SYMBOL(iowrite16);
|
||||
EXPORT_SYMBOL(iowrite16be);
|
||||
|
|
@ -518,6 +535,7 @@ EXPORT_SYMBOL(iowrite32);
|
|||
EXPORT_SYMBOL(iowrite32be);
|
||||
EXPORT_SYMBOL(iowrite64);
|
||||
EXPORT_SYMBOL(iowrite64be);
|
||||
EXPORT_SYMBOL(iowrite64_hi_lo);
|
||||
EXPORT_SYMBOL(ioread8_rep);
|
||||
EXPORT_SYMBOL(ioread16_rep);
|
||||
EXPORT_SYMBOL(ioread32_rep);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ typedef int (*hyperv_fill_flush_list_func)(
|
|||
#define hv_enable_vdso_clocksource() \
|
||||
vclocks_set_used(VDSO_CLOCKMODE_HVCLOCK);
|
||||
#define hv_get_raw_timer() rdtsc_ordered()
|
||||
#define hv_get_vector() HYPERVISOR_CALLBACK_VECTOR
|
||||
|
||||
/*
|
||||
* Reference to pv_ops must be inline so objtool
|
||||
|
|
|
|||
|
|
@ -55,9 +55,14 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_callback)
|
|||
set_irq_regs(old_regs);
|
||||
}
|
||||
|
||||
void hv_setup_vmbus_irq(void (*handler)(void))
|
||||
int hv_setup_vmbus_irq(int irq, void (*handler)(void))
|
||||
{
|
||||
/*
|
||||
* The 'irq' argument is ignored on x86/x64 because a hard-coded
|
||||
* interrupt vector is used for Hyper-V interrupts.
|
||||
*/
|
||||
vmbus_handler = handler;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hv_remove_vmbus_irq(void)
|
||||
|
|
|
|||
|
|
@ -523,7 +523,7 @@ config MEMMAP_CACHEATTR
|
|||
2: cache bypass,
|
||||
4: WB cached,
|
||||
f: illegal.
|
||||
For ful MMU:
|
||||
For full MMU:
|
||||
bit 0: executable,
|
||||
bit 1: writable,
|
||||
bits 2..3:
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ config RASPBERRYPI_FIRMWARE
|
|||
|
||||
config FW_CFG_SYSFS
|
||||
tristate "QEMU fw_cfg device support in sysfs"
|
||||
depends on SYSFS && (ARM || ARM64 || PPC_PMAC || SPARC || X86)
|
||||
depends on SYSFS && (ARM || ARM64 || PARISC || PPC_PMAC || SPARC || X86)
|
||||
depends on HAS_IOPORT_MAP
|
||||
default n
|
||||
help
|
||||
|
|
|
|||
|
|
@ -215,6 +215,9 @@ static void fw_cfg_io_cleanup(void)
|
|||
# define FW_CFG_CTRL_OFF 0x08
|
||||
# define FW_CFG_DATA_OFF 0x00
|
||||
# define FW_CFG_DMA_OFF 0x10
|
||||
# elif defined(CONFIG_PARISC) /* parisc */
|
||||
# define FW_CFG_CTRL_OFF 0x00
|
||||
# define FW_CFG_DATA_OFF 0x04
|
||||
# elif (defined(CONFIG_PPC_PMAC) || defined(CONFIG_SPARC32)) /* ppc/mac,sun4m */
|
||||
# define FW_CFG_CTRL_OFF 0x00
|
||||
# define FW_CFG_DATA_OFF 0x02
|
||||
|
|
|
|||
|
|
@ -397,6 +397,15 @@ config HID_GOOGLE_HAMMER
|
|||
help
|
||||
Say Y here if you have a Google Hammer device.
|
||||
|
||||
config HID_VIVALDI
|
||||
tristate "Vivaldi Keyboard"
|
||||
depends on HID
|
||||
help
|
||||
Say Y here if you want to enable support for Vivaldi keyboards.
|
||||
|
||||
Vivaldi keyboards use a vendor-specific (Google) HID usage to report
|
||||
how the keys in the top row are physically ordered.
|
||||
|
||||
config HID_GT683R
|
||||
tristate "MSI GT68xR LED support"
|
||||
depends on LEDS_CLASS && USB_HID
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ obj-$(CONFIG_HID_GEMBIRD) += hid-gembird.o
|
|||
obj-$(CONFIG_HID_GFRM) += hid-gfrm.o
|
||||
obj-$(CONFIG_HID_GLORIOUS) += hid-glorious.o
|
||||
obj-$(CONFIG_HID_GOOGLE_HAMMER) += hid-google-hammer.o
|
||||
obj-$(CONFIG_HID_VIVALDI) += hid-vivaldi.o
|
||||
obj-$(CONFIG_HID_GT683R) += hid-gt683r.o
|
||||
obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
|
||||
obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o
|
||||
|
|
|
|||
|
|
@ -526,7 +526,7 @@ static int u1_init(struct hid_device *hdev, struct alps_dev *pri_data)
|
|||
|
||||
ret = u1_read_write_register(hdev, ADDRESS_U1_NUM_SENS_Y,
|
||||
&sen_line_num_y, 0, true);
|
||||
if (ret < 0) {
|
||||
if (ret < 0) {
|
||||
dev_err(&hdev->dev, "failed U1_NUM_SENS_Y (%d)\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -503,6 +503,8 @@ static const struct hid_device_id apple_devices[] = {
|
|||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS),
|
||||
.driver_data = APPLE_HAS_FN },
|
||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
|
||||
|
|
|
|||
|
|
@ -814,6 +814,13 @@ static void hid_scan_collection(struct hid_parser *parser, unsigned type)
|
|||
|
||||
if ((parser->global.usage_page << 16) >= HID_UP_MSVENDOR)
|
||||
parser->scan_flags |= HID_SCAN_FLAG_VENDOR_SPECIFIC;
|
||||
|
||||
if ((parser->global.usage_page << 16) == HID_UP_GOOGLEVENDOR)
|
||||
for (i = 0; i < parser->local.usage_index; i++)
|
||||
if (parser->local.usage[i] ==
|
||||
(HID_UP_GOOGLEVENDOR | 0x0001))
|
||||
parser->device->group =
|
||||
HID_GROUP_VIVALDI;
|
||||
}
|
||||
|
||||
static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
|
||||
|
|
@ -920,7 +927,7 @@ static int hid_scan_report(struct hid_device *hid)
|
|||
/**
|
||||
* hid_parse_report - parse device report
|
||||
*
|
||||
* @device: hid device
|
||||
* @hid: hid device
|
||||
* @start: report start
|
||||
* @size: report size
|
||||
*
|
||||
|
|
@ -945,7 +952,7 @@ static const char * const hid_report_names[] = {
|
|||
/**
|
||||
* hid_validate_values - validate existing device report's value indexes
|
||||
*
|
||||
* @device: hid device
|
||||
* @hid: hid device
|
||||
* @type: which report type to examine
|
||||
* @id: which report ID to examine (0 for first)
|
||||
* @field_index: which report field to examine
|
||||
|
|
@ -1444,7 +1451,7 @@ static int search(__s32 *array, __s32 value, unsigned n)
|
|||
* hid_match_report - check if driver's raw_event should be called
|
||||
*
|
||||
* @hid: hid device
|
||||
* @report_type: type to match against
|
||||
* @report: hid report to match against
|
||||
*
|
||||
* compare hid->driver->report_table->report_type to report->type
|
||||
*/
|
||||
|
|
@ -2120,7 +2127,7 @@ struct hid_dynid {
|
|||
|
||||
/**
|
||||
* store_new_id - add a new HID device ID to this driver and re-probe devices
|
||||
* @driver: target device driver
|
||||
* @drv: target device driver
|
||||
* @buf: buffer for scanning device ID data
|
||||
* @count: input size
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1235,6 +1235,7 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
struct cp2112_device *dev;
|
||||
u8 buf[3];
|
||||
struct cp2112_smbus_config_report config;
|
||||
struct gpio_irq_chip *girq;
|
||||
int ret;
|
||||
|
||||
dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL);
|
||||
|
|
@ -1338,6 +1339,15 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
dev->gc.can_sleep = 1;
|
||||
dev->gc.parent = &hdev->dev;
|
||||
|
||||
girq = &dev->gc.irq;
|
||||
girq->chip = &cp2112_gpio_irqchip;
|
||||
/* The event comes from the outside so no parent handler */
|
||||
girq->parent_handler = NULL;
|
||||
girq->num_parents = 0;
|
||||
girq->parents = NULL;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_simple_irq;
|
||||
|
||||
ret = gpiochip_add_data(&dev->gc, dev);
|
||||
if (ret < 0) {
|
||||
hid_err(hdev, "error registering gpio chip\n");
|
||||
|
|
@ -1353,17 +1363,8 @@ static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||
chmod_sysfs_attrs(hdev);
|
||||
hid_hw_power(hdev, PM_HINT_NORMAL);
|
||||
|
||||
ret = gpiochip_irqchip_add(&dev->gc, &cp2112_gpio_irqchip, 0,
|
||||
handle_simple_irq, IRQ_TYPE_NONE);
|
||||
if (ret) {
|
||||
dev_err(dev->gc.parent, "failed to add IRQ chip\n");
|
||||
goto err_sysfs_remove;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
err_sysfs_remove:
|
||||
sysfs_remove_group(&hdev->dev.kobj, &cp2112_attr_group);
|
||||
err_gpiochip_remove:
|
||||
gpiochip_remove(&dev->gc);
|
||||
err_free_i2c:
|
||||
|
|
|
|||
|
|
@ -1101,11 +1101,6 @@ static ssize_t hid_debug_events_read(struct file *file, char __user *buffer,
|
|||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
while (kfifo_is_empty(&list->hid_debug_fifo)) {
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
|
|
@ -1122,6 +1117,11 @@ static ssize_t hid_debug_events_read(struct file *file, char __user *buffer,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
/* allow O_NONBLOCK from other threads */
|
||||
mutex_unlock(&list->read_mutex);
|
||||
schedule();
|
||||
|
|
|
|||
|
|
@ -727,6 +727,8 @@
|
|||
#define USB_DEVICE_ID_LENOVO_TP10UBKBD 0x6062
|
||||
#define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067
|
||||
#define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085
|
||||
#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3
|
||||
#define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5
|
||||
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d
|
||||
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019
|
||||
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E 0x602e
|
||||
|
|
@ -1126,6 +1128,7 @@
|
|||
#define USB_DEVICE_ID_SYNAPTICS_DELL_K12A 0x2819
|
||||
#define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012 0x2968
|
||||
#define USB_DEVICE_ID_SYNAPTICS_TP_V103 0x5710
|
||||
#define USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003 0x73f5
|
||||
#define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5 0x81a7
|
||||
|
||||
#define USB_VENDOR_ID_TEXAS_INSTRUMENTS 0x2047
|
||||
|
|
|
|||
|
|
@ -797,7 +797,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
|||
case 0x3b: /* Battery Strength */
|
||||
hidinput_setup_battery(device, HID_INPUT_REPORT, field);
|
||||
usage->type = EV_PWR;
|
||||
goto ignore;
|
||||
return;
|
||||
|
||||
case 0x3c: /* Invert */
|
||||
map_key_clear(BTN_TOOL_RUBBER);
|
||||
|
|
@ -1059,7 +1059,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
|
|||
case HID_DC_BATTERYSTRENGTH:
|
||||
hidinput_setup_battery(device, HID_INPUT_REPORT, field);
|
||||
usage->type = EV_PWR;
|
||||
goto ignore;
|
||||
return;
|
||||
}
|
||||
goto unknown;
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ static const struct hid_device_id ite_devices[] = {
|
|||
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_SYNAPTICS,
|
||||
USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) },
|
||||
/* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */
|
||||
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_SYNAPTICS,
|
||||
USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, ite_devices);
|
||||
|
|
|
|||
|
|
@ -820,7 +820,7 @@ static void logi_dj_recv_queue_unknown_work(struct dj_receiver_dev *djrcv_dev)
|
|||
{
|
||||
struct dj_workitem workitem = { .type = WORKITEM_TYPE_UNKNOWN };
|
||||
|
||||
/* Rate limit queries done because of unhandeled reports to 2/sec */
|
||||
/* Rate limit queries done because of unhandled reports to 2/sec */
|
||||
if (time_before(jiffies, djrcv_dev->last_query + HZ / 2))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -1973,6 +1973,18 @@ static const struct hid_device_id mt_devices[] = {
|
|||
HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_7010) },
|
||||
|
||||
/* Lenovo X1 TAB Gen 2 */
|
||||
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
|
||||
HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
|
||||
USB_VENDOR_ID_LENOVO,
|
||||
USB_DEVICE_ID_LENOVO_X1_TAB) },
|
||||
|
||||
/* Lenovo X1 TAB Gen 3 */
|
||||
{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT,
|
||||
HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
|
||||
USB_VENDOR_ID_LENOVO,
|
||||
USB_DEVICE_ID_LENOVO_X1_TAB3) },
|
||||
|
||||
/* MosArt panels */
|
||||
{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
|
||||
MT_USB_DEVICE(USB_VENDOR_ID_ASUS,
|
||||
|
|
|
|||
|
|
@ -294,31 +294,40 @@ static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj,
|
|||
struct kone_device *kone = hid_get_drvdata(dev_get_drvdata(dev));
|
||||
struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
|
||||
int retval = 0, difference, old_profile;
|
||||
struct kone_settings *settings = (struct kone_settings *)buf;
|
||||
|
||||
/* I need to get my data in one piece */
|
||||
if (off != 0 || count != sizeof(struct kone_settings))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&kone->kone_lock);
|
||||
difference = memcmp(buf, &kone->settings, sizeof(struct kone_settings));
|
||||
difference = memcmp(settings, &kone->settings,
|
||||
sizeof(struct kone_settings));
|
||||
if (difference) {
|
||||
retval = kone_set_settings(usb_dev,
|
||||
(struct kone_settings const *)buf);
|
||||
if (retval) {
|
||||
mutex_unlock(&kone->kone_lock);
|
||||
return retval;
|
||||
if (settings->startup_profile < 1 ||
|
||||
settings->startup_profile > 5) {
|
||||
retval = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
retval = kone_set_settings(usb_dev, settings);
|
||||
if (retval)
|
||||
goto unlock;
|
||||
|
||||
old_profile = kone->settings.startup_profile;
|
||||
memcpy(&kone->settings, buf, sizeof(struct kone_settings));
|
||||
memcpy(&kone->settings, settings, sizeof(struct kone_settings));
|
||||
|
||||
kone_profile_activated(kone, kone->settings.startup_profile);
|
||||
|
||||
if (kone->settings.startup_profile != old_profile)
|
||||
kone_profile_report(kone, kone->settings.startup_profile);
|
||||
}
|
||||
unlock:
|
||||
mutex_unlock(&kone->kone_lock);
|
||||
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
return sizeof(struct kone_settings);
|
||||
}
|
||||
static BIN_ATTR(settings, 0660, kone_sysfs_read_settings,
|
||||
|
|
|
|||
144
drivers/hid/hid-vivaldi.c
Normal file
144
drivers/hid/hid-vivaldi.c
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* HID support for Vivaldi Keyboard
|
||||
*
|
||||
* Copyright 2020 Google LLC.
|
||||
* Author: Sean O'Brien <seobrien@chromium.org>
|
||||
*/
|
||||
|
||||
#include <linux/hid.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#define MIN_FN_ROW_KEY 1
|
||||
#define MAX_FN_ROW_KEY 24
|
||||
#define HID_VD_FN_ROW_PHYSMAP 0x00000001
|
||||
#define HID_USAGE_FN_ROW_PHYSMAP (HID_UP_GOOGLEVENDOR | HID_VD_FN_ROW_PHYSMAP)
|
||||
|
||||
static struct hid_driver hid_vivaldi;
|
||||
|
||||
struct vivaldi_data {
|
||||
u32 function_row_physmap[MAX_FN_ROW_KEY - MIN_FN_ROW_KEY + 1];
|
||||
int max_function_row_key;
|
||||
};
|
||||
|
||||
static ssize_t function_row_physmap_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct hid_device *hdev = to_hid_device(dev);
|
||||
struct vivaldi_data *drvdata = hid_get_drvdata(hdev);
|
||||
ssize_t size = 0;
|
||||
int i;
|
||||
|
||||
if (!drvdata->max_function_row_key)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < drvdata->max_function_row_key; i++)
|
||||
size += sprintf(buf + size, "%02X ",
|
||||
drvdata->function_row_physmap[i]);
|
||||
size += sprintf(buf + size, "\n");
|
||||
return size;
|
||||
}
|
||||
|
||||
DEVICE_ATTR_RO(function_row_physmap);
|
||||
static struct attribute *sysfs_attrs[] = {
|
||||
&dev_attr_function_row_physmap.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group input_attribute_group = {
|
||||
.attrs = sysfs_attrs
|
||||
};
|
||||
|
||||
static int vivaldi_probe(struct hid_device *hdev,
|
||||
const struct hid_device_id *id)
|
||||
{
|
||||
struct vivaldi_data *drvdata;
|
||||
int ret;
|
||||
|
||||
drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL);
|
||||
hid_set_drvdata(hdev, drvdata);
|
||||
|
||||
ret = hid_parse(hdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
}
|
||||
|
||||
static void vivaldi_feature_mapping(struct hid_device *hdev,
|
||||
struct hid_field *field,
|
||||
struct hid_usage *usage)
|
||||
{
|
||||
struct vivaldi_data *drvdata = hid_get_drvdata(hdev);
|
||||
int fn_key;
|
||||
int ret;
|
||||
u32 report_len;
|
||||
u8 *buf;
|
||||
|
||||
if (field->logical != HID_USAGE_FN_ROW_PHYSMAP ||
|
||||
(usage->hid & HID_USAGE_PAGE) != HID_UP_ORDINAL)
|
||||
return;
|
||||
|
||||
fn_key = (usage->hid & HID_USAGE);
|
||||
if (fn_key < MIN_FN_ROW_KEY || fn_key > MAX_FN_ROW_KEY)
|
||||
return;
|
||||
if (fn_key > drvdata->max_function_row_key)
|
||||
drvdata->max_function_row_key = fn_key;
|
||||
|
||||
buf = hid_alloc_report_buf(field->report, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return;
|
||||
|
||||
report_len = hid_report_len(field->report);
|
||||
ret = hid_hw_raw_request(hdev, field->report->id, buf,
|
||||
report_len, HID_FEATURE_REPORT,
|
||||
HID_REQ_GET_REPORT);
|
||||
if (ret < 0) {
|
||||
dev_warn(&hdev->dev, "failed to fetch feature %d\n",
|
||||
field->report->id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf,
|
||||
report_len, 0);
|
||||
if (ret) {
|
||||
dev_warn(&hdev->dev, "failed to report feature %d\n",
|
||||
field->report->id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
drvdata->function_row_physmap[fn_key - MIN_FN_ROW_KEY] =
|
||||
field->value[usage->usage_index];
|
||||
|
||||
out:
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
static int vivaldi_input_configured(struct hid_device *hdev,
|
||||
struct hid_input *hidinput)
|
||||
{
|
||||
return sysfs_create_group(&hdev->dev.kobj, &input_attribute_group);
|
||||
}
|
||||
|
||||
static const struct hid_device_id vivaldi_table[] = {
|
||||
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_VIVALDI, HID_ANY_ID,
|
||||
HID_ANY_ID) },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(hid, vivaldi_table);
|
||||
|
||||
static struct hid_driver hid_vivaldi = {
|
||||
.name = "hid-vivaldi",
|
||||
.id_table = vivaldi_table,
|
||||
.probe = vivaldi_probe,
|
||||
.feature_mapping = vivaldi_feature_mapping,
|
||||
.input_configured = vivaldi_input_configured,
|
||||
};
|
||||
|
||||
module_hid_driver(hid_vivaldi);
|
||||
|
||||
MODULE_AUTHOR("Sean O'Brien");
|
||||
MODULE_DESCRIPTION("HID vivaldi driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -1586,7 +1586,7 @@ struct wiiproto_handler {
|
|||
void (*func)(struct wiimote_data *wdata, const __u8 *payload);
|
||||
};
|
||||
|
||||
static struct wiiproto_handler handlers[] = {
|
||||
static const struct wiiproto_handler handlers[] = {
|
||||
{ .id = WIIPROTO_REQ_STATUS, .size = 6, .func = handler_status },
|
||||
{ .id = WIIPROTO_REQ_STATUS, .size = 2, .func = handler_status_K },
|
||||
{ .id = WIIPROTO_REQ_DATA, .size = 21, .func = handler_data },
|
||||
|
|
@ -1618,19 +1618,19 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
|
|||
u8 *raw_data, int size)
|
||||
{
|
||||
struct wiimote_data *wdata = hid_get_drvdata(hdev);
|
||||
struct wiiproto_handler *h;
|
||||
const struct wiiproto_handler *h;
|
||||
int i;
|
||||
unsigned long flags;
|
||||
|
||||
if (size < 1)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&wdata->state.lock, flags);
|
||||
|
||||
for (i = 0; handlers[i].id; ++i) {
|
||||
h = &handlers[i];
|
||||
if (h->id == raw_data[0] && h->size < size) {
|
||||
spin_lock_irqsave(&wdata->state.lock, flags);
|
||||
h->func(wdata, &raw_data[1]);
|
||||
spin_unlock_irqrestore(&wdata->state.lock, flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1639,8 +1639,6 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
|
|||
hid_warn(hdev, "Unhandled report %hhu size %d\n", raw_data[0],
|
||||
size);
|
||||
|
||||
spin_unlock_irqrestore(&wdata->state.lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@ static int i2c_hid_get_report(struct i2c_client *client, u8 reportType,
|
|||
* @reportType: 0x03 for HID_FEATURE_REPORT ; 0x02 for HID_OUTPUT_REPORT
|
||||
* @reportID: the report ID
|
||||
* @buf: the actual data to transfer, without the report ID
|
||||
* @len: size of buf
|
||||
* @data_len: size of buf
|
||||
* @use_data: true: use SET_REPORT HID command, false: send plain OUTPUT report
|
||||
*/
|
||||
static int i2c_hid_set_or_send_report(struct i2c_client *client, u8 reportType,
|
||||
|
|
@ -935,6 +935,14 @@ static void i2c_hid_acpi_fix_up_power(struct device *dev)
|
|||
acpi_device_fix_up_power(adev);
|
||||
}
|
||||
|
||||
static void i2c_hid_acpi_enable_wakeup(struct device *dev)
|
||||
{
|
||||
if (acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0) {
|
||||
device_set_wakeup_capable(dev, true);
|
||||
device_set_wakeup_enable(dev, false);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct acpi_device_id i2c_hid_acpi_match[] = {
|
||||
{"ACPI0C50", 0 },
|
||||
{"PNP0C50", 0 },
|
||||
|
|
@ -949,6 +957,8 @@ static inline int i2c_hid_acpi_pdata(struct i2c_client *client,
|
|||
}
|
||||
|
||||
static inline void i2c_hid_acpi_fix_up_power(struct device *dev) {}
|
||||
|
||||
static inline void i2c_hid_acpi_enable_wakeup(struct device *dev) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
|
|
@ -1076,6 +1086,8 @@ static int i2c_hid_probe(struct i2c_client *client,
|
|||
|
||||
i2c_hid_acpi_fix_up_power(&client->dev);
|
||||
|
||||
i2c_hid_acpi_enable_wakeup(&client->dev);
|
||||
|
||||
device_enable_async_suspend(&client->dev);
|
||||
|
||||
/* Make sure there is something at this address */
|
||||
|
|
@ -1268,6 +1280,7 @@ static struct i2c_driver i2c_hid_driver = {
|
|||
.driver = {
|
||||
.name = "i2c_hid",
|
||||
.pm = &i2c_hid_pm,
|
||||
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
|
||||
.acpi_match_table = ACPI_PTR(i2c_hid_acpi_match),
|
||||
.of_match_table = of_match_ptr(i2c_hid_of_match),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -502,8 +502,6 @@ static void ishtp_bus_remove_device(struct ishtp_cl_device *device)
|
|||
int ishtp_cl_driver_register(struct ishtp_cl_driver *driver,
|
||||
struct module *owner)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!ishtp_device_ready)
|
||||
return -ENODEV;
|
||||
|
||||
|
|
@ -511,11 +509,7 @@ int ishtp_cl_driver_register(struct ishtp_cl_driver *driver,
|
|||
driver->driver.owner = owner;
|
||||
driver->driver.bus = &ishtp_cl_bus_type;
|
||||
|
||||
err = driver_register(&driver->driver);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
return driver_register(&driver->driver);
|
||||
}
|
||||
EXPORT_SYMBOL(ishtp_cl_driver_register);
|
||||
|
||||
|
|
|
|||
|
|
@ -2773,7 +2773,9 @@ static int wacom_wac_collection(struct hid_device *hdev, struct hid_report *repo
|
|||
if (report->type != HID_INPUT_REPORT)
|
||||
return -1;
|
||||
|
||||
if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
|
||||
if (WACOM_PAD_FIELD(field))
|
||||
return 0;
|
||||
else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
|
||||
wacom_wac_pen_report(hdev, report);
|
||||
else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input)
|
||||
wacom_wac_finger_report(hdev, report);
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ void hv_synic_enable_regs(unsigned int cpu)
|
|||
/* Setup the shared SINT. */
|
||||
hv_get_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
|
||||
|
||||
shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR;
|
||||
shared_sint.vector = hv_get_vector();
|
||||
shared_sint.masked = false;
|
||||
shared_sint.auto_eoi = hv_recommend_using_aeoi();
|
||||
hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@ static int hyperv_cpuhp_online;
|
|||
|
||||
static void *hv_panic_page;
|
||||
|
||||
/* Values parsed from ACPI DSDT */
|
||||
static int vmbus_irq;
|
||||
int vmbus_interrupt;
|
||||
|
||||
/*
|
||||
* Boolean to control whether to report panic messages over Hyper-V.
|
||||
*
|
||||
|
|
@ -1347,7 +1351,7 @@ static void vmbus_isr(void)
|
|||
tasklet_schedule(&hv_cpu->msg_dpc);
|
||||
}
|
||||
|
||||
add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR, 0);
|
||||
add_interrupt_randomness(hv_get_vector(), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1430,7 +1434,9 @@ static int vmbus_bus_init(void)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
hv_setup_vmbus_irq(vmbus_isr);
|
||||
ret = hv_setup_vmbus_irq(vmbus_irq, vmbus_isr);
|
||||
if (ret)
|
||||
goto err_setup;
|
||||
|
||||
ret = hv_synic_alloc();
|
||||
if (ret)
|
||||
|
|
@ -1505,7 +1511,7 @@ static int vmbus_bus_init(void)
|
|||
hv_synic_free();
|
||||
err_alloc:
|
||||
hv_remove_vmbus_irq();
|
||||
|
||||
err_setup:
|
||||
bus_unregister(&hv_bus);
|
||||
unregister_sysctl_table(hv_ctl_table_hdr);
|
||||
hv_ctl_table_hdr = NULL;
|
||||
|
|
@ -2070,6 +2076,7 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
|
|||
struct resource *new_res;
|
||||
struct resource **old_res = &hyperv_mmio;
|
||||
struct resource **prev_res = NULL;
|
||||
struct resource r;
|
||||
|
||||
switch (res->type) {
|
||||
|
||||
|
|
@ -2088,6 +2095,23 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
|
|||
end = res->data.address64.address.maximum;
|
||||
break;
|
||||
|
||||
/*
|
||||
* The IRQ information is needed only on ARM64, which Hyper-V
|
||||
* sets up in the extended format. IRQ information is present
|
||||
* on x86/x64 in the non-extended format but it is not used by
|
||||
* Linux. So don't bother checking for the non-extended format.
|
||||
*/
|
||||
case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
|
||||
if (!acpi_dev_resource_interrupt(res, 0, &r)) {
|
||||
pr_err("Unable to parse Hyper-V ACPI interrupt\n");
|
||||
return AE_ERROR;
|
||||
}
|
||||
/* ARM64 INTID for VMbus */
|
||||
vmbus_interrupt = res->data.extended_irq.interrupts[0];
|
||||
/* Linux IRQ number */
|
||||
vmbus_irq = r.start;
|
||||
return AE_OK;
|
||||
|
||||
default:
|
||||
/* Unused resource type */
|
||||
return AE_OK;
|
||||
|
|
|
|||
|
|
@ -144,8 +144,7 @@ static int oxnas_nand_probe(struct platform_device *pdev)
|
|||
if (err)
|
||||
goto err_cleanup_nand;
|
||||
|
||||
oxnas->chips[oxnas->nchips] = chip;
|
||||
++oxnas->nchips;
|
||||
oxnas->chips[oxnas->nchips++] = chip;
|
||||
}
|
||||
|
||||
/* Exit if no chips found */
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ config STI_CONSOLE
|
|||
bool "STI text console"
|
||||
depends on PARISC && HAS_IOMEM
|
||||
select FONT_SUPPORT
|
||||
select CRC32
|
||||
default y
|
||||
help
|
||||
The STI console is the builtin display/keyboard on HP-PARISC
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
* linux/drivers/video/console/sticon.c - console driver using HP's STI firmware
|
||||
*
|
||||
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
|
||||
* Copyright (C) 2002 Helge Deller <deller@gmx.de>
|
||||
* Copyright (C) 2002-2020 Helge Deller <deller@gmx.de>
|
||||
*
|
||||
* Based on linux/drivers/video/vgacon.c and linux/drivers/video/fbcon.c,
|
||||
* which were
|
||||
|
|
@ -43,6 +43,9 @@
|
|||
#include <linux/kd.h>
|
||||
#include <linux/selection.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/font.h>
|
||||
#include <linux/crc32.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
|
||||
|
|
@ -52,28 +55,16 @@
|
|||
#define BLANK 0
|
||||
static int vga_is_gfx;
|
||||
|
||||
#define STI_DEF_FONT sticon_sti->font
|
||||
|
||||
/* borrowed from fbcon.c */
|
||||
#define FNTREFCOUNT(fd) (fd->refcount)
|
||||
#define FNTCRC(fd) (fd->crc)
|
||||
static struct sti_cooked_font *font_data[MAX_NR_CONSOLES];
|
||||
|
||||
/* this is the sti_struct used for this console */
|
||||
static struct sti_struct *sticon_sti;
|
||||
|
||||
/* Software scrollback */
|
||||
static unsigned long softback_buf, softback_curr;
|
||||
static unsigned long softback_in;
|
||||
static unsigned long /* softback_top, */ softback_end;
|
||||
static int softback_lines;
|
||||
|
||||
/* software cursor */
|
||||
static int cursor_drawn;
|
||||
#define CURSOR_DRAW_DELAY (1)
|
||||
#define DEFAULT_CURSOR_BLINK_RATE (20)
|
||||
|
||||
static int vbl_cursor_cnt;
|
||||
|
||||
static inline void cursor_undrawn(void)
|
||||
{
|
||||
vbl_cursor_cnt = 0;
|
||||
cursor_drawn = 0;
|
||||
}
|
||||
|
||||
static const char *sticon_startup(void)
|
||||
{
|
||||
return "STI console";
|
||||
|
|
@ -81,61 +72,43 @@ static const char *sticon_startup(void)
|
|||
|
||||
static void sticon_putc(struct vc_data *conp, int c, int ypos, int xpos)
|
||||
{
|
||||
int redraw_cursor = 0;
|
||||
|
||||
if (vga_is_gfx || console_blanked)
|
||||
return;
|
||||
|
||||
if (conp->vc_mode != KD_TEXT)
|
||||
return;
|
||||
#if 0
|
||||
if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) {
|
||||
cursor_undrawn();
|
||||
redraw_cursor = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
sti_putc(sticon_sti, c, ypos, xpos);
|
||||
|
||||
if (redraw_cursor)
|
||||
vbl_cursor_cnt = CURSOR_DRAW_DELAY;
|
||||
sti_putc(sticon_sti, c, ypos, xpos, font_data[conp->vc_num]);
|
||||
}
|
||||
|
||||
static void sticon_putcs(struct vc_data *conp, const unsigned short *s,
|
||||
int count, int ypos, int xpos)
|
||||
{
|
||||
int redraw_cursor = 0;
|
||||
|
||||
if (vga_is_gfx || console_blanked)
|
||||
return;
|
||||
|
||||
if (conp->vc_mode != KD_TEXT)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) &&
|
||||
(p->cursor_x < (xpos + count))) {
|
||||
cursor_undrawn();
|
||||
redraw_cursor = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
while (count--) {
|
||||
sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++);
|
||||
sti_putc(sticon_sti, scr_readw(s++), ypos, xpos++,
|
||||
font_data[conp->vc_num]);
|
||||
}
|
||||
|
||||
if (redraw_cursor)
|
||||
vbl_cursor_cnt = CURSOR_DRAW_DELAY;
|
||||
}
|
||||
|
||||
static void sticon_cursor(struct vc_data *conp, int mode)
|
||||
{
|
||||
unsigned short car1;
|
||||
|
||||
/* no cursor update if screen is blanked */
|
||||
if (vga_is_gfx || console_blanked)
|
||||
return;
|
||||
|
||||
car1 = conp->vc_screenbuf[conp->state.x + conp->state.y * conp->vc_cols];
|
||||
switch (mode) {
|
||||
case CM_ERASE:
|
||||
sti_putc(sticon_sti, car1, conp->state.y, conp->state.x);
|
||||
sti_putc(sticon_sti, car1, conp->state.y, conp->state.x,
|
||||
font_data[conp->vc_num]);
|
||||
break;
|
||||
case CM_MOVE:
|
||||
case CM_DRAW:
|
||||
|
|
@ -146,7 +119,7 @@ static void sticon_cursor(struct vc_data *conp, int mode)
|
|||
case CUR_TWO_THIRDS:
|
||||
case CUR_BLOCK:
|
||||
sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11),
|
||||
conp->state.y, conp->state.x);
|
||||
conp->state.y, conp->state.x, font_data[conp->vc_num]);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
@ -165,42 +138,164 @@ static bool sticon_scroll(struct vc_data *conp, unsigned int t,
|
|||
|
||||
switch (dir) {
|
||||
case SM_UP:
|
||||
sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols);
|
||||
sti_clear(sti, b - count, 0, count, conp->vc_cols, conp->vc_video_erase_char);
|
||||
sti_bmove(sti, t + count, 0, t, 0, b - t - count, conp->vc_cols,
|
||||
font_data[conp->vc_num]);
|
||||
sti_clear(sti, b - count, 0, count, conp->vc_cols,
|
||||
conp->vc_video_erase_char, font_data[conp->vc_num]);
|
||||
break;
|
||||
|
||||
case SM_DOWN:
|
||||
sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols);
|
||||
sti_clear(sti, t, 0, count, conp->vc_cols, conp->vc_video_erase_char);
|
||||
sti_bmove(sti, t, 0, t + count, 0, b - t - count, conp->vc_cols,
|
||||
font_data[conp->vc_num]);
|
||||
sti_clear(sti, t, 0, count, conp->vc_cols,
|
||||
conp->vc_video_erase_char, font_data[conp->vc_num]);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int sticon_set_def_font(int unit, struct console_font *op)
|
||||
{
|
||||
if (font_data[unit] != STI_DEF_FONT) {
|
||||
if (--FNTREFCOUNT(font_data[unit]) == 0) {
|
||||
kfree(font_data[unit]->raw_ptr);
|
||||
kfree(font_data[unit]);
|
||||
}
|
||||
font_data[unit] = STI_DEF_FONT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sticon_set_font(struct vc_data *vc, struct console_font *op)
|
||||
{
|
||||
struct sti_struct *sti = sticon_sti;
|
||||
int vc_cols, vc_rows, vc_old_cols, vc_old_rows;
|
||||
int unit = vc->vc_num;
|
||||
int w = op->width;
|
||||
int h = op->height;
|
||||
int size, i, bpc, pitch;
|
||||
struct sti_rom_font *new_font;
|
||||
struct sti_cooked_font *cooked_font;
|
||||
unsigned char *data = op->data, *p;
|
||||
|
||||
if ((w < 6) || (h < 6) || (w > 32) || (h > 32)
|
||||
|| (op->charcount != 256 && op->charcount != 512))
|
||||
return -EINVAL;
|
||||
pitch = ALIGN(w, 8) / 8;
|
||||
bpc = pitch * h;
|
||||
size = bpc * op->charcount;
|
||||
|
||||
new_font = kmalloc(sizeof(*new_font) + size, STI_LOWMEM);
|
||||
if (!new_font)
|
||||
return -ENOMEM;
|
||||
|
||||
new_font->first_char = 0;
|
||||
new_font->last_char = op->charcount - 1;
|
||||
new_font->width = w;
|
||||
new_font->height = h;
|
||||
new_font->font_type = STI_FONT_HPROMAN8;
|
||||
new_font->bytes_per_char = bpc;
|
||||
new_font->underline_height = 0;
|
||||
new_font->underline_pos = 0;
|
||||
|
||||
cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL);
|
||||
if (!cooked_font) {
|
||||
kfree(new_font);
|
||||
return -ENOMEM;
|
||||
}
|
||||
cooked_font->raw = new_font;
|
||||
cooked_font->raw_ptr = new_font;
|
||||
cooked_font->width = w;
|
||||
cooked_font->height = h;
|
||||
FNTREFCOUNT(cooked_font) = 0; /* usage counter */
|
||||
|
||||
p = (unsigned char *) new_font;
|
||||
p += sizeof(*new_font);
|
||||
for (i = 0; i < op->charcount; i++) {
|
||||
memcpy(p, data, bpc);
|
||||
data += pitch*32;
|
||||
p += bpc;
|
||||
}
|
||||
FNTCRC(cooked_font) = crc32(0, new_font, size + sizeof(*new_font));
|
||||
sti_font_convert_bytemode(sti, cooked_font);
|
||||
new_font = cooked_font->raw_ptr;
|
||||
|
||||
/* check if font is already used by other console */
|
||||
for (i = 0; i < MAX_NR_CONSOLES; i++) {
|
||||
if (font_data[i] != STI_DEF_FONT
|
||||
&& (FNTCRC(font_data[i]) == FNTCRC(cooked_font))) {
|
||||
kfree(new_font);
|
||||
kfree(cooked_font);
|
||||
/* current font is the same as the new one */
|
||||
if (i == unit)
|
||||
return 0;
|
||||
cooked_font = font_data[i];
|
||||
new_font = cooked_font->raw_ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear screen with old font: we now may have less rows */
|
||||
vc_old_rows = vc->vc_rows;
|
||||
vc_old_cols = vc->vc_cols;
|
||||
sti_clear(sticon_sti, 0, 0, vc_old_rows, vc_old_cols,
|
||||
vc->vc_video_erase_char, font_data[vc->vc_num]);
|
||||
|
||||
/* delete old font in case it is a user font */
|
||||
sticon_set_def_font(unit, NULL);
|
||||
|
||||
FNTREFCOUNT(cooked_font)++;
|
||||
font_data[unit] = cooked_font;
|
||||
|
||||
vc_cols = sti_onscreen_x(sti) / cooked_font->width;
|
||||
vc_rows = sti_onscreen_y(sti) / cooked_font->height;
|
||||
vc_resize(vc, vc_cols, vc_rows);
|
||||
|
||||
/* need to repaint screen if cols & rows are same as old font */
|
||||
if (vc_cols == vc_old_cols && vc_rows == vc_old_rows)
|
||||
update_screen(vc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sticon_font_default(struct vc_data *vc, struct console_font *op, char *name)
|
||||
{
|
||||
return sticon_set_def_font(vc->vc_num, op);
|
||||
}
|
||||
|
||||
static int sticon_font_set(struct vc_data *vc, struct console_font *font,
|
||||
unsigned int flags)
|
||||
{
|
||||
return sticon_set_font(vc, font);
|
||||
}
|
||||
|
||||
static void sticon_init(struct vc_data *c, int init)
|
||||
{
|
||||
struct sti_struct *sti = sticon_sti;
|
||||
int vc_cols, vc_rows;
|
||||
|
||||
sti_set(sti, 0, 0, sti_onscreen_y(sti), sti_onscreen_x(sti), 0);
|
||||
vc_cols = sti_onscreen_x(sti) / sti->font_width;
|
||||
vc_rows = sti_onscreen_y(sti) / sti->font_height;
|
||||
vc_cols = sti_onscreen_x(sti) / sti->font->width;
|
||||
vc_rows = sti_onscreen_y(sti) / sti->font->height;
|
||||
c->vc_can_do_color = 1;
|
||||
|
||||
if (init) {
|
||||
c->vc_cols = vc_cols;
|
||||
c->vc_rows = vc_rows;
|
||||
} else {
|
||||
/* vc_rows = (c->vc_rows > vc_rows) ? vc_rows : c->vc_rows; */
|
||||
/* vc_cols = (c->vc_cols > vc_cols) ? vc_cols : c->vc_cols; */
|
||||
vc_resize(c, vc_cols, vc_rows);
|
||||
/* vc_resize_con(vc_rows, vc_cols, c->vc_num); */
|
||||
}
|
||||
}
|
||||
|
||||
static void sticon_deinit(struct vc_data *c)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* free memory used by user font */
|
||||
for (i = 0; i < MAX_NR_CONSOLES; i++)
|
||||
sticon_set_def_font(i, NULL);
|
||||
}
|
||||
|
||||
static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,
|
||||
|
|
@ -209,7 +304,8 @@ static void sticon_clear(struct vc_data *conp, int sy, int sx, int height,
|
|||
if (!height || !width)
|
||||
return;
|
||||
|
||||
sti_clear(sticon_sti, sy, sx, height, width, conp->vc_video_erase_char);
|
||||
sti_clear(sticon_sti, sy, sx, height, width,
|
||||
conp->vc_video_erase_char, font_data[conp->vc_num]);
|
||||
}
|
||||
|
||||
static int sticon_switch(struct vc_data *conp)
|
||||
|
|
@ -224,64 +320,13 @@ static int sticon_blank(struct vc_data *c, int blank, int mode_switch)
|
|||
vga_is_gfx = 0;
|
||||
return 1;
|
||||
}
|
||||
sti_clear(sticon_sti, 0,0, c->vc_rows, c->vc_cols, BLANK);
|
||||
sti_clear(sticon_sti, 0, 0, c->vc_rows, c->vc_cols, BLANK,
|
||||
font_data[c->vc_num]);
|
||||
if (mode_switch)
|
||||
vga_is_gfx = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u16 *sticon_screen_pos(const struct vc_data *conp, int offset)
|
||||
{
|
||||
int line;
|
||||
unsigned long p;
|
||||
|
||||
if (conp->vc_num != fg_console || !softback_lines)
|
||||
return (u16 *)(conp->vc_origin + offset);
|
||||
line = offset / conp->vc_size_row;
|
||||
if (line >= softback_lines)
|
||||
return (u16 *)(conp->vc_origin + offset - softback_lines * conp->vc_size_row);
|
||||
p = softback_curr + offset;
|
||||
if (p >= softback_end)
|
||||
p += softback_buf - softback_end;
|
||||
return (u16 *)p;
|
||||
}
|
||||
|
||||
static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos,
|
||||
int *px, int *py)
|
||||
{
|
||||
int x, y;
|
||||
unsigned long ret;
|
||||
if (pos >= conp->vc_origin && pos < conp->vc_scr_end) {
|
||||
unsigned long offset = (pos - conp->vc_origin) / 2;
|
||||
|
||||
x = offset % conp->vc_cols;
|
||||
y = offset / conp->vc_cols;
|
||||
if (conp->vc_num == fg_console)
|
||||
y += softback_lines;
|
||||
ret = pos + (conp->vc_cols - x) * 2;
|
||||
} else if (conp->vc_num == fg_console && softback_lines) {
|
||||
unsigned long offset = pos - softback_curr;
|
||||
|
||||
if (pos < softback_curr)
|
||||
offset += softback_end - softback_buf;
|
||||
offset /= 2;
|
||||
x = offset % conp->vc_cols;
|
||||
y = offset / conp->vc_cols;
|
||||
ret = pos + (conp->vc_cols - x) * 2;
|
||||
if (ret == softback_end)
|
||||
ret = softback_buf;
|
||||
if (ret == softback_in)
|
||||
ret = conp->vc_origin;
|
||||
} else {
|
||||
/* Should not happen */
|
||||
x = y = 0;
|
||||
ret = conp->vc_origin;
|
||||
}
|
||||
if (px) *px = x;
|
||||
if (py) *py = y;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u8 sticon_build_attr(struct vc_data *conp, u8 color,
|
||||
enum vc_intensity intens,
|
||||
bool blink, bool underline, bool reverse,
|
||||
|
|
@ -312,10 +357,6 @@ static void sticon_invert_region(struct vc_data *conp, u16 *p, int count)
|
|||
}
|
||||
}
|
||||
|
||||
static void sticon_save_screen(struct vc_data *conp)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct consw sti_con = {
|
||||
.owner = THIS_MODULE,
|
||||
.con_startup = sticon_startup,
|
||||
|
|
@ -328,18 +369,18 @@ static const struct consw sti_con = {
|
|||
.con_scroll = sticon_scroll,
|
||||
.con_switch = sticon_switch,
|
||||
.con_blank = sticon_blank,
|
||||
.con_save_screen = sticon_save_screen,
|
||||
.con_font_set = sticon_font_set,
|
||||
.con_font_default = sticon_font_default,
|
||||
.con_build_attr = sticon_build_attr,
|
||||
.con_invert_region = sticon_invert_region,
|
||||
.con_screen_pos = sticon_screen_pos,
|
||||
.con_getxy = sticon_getxy,
|
||||
};
|
||||
|
||||
|
||||
|
||||
static int __init sticonsole_init(void)
|
||||
{
|
||||
int err;
|
||||
int err, i;
|
||||
|
||||
/* already initialized ? */
|
||||
if (sticon_sti)
|
||||
return 0;
|
||||
|
|
@ -348,14 +389,16 @@ static int __init sticonsole_init(void)
|
|||
if (!sticon_sti)
|
||||
return -ENODEV;
|
||||
|
||||
if (conswitchp == &dummy_con) {
|
||||
printk(KERN_INFO "sticon: Initializing STI text console.\n");
|
||||
console_lock();
|
||||
err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1, 1);
|
||||
console_unlock();
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
for (i = 0; i < MAX_NR_CONSOLES; i++)
|
||||
font_data[i] = STI_DEF_FONT;
|
||||
|
||||
pr_info("sticon: Initializing STI text console.\n");
|
||||
console_lock();
|
||||
err = do_take_over_console(&sti_con, 0, MAX_NR_CONSOLES - 1,
|
||||
PAGE0->mem_cons.cl_class != CL_DUPLEX);
|
||||
console_unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
module_init(sticonsole_init);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* core code for console driver using HP's STI firmware
|
||||
*
|
||||
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
|
||||
* Copyright (C) 2001-2013 Helge Deller <deller@gmx.de>
|
||||
* Copyright (C) 2001-2020 Helge Deller <deller@gmx.de>
|
||||
* Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
|
||||
*
|
||||
* TODO:
|
||||
|
|
@ -14,6 +14,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "%s: " fmt, KBUILD_MODNAME
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
|
|
@ -133,16 +135,17 @@ static const struct sti_font_flags default_font_flags = {
|
|||
};
|
||||
|
||||
void
|
||||
sti_putc(struct sti_struct *sti, int c, int y, int x)
|
||||
sti_putc(struct sti_struct *sti, int c, int y, int x,
|
||||
struct sti_cooked_font *font)
|
||||
{
|
||||
struct sti_font_inptr *inptr = &sti->sti_data->font_inptr;
|
||||
struct sti_font_inptr inptr_default = {
|
||||
.font_start_addr= STI_PTR(sti->font->raw),
|
||||
.font_start_addr = STI_PTR(font->raw),
|
||||
.index = c_index(sti, c),
|
||||
.fg_color = c_fg(sti, c),
|
||||
.bg_color = c_bg(sti, c),
|
||||
.dest_x = x * sti->font_width,
|
||||
.dest_y = y * sti->font_height,
|
||||
.dest_x = x * font->width,
|
||||
.dest_y = y * font->height,
|
||||
};
|
||||
struct sti_font_outptr *outptr = &sti->sti_data->font_outptr;
|
||||
s32 ret;
|
||||
|
|
@ -193,18 +196,18 @@ sti_set(struct sti_struct *sti, int src_y, int src_x,
|
|||
|
||||
void
|
||||
sti_clear(struct sti_struct *sti, int src_y, int src_x,
|
||||
int height, int width, int c)
|
||||
int height, int width, int c, struct sti_cooked_font *font)
|
||||
{
|
||||
struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
|
||||
struct sti_blkmv_inptr inptr_default = {
|
||||
.fg_color = c_fg(sti, c),
|
||||
.bg_color = c_bg(sti, c),
|
||||
.src_x = src_x * sti->font_width,
|
||||
.src_y = src_y * sti->font_height,
|
||||
.dest_x = src_x * sti->font_width,
|
||||
.dest_y = src_y * sti->font_height,
|
||||
.width = width * sti->font_width,
|
||||
.height = height* sti->font_height,
|
||||
.src_x = src_x * font->width,
|
||||
.src_y = src_y * font->height,
|
||||
.dest_x = src_x * font->width,
|
||||
.dest_y = src_y * font->height,
|
||||
.width = width * font->width,
|
||||
.height = height * font->height,
|
||||
};
|
||||
struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
|
||||
s32 ret;
|
||||
|
|
@ -225,16 +228,17 @@ static const struct sti_blkmv_flags default_blkmv_flags = {
|
|||
|
||||
void
|
||||
sti_bmove(struct sti_struct *sti, int src_y, int src_x,
|
||||
int dst_y, int dst_x, int height, int width)
|
||||
int dst_y, int dst_x, int height, int width,
|
||||
struct sti_cooked_font *font)
|
||||
{
|
||||
struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr;
|
||||
struct sti_blkmv_inptr inptr_default = {
|
||||
.src_x = src_x * sti->font_width,
|
||||
.src_y = src_y * sti->font_height,
|
||||
.dest_x = dst_x * sti->font_width,
|
||||
.dest_y = dst_y * sti->font_height,
|
||||
.width = width * sti->font_width,
|
||||
.height = height* sti->font_height,
|
||||
.src_x = src_x * font->width,
|
||||
.src_y = src_y * font->height,
|
||||
.dest_x = dst_x * font->width,
|
||||
.dest_y = dst_y * font->height,
|
||||
.width = width * font->width,
|
||||
.height = height * font->height,
|
||||
};
|
||||
struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;
|
||||
s32 ret;
|
||||
|
|
@ -301,36 +305,32 @@ __setup("sti=", sti_setup);
|
|||
|
||||
|
||||
|
||||
static char *font_name[MAX_STI_ROMS];
|
||||
static int font_index[MAX_STI_ROMS],
|
||||
font_height[MAX_STI_ROMS],
|
||||
font_width[MAX_STI_ROMS];
|
||||
static char *font_name;
|
||||
static int font_index,
|
||||
font_height,
|
||||
font_width;
|
||||
#ifndef MODULE
|
||||
static int sti_font_setup(char *str)
|
||||
{
|
||||
char *x;
|
||||
int i = 0;
|
||||
/*
|
||||
* The default font can be selected in various ways.
|
||||
* a) sti_font=VGA8x16, sti_font=10x20, sti_font=10*20 selects
|
||||
* an built-in Linux framebuffer font.
|
||||
* b) sti_font=<index>, where index is (1..x) with 1 selecting
|
||||
* the first HP STI ROM built-in font..
|
||||
*/
|
||||
|
||||
/* we accept sti_font=VGA8x16, sti_font=10x20, sti_font=10*20
|
||||
* or sti_font=7 style command lines. */
|
||||
if (*str >= '0' && *str <= '9') {
|
||||
char *x;
|
||||
|
||||
while (i<MAX_STI_ROMS && str && *str) {
|
||||
if (*str>='0' && *str<='9') {
|
||||
if ((x = strchr(str, 'x')) || (x = strchr(str, '*'))) {
|
||||
font_height[i] = simple_strtoul(str, NULL, 0);
|
||||
font_width[i] = simple_strtoul(x+1, NULL, 0);
|
||||
} else {
|
||||
font_index[i] = simple_strtoul(str, NULL, 0);
|
||||
}
|
||||
if ((x = strchr(str, 'x')) || (x = strchr(str, '*'))) {
|
||||
font_height = simple_strtoul(str, NULL, 0);
|
||||
font_width = simple_strtoul(x+1, NULL, 0);
|
||||
} else {
|
||||
font_name[i] = str; /* fb font name */
|
||||
font_index = simple_strtoul(str, NULL, 0);
|
||||
}
|
||||
|
||||
if ((x = strchr(str, ',')))
|
||||
*x++ = 0;
|
||||
str = x;
|
||||
|
||||
i++;
|
||||
} else {
|
||||
font_name = str; /* fb font name */
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
|
@ -344,7 +344,7 @@ static int sti_font_setup(char *str)
|
|||
* framebuffer font names (e.g. VGA8x16, SUN22x18).
|
||||
* This is only available if the fonts have been statically compiled
|
||||
* in with e.g. the CONFIG_FONT_8x16 or CONFIG_FONT_SUN12x22 options.
|
||||
* - sti_font=<number>
|
||||
* - sti_font=<number> (<number> = 1,2,3,...)
|
||||
* most STI ROMs have built-in HP specific fonts, which can be selected
|
||||
* by giving the desired number to the sticon driver.
|
||||
* NOTE: This number is machine and STI ROM dependend.
|
||||
|
|
@ -364,8 +364,7 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg,
|
|||
{
|
||||
struct sti_glob_cfg_ext *cfg;
|
||||
|
||||
DPRINTK((KERN_INFO
|
||||
"%d text planes\n"
|
||||
pr_debug("%d text planes\n"
|
||||
"%4d x %4d screen resolution\n"
|
||||
"%4d x %4d offscreen\n"
|
||||
"%4d x %4d layout\n"
|
||||
|
|
@ -382,12 +381,11 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg,
|
|||
glob_cfg->region_ptrs[4], glob_cfg->region_ptrs[5],
|
||||
glob_cfg->region_ptrs[6], glob_cfg->region_ptrs[7],
|
||||
glob_cfg->reent_lvl,
|
||||
glob_cfg->save_addr));
|
||||
glob_cfg->save_addr);
|
||||
|
||||
/* dump extended cfg */
|
||||
cfg = PTR_STI((unsigned long)glob_cfg->ext_ptr);
|
||||
DPRINTK(( KERN_INFO
|
||||
"monitor %d\n"
|
||||
pr_debug("monitor %d\n"
|
||||
"in friendly mode: %d\n"
|
||||
"power consumption %d watts\n"
|
||||
"freq ref %d\n"
|
||||
|
|
@ -396,20 +394,19 @@ static void sti_dump_globcfg(struct sti_glob_cfg *glob_cfg,
|
|||
cfg->friendly_boot,
|
||||
cfg->power,
|
||||
cfg->freq_ref,
|
||||
cfg->sti_mem_addr, sti_mem_request));
|
||||
cfg->sti_mem_addr, sti_mem_request);
|
||||
}
|
||||
|
||||
static void sti_dump_outptr(struct sti_struct *sti)
|
||||
{
|
||||
DPRINTK((KERN_INFO
|
||||
"%d bits per pixel\n"
|
||||
pr_debug("%d bits per pixel\n"
|
||||
"%d used bits\n"
|
||||
"%d planes\n"
|
||||
"attributes %08x\n",
|
||||
sti->sti_data->inq_outptr.bits_per_pixel,
|
||||
sti->sti_data->inq_outptr.bits_used,
|
||||
sti->sti_data->inq_outptr.planes,
|
||||
sti->sti_data->inq_outptr.attributes));
|
||||
sti->sti_data->inq_outptr.attributes);
|
||||
}
|
||||
|
||||
static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
|
||||
|
|
@ -448,8 +445,7 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
|
|||
if (offs != PCI_ROM_ADDRESS &&
|
||||
(offs < PCI_BASE_ADDRESS_0 ||
|
||||
offs > PCI_BASE_ADDRESS_5)) {
|
||||
printk (KERN_WARNING
|
||||
"STI pci region mapping for region %d (%02x) can't be mapped\n",
|
||||
pr_warn("STI pci region mapping for region %d (%02x) can't be mapped\n",
|
||||
i,sti->rm_entry[i]);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -464,14 +460,14 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
|
|||
if (len)
|
||||
glob_cfg->region_ptrs[i] = sti->regions_phys[i];
|
||||
|
||||
DPRINTK(("region #%d: phys %08lx, region_ptr %08x, len=%lukB, "
|
||||
pr_debug("region #%d: phys %08lx, region_ptr %08x, len=%lukB, "
|
||||
"btlb=%d, sysonly=%d, cache=%d, last=%d\n",
|
||||
i, sti->regions_phys[i], glob_cfg->region_ptrs[i],
|
||||
len/1024,
|
||||
sti->regions[i].region_desc.btlb,
|
||||
sti->regions[i].region_desc.sys_only,
|
||||
sti->regions[i].region_desc.cache,
|
||||
sti->regions[i].region_desc.last));
|
||||
sti->regions[i].region_desc.last);
|
||||
|
||||
/* last entry reached ? */
|
||||
if (sti->regions[i].region_desc.last)
|
||||
|
|
@ -479,8 +475,8 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,
|
|||
}
|
||||
|
||||
if (++i<8 && sti->regions[i].region)
|
||||
printk(KERN_WARNING "%s: *future ptr (0x%8x) not yet supported !\n",
|
||||
__FILE__, sti->regions[i].region);
|
||||
pr_warn("future ptr (0x%8x) not yet supported !\n",
|
||||
sti->regions[i].region);
|
||||
|
||||
glob_cfg_ext->sti_mem_addr = STI_PTR(sti_mem_addr);
|
||||
|
||||
|
|
@ -538,6 +534,7 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
|
|||
}
|
||||
|
||||
cooked_font->raw = nf;
|
||||
cooked_font->raw_ptr = nf;
|
||||
cooked_font->next_font = NULL;
|
||||
|
||||
cooked_rom->font_start = cooked_font;
|
||||
|
|
@ -552,24 +549,38 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
|
|||
}
|
||||
#endif
|
||||
|
||||
static struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom,
|
||||
int (*search_font_fnc)(struct sti_cooked_rom *, int, int))
|
||||
static int sti_search_font(struct sti_cooked_rom *rom, int height, int width)
|
||||
{
|
||||
struct sti_cooked_font *font;
|
||||
int i = 0;
|
||||
|
||||
for (font = rom->font_start; font; font = font->next_font, i++) {
|
||||
if ((font->raw->width == width) &&
|
||||
(font->raw->height == height))
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom)
|
||||
{
|
||||
struct sti_cooked_font *font;
|
||||
int i;
|
||||
int index = num_sti_roms;
|
||||
|
||||
/* check for framebuffer-font first */
|
||||
if ((font = sti_select_fbfont(rom, font_name[index])))
|
||||
return font;
|
||||
if (!font_index) {
|
||||
font = sti_select_fbfont(rom, font_name);
|
||||
if (font)
|
||||
return font;
|
||||
}
|
||||
|
||||
if (font_width[index] && font_height[index])
|
||||
font_index[index] = search_font_fnc(rom,
|
||||
font_height[index], font_width[index]);
|
||||
if (font_width && font_height)
|
||||
font_index = sti_search_font(rom,
|
||||
font_height, font_width);
|
||||
|
||||
for (font = rom->font_start, i = font_index[index];
|
||||
font && (i > 0);
|
||||
font = font->next_font, i--);
|
||||
for (font = rom->font_start, i = font_index - 1;
|
||||
font && (i > 0);
|
||||
font = font->next_font, i--);
|
||||
|
||||
if (font)
|
||||
return font;
|
||||
|
|
@ -578,20 +589,35 @@ static struct sti_cooked_font *sti_select_font(struct sti_cooked_rom *rom,
|
|||
}
|
||||
|
||||
|
||||
static void sti_dump_rom(struct sti_rom *rom)
|
||||
static void sti_dump_rom(struct sti_struct *sti)
|
||||
{
|
||||
printk(KERN_INFO " id %04x-%04x, conforms to spec rev. %d.%02x\n",
|
||||
struct sti_rom *rom = sti->rom->raw;
|
||||
struct sti_cooked_font *font_start;
|
||||
int nr;
|
||||
|
||||
pr_info(" id %04x-%04x, conforms to spec rev. %d.%02x\n",
|
||||
rom->graphics_id[0],
|
||||
rom->graphics_id[1],
|
||||
rom->revno[0] >> 4,
|
||||
rom->revno[0] & 0x0f);
|
||||
DPRINTK((" supports %d monitors\n", rom->num_mons));
|
||||
DPRINTK((" font start %08x\n", rom->font_start));
|
||||
DPRINTK((" region list %08x\n", rom->region_list));
|
||||
DPRINTK((" init_graph %08x\n", rom->init_graph));
|
||||
DPRINTK((" bus support %02x\n", rom->bus_support));
|
||||
DPRINTK((" ext bus support %02x\n", rom->ext_bus_support));
|
||||
DPRINTK((" alternate code type %d\n", rom->alt_code_type));
|
||||
pr_debug(" supports %d monitors\n", rom->num_mons);
|
||||
pr_debug(" font start %08x\n", rom->font_start);
|
||||
pr_debug(" region list %08x\n", rom->region_list);
|
||||
pr_debug(" init_graph %08x\n", rom->init_graph);
|
||||
pr_debug(" bus support %02x\n", rom->bus_support);
|
||||
pr_debug(" ext bus support %02x\n", rom->ext_bus_support);
|
||||
pr_debug(" alternate code type %d\n", rom->alt_code_type);
|
||||
|
||||
font_start = sti->rom->font_start;
|
||||
nr = 0;
|
||||
while (font_start) {
|
||||
struct sti_rom_font *f = font_start->raw;
|
||||
|
||||
pr_info(" built-in font #%d: size %dx%d, chars %d-%d, bpc %d\n", ++nr,
|
||||
f->width, f->height,
|
||||
f->first_char, f->last_char, f->bytes_per_char);
|
||||
font_start = font_start->next_font;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -628,39 +654,34 @@ static int sti_cook_fonts(struct sti_cooked_rom *cooked_rom,
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int sti_search_font(struct sti_cooked_rom *rom, int height, int width)
|
||||
{
|
||||
struct sti_cooked_font *font;
|
||||
int i = 0;
|
||||
|
||||
for (font = rom->font_start; font; font = font->next_font, i++) {
|
||||
if ((font->raw->width == width) &&
|
||||
(font->raw->height == height))
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BMODE_RELOCATE(offset) offset = (offset) / 4;
|
||||
#define BMODE_LAST_ADDR_OFFS 0x50
|
||||
|
||||
static void *sti_bmode_font_raw(struct sti_cooked_font *f)
|
||||
void sti_font_convert_bytemode(struct sti_struct *sti, struct sti_cooked_font *f)
|
||||
{
|
||||
unsigned char *n, *p, *q;
|
||||
int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font);
|
||||
|
||||
int size = f->raw->bytes_per_char * 256 + sizeof(struct sti_rom_font);
|
||||
struct sti_rom_font *old_font;
|
||||
|
||||
if (sti->wordmode)
|
||||
return;
|
||||
|
||||
old_font = f->raw_ptr;
|
||||
n = kcalloc(4, size, STI_LOWMEM);
|
||||
f->raw_ptr = n;
|
||||
if (!n)
|
||||
return NULL;
|
||||
return;
|
||||
p = n + 3;
|
||||
q = (unsigned char *)f->raw;
|
||||
q = (unsigned char *) f->raw;
|
||||
while (size--) {
|
||||
*p = *q++;
|
||||
p+=4;
|
||||
p += 4;
|
||||
}
|
||||
return n + 3;
|
||||
/* store new ptr to byte-mode font and delete old font */
|
||||
f->raw = (struct sti_rom_font *) (n + 3);
|
||||
kfree(old_font);
|
||||
}
|
||||
EXPORT_SYMBOL(sti_font_convert_bytemode);
|
||||
|
||||
static void sti_bmode_rom_copy(unsigned long base, unsigned long count,
|
||||
void *dest)
|
||||
|
|
@ -747,7 +768,7 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti,
|
|||
goto out_err;
|
||||
|
||||
if (!sti_cook_fonts(cooked, raw)) {
|
||||
printk(KERN_ERR "No font found for STI at %08lx\n", address);
|
||||
pr_warn("No font found for STI at %08lx\n", address);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
|
|
@ -756,7 +777,8 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti,
|
|||
|
||||
address = (unsigned long) STI_PTR(raw);
|
||||
|
||||
pr_info("STI ROM supports 32 %sbit firmware functions.\n",
|
||||
pr_info("STI %s ROM supports 32 %sbit firmware functions.\n",
|
||||
wordmode ? "word mode" : "byte mode",
|
||||
raw->alt_code_type == ALT_CODE_TYPE_PA_RISC_64
|
||||
? "and 64 " : "");
|
||||
|
||||
|
|
@ -767,18 +789,17 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti,
|
|||
|
||||
sti->rom = cooked;
|
||||
sti->rom->raw = raw;
|
||||
|
||||
sti->font = sti_select_font(sti->rom, sti_search_font);
|
||||
sti->font_width = sti->font->raw->width;
|
||||
sti->font_height = sti->font->raw->height;
|
||||
if (!wordmode)
|
||||
sti->font->raw = sti_bmode_font_raw(sti->font);
|
||||
sti_dump_rom(sti);
|
||||
|
||||
sti->wordmode = wordmode;
|
||||
sti->font = sti_select_font(sti->rom);
|
||||
sti->font->width = sti->font->raw->width;
|
||||
sti->font->height = sti->font->raw->height;
|
||||
sti_font_convert_bytemode(sti, sti->font);
|
||||
|
||||
sti->sti_mem_request = raw->sti_mem_req;
|
||||
sti->graphics_id[0] = raw->graphics_id[0];
|
||||
sti->graphics_id[1] = raw->graphics_id[1];
|
||||
|
||||
sti_dump_rom(raw);
|
||||
|
||||
/* check if the ROM routines in this card are compatible */
|
||||
if (wordmode || sti->graphics_id[1] != 0x09A02587)
|
||||
|
|
@ -804,9 +825,9 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti,
|
|||
return 1;
|
||||
|
||||
msg_not_supported:
|
||||
printk(KERN_ERR "Sorry, this GSC/STI card is not yet supported.\n");
|
||||
printk(KERN_ERR "Please see http://parisc-linux.org/faq/"
|
||||
"graphics-howto.html for more info.\n");
|
||||
pr_warn("Sorry, this GSC/STI card is not yet supported.\n");
|
||||
pr_warn("Please see https://parisc.wiki.kernel.org/"
|
||||
"index.php/Graphics_howto for more info.\n");
|
||||
/* fall through */
|
||||
out_err:
|
||||
kfree(raw);
|
||||
|
|
@ -823,7 +844,7 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address,
|
|||
u32 sig;
|
||||
|
||||
if (num_sti_roms >= MAX_STI_ROMS) {
|
||||
printk(KERN_WARNING "maximum number of STI ROMS reached !\n");
|
||||
pr_warn("maximum number of STI ROMS reached !\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -849,16 +870,15 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address,
|
|||
if (i != 1) {
|
||||
/* The ROM could have multiple architecture
|
||||
* dependent images (e.g. i386, parisc,...) */
|
||||
printk(KERN_WARNING
|
||||
"PCI ROM is not a STI ROM type image (0x%8x)\n", i);
|
||||
pr_warn("PCI ROM is not a STI ROM type image (0x%8x)\n", i);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
sti->pd = pd;
|
||||
|
||||
i = gsc_readl(address+0x0c);
|
||||
DPRINTK(("PCI ROM size (from header) = %d kB\n",
|
||||
le16_to_cpu(i>>16)*512/1024));
|
||||
pr_debug("PCI ROM size (from header) = %d kB\n",
|
||||
le16_to_cpu(i>>16)*512/1024);
|
||||
rm_offset = le16_to_cpu(i & 0xffff);
|
||||
if (rm_offset) {
|
||||
/* read 16 bytes from the pci region mapper array */
|
||||
|
|
@ -867,29 +887,24 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address,
|
|||
*rm++ = gsc_readl(address+rm_offset+0x04);
|
||||
*rm++ = gsc_readl(address+rm_offset+0x08);
|
||||
*rm++ = gsc_readl(address+rm_offset+0x0c);
|
||||
DPRINTK(("PCI region Mapper offset = %08x: ",
|
||||
rm_offset));
|
||||
for (i=0; i<16; i++)
|
||||
DPRINTK(("%02x ", sti->rm_entry[i]));
|
||||
DPRINTK(("\n"));
|
||||
}
|
||||
|
||||
address += le32_to_cpu(gsc_readl(address+8));
|
||||
DPRINTK(("sig %04x, PCI STI ROM at %08lx\n", sig, address));
|
||||
pr_debug("sig %04x, PCI STI ROM at %08lx\n", sig, address);
|
||||
goto test_rom;
|
||||
}
|
||||
|
||||
ok = 0;
|
||||
|
||||
if ((sig & 0xff) == 0x01) {
|
||||
DPRINTK((" byte mode ROM at %08lx, hpa at %08lx\n",
|
||||
address, hpa));
|
||||
pr_debug(" byte mode ROM at %08lx, hpa at %08lx\n",
|
||||
address, hpa);
|
||||
ok = sti_read_rom(0, sti, address);
|
||||
}
|
||||
|
||||
if ((sig & 0xffff) == 0x0303) {
|
||||
DPRINTK((" word mode ROM at %08lx, hpa at %08lx\n",
|
||||
address, hpa));
|
||||
pr_debug(" word mode ROM at %08lx, hpa at %08lx\n",
|
||||
address, hpa);
|
||||
ok = sti_read_rom(1, sti, address);
|
||||
}
|
||||
|
||||
|
|
@ -906,7 +921,7 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address,
|
|||
unsigned long rom_base;
|
||||
rom_base = pci_resource_start(sti->pd, PCI_ROM_RESOURCE);
|
||||
pci_write_config_dword(sti->pd, PCI_ROM_ADDRESS, rom_base & ~PCI_ROM_ADDRESS_ENABLE);
|
||||
DPRINTK((KERN_DEBUG "STI PCI ROM disabled\n"));
|
||||
pr_debug("STI PCI ROM disabled\n");
|
||||
}
|
||||
|
||||
if (sti_init_graph(sti))
|
||||
|
|
@ -981,14 +996,14 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent)
|
|||
rom_len = pci_resource_len(pd, PCI_ROM_RESOURCE);
|
||||
if (rom_base) {
|
||||
pci_write_config_dword(pd, PCI_ROM_ADDRESS, rom_base | PCI_ROM_ADDRESS_ENABLE);
|
||||
DPRINTK((KERN_DEBUG "STI PCI ROM enabled at 0x%08lx\n", rom_base));
|
||||
pr_debug("STI PCI ROM enabled at 0x%08lx\n", rom_base);
|
||||
}
|
||||
|
||||
printk(KERN_INFO "STI PCI graphic ROM found at %08lx (%u kB), fb at %08lx (%u MB)\n",
|
||||
pr_info("STI PCI graphic ROM found at %08lx (%u kB), fb at %08lx (%u MB)\n",
|
||||
rom_base, rom_len/1024, fb_base, fb_len/1024/1024);
|
||||
|
||||
DPRINTK((KERN_DEBUG "Trying PCI STI ROM at %08lx, PCI hpa at %08lx\n",
|
||||
rom_base, fb_base));
|
||||
pr_debug("Trying PCI STI ROM at %08lx, PCI hpa at %08lx\n",
|
||||
rom_base, fb_base);
|
||||
|
||||
sti = sti_try_rom_generic(rom_base, fb_base, pd);
|
||||
if (sti) {
|
||||
|
|
@ -998,8 +1013,7 @@ static int sticore_pci_init(struct pci_dev *pd, const struct pci_device_id *ent)
|
|||
}
|
||||
|
||||
if (!sti) {
|
||||
printk(KERN_WARNING "Unable to handle STI device '%s'\n",
|
||||
pci_name(pd));
|
||||
pr_warn("Unable to handle STI device '%s'\n", pci_name(pd));
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
|
@ -1058,7 +1072,7 @@ static void sti_init_roms(void)
|
|||
|
||||
sticore_initialized = 1;
|
||||
|
||||
printk(KERN_INFO "STI GSC/PCI core graphics driver "
|
||||
pr_info("STI GSC/PCI core graphics driver "
|
||||
STI_DRIVERVERSION "\n");
|
||||
|
||||
/* Register drivers for native & PCI cards */
|
||||
|
|
|
|||
|
|
@ -4,12 +4,6 @@
|
|||
|
||||
/* generic STI structures & functions */
|
||||
|
||||
#if 0
|
||||
#define DPRINTK(x) printk x
|
||||
#else
|
||||
#define DPRINTK(x)
|
||||
#endif
|
||||
|
||||
#define MAX_STI_ROMS 4 /* max no. of ROMs which this driver handles */
|
||||
|
||||
#define STI_REGION_MAX 8 /* hardcoded STI constants */
|
||||
|
|
@ -246,8 +240,12 @@ struct sti_rom_font {
|
|||
/* sticore internal font handling */
|
||||
|
||||
struct sti_cooked_font {
|
||||
struct sti_rom_font *raw;
|
||||
struct sti_rom_font *raw; /* native ptr for STI functions */
|
||||
void *raw_ptr; /* kmalloc'ed font data */
|
||||
struct sti_cooked_font *next_font;
|
||||
int height, width;
|
||||
int refcount;
|
||||
u32 crc;
|
||||
};
|
||||
|
||||
struct sti_cooked_rom {
|
||||
|
|
@ -341,9 +339,6 @@ struct sti_all_data {
|
|||
struct sti_struct {
|
||||
spinlock_t lock;
|
||||
|
||||
/* the following fields needs to be filled in by the word/byte routines */
|
||||
int font_width;
|
||||
int font_height;
|
||||
/* char **mon_strings; */
|
||||
int sti_mem_request;
|
||||
u32 graphics_id[2];
|
||||
|
|
@ -362,6 +357,7 @@ struct sti_struct {
|
|||
|
||||
struct sti_glob_cfg *glob_cfg; /* points into sti_all_data */
|
||||
|
||||
int wordmode;
|
||||
struct sti_cooked_font *font; /* ptr to selected font (cooked) */
|
||||
|
||||
struct pci_dev *pd;
|
||||
|
|
@ -380,6 +376,7 @@ struct sti_struct {
|
|||
/* sticore interface functions */
|
||||
|
||||
struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */
|
||||
void sti_font_convert_bytemode(struct sti_struct *sti, struct sti_cooked_font *f);
|
||||
|
||||
|
||||
/* sticore main function to call STI firmware */
|
||||
|
|
@ -391,12 +388,14 @@ int sti_call(const struct sti_struct *sti, unsigned long func,
|
|||
|
||||
/* functions to call the STI ROM directly */
|
||||
|
||||
void sti_putc(struct sti_struct *sti, int c, int y, int x);
|
||||
void sti_putc(struct sti_struct *sti, int c, int y, int x,
|
||||
struct sti_cooked_font *font);
|
||||
void sti_set(struct sti_struct *sti, int src_y, int src_x,
|
||||
int height, int width, u8 color);
|
||||
int height, int width, u8 color);
|
||||
void sti_clear(struct sti_struct *sti, int src_y, int src_x,
|
||||
int height, int width, int c);
|
||||
int height, int width, int c, struct sti_cooked_font *font);
|
||||
void sti_bmove(struct sti_struct *sti, int src_y, int src_x,
|
||||
int dst_y, int dst_x, int height, int width);
|
||||
int dst_y, int dst_x, int height, int width,
|
||||
struct sti_cooked_font *font);
|
||||
|
||||
#endif /* STICORE_H */
|
||||
|
|
|
|||
|
|
@ -1159,22 +1159,13 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
|
|||
* the early prefetch in the caller enough time.
|
||||
*/
|
||||
|
||||
if (align & blocksize_mask) {
|
||||
if (bdev)
|
||||
blkbits = blksize_bits(bdev_logical_block_size(bdev));
|
||||
blocksize_mask = (1 << blkbits) - 1;
|
||||
if (align & blocksize_mask)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* watch out for a 0 len io from a tricksy fs */
|
||||
if (iov_iter_rw(iter) == READ && !count)
|
||||
return 0;
|
||||
|
||||
dio = kmem_cache_alloc(dio_cache, GFP_KERNEL);
|
||||
retval = -ENOMEM;
|
||||
if (!dio)
|
||||
goto out;
|
||||
return -ENOMEM;
|
||||
/*
|
||||
* Believe it or not, zeroing out the page array caused a .5%
|
||||
* performance regression in a database benchmark. So, we take
|
||||
|
|
@ -1183,32 +1174,32 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
|
|||
memset(dio, 0, offsetof(struct dio, pages));
|
||||
|
||||
dio->flags = flags;
|
||||
if (dio->flags & DIO_LOCKING) {
|
||||
if (iov_iter_rw(iter) == READ) {
|
||||
struct address_space *mapping =
|
||||
iocb->ki_filp->f_mapping;
|
||||
|
||||
/* will be released by direct_io_worker */
|
||||
inode_lock(inode);
|
||||
|
||||
retval = filemap_write_and_wait_range(mapping, offset,
|
||||
end - 1);
|
||||
if (retval) {
|
||||
inode_unlock(inode);
|
||||
kmem_cache_free(dio_cache, dio);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ) {
|
||||
/* will be released by direct_io_worker */
|
||||
inode_lock(inode);
|
||||
}
|
||||
|
||||
/* Once we sampled i_size check for reads beyond EOF */
|
||||
dio->i_size = i_size_read(inode);
|
||||
if (iov_iter_rw(iter) == READ && offset >= dio->i_size) {
|
||||
if (dio->flags & DIO_LOCKING)
|
||||
inode_unlock(inode);
|
||||
kmem_cache_free(dio_cache, dio);
|
||||
retval = 0;
|
||||
goto out;
|
||||
goto fail_dio;
|
||||
}
|
||||
|
||||
if (align & blocksize_mask) {
|
||||
if (bdev)
|
||||
blkbits = blksize_bits(bdev_logical_block_size(bdev));
|
||||
blocksize_mask = (1 << blkbits) - 1;
|
||||
if (align & blocksize_mask)
|
||||
goto fail_dio;
|
||||
}
|
||||
|
||||
if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ) {
|
||||
struct address_space *mapping = iocb->ki_filp->f_mapping;
|
||||
|
||||
retval = filemap_write_and_wait_range(mapping, offset, end - 1);
|
||||
if (retval)
|
||||
goto fail_dio;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1252,14 +1243,8 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
|
|||
*/
|
||||
retval = sb_init_dio_done_wq(dio->inode->i_sb);
|
||||
}
|
||||
if (retval) {
|
||||
/*
|
||||
* We grab i_mutex only for reads so we don't have
|
||||
* to release it here
|
||||
*/
|
||||
kmem_cache_free(dio_cache, dio);
|
||||
goto out;
|
||||
}
|
||||
if (retval)
|
||||
goto fail_dio;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1362,7 +1347,13 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode,
|
|||
} else
|
||||
BUG_ON(retval != -EIOCBQUEUED);
|
||||
|
||||
out:
|
||||
return retval;
|
||||
|
||||
fail_dio:
|
||||
if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ)
|
||||
inode_unlock(inode);
|
||||
|
||||
kmem_cache_free(dio_cache, dio);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ static void group_adjust_blocks(struct super_block *sb, int group_no,
|
|||
|
||||
/**
|
||||
* __rsv_window_dump() -- Dump the filesystem block allocation reservation map
|
||||
* @rb_root: root of per-filesystem reservation rb tree
|
||||
* @root: root of per-filesystem reservation rb tree
|
||||
* @verbose: verbose mode
|
||||
* @fn: function which wishes to dump the reservation map
|
||||
*
|
||||
|
|
@ -282,7 +282,7 @@ goal_in_my_reservation(struct ext2_reserve_window *rsv, ext2_grpblk_t grp_goal,
|
|||
|
||||
/**
|
||||
* search_reserve_window()
|
||||
* @rb_root: root of reservation tree
|
||||
* @root: root of reservation tree
|
||||
* @goal: target allocation block
|
||||
*
|
||||
* Find the reserved window which includes the goal, or the previous one
|
||||
|
|
@ -859,7 +859,7 @@ static int find_next_reservable_window(
|
|||
*
|
||||
* failed: we failed to find a reservation window in this group
|
||||
*
|
||||
* @rsv: the reservation
|
||||
* @my_rsv: the reservation
|
||||
*
|
||||
* @grp_goal: The goal (group-relative). It is where the search for a
|
||||
* free reservable space should start from.
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@
|
|||
#include <linux/iomap.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/fiemap.h>
|
||||
#include "ext2.h"
|
||||
#include "acl.h"
|
||||
#include "xattr.h"
|
||||
|
|
|
|||
|
|
@ -532,6 +532,14 @@ static inline u64 quota_btobb(u64 bytes)
|
|||
return (bytes + (1 << XFS_BB_SHIFT) - 1) >> XFS_BB_SHIFT;
|
||||
}
|
||||
|
||||
static inline s64 copy_from_xfs_dqblk_ts(const struct fs_disk_quota *d,
|
||||
__s32 timer, __s8 timer_hi)
|
||||
{
|
||||
if (d->d_fieldmask & FS_DQ_BIGTIME)
|
||||
return (u32)timer | (s64)timer_hi << 32;
|
||||
return timer;
|
||||
}
|
||||
|
||||
static void copy_from_xfs_dqblk(struct qc_dqblk *dst, struct fs_disk_quota *src)
|
||||
{
|
||||
dst->d_spc_hardlimit = quota_bbtob(src->d_blk_hardlimit);
|
||||
|
|
@ -540,14 +548,17 @@ static void copy_from_xfs_dqblk(struct qc_dqblk *dst, struct fs_disk_quota *src)
|
|||
dst->d_ino_softlimit = src->d_ino_softlimit;
|
||||
dst->d_space = quota_bbtob(src->d_bcount);
|
||||
dst->d_ino_count = src->d_icount;
|
||||
dst->d_ino_timer = src->d_itimer;
|
||||
dst->d_spc_timer = src->d_btimer;
|
||||
dst->d_ino_timer = copy_from_xfs_dqblk_ts(src, src->d_itimer,
|
||||
src->d_itimer_hi);
|
||||
dst->d_spc_timer = copy_from_xfs_dqblk_ts(src, src->d_btimer,
|
||||
src->d_btimer_hi);
|
||||
dst->d_ino_warns = src->d_iwarns;
|
||||
dst->d_spc_warns = src->d_bwarns;
|
||||
dst->d_rt_spc_hardlimit = quota_bbtob(src->d_rtb_hardlimit);
|
||||
dst->d_rt_spc_softlimit = quota_bbtob(src->d_rtb_softlimit);
|
||||
dst->d_rt_space = quota_bbtob(src->d_rtbcount);
|
||||
dst->d_rt_spc_timer = src->d_rtbtimer;
|
||||
dst->d_rt_spc_timer = copy_from_xfs_dqblk_ts(src, src->d_rtbtimer,
|
||||
src->d_rtbtimer_hi);
|
||||
dst->d_rt_spc_warns = src->d_rtbwarns;
|
||||
dst->d_fieldmask = 0;
|
||||
if (src->d_fieldmask & FS_DQ_ISOFT)
|
||||
|
|
@ -639,10 +650,26 @@ static int quota_setxquota(struct super_block *sb, int type, qid_t id,
|
|||
return sb->s_qcop->set_dqblk(sb, qid, &qdq);
|
||||
}
|
||||
|
||||
static inline void copy_to_xfs_dqblk_ts(const struct fs_disk_quota *d,
|
||||
__s32 *timer_lo, __s8 *timer_hi, s64 timer)
|
||||
{
|
||||
*timer_lo = timer;
|
||||
if (d->d_fieldmask & FS_DQ_BIGTIME)
|
||||
*timer_hi = timer >> 32;
|
||||
}
|
||||
|
||||
static inline bool want_bigtime(s64 timer)
|
||||
{
|
||||
return timer > S32_MAX || timer < S32_MIN;
|
||||
}
|
||||
|
||||
static void copy_to_xfs_dqblk(struct fs_disk_quota *dst, struct qc_dqblk *src,
|
||||
int type, qid_t id)
|
||||
{
|
||||
memset(dst, 0, sizeof(*dst));
|
||||
if (want_bigtime(src->d_ino_timer) || want_bigtime(src->d_spc_timer) ||
|
||||
want_bigtime(src->d_rt_spc_timer))
|
||||
dst->d_fieldmask |= FS_DQ_BIGTIME;
|
||||
dst->d_version = FS_DQUOT_VERSION;
|
||||
dst->d_id = id;
|
||||
if (type == USRQUOTA)
|
||||
|
|
@ -657,14 +684,17 @@ static void copy_to_xfs_dqblk(struct fs_disk_quota *dst, struct qc_dqblk *src,
|
|||
dst->d_ino_softlimit = src->d_ino_softlimit;
|
||||
dst->d_bcount = quota_btobb(src->d_space);
|
||||
dst->d_icount = src->d_ino_count;
|
||||
dst->d_itimer = src->d_ino_timer;
|
||||
dst->d_btimer = src->d_spc_timer;
|
||||
copy_to_xfs_dqblk_ts(dst, &dst->d_itimer, &dst->d_itimer_hi,
|
||||
src->d_ino_timer);
|
||||
copy_to_xfs_dqblk_ts(dst, &dst->d_btimer, &dst->d_btimer_hi,
|
||||
src->d_spc_timer);
|
||||
dst->d_iwarns = src->d_ino_warns;
|
||||
dst->d_bwarns = src->d_spc_warns;
|
||||
dst->d_rtb_hardlimit = quota_btobb(src->d_rt_spc_hardlimit);
|
||||
dst->d_rtb_softlimit = quota_btobb(src->d_rt_spc_softlimit);
|
||||
dst->d_rtbcount = quota_btobb(src->d_rt_space);
|
||||
dst->d_rtbtimer = src->d_rt_spc_timer;
|
||||
copy_to_xfs_dqblk_ts(dst, &dst->d_rtbtimer, &dst->d_rtbtimer_hi,
|
||||
src->d_rt_spc_timer);
|
||||
dst->d_rtbwarns = src->d_rt_spc_warns;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -282,6 +282,7 @@ static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot)
|
|||
d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
|
||||
d->dqb_btime = cpu_to_le64(m->dqb_btime);
|
||||
d->dqb_id = cpu_to_le32(from_kqid(&init_user_ns, dquot->dq_id));
|
||||
d->dqb_pad = 0;
|
||||
if (qtree_entry_unused(info, dp))
|
||||
d->dqb_itime = cpu_to_le64(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1551,11 +1551,7 @@ void reiserfs_read_locked_inode(struct inode *inode,
|
|||
* set version 1, version 2 could be used too, because stat data
|
||||
* key is the same in both versions
|
||||
*/
|
||||
key.version = KEY_FORMAT_3_5;
|
||||
key.on_disk_key.k_dir_id = dirino;
|
||||
key.on_disk_key.k_objectid = inode->i_ino;
|
||||
key.on_disk_key.k_offset = 0;
|
||||
key.on_disk_key.k_type = 0;
|
||||
_make_cpu_key(&key, KEY_FORMAT_3_5, dirino, inode->i_ino, 0, 0, 3);
|
||||
|
||||
/* look for the object's stat data */
|
||||
retval = search_item(inode->i_sb, &key, &path_to_sd);
|
||||
|
|
@ -2163,7 +2159,8 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
|
|||
out_inserted_sd:
|
||||
clear_nlink(inode);
|
||||
th->t_trans_id = 0; /* so the caller can't use this handle later */
|
||||
unlock_new_inode(inode); /* OK to do even if we hadn't locked it */
|
||||
if (inode->i_state & I_NEW)
|
||||
unlock_new_inode(inode);
|
||||
iput(inode);
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1258,6 +1258,10 @@ static int reiserfs_parse_options(struct super_block *s,
|
|||
"turned on.");
|
||||
return 0;
|
||||
}
|
||||
if (qf_names[qtype] !=
|
||||
REISERFS_SB(s)->s_qf_names[qtype])
|
||||
kfree(qf_names[qtype]);
|
||||
qf_names[qtype] = NULL;
|
||||
if (*arg) { /* Some filename specified? */
|
||||
if (REISERFS_SB(s)->s_qf_names[qtype]
|
||||
&& strcmp(REISERFS_SB(s)->s_qf_names[qtype],
|
||||
|
|
@ -1287,10 +1291,6 @@ static int reiserfs_parse_options(struct super_block *s,
|
|||
else
|
||||
*mount_options |= 1 << REISERFS_GRPQUOTA;
|
||||
} else {
|
||||
if (qf_names[qtype] !=
|
||||
REISERFS_SB(s)->s_qf_names[qtype])
|
||||
kfree(qf_names[qtype]);
|
||||
qf_names[qtype] = NULL;
|
||||
if (qtype == USRQUOTA)
|
||||
*mount_options &= ~(1 << REISERFS_USRQUOTA);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -674,6 +674,13 @@ reiserfs_xattr_get(struct inode *inode, const char *name, void *buffer,
|
|||
if (get_inode_sd_version(inode) == STAT_DATA_V1)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/*
|
||||
* priv_root needn't be initialized during mount so allow initial
|
||||
* lookups to succeed.
|
||||
*/
|
||||
if (!REISERFS_SB(inode->i_sb)->priv_root)
|
||||
return 0;
|
||||
|
||||
dentry = xattr_lookup(inode, name, XATTR_REPLACE);
|
||||
if (IS_ERR(dentry)) {
|
||||
err = PTR_ERR(dentry);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ struct fileIdentDesc *udf_fileident_read(struct inode *dir, loff_t *nf_pos,
|
|||
fibh->soffset = fibh->eoffset;
|
||||
|
||||
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
|
||||
fi = udf_get_fileident(iinfo->i_ext.i_data -
|
||||
fi = udf_get_fileident(iinfo->i_data -
|
||||
(iinfo->i_efe ?
|
||||
sizeof(struct extendedFileEntry) :
|
||||
sizeof(struct fileEntry)),
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ static void __udf_adinicb_readpage(struct page *page)
|
|||
* So just sample it once and use the same value everywhere.
|
||||
*/
|
||||
kaddr = kmap_atomic(page);
|
||||
memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, isize);
|
||||
memcpy(kaddr, iinfo->i_data + iinfo->i_lenEAttr, isize);
|
||||
memset(kaddr + isize, 0, PAGE_SIZE - isize);
|
||||
flush_dcache_page(page);
|
||||
SetPageUptodate(page);
|
||||
|
|
@ -76,8 +76,7 @@ static int udf_adinicb_writepage(struct page *page,
|
|||
BUG_ON(!PageLocked(page));
|
||||
|
||||
kaddr = kmap_atomic(page);
|
||||
memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr,
|
||||
i_size_read(inode));
|
||||
memcpy(iinfo->i_data + iinfo->i_lenEAttr, kaddr, i_size_read(inode));
|
||||
SetPageUptodate(page);
|
||||
kunmap_atomic(kaddr);
|
||||
mark_inode_dirty(inode);
|
||||
|
|
@ -215,7 +214,7 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
return put_user(UDF_I(inode)->i_lenEAttr, (int __user *)arg);
|
||||
case UDF_GETEABLOCK:
|
||||
return copy_to_user((char __user *)arg,
|
||||
UDF_I(inode)->i_ext.i_data,
|
||||
UDF_I(inode)->i_data,
|
||||
UDF_I(inode)->i_lenEAttr) ? -EFAULT : 0;
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
|
|
|
|||
|
|
@ -67,16 +67,16 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode)
|
|||
iinfo->i_efe = 1;
|
||||
if (UDF_VERS_USE_EXTENDED_FE > sbi->s_udfrev)
|
||||
sbi->s_udfrev = UDF_VERS_USE_EXTENDED_FE;
|
||||
iinfo->i_ext.i_data = kzalloc(inode->i_sb->s_blocksize -
|
||||
sizeof(struct extendedFileEntry),
|
||||
GFP_KERNEL);
|
||||
iinfo->i_data = kzalloc(inode->i_sb->s_blocksize -
|
||||
sizeof(struct extendedFileEntry),
|
||||
GFP_KERNEL);
|
||||
} else {
|
||||
iinfo->i_efe = 0;
|
||||
iinfo->i_ext.i_data = kzalloc(inode->i_sb->s_blocksize -
|
||||
sizeof(struct fileEntry),
|
||||
GFP_KERNEL);
|
||||
iinfo->i_data = kzalloc(inode->i_sb->s_blocksize -
|
||||
sizeof(struct fileEntry),
|
||||
GFP_KERNEL);
|
||||
}
|
||||
if (!iinfo->i_ext.i_data) {
|
||||
if (!iinfo->i_data) {
|
||||
iput(inode);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,23 +139,26 @@ void udf_evict_inode(struct inode *inode)
|
|||
struct udf_inode_info *iinfo = UDF_I(inode);
|
||||
int want_delete = 0;
|
||||
|
||||
if (!inode->i_nlink && !is_bad_inode(inode)) {
|
||||
want_delete = 1;
|
||||
udf_setsize(inode, 0);
|
||||
udf_update_inode(inode, IS_SYNC(inode));
|
||||
if (!is_bad_inode(inode)) {
|
||||
if (!inode->i_nlink) {
|
||||
want_delete = 1;
|
||||
udf_setsize(inode, 0);
|
||||
udf_update_inode(inode, IS_SYNC(inode));
|
||||
}
|
||||
if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB &&
|
||||
inode->i_size != iinfo->i_lenExtents) {
|
||||
udf_warn(inode->i_sb,
|
||||
"Inode %lu (mode %o) has inode size %llu different from extent length %llu. Filesystem need not be standards compliant.\n",
|
||||
inode->i_ino, inode->i_mode,
|
||||
(unsigned long long)inode->i_size,
|
||||
(unsigned long long)iinfo->i_lenExtents);
|
||||
}
|
||||
}
|
||||
truncate_inode_pages_final(&inode->i_data);
|
||||
invalidate_inode_buffers(inode);
|
||||
clear_inode(inode);
|
||||
if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB &&
|
||||
inode->i_size != iinfo->i_lenExtents) {
|
||||
udf_warn(inode->i_sb, "Inode %lu (mode %o) has inode size %llu different from extent length %llu. Filesystem need not be standards compliant.\n",
|
||||
inode->i_ino, inode->i_mode,
|
||||
(unsigned long long)inode->i_size,
|
||||
(unsigned long long)iinfo->i_lenExtents);
|
||||
}
|
||||
kfree(iinfo->i_ext.i_data);
|
||||
iinfo->i_ext.i_data = NULL;
|
||||
kfree(iinfo->i_data);
|
||||
iinfo->i_data = NULL;
|
||||
udf_clear_extent_cache(inode);
|
||||
if (want_delete) {
|
||||
udf_free_inode(inode);
|
||||
|
|
@ -285,14 +288,14 @@ int udf_expand_file_adinicb(struct inode *inode)
|
|||
kaddr = kmap_atomic(page);
|
||||
memset(kaddr + iinfo->i_lenAlloc, 0x00,
|
||||
PAGE_SIZE - iinfo->i_lenAlloc);
|
||||
memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr,
|
||||
memcpy(kaddr, iinfo->i_data + iinfo->i_lenEAttr,
|
||||
iinfo->i_lenAlloc);
|
||||
flush_dcache_page(page);
|
||||
SetPageUptodate(page);
|
||||
kunmap_atomic(kaddr);
|
||||
}
|
||||
down_write(&iinfo->i_data_sem);
|
||||
memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0x00,
|
||||
memset(iinfo->i_data + iinfo->i_lenEAttr, 0x00,
|
||||
iinfo->i_lenAlloc);
|
||||
iinfo->i_lenAlloc = 0;
|
||||
if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
|
||||
|
|
@ -308,8 +311,7 @@ int udf_expand_file_adinicb(struct inode *inode)
|
|||
lock_page(page);
|
||||
down_write(&iinfo->i_data_sem);
|
||||
kaddr = kmap_atomic(page);
|
||||
memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr,
|
||||
inode->i_size);
|
||||
memcpy(iinfo->i_data + iinfo->i_lenEAttr, kaddr, inode->i_size);
|
||||
kunmap_atomic(kaddr);
|
||||
unlock_page(page);
|
||||
iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
|
||||
|
|
@ -396,8 +398,7 @@ struct buffer_head *udf_expand_dir_adinicb(struct inode *inode,
|
|||
}
|
||||
mark_buffer_dirty_inode(dbh, inode);
|
||||
|
||||
memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr, 0,
|
||||
iinfo->i_lenAlloc);
|
||||
memset(iinfo->i_data + iinfo->i_lenEAttr, 0, iinfo->i_lenAlloc);
|
||||
iinfo->i_lenAlloc = 0;
|
||||
eloc.logicalBlockNum = *block;
|
||||
eloc.partitionReferenceNum =
|
||||
|
|
@ -1260,7 +1261,7 @@ int udf_setsize(struct inode *inode, loff_t newsize)
|
|||
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
|
||||
down_write(&iinfo->i_data_sem);
|
||||
udf_clear_extent_cache(inode);
|
||||
memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr + newsize,
|
||||
memset(iinfo->i_data + iinfo->i_lenEAttr + newsize,
|
||||
0x00, bsize - newsize -
|
||||
udf_file_entry_alloc_offset(inode));
|
||||
iinfo->i_lenAlloc = newsize;
|
||||
|
|
@ -1411,7 +1412,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
|
|||
sizeof(struct extendedFileEntry));
|
||||
if (ret)
|
||||
goto out;
|
||||
memcpy(iinfo->i_ext.i_data,
|
||||
memcpy(iinfo->i_data,
|
||||
bh->b_data + sizeof(struct extendedFileEntry),
|
||||
bs - sizeof(struct extendedFileEntry));
|
||||
} else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) {
|
||||
|
|
@ -1420,7 +1421,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
|
|||
ret = udf_alloc_i_data(inode, bs - sizeof(struct fileEntry));
|
||||
if (ret)
|
||||
goto out;
|
||||
memcpy(iinfo->i_ext.i_data,
|
||||
memcpy(iinfo->i_data,
|
||||
bh->b_data + sizeof(struct fileEntry),
|
||||
bs - sizeof(struct fileEntry));
|
||||
} else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_USE)) {
|
||||
|
|
@ -1433,7 +1434,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
|
|||
sizeof(struct unallocSpaceEntry));
|
||||
if (ret)
|
||||
goto out;
|
||||
memcpy(iinfo->i_ext.i_data,
|
||||
memcpy(iinfo->i_data,
|
||||
bh->b_data + sizeof(struct unallocSpaceEntry),
|
||||
bs - sizeof(struct unallocSpaceEntry));
|
||||
return 0;
|
||||
|
|
@ -1614,8 +1615,8 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
|
|||
static int udf_alloc_i_data(struct inode *inode, size_t size)
|
||||
{
|
||||
struct udf_inode_info *iinfo = UDF_I(inode);
|
||||
iinfo->i_ext.i_data = kmalloc(size, GFP_KERNEL);
|
||||
if (!iinfo->i_ext.i_data)
|
||||
iinfo->i_data = kmalloc(size, GFP_KERNEL);
|
||||
if (!iinfo->i_data)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1706,7 +1707,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
|
|||
|
||||
use->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc);
|
||||
memcpy(bh->b_data + sizeof(struct unallocSpaceEntry),
|
||||
iinfo->i_ext.i_data, inode->i_sb->s_blocksize -
|
||||
iinfo->i_data, inode->i_sb->s_blocksize -
|
||||
sizeof(struct unallocSpaceEntry));
|
||||
use->descTag.tagIdent = cpu_to_le16(TAG_IDENT_USE);
|
||||
crclen = sizeof(struct unallocSpaceEntry);
|
||||
|
|
@ -1772,7 +1773,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
|
|||
|
||||
if (iinfo->i_efe == 0) {
|
||||
memcpy(bh->b_data + sizeof(struct fileEntry),
|
||||
iinfo->i_ext.i_data,
|
||||
iinfo->i_data,
|
||||
inode->i_sb->s_blocksize - sizeof(struct fileEntry));
|
||||
fe->logicalBlocksRecorded = cpu_to_le64(lb_recorded);
|
||||
|
||||
|
|
@ -1791,7 +1792,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
|
|||
crclen = sizeof(struct fileEntry);
|
||||
} else {
|
||||
memcpy(bh->b_data + sizeof(struct extendedFileEntry),
|
||||
iinfo->i_ext.i_data,
|
||||
iinfo->i_data,
|
||||
inode->i_sb->s_blocksize -
|
||||
sizeof(struct extendedFileEntry));
|
||||
efe->objectSize =
|
||||
|
|
@ -2087,7 +2088,7 @@ void udf_write_aext(struct inode *inode, struct extent_position *epos,
|
|||
struct udf_inode_info *iinfo = UDF_I(inode);
|
||||
|
||||
if (!epos->bh)
|
||||
ptr = iinfo->i_ext.i_data + epos->offset -
|
||||
ptr = iinfo->i_data + epos->offset -
|
||||
udf_file_entry_alloc_offset(inode) +
|
||||
iinfo->i_lenEAttr;
|
||||
else
|
||||
|
|
@ -2179,7 +2180,7 @@ int8_t udf_current_aext(struct inode *inode, struct extent_position *epos,
|
|||
if (!epos->bh) {
|
||||
if (!epos->offset)
|
||||
epos->offset = udf_file_entry_alloc_offset(inode);
|
||||
ptr = iinfo->i_ext.i_data + epos->offset -
|
||||
ptr = iinfo->i_data + epos->offset -
|
||||
udf_file_entry_alloc_offset(inode) +
|
||||
iinfo->i_lenEAttr;
|
||||
alen = udf_file_entry_alloc_offset(inode) +
|
||||
|
|
|
|||
|
|
@ -52,9 +52,9 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size,
|
|||
uint16_t crclen;
|
||||
struct udf_inode_info *iinfo = UDF_I(inode);
|
||||
|
||||
ea = iinfo->i_ext.i_data;
|
||||
ea = iinfo->i_data;
|
||||
if (iinfo->i_lenEAttr) {
|
||||
ad = iinfo->i_ext.i_data + iinfo->i_lenEAttr;
|
||||
ad = iinfo->i_data + iinfo->i_lenEAttr;
|
||||
} else {
|
||||
ad = ea;
|
||||
size += sizeof(struct extendedAttrHeaderDesc);
|
||||
|
|
@ -153,7 +153,7 @@ struct genericFormat *udf_get_extendedattr(struct inode *inode, uint32_t type,
|
|||
uint32_t offset;
|
||||
struct udf_inode_info *iinfo = UDF_I(inode);
|
||||
|
||||
ea = iinfo->i_ext.i_data;
|
||||
ea = iinfo->i_data;
|
||||
|
||||
if (iinfo->i_lenEAttr) {
|
||||
struct extendedAttrHeaderDesc *eahd;
|
||||
|
|
|
|||
|
|
@ -460,8 +460,7 @@ static struct fileIdentDesc *udf_add_entry(struct inode *dir,
|
|||
if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
|
||||
block = dinfo->i_location.logicalBlockNum;
|
||||
fi = (struct fileIdentDesc *)
|
||||
(dinfo->i_ext.i_data +
|
||||
fibh->soffset -
|
||||
(dinfo->i_data + fibh->soffset -
|
||||
udf_ext0_offset(dir) +
|
||||
dinfo->i_lenEAttr);
|
||||
} else {
|
||||
|
|
@ -940,7 +939,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
|
|||
mark_buffer_dirty_inode(epos.bh, inode);
|
||||
ea = epos.bh->b_data + udf_ext0_offset(inode);
|
||||
} else
|
||||
ea = iinfo->i_ext.i_data + iinfo->i_lenEAttr;
|
||||
ea = iinfo->i_data + iinfo->i_lenEAttr;
|
||||
|
||||
eoffset = sb->s_blocksize - udf_ext0_offset(inode);
|
||||
pc = (struct pathComponent *)ea;
|
||||
|
|
@ -1120,7 +1119,7 @@ static int udf_rename(struct inode *old_dir, struct dentry *old_dentry,
|
|||
retval = -EIO;
|
||||
if (old_iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
|
||||
dir_fi = udf_get_fileident(
|
||||
old_iinfo->i_ext.i_data -
|
||||
old_iinfo->i_data -
|
||||
(old_iinfo->i_efe ?
|
||||
sizeof(struct extendedFileEntry) :
|
||||
sizeof(struct fileEntry)),
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
|
|||
}
|
||||
|
||||
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
|
||||
loc = le32_to_cpu(((__le32 *)(iinfo->i_ext.i_data +
|
||||
loc = le32_to_cpu(((__le32 *)(iinfo->i_data +
|
||||
vdata->s_start_offset))[block]);
|
||||
goto translate;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ static void init_once(void *foo)
|
|||
{
|
||||
struct udf_inode_info *ei = (struct udf_inode_info *)foo;
|
||||
|
||||
ei->i_ext.i_data = NULL;
|
||||
ei->i_data = NULL;
|
||||
inode_init_once(&ei->vfs_inode);
|
||||
}
|
||||
|
||||
|
|
@ -854,7 +854,7 @@ static int udf_load_pvoldesc(struct super_block *sb, sector_t block)
|
|||
uint8_t *outstr;
|
||||
struct buffer_head *bh;
|
||||
uint16_t ident;
|
||||
int ret = -ENOMEM;
|
||||
int ret;
|
||||
struct timestamp *ts;
|
||||
|
||||
outstr = kmalloc(128, GFP_NOFS);
|
||||
|
|
@ -1006,18 +1006,10 @@ int udf_compute_nr_groups(struct super_block *sb, u32 partition)
|
|||
static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index)
|
||||
{
|
||||
struct udf_bitmap *bitmap;
|
||||
int nr_groups;
|
||||
int size;
|
||||
|
||||
nr_groups = udf_compute_nr_groups(sb, index);
|
||||
size = sizeof(struct udf_bitmap) +
|
||||
(sizeof(struct buffer_head *) * nr_groups);
|
||||
|
||||
if (size <= PAGE_SIZE)
|
||||
bitmap = kzalloc(size, GFP_KERNEL);
|
||||
else
|
||||
bitmap = vzalloc(size); /* TODO: get rid of vzalloc */
|
||||
int nr_groups = udf_compute_nr_groups(sb, index);
|
||||
|
||||
bitmap = kvzalloc(struct_size(bitmap, s_block_bitmap, nr_groups),
|
||||
GFP_KERNEL);
|
||||
if (!bitmap)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -1210,7 +1202,7 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
|
|||
vat20 = (struct virtualAllocationTable20 *)bh->b_data;
|
||||
} else {
|
||||
vat20 = (struct virtualAllocationTable20 *)
|
||||
vati->i_ext.i_data;
|
||||
vati->i_data;
|
||||
}
|
||||
|
||||
map->s_type_specific.s_virtual.s_start_offset =
|
||||
|
|
@ -1353,6 +1345,12 @@ static int udf_load_sparable_map(struct super_block *sb,
|
|||
(int)spm->numSparingTables);
|
||||
return -EIO;
|
||||
}
|
||||
if (le32_to_cpu(spm->sizeSparingTable) > sb->s_blocksize) {
|
||||
udf_err(sb, "error loading logical volume descriptor: "
|
||||
"Too big sparing table size (%u)\n",
|
||||
le32_to_cpu(spm->sizeSparingTable));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
for (i = 0; i < spm->numSparingTables; i++) {
|
||||
loc = le32_to_cpu(spm->locSparingTable[i]);
|
||||
|
|
@ -1698,7 +1696,8 @@ static noinline int udf_process_sequence(
|
|||
"Pointers (max %u supported)\n",
|
||||
UDF_MAX_TD_NESTING);
|
||||
brelse(bh);
|
||||
return -EIO;
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
vdp = (struct volDescPtr *)bh->b_data;
|
||||
|
|
@ -1718,7 +1717,8 @@ static noinline int udf_process_sequence(
|
|||
curr = get_volume_descriptor_record(ident, bh, &data);
|
||||
if (IS_ERR(curr)) {
|
||||
brelse(bh);
|
||||
return PTR_ERR(curr);
|
||||
ret = PTR_ERR(curr);
|
||||
goto out;
|
||||
}
|
||||
/* Descriptor we don't care about? */
|
||||
if (!curr)
|
||||
|
|
@ -1740,28 +1740,31 @@ static noinline int udf_process_sequence(
|
|||
*/
|
||||
if (!data.vds[VDS_POS_PRIMARY_VOL_DESC].block) {
|
||||
udf_err(sb, "Primary Volume Descriptor not found!\n");
|
||||
return -EAGAIN;
|
||||
ret = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
ret = udf_load_pvoldesc(sb, data.vds[VDS_POS_PRIMARY_VOL_DESC].block);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
if (data.vds[VDS_POS_LOGICAL_VOL_DESC].block) {
|
||||
ret = udf_load_logicalvol(sb,
|
||||
data.vds[VDS_POS_LOGICAL_VOL_DESC].block,
|
||||
fileset);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Now handle prevailing Partition Descriptors */
|
||||
for (i = 0; i < data.num_part_descs; i++) {
|
||||
ret = udf_load_partdesc(sb, data.part_descs_loc[i].rec.block);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
ret = 0;
|
||||
out:
|
||||
kfree(data.part_descs_loc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ static int udf_symlink_filler(struct file *file, struct page *page)
|
|||
|
||||
down_read(&iinfo->i_data_sem);
|
||||
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
|
||||
symlink = iinfo->i_ext.i_data + iinfo->i_lenEAttr;
|
||||
symlink = iinfo->i_data + iinfo->i_lenEAttr;
|
||||
} else {
|
||||
bh = sb_bread(inode->i_sb, pos);
|
||||
|
||||
|
|
|
|||
|
|
@ -45,11 +45,7 @@ struct udf_inode_info {
|
|||
unsigned i_strat4096 : 1;
|
||||
unsigned i_streamdir : 1;
|
||||
unsigned reserved : 25;
|
||||
union {
|
||||
struct short_ad *i_sad;
|
||||
struct long_ad *i_lad;
|
||||
__u8 *i_data;
|
||||
} i_ext;
|
||||
__u8 *i_data;
|
||||
struct kernel_lb_addr i_locStreamdir;
|
||||
__u64 i_lenStreams;
|
||||
struct rw_semaphore i_data_sem;
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ static bool vboxsf_dir_emit(struct file *dir, struct dir_context *ctx)
|
|||
d_type = vboxsf_get_d_type(info->info.attr.mode);
|
||||
|
||||
/*
|
||||
* On 32 bit systems pos is 64 signed, while ino is 32 bit
|
||||
* On 32-bit systems pos is 64-bit signed, while ino is 32-bit
|
||||
* unsigned so fake_ino may overflow, check for this.
|
||||
*/
|
||||
if ((ino_t)(ctx->pos + 1) != (u64)(ctx->pos + 1)) {
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type)
|
|||
}
|
||||
}
|
||||
|
||||
void hv_setup_vmbus_irq(void (*handler)(void));
|
||||
int hv_setup_vmbus_irq(int irq, void (*handler)(void));
|
||||
void hv_remove_vmbus_irq(void);
|
||||
void hv_enable_vmbus_irq(void);
|
||||
void hv_disable_vmbus_irq(void);
|
||||
|
|
@ -99,6 +99,8 @@ void hv_remove_kexec_handler(void);
|
|||
void hv_setup_crash_handler(void (*handler)(struct pt_regs *regs));
|
||||
void hv_remove_crash_handler(void);
|
||||
|
||||
extern int vmbus_interrupt;
|
||||
|
||||
#if IS_ENABLED(CONFIG_HYPERV)
|
||||
/*
|
||||
* Hypervisor's notion of virtual processor ID is different from
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ struct hid_item {
|
|||
#define HID_UP_LNVENDOR 0xffa00000
|
||||
#define HID_UP_SENSOR 0x00200000
|
||||
#define HID_UP_ASUSVENDOR 0xff310000
|
||||
#define HID_UP_GOOGLEVENDOR 0xffd10000
|
||||
|
||||
#define HID_USAGE 0x0000ffff
|
||||
|
||||
|
|
@ -371,6 +372,7 @@ struct hid_item {
|
|||
#define HID_GROUP_LOGITECH_DJ_DEVICE 0x0102
|
||||
#define HID_GROUP_STEAM 0x0103
|
||||
#define HID_GROUP_LOGITECH_27MHZ_DEVICE 0x0104
|
||||
#define HID_GROUP_VIVALDI 0x0105
|
||||
|
||||
/*
|
||||
* HID protocol status
|
||||
|
|
|
|||
|
|
@ -657,7 +657,7 @@ int scif_unregister(scif_epd_t epd, off_t offset, size_t len);
|
|||
* the negative of one of the following errors is returned.
|
||||
*
|
||||
* Errors:
|
||||
* EACCESS - Attempt to write to a read-only range
|
||||
* EACCES - Attempt to write to a read-only range
|
||||
* EBADF, ENOTTY - epd is not a valid endpoint descriptor
|
||||
* ECONNRESET - Connection reset by peer
|
||||
* EINVAL - rma_flags is invalid
|
||||
|
|
@ -733,7 +733,7 @@ int scif_readfrom(scif_epd_t epd, off_t loffset, size_t len, off_t
|
|||
* the negative of one of the following errors is returned.
|
||||
*
|
||||
* Errors:
|
||||
* EACCESS - Attempt to write to a read-only range
|
||||
* EACCES - Attempt to write to a read-only range
|
||||
* EBADF, ENOTTY - epd is not a valid endpoint descriptor
|
||||
* ECONNRESET - Connection reset by peer
|
||||
* EINVAL - rma_flags is invalid
|
||||
|
|
@ -815,7 +815,7 @@ int scif_writeto(scif_epd_t epd, off_t loffset, size_t len, off_t
|
|||
* the negative of one of the following errors is returned.
|
||||
*
|
||||
* Errors:
|
||||
* EACCESS - Attempt to write to a read-only range
|
||||
* EACCES - Attempt to write to a read-only range
|
||||
* EBADF, ENOTTY - epd is not a valid endpoint descriptor
|
||||
* ECONNRESET - Connection reset by peer
|
||||
* EINVAL - rma_flags is invalid
|
||||
|
|
@ -895,7 +895,7 @@ int scif_vreadfrom(scif_epd_t epd, void *addr, size_t len, off_t roffset,
|
|||
* the negative of one of the following errors is returned.
|
||||
*
|
||||
* Errors:
|
||||
* EACCESS - Attempt to write to a read-only range
|
||||
* EACCES - Attempt to write to a read-only range
|
||||
* EBADF, ENOTTY - epd is not a valid endpoint descriptor
|
||||
* ECONNRESET - Connection reset by peer
|
||||
* EINVAL - rma_flags is invalid
|
||||
|
|
|
|||
|
|
@ -61,12 +61,16 @@ typedef struct fs_disk_quota {
|
|||
__u64 d_ino_softlimit;/* preferred inode limit */
|
||||
__u64 d_bcount; /* # disk blocks owned by the user */
|
||||
__u64 d_icount; /* # inodes owned by the user */
|
||||
__s32 d_itimer; /* zero if within inode limits */
|
||||
/* if not, we refuse service */
|
||||
__s32 d_itimer; /* Zero if within inode limits. If
|
||||
* not, we refuse service at this time
|
||||
* (in seconds since Unix epoch) */
|
||||
__s32 d_btimer; /* similar to above; for disk blocks */
|
||||
__u16 d_iwarns; /* # warnings issued wrt num inodes */
|
||||
__u16 d_bwarns; /* # warnings issued wrt disk blocks */
|
||||
__s32 d_padding2; /* padding2 - for future use */
|
||||
__s8 d_itimer_hi; /* upper 8 bits of timer values */
|
||||
__s8 d_btimer_hi;
|
||||
__s8 d_rtbtimer_hi;
|
||||
__s8 d_padding2; /* padding2 - for future use */
|
||||
__u64 d_rtb_hardlimit;/* absolute limit on realtime blks */
|
||||
__u64 d_rtb_softlimit;/* preferred limit on RT disk blks */
|
||||
__u64 d_rtbcount; /* # realtime blocks owned */
|
||||
|
|
@ -121,6 +125,12 @@ typedef struct fs_disk_quota {
|
|||
#define FS_DQ_RTBCOUNT (1<<14)
|
||||
#define FS_DQ_ACCT_MASK (FS_DQ_BCOUNT | FS_DQ_ICOUNT | FS_DQ_RTBCOUNT)
|
||||
|
||||
/*
|
||||
* Quota expiration timestamps are 40-bit signed integers, with the upper 8
|
||||
* bits encoded in the _hi fields.
|
||||
*/
|
||||
#define FS_DQ_BIGTIME (1<<15)
|
||||
|
||||
/*
|
||||
* Various flags related to quotactl(2).
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -468,7 +468,7 @@ static void __init setup_boot_config(const char *cmdline)
|
|||
|
||||
static int __init warn_bootconfig(char *str)
|
||||
{
|
||||
pr_warn("WARNING: 'bootconfig' found on the kernel command line but CONFIG_BOOTCONFIG is not set.\n");
|
||||
pr_warn("WARNING: 'bootconfig' found on the kernel command line but CONFIG_BOOT_CONFIG is not set.\n");
|
||||
return 0;
|
||||
}
|
||||
early_param("bootconfig", warn_bootconfig);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
* is later flushed into the main ring buffer via IRQ work.
|
||||
*
|
||||
* The alternative implementation is chosen transparently
|
||||
* by examinig current printk() context mask stored in @printk_context
|
||||
* by examining current printk() context mask stored in @printk_context
|
||||
* per-CPU variable.
|
||||
*
|
||||
* The implementation allows to flush the strings also from another CPU.
|
||||
|
|
|
|||
|
|
@ -552,7 +552,7 @@ static inline bool end_of_region(char c)
|
|||
}
|
||||
|
||||
/*
|
||||
* The format allows commas and whitespases at the beginning
|
||||
* The format allows commas and whitespaces at the beginning
|
||||
* of the region.
|
||||
*/
|
||||
static const char *bitmap_find_region(const char *str)
|
||||
|
|
|
|||
|
|
@ -7,19 +7,17 @@
|
|||
* macros defined by configfs.h
|
||||
*
|
||||
* Based on sysfs:
|
||||
* sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
|
||||
* sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
|
||||
*
|
||||
* configfs Copyright (C) 2005 Oracle. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/configfs.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 01-childless
|
||||
*
|
||||
|
|
@ -40,8 +38,8 @@ struct childless {
|
|||
|
||||
static inline struct childless *to_childless(struct config_item *item)
|
||||
{
|
||||
return item ? container_of(to_configfs_subsystem(to_config_group(item)),
|
||||
struct childless, subsys) : NULL;
|
||||
return container_of(to_configfs_subsystem(to_config_group(item)),
|
||||
struct childless, subsys);
|
||||
}
|
||||
|
||||
static ssize_t childless_showme_show(struct config_item *item, char *page)
|
||||
|
|
@ -64,17 +62,11 @@ static ssize_t childless_storeme_store(struct config_item *item,
|
|||
const char *page, size_t count)
|
||||
{
|
||||
struct childless *childless = to_childless(item);
|
||||
unsigned long tmp;
|
||||
char *p = (char *) page;
|
||||
int ret;
|
||||
|
||||
tmp = simple_strtoul(p, &p, 10);
|
||||
if (!p || (*p && (*p != '\n')))
|
||||
return -EINVAL;
|
||||
|
||||
if (tmp > INT_MAX)
|
||||
return -ERANGE;
|
||||
|
||||
childless->storeme = tmp;
|
||||
ret = kstrtoint(page, 10, &childless->storeme);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
|
@ -117,7 +109,6 @@ static struct childless childless_subsys = {
|
|||
},
|
||||
};
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
|
|
@ -136,7 +127,7 @@ struct simple_child {
|
|||
|
||||
static inline struct simple_child *to_simple_child(struct config_item *item)
|
||||
{
|
||||
return item ? container_of(item, struct simple_child, item) : NULL;
|
||||
return container_of(item, struct simple_child, item);
|
||||
}
|
||||
|
||||
static ssize_t simple_child_storeme_show(struct config_item *item, char *page)
|
||||
|
|
@ -148,17 +139,11 @@ static ssize_t simple_child_storeme_store(struct config_item *item,
|
|||
const char *page, size_t count)
|
||||
{
|
||||
struct simple_child *simple_child = to_simple_child(item);
|
||||
unsigned long tmp;
|
||||
char *p = (char *) page;
|
||||
int ret;
|
||||
|
||||
tmp = simple_strtoul(p, &p, 10);
|
||||
if (!p || (*p && (*p != '\n')))
|
||||
return -EINVAL;
|
||||
|
||||
if (tmp > INT_MAX)
|
||||
return -ERANGE;
|
||||
|
||||
simple_child->storeme = tmp;
|
||||
ret = kstrtoint(page, 10, &simple_child->storeme);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
|
@ -176,7 +161,7 @@ static void simple_child_release(struct config_item *item)
|
|||
}
|
||||
|
||||
static struct configfs_item_operations simple_child_item_ops = {
|
||||
.release = simple_child_release,
|
||||
.release = simple_child_release,
|
||||
};
|
||||
|
||||
static const struct config_item_type simple_child_type = {
|
||||
|
|
@ -185,15 +170,14 @@ static const struct config_item_type simple_child_type = {
|
|||
.ct_owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
||||
struct simple_children {
|
||||
struct config_group group;
|
||||
};
|
||||
|
||||
static inline struct simple_children *to_simple_children(struct config_item *item)
|
||||
{
|
||||
return item ? container_of(to_config_group(item),
|
||||
struct simple_children, group) : NULL;
|
||||
return container_of(to_config_group(item),
|
||||
struct simple_children, group);
|
||||
}
|
||||
|
||||
static struct config_item *simple_children_make_item(struct config_group *group,
|
||||
|
|
@ -208,8 +192,6 @@ static struct config_item *simple_children_make_item(struct config_group *group,
|
|||
config_item_init_type_name(&simple_child->item, name,
|
||||
&simple_child_type);
|
||||
|
||||
simple_child->storeme = 0;
|
||||
|
||||
return &simple_child->item;
|
||||
}
|
||||
|
||||
|
|
@ -263,7 +245,6 @@ static struct configfs_subsystem simple_children_subsys = {
|
|||
},
|
||||
};
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
|
|
@ -350,9 +331,8 @@ static struct configfs_subsystem *example_subsys[] = {
|
|||
|
||||
static int __init configfs_example_init(void)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
struct configfs_subsystem *subsys;
|
||||
int ret, i;
|
||||
|
||||
for (i = 0; example_subsys[i]; i++) {
|
||||
subsys = example_subsys[i];
|
||||
|
|
@ -361,9 +341,8 @@ static int __init configfs_example_init(void)
|
|||
mutex_init(&subsys->su_mutex);
|
||||
ret = configfs_register_subsystem(subsys);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "Error %d while registering subsystem %s\n",
|
||||
ret,
|
||||
subsys->su_group.cg_item.ci_namebuf);
|
||||
pr_err("Error %d while registering subsystem %s\n",
|
||||
ret, subsys->su_group.cg_item.ci_namebuf);
|
||||
goto out_unregister;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -598,7 +598,6 @@ extenstion||extension
|
|||
extracter||extractor
|
||||
faied||failed
|
||||
faield||failed
|
||||
falied||failed
|
||||
faild||failed
|
||||
failded||failed
|
||||
failer||failure
|
||||
|
|
@ -795,7 +794,6 @@ interrup||interrupt
|
|||
interrups||interrupts
|
||||
interruptted||interrupted
|
||||
interupted||interrupted
|
||||
interupt||interrupt
|
||||
intial||initial
|
||||
intialisation||initialisation
|
||||
intialised||initialised
|
||||
|
|
@ -971,7 +969,6 @@ occurd||occurred
|
|||
occured||occurred
|
||||
occurence||occurrence
|
||||
occure||occurred
|
||||
occured||occurred
|
||||
occuring||occurring
|
||||
offser||offset
|
||||
offet||offset
|
||||
|
|
@ -1440,7 +1437,6 @@ udpate||update
|
|||
uesd||used
|
||||
uknown||unknown
|
||||
usccess||success
|
||||
usupported||unsupported
|
||||
uncommited||uncommitted
|
||||
uncompatible||incompatible
|
||||
unconditionaly||unconditionally
|
||||
|
|
|
|||
|
|
@ -39,6 +39,5 @@
|
|||
#define MADV_SOFT_OFFLINE 101
|
||||
/* MAP_32BIT is undefined on parisc, fix it for perf */
|
||||
#define MAP_32BIT 0
|
||||
/* MAP_UNINITIALIZED is undefined on parisc, fix it for perf */
|
||||
#define MAP_UNINITIALIZED 0
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -39,3 +39,4 @@
|
|||
# CONFIG_QCOM_CPR is not set
|
||||
# CONFIG_RESET_BRCMSTB_RESCAL is not set
|
||||
# CONFIG_RESET_INTEL_GW is not set
|
||||
# CONFIG_ADI_AXI_ADC is not set
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ from collections import namedtuple
|
|||
from enum import Enum, auto
|
||||
|
||||
import kunit_config
|
||||
import kunit_json
|
||||
import kunit_kernel
|
||||
import kunit_parser
|
||||
|
||||
|
|
@ -30,9 +31,9 @@ KunitBuildRequest = namedtuple('KunitBuildRequest',
|
|||
KunitExecRequest = namedtuple('KunitExecRequest',
|
||||
['timeout', 'build_dir', 'alltests'])
|
||||
KunitParseRequest = namedtuple('KunitParseRequest',
|
||||
['raw_output', 'input_data'])
|
||||
['raw_output', 'input_data', 'build_dir', 'json'])
|
||||
KunitRequest = namedtuple('KunitRequest', ['raw_output','timeout', 'jobs',
|
||||
'build_dir', 'alltests',
|
||||
'build_dir', 'alltests', 'json',
|
||||
'make_options'])
|
||||
|
||||
KernelDirectoryPath = sys.argv[0].split('tools/testing/kunit/')[0]
|
||||
|
|
@ -113,12 +114,22 @@ def parse_tests(request: KunitParseRequest) -> KunitResult:
|
|||
test_result = kunit_parser.TestResult(kunit_parser.TestStatus.SUCCESS,
|
||||
[],
|
||||
'Tests not Parsed.')
|
||||
|
||||
if request.raw_output:
|
||||
kunit_parser.raw_output(request.input_data)
|
||||
else:
|
||||
test_result = kunit_parser.parse_run_tests(request.input_data)
|
||||
parse_end = time.time()
|
||||
|
||||
if request.json:
|
||||
json_obj = kunit_json.get_json_result(
|
||||
test_result=test_result,
|
||||
def_config='kunit_defconfig',
|
||||
build_dir=request.build_dir,
|
||||
json_path=request.json)
|
||||
if request.json == 'stdout':
|
||||
print(json_obj)
|
||||
|
||||
if test_result.status != kunit_parser.TestStatus.SUCCESS:
|
||||
return KunitResult(KunitStatus.TEST_FAILURE, test_result,
|
||||
parse_end - parse_start)
|
||||
|
|
@ -151,7 +162,9 @@ def run_tests(linux: kunit_kernel.LinuxSourceTree,
|
|||
return exec_result
|
||||
|
||||
parse_request = KunitParseRequest(request.raw_output,
|
||||
exec_result.result)
|
||||
exec_result.result,
|
||||
request.build_dir,
|
||||
request.json)
|
||||
parse_result = parse_tests(parse_request)
|
||||
|
||||
run_end = time.time()
|
||||
|
|
@ -195,7 +208,12 @@ def add_exec_opts(parser):
|
|||
def add_parse_opts(parser):
|
||||
parser.add_argument('--raw_output', help='don\'t format output from kernel',
|
||||
action='store_true')
|
||||
|
||||
parser.add_argument('--json',
|
||||
nargs='?',
|
||||
help='Stores test results in a JSON, and either '
|
||||
'prints to stdout or saves to file if a '
|
||||
'filename is specified',
|
||||
type=str, const='stdout', default=None)
|
||||
|
||||
def main(argv, linux=None):
|
||||
parser = argparse.ArgumentParser(
|
||||
|
|
@ -237,10 +255,16 @@ def main(argv, linux=None):
|
|||
|
||||
cli_args = parser.parse_args(argv)
|
||||
|
||||
if get_kernel_root_path():
|
||||
os.chdir(get_kernel_root_path())
|
||||
|
||||
if cli_args.subcommand == 'run':
|
||||
if not os.path.exists(cli_args.build_dir):
|
||||
os.mkdir(cli_args.build_dir)
|
||||
|
||||
if not os.path.exists(kunit_kernel.kunitconfig_path):
|
||||
create_default_kunitconfig()
|
||||
|
||||
if not linux:
|
||||
linux = kunit_kernel.LinuxSourceTree()
|
||||
|
||||
|
|
@ -249,14 +273,18 @@ def main(argv, linux=None):
|
|||
cli_args.jobs,
|
||||
cli_args.build_dir,
|
||||
cli_args.alltests,
|
||||
cli_args.json,
|
||||
cli_args.make_options)
|
||||
result = run_tests(linux, request)
|
||||
if result.status != KunitStatus.SUCCESS:
|
||||
sys.exit(1)
|
||||
elif cli_args.subcommand == 'config':
|
||||
if cli_args.build_dir:
|
||||
if not os.path.exists(cli_args.build_dir):
|
||||
os.mkdir(cli_args.build_dir)
|
||||
if cli_args.build_dir and (
|
||||
not os.path.exists(cli_args.build_dir)):
|
||||
os.mkdir(cli_args.build_dir)
|
||||
|
||||
if not os.path.exists(kunit_kernel.kunitconfig_path):
|
||||
create_default_kunitconfig()
|
||||
|
||||
if not linux:
|
||||
linux = kunit_kernel.LinuxSourceTree()
|
||||
|
|
@ -270,10 +298,6 @@ def main(argv, linux=None):
|
|||
if result.status != KunitStatus.SUCCESS:
|
||||
sys.exit(1)
|
||||
elif cli_args.subcommand == 'build':
|
||||
if cli_args.build_dir:
|
||||
if not os.path.exists(cli_args.build_dir):
|
||||
os.mkdir(cli_args.build_dir)
|
||||
|
||||
if not linux:
|
||||
linux = kunit_kernel.LinuxSourceTree()
|
||||
|
||||
|
|
@ -288,10 +312,6 @@ def main(argv, linux=None):
|
|||
if result.status != KunitStatus.SUCCESS:
|
||||
sys.exit(1)
|
||||
elif cli_args.subcommand == 'exec':
|
||||
if cli_args.build_dir:
|
||||
if not os.path.exists(cli_args.build_dir):
|
||||
os.mkdir(cli_args.build_dir)
|
||||
|
||||
if not linux:
|
||||
linux = kunit_kernel.LinuxSourceTree()
|
||||
|
||||
|
|
@ -300,7 +320,9 @@ def main(argv, linux=None):
|
|||
cli_args.alltests)
|
||||
exec_result = exec_tests(linux, exec_request)
|
||||
parse_request = KunitParseRequest(cli_args.raw_output,
|
||||
exec_result.result)
|
||||
exec_result.result,
|
||||
cli_args.build_dir,
|
||||
cli_args.json)
|
||||
result = parse_tests(parse_request)
|
||||
kunit_parser.print_with_timestamp((
|
||||
'Elapsed time: %.3fs\n') % (
|
||||
|
|
@ -314,7 +336,9 @@ def main(argv, linux=None):
|
|||
with open(cli_args.file, 'r') as f:
|
||||
kunit_output = f.read().splitlines()
|
||||
request = KunitParseRequest(cli_args.raw_output,
|
||||
kunit_output)
|
||||
kunit_output,
|
||||
cli_args.build_dir,
|
||||
cli_args.json)
|
||||
result = parse_tests(request)
|
||||
if result.status != KunitStatus.SUCCESS:
|
||||
sys.exit(1)
|
||||
|
|
|
|||
63
tools/testing/kunit/kunit_json.py
Normal file
63
tools/testing/kunit/kunit_json.py
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Generates JSON from KUnit results according to
|
||||
# KernelCI spec: https://github.com/kernelci/kernelci-doc/wiki/Test-API
|
||||
#
|
||||
# Copyright (C) 2020, Google LLC.
|
||||
# Author: Heidi Fahim <heidifahim@google.com>
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
import kunit_parser
|
||||
|
||||
from kunit_parser import TestStatus
|
||||
|
||||
def get_json_result(test_result, def_config, build_dir, json_path):
|
||||
sub_groups = []
|
||||
|
||||
# Each test suite is mapped to a KernelCI sub_group
|
||||
for test_suite in test_result.suites:
|
||||
sub_group = {
|
||||
"name": test_suite.name,
|
||||
"arch": "UM",
|
||||
"defconfig": def_config,
|
||||
"build_environment": build_dir,
|
||||
"test_cases": [],
|
||||
"lab_name": None,
|
||||
"kernel": None,
|
||||
"job": None,
|
||||
"git_branch": "kselftest",
|
||||
}
|
||||
test_cases = []
|
||||
# TODO: Add attachments attribute in test_case with detailed
|
||||
# failure message, see https://api.kernelci.org/schema-test-case.html#get
|
||||
for case in test_suite.cases:
|
||||
test_case = {"name": case.name, "status": "FAIL"}
|
||||
if case.status == TestStatus.SUCCESS:
|
||||
test_case["status"] = "PASS"
|
||||
elif case.status == TestStatus.TEST_CRASHED:
|
||||
test_case["status"] = "ERROR"
|
||||
test_cases.append(test_case)
|
||||
sub_group["test_cases"] = test_cases
|
||||
sub_groups.append(sub_group)
|
||||
test_group = {
|
||||
"name": "KUnit Test Group",
|
||||
"arch": "UM",
|
||||
"defconfig": def_config,
|
||||
"build_environment": build_dir,
|
||||
"sub_groups": sub_groups,
|
||||
"lab_name": None,
|
||||
"kernel": None,
|
||||
"job": None,
|
||||
"git_branch": "kselftest",
|
||||
}
|
||||
json_obj = json.dumps(test_group, indent=4)
|
||||
if json_path != 'stdout':
|
||||
with open(json_path, 'w') as result_path:
|
||||
result_path.write(json_obj)
|
||||
root = __file__.split('tools/testing/kunit/')[0]
|
||||
kunit_parser.print_with_timestamp(
|
||||
"Test results stored in %s" %
|
||||
os.path.join(root, result_path.name))
|
||||
return json_obj
|
||||
|
|
@ -36,9 +36,9 @@ class LinuxSourceTreeOperations(object):
|
|||
try:
|
||||
subprocess.check_output(['make', 'mrproper'], stderr=subprocess.STDOUT)
|
||||
except OSError as e:
|
||||
raise ConfigError('Could not call make command: ' + e)
|
||||
raise ConfigError('Could not call make command: ' + str(e))
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise ConfigError(e.output)
|
||||
raise ConfigError(e.output.decode())
|
||||
|
||||
def make_olddefconfig(self, build_dir, make_options):
|
||||
command = ['make', 'ARCH=um', 'olddefconfig']
|
||||
|
|
@ -49,22 +49,27 @@ class LinuxSourceTreeOperations(object):
|
|||
try:
|
||||
subprocess.check_output(command, stderr=subprocess.STDOUT)
|
||||
except OSError as e:
|
||||
raise ConfigError('Could not call make command: ' + e)
|
||||
raise ConfigError('Could not call make command: ' + str(e))
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise ConfigError(e.output)
|
||||
raise ConfigError(e.output.decode())
|
||||
|
||||
def make_allyesconfig(self):
|
||||
def make_allyesconfig(self, build_dir, make_options):
|
||||
kunit_parser.print_with_timestamp(
|
||||
'Enabling all CONFIGs for UML...')
|
||||
command = ['make', 'ARCH=um', 'allyesconfig']
|
||||
if make_options:
|
||||
command.extend(make_options)
|
||||
if build_dir:
|
||||
command += ['O=' + build_dir]
|
||||
process = subprocess.Popen(
|
||||
['make', 'ARCH=um', 'allyesconfig'],
|
||||
command,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.STDOUT)
|
||||
process.wait()
|
||||
kunit_parser.print_with_timestamp(
|
||||
'Disabling broken configs to run KUnit tests...')
|
||||
with ExitStack() as es:
|
||||
config = open(KCONFIG_PATH, 'a')
|
||||
config = open(get_kconfig_path(build_dir), 'a')
|
||||
disable = open(BROKEN_ALLCONFIG_PATH, 'r').read()
|
||||
config.write(disable)
|
||||
kunit_parser.print_with_timestamp(
|
||||
|
|
@ -79,9 +84,9 @@ class LinuxSourceTreeOperations(object):
|
|||
try:
|
||||
subprocess.check_output(command, stderr=subprocess.STDOUT)
|
||||
except OSError as e:
|
||||
raise BuildError('Could not call execute make: ' + e)
|
||||
raise BuildError('Could not call execute make: ' + str(e))
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise BuildError(e.output)
|
||||
raise BuildError(e.output.decode())
|
||||
|
||||
def linux_bin(self, params, timeout, build_dir, outfile):
|
||||
"""Runs the Linux UML binary. Must be named 'linux'."""
|
||||
|
|
@ -161,9 +166,9 @@ class LinuxSourceTree(object):
|
|||
return self.build_config(build_dir, make_options)
|
||||
|
||||
def build_um_kernel(self, alltests, jobs, build_dir, make_options):
|
||||
if alltests:
|
||||
self._ops.make_allyesconfig()
|
||||
try:
|
||||
if alltests:
|
||||
self._ops.make_allyesconfig(build_dir, make_options)
|
||||
self._ops.make_olddefconfig(build_dir, make_options)
|
||||
self._ops.make(jobs, build_dir, make_options)
|
||||
except (ConfigError, BuildError) as e:
|
||||
|
|
|
|||
|
|
@ -11,11 +11,13 @@ from unittest import mock
|
|||
|
||||
import tempfile, shutil # Handling test_tmpdir
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
import kunit_config
|
||||
import kunit_parser
|
||||
import kunit_kernel
|
||||
import kunit_json
|
||||
import kunit
|
||||
|
||||
test_tmpdir = ''
|
||||
|
|
@ -230,6 +232,37 @@ class KUnitParserTest(unittest.TestCase):
|
|||
result = kunit_parser.parse_run_tests(file.readlines())
|
||||
self.assertEqual('kunit-resource-test', result.suites[0].name)
|
||||
|
||||
class KUnitJsonTest(unittest.TestCase):
|
||||
|
||||
def _json_for(self, log_file):
|
||||
with(open(get_absolute_path(log_file))) as file:
|
||||
test_result = kunit_parser.parse_run_tests(file)
|
||||
json_obj = kunit_json.get_json_result(
|
||||
test_result=test_result,
|
||||
def_config='kunit_defconfig',
|
||||
build_dir=None,
|
||||
json_path='stdout')
|
||||
return json.loads(json_obj)
|
||||
|
||||
def test_failed_test_json(self):
|
||||
result = self._json_for(
|
||||
'test_data/test_is_test_passed-failure.log')
|
||||
self.assertEqual(
|
||||
{'name': 'example_simple_test', 'status': 'FAIL'},
|
||||
result["sub_groups"][1]["test_cases"][0])
|
||||
|
||||
def test_crashed_test_json(self):
|
||||
result = self._json_for(
|
||||
'test_data/test_is_test_passed-crash.log')
|
||||
self.assertEqual(
|
||||
{'name': 'example_simple_test', 'status': 'ERROR'},
|
||||
result["sub_groups"][1]["test_cases"][0])
|
||||
|
||||
def test_no_tests_json(self):
|
||||
result = self._json_for(
|
||||
'test_data/test_is_test_passed-no_tests_run.log')
|
||||
self.assertEqual(0, len(result['sub_groups']))
|
||||
|
||||
class StrContains(str):
|
||||
def __eq__(self, other):
|
||||
return self in other
|
||||
|
|
|
|||
|
|
@ -88,10 +88,10 @@ endif
|
|||
# of the targets gets built.
|
||||
FORCE_TARGETS ?=
|
||||
|
||||
# Clear LDFLAGS and MAKEFLAGS if called from main
|
||||
# Makefile to avoid test build failures when test
|
||||
# Makefile doesn't have explicit build rules.
|
||||
ifeq (1,$(MAKELEVEL))
|
||||
# Clear LDFLAGS and MAKEFLAGS when implicit rules are missing. This provides
|
||||
# implicit rules to sub-test Makefiles which avoids build failures in test
|
||||
# Makefile that don't have explicit build rules.
|
||||
ifeq (,$(LINK.c))
|
||||
override LDFLAGS =
|
||||
override MAKEFLAGS =
|
||||
endif
|
||||
|
|
@ -206,6 +206,7 @@ KSFT_INSTALL_PATH := $(abspath $(KSFT_INSTALL_PATH))
|
|||
# Avoid changing the rest of the logic here and lib.mk.
|
||||
INSTALL_PATH := $(KSFT_INSTALL_PATH)
|
||||
ALL_SCRIPT := $(INSTALL_PATH)/run_kselftest.sh
|
||||
TEST_LIST := $(INSTALL_PATH)/kselftest-list.txt
|
||||
|
||||
install: all
|
||||
ifdef INSTALL_PATH
|
||||
|
|
@ -214,6 +215,8 @@ ifdef INSTALL_PATH
|
|||
install -m 744 kselftest/module.sh $(INSTALL_PATH)/kselftest/
|
||||
install -m 744 kselftest/runner.sh $(INSTALL_PATH)/kselftest/
|
||||
install -m 744 kselftest/prefix.pl $(INSTALL_PATH)/kselftest/
|
||||
install -m 744 run_kselftest.sh $(INSTALL_PATH)/
|
||||
rm -f $(TEST_LIST)
|
||||
@ret=1; \
|
||||
for TARGET in $(TARGETS); do \
|
||||
BUILD_TARGET=$$BUILD/$$TARGET; \
|
||||
|
|
@ -222,33 +225,18 @@ ifdef INSTALL_PATH
|
|||
ret=$$((ret * $$?)); \
|
||||
done; exit $$ret;
|
||||
|
||||
@# Ask all targets to emit their test scripts
|
||||
echo "#!/bin/sh" > $(ALL_SCRIPT)
|
||||
echo "BASE_DIR=\$$(realpath \$$(dirname \$$0))" >> $(ALL_SCRIPT)
|
||||
echo "cd \$$BASE_DIR" >> $(ALL_SCRIPT)
|
||||
echo ". ./kselftest/runner.sh" >> $(ALL_SCRIPT)
|
||||
echo "ROOT=\$$PWD" >> $(ALL_SCRIPT)
|
||||
echo "if [ \"\$$1\" = \"--summary\" ]; then" >> $(ALL_SCRIPT)
|
||||
echo " logfile=\$$BASE_DIR/output.log" >> $(ALL_SCRIPT)
|
||||
echo " cat /dev/null > \$$logfile" >> $(ALL_SCRIPT)
|
||||
echo "fi" >> $(ALL_SCRIPT)
|
||||
|
||||
@# While building run_kselftest.sh skip also non-existent TARGET dirs:
|
||||
@# Ask all targets to emit their test scripts
|
||||
@# While building kselftest-list.text skip also non-existent TARGET dirs:
|
||||
@# they could be the result of a build failure and should NOT be
|
||||
@# included in the generated runlist.
|
||||
for TARGET in $(TARGETS); do \
|
||||
BUILD_TARGET=$$BUILD/$$TARGET; \
|
||||
[ ! -d $(INSTALL_PATH)/$$TARGET ] && echo "Skipping non-existent dir: $$TARGET" && continue; \
|
||||
echo "[ -w /dev/kmsg ] && echo \"kselftest: Running tests in $$TARGET\" >> /dev/kmsg" >> $(ALL_SCRIPT); \
|
||||
echo "cd $$TARGET" >> $(ALL_SCRIPT); \
|
||||
echo -n "run_many" >> $(ALL_SCRIPT); \
|
||||
echo -n "Emit Tests for $$TARGET\n"; \
|
||||
$(MAKE) -s --no-print-directory OUTPUT=$$BUILD_TARGET -C $$TARGET emit_tests >> $(ALL_SCRIPT); \
|
||||
echo "" >> $(ALL_SCRIPT); \
|
||||
echo "cd \$$ROOT" >> $(ALL_SCRIPT); \
|
||||
$(MAKE) -s --no-print-directory OUTPUT=$$BUILD_TARGET COLLECTION=$$TARGET \
|
||||
-C $$TARGET emit_tests >> $(TEST_LIST); \
|
||||
done;
|
||||
|
||||
chmod u+x $(ALL_SCRIPT)
|
||||
else
|
||||
$(error Error: set INSTALL_PATH to use install)
|
||||
endif
|
||||
|
|
|
|||
2
tools/testing/selftests/firmware/.gitignore
vendored
Normal file
2
tools/testing/selftests/firmware/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
fw_namespace
|
||||
|
|
@ -47,9 +47,9 @@ ARCH ?= $(SUBARCH)
|
|||
khdr:
|
||||
ifndef KSFT_KHDR_INSTALL_DONE
|
||||
ifeq (1,$(DEFAULT_INSTALL_HDR_PATH))
|
||||
make --no-builtin-rules ARCH=$(ARCH) -C $(top_srcdir) headers_install
|
||||
$(MAKE) --no-builtin-rules ARCH=$(ARCH) -C $(top_srcdir) headers_install
|
||||
else
|
||||
make --no-builtin-rules INSTALL_HDR_PATH=$$OUTPUT/usr \
|
||||
$(MAKE) --no-builtin-rules INSTALL_HDR_PATH=$$OUTPUT/usr \
|
||||
ARCH=$(ARCH) -C $(top_srcdir) headers_install
|
||||
endif
|
||||
endif
|
||||
|
|
@ -107,9 +107,8 @@ endif
|
|||
emit_tests:
|
||||
for TEST in $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(TEST_PROGS); do \
|
||||
BASENAME_TEST=`basename $$TEST`; \
|
||||
echo " \\"; \
|
||||
echo -n " \"$$BASENAME_TEST\""; \
|
||||
done; \
|
||||
echo "$(COLLECTION):$$BASENAME_TEST"; \
|
||||
done
|
||||
|
||||
# define if isn't already. It is undefined in make O= case.
|
||||
ifeq ($(RM),)
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ function check_result {
|
|||
# help differentiate repeated testing runs. Remove them with a
|
||||
# post-comparison sed filter.
|
||||
|
||||
result=$(dmesg | comm -13 "$SAVED_DMESG" - | \
|
||||
result=$(dmesg | comm --nocheck-order -13 "$SAVED_DMESG" - | \
|
||||
grep -e 'livepatch:' -e 'test_klp' | \
|
||||
grep -v '\(tainting\|taints\) kernel' | \
|
||||
sed 's/^\[[ 0-9.]*\] //')
|
||||
|
|
|
|||
2
tools/testing/selftests/netfilter/.gitignore
vendored
Normal file
2
tools/testing/selftests/netfilter/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
nf-queue
|
||||
1
tools/testing/selftests/ptrace/.gitignore
vendored
1
tools/testing/selftests/ptrace/.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
get_syscall_info
|
||||
peeksiginfo
|
||||
vmaccess
|
||||
|
|
|
|||
93
tools/testing/selftests/run_kselftest.sh
Executable file
93
tools/testing/selftests/run_kselftest.sh
Executable file
|
|
@ -0,0 +1,93 @@
|
|||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Run installed kselftest tests.
|
||||
#
|
||||
BASE_DIR=$(realpath $(dirname $0))
|
||||
cd $BASE_DIR
|
||||
TESTS="$BASE_DIR"/kselftest-list.txt
|
||||
if [ ! -r "$TESTS" ] ; then
|
||||
echo "$0: Could not find list of tests to run ($TESTS)" >&2
|
||||
available=""
|
||||
else
|
||||
available="$(cat "$TESTS")"
|
||||
fi
|
||||
|
||||
. ./kselftest/runner.sh
|
||||
ROOT=$PWD
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
Usage: $0 [OPTIONS]
|
||||
-s | --summary Print summary with detailed log in output.log
|
||||
-t | --test COLLECTION:TEST Run TEST from COLLECTION
|
||||
-c | --collection COLLECTION Run all tests from COLLECTION
|
||||
-l | --list List the available collection:test entries
|
||||
-d | --dry-run Don't actually run any tests
|
||||
-h | --help Show this usage info
|
||||
EOF
|
||||
exit $1
|
||||
}
|
||||
|
||||
COLLECTIONS=""
|
||||
TESTS=""
|
||||
dryrun=""
|
||||
while true; do
|
||||
case "$1" in
|
||||
-s | --summary)
|
||||
logfile="$BASE_DIR"/output.log
|
||||
cat /dev/null > $logfile
|
||||
shift ;;
|
||||
-t | --test)
|
||||
TESTS="$TESTS $2"
|
||||
shift 2 ;;
|
||||
-c | --collection)
|
||||
COLLECTIONS="$COLLECTIONS $2"
|
||||
shift 2 ;;
|
||||
-l | --list)
|
||||
echo "$available"
|
||||
exit 0 ;;
|
||||
-n | --dry-run)
|
||||
dryrun="echo"
|
||||
shift ;;
|
||||
-h | --help)
|
||||
usage 0 ;;
|
||||
"")
|
||||
break ;;
|
||||
*)
|
||||
usage 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Add all selected collections to the explicit test list.
|
||||
if [ -n "$COLLECTIONS" ]; then
|
||||
for collection in $COLLECTIONS ; do
|
||||
found="$(echo "$available" | grep "^$collection:")"
|
||||
if [ -z "$found" ] ; then
|
||||
echo "No such collection '$collection'" >&2
|
||||
exit 1
|
||||
fi
|
||||
TESTS="$TESTS $found"
|
||||
done
|
||||
fi
|
||||
# Replace available test list with explicitly selected tests.
|
||||
if [ -n "$TESTS" ]; then
|
||||
valid=""
|
||||
for test in $TESTS ; do
|
||||
found="$(echo "$available" | grep "^${test}$")"
|
||||
if [ -z "$found" ] ; then
|
||||
echo "No such test '$test'" >&2
|
||||
exit 1
|
||||
fi
|
||||
valid="$valid $found"
|
||||
done
|
||||
available="$(echo "$valid" | sed -e 's/ /\n/g')"
|
||||
fi
|
||||
|
||||
collections=$(echo "$available" | cut -d: -f1 | uniq)
|
||||
for collection in $collections ; do
|
||||
[ -w /dev/kmsg ] && echo "kselftest: Running tests in $collection" >> /dev/kmsg
|
||||
tests=$(echo "$available" | grep "^$collection:" | cut -d: -f2)
|
||||
($dryrun cd "$collection" && $dryrun run_many $tests)
|
||||
done
|
||||
|
|
@ -3,3 +3,4 @@ CONFIG_USERFAULTFD=y
|
|||
CONFIG_TEST_VMALLOC=m
|
||||
CONFIG_DEVICE_PRIVATE=y
|
||||
CONFIG_TEST_HMM=m
|
||||
CONFIG_GUP_BENCHMARK=y
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user