mirror of
https://github.com/torvalds/linux.git
synced 2026-06-08 06:25:52 +02:00
Merge branch 'linux-linaro-lsk-v3.10' into linux-linaro-lsk-v3.10-android
This commit is contained in:
commit
54db03197e
|
|
@ -42,15 +42,48 @@ Description:
|
|||
The invalid_io file is read-only and specifies the number of
|
||||
non-page-size-aligned I/O requests issued to this device.
|
||||
|
||||
What: /sys/block/zram<id>/failed_reads
|
||||
Date: February 2014
|
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
|
||||
Description:
|
||||
The failed_reads file is read-only and specifies the number of
|
||||
failed reads happened on this device.
|
||||
|
||||
What: /sys/block/zram<id>/failed_writes
|
||||
Date: February 2014
|
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
|
||||
Description:
|
||||
The failed_writes file is read-only and specifies the number of
|
||||
failed writes happened on this device.
|
||||
|
||||
What: /sys/block/zram<id>/max_comp_streams
|
||||
Date: February 2014
|
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
|
||||
Description:
|
||||
The max_comp_streams file is read-write and specifies the
|
||||
number of backend's zcomp_strm compression streams (number of
|
||||
concurrent compress operations).
|
||||
|
||||
What: /sys/block/zram<id>/comp_algorithm
|
||||
Date: February 2014
|
||||
Contact: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
|
||||
Description:
|
||||
The comp_algorithm file is read-write and lets to show
|
||||
available and selected compression algorithms, change
|
||||
compression algorithm selection.
|
||||
|
||||
What: /sys/block/zram<id>/notify_free
|
||||
Date: August 2010
|
||||
Contact: Nitin Gupta <ngupta@vflare.org>
|
||||
Description:
|
||||
The notify_free file is read-only and specifies the number of
|
||||
swap slot free notifications received by this device. These
|
||||
notifications are send to a swap block device when a swap slot
|
||||
is freed. This statistic is applicable only when this disk is
|
||||
being used as a swap disk.
|
||||
The notify_free file is read-only. Depending on device usage
|
||||
scenario it may account a) the number of pages freed because
|
||||
of swap slot free notifications or b) the number of pages freed
|
||||
because of REQ_DISCARD requests sent by bio. The former ones
|
||||
are sent to a swap block device when a swap slot is freed, which
|
||||
implies that this disk is being used as a swap disk. The latter
|
||||
ones are sent by filesystem mounted with discard option,
|
||||
whenever some data blocks are getting discarded.
|
||||
|
||||
What: /sys/block/zram<id>/discard
|
||||
Date: August 2010
|
||||
|
|
@ -97,3 +130,22 @@ Description:
|
|||
efficiency can be calculated using compr_data_size and this
|
||||
statistic.
|
||||
Unit: bytes
|
||||
|
||||
What: /sys/block/zram<id>/mem_used_max
|
||||
Date: August 2014
|
||||
Contact: Minchan Kim <minchan@kernel.org>
|
||||
Description:
|
||||
The mem_used_max file is read/write and specifies the amount
|
||||
of maximum memory zram have consumed to store compressed data.
|
||||
For resetting the value, you should write "0". Otherwise,
|
||||
you could see -EINVAL.
|
||||
Unit: bytes
|
||||
|
||||
What: /sys/block/zram<id>/mem_limit
|
||||
Date: August 2014
|
||||
Contact: Minchan Kim <minchan@kernel.org>
|
||||
Description:
|
||||
The mem_limit file is read/write and specifies the maximum
|
||||
amount of memory ZRAM can use to store the compressed data. The
|
||||
limit could be changed in run time and "0" means disable the
|
||||
limit. No limit is the initial state. Unit: bytes
|
||||
|
|
|
|||
129
Documentation/blockdev/zram.txt
Normal file
129
Documentation/blockdev/zram.txt
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
zram: Compressed RAM based block devices
|
||||
----------------------------------------
|
||||
|
||||
* Introduction
|
||||
|
||||
The zram module creates RAM based block devices named /dev/zram<id>
|
||||
(<id> = 0, 1, ...). Pages written to these disks are compressed and stored
|
||||
in memory itself. These disks allow very fast I/O and compression provides
|
||||
good amounts of memory savings. Some of the usecases include /tmp storage,
|
||||
use as swap disks, various caches under /var and maybe many more :)
|
||||
|
||||
Statistics for individual zram devices are exported through sysfs nodes at
|
||||
/sys/block/zram<id>/
|
||||
|
||||
* Usage
|
||||
|
||||
Following shows a typical sequence of steps for using zram.
|
||||
|
||||
1) Load Module:
|
||||
modprobe zram num_devices=4
|
||||
This creates 4 devices: /dev/zram{0,1,2,3}
|
||||
(num_devices parameter is optional. Default: 1)
|
||||
|
||||
2) Set max number of compression streams
|
||||
Compression backend may use up to max_comp_streams compression streams,
|
||||
thus allowing up to max_comp_streams concurrent compression operations.
|
||||
By default, compression backend uses single compression stream.
|
||||
|
||||
Examples:
|
||||
#show max compression streams number
|
||||
cat /sys/block/zram0/max_comp_streams
|
||||
|
||||
#set max compression streams number to 3
|
||||
echo 3 > /sys/block/zram0/max_comp_streams
|
||||
|
||||
Note:
|
||||
In order to enable compression backend's multi stream support max_comp_streams
|
||||
must be initially set to desired concurrency level before ZRAM device
|
||||
initialisation. Once the device initialised as a single stream compression
|
||||
backend (max_comp_streams equals to 1), you will see error if you try to change
|
||||
the value of max_comp_streams because single stream compression backend
|
||||
implemented as a special case by lock overhead issue and does not support
|
||||
dynamic max_comp_streams. Only multi stream backend supports dynamic
|
||||
max_comp_streams adjustment.
|
||||
|
||||
3) Select compression algorithm
|
||||
Using comp_algorithm device attribute one can see available and
|
||||
currently selected (shown in square brackets) compression algortithms,
|
||||
change selected compression algorithm (once the device is initialised
|
||||
there is no way to change compression algorithm).
|
||||
|
||||
Examples:
|
||||
#show supported compression algorithms
|
||||
cat /sys/block/zram0/comp_algorithm
|
||||
lzo [lz4]
|
||||
|
||||
#select lzo compression algorithm
|
||||
echo lzo > /sys/block/zram0/comp_algorithm
|
||||
|
||||
4) Set Disksize
|
||||
Set disk size by writing the value to sysfs node 'disksize'.
|
||||
The value can be either in bytes or you can use mem suffixes.
|
||||
Examples:
|
||||
# Initialize /dev/zram0 with 50MB disksize
|
||||
echo $((50*1024*1024)) > /sys/block/zram0/disksize
|
||||
|
||||
# Using mem suffixes
|
||||
echo 256K > /sys/block/zram0/disksize
|
||||
echo 512M > /sys/block/zram0/disksize
|
||||
echo 1G > /sys/block/zram0/disksize
|
||||
|
||||
Note:
|
||||
There is little point creating a zram of greater than twice the size of memory
|
||||
since we expect a 2:1 compression ratio. Note that zram uses about 0.1% of the
|
||||
size of the disk when not in use so a huge zram is wasteful.
|
||||
|
||||
5) Set memory limit: Optional
|
||||
Set memory limit by writing the value to sysfs node 'mem_limit'.
|
||||
The value can be either in bytes or you can use mem suffixes.
|
||||
In addition, you could change the value in runtime.
|
||||
Examples:
|
||||
# limit /dev/zram0 with 50MB memory
|
||||
echo $((50*1024*1024)) > /sys/block/zram0/mem_limit
|
||||
|
||||
# Using mem suffixes
|
||||
echo 256K > /sys/block/zram0/mem_limit
|
||||
echo 512M > /sys/block/zram0/mem_limit
|
||||
echo 1G > /sys/block/zram0/mem_limit
|
||||
|
||||
# To disable memory limit
|
||||
echo 0 > /sys/block/zram0/mem_limit
|
||||
|
||||
6) Activate:
|
||||
mkswap /dev/zram0
|
||||
swapon /dev/zram0
|
||||
|
||||
mkfs.ext4 /dev/zram1
|
||||
mount /dev/zram1 /tmp
|
||||
|
||||
7) Stats:
|
||||
Per-device statistics are exported as various nodes under
|
||||
/sys/block/zram<id>/
|
||||
disksize
|
||||
num_reads
|
||||
num_writes
|
||||
invalid_io
|
||||
notify_free
|
||||
discard
|
||||
zero_pages
|
||||
orig_data_size
|
||||
compr_data_size
|
||||
mem_used_total
|
||||
mem_used_max
|
||||
|
||||
8) Deactivate:
|
||||
swapoff /dev/zram0
|
||||
umount /dev/zram1
|
||||
|
||||
9) Reset:
|
||||
Write any positive value to 'reset' sysfs node
|
||||
echo 1 > /sys/block/zram0/reset
|
||||
echo 1 > /sys/block/zram1/reset
|
||||
|
||||
This frees all the memory allocated for the given device and
|
||||
resets the disksize to zero. You must set the disksize again
|
||||
before reusing the device.
|
||||
|
||||
Nitin Gupta
|
||||
ngupta@vflare.org
|
||||
2
Makefile
2
Makefile
|
|
@ -1,6 +1,6 @@
|
|||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 74
|
||||
SUBLEVEL = 77
|
||||
EXTRAVERSION =
|
||||
NAME = TOSSUG Baby Fish
|
||||
|
||||
|
|
|
|||
|
|
@ -156,6 +156,8 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -160,6 +160,8 @@ void do_page_fault(struct pt_regs *regs, int write, unsigned long address,
|
|||
/* TBD: switch to pagefault_out_of_memory() */
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
|
|||
the loader. We need to make sure that it is out of the way of the program
|
||||
that it will "exec", and that there is sufficient room for the brk. */
|
||||
|
||||
#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
|
||||
#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
|
||||
|
||||
/* When the program starts, a1 contains a pointer to a function to be
|
||||
registered with atexit, as per the SVR4 ABI. A value of 0 means we
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/gpio.h>
|
||||
|
||||
#define GLENFARCLAS_PMIC_IRQ_BASE IRQ_BOARD_START
|
||||
#define BANFF_PMIC_IRQ_BASE (IRQ_BOARD_START + 64)
|
||||
|
||||
#define PCA935X_GPIO_BASE GPIO_BOARD_START
|
||||
#define CODEC_GPIO_BASE (GPIO_BOARD_START + 8)
|
||||
|
|
|
|||
|
|
@ -558,6 +558,7 @@ static struct wm831x_touch_pdata touch_pdata = {
|
|||
|
||||
static struct wm831x_pdata crag_pmic_pdata = {
|
||||
.wm831x_num = 1,
|
||||
.irq_base = BANFF_PMIC_IRQ_BASE,
|
||||
.gpio_base = BANFF_PMIC_GPIO_BASE,
|
||||
.soft_shutdown = true,
|
||||
|
||||
|
|
|
|||
|
|
@ -142,6 +142,8 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ u64 sched_clock(void)
|
|||
return (tsc * sched_clock_multiplier) >> SCHED_CLOCK_SHIFT;
|
||||
}
|
||||
|
||||
void time_init(void)
|
||||
void __init time_init(void)
|
||||
{
|
||||
u64 tmp = (u64)NSEC_PER_SEC << SCHED_CLOCK_SHIFT;
|
||||
|
||||
|
|
|
|||
|
|
@ -176,6 +176,8 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -168,6 +168,8 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -172,6 +172,8 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
|
|||
*/
|
||||
if (fault & VM_FAULT_OOM) {
|
||||
goto out_of_memory;
|
||||
} else if (fault & VM_FAULT_SIGSEGV) {
|
||||
goto bad_area;
|
||||
} else if (fault & VM_FAULT_SIGBUS) {
|
||||
signal = SIGBUS;
|
||||
goto bad_area;
|
||||
|
|
|
|||
|
|
@ -200,6 +200,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code,
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -153,6 +153,8 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto map_err;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto bus_err;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -141,6 +141,8 @@ int do_page_fault(struct pt_regs *regs, unsigned long address,
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -224,6 +224,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
#ifndef __ASM_SUSPEND_H
|
||||
#define __ASM_SUSPEND_H
|
||||
|
||||
/* References to section boundaries */
|
||||
extern const void __nosave_begin, __nosave_end;
|
||||
|
||||
#endif /* __ASM_SUSPEND_H */
|
||||
|
|
@ -157,6 +157,8 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, unsigned long writ
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
* Author: Hu Hongbing <huhb@lemote.com>
|
||||
* Wu Zhangjin <wuzhangjin@gmail.com>
|
||||
*/
|
||||
#include <asm/suspend.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/fpu.h>
|
||||
#include <asm/dsp.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ LEAF(swsusp_arch_suspend)
|
|||
END(swsusp_arch_suspend)
|
||||
|
||||
LEAF(swsusp_arch_resume)
|
||||
/* Avoid TLB mismatch during and after kernel resume */
|
||||
jal local_flush_tlb_all
|
||||
PTR_L t0, restore_pblist
|
||||
0:
|
||||
PTR_L t1, PBE_ADDRESS(t0) /* source */
|
||||
|
|
@ -43,7 +45,6 @@ LEAF(swsusp_arch_resume)
|
|||
bne t1, t3, 1b
|
||||
PTR_L t0, PBE_NEXT(t0)
|
||||
bnez t0, 0b
|
||||
jal local_flush_tlb_all /* Avoid TLB mismatch after kernel resume */
|
||||
PTR_LA t0, saved_regs
|
||||
PTR_L ra, PT_R31(t0)
|
||||
PTR_L sp, PT_R29(t0)
|
||||
|
|
|
|||
|
|
@ -262,6 +262,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long fault_code,
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -171,6 +171,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long address,
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -220,6 +220,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long code,
|
|||
*/
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto bad_area;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -9,9 +9,7 @@
|
|||
|
||||
#include <linux/mm.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
/* References to section boundaries */
|
||||
extern const void __nosave_begin, __nosave_end;
|
||||
#include <asm/sections.h>
|
||||
|
||||
/*
|
||||
* pfn_is_nosave - check if given pfn is in the 'nosave' section
|
||||
|
|
|
|||
|
|
@ -425,6 +425,8 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
|
|||
*/
|
||||
fault = handle_mm_fault(mm, vma, address, flags);
|
||||
if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) {
|
||||
if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
rc = mm_fault_error(regs, address, fault);
|
||||
if (rc >= MM_FAULT_RETURN)
|
||||
goto bail;
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ static void perf_callchain_user_64(struct perf_callchain_entry *entry,
|
|||
sp = regs->gpr[1];
|
||||
perf_callchain_store(entry, next_ip);
|
||||
|
||||
for (;;) {
|
||||
while (entry->nr < PERF_MAX_STACK_DEPTH) {
|
||||
fp = (unsigned long __user *) sp;
|
||||
if (!valid_user_sp(sp, 1) || read_user_stack_64(fp, &next_sp))
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
|
|||
if (*flt & VM_FAULT_OOM) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unlock;
|
||||
} else if (*flt & VM_FAULT_SIGBUS) {
|
||||
} else if (*flt & (VM_FAULT_SIGBUS | VM_FAULT_SIGSEGV)) {
|
||||
ret = -EFAULT;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ static void spufs_prune_dir(struct dentry *dir)
|
|||
struct dentry *dentry, *tmp;
|
||||
|
||||
mutex_lock(&dir->d_inode->i_mutex);
|
||||
list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) {
|
||||
list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) {
|
||||
spin_lock(&dentry->d_lock);
|
||||
if (!(d_unhashed(dentry)) && dentry->d_inode) {
|
||||
dget_dlock(dentry);
|
||||
|
|
|
|||
|
|
@ -9,12 +9,9 @@
|
|||
#include <linux/pfn.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/ctl_reg.h>
|
||||
|
||||
/*
|
||||
* References to section boundaries
|
||||
*/
|
||||
extern const void __nosave_begin, __nosave_end;
|
||||
#include <asm/ipl.h>
|
||||
|
||||
/*
|
||||
* The restore of the saved pages in an hibernation image will set
|
||||
|
|
@ -138,6 +135,8 @@ int pfn_is_nosave(unsigned long pfn)
|
|||
{
|
||||
unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin));
|
||||
unsigned long nosave_end_pfn = PFN_DOWN(__pa(&__nosave_end));
|
||||
unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1;
|
||||
unsigned long stext_pfn = PFN_DOWN(__pa(&_stext));
|
||||
|
||||
/* Always save lowcore pages (LC protection might be enabled). */
|
||||
if (pfn <= LC_PAGES)
|
||||
|
|
@ -145,6 +144,8 @@ int pfn_is_nosave(unsigned long pfn)
|
|||
if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn)
|
||||
return 1;
|
||||
/* Skip memory holes and read-only pages (NSS, DCSS, ...). */
|
||||
if (pfn >= stext_pfn && pfn <= eshared_pfn)
|
||||
return ipl_info.type == IPL_TYPE_NSS ? 1 : 0;
|
||||
if (tprot(PFN_PHYS(pfn)))
|
||||
return 1;
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -328,6 +328,7 @@ static void handle_stsi_3_2_2(struct kvm_vcpu *vcpu, struct sysinfo_3_2_2 *mem)
|
|||
for (n = mem->count - 1; n > 0 ; n--)
|
||||
memcpy(&mem->vm[n], &mem->vm[n - 1], sizeof(mem->vm[0]));
|
||||
|
||||
memset(&mem->vm[0], 0, sizeof(mem->vm[0]));
|
||||
mem->vm[0].cpus_total = cpus;
|
||||
mem->vm[0].cpus_configured = cpus;
|
||||
mem->vm[0].cpus_standby = 0;
|
||||
|
|
|
|||
|
|
@ -244,6 +244,12 @@ static noinline void do_fault_error(struct pt_regs *regs, int fault)
|
|||
do_no_context(regs);
|
||||
else
|
||||
pagefault_out_of_memory();
|
||||
} else if (fault & VM_FAULT_SIGSEGV) {
|
||||
/* Kernel mode? Handle exceptions or die */
|
||||
if (!user_mode(regs))
|
||||
do_no_context(regs);
|
||||
else
|
||||
do_sigsegv(regs, SEGV_MAPERR);
|
||||
} else if (fault & VM_FAULT_SIGBUS) {
|
||||
/* Kernel mode? Handle exceptions or die */
|
||||
if (!user_mode(regs))
|
||||
|
|
|
|||
|
|
@ -114,6 +114,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include <asm-generic/sections.h>
|
||||
|
||||
extern long __nosave_begin, __nosave_end;
|
||||
extern long __machvec_start, __machvec_end;
|
||||
extern char __uncached_start, __uncached_end;
|
||||
extern char __start_eh_frame[], __stop_eh_frame[];
|
||||
|
|
|
|||
|
|
@ -353,6 +353,8 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code,
|
|||
} else {
|
||||
if (fault & VM_FAULT_SIGBUS)
|
||||
do_sigbus(regs, error_code, address);
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
bad_area(regs, error_code, address);
|
||||
else
|
||||
BUG();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -252,6 +252,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -443,6 +443,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -9,11 +9,9 @@
|
|||
#include <asm/hibernate.h>
|
||||
#include <asm/visasm.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/tlb.h>
|
||||
|
||||
/* References to section boundaries */
|
||||
extern const void __nosave_begin, __nosave_end;
|
||||
|
||||
struct saved_context saved_context;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -446,6 +446,8 @@ static int handle_page_fault(struct pt_regs *regs,
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ int handle_page_fault(unsigned long address, unsigned long ip,
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM) {
|
||||
goto out_of_memory;
|
||||
} else if (fault & VM_FAULT_SIGSEGV) {
|
||||
goto out;
|
||||
} else if (fault & VM_FAULT_SIGBUS) {
|
||||
err = -EACCES;
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -36,8 +36,5 @@ extern int puv3_pm_enter(suspend_state_t state);
|
|||
/* Defined in hibernate_asm.S */
|
||||
extern int restore_image(pgd_t *resume_pg_dir, struct pbe *restore_pblist);
|
||||
|
||||
/* References to section boundaries */
|
||||
extern const void __nosave_begin, __nosave_end;
|
||||
|
||||
extern struct pbe *restore_pblist;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/suspend.h>
|
||||
|
||||
#include "mach/pm.h"
|
||||
|
|
|
|||
|
|
@ -2450,7 +2450,7 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt)
|
|||
* Not recognized on AMD in compat mode (but is recognized in legacy
|
||||
* mode).
|
||||
*/
|
||||
if ((ctxt->mode == X86EMUL_MODE_PROT32) && (efer & EFER_LMA)
|
||||
if ((ctxt->mode != X86EMUL_MODE_PROT64) && (efer & EFER_LMA)
|
||||
&& !vendor_intel(ctxt))
|
||||
return emulate_ud(ctxt);
|
||||
|
||||
|
|
@ -2463,25 +2463,13 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt)
|
|||
setup_syscalls_segments(ctxt, &cs, &ss);
|
||||
|
||||
ops->get_msr(ctxt, MSR_IA32_SYSENTER_CS, &msr_data);
|
||||
switch (ctxt->mode) {
|
||||
case X86EMUL_MODE_PROT32:
|
||||
if ((msr_data & 0xfffc) == 0x0)
|
||||
return emulate_gp(ctxt, 0);
|
||||
break;
|
||||
case X86EMUL_MODE_PROT64:
|
||||
if (msr_data == 0x0)
|
||||
return emulate_gp(ctxt, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((msr_data & 0xfffc) == 0x0)
|
||||
return emulate_gp(ctxt, 0);
|
||||
|
||||
ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF);
|
||||
cs_sel = (u16)msr_data;
|
||||
cs_sel &= ~SELECTOR_RPL_MASK;
|
||||
cs_sel = (u16)msr_data & ~SELECTOR_RPL_MASK;
|
||||
ss_sel = cs_sel + 8;
|
||||
ss_sel &= ~SELECTOR_RPL_MASK;
|
||||
if (ctxt->mode == X86EMUL_MODE_PROT64 || (efer & EFER_LMA)) {
|
||||
if (efer & EFER_LMA) {
|
||||
cs.d = 0;
|
||||
cs.l = 1;
|
||||
}
|
||||
|
|
@ -2490,10 +2478,11 @@ static int em_sysenter(struct x86_emulate_ctxt *ctxt)
|
|||
ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS);
|
||||
|
||||
ops->get_msr(ctxt, MSR_IA32_SYSENTER_EIP, &msr_data);
|
||||
ctxt->_eip = msr_data;
|
||||
ctxt->_eip = (efer & EFER_LMA) ? msr_data : (u32)msr_data;
|
||||
|
||||
ops->get_msr(ctxt, MSR_IA32_SYSENTER_ESP, &msr_data);
|
||||
*reg_write(ctxt, VCPU_REGS_RSP) = msr_data;
|
||||
*reg_write(ctxt, VCPU_REGS_RSP) = (efer & EFER_LMA) ? msr_data :
|
||||
(u32)msr_data;
|
||||
|
||||
return X86EMUL_CONTINUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -812,11 +812,8 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
|
|||
unsigned int fault)
|
||||
{
|
||||
struct task_struct *tsk = current;
|
||||
struct mm_struct *mm = tsk->mm;
|
||||
int code = BUS_ADRERR;
|
||||
|
||||
up_read(&mm->mmap_sem);
|
||||
|
||||
/* Kernel mode? Handle exceptions or die: */
|
||||
if (!(error_code & PF_USER)) {
|
||||
no_context(regs, error_code, address, SIGBUS, BUS_ADRERR);
|
||||
|
|
@ -847,7 +844,6 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code,
|
|||
unsigned long address, unsigned int fault)
|
||||
{
|
||||
if (fatal_signal_pending(current) && !(error_code & PF_USER)) {
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
no_context(regs, error_code, address, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
|
@ -855,14 +851,11 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code,
|
|||
if (fault & VM_FAULT_OOM) {
|
||||
/* Kernel mode? Handle exceptions or die: */
|
||||
if (!(error_code & PF_USER)) {
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
no_context(regs, error_code, address,
|
||||
SIGSEGV, SEGV_MAPERR);
|
||||
return;
|
||||
}
|
||||
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
|
||||
/*
|
||||
* We ran out of memory, call the OOM killer, and return the
|
||||
* userspace (which will retry the fault, or kill us if we got
|
||||
|
|
@ -873,6 +866,8 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code,
|
|||
if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON|
|
||||
VM_FAULT_HWPOISON_LARGE))
|
||||
do_sigbus(regs, error_code, address, fault);
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
bad_area_nosemaphore(regs, error_code, address);
|
||||
else
|
||||
BUG();
|
||||
}
|
||||
|
|
@ -1193,6 +1188,7 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code)
|
|||
return;
|
||||
|
||||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
up_read(&mm->mmap_sem);
|
||||
mm_fault_error(regs, error_code, address, fault);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,13 +13,11 @@
|
|||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/mmzone.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
/* Defined in hibernate_asm_32.S */
|
||||
extern int restore_image(void);
|
||||
|
||||
/* References to section boundaries */
|
||||
extern const void __nosave_begin, __nosave_end;
|
||||
|
||||
/* Pointer to the temporary resume page tables */
|
||||
pgd_t *resume_pg_dir;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,11 +17,9 @@
|
|||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/mtrr.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/suspend.h>
|
||||
|
||||
/* References to section boundaries */
|
||||
extern const void __nosave_begin, __nosave_end;
|
||||
|
||||
/* Defined in hibernate_asm_64.S */
|
||||
extern int restore_image(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -287,6 +287,36 @@ menu "Executable file formats"
|
|||
|
||||
source "fs/Kconfig.binfmt"
|
||||
|
||||
config XTFPGA_LCD
|
||||
bool "Enable XTFPGA LCD driver"
|
||||
depends on XTENSA_PLATFORM_XTFPGA
|
||||
default n
|
||||
help
|
||||
There's a 2x16 LCD on most of XTFPGA boards, kernel may output
|
||||
progress messages there during bootup/shutdown. It may be useful
|
||||
during board bringup.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config XTFPGA_LCD_BASE_ADDR
|
||||
hex "XTFPGA LCD base address"
|
||||
depends on XTFPGA_LCD
|
||||
default "0x0d0c0000"
|
||||
help
|
||||
Base address of the LCD controller inside KIO region.
|
||||
Different boards from XTFPGA family have LCD controller at different
|
||||
addresses. Please consult prototyping user guide for your board for
|
||||
the correct address. Wrong address here may lead to hardware lockup.
|
||||
|
||||
config XTFPGA_LCD_8BIT_ACCESS
|
||||
bool "Use 8-bit access to XTFPGA LCD"
|
||||
depends on XTFPGA_LCD
|
||||
default n
|
||||
help
|
||||
LCD may be connected with 4- or 8-bit interface, 8-bit access may
|
||||
only be used with 8-bit interface. Please consult prototyping user
|
||||
guide for your board for the correct interface width.
|
||||
|
||||
endmenu
|
||||
|
||||
source "net/Kconfig"
|
||||
|
|
|
|||
|
|
@ -715,7 +715,7 @@ __SYSCALL(323, sys_process_vm_writev, 6)
|
|||
__SYSCALL(324, sys_name_to_handle_at, 5)
|
||||
#define __NR_open_by_handle_at 325
|
||||
__SYSCALL(325, sys_open_by_handle_at, 3)
|
||||
#define __NR_sync_file_range 326
|
||||
#define __NR_sync_file_range2 326
|
||||
__SYSCALL(326, sys_sync_file_range2, 6)
|
||||
#define __NR_perf_event_open 327
|
||||
__SYSCALL(327, sys_perf_event_open, 5)
|
||||
|
|
|
|||
|
|
@ -117,6 +117,8 @@ void do_page_fault(struct pt_regs *regs)
|
|||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
else if (fault & VM_FAULT_SIGSEGV)
|
||||
goto bad_area;
|
||||
else if (fault & VM_FAULT_SIGBUS)
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
|
|
|
|||
|
|
@ -6,4 +6,5 @@
|
|||
#
|
||||
# Note 2! The CFLAGS definitions are in the main makefile...
|
||||
|
||||
obj-y = setup.o lcd.o
|
||||
obj-y += setup.o
|
||||
obj-$(CONFIG_XTFPGA_LCD) += lcd.o
|
||||
|
|
|
|||
|
|
@ -44,9 +44,6 @@
|
|||
|
||||
/* UART */
|
||||
#define DUART16552_PADDR (XCHAL_KIO_PADDR + 0x0D050020)
|
||||
/* LCD instruction and data addresses. */
|
||||
#define LCD_INSTR_ADDR ((char *)IOADDR(0x0D040000))
|
||||
#define LCD_DATA_ADDR ((char *)IOADDR(0x0D040004))
|
||||
|
||||
/* Misc. */
|
||||
#define XTFPGA_FPGAREGS_VADDR IOADDR(0x0D020000)
|
||||
|
|
|
|||
|
|
@ -11,10 +11,25 @@
|
|||
#ifndef __XTENSA_XTAVNET_LCD_H
|
||||
#define __XTENSA_XTAVNET_LCD_H
|
||||
|
||||
#ifdef CONFIG_XTFPGA_LCD
|
||||
/* Display string STR at position POS on the LCD. */
|
||||
void lcd_disp_at_pos(char *str, unsigned char pos);
|
||||
|
||||
/* Shift the contents of the LCD display left or right. */
|
||||
void lcd_shiftleft(void);
|
||||
void lcd_shiftright(void);
|
||||
#else
|
||||
static inline void lcd_disp_at_pos(char *str, unsigned char pos)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void lcd_shiftleft(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void lcd_shiftright(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,50 +1,63 @@
|
|||
/*
|
||||
* Driver for the LCD display on the Tensilica LX60 Board.
|
||||
* Driver for the LCD display on the Tensilica XTFPGA board family.
|
||||
* http://www.mytechcorp.com/cfdata/productFile/File1/MOC-16216B-B-A0A04.pdf
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
* Copyright (C) 2001, 2006 Tensilica Inc.
|
||||
* Copyright (C) 2015 Cadence Design Systems Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* FIXME: this code is from the examples from the LX60 user guide.
|
||||
*
|
||||
* The lcd_pause function does busy waiting, which is probably not
|
||||
* great. Maybe the code could be changed to use kernel timers, or
|
||||
* change the hardware to not need to wait.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <platform/hardware.h>
|
||||
#include <platform/lcd.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#define LCD_PAUSE_ITERATIONS 4000
|
||||
/* LCD instruction and data addresses. */
|
||||
#define LCD_INSTR_ADDR ((char *)IOADDR(CONFIG_XTFPGA_LCD_BASE_ADDR))
|
||||
#define LCD_DATA_ADDR (LCD_INSTR_ADDR + 4)
|
||||
|
||||
#define LCD_CLEAR 0x1
|
||||
#define LCD_DISPLAY_ON 0xc
|
||||
|
||||
/* 8bit and 2 lines display */
|
||||
#define LCD_DISPLAY_MODE8BIT 0x38
|
||||
#define LCD_DISPLAY_MODE4BIT 0x28
|
||||
#define LCD_DISPLAY_POS 0x80
|
||||
#define LCD_SHIFT_LEFT 0x18
|
||||
#define LCD_SHIFT_RIGHT 0x1c
|
||||
|
||||
static void lcd_put_byte(u8 *addr, u8 data)
|
||||
{
|
||||
#ifdef CONFIG_XTFPGA_LCD_8BIT_ACCESS
|
||||
ACCESS_ONCE(*addr) = data;
|
||||
#else
|
||||
ACCESS_ONCE(*addr) = data & 0xf0;
|
||||
ACCESS_ONCE(*addr) = (data << 4) & 0xf0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int __init lcd_init(void)
|
||||
{
|
||||
*LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
|
||||
ACCESS_ONCE(*LCD_INSTR_ADDR) = LCD_DISPLAY_MODE8BIT;
|
||||
mdelay(5);
|
||||
*LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
|
||||
ACCESS_ONCE(*LCD_INSTR_ADDR) = LCD_DISPLAY_MODE8BIT;
|
||||
udelay(200);
|
||||
*LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
|
||||
ACCESS_ONCE(*LCD_INSTR_ADDR) = LCD_DISPLAY_MODE8BIT;
|
||||
udelay(50);
|
||||
*LCD_INSTR_ADDR = LCD_DISPLAY_ON;
|
||||
#ifndef CONFIG_XTFPGA_LCD_8BIT_ACCESS
|
||||
ACCESS_ONCE(*LCD_INSTR_ADDR) = LCD_DISPLAY_MODE4BIT;
|
||||
udelay(50);
|
||||
*LCD_INSTR_ADDR = LCD_CLEAR;
|
||||
lcd_put_byte(LCD_INSTR_ADDR, LCD_DISPLAY_MODE4BIT);
|
||||
udelay(50);
|
||||
#endif
|
||||
lcd_put_byte(LCD_INSTR_ADDR, LCD_DISPLAY_ON);
|
||||
udelay(50);
|
||||
lcd_put_byte(LCD_INSTR_ADDR, LCD_CLEAR);
|
||||
mdelay(10);
|
||||
lcd_disp_at_pos("XTENSA LINUX", 0);
|
||||
return 0;
|
||||
|
|
@ -52,10 +65,10 @@ static int __init lcd_init(void)
|
|||
|
||||
void lcd_disp_at_pos(char *str, unsigned char pos)
|
||||
{
|
||||
*LCD_INSTR_ADDR = LCD_DISPLAY_POS | pos;
|
||||
lcd_put_byte(LCD_INSTR_ADDR, LCD_DISPLAY_POS | pos);
|
||||
udelay(100);
|
||||
while (*str != 0) {
|
||||
*LCD_DATA_ADDR = *str;
|
||||
lcd_put_byte(LCD_DATA_ADDR, *str);
|
||||
udelay(200);
|
||||
str++;
|
||||
}
|
||||
|
|
@ -63,13 +76,13 @@ void lcd_disp_at_pos(char *str, unsigned char pos)
|
|||
|
||||
void lcd_shiftleft(void)
|
||||
{
|
||||
*LCD_INSTR_ADDR = LCD_SHIFT_LEFT;
|
||||
lcd_put_byte(LCD_INSTR_ADDR, LCD_SHIFT_LEFT);
|
||||
udelay(50);
|
||||
}
|
||||
|
||||
void lcd_shiftright(void)
|
||||
{
|
||||
*LCD_INSTR_ADDR = LCD_SHIFT_RIGHT;
|
||||
lcd_put_byte(LCD_INSTR_ADDR, LCD_SHIFT_RIGHT);
|
||||
udelay(50);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -978,7 +978,7 @@ static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
|
|||
return -EINVAL;
|
||||
|
||||
drv->safe_state_index = -1;
|
||||
for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
|
||||
for (i = CPUIDLE_DRIVER_STATE_START; i < CPUIDLE_STATE_MAX; i++) {
|
||||
drv->states[i].name[0] = '\0';
|
||||
drv->states[i].desc[0] = '\0';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ source "drivers/block/paride/Kconfig"
|
|||
|
||||
source "drivers/block/mtip32xx/Kconfig"
|
||||
|
||||
source "drivers/block/zram/Kconfig"
|
||||
|
||||
config BLK_CPQ_DA
|
||||
tristate "Compaq SMART2 support"
|
||||
depends on PCI && VIRT_TO_BUS
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ obj-$(CONFIG_BLK_DEV_RBD) += rbd.o
|
|||
obj-$(CONFIG_BLK_DEV_PCIESSD_MTIP32XX) += mtip32xx/
|
||||
|
||||
obj-$(CONFIG_BLK_DEV_RSXX) += rsxx/
|
||||
obj-$(CONFIG_ZRAM) += zram/
|
||||
|
||||
nvme-y := nvme-core.o nvme-scsi.o
|
||||
swim_mod-y := swim.o swim_asm.o
|
||||
|
|
|
|||
|
|
@ -815,10 +815,6 @@ static int __init nbd_init(void)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
nbd_dev = kcalloc(nbds_max, sizeof(*nbd_dev), GFP_KERNEL);
|
||||
if (!nbd_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
part_shift = 0;
|
||||
if (max_part > 0) {
|
||||
part_shift = fls(max_part);
|
||||
|
|
@ -840,6 +836,10 @@ static int __init nbd_init(void)
|
|||
if (nbds_max > 1UL << (MINORBITS - part_shift))
|
||||
return -EINVAL;
|
||||
|
||||
nbd_dev = kcalloc(nbds_max, sizeof(*nbd_dev), GFP_KERNEL);
|
||||
if (!nbd_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < nbds_max; i++) {
|
||||
struct gendisk *disk = alloc_disk(1 << part_shift);
|
||||
if (!disk)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,16 @@ config ZRAM
|
|||
disks and maybe many more.
|
||||
|
||||
See zram.txt for more information.
|
||||
Project home: <https://compcache.googlecode.com/>
|
||||
|
||||
config ZRAM_LZ4_COMPRESS
|
||||
bool "Enable LZ4 algorithm support"
|
||||
depends on ZRAM
|
||||
select LZ4_COMPRESS
|
||||
select LZ4_DECOMPRESS
|
||||
default n
|
||||
help
|
||||
This option enables LZ4 compression algorithm support. Compression
|
||||
algorithm can be changed using `comp_algorithm' device attribute.
|
||||
|
||||
config ZRAM_DEBUG
|
||||
bool "Compressed RAM block device debug support"
|
||||
5
drivers/block/zram/Makefile
Normal file
5
drivers/block/zram/Makefile
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
zram-y := zcomp_lzo.o zcomp.o zram_drv.o
|
||||
|
||||
zram-$(CONFIG_ZRAM_LZ4_COMPRESS) += zcomp_lz4.o
|
||||
|
||||
obj-$(CONFIG_ZRAM) += zram.o
|
||||
353
drivers/block/zram/zcomp.c
Normal file
353
drivers/block/zram/zcomp.c
Normal file
|
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Sergey Senozhatsky.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include "zcomp.h"
|
||||
#include "zcomp_lzo.h"
|
||||
#ifdef CONFIG_ZRAM_LZ4_COMPRESS
|
||||
#include "zcomp_lz4.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* single zcomp_strm backend
|
||||
*/
|
||||
struct zcomp_strm_single {
|
||||
struct mutex strm_lock;
|
||||
struct zcomp_strm *zstrm;
|
||||
};
|
||||
|
||||
/*
|
||||
* multi zcomp_strm backend
|
||||
*/
|
||||
struct zcomp_strm_multi {
|
||||
/* protect strm list */
|
||||
spinlock_t strm_lock;
|
||||
/* max possible number of zstrm streams */
|
||||
int max_strm;
|
||||
/* number of available zstrm streams */
|
||||
int avail_strm;
|
||||
/* list of available strms */
|
||||
struct list_head idle_strm;
|
||||
wait_queue_head_t strm_wait;
|
||||
};
|
||||
|
||||
static struct zcomp_backend *backends[] = {
|
||||
&zcomp_lzo,
|
||||
#ifdef CONFIG_ZRAM_LZ4_COMPRESS
|
||||
&zcomp_lz4,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct zcomp_backend *find_backend(const char *compress)
|
||||
{
|
||||
int i = 0;
|
||||
while (backends[i]) {
|
||||
if (sysfs_streq(compress, backends[i]->name))
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
return backends[i];
|
||||
}
|
||||
|
||||
static void zcomp_strm_free(struct zcomp *comp, struct zcomp_strm *zstrm)
|
||||
{
|
||||
if (zstrm->private)
|
||||
comp->backend->destroy(zstrm->private);
|
||||
free_pages((unsigned long)zstrm->buffer, 1);
|
||||
kfree(zstrm);
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate new zcomp_strm structure with ->private initialized by
|
||||
* backend, return NULL on error
|
||||
*/
|
||||
static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp)
|
||||
{
|
||||
struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_KERNEL);
|
||||
if (!zstrm)
|
||||
return NULL;
|
||||
|
||||
zstrm->private = comp->backend->create();
|
||||
/*
|
||||
* allocate 2 pages. 1 for compressed data, plus 1 extra for the
|
||||
* case when compressed size is larger than the original one
|
||||
*/
|
||||
zstrm->buffer = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
|
||||
if (!zstrm->private || !zstrm->buffer) {
|
||||
zcomp_strm_free(comp, zstrm);
|
||||
zstrm = NULL;
|
||||
}
|
||||
return zstrm;
|
||||
}
|
||||
|
||||
/*
|
||||
* get idle zcomp_strm or wait until other process release
|
||||
* (zcomp_strm_release()) one for us
|
||||
*/
|
||||
static struct zcomp_strm *zcomp_strm_multi_find(struct zcomp *comp)
|
||||
{
|
||||
struct zcomp_strm_multi *zs = comp->stream;
|
||||
struct zcomp_strm *zstrm;
|
||||
|
||||
while (1) {
|
||||
spin_lock(&zs->strm_lock);
|
||||
if (!list_empty(&zs->idle_strm)) {
|
||||
zstrm = list_entry(zs->idle_strm.next,
|
||||
struct zcomp_strm, list);
|
||||
list_del(&zstrm->list);
|
||||
spin_unlock(&zs->strm_lock);
|
||||
return zstrm;
|
||||
}
|
||||
/* zstrm streams limit reached, wait for idle stream */
|
||||
if (zs->avail_strm >= zs->max_strm) {
|
||||
spin_unlock(&zs->strm_lock);
|
||||
wait_event(zs->strm_wait, !list_empty(&zs->idle_strm));
|
||||
continue;
|
||||
}
|
||||
/* allocate new zstrm stream */
|
||||
zs->avail_strm++;
|
||||
spin_unlock(&zs->strm_lock);
|
||||
|
||||
zstrm = zcomp_strm_alloc(comp);
|
||||
if (!zstrm) {
|
||||
spin_lock(&zs->strm_lock);
|
||||
zs->avail_strm--;
|
||||
spin_unlock(&zs->strm_lock);
|
||||
wait_event(zs->strm_wait, !list_empty(&zs->idle_strm));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return zstrm;
|
||||
}
|
||||
|
||||
/* add stream back to idle list and wake up waiter or free the stream */
|
||||
static void zcomp_strm_multi_release(struct zcomp *comp, struct zcomp_strm *zstrm)
|
||||
{
|
||||
struct zcomp_strm_multi *zs = comp->stream;
|
||||
|
||||
spin_lock(&zs->strm_lock);
|
||||
if (zs->avail_strm <= zs->max_strm) {
|
||||
list_add(&zstrm->list, &zs->idle_strm);
|
||||
spin_unlock(&zs->strm_lock);
|
||||
wake_up(&zs->strm_wait);
|
||||
return;
|
||||
}
|
||||
|
||||
zs->avail_strm--;
|
||||
spin_unlock(&zs->strm_lock);
|
||||
zcomp_strm_free(comp, zstrm);
|
||||
}
|
||||
|
||||
/* change max_strm limit */
|
||||
static bool zcomp_strm_multi_set_max_streams(struct zcomp *comp, int num_strm)
|
||||
{
|
||||
struct zcomp_strm_multi *zs = comp->stream;
|
||||
struct zcomp_strm *zstrm;
|
||||
|
||||
spin_lock(&zs->strm_lock);
|
||||
zs->max_strm = num_strm;
|
||||
/*
|
||||
* if user has lowered the limit and there are idle streams,
|
||||
* immediately free as much streams (and memory) as we can.
|
||||
*/
|
||||
while (zs->avail_strm > num_strm && !list_empty(&zs->idle_strm)) {
|
||||
zstrm = list_entry(zs->idle_strm.next,
|
||||
struct zcomp_strm, list);
|
||||
list_del(&zstrm->list);
|
||||
zcomp_strm_free(comp, zstrm);
|
||||
zs->avail_strm--;
|
||||
}
|
||||
spin_unlock(&zs->strm_lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void zcomp_strm_multi_destroy(struct zcomp *comp)
|
||||
{
|
||||
struct zcomp_strm_multi *zs = comp->stream;
|
||||
struct zcomp_strm *zstrm;
|
||||
|
||||
while (!list_empty(&zs->idle_strm)) {
|
||||
zstrm = list_entry(zs->idle_strm.next,
|
||||
struct zcomp_strm, list);
|
||||
list_del(&zstrm->list);
|
||||
zcomp_strm_free(comp, zstrm);
|
||||
}
|
||||
kfree(zs);
|
||||
}
|
||||
|
||||
static int zcomp_strm_multi_create(struct zcomp *comp, int max_strm)
|
||||
{
|
||||
struct zcomp_strm *zstrm;
|
||||
struct zcomp_strm_multi *zs;
|
||||
|
||||
comp->destroy = zcomp_strm_multi_destroy;
|
||||
comp->strm_find = zcomp_strm_multi_find;
|
||||
comp->strm_release = zcomp_strm_multi_release;
|
||||
comp->set_max_streams = zcomp_strm_multi_set_max_streams;
|
||||
zs = kmalloc(sizeof(struct zcomp_strm_multi), GFP_KERNEL);
|
||||
if (!zs)
|
||||
return -ENOMEM;
|
||||
|
||||
comp->stream = zs;
|
||||
spin_lock_init(&zs->strm_lock);
|
||||
INIT_LIST_HEAD(&zs->idle_strm);
|
||||
init_waitqueue_head(&zs->strm_wait);
|
||||
zs->max_strm = max_strm;
|
||||
zs->avail_strm = 1;
|
||||
|
||||
zstrm = zcomp_strm_alloc(comp);
|
||||
if (!zstrm) {
|
||||
kfree(zs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
list_add(&zstrm->list, &zs->idle_strm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct zcomp_strm *zcomp_strm_single_find(struct zcomp *comp)
|
||||
{
|
||||
struct zcomp_strm_single *zs = comp->stream;
|
||||
mutex_lock(&zs->strm_lock);
|
||||
return zs->zstrm;
|
||||
}
|
||||
|
||||
static void zcomp_strm_single_release(struct zcomp *comp,
|
||||
struct zcomp_strm *zstrm)
|
||||
{
|
||||
struct zcomp_strm_single *zs = comp->stream;
|
||||
mutex_unlock(&zs->strm_lock);
|
||||
}
|
||||
|
||||
static bool zcomp_strm_single_set_max_streams(struct zcomp *comp, int num_strm)
|
||||
{
|
||||
/* zcomp_strm_single support only max_comp_streams == 1 */
|
||||
return false;
|
||||
}
|
||||
|
||||
static void zcomp_strm_single_destroy(struct zcomp *comp)
|
||||
{
|
||||
struct zcomp_strm_single *zs = comp->stream;
|
||||
zcomp_strm_free(comp, zs->zstrm);
|
||||
kfree(zs);
|
||||
}
|
||||
|
||||
static int zcomp_strm_single_create(struct zcomp *comp)
|
||||
{
|
||||
struct zcomp_strm_single *zs;
|
||||
|
||||
comp->destroy = zcomp_strm_single_destroy;
|
||||
comp->strm_find = zcomp_strm_single_find;
|
||||
comp->strm_release = zcomp_strm_single_release;
|
||||
comp->set_max_streams = zcomp_strm_single_set_max_streams;
|
||||
zs = kmalloc(sizeof(struct zcomp_strm_single), GFP_KERNEL);
|
||||
if (!zs)
|
||||
return -ENOMEM;
|
||||
|
||||
comp->stream = zs;
|
||||
mutex_init(&zs->strm_lock);
|
||||
zs->zstrm = zcomp_strm_alloc(comp);
|
||||
if (!zs->zstrm) {
|
||||
kfree(zs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* show available compressors */
|
||||
ssize_t zcomp_available_show(const char *comp, char *buf)
|
||||
{
|
||||
ssize_t sz = 0;
|
||||
int i = 0;
|
||||
|
||||
while (backends[i]) {
|
||||
if (sysfs_streq(comp, backends[i]->name))
|
||||
sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
|
||||
"[%s] ", backends[i]->name);
|
||||
else
|
||||
sz += scnprintf(buf + sz, PAGE_SIZE - sz - 2,
|
||||
"%s ", backends[i]->name);
|
||||
i++;
|
||||
}
|
||||
sz += scnprintf(buf + sz, PAGE_SIZE - sz, "\n");
|
||||
return sz;
|
||||
}
|
||||
|
||||
bool zcomp_set_max_streams(struct zcomp *comp, int num_strm)
|
||||
{
|
||||
return comp->set_max_streams(comp, num_strm);
|
||||
}
|
||||
|
||||
struct zcomp_strm *zcomp_strm_find(struct zcomp *comp)
|
||||
{
|
||||
return comp->strm_find(comp);
|
||||
}
|
||||
|
||||
void zcomp_strm_release(struct zcomp *comp, struct zcomp_strm *zstrm)
|
||||
{
|
||||
comp->strm_release(comp, zstrm);
|
||||
}
|
||||
|
||||
int zcomp_compress(struct zcomp *comp, struct zcomp_strm *zstrm,
|
||||
const unsigned char *src, size_t *dst_len)
|
||||
{
|
||||
return comp->backend->compress(src, zstrm->buffer, dst_len,
|
||||
zstrm->private);
|
||||
}
|
||||
|
||||
int zcomp_decompress(struct zcomp *comp, const unsigned char *src,
|
||||
size_t src_len, unsigned char *dst)
|
||||
{
|
||||
return comp->backend->decompress(src, src_len, dst);
|
||||
}
|
||||
|
||||
void zcomp_destroy(struct zcomp *comp)
|
||||
{
|
||||
comp->destroy(comp);
|
||||
kfree(comp);
|
||||
}
|
||||
|
||||
/*
|
||||
* search available compressors for requested algorithm.
|
||||
* allocate new zcomp and initialize it. return compressing
|
||||
* backend pointer or ERR_PTR if things went bad. ERR_PTR(-EINVAL)
|
||||
* if requested algorithm is not supported, ERR_PTR(-ENOMEM) in
|
||||
* case of allocation error.
|
||||
*/
|
||||
struct zcomp *zcomp_create(const char *compress, int max_strm)
|
||||
{
|
||||
struct zcomp *comp;
|
||||
struct zcomp_backend *backend;
|
||||
|
||||
backend = find_backend(compress);
|
||||
if (!backend)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
comp = kzalloc(sizeof(struct zcomp), GFP_KERNEL);
|
||||
if (!comp)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
comp->backend = backend;
|
||||
if (max_strm > 1)
|
||||
zcomp_strm_multi_create(comp, max_strm);
|
||||
else
|
||||
zcomp_strm_single_create(comp);
|
||||
if (!comp->stream) {
|
||||
kfree(comp);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
return comp;
|
||||
}
|
||||
68
drivers/block/zram/zcomp.h
Normal file
68
drivers/block/zram/zcomp.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Sergey Senozhatsky.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _ZCOMP_H_
|
||||
#define _ZCOMP_H_
|
||||
|
||||
#include <linux/mutex.h>
|
||||
|
||||
struct zcomp_strm {
|
||||
/* compression/decompression buffer */
|
||||
void *buffer;
|
||||
/*
|
||||
* The private data of the compression stream, only compression
|
||||
* stream backend can touch this (e.g. compression algorithm
|
||||
* working memory)
|
||||
*/
|
||||
void *private;
|
||||
/* used in multi stream backend, protected by backend strm_lock */
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
/* static compression backend */
|
||||
struct zcomp_backend {
|
||||
int (*compress)(const unsigned char *src, unsigned char *dst,
|
||||
size_t *dst_len, void *private);
|
||||
|
||||
int (*decompress)(const unsigned char *src, size_t src_len,
|
||||
unsigned char *dst);
|
||||
|
||||
void *(*create)(void);
|
||||
void (*destroy)(void *private);
|
||||
|
||||
const char *name;
|
||||
};
|
||||
|
||||
/* dynamic per-device compression frontend */
|
||||
struct zcomp {
|
||||
void *stream;
|
||||
struct zcomp_backend *backend;
|
||||
|
||||
struct zcomp_strm *(*strm_find)(struct zcomp *comp);
|
||||
void (*strm_release)(struct zcomp *comp, struct zcomp_strm *zstrm);
|
||||
bool (*set_max_streams)(struct zcomp *comp, int num_strm);
|
||||
void (*destroy)(struct zcomp *comp);
|
||||
};
|
||||
|
||||
ssize_t zcomp_available_show(const char *comp, char *buf);
|
||||
|
||||
struct zcomp *zcomp_create(const char *comp, int max_strm);
|
||||
void zcomp_destroy(struct zcomp *comp);
|
||||
|
||||
struct zcomp_strm *zcomp_strm_find(struct zcomp *comp);
|
||||
void zcomp_strm_release(struct zcomp *comp, struct zcomp_strm *zstrm);
|
||||
|
||||
int zcomp_compress(struct zcomp *comp, struct zcomp_strm *zstrm,
|
||||
const unsigned char *src, size_t *dst_len);
|
||||
|
||||
int zcomp_decompress(struct zcomp *comp, const unsigned char *src,
|
||||
size_t src_len, unsigned char *dst);
|
||||
|
||||
bool zcomp_set_max_streams(struct zcomp *comp, int num_strm);
|
||||
#endif /* _ZCOMP_H_ */
|
||||
47
drivers/block/zram/zcomp_lz4.c
Normal file
47
drivers/block/zram/zcomp_lz4.c
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Sergey Senozhatsky.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/lz4.h>
|
||||
|
||||
#include "zcomp_lz4.h"
|
||||
|
||||
static void *zcomp_lz4_create(void)
|
||||
{
|
||||
return kzalloc(LZ4_MEM_COMPRESS, GFP_KERNEL);
|
||||
}
|
||||
|
||||
static void zcomp_lz4_destroy(void *private)
|
||||
{
|
||||
kfree(private);
|
||||
}
|
||||
|
||||
static int zcomp_lz4_compress(const unsigned char *src, unsigned char *dst,
|
||||
size_t *dst_len, void *private)
|
||||
{
|
||||
/* return : Success if return 0 */
|
||||
return lz4_compress(src, PAGE_SIZE, dst, dst_len, private);
|
||||
}
|
||||
|
||||
static int zcomp_lz4_decompress(const unsigned char *src, size_t src_len,
|
||||
unsigned char *dst)
|
||||
{
|
||||
size_t dst_len = PAGE_SIZE;
|
||||
/* return : Success if return 0 */
|
||||
return lz4_decompress_unknownoutputsize(src, src_len, dst, &dst_len);
|
||||
}
|
||||
|
||||
struct zcomp_backend zcomp_lz4 = {
|
||||
.compress = zcomp_lz4_compress,
|
||||
.decompress = zcomp_lz4_decompress,
|
||||
.create = zcomp_lz4_create,
|
||||
.destroy = zcomp_lz4_destroy,
|
||||
.name = "lz4",
|
||||
};
|
||||
17
drivers/block/zram/zcomp_lz4.h
Normal file
17
drivers/block/zram/zcomp_lz4.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Sergey Senozhatsky.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _ZCOMP_LZ4_H_
|
||||
#define _ZCOMP_LZ4_H_
|
||||
|
||||
#include "zcomp.h"
|
||||
|
||||
extern struct zcomp_backend zcomp_lz4;
|
||||
|
||||
#endif /* _ZCOMP_LZ4_H_ */
|
||||
47
drivers/block/zram/zcomp_lzo.c
Normal file
47
drivers/block/zram/zcomp_lzo.c
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Sergey Senozhatsky.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/lzo.h>
|
||||
|
||||
#include "zcomp_lzo.h"
|
||||
|
||||
static void *lzo_create(void)
|
||||
{
|
||||
return kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
|
||||
}
|
||||
|
||||
static void lzo_destroy(void *private)
|
||||
{
|
||||
kfree(private);
|
||||
}
|
||||
|
||||
static int lzo_compress(const unsigned char *src, unsigned char *dst,
|
||||
size_t *dst_len, void *private)
|
||||
{
|
||||
int ret = lzo1x_1_compress(src, PAGE_SIZE, dst, dst_len, private);
|
||||
return ret == LZO_E_OK ? 0 : ret;
|
||||
}
|
||||
|
||||
static int lzo_decompress(const unsigned char *src, size_t src_len,
|
||||
unsigned char *dst)
|
||||
{
|
||||
size_t dst_len = PAGE_SIZE;
|
||||
int ret = lzo1x_decompress_safe(src, src_len, dst, &dst_len);
|
||||
return ret == LZO_E_OK ? 0 : ret;
|
||||
}
|
||||
|
||||
struct zcomp_backend zcomp_lzo = {
|
||||
.compress = lzo_compress,
|
||||
.decompress = lzo_decompress,
|
||||
.create = lzo_create,
|
||||
.destroy = lzo_destroy,
|
||||
.name = "lzo",
|
||||
};
|
||||
17
drivers/block/zram/zcomp_lzo.h
Normal file
17
drivers/block/zram/zcomp_lzo.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Sergey Senozhatsky.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _ZCOMP_LZO_H_
|
||||
#define _ZCOMP_LZO_H_
|
||||
|
||||
#include "zcomp.h"
|
||||
|
||||
extern struct zcomp_backend zcomp_lzo;
|
||||
|
||||
#endif /* _ZCOMP_LZO_H_ */
|
||||
1162
drivers/block/zram/zram_drv.c
Normal file
1162
drivers/block/zram/zram_drv.c
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -2,6 +2,7 @@
|
|||
* Compressed RAM block device
|
||||
*
|
||||
* Copyright (C) 2008, 2009, 2010 Nitin Gupta
|
||||
* 2012, 2013 Minchan Kim
|
||||
*
|
||||
* This code is released using a dual license strategy: BSD/GPL
|
||||
* You can choose the licence that better fits your requirements.
|
||||
|
|
@ -9,16 +10,15 @@
|
|||
* Released under the terms of 3-clause BSD License
|
||||
* Released under the terms of GNU General Public License Version 2.0
|
||||
*
|
||||
* Project home: http://compcache.googlecode.com
|
||||
*/
|
||||
|
||||
#ifndef _ZRAM_DRV_H_
|
||||
#define _ZRAM_DRV_H_
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/zsmalloc.h>
|
||||
|
||||
#include "../zsmalloc/zsmalloc.h"
|
||||
#include "zcomp.h"
|
||||
|
||||
/*
|
||||
* Some arbitrary value. This is just to catch
|
||||
|
|
@ -43,7 +43,6 @@ static const size_t max_zpage_size = PAGE_SIZE / 4 * 3;
|
|||
/*-- End of configurable params */
|
||||
|
||||
#define SECTOR_SHIFT 9
|
||||
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
|
||||
#define SECTORS_PER_PAGE_SHIFT (PAGE_SHIFT - SECTOR_SHIFT)
|
||||
#define SECTORS_PER_PAGE (1 << SECTORS_PER_PAGE_SHIFT)
|
||||
#define ZRAM_LOGICAL_BLOCK_SHIFT 12
|
||||
|
|
@ -51,10 +50,24 @@ static const size_t max_zpage_size = PAGE_SIZE / 4 * 3;
|
|||
#define ZRAM_SECTOR_PER_LOGICAL_BLOCK \
|
||||
(1 << (ZRAM_LOGICAL_BLOCK_SHIFT - SECTOR_SHIFT))
|
||||
|
||||
/* Flags for zram pages (table[page_no].flags) */
|
||||
|
||||
/*
|
||||
* The lower ZRAM_FLAG_SHIFT bits of table.value is for
|
||||
* object size (excluding header), the higher bits is for
|
||||
* zram_pageflags.
|
||||
*
|
||||
* zram is mainly used for memory efficiency so we want to keep memory
|
||||
* footprint small so we can squeeze size and flags into a field.
|
||||
* The lower ZRAM_FLAG_SHIFT bits is for object size (excluding header),
|
||||
* the higher bits is for zram_pageflags.
|
||||
*/
|
||||
#define ZRAM_FLAG_SHIFT 24
|
||||
|
||||
/* Flags for zram pages (table[page_no].value) */
|
||||
enum zram_pageflags {
|
||||
/* Page consists entirely of zeros */
|
||||
ZRAM_ZERO,
|
||||
ZRAM_ZERO = ZRAM_FLAG_SHIFT,
|
||||
ZRAM_ACCESS, /* page is now accessed */
|
||||
|
||||
__NR_ZRAM_PAGEFLAGS,
|
||||
};
|
||||
|
|
@ -62,43 +75,35 @@ enum zram_pageflags {
|
|||
/*-- Data structures */
|
||||
|
||||
/* Allocated for each disk page */
|
||||
struct table {
|
||||
struct zram_table_entry {
|
||||
unsigned long handle;
|
||||
u16 size; /* object size (excluding header) */
|
||||
u8 count; /* object ref count (not yet used) */
|
||||
u8 flags;
|
||||
} __aligned(4);
|
||||
unsigned long value;
|
||||
};
|
||||
|
||||
struct zram_stats {
|
||||
u64 compr_size; /* compressed size of pages stored */
|
||||
u64 num_reads; /* failed + successful */
|
||||
u64 num_writes; /* --do-- */
|
||||
u64 failed_reads; /* should NEVER! happen */
|
||||
u64 failed_writes; /* can happen when memory is too low */
|
||||
u64 invalid_io; /* non-page-aligned I/O requests */
|
||||
u64 notify_free; /* no. of swap slot free notifications */
|
||||
u32 pages_zero; /* no. of zero filled pages */
|
||||
u32 pages_stored; /* no. of pages currently stored */
|
||||
u32 good_compress; /* % of pages with compression ratio<=50% */
|
||||
u32 bad_compress; /* % of pages with compression ratio>=75% */
|
||||
atomic64_t compr_data_size; /* compressed size of pages stored */
|
||||
atomic64_t num_reads; /* failed + successful */
|
||||
atomic64_t num_writes; /* --do-- */
|
||||
atomic64_t failed_reads; /* can happen when memory is too low */
|
||||
atomic64_t failed_writes; /* can happen when memory is too low */
|
||||
atomic64_t invalid_io; /* non-page-aligned I/O requests */
|
||||
atomic64_t notify_free; /* no. of swap slot free notifications */
|
||||
atomic64_t zero_pages; /* no. of zero filled pages */
|
||||
atomic64_t pages_stored; /* no. of pages currently stored */
|
||||
atomic_long_t max_used_pages; /* no. of maximum pages stored */
|
||||
};
|
||||
|
||||
struct zram_meta {
|
||||
void *compress_workmem;
|
||||
void *compress_buffer;
|
||||
struct table *table;
|
||||
struct zram_table_entry *table;
|
||||
struct zs_pool *mem_pool;
|
||||
};
|
||||
|
||||
struct zram {
|
||||
struct zram_meta *meta;
|
||||
spinlock_t stat64_lock; /* protect 64-bit stats */
|
||||
struct rw_semaphore lock; /* protect compression buffers, table,
|
||||
* 32bit stat counters against concurrent
|
||||
* notifications, reads and writes */
|
||||
struct request_queue *queue;
|
||||
struct gendisk *disk;
|
||||
int init_done;
|
||||
struct zcomp *comp;
|
||||
|
||||
/* Prevent concurrent execution of device init, reset and R/W request */
|
||||
struct rw_semaphore init_lock;
|
||||
/*
|
||||
|
|
@ -106,19 +111,13 @@ struct zram {
|
|||
* we can store in a disk.
|
||||
*/
|
||||
u64 disksize; /* bytes */
|
||||
|
||||
int max_comp_streams;
|
||||
struct zram_stats stats;
|
||||
/*
|
||||
* the number of pages zram can consume for storing compressed data
|
||||
*/
|
||||
unsigned long limit_pages;
|
||||
|
||||
char compressor[10];
|
||||
};
|
||||
|
||||
extern struct zram *zram_devices;
|
||||
unsigned int zram_get_num_devices(void);
|
||||
#ifdef CONFIG_SYSFS
|
||||
extern struct attribute_group zram_disk_attr_group;
|
||||
#endif
|
||||
|
||||
extern void zram_reset_device(struct zram *zram);
|
||||
extern struct zram_meta *zram_meta_alloc(u64 disksize);
|
||||
extern void zram_meta_free(struct zram_meta *meta);
|
||||
extern void zram_init_device(struct zram *zram, struct zram_meta *meta);
|
||||
|
||||
#endif
|
||||
|
|
@ -77,6 +77,8 @@ static struct usb_device_id ath3k_table[] = {
|
|||
{ USB_DEVICE(0x0CF3, 0x3004) },
|
||||
{ USB_DEVICE(0x0CF3, 0x3008) },
|
||||
{ USB_DEVICE(0x0CF3, 0x311D) },
|
||||
{ USB_DEVICE(0x0CF3, 0x311E) },
|
||||
{ USB_DEVICE(0x0CF3, 0x311F) },
|
||||
{ USB_DEVICE(0x0CF3, 0x817a) },
|
||||
{ USB_DEVICE(0x13d3, 0x3375) },
|
||||
{ USB_DEVICE(0x04CA, 0x3004) },
|
||||
|
|
@ -120,6 +122,8 @@ static struct usb_device_id ath3k_blist_tbl[] = {
|
|||
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x311E), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x311F), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ static struct usb_driver btusb_driver;
|
|||
#define BTUSB_WRONG_SCO_MTU 0x40
|
||||
#define BTUSB_ATH3012 0x80
|
||||
#define BTUSB_INTEL 0x100
|
||||
#define BTUSB_INTEL_BOOT 0x200
|
||||
|
||||
static struct usb_device_id btusb_table[] = {
|
||||
/* Generic Bluetooth USB device */
|
||||
|
|
@ -113,6 +114,13 @@ static struct usb_device_id btusb_table[] = {
|
|||
/*Broadcom devices with vendor specific id */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) },
|
||||
|
||||
/* IMC Networks - Broadcom based */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01) },
|
||||
|
||||
/* Intel Bluetooth USB Bootloader (RAM module) */
|
||||
{ USB_DEVICE(0x8087, 0x0a5a),
|
||||
.driver_info = BTUSB_INTEL_BOOT | BTUSB_BROKEN_ISOC },
|
||||
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
|
|
@ -141,6 +149,8 @@ static struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x311f), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
|
||||
|
|
@ -1444,6 +1454,9 @@ static int btusb_probe(struct usb_interface *intf,
|
|||
if (id->driver_info & BTUSB_INTEL)
|
||||
hdev->setup = btusb_setup_intel;
|
||||
|
||||
if (id->driver_info & BTUSB_INTEL_BOOT)
|
||||
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
|
||||
|
||||
/* Interface numbers are hardcoded in the specification */
|
||||
data->isoc = usb_ifnum_to_if(data->udev, 1);
|
||||
|
||||
|
|
|
|||
|
|
@ -487,6 +487,7 @@ static int omap_dma_terminate_all(struct omap_chan *c)
|
|||
* c->desc is NULL and exit.)
|
||||
*/
|
||||
if (c->desc) {
|
||||
omap_dma_desc_free(&c->desc->vd);
|
||||
c->desc = NULL;
|
||||
/* Avoid stopping the dma twice */
|
||||
if (!c->paused)
|
||||
|
|
|
|||
|
|
@ -270,8 +270,9 @@ static const u32 correrrthrsld[] = {
|
|||
* sbridge structs
|
||||
*/
|
||||
|
||||
#define NUM_CHANNELS 4
|
||||
#define MAX_DIMMS 3 /* Max DIMMS per channel */
|
||||
#define NUM_CHANNELS 4
|
||||
#define MAX_DIMMS 3 /* Max DIMMS per channel */
|
||||
#define CHANNEL_UNSPECIFIED 0xf /* Intel IA32 SDM 15-14 */
|
||||
|
||||
struct sbridge_info {
|
||||
u32 mcmtr;
|
||||
|
|
@ -1451,6 +1452,9 @@ static void sbridge_mce_output_error(struct mem_ctl_info *mci,
|
|||
|
||||
/* FIXME: need support for channel mask */
|
||||
|
||||
if (channel == CHANNEL_UNSPECIFIED)
|
||||
channel = -1;
|
||||
|
||||
/* Call the helper to output message */
|
||||
edac_mc_handle_error(tp_event, mci, core_err_cnt,
|
||||
m->addr >> PAGE_SHIFT, m->addr & ~PAGE_MASK, 0,
|
||||
|
|
|
|||
|
|
@ -909,6 +909,7 @@
|
|||
#define GMBUS_CYCLE_INDEX (2<<25)
|
||||
#define GMBUS_CYCLE_STOP (4<<25)
|
||||
#define GMBUS_BYTE_COUNT_SHIFT 16
|
||||
#define GMBUS_BYTE_COUNT_MAX 256U
|
||||
#define GMBUS_SLAVE_INDEX_SHIFT 8
|
||||
#define GMBUS_SLAVE_ADDR_SHIFT 1
|
||||
#define GMBUS_SLAVE_READ (1<<0)
|
||||
|
|
|
|||
|
|
@ -276,18 +276,17 @@ gmbus_wait_idle(struct drm_i915_private *dev_priv)
|
|||
}
|
||||
|
||||
static int
|
||||
gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
|
||||
u32 gmbus1_index)
|
||||
gmbus_xfer_read_chunk(struct drm_i915_private *dev_priv,
|
||||
unsigned short addr, u8 *buf, unsigned int len,
|
||||
u32 gmbus1_index)
|
||||
{
|
||||
int reg_offset = dev_priv->gpio_mmio_base;
|
||||
u16 len = msg->len;
|
||||
u8 *buf = msg->buf;
|
||||
|
||||
I915_WRITE(GMBUS1 + reg_offset,
|
||||
gmbus1_index |
|
||||
GMBUS_CYCLE_WAIT |
|
||||
(len << GMBUS_BYTE_COUNT_SHIFT) |
|
||||
(msg->addr << GMBUS_SLAVE_ADDR_SHIFT) |
|
||||
(addr << GMBUS_SLAVE_ADDR_SHIFT) |
|
||||
GMBUS_SLAVE_READ | GMBUS_SW_RDY);
|
||||
while (len) {
|
||||
int ret;
|
||||
|
|
@ -309,11 +308,35 @@ gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
|
|||
}
|
||||
|
||||
static int
|
||||
gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
|
||||
gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg,
|
||||
u32 gmbus1_index)
|
||||
{
|
||||
u8 *buf = msg->buf;
|
||||
unsigned int rx_size = msg->len;
|
||||
unsigned int len;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
len = min(rx_size, GMBUS_BYTE_COUNT_MAX);
|
||||
|
||||
ret = gmbus_xfer_read_chunk(dev_priv, msg->addr,
|
||||
buf, len, gmbus1_index);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
rx_size -= len;
|
||||
buf += len;
|
||||
} while (rx_size != 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gmbus_xfer_write_chunk(struct drm_i915_private *dev_priv,
|
||||
unsigned short addr, u8 *buf, unsigned int len)
|
||||
{
|
||||
int reg_offset = dev_priv->gpio_mmio_base;
|
||||
u16 len = msg->len;
|
||||
u8 *buf = msg->buf;
|
||||
unsigned int chunk_size = len;
|
||||
u32 val, loop;
|
||||
|
||||
val = loop = 0;
|
||||
|
|
@ -325,8 +348,8 @@ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
|
|||
I915_WRITE(GMBUS3 + reg_offset, val);
|
||||
I915_WRITE(GMBUS1 + reg_offset,
|
||||
GMBUS_CYCLE_WAIT |
|
||||
(msg->len << GMBUS_BYTE_COUNT_SHIFT) |
|
||||
(msg->addr << GMBUS_SLAVE_ADDR_SHIFT) |
|
||||
(chunk_size << GMBUS_BYTE_COUNT_SHIFT) |
|
||||
(addr << GMBUS_SLAVE_ADDR_SHIFT) |
|
||||
GMBUS_SLAVE_WRITE | GMBUS_SW_RDY);
|
||||
while (len) {
|
||||
int ret;
|
||||
|
|
@ -343,6 +366,29 @@ gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
|
|||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg)
|
||||
{
|
||||
u8 *buf = msg->buf;
|
||||
unsigned int tx_size = msg->len;
|
||||
unsigned int len;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
len = min(tx_size, GMBUS_BYTE_COUNT_MAX);
|
||||
|
||||
ret = gmbus_xfer_write_chunk(dev_priv, msg->addr, buf, len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
buf += len;
|
||||
tx_size -= len;
|
||||
} while (tx_size != 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -312,8 +312,10 @@ atombios_set_crtc_dtd_timing(struct drm_crtc *crtc,
|
|||
misc |= ATOM_COMPOSITESYNC;
|
||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
misc |= ATOM_INTERLACE;
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
||||
misc |= ATOM_DOUBLE_CLOCK_MODE;
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
misc |= ATOM_H_REPLICATIONBY2 | ATOM_V_REPLICATIONBY2;
|
||||
|
||||
args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
|
||||
args.ucCRTC = radeon_crtc->crtc_id;
|
||||
|
|
@ -356,8 +358,10 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc,
|
|||
misc |= ATOM_COMPOSITESYNC;
|
||||
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
misc |= ATOM_INTERLACE;
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
|
||||
misc |= ATOM_DOUBLE_CLOCK_MODE;
|
||||
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
|
||||
misc |= ATOM_H_REPLICATIONBY2 | ATOM_V_REPLICATIONBY2;
|
||||
|
||||
args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
|
||||
args.ucCRTC = radeon_crtc->crtc_id;
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ static bool igp_read_bios_from_vram(struct radeon_device *rdev)
|
|||
|
||||
static bool radeon_read_bios(struct radeon_device *rdev)
|
||||
{
|
||||
uint8_t __iomem *bios;
|
||||
uint8_t __iomem *bios, val1, val2;
|
||||
size_t size;
|
||||
|
||||
rdev->bios = NULL;
|
||||
|
|
@ -86,15 +86,19 @@ static bool radeon_read_bios(struct radeon_device *rdev)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) {
|
||||
val1 = readb(&bios[0]);
|
||||
val2 = readb(&bios[1]);
|
||||
|
||||
if (size == 0 || val1 != 0x55 || val2 != 0xaa) {
|
||||
pci_unmap_rom(rdev->pdev, bios);
|
||||
return false;
|
||||
}
|
||||
rdev->bios = kmemdup(bios, size, GFP_KERNEL);
|
||||
rdev->bios = kzalloc(size, GFP_KERNEL);
|
||||
if (rdev->bios == NULL) {
|
||||
pci_unmap_rom(rdev->pdev, bios);
|
||||
return false;
|
||||
}
|
||||
memcpy_fromio(rdev->bios, bios, size);
|
||||
pci_unmap_rom(rdev->pdev, bios);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
|||
GFP_KERNEL);
|
||||
if (!open_info) {
|
||||
err = -ENOMEM;
|
||||
goto error0;
|
||||
goto error_gpadl;
|
||||
}
|
||||
|
||||
init_completion(&open_info->waitevent);
|
||||
|
|
@ -185,7 +185,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
|||
|
||||
if (userdatalen > MAX_USER_DEFINED_BYTES) {
|
||||
err = -EINVAL;
|
||||
goto error0;
|
||||
goto error_gpadl;
|
||||
}
|
||||
|
||||
if (userdatalen)
|
||||
|
|
@ -226,6 +226,9 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
|||
list_del(&open_info->msglistentry);
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
error_gpadl:
|
||||
vmbus_teardown_gpadl(newchannel, newchannel->ringbuffer_gpadlhandle);
|
||||
|
||||
error0:
|
||||
free_pages((unsigned long)out,
|
||||
get_order(send_ringbuffer_size + recv_ringbuffer_size));
|
||||
|
|
|
|||
|
|
@ -213,6 +213,7 @@ int i2c_generic_scl_recovery(struct i2c_adapter *adap)
|
|||
adap->bus_recovery_info->set_scl(adap, 1);
|
||||
return i2c_generic_recovery(adap);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(i2c_generic_scl_recovery);
|
||||
|
||||
int i2c_generic_gpio_recovery(struct i2c_adapter *adap)
|
||||
{
|
||||
|
|
@ -227,6 +228,7 @@ int i2c_generic_gpio_recovery(struct i2c_adapter *adap)
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(i2c_generic_gpio_recovery);
|
||||
|
||||
int i2c_recover_bus(struct i2c_adapter *adap)
|
||||
{
|
||||
|
|
@ -236,6 +238,7 @@ int i2c_recover_bus(struct i2c_adapter *adap)
|
|||
dev_dbg(&adap->dev, "Trying i2c bus recovery\n");
|
||||
return adap->bus_recovery_info->recover_bus(adap);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(i2c_recover_bus);
|
||||
|
||||
static int i2c_device_probe(struct device *dev)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev)
|
|||
iio_trigger_set_drvdata(adis->trig, adis);
|
||||
ret = iio_trigger_register(adis->trig);
|
||||
|
||||
indio_dev->trig = adis->trig;
|
||||
indio_dev->trig = iio_trigger_get(adis->trig);
|
||||
if (ret)
|
||||
goto error_free_irq;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,16 @@
|
|||
#include <linux/poll.h>
|
||||
#include "inv_mpu_iio.h"
|
||||
|
||||
static void inv_clear_kfifo(struct inv_mpu6050_state *st)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/* take the spin lock sem to avoid interrupt kick in */
|
||||
spin_lock_irqsave(&st->time_stamp_lock, flags);
|
||||
kfifo_reset(&st->timestamps);
|
||||
spin_unlock_irqrestore(&st->time_stamp_lock, flags);
|
||||
}
|
||||
|
||||
int inv_reset_fifo(struct iio_dev *indio_dev)
|
||||
{
|
||||
int result;
|
||||
|
|
@ -51,6 +61,10 @@ int inv_reset_fifo(struct iio_dev *indio_dev)
|
|||
INV_MPU6050_BIT_FIFO_RST);
|
||||
if (result)
|
||||
goto reset_fifo_fail;
|
||||
|
||||
/* clear timestamps fifo */
|
||||
inv_clear_kfifo(st);
|
||||
|
||||
/* enable interrupt */
|
||||
if (st->chip_config.accl_fifo_enable ||
|
||||
st->chip_config.gyro_fifo_enable) {
|
||||
|
|
@ -84,16 +98,6 @@ int inv_reset_fifo(struct iio_dev *indio_dev)
|
|||
return result;
|
||||
}
|
||||
|
||||
static void inv_clear_kfifo(struct inv_mpu6050_state *st)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/* take the spin lock sem to avoid interrupt kick in */
|
||||
spin_lock_irqsave(&st->time_stamp_lock, flags);
|
||||
kfifo_reset(&st->timestamps);
|
||||
spin_unlock_irqrestore(&st->time_stamp_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* inv_mpu6050_irq_handler() - Cache a timestamp at each data ready interrupt.
|
||||
*/
|
||||
|
|
@ -187,7 +191,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
|
|||
flush_fifo:
|
||||
/* Flush HW and SW FIFOs. */
|
||||
inv_reset_fifo(indio_dev);
|
||||
inv_clear_kfifo(st);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
iio_trigger_notify_done(indio_dev->trig);
|
||||
|
||||
|
|
|
|||
|
|
@ -94,6 +94,17 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
|
|||
if (dmasync)
|
||||
dma_set_attr(DMA_ATTR_WRITE_BARRIER, &attrs);
|
||||
|
||||
if (!size)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/*
|
||||
* If the combination of the addr and size requested for this memory
|
||||
* region causes an integer overflow, return error.
|
||||
*/
|
||||
if (((addr + size) < addr) ||
|
||||
PAGE_ALIGN(addr + size) < (addr + size))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (!can_do_mlock())
|
||||
return ERR_PTR(-EPERM);
|
||||
|
||||
|
|
|
|||
|
|
@ -460,6 +460,7 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
|
|||
|
||||
entry->desc.async.element = element;
|
||||
entry->desc.async.event_type = event;
|
||||
entry->desc.async.reserved = 0;
|
||||
entry->counter = counter;
|
||||
|
||||
list_add_tail(&entry->list, &file->async_file->event_list);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,14 @@ enum {
|
|||
#define GUID_TBL_BLK_NUM_ENTRIES 8
|
||||
#define GUID_TBL_BLK_SIZE (GUID_TBL_ENTRY_SIZE * GUID_TBL_BLK_NUM_ENTRIES)
|
||||
|
||||
/* Counters should be saturate once they reach their maximum value */
|
||||
#define ASSIGN_32BIT_COUNTER(counter, value) do {\
|
||||
if ((value) > U32_MAX) \
|
||||
counter = cpu_to_be32(U32_MAX); \
|
||||
else \
|
||||
counter = cpu_to_be32(value); \
|
||||
} while (0)
|
||||
|
||||
struct mlx4_mad_rcv_buf {
|
||||
struct ib_grh grh;
|
||||
u8 payload[256];
|
||||
|
|
@ -730,10 +738,14 @@ static int ib_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
|
|||
static void edit_counter(struct mlx4_counter *cnt,
|
||||
struct ib_pma_portcounters *pma_cnt)
|
||||
{
|
||||
pma_cnt->port_xmit_data = cpu_to_be32((be64_to_cpu(cnt->tx_bytes)>>2));
|
||||
pma_cnt->port_rcv_data = cpu_to_be32((be64_to_cpu(cnt->rx_bytes)>>2));
|
||||
pma_cnt->port_xmit_packets = cpu_to_be32(be64_to_cpu(cnt->tx_frames));
|
||||
pma_cnt->port_rcv_packets = cpu_to_be32(be64_to_cpu(cnt->rx_frames));
|
||||
ASSIGN_32BIT_COUNTER(pma_cnt->port_xmit_data,
|
||||
(be64_to_cpu(cnt->tx_bytes) >> 2));
|
||||
ASSIGN_32BIT_COUNTER(pma_cnt->port_rcv_data,
|
||||
(be64_to_cpu(cnt->rx_bytes) >> 2));
|
||||
ASSIGN_32BIT_COUNTER(pma_cnt->port_xmit_packets,
|
||||
be64_to_cpu(cnt->tx_frames));
|
||||
ASSIGN_32BIT_COUNTER(pma_cnt->port_rcv_packets,
|
||||
be64_to_cpu(cnt->rx_frames));
|
||||
}
|
||||
|
||||
static int iboe_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num,
|
||||
|
|
|
|||
|
|
@ -2174,8 +2174,7 @@ static int build_lso_seg(struct mlx4_wqe_lso_seg *wqe, struct ib_send_wr *wr,
|
|||
|
||||
memcpy(wqe->header, wr->wr.ud.header, wr->wr.ud.hlen);
|
||||
|
||||
*lso_hdr_sz = cpu_to_be32((wr->wr.ud.mss - wr->wr.ud.hlen) << 16 |
|
||||
wr->wr.ud.hlen);
|
||||
*lso_hdr_sz = cpu_to_be32(wr->wr.ud.mss << 16 | wr->wr.ud.hlen);
|
||||
*lso_seg_len = halign;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -783,6 +783,21 @@ static psmouse_ret_t elantech_process_byte(struct psmouse *psmouse)
|
|||
return PSMOUSE_FULL_PACKET;
|
||||
}
|
||||
|
||||
/*
|
||||
* This writes the reg_07 value again to the hardware at the end of every
|
||||
* set_rate call because the register loses its value. reg_07 allows setting
|
||||
* absolute mode on v4 hardware
|
||||
*/
|
||||
static void elantech_set_rate_restore_reg_07(struct psmouse *psmouse,
|
||||
unsigned int rate)
|
||||
{
|
||||
struct elantech_data *etd = psmouse->private;
|
||||
|
||||
etd->original_set_rate(psmouse, rate);
|
||||
if (elantech_write_reg(psmouse, 0x07, etd->reg_07))
|
||||
psmouse_err(psmouse, "restoring reg_07 failed\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the touchpad into absolute mode
|
||||
*/
|
||||
|
|
@ -985,6 +1000,8 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse,
|
|||
* Asus K53SV 0x450f01 78, 15, 0c 2 hw buttons
|
||||
* Asus G46VW 0x460f02 00, 18, 0c 2 hw buttons
|
||||
* Asus G750JX 0x360f00 00, 16, 0c 2 hw buttons
|
||||
* Asus TP500LN 0x381f17 10, 14, 0e clickpad
|
||||
* Asus X750JN 0x381f17 10, 14, 0e clickpad
|
||||
* Asus UX31 0x361f00 20, 15, 0e clickpad
|
||||
* Asus UX32VD 0x361f02 00, 15, 0e clickpad
|
||||
* Avatar AVIU-145A2 0x361f00 ? clickpad
|
||||
|
|
@ -1452,6 +1469,11 @@ int elantech_init(struct psmouse *psmouse)
|
|||
goto init_fail;
|
||||
}
|
||||
|
||||
if (etd->fw_version == 0x381f17) {
|
||||
etd->original_set_rate = psmouse->set_rate;
|
||||
psmouse->set_rate = elantech_set_rate_restore_reg_07;
|
||||
}
|
||||
|
||||
if (elantech_set_input_params(psmouse)) {
|
||||
psmouse_err(psmouse, "failed to query touchpad range.\n");
|
||||
goto init_fail;
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ struct elantech_data {
|
|||
struct finger_pos mt[ETP_MAX_FINGERS];
|
||||
unsigned char parity[256];
|
||||
int (*send_cmd)(struct psmouse *psmouse, unsigned char c, unsigned char *param);
|
||||
void (*original_set_rate)(struct psmouse *psmouse, unsigned int rate);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MOUSE_PS2_ELANTECH
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
/* Offset base used to differentiate between CAPTURE and OUTPUT
|
||||
* while mmaping */
|
||||
#define DST_QUEUE_OFF_BASE (TASK_SIZE / 2)
|
||||
#define DST_QUEUE_OFF_BASE (1 << 30)
|
||||
|
||||
#define MFC_BANK1_ALLOC_CTX 0
|
||||
#define MFC_BANK2_ALLOC_CTX 1
|
||||
|
|
|
|||
|
|
@ -245,6 +245,11 @@ static int stk1160_stop_streaming(struct stk1160 *dev)
|
|||
if (mutex_lock_interruptible(&dev->v4l_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
/*
|
||||
* Once URBs are cancelled, the URB complete handler
|
||||
* won't be running. This is required to safely release the
|
||||
* current buffer (dev->isoc_ctl.buf).
|
||||
*/
|
||||
stk1160_cancel_isoc(dev);
|
||||
|
||||
/*
|
||||
|
|
@ -665,8 +670,16 @@ void stk1160_clear_queue(struct stk1160 *dev)
|
|||
stk1160_info("buffer [%p/%d] aborted\n",
|
||||
buf, buf->vb.v4l2_buf.index);
|
||||
}
|
||||
/* It's important to clear current buffer */
|
||||
dev->isoc_ctl.buf = NULL;
|
||||
|
||||
/* It's important to release the current buffer */
|
||||
if (dev->isoc_ctl.buf) {
|
||||
buf = dev->isoc_ctl.buf;
|
||||
dev->isoc_ctl.buf = NULL;
|
||||
|
||||
vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
|
||||
stk1160_info("buffer [%p/%d] aborted\n",
|
||||
buf, buf->vb.v4l2_buf.index);
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->buf_lock, flags);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -758,7 +758,7 @@ static int mspro_block_complete_req(struct memstick_dev *card, int error)
|
|||
|
||||
if (error || (card->current_mrq.tpc == MSPRO_CMD_STOP)) {
|
||||
if (msb->data_dir == READ) {
|
||||
for (cnt = 0; cnt < msb->current_seg; cnt++)
|
||||
for (cnt = 0; cnt < msb->current_seg; cnt++) {
|
||||
t_len += msb->req_sg[cnt].length
|
||||
/ msb->page_size;
|
||||
|
||||
|
|
@ -766,6 +766,7 @@ static int mspro_block_complete_req(struct memstick_dev *card, int error)
|
|||
t_len += msb->current_page - 1;
|
||||
|
||||
t_len *= msb->page_size;
|
||||
}
|
||||
}
|
||||
} else
|
||||
t_len = blk_rq_bytes(msb->block_req);
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
|
|||
second_is_newer = !second_is_newer;
|
||||
} else {
|
||||
dbg_bld("PEB %d CRC is OK", pnum);
|
||||
bitflips = !!err;
|
||||
bitflips |= !!err;
|
||||
}
|
||||
mutex_unlock(&ubi->buf_mutex);
|
||||
|
||||
|
|
|
|||
|
|
@ -475,7 +475,7 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd,
|
|||
/* Validate the request */
|
||||
err = -EINVAL;
|
||||
if (req.lnum < 0 || req.lnum >= vol->reserved_pebs ||
|
||||
req.bytes < 0 || req.lnum >= vol->usable_leb_size)
|
||||
req.bytes < 0 || req.bytes > vol->usable_leb_size)
|
||||
break;
|
||||
|
||||
err = get_exclusive(desc);
|
||||
|
|
|
|||
|
|
@ -1362,7 +1362,8 @@ int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
|
|||
* during re-size.
|
||||
*/
|
||||
ubi_move_aeb_to_list(av, aeb, &ai->erase);
|
||||
vol->eba_tbl[aeb->lnum] = aeb->pnum;
|
||||
else
|
||||
vol->eba_tbl[aeb->lnum] = aeb->pnum;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -999,7 +999,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
|
|||
int cancel)
|
||||
{
|
||||
int err, scrubbing = 0, torture = 0, protect = 0, erroneous = 0;
|
||||
int vol_id = -1, uninitialized_var(lnum);
|
||||
int vol_id = -1, lnum = -1;
|
||||
#ifdef CONFIG_MTD_UBI_FASTMAP
|
||||
int anchor = wrk->anchor;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2869,7 +2869,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
|
|||
sw_cons = BNX2_NEXT_TX_BD(sw_cons);
|
||||
|
||||
tx_bytes += skb->len;
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
tx_pkt++;
|
||||
if (tx_pkt == budget)
|
||||
break;
|
||||
|
|
@ -6610,7 +6610,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
mapping = dma_map_single(&bp->pdev->dev, skb->data, len, PCI_DMA_TODEVICE);
|
||||
if (dma_mapping_error(&bp->pdev->dev, mapping)) {
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
|
@ -6703,7 +6703,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
PCI_DMA_TODEVICE);
|
||||
}
|
||||
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6437,7 +6437,7 @@ static void tg3_tx(struct tg3_napi *tnapi)
|
|||
pkts_compl++;
|
||||
bytes_compl += skb->len;
|
||||
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
|
||||
if (unlikely(tx_bug)) {
|
||||
tg3_tx_recover(tp);
|
||||
|
|
@ -6769,7 +6769,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
|
|||
if (len > (tp->dev->mtu + ETH_HLEN) &&
|
||||
skb->protocol != htons(ETH_P_8021Q) &&
|
||||
skb->protocol != htons(ETH_P_8021AD)) {
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
goto drop_it_no_recycle;
|
||||
}
|
||||
|
||||
|
|
@ -7652,7 +7652,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
|
|||
PCI_DMA_TODEVICE);
|
||||
/* Make sure the mapping succeeded */
|
||||
if (pci_dma_mapping_error(tp->pdev, new_addr)) {
|
||||
dev_kfree_skb(new_skb);
|
||||
dev_kfree_skb_any(new_skb);
|
||||
ret = -1;
|
||||
} else {
|
||||
u32 save_entry = *entry;
|
||||
|
|
@ -7667,13 +7667,13 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
|
|||
new_skb->len, base_flags,
|
||||
mss, vlan)) {
|
||||
tg3_tx_skb_unmap(tnapi, save_entry, -1);
|
||||
dev_kfree_skb(new_skb);
|
||||
dev_kfree_skb_any(new_skb);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
*pskb = new_skb;
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -7716,7 +7716,7 @@ static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb)
|
|||
} while (segs);
|
||||
|
||||
tg3_tso_bug_end:
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
|
@ -7954,7 +7954,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, --i);
|
||||
tnapi->tx_buffers[tnapi->tx_prod].skb = NULL;
|
||||
drop:
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
drop_nofree:
|
||||
tp->tx_dropped++;
|
||||
return NETDEV_TX_OK;
|
||||
|
|
|
|||
|
|
@ -1767,7 +1767,7 @@ static u16 be_tx_compl_process(struct be_adapter *adapter,
|
|||
queue_tail_inc(txq);
|
||||
} while (cur_index != last_index);
|
||||
|
||||
kfree_skb(sent_skb);
|
||||
dev_kfree_skb_any(sent_skb);
|
||||
return num_wrbs;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -144,6 +144,11 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
|
|||
static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
|
||||
struct e1000_rx_ring *rx_ring,
|
||||
int *work_done, int work_to_do);
|
||||
static void e1000_alloc_dummy_rx_buffers(struct e1000_adapter *adapter,
|
||||
struct e1000_rx_ring *rx_ring,
|
||||
int cleaned_count)
|
||||
{
|
||||
}
|
||||
static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
|
||||
struct e1000_rx_ring *rx_ring,
|
||||
int cleaned_count);
|
||||
|
|
@ -3555,8 +3560,11 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
|
|||
msleep(1);
|
||||
/* e1000_down has a dependency on max_frame_size */
|
||||
hw->max_frame_size = max_frame;
|
||||
if (netif_running(netdev))
|
||||
if (netif_running(netdev)) {
|
||||
/* prevent buffers from being reallocated */
|
||||
adapter->alloc_rx_buf = e1000_alloc_dummy_rx_buffers;
|
||||
e1000_down(adapter);
|
||||
}
|
||||
|
||||
/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
|
||||
* means we reserve 2 more, this pushes us to allocate from the next
|
||||
|
|
|
|||
|
|
@ -1527,12 +1527,12 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
|||
int tso;
|
||||
|
||||
if (test_bit(__IXGB_DOWN, &adapter->flags)) {
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
if (skb->len <= 0) {
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1549,7 +1549,7 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
|||
|
||||
tso = ixgb_tso(adapter, skb);
|
||||
if (tso < 0) {
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -899,7 +899,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
|
|||
|
||||
return NETDEV_TX_OK;
|
||||
out_dma_error:
|
||||
kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
cp->dev->stats.tx_dropped++;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1715,9 +1715,9 @@ static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
|
|||
if (len < ETH_ZLEN)
|
||||
memset(tp->tx_buf[entry], 0, ETH_ZLEN);
|
||||
skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
} else {
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
dev->stats.tx_dropped++;
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5768,7 +5768,7 @@ static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start,
|
|||
tp->TxDescArray + entry);
|
||||
if (skb) {
|
||||
tp->dev->stats.tx_dropped++;
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
tx_skb->skb = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -5993,7 +5993,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
|
|||
err_dma_1:
|
||||
rtl8169_unmap_tx_skb(d, tp->tx_skb + entry, txd);
|
||||
err_dma_0:
|
||||
dev_kfree_skb(skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
err_update_stats:
|
||||
dev->stats.tx_dropped++;
|
||||
return NETDEV_TX_OK;
|
||||
|
|
@ -6076,7 +6076,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
|
|||
tp->tx_stats.packets++;
|
||||
tp->tx_stats.bytes += tx_skb->skb->len;
|
||||
u64_stats_update_end(&tp->tx_stats.syncp);
|
||||
dev_kfree_skb(tx_skb->skb);
|
||||
dev_kfree_skb_any(tx_skb->skb);
|
||||
tx_skb->skb = NULL;
|
||||
}
|
||||
dirty_tx++;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user