Merge commit 'v3.0.1' into android-3.0
This commit is contained in:
commit
9abd59b0df
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
||||||
VERSION = 3
|
VERSION = 3
|
||||||
PATCHLEVEL = 0
|
PATCHLEVEL = 0
|
||||||
SUBLEVEL = 0
|
SUBLEVEL = 1
|
||||||
EXTRAVERSION =
|
EXTRAVERSION =
|
||||||
NAME = Sneaky Weasel
|
NAME = Sneaky Weasel
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ DEFINE_PER_CPU(u8, irq_work_pending);
|
||||||
#define test_irq_work_pending() __get_cpu_var(irq_work_pending)
|
#define test_irq_work_pending() __get_cpu_var(irq_work_pending)
|
||||||
#define clear_irq_work_pending() __get_cpu_var(irq_work_pending) = 0
|
#define clear_irq_work_pending() __get_cpu_var(irq_work_pending) = 0
|
||||||
|
|
||||||
void set_irq_work_pending(void)
|
void arch_irq_work_raise(void)
|
||||||
{
|
{
|
||||||
set_irq_work_pending_flag();
|
set_irq_work_pending_flag();
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,9 +161,9 @@ static mfp_cfg_t cm_x3xx_mfp_cfg[] __initdata = {
|
||||||
GPIO99_GPIO, /* Ethernet IRQ */
|
GPIO99_GPIO, /* Ethernet IRQ */
|
||||||
|
|
||||||
/* RTC GPIOs */
|
/* RTC GPIOs */
|
||||||
GPIO95_GPIO, /* RTC CS */
|
GPIO95_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC CS */
|
||||||
GPIO96_GPIO, /* RTC WR */
|
GPIO96_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC WR */
|
||||||
GPIO97_GPIO, /* RTC RD */
|
GPIO97_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC RD */
|
||||||
GPIO98_GPIO, /* RTC IO */
|
GPIO98_GPIO, /* RTC IO */
|
||||||
|
|
||||||
/* Standard I2C */
|
/* Standard I2C */
|
||||||
|
|
|
@ -242,12 +242,8 @@ static void crash_kexec_wait_realmode(int cpu)
|
||||||
|
|
||||||
while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) {
|
while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) {
|
||||||
barrier();
|
barrier();
|
||||||
if (!cpu_possible(i)) {
|
if (!cpu_possible(i) || !cpu_online(i) || (msecs <= 0))
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
if (!cpu_online(i)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
msecs--;
|
msecs--;
|
||||||
mdelay(1);
|
mdelay(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -544,7 +544,7 @@ DEFINE_PER_CPU(u8, irq_work_pending);
|
||||||
|
|
||||||
#endif /* 32 vs 64 bit */
|
#endif /* 32 vs 64 bit */
|
||||||
|
|
||||||
void set_irq_work_pending(void)
|
void arch_irq_work_raise(void)
|
||||||
{
|
{
|
||||||
preempt_disable();
|
preempt_disable();
|
||||||
set_irq_work_pending_flag();
|
set_irq_work_pending_flag();
|
||||||
|
|
|
@ -73,7 +73,7 @@ int hvc_put_chars(uint32_t vtermno, const char *buf, int count)
|
||||||
if (ret == H_SUCCESS)
|
if (ret == H_SUCCESS)
|
||||||
return count;
|
return count;
|
||||||
if (ret == H_BUSY)
|
if (ret == H_BUSY)
|
||||||
return 0;
|
return -EAGAIN;
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -259,6 +259,9 @@
|
||||||
#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2
|
#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2
|
||||||
|
|
||||||
#define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0
|
#define MSR_IA32_ENERGY_PERF_BIAS 0x000001b0
|
||||||
|
#define ENERGY_PERF_BIAS_PERFORMANCE 0
|
||||||
|
#define ENERGY_PERF_BIAS_NORMAL 6
|
||||||
|
#define ENERGY_PERF_BIAS_POWERSWAVE 15
|
||||||
|
|
||||||
#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1
|
#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1
|
||||||
|
|
||||||
|
|
|
@ -456,6 +456,24 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c)
|
||||||
|
|
||||||
if (cpu_has(c, X86_FEATURE_VMX))
|
if (cpu_has(c, X86_FEATURE_VMX))
|
||||||
detect_vmx_virtcap(c);
|
detect_vmx_virtcap(c);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize MSR_IA32_ENERGY_PERF_BIAS if BIOS did not.
|
||||||
|
* x86_energy_perf_policy(8) is available to change it at run-time
|
||||||
|
*/
|
||||||
|
if (cpu_has(c, X86_FEATURE_EPB)) {
|
||||||
|
u64 epb;
|
||||||
|
|
||||||
|
rdmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb);
|
||||||
|
if ((epb & 0xF) == 0) {
|
||||||
|
printk_once(KERN_WARNING, "x86: updated energy_perf_bias"
|
||||||
|
" to 'normal' from 'performance'\n"
|
||||||
|
"You can view and update epb via utility,"
|
||||||
|
" such as x86_energy_perf_policy(8)\n");
|
||||||
|
epb = (epb & ~0xF) | ENERGY_PERF_BIAS_NORMAL;
|
||||||
|
wrmsrl(MSR_IA32_ENERGY_PERF_BIAS, epb);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
|
|
|
@ -97,6 +97,8 @@ relocate_kernel:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
identity_mapped:
|
identity_mapped:
|
||||||
|
/* set return address to 0 if not preserving context */
|
||||||
|
pushl $0
|
||||||
/* store the start address on the stack */
|
/* store the start address on the stack */
|
||||||
pushl %edx
|
pushl %edx
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,8 @@ relocate_kernel:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
identity_mapped:
|
identity_mapped:
|
||||||
|
/* set return address to 0 if not preserving context */
|
||||||
|
pushq $0
|
||||||
/* store the start address on the stack */
|
/* store the start address on the stack */
|
||||||
pushq %rdx
|
pushq %rdx
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,12 @@
|
||||||
#include <linux/oprofile.h>
|
#include <linux/oprofile.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/mm.h>
|
#include <linux/mm.h>
|
||||||
|
#include <linux/compat.h>
|
||||||
|
#include <linux/highmem.h>
|
||||||
|
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/stacktrace.h>
|
#include <asm/stacktrace.h>
|
||||||
#include <linux/compat.h>
|
|
||||||
|
|
||||||
static int backtrace_stack(void *data, char *name)
|
static int backtrace_stack(void *data, char *name)
|
||||||
{
|
{
|
||||||
|
@ -36,17 +38,53 @@ static struct stacktrace_ops backtrace_ops = {
|
||||||
.walk_stack = print_context_stack,
|
.walk_stack = print_context_stack,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* from arch/x86/kernel/cpu/perf_event.c: */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* best effort, GUP based copy_from_user() that assumes IRQ or NMI context
|
||||||
|
*/
|
||||||
|
static unsigned long
|
||||||
|
copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
|
||||||
|
{
|
||||||
|
unsigned long offset, addr = (unsigned long)from;
|
||||||
|
unsigned long size, len = 0;
|
||||||
|
struct page *page;
|
||||||
|
void *map;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
do {
|
||||||
|
ret = __get_user_pages_fast(addr, 1, 0, &page);
|
||||||
|
if (!ret)
|
||||||
|
break;
|
||||||
|
|
||||||
|
offset = addr & (PAGE_SIZE - 1);
|
||||||
|
size = min(PAGE_SIZE - offset, n - len);
|
||||||
|
|
||||||
|
map = kmap_atomic(page);
|
||||||
|
memcpy(to, map+offset, size);
|
||||||
|
kunmap_atomic(map);
|
||||||
|
put_page(page);
|
||||||
|
|
||||||
|
len += size;
|
||||||
|
to += size;
|
||||||
|
addr += size;
|
||||||
|
|
||||||
|
} while (len < n);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_COMPAT
|
#ifdef CONFIG_COMPAT
|
||||||
static struct stack_frame_ia32 *
|
static struct stack_frame_ia32 *
|
||||||
dump_user_backtrace_32(struct stack_frame_ia32 *head)
|
dump_user_backtrace_32(struct stack_frame_ia32 *head)
|
||||||
{
|
{
|
||||||
|
/* Also check accessibility of one struct frame_head beyond: */
|
||||||
struct stack_frame_ia32 bufhead[2];
|
struct stack_frame_ia32 bufhead[2];
|
||||||
struct stack_frame_ia32 *fp;
|
struct stack_frame_ia32 *fp;
|
||||||
|
unsigned long bytes;
|
||||||
|
|
||||||
/* Also check accessibility of one struct frame_head beyond */
|
bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead));
|
||||||
if (!access_ok(VERIFY_READ, head, sizeof(bufhead)))
|
if (bytes != sizeof(bufhead))
|
||||||
return NULL;
|
|
||||||
if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
fp = (struct stack_frame_ia32 *) compat_ptr(bufhead[0].next_frame);
|
fp = (struct stack_frame_ia32 *) compat_ptr(bufhead[0].next_frame);
|
||||||
|
@ -87,12 +125,12 @@ x86_backtrace_32(struct pt_regs * const regs, unsigned int depth)
|
||||||
|
|
||||||
static struct stack_frame *dump_user_backtrace(struct stack_frame *head)
|
static struct stack_frame *dump_user_backtrace(struct stack_frame *head)
|
||||||
{
|
{
|
||||||
|
/* Also check accessibility of one struct frame_head beyond: */
|
||||||
struct stack_frame bufhead[2];
|
struct stack_frame bufhead[2];
|
||||||
|
unsigned long bytes;
|
||||||
|
|
||||||
/* Also check accessibility of one struct stack_frame beyond */
|
bytes = copy_from_user_nmi(bufhead, head, sizeof(bufhead));
|
||||||
if (!access_ok(VERIFY_READ, head, sizeof(bufhead)))
|
if (bytes != sizeof(bufhead))
|
||||||
return NULL;
|
|
||||||
if (__copy_from_user_inatomic(bufhead, head, sizeof(bufhead)))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
oprofile_add_trace(bufhead[0].return_address);
|
oprofile_add_trace(bufhead[0].return_address);
|
||||||
|
|
|
@ -147,6 +147,9 @@ int ptrace_setxregs(struct task_struct *child, void __user *uregs)
|
||||||
elf_xtregs_t *xtregs = uregs;
|
elf_xtregs_t *xtregs = uregs;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!access_ok(VERIFY_READ, uregs, sizeof(elf_xtregs_t)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
#if XTENSA_HAVE_COPROCESSORS
|
#if XTENSA_HAVE_COPROCESSORS
|
||||||
/* Flush all coprocessors before we overwrite them. */
|
/* Flush all coprocessors before we overwrite them. */
|
||||||
coprocessor_flush_all(ti);
|
coprocessor_flush_all(ti);
|
||||||
|
|
|
@ -839,6 +839,9 @@ struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask)
|
||||||
{
|
{
|
||||||
struct request *rq;
|
struct request *rq;
|
||||||
|
|
||||||
|
if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
BUG_ON(rw != READ && rw != WRITE);
|
BUG_ON(rw != READ && rw != WRITE);
|
||||||
|
|
||||||
spin_lock_irq(q->queue_lock);
|
spin_lock_irq(q->queue_lock);
|
||||||
|
|
|
@ -50,6 +50,13 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
|
||||||
{
|
{
|
||||||
int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
|
int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
|
||||||
|
|
||||||
|
if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) {
|
||||||
|
rq->errors = -ENXIO;
|
||||||
|
if (rq->end_io)
|
||||||
|
rq->end_io(rq, rq->errors);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rq->rq_disk = bd_disk;
|
rq->rq_disk = bd_disk;
|
||||||
rq->end_io = done;
|
rq->end_io = done;
|
||||||
WARN_ON(irqs_disabled());
|
WARN_ON(irqs_disabled());
|
||||||
|
|
|
@ -223,7 +223,7 @@ static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c)
|
||||||
h->ctlr, c->busaddr);
|
h->ctlr, c->busaddr);
|
||||||
#endif /* CCISS_DEBUG */
|
#endif /* CCISS_DEBUG */
|
||||||
writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
|
writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
|
||||||
readl(h->vaddr + SA5_REQUEST_PORT_OFFSET);
|
readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
|
||||||
h->commands_outstanding++;
|
h->commands_outstanding++;
|
||||||
if ( h->commands_outstanding > h->max_outstanding)
|
if ( h->commands_outstanding > h->max_outstanding)
|
||||||
h->max_outstanding = h->commands_outstanding;
|
h->max_outstanding = h->commands_outstanding;
|
||||||
|
|
|
@ -253,14 +253,11 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
|
||||||
init_waitqueue_head(&client->wait);
|
init_waitqueue_head(&client->wait);
|
||||||
init_waitqueue_head(&client->tx_flush_wait);
|
init_waitqueue_head(&client->tx_flush_wait);
|
||||||
INIT_LIST_HEAD(&client->phy_receiver_link);
|
INIT_LIST_HEAD(&client->phy_receiver_link);
|
||||||
|
INIT_LIST_HEAD(&client->link);
|
||||||
kref_init(&client->kref);
|
kref_init(&client->kref);
|
||||||
|
|
||||||
file->private_data = client;
|
file->private_data = client;
|
||||||
|
|
||||||
mutex_lock(&device->client_list_mutex);
|
|
||||||
list_add_tail(&client->link, &device->client_list);
|
|
||||||
mutex_unlock(&device->client_list_mutex);
|
|
||||||
|
|
||||||
return nonseekable_open(inode, file);
|
return nonseekable_open(inode, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,15 +448,20 @@ static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
mutex_lock(&client->device->client_list_mutex);
|
||||||
|
|
||||||
client->bus_reset_closure = a->bus_reset_closure;
|
client->bus_reset_closure = a->bus_reset_closure;
|
||||||
if (a->bus_reset != 0) {
|
if (a->bus_reset != 0) {
|
||||||
fill_bus_reset_event(&bus_reset, client);
|
fill_bus_reset_event(&bus_reset, client);
|
||||||
if (copy_to_user(u64_to_uptr(a->bus_reset),
|
ret = copy_to_user(u64_to_uptr(a->bus_reset),
|
||||||
&bus_reset, sizeof(bus_reset)))
|
&bus_reset, sizeof(bus_reset));
|
||||||
return -EFAULT;
|
|
||||||
}
|
}
|
||||||
|
if (ret == 0 && list_empty(&client->link))
|
||||||
|
list_add_tail(&client->link, &client->device->client_list);
|
||||||
|
|
||||||
return 0;
|
mutex_unlock(&client->device->client_list_mutex);
|
||||||
|
|
||||||
|
return ret ? -EFAULT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_client_resource(struct client *client,
|
static int add_client_resource(struct client *client,
|
||||||
|
@ -1583,7 +1585,7 @@ static int dispatch_ioctl(struct client *client,
|
||||||
if (_IOC_TYPE(cmd) != '#' ||
|
if (_IOC_TYPE(cmd) != '#' ||
|
||||||
_IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) ||
|
_IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) ||
|
||||||
_IOC_SIZE(cmd) > sizeof(buffer))
|
_IOC_SIZE(cmd) > sizeof(buffer))
|
||||||
return -EINVAL;
|
return -ENOTTY;
|
||||||
|
|
||||||
if (_IOC_DIR(cmd) == _IOC_READ)
|
if (_IOC_DIR(cmd) == _IOC_READ)
|
||||||
memset(&buffer, 0, _IOC_SIZE(cmd));
|
memset(&buffer, 0, _IOC_SIZE(cmd));
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <linux/firmware.h>
|
#include <linux/firmware.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/module.h>
|
||||||
#include <linux/sigma.h>
|
#include <linux/sigma.h>
|
||||||
|
|
||||||
/* Return: 0==OK, <0==error, =1 ==no more actions */
|
/* Return: 0==OK, <0==error, =1 ==no more actions */
|
||||||
|
@ -113,3 +114,5 @@ int process_sigma_firmware(struct i2c_client *client, const char *name)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(process_sigma_firmware);
|
EXPORT_SYMBOL(process_sigma_firmware);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -627,6 +627,7 @@ struct radeon_dp_link_train_info {
|
||||||
u8 train_set[4];
|
u8 train_set[4];
|
||||||
u8 link_status[DP_LINK_STATUS_SIZE];
|
u8 link_status[DP_LINK_STATUS_SIZE];
|
||||||
u8 tries;
|
u8 tries;
|
||||||
|
bool use_dpencoder;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info)
|
static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info)
|
||||||
|
@ -646,7 +647,7 @@ static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp)
|
||||||
int rtp = 0;
|
int rtp = 0;
|
||||||
|
|
||||||
/* set training pattern on the source */
|
/* set training pattern on the source */
|
||||||
if (ASIC_IS_DCE4(dp_info->rdev)) {
|
if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder) {
|
||||||
switch (tp) {
|
switch (tp) {
|
||||||
case DP_TRAINING_PATTERN_1:
|
case DP_TRAINING_PATTERN_1:
|
||||||
rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1;
|
rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1;
|
||||||
|
@ -706,7 +707,7 @@ static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info)
|
||||||
radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp);
|
radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp);
|
||||||
|
|
||||||
/* start training on the source */
|
/* start training on the source */
|
||||||
if (ASIC_IS_DCE4(dp_info->rdev))
|
if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder)
|
||||||
atombios_dig_encoder_setup(dp_info->encoder,
|
atombios_dig_encoder_setup(dp_info->encoder,
|
||||||
ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0);
|
ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0);
|
||||||
else
|
else
|
||||||
|
@ -731,7 +732,7 @@ static int radeon_dp_link_train_finish(struct radeon_dp_link_train_info *dp_info
|
||||||
DP_TRAINING_PATTERN_DISABLE);
|
DP_TRAINING_PATTERN_DISABLE);
|
||||||
|
|
||||||
/* disable the training pattern on the source */
|
/* disable the training pattern on the source */
|
||||||
if (ASIC_IS_DCE4(dp_info->rdev))
|
if (ASIC_IS_DCE4(dp_info->rdev) || !dp_info->use_dpencoder)
|
||||||
atombios_dig_encoder_setup(dp_info->encoder,
|
atombios_dig_encoder_setup(dp_info->encoder,
|
||||||
ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0);
|
ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0);
|
||||||
else
|
else
|
||||||
|
@ -869,7 +870,8 @@ void radeon_dp_link_train(struct drm_encoder *encoder,
|
||||||
struct radeon_connector *radeon_connector;
|
struct radeon_connector *radeon_connector;
|
||||||
struct radeon_connector_atom_dig *dig_connector;
|
struct radeon_connector_atom_dig *dig_connector;
|
||||||
struct radeon_dp_link_train_info dp_info;
|
struct radeon_dp_link_train_info dp_info;
|
||||||
u8 tmp;
|
int index;
|
||||||
|
u8 tmp, frev, crev;
|
||||||
|
|
||||||
if (!radeon_encoder->enc_priv)
|
if (!radeon_encoder->enc_priv)
|
||||||
return;
|
return;
|
||||||
|
@ -884,6 +886,18 @@ void radeon_dp_link_train(struct drm_encoder *encoder,
|
||||||
(dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_eDP))
|
(dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_eDP))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* DPEncoderService newer than 1.1 can't program properly the
|
||||||
|
* training pattern. When facing such version use the
|
||||||
|
* DIGXEncoderControl (X== 1 | 2)
|
||||||
|
*/
|
||||||
|
dp_info.use_dpencoder = true;
|
||||||
|
index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
|
||||||
|
if (atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) {
|
||||||
|
if (crev > 1) {
|
||||||
|
dp_info.use_dpencoder = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dp_info.enc_id = 0;
|
dp_info.enc_id = 0;
|
||||||
if (dig->dig_encoder)
|
if (dig->dig_encoder)
|
||||||
dp_info.enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
|
dp_info.enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
|
||||||
|
|
|
@ -779,7 +779,8 @@ void radeon_combios_i2c_init(struct radeon_device *rdev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (rdev->family >= CHIP_R200) {
|
} else if ((rdev->family == CHIP_R200) ||
|
||||||
|
(rdev->family >= CHIP_R300)) {
|
||||||
/* 0x68 */
|
/* 0x68 */
|
||||||
i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
|
i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
|
||||||
rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
|
rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
|
||||||
|
|
|
@ -594,6 +594,9 @@ int radeon_pm_init(struct radeon_device *rdev)
|
||||||
if (rdev->pm.default_vddc)
|
if (rdev->pm.default_vddc)
|
||||||
radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
|
radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
|
||||||
SET_VOLTAGE_TYPE_ASIC_VDDC);
|
SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||||
|
if (rdev->pm.default_vddci)
|
||||||
|
radeon_atom_set_voltage(rdev, rdev->pm.default_vddci,
|
||||||
|
SET_VOLTAGE_TYPE_ASIC_VDDCI);
|
||||||
if (rdev->pm.default_sclk)
|
if (rdev->pm.default_sclk)
|
||||||
radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
|
radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
|
||||||
if (rdev->pm.default_mclk)
|
if (rdev->pm.default_mclk)
|
||||||
|
|
|
@ -2127,6 +2127,8 @@ static ssize_t srp_create_target(struct device *dev,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
target_host->transportt = ib_srp_transport_template;
|
target_host->transportt = ib_srp_transport_template;
|
||||||
|
target_host->max_channel = 0;
|
||||||
|
target_host->max_id = 1;
|
||||||
target_host->max_lun = SRP_MAX_LUN;
|
target_host->max_lun = SRP_MAX_LUN;
|
||||||
target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb;
|
target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb;
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,8 @@ struct io {
|
||||||
struct dm_io_client *client;
|
struct dm_io_client *client;
|
||||||
io_notify_fn callback;
|
io_notify_fn callback;
|
||||||
void *context;
|
void *context;
|
||||||
|
void *vma_invalidate_address;
|
||||||
|
unsigned long vma_invalidate_size;
|
||||||
} __attribute__((aligned(DM_IO_MAX_REGIONS)));
|
} __attribute__((aligned(DM_IO_MAX_REGIONS)));
|
||||||
|
|
||||||
static struct kmem_cache *_dm_io_cache;
|
static struct kmem_cache *_dm_io_cache;
|
||||||
|
@ -116,6 +118,10 @@ static void dec_count(struct io *io, unsigned int region, int error)
|
||||||
set_bit(region, &io->error_bits);
|
set_bit(region, &io->error_bits);
|
||||||
|
|
||||||
if (atomic_dec_and_test(&io->count)) {
|
if (atomic_dec_and_test(&io->count)) {
|
||||||
|
if (io->vma_invalidate_size)
|
||||||
|
invalidate_kernel_vmap_range(io->vma_invalidate_address,
|
||||||
|
io->vma_invalidate_size);
|
||||||
|
|
||||||
if (io->sleeper)
|
if (io->sleeper)
|
||||||
wake_up_process(io->sleeper);
|
wake_up_process(io->sleeper);
|
||||||
|
|
||||||
|
@ -159,6 +165,9 @@ struct dpages {
|
||||||
|
|
||||||
unsigned context_u;
|
unsigned context_u;
|
||||||
void *context_ptr;
|
void *context_ptr;
|
||||||
|
|
||||||
|
void *vma_invalidate_address;
|
||||||
|
unsigned long vma_invalidate_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -377,6 +386,9 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,
|
||||||
io->sleeper = current;
|
io->sleeper = current;
|
||||||
io->client = client;
|
io->client = client;
|
||||||
|
|
||||||
|
io->vma_invalidate_address = dp->vma_invalidate_address;
|
||||||
|
io->vma_invalidate_size = dp->vma_invalidate_size;
|
||||||
|
|
||||||
dispatch_io(rw, num_regions, where, dp, io, 1);
|
dispatch_io(rw, num_regions, where, dp, io, 1);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -415,13 +427,21 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions,
|
||||||
io->callback = fn;
|
io->callback = fn;
|
||||||
io->context = context;
|
io->context = context;
|
||||||
|
|
||||||
|
io->vma_invalidate_address = dp->vma_invalidate_address;
|
||||||
|
io->vma_invalidate_size = dp->vma_invalidate_size;
|
||||||
|
|
||||||
dispatch_io(rw, num_regions, where, dp, io, 0);
|
dispatch_io(rw, num_regions, where, dp, io, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dp_init(struct dm_io_request *io_req, struct dpages *dp)
|
static int dp_init(struct dm_io_request *io_req, struct dpages *dp,
|
||||||
|
unsigned long size)
|
||||||
{
|
{
|
||||||
/* Set up dpages based on memory type */
|
/* Set up dpages based on memory type */
|
||||||
|
|
||||||
|
dp->vma_invalidate_address = NULL;
|
||||||
|
dp->vma_invalidate_size = 0;
|
||||||
|
|
||||||
switch (io_req->mem.type) {
|
switch (io_req->mem.type) {
|
||||||
case DM_IO_PAGE_LIST:
|
case DM_IO_PAGE_LIST:
|
||||||
list_dp_init(dp, io_req->mem.ptr.pl, io_req->mem.offset);
|
list_dp_init(dp, io_req->mem.ptr.pl, io_req->mem.offset);
|
||||||
|
@ -432,6 +452,11 @@ static int dp_init(struct dm_io_request *io_req, struct dpages *dp)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DM_IO_VMA:
|
case DM_IO_VMA:
|
||||||
|
flush_kernel_vmap_range(io_req->mem.ptr.vma, size);
|
||||||
|
if ((io_req->bi_rw & RW_MASK) == READ) {
|
||||||
|
dp->vma_invalidate_address = io_req->mem.ptr.vma;
|
||||||
|
dp->vma_invalidate_size = size;
|
||||||
|
}
|
||||||
vm_dp_init(dp, io_req->mem.ptr.vma);
|
vm_dp_init(dp, io_req->mem.ptr.vma);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -460,7 +485,7 @@ int dm_io(struct dm_io_request *io_req, unsigned num_regions,
|
||||||
int r;
|
int r;
|
||||||
struct dpages dp;
|
struct dpages dp;
|
||||||
|
|
||||||
r = dp_init(io_req, &dp);
|
r = dp_init(io_req, &dp, (unsigned long)where->count << SECTOR_SHIFT);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -807,6 +807,11 @@ static int parse_features(struct arg_set *as, struct multipath *m)
|
||||||
if (!argc)
|
if (!argc)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (argc > as->argc) {
|
||||||
|
ti->error = "not enough arguments for features";
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
param_name = shift(as);
|
param_name = shift(as);
|
||||||
argc--;
|
argc--;
|
||||||
|
|
|
@ -753,7 +753,7 @@ static int persistent_commit_merge(struct dm_exception_store *store,
|
||||||
for (i = 0; i < nr_merged; i++)
|
for (i = 0; i < nr_merged; i++)
|
||||||
clear_exception(ps, ps->current_committed - 1 - i);
|
clear_exception(ps, ps->current_committed - 1 - i);
|
||||||
|
|
||||||
r = area_io(ps, WRITE);
|
r = area_io(ps, WRITE_FLUSH_FUA);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@ static const char *_name = DM_NAME;
|
||||||
static unsigned int major = 0;
|
static unsigned int major = 0;
|
||||||
static unsigned int _major = 0;
|
static unsigned int _major = 0;
|
||||||
|
|
||||||
|
static DEFINE_IDR(_minor_idr);
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(_minor_lock);
|
static DEFINE_SPINLOCK(_minor_lock);
|
||||||
/*
|
/*
|
||||||
* For bio-based dm.
|
* For bio-based dm.
|
||||||
|
@ -313,6 +315,12 @@ static void __exit dm_exit(void)
|
||||||
|
|
||||||
while (i--)
|
while (i--)
|
||||||
_exits[i]();
|
_exits[i]();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should be empty by this point.
|
||||||
|
*/
|
||||||
|
idr_remove_all(&_minor_idr);
|
||||||
|
idr_destroy(&_minor_idr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1705,8 +1713,6 @@ static int dm_any_congested(void *congested_data, int bdi_bits)
|
||||||
/*-----------------------------------------------------------------
|
/*-----------------------------------------------------------------
|
||||||
* An IDR is used to keep track of allocated minor numbers.
|
* An IDR is used to keep track of allocated minor numbers.
|
||||||
*---------------------------------------------------------------*/
|
*---------------------------------------------------------------*/
|
||||||
static DEFINE_IDR(_minor_idr);
|
|
||||||
|
|
||||||
static void free_minor(int minor)
|
static void free_minor(int minor)
|
||||||
{
|
{
|
||||||
spin_lock(&_minor_lock);
|
spin_lock(&_minor_lock);
|
||||||
|
|
|
@ -256,8 +256,7 @@ config SGI_XP
|
||||||
|
|
||||||
config CS5535_MFGPT
|
config CS5535_MFGPT
|
||||||
tristate "CS5535/CS5536 Geode Multi-Function General Purpose Timer (MFGPT) support"
|
tristate "CS5535/CS5536 Geode Multi-Function General Purpose Timer (MFGPT) support"
|
||||||
depends on PCI
|
depends on PCI && X86 && MFD_CS5535
|
||||||
depends on X86
|
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
This driver provides access to MFGPT functionality for other
|
This driver provides access to MFGPT functionality for other
|
||||||
|
|
|
@ -74,7 +74,7 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
|
||||||
if (boarddata && gpio_is_valid(boarddata->cd_gpio)
|
if (boarddata && gpio_is_valid(boarddata->cd_gpio)
|
||||||
&& gpio_get_value(boarddata->cd_gpio))
|
&& gpio_get_value(boarddata->cd_gpio))
|
||||||
/* no card, if a valid gpio says so... */
|
/* no card, if a valid gpio says so... */
|
||||||
val &= SDHCI_CARD_PRESENT;
|
val &= ~SDHCI_CARD_PRESENT;
|
||||||
else
|
else
|
||||||
/* ... in all other cases assume card is present */
|
/* ... in all other cases assume card is present */
|
||||||
val |= SDHCI_CARD_PRESENT;
|
val |= SDHCI_CARD_PRESENT;
|
||||||
|
|
|
@ -753,20 +753,28 @@ jme_make_new_rx_buf(struct jme_adapter *jme, int i)
|
||||||
struct jme_ring *rxring = &(jme->rxring[0]);
|
struct jme_ring *rxring = &(jme->rxring[0]);
|
||||||
struct jme_buffer_info *rxbi = rxring->bufinf + i;
|
struct jme_buffer_info *rxbi = rxring->bufinf + i;
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
|
dma_addr_t mapping;
|
||||||
|
|
||||||
skb = netdev_alloc_skb(jme->dev,
|
skb = netdev_alloc_skb(jme->dev,
|
||||||
jme->dev->mtu + RX_EXTRA_LEN);
|
jme->dev->mtu + RX_EXTRA_LEN);
|
||||||
if (unlikely(!skb))
|
if (unlikely(!skb))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
mapping = pci_map_page(jme->pdev, virt_to_page(skb->data),
|
||||||
|
offset_in_page(skb->data), skb_tailroom(skb),
|
||||||
|
PCI_DMA_FROMDEVICE);
|
||||||
|
if (unlikely(pci_dma_mapping_error(jme->pdev, mapping))) {
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (likely(rxbi->mapping))
|
||||||
|
pci_unmap_page(jme->pdev, rxbi->mapping,
|
||||||
|
rxbi->len, PCI_DMA_FROMDEVICE);
|
||||||
|
|
||||||
rxbi->skb = skb;
|
rxbi->skb = skb;
|
||||||
rxbi->len = skb_tailroom(skb);
|
rxbi->len = skb_tailroom(skb);
|
||||||
rxbi->mapping = pci_map_page(jme->pdev,
|
rxbi->mapping = mapping;
|
||||||
virt_to_page(skb->data),
|
|
||||||
offset_in_page(skb->data),
|
|
||||||
rxbi->len,
|
|
||||||
PCI_DMA_FROMDEVICE);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -629,8 +629,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
|
||||||
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
|
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
|
||||||
else if (rxsp->status11 & AR_MichaelErr)
|
else if (rxsp->status11 & AR_MichaelErr)
|
||||||
rxs->rs_status |= ATH9K_RXERR_MIC;
|
rxs->rs_status |= ATH9K_RXERR_MIC;
|
||||||
|
else if (rxsp->status11 & AR_KeyMiss)
|
||||||
if (rxsp->status11 & AR_KeyMiss)
|
|
||||||
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
|
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -645,8 +645,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||||
rs->rs_status |= ATH9K_RXERR_DECRYPT;
|
rs->rs_status |= ATH9K_RXERR_DECRYPT;
|
||||||
else if (ads.ds_rxstatus8 & AR_MichaelErr)
|
else if (ads.ds_rxstatus8 & AR_MichaelErr)
|
||||||
rs->rs_status |= ATH9K_RXERR_MIC;
|
rs->rs_status |= ATH9K_RXERR_MIC;
|
||||||
|
else if (ads.ds_rxstatus8 & AR_KeyMiss)
|
||||||
if (ads.ds_rxstatus8 & AR_KeyMiss)
|
|
||||||
rs->rs_status |= ATH9K_RXERR_DECRYPT;
|
rs->rs_status |= ATH9K_RXERR_DECRYPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1158,6 +1158,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_RT2800PCI_RT53XX
|
#ifdef CONFIG_RT2800PCI_RT53XX
|
||||||
{ PCI_DEVICE(0x1814, 0x5390) },
|
{ PCI_DEVICE(0x1814, 0x5390) },
|
||||||
|
{ PCI_DEVICE(0x1814, 0x539f) },
|
||||||
#endif
|
#endif
|
||||||
{ 0, }
|
{ 0, }
|
||||||
};
|
};
|
||||||
|
|
|
@ -104,7 +104,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
|
||||||
tx_agc[RF90_PATH_A] = 0x10101010;
|
tx_agc[RF90_PATH_A] = 0x10101010;
|
||||||
tx_agc[RF90_PATH_B] = 0x10101010;
|
tx_agc[RF90_PATH_B] = 0x10101010;
|
||||||
} else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
|
} else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
|
||||||
TXHIGHPWRLEVEL_LEVEL1) {
|
TXHIGHPWRLEVEL_LEVEL2) {
|
||||||
tx_agc[RF90_PATH_A] = 0x00000000;
|
tx_agc[RF90_PATH_A] = 0x00000000;
|
||||||
tx_agc[RF90_PATH_B] = 0x00000000;
|
tx_agc[RF90_PATH_B] = 0x00000000;
|
||||||
} else{
|
} else{
|
||||||
|
|
|
@ -1905,7 +1905,7 @@ void pci_enable_ari(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
int pos;
|
int pos;
|
||||||
u32 cap;
|
u32 cap;
|
||||||
u16 ctrl;
|
u16 flags, ctrl;
|
||||||
struct pci_dev *bridge;
|
struct pci_dev *bridge;
|
||||||
|
|
||||||
if (!pci_is_pcie(dev) || dev->devfn)
|
if (!pci_is_pcie(dev) || dev->devfn)
|
||||||
|
@ -1923,6 +1923,11 @@ void pci_enable_ari(struct pci_dev *dev)
|
||||||
if (!pos)
|
if (!pos)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* ARI is a PCIe v2 feature */
|
||||||
|
pci_read_config_word(bridge, pos + PCI_EXP_FLAGS, &flags);
|
||||||
|
if ((flags & PCI_EXP_FLAGS_VERS) < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap);
|
pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap);
|
||||||
if (!(cap & PCI_EXP_DEVCAP2_ARI))
|
if (!(cap & PCI_EXP_DEVCAP2_ARI))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -2758,6 +2758,29 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev)
|
||||||
|
|
||||||
dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n");
|
dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n");
|
||||||
dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
|
dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RICOH 0xe823 SD/MMC card reader fails to recognize
|
||||||
|
* certain types of SD/MMC cards. Lowering the SD base
|
||||||
|
* clock frequency from 200Mhz to 50Mhz fixes this issue.
|
||||||
|
*
|
||||||
|
* 0x150 - SD2.0 mode enable for changing base clock
|
||||||
|
* frequency to 50Mhz
|
||||||
|
* 0xe1 - Base clock frequency
|
||||||
|
* 0x32 - 50Mhz new clock frequency
|
||||||
|
* 0xf9 - Key register for 0x150
|
||||||
|
* 0xfc - key register for 0xe1
|
||||||
|
*/
|
||||||
|
if (dev->device == PCI_DEVICE_ID_RICOH_R5CE823) {
|
||||||
|
pci_write_config_byte(dev, 0xf9, 0xfc);
|
||||||
|
pci_write_config_byte(dev, 0x150, 0x10);
|
||||||
|
pci_write_config_byte(dev, 0xf9, 0x00);
|
||||||
|
pci_write_config_byte(dev, 0xfc, 0x01);
|
||||||
|
pci_write_config_byte(dev, 0xe1, 0x32);
|
||||||
|
pci_write_config_byte(dev, 0xfc, 0x00);
|
||||||
|
|
||||||
|
dev_notice(&dev->dev, "MMC controller base frequency changed to 50Mhz.\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
|
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
|
||||||
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
|
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
|
||||||
|
|
|
@ -636,6 +636,29 @@ void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rtc_irq_unregister);
|
EXPORT_SYMBOL_GPL(rtc_irq_unregister);
|
||||||
|
|
||||||
|
static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* We unconditionally cancel the timer here, because otherwise
|
||||||
|
* we could run into BUG_ON(timer->state != HRTIMER_STATE_CALLBACK);
|
||||||
|
* when we manage to start the timer before the callback
|
||||||
|
* returns HRTIMER_RESTART.
|
||||||
|
*
|
||||||
|
* We cannot use hrtimer_cancel() here as a running callback
|
||||||
|
* could be blocked on rtc->irq_task_lock and hrtimer_cancel()
|
||||||
|
* would spin forever.
|
||||||
|
*/
|
||||||
|
if (hrtimer_try_to_cancel(&rtc->pie_timer) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
ktime_t period = ktime_set(0, NSEC_PER_SEC / rtc->irq_freq);
|
||||||
|
|
||||||
|
hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rtc_irq_set_state - enable/disable 2^N Hz periodic IRQs
|
* rtc_irq_set_state - enable/disable 2^N Hz periodic IRQs
|
||||||
* @rtc: the rtc device
|
* @rtc: the rtc device
|
||||||
|
@ -651,21 +674,21 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled
|
||||||
int err = 0;
|
int err = 0;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
retry:
|
||||||
spin_lock_irqsave(&rtc->irq_task_lock, flags);
|
spin_lock_irqsave(&rtc->irq_task_lock, flags);
|
||||||
if (rtc->irq_task != NULL && task == NULL)
|
if (rtc->irq_task != NULL && task == NULL)
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
if (rtc->irq_task != task)
|
if (rtc->irq_task != task)
|
||||||
err = -EACCES;
|
err = -EACCES;
|
||||||
|
if (!err) {
|
||||||
if (enabled) {
|
if (rtc_update_hrtimer(rtc, enabled) < 0) {
|
||||||
ktime_t period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq);
|
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
|
||||||
hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL);
|
cpu_relax();
|
||||||
} else {
|
goto retry;
|
||||||
hrtimer_cancel(&rtc->pie_timer);
|
|
||||||
}
|
}
|
||||||
rtc->pie_enabled = enabled;
|
rtc->pie_enabled = enabled;
|
||||||
|
}
|
||||||
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
|
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(rtc_irq_set_state);
|
EXPORT_SYMBOL_GPL(rtc_irq_set_state);
|
||||||
|
@ -685,22 +708,20 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
|
||||||
int err = 0;
|
int err = 0;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (freq <= 0)
|
if (freq <= 0 || freq > 5000)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
retry:
|
||||||
spin_lock_irqsave(&rtc->irq_task_lock, flags);
|
spin_lock_irqsave(&rtc->irq_task_lock, flags);
|
||||||
if (rtc->irq_task != NULL && task == NULL)
|
if (rtc->irq_task != NULL && task == NULL)
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
if (rtc->irq_task != task)
|
if (rtc->irq_task != task)
|
||||||
err = -EACCES;
|
err = -EACCES;
|
||||||
if (err == 0) {
|
if (!err) {
|
||||||
rtc->irq_freq = freq;
|
rtc->irq_freq = freq;
|
||||||
if (rtc->pie_enabled) {
|
if (rtc->pie_enabled && rtc_update_hrtimer(rtc, 1) < 0) {
|
||||||
ktime_t period;
|
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
|
||||||
hrtimer_cancel(&rtc->pie_timer);
|
cpu_relax();
|
||||||
period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq);
|
goto retry;
|
||||||
hrtimer_start(&rtc->pie_timer, period,
|
|
||||||
HRTIMER_MODE_REL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
|
spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
|
||||||
|
|
|
@ -343,7 +343,7 @@ static int __devinit tegra_rtc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
/* set context info. */
|
/* set context info. */
|
||||||
info->pdev = pdev;
|
info->pdev = pdev;
|
||||||
info->tegra_rtc_lock = __SPIN_LOCK_UNLOCKED(info->tegra_rtc_lock);
|
spin_lock_init(&info->tegra_rtc_lock);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, info);
|
platform_set_drvdata(pdev, info);
|
||||||
|
|
||||||
|
|
|
@ -214,7 +214,7 @@ static void SA5_submit_command(struct ctlr_info *h,
|
||||||
dev_dbg(&h->pdev->dev, "Sending %x, tag = %x\n", c->busaddr,
|
dev_dbg(&h->pdev->dev, "Sending %x, tag = %x\n", c->busaddr,
|
||||||
c->Header.Tag.lower);
|
c->Header.Tag.lower);
|
||||||
writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
|
writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
|
||||||
(void) readl(h->vaddr + SA5_REQUEST_PORT_OFFSET);
|
(void) readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
|
||||||
h->commands_outstanding++;
|
h->commands_outstanding++;
|
||||||
if (h->commands_outstanding > h->max_outstanding)
|
if (h->commands_outstanding > h->max_outstanding)
|
||||||
h->max_outstanding = h->commands_outstanding;
|
h->max_outstanding = h->commands_outstanding;
|
||||||
|
|
|
@ -849,6 +849,9 @@ static struct domain_device *sas_ex_discover_expander(
|
||||||
|
|
||||||
res = sas_discover_expander(child);
|
res = sas_discover_expander(child);
|
||||||
if (res) {
|
if (res) {
|
||||||
|
spin_lock_irq(&parent->port->dev_list_lock);
|
||||||
|
list_del(&child->dev_list_node);
|
||||||
|
spin_unlock_irq(&parent->port->dev_list_lock);
|
||||||
kfree(child);
|
kfree(child);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3871,6 +3871,9 @@ static long pmcraid_ioctl_passthrough(
|
||||||
pmcraid_err("couldn't build passthrough ioadls\n");
|
pmcraid_err("couldn't build passthrough ioadls\n");
|
||||||
goto out_free_buffer;
|
goto out_free_buffer;
|
||||||
}
|
}
|
||||||
|
} else if (request_size < 0) {
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto out_free_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If data is being written into the device, copy the data from user
|
/* If data is being written into the device, copy the data from user
|
||||||
|
|
|
@ -197,6 +197,7 @@ static struct {
|
||||||
{"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
|
{"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
|
||||||
{"IBM", "2105", NULL, BLIST_RETRY_HWERROR},
|
{"IBM", "2105", NULL, BLIST_RETRY_HWERROR},
|
||||||
{"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
|
{"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN},
|
||||||
|
{"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN},
|
||||||
{"IOMEGA", "Io20S *F", NULL, BLIST_KEY},
|
{"IOMEGA", "Io20S *F", NULL, BLIST_KEY},
|
||||||
{"INSITE", "Floptical F*8I", NULL, BLIST_KEY},
|
{"INSITE", "Floptical F*8I", NULL, BLIST_KEY},
|
||||||
{"INSITE", "I325VM", NULL, BLIST_KEY},
|
{"INSITE", "I325VM", NULL, BLIST_KEY},
|
||||||
|
@ -243,6 +244,7 @@ static struct {
|
||||||
{"Tornado-", "F4", "*", BLIST_NOREPORTLUN},
|
{"Tornado-", "F4", "*", BLIST_NOREPORTLUN},
|
||||||
{"TOSHIBA", "CDROM", NULL, BLIST_ISROM},
|
{"TOSHIBA", "CDROM", NULL, BLIST_ISROM},
|
||||||
{"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM},
|
{"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM},
|
||||||
|
{"Traxdata", "CDR4120", NULL, BLIST_NOLUN}, /* locks up */
|
||||||
{"USB2.0", "SMARTMEDIA/XD", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36},
|
{"USB2.0", "SMARTMEDIA/XD", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36},
|
||||||
{"WangDAT", "Model 2600", "01.7", BLIST_SELECT_NO_ATN},
|
{"WangDAT", "Model 2600", "01.7", BLIST_SELECT_NO_ATN},
|
||||||
{"WangDAT", "Model 3200", "02.2", BLIST_SELECT_NO_ATN},
|
{"WangDAT", "Model 3200", "02.2", BLIST_SELECT_NO_ATN},
|
||||||
|
|
|
@ -213,6 +213,8 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
|
||||||
int ret = DRIVER_ERROR << 24;
|
int ret = DRIVER_ERROR << 24;
|
||||||
|
|
||||||
req = blk_get_request(sdev->request_queue, write, __GFP_WAIT);
|
req = blk_get_request(sdev->request_queue, write, __GFP_WAIT);
|
||||||
|
if (!req)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (bufflen && blk_rq_map_kern(sdev->request_queue, req,
|
if (bufflen && blk_rq_map_kern(sdev->request_queue, req,
|
||||||
buffer, bufflen, __GFP_WAIT))
|
buffer, bufflen, __GFP_WAIT))
|
||||||
|
|
|
@ -160,6 +160,10 @@ static unsigned char *ses_get_page2_descriptor(struct enclosure_device *edev,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For device slot and array device slot elements, byte 3 bit 6
|
||||||
|
* is "fault sensed" while byte 3 bit 5 is "fault reqstd". As this
|
||||||
|
* code stands these bits are shifted 4 positions right so in
|
||||||
|
* sysfs they will appear as bits 2 and 1 respectively. Strange. */
|
||||||
static void ses_get_fault(struct enclosure_device *edev,
|
static void ses_get_fault(struct enclosure_device *edev,
|
||||||
struct enclosure_component *ecomp)
|
struct enclosure_component *ecomp)
|
||||||
{
|
{
|
||||||
|
@ -181,7 +185,7 @@ static int ses_set_fault(struct enclosure_device *edev,
|
||||||
/* zero is disabled */
|
/* zero is disabled */
|
||||||
break;
|
break;
|
||||||
case ENCLOSURE_SETTING_ENABLED:
|
case ENCLOSURE_SETTING_ENABLED:
|
||||||
desc[2] = 0x02;
|
desc[3] = 0x20;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* SES doesn't do the SGPIO blink settings */
|
/* SES doesn't do the SGPIO blink settings */
|
||||||
|
|
|
@ -221,14 +221,33 @@ static unsigned int sr_check_events(struct cdrom_device_info *cdi,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
events = sr_get_events(cd->device);
|
events = sr_get_events(cd->device);
|
||||||
|
cd->get_event_changed |= events & DISK_EVENT_MEDIA_CHANGE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If earlier GET_EVENT_STATUS_NOTIFICATION and TUR did not agree
|
||||||
|
* for several times in a row. We rely on TUR only for this likely
|
||||||
|
* broken device, to prevent generating incorrect media changed
|
||||||
|
* events for every open().
|
||||||
|
*/
|
||||||
|
if (cd->ignore_get_event) {
|
||||||
|
events &= ~DISK_EVENT_MEDIA_CHANGE;
|
||||||
|
goto do_tur;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GET_EVENT_STATUS_NOTIFICATION is enough unless MEDIA_CHANGE
|
* GET_EVENT_STATUS_NOTIFICATION is enough unless MEDIA_CHANGE
|
||||||
* is being cleared. Note that there are devices which hang
|
* is being cleared. Note that there are devices which hang
|
||||||
* if asked to execute TUR repeatedly.
|
* if asked to execute TUR repeatedly.
|
||||||
*/
|
*/
|
||||||
if (!(clearing & DISK_EVENT_MEDIA_CHANGE))
|
if (cd->device->changed) {
|
||||||
goto skip_tur;
|
events |= DISK_EVENT_MEDIA_CHANGE;
|
||||||
|
cd->device->changed = 0;
|
||||||
|
cd->tur_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(clearing & DISK_EVENT_MEDIA_CHANGE))
|
||||||
|
return events;
|
||||||
|
do_tur:
|
||||||
/* let's see whether the media is there with TUR */
|
/* let's see whether the media is there with TUR */
|
||||||
last_present = cd->media_present;
|
last_present = cd->media_present;
|
||||||
ret = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr);
|
ret = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr);
|
||||||
|
@ -242,13 +261,32 @@ static unsigned int sr_check_events(struct cdrom_device_info *cdi,
|
||||||
(scsi_sense_valid(&sshdr) && sshdr.asc != 0x3a);
|
(scsi_sense_valid(&sshdr) && sshdr.asc != 0x3a);
|
||||||
|
|
||||||
if (last_present != cd->media_present)
|
if (last_present != cd->media_present)
|
||||||
events |= DISK_EVENT_MEDIA_CHANGE;
|
cd->device->changed = 1;
|
||||||
skip_tur:
|
|
||||||
if (cd->device->changed) {
|
if (cd->device->changed) {
|
||||||
events |= DISK_EVENT_MEDIA_CHANGE;
|
events |= DISK_EVENT_MEDIA_CHANGE;
|
||||||
cd->device->changed = 0;
|
cd->device->changed = 0;
|
||||||
|
cd->tur_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cd->ignore_get_event)
|
||||||
|
return events;
|
||||||
|
|
||||||
|
/* check whether GET_EVENT is reporting spurious MEDIA_CHANGE */
|
||||||
|
if (!cd->tur_changed) {
|
||||||
|
if (cd->get_event_changed) {
|
||||||
|
if (cd->tur_mismatch++ > 8) {
|
||||||
|
sdev_printk(KERN_WARNING, cd->device,
|
||||||
|
"GET_EVENT and TUR disagree continuously, suppress GET_EVENT events\n");
|
||||||
|
cd->ignore_get_event = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cd->tur_mismatch = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cd->tur_changed = false;
|
||||||
|
cd->get_event_changed = false;
|
||||||
|
|
||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,13 @@ typedef struct scsi_cd {
|
||||||
unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */
|
unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */
|
||||||
unsigned readcd_cdda:1; /* reading audio data using READ_CD */
|
unsigned readcd_cdda:1; /* reading audio data using READ_CD */
|
||||||
unsigned media_present:1; /* media is present */
|
unsigned media_present:1; /* media is present */
|
||||||
|
|
||||||
|
/* GET_EVENT spurious event handling, blk layer guarantees exclusion */
|
||||||
|
int tur_mismatch; /* nr of get_event TUR mismatches */
|
||||||
|
bool tur_changed:1; /* changed according to TUR */
|
||||||
|
bool get_event_changed:1; /* changed according to GET_EVENT */
|
||||||
|
bool ignore_get_event:1; /* GET_EVENT is unreliable, use TUR */
|
||||||
|
|
||||||
struct cdrom_device_info cdi;
|
struct cdrom_device_info cdi;
|
||||||
/* We hold gendisk and scsi_device references on probe and use
|
/* We hold gendisk and scsi_device references on probe and use
|
||||||
* the refs on this kref to decide when to release them */
|
* the refs on this kref to decide when to release them */
|
||||||
|
|
|
@ -954,9 +954,13 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address,
|
||||||
const char *filename;
|
const char *filename;
|
||||||
const struct firmware *fw_entry;
|
const struct firmware *fw_entry;
|
||||||
u32 fw_entry_size;
|
u32 fw_entry_size;
|
||||||
|
u8 **buf;
|
||||||
|
size_t *buf_len;
|
||||||
|
|
||||||
switch (file) {
|
switch (file) {
|
||||||
case AR6K_OTP_FILE:
|
case AR6K_OTP_FILE:
|
||||||
|
buf = &ar->fw_otp;
|
||||||
|
buf_len = &ar->fw_otp_len;
|
||||||
if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
|
if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
|
||||||
filename = AR6003_REV1_OTP_FILE;
|
filename = AR6003_REV1_OTP_FILE;
|
||||||
} else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
|
} else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
|
||||||
|
@ -970,6 +974,8 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AR6K_FIRMWARE_FILE:
|
case AR6K_FIRMWARE_FILE:
|
||||||
|
buf = &ar->fw;
|
||||||
|
buf_len = &ar->fw_len;
|
||||||
if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
|
if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
|
||||||
filename = AR6003_REV1_FIRMWARE_FILE;
|
filename = AR6003_REV1_FIRMWARE_FILE;
|
||||||
} else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
|
} else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
|
||||||
|
@ -1028,6 +1034,8 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AR6K_PATCH_FILE:
|
case AR6K_PATCH_FILE:
|
||||||
|
buf = &ar->fw_patch;
|
||||||
|
buf_len = &ar->fw_patch_len;
|
||||||
if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
|
if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
|
||||||
filename = AR6003_REV1_PATCH_FILE;
|
filename = AR6003_REV1_PATCH_FILE;
|
||||||
} else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
|
} else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
|
||||||
|
@ -1041,6 +1049,8 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AR6K_BOARD_DATA_FILE:
|
case AR6K_BOARD_DATA_FILE:
|
||||||
|
buf = &ar->fw_data;
|
||||||
|
buf_len = &ar->fw_data_len;
|
||||||
if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
|
if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
|
||||||
filename = AR6003_REV1_BOARD_DATA_FILE;
|
filename = AR6003_REV1_BOARD_DATA_FILE;
|
||||||
} else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
|
} else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
|
||||||
|
@ -1057,23 +1067,29 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address,
|
||||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown file type: %d\n", file));
|
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown file type: %d\n", file));
|
||||||
return A_ERROR;
|
return A_ERROR;
|
||||||
}
|
}
|
||||||
if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0)
|
|
||||||
{
|
if (*buf == NULL) {
|
||||||
|
if ((A_REQUEST_FIRMWARE(&fw_entry, filename, ((struct device *)ar->osDevInfo.pOSDevice))) != 0) {
|
||||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename));
|
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to get %s\n", filename));
|
||||||
return A_ENOENT;
|
return A_ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*buf = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
|
||||||
|
*buf_len = fw_entry->size;
|
||||||
|
A_RELEASE_FIRMWARE(fw_entry);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SOFTMAC_FILE_USED
|
#ifdef SOFTMAC_FILE_USED
|
||||||
if (file==AR6K_BOARD_DATA_FILE && fw_entry->data) {
|
if (file==AR6K_BOARD_DATA_FILE && *buf_len) {
|
||||||
ar6000_softmac_update(ar, (u8 *)fw_entry->data, fw_entry->size);
|
ar6000_softmac_update(ar, *buf, *buf_len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
fw_entry_size = fw_entry->size;
|
fw_entry_size = *buf_len;
|
||||||
|
|
||||||
/* Load extended board data for AR6003 */
|
/* Load extended board data for AR6003 */
|
||||||
if ((file==AR6K_BOARD_DATA_FILE) && (fw_entry->data)) {
|
if ((file==AR6K_BOARD_DATA_FILE) && *buf) {
|
||||||
u32 board_ext_address;
|
u32 board_ext_address;
|
||||||
u32 board_ext_data_size;
|
u32 board_ext_data_size;
|
||||||
u32 board_data_size;
|
u32 board_data_size;
|
||||||
|
@ -1089,14 +1105,13 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address,
|
||||||
AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board extended Data download address: 0x%x\n", board_ext_address));
|
AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board extended Data download address: 0x%x\n", board_ext_address));
|
||||||
|
|
||||||
/* check whether the target has allocated memory for extended board data and file contains extended board data */
|
/* check whether the target has allocated memory for extended board data and file contains extended board data */
|
||||||
if ((board_ext_address) && (fw_entry->size == (board_data_size + board_ext_data_size))) {
|
if ((board_ext_address) && (*buf_len == (board_data_size + board_ext_data_size))) {
|
||||||
u32 param;
|
u32 param;
|
||||||
|
|
||||||
status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(fw_entry->data + board_data_size), board_ext_data_size);
|
status = BMIWriteMemory(ar->arHifDevice, board_ext_address, (u8 *)(*buf + board_data_size), board_ext_data_size);
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
|
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
|
||||||
A_RELEASE_FIRMWARE(fw_entry);
|
|
||||||
return A_ERROR;
|
return A_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1110,17 +1125,16 @@ ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compressed) {
|
if (compressed) {
|
||||||
status = BMIFastDownload(ar->arHifDevice, address, (u8 *)fw_entry->data, fw_entry_size);
|
status = BMIFastDownload(ar->arHifDevice, address, *buf, fw_entry_size);
|
||||||
} else {
|
} else {
|
||||||
status = BMIWriteMemory(ar->arHifDevice, address, (u8 *)fw_entry->data, fw_entry_size);
|
status = BMIWriteMemory(ar->arHifDevice, address, *buf, fw_entry_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
|
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__));
|
||||||
A_RELEASE_FIRMWARE(fw_entry);
|
|
||||||
return A_ERROR;
|
return A_ERROR;
|
||||||
}
|
}
|
||||||
A_RELEASE_FIRMWARE(fw_entry);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2088,6 +2102,11 @@ ar6000_destroy(struct net_device *dev, unsigned int unregister)
|
||||||
ar6000_remove_ap_interface();
|
ar6000_remove_ap_interface();
|
||||||
#endif /*CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
|
#endif /*CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
|
||||||
|
|
||||||
|
kfree(ar->fw_otp);
|
||||||
|
kfree(ar->fw);
|
||||||
|
kfree(ar->fw_patch);
|
||||||
|
kfree(ar->fw_data);
|
||||||
|
|
||||||
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("-ar6000_destroy \n"));
|
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("-ar6000_destroy \n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -867,14 +867,18 @@ ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status)
|
||||||
|
|
||||||
AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status));
|
AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status));
|
||||||
|
|
||||||
if(ar->scan_request)
|
if (!ar->scan_request)
|
||||||
{
|
return;
|
||||||
|
|
||||||
|
if ((status == A_ECANCELED) || (status == A_EBUSY)) {
|
||||||
|
cfg80211_scan_done(ar->scan_request, true);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* Translate data to cfg80211 mgmt format */
|
/* Translate data to cfg80211 mgmt format */
|
||||||
if (ar->arWmi)
|
|
||||||
wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
|
wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
|
||||||
|
|
||||||
cfg80211_scan_done(ar->scan_request,
|
cfg80211_scan_done(ar->scan_request, false);
|
||||||
((status & A_ECANCELED) || (status & A_EBUSY)) ? true : false);
|
|
||||||
|
|
||||||
if(ar->scan_request->n_ssids &&
|
if(ar->scan_request->n_ssids &&
|
||||||
ar->scan_request->ssids[0].ssid_len) {
|
ar->scan_request->ssids[0].ssid_len) {
|
||||||
|
@ -885,8 +889,9 @@ ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status)
|
||||||
0, NULL);
|
0, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
ar->scan_request = NULL;
|
ar->scan_request = NULL;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -651,6 +651,15 @@ struct ar6_softc {
|
||||||
void *arApDev;
|
void *arApDev;
|
||||||
#endif
|
#endif
|
||||||
u8 arAutoAuthStage;
|
u8 arAutoAuthStage;
|
||||||
|
|
||||||
|
u8 *fw_otp;
|
||||||
|
size_t fw_otp_len;
|
||||||
|
u8 *fw;
|
||||||
|
size_t fw_len;
|
||||||
|
u8 *fw_patch;
|
||||||
|
size_t fw_patch_len;
|
||||||
|
u8 *fw_data;
|
||||||
|
size_t fw_data_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
|
#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
|
||||||
|
|
|
@ -449,11 +449,6 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw,
|
||||||
wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__,
|
wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__,
|
||||||
info->qos ? "true" : "false");
|
info->qos ? "true" : "false");
|
||||||
}
|
}
|
||||||
if (changed & BSS_CHANGED_IDLE) {
|
|
||||||
/* Idle changed for this BSS/interface */
|
|
||||||
wiphy_err(wiphy, "%s: BSS idle: %s (implement)\n", __func__,
|
|
||||||
info->idle ? "true" : "false");
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -383,8 +383,8 @@ static int do_devinfo_ioctl(struct comedi_device *dev,
|
||||||
/* fill devinfo structure */
|
/* fill devinfo structure */
|
||||||
devinfo.version_code = COMEDI_VERSION_CODE;
|
devinfo.version_code = COMEDI_VERSION_CODE;
|
||||||
devinfo.n_subdevs = dev->n_subdevices;
|
devinfo.n_subdevs = dev->n_subdevices;
|
||||||
memcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN);
|
strlcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN);
|
||||||
memcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN);
|
strlcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN);
|
||||||
|
|
||||||
if (read_subdev)
|
if (read_subdev)
|
||||||
devinfo.read_subdevice = read_subdev - dev->subdevices;
|
devinfo.read_subdevice = read_subdev - dev->subdevices;
|
||||||
|
|
|
@ -212,7 +212,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
|
|
||||||
t = wait_for_completion_timeout(&openInfo->waitevent, HZ);
|
t = wait_for_completion_timeout(&openInfo->waitevent, 5*HZ);
|
||||||
if (t == 0) {
|
if (t == 0) {
|
||||||
err = -ETIMEDOUT;
|
err = -ETIMEDOUT;
|
||||||
goto errorout;
|
goto errorout;
|
||||||
|
|
|
@ -773,7 +773,7 @@ int vmbus_request_offers(void)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = wait_for_completion_timeout(&msginfo->waitevent, HZ);
|
t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ);
|
||||||
if (t == 0) {
|
if (t == 0) {
|
||||||
ret = -ETIMEDOUT;
|
ret = -ETIMEDOUT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
|
@ -135,7 +135,7 @@ int vmbus_connect(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for the connection response */
|
/* Wait for the connection response */
|
||||||
t = wait_for_completion_timeout(&msginfo->waitevent, HZ);
|
t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ);
|
||||||
if (t == 0) {
|
if (t == 0) {
|
||||||
spin_lock_irqsave(&vmbus_connection.channelmsg_lock,
|
spin_lock_irqsave(&vmbus_connection.channelmsg_lock,
|
||||||
flags);
|
flags);
|
||||||
|
|
|
@ -270,7 +270,7 @@ static int netvsc_init_recv_buf(struct hv_device *device)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
t = wait_for_completion_timeout(&net_device->channel_init_wait, HZ);
|
t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
|
||||||
BUG_ON(t == 0);
|
BUG_ON(t == 0);
|
||||||
|
|
||||||
|
|
||||||
|
@ -513,7 +513,7 @@ static int netvsc_connect_vsp(struct hv_device *device)
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
t = wait_for_completion_timeout(&net_device->channel_init_wait, HZ);
|
t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
|
||||||
|
|
||||||
if (t == 0) {
|
if (t == 0) {
|
||||||
ret = -ETIMEDOUT;
|
ret = -ETIMEDOUT;
|
||||||
|
|
|
@ -467,7 +467,7 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
|
|
||||||
t = wait_for_completion_timeout(&request->wait_event, HZ);
|
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
|
||||||
if (t == 0) {
|
if (t == 0) {
|
||||||
ret = -ETIMEDOUT;
|
ret = -ETIMEDOUT;
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
|
@ -543,7 +543,7 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev,
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
|
|
||||||
t = wait_for_completion_timeout(&request->wait_event, HZ);
|
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
|
||||||
|
|
||||||
if (t == 0) {
|
if (t == 0) {
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
@ -600,7 +600,7 @@ static int rndis_filter_init_device(struct rndis_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
t = wait_for_completion_timeout(&request->wait_event, HZ);
|
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
|
||||||
|
|
||||||
if (t == 0) {
|
if (t == 0) {
|
||||||
ret = -ETIMEDOUT;
|
ret = -ETIMEDOUT;
|
||||||
|
|
|
@ -135,7 +135,7 @@ static int storvsc_channel_init(struct hv_device *device)
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
t = wait_for_completion_timeout(&request->wait_event, HZ);
|
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
|
||||||
if (t == 0) {
|
if (t == 0) {
|
||||||
ret = -ETIMEDOUT;
|
ret = -ETIMEDOUT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -163,7 +163,7 @@ static int storvsc_channel_init(struct hv_device *device)
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
t = wait_for_completion_timeout(&request->wait_event, HZ);
|
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
|
||||||
if (t == 0) {
|
if (t == 0) {
|
||||||
ret = -ETIMEDOUT;
|
ret = -ETIMEDOUT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -192,7 +192,7 @@ static int storvsc_channel_init(struct hv_device *device)
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
t = wait_for_completion_timeout(&request->wait_event, HZ);
|
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
|
||||||
if (t == 0) {
|
if (t == 0) {
|
||||||
ret = -ETIMEDOUT;
|
ret = -ETIMEDOUT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
@ -222,7 +222,7 @@ static int storvsc_channel_init(struct hv_device *device)
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
t = wait_for_completion_timeout(&request->wait_event, HZ);
|
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
|
||||||
if (t == 0) {
|
if (t == 0) {
|
||||||
ret = -ETIMEDOUT;
|
ret = -ETIMEDOUT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
|
@ -393,7 +393,7 @@ static int storvsc_host_reset(struct hv_device *device)
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
t = wait_for_completion_timeout(&request->wait_event, HZ);
|
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
|
||||||
if (t == 0) {
|
if (t == 0) {
|
||||||
ret = -ETIMEDOUT;
|
ret = -ETIMEDOUT;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
|
@ -4532,6 +4532,7 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
|
||||||
u8 unit = 0;
|
u8 unit = 0;
|
||||||
int ret = -ENODEV;
|
int ret = -ENODEV;
|
||||||
unsigned long pmem_start, pmem_len, pmem_flags;
|
unsigned long pmem_start, pmem_len, pmem_flags;
|
||||||
|
u8 revisionid;
|
||||||
|
|
||||||
RT_TRACE(COMP_INIT,"Configuring chip resources\n");
|
RT_TRACE(COMP_INIT,"Configuring chip resources\n");
|
||||||
|
|
||||||
|
@ -4592,6 +4593,11 @@ static int __devinit rtl8192_pci_probe(struct pci_dev *pdev,
|
||||||
pci_write_config_byte(pdev, 0x41, 0x00);
|
pci_write_config_byte(pdev, 0x41, 0x00);
|
||||||
|
|
||||||
|
|
||||||
|
pci_read_config_byte(pdev, 0x08, &revisionid);
|
||||||
|
/* If the revisionid is 0x10, the device uses rtl8192se. */
|
||||||
|
if (pdev->device == 0x8192 && revisionid == 0x10)
|
||||||
|
goto fail1;
|
||||||
|
|
||||||
pci_read_config_byte(pdev, 0x05, &unit);
|
pci_read_config_byte(pdev, 0x05, &unit);
|
||||||
pci_write_config_byte(pdev, 0x05, unit & (~0x04));
|
pci_write_config_byte(pdev, 0x05, unit & (~0x04));
|
||||||
|
|
||||||
|
|
|
@ -846,9 +846,9 @@ static void vhci_shutdown_connection(struct usbip_device *ud)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* kill threads related to this sdev, if v.c. exists */
|
/* kill threads related to this sdev, if v.c. exists */
|
||||||
if (vdev->ud.tcp_rx)
|
if (vdev->ud.tcp_rx && !task_is_dead(vdev->ud.tcp_rx))
|
||||||
kthread_stop(vdev->ud.tcp_rx);
|
kthread_stop(vdev->ud.tcp_rx);
|
||||||
if (vdev->ud.tcp_tx)
|
if (vdev->ud.tcp_tx && !task_is_dead(vdev->ud.tcp_tx))
|
||||||
kthread_stop(vdev->ud.tcp_tx);
|
kthread_stop(vdev->ud.tcp_tx);
|
||||||
|
|
||||||
pr_info("stop threads\n");
|
pr_info("stop threads\n");
|
||||||
|
|
|
@ -163,7 +163,9 @@ static void hvc_console_print(struct console *co, const char *b,
|
||||||
} else {
|
} else {
|
||||||
r = cons_ops[index]->put_chars(vtermnos[index], c, i);
|
r = cons_ops[index]->put_chars(vtermnos[index], c, i);
|
||||||
if (r <= 0) {
|
if (r <= 0) {
|
||||||
/* throw away chars on error */
|
/* throw away characters on error
|
||||||
|
* but spin in case of -EAGAIN */
|
||||||
|
if (r != -EAGAIN)
|
||||||
i = 0;
|
i = 0;
|
||||||
} else if (r > 0) {
|
} else if (r > 0) {
|
||||||
i -= r;
|
i -= r;
|
||||||
|
@ -448,7 +450,7 @@ static int hvc_push(struct hvc_struct *hp)
|
||||||
|
|
||||||
n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
|
n = hp->ops->put_chars(hp->vtermno, hp->outbuf, hp->n_outbuf);
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
if (n == 0) {
|
if (n == 0 || n == -EAGAIN) {
|
||||||
hp->do_wakeup = 1;
|
hp->do_wakeup = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1823,10 +1823,6 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
|
||||||
break;
|
break;
|
||||||
case GSM_FCS: /* FCS follows the packet */
|
case GSM_FCS: /* FCS follows the packet */
|
||||||
gsm->received_fcs = c;
|
gsm->received_fcs = c;
|
||||||
if (c == GSM0_SOF) {
|
|
||||||
gsm->state = GSM_SEARCH;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
gsm_queue(gsm);
|
gsm_queue(gsm);
|
||||||
gsm->state = GSM_SSOF;
|
gsm->state = GSM_SSOF;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1107,7 +1107,7 @@ static void autoconfig_16550a(struct uart_8250_port *up)
|
||||||
*/
|
*/
|
||||||
DEBUG_AUTOCONF("Xscale ");
|
DEBUG_AUTOCONF("Xscale ");
|
||||||
up->port.type = PORT_XSCALE;
|
up->port.type = PORT_XSCALE;
|
||||||
up->capabilities |= UART_CAP_UUE;
|
up->capabilities |= UART_CAP_UUE | UART_CAP_RTOIE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1419,7 +1419,7 @@ config SERIAL_SC26XX
|
||||||
|
|
||||||
config SERIAL_SC26XX_CONSOLE
|
config SERIAL_SC26XX_CONSOLE
|
||||||
bool "Console on SC2681/SC2692 serial port"
|
bool "Console on SC2681/SC2692 serial port"
|
||||||
depends on SERIAL_SC26XX
|
depends on SERIAL_SC26XX=y
|
||||||
select SERIAL_CORE_CONSOLE
|
select SERIAL_CORE_CONSOLE
|
||||||
help
|
help
|
||||||
Support for Console on SC2681/SC2692 serial ports.
|
Support for Console on SC2681/SC2692 serial ports.
|
||||||
|
|
|
@ -94,7 +94,8 @@ static const char hcd_name [] = "ehci_hcd";
|
||||||
#define EHCI_IAA_MSECS 10 /* arbitrary */
|
#define EHCI_IAA_MSECS 10 /* arbitrary */
|
||||||
#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */
|
#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */
|
||||||
#define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */
|
#define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */
|
||||||
#define EHCI_SHRINK_FRAMES 5 /* async qh unlink delay */
|
#define EHCI_SHRINK_JIFFIES (DIV_ROUND_UP(HZ, 200) + 1)
|
||||||
|
/* 200-ms async qh unlink delay */
|
||||||
|
|
||||||
/* Initial IRQ latency: faster than hw default */
|
/* Initial IRQ latency: faster than hw default */
|
||||||
static int log2_irq_thresh = 0; // 0 to 6
|
static int log2_irq_thresh = 0; // 0 to 6
|
||||||
|
@ -152,10 +153,7 @@ timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action)
|
||||||
break;
|
break;
|
||||||
/* case TIMER_ASYNC_SHRINK: */
|
/* case TIMER_ASYNC_SHRINK: */
|
||||||
default:
|
default:
|
||||||
/* add a jiffie since we synch against the
|
t = EHCI_SHRINK_JIFFIES;
|
||||||
* 8 KHz uframe counter.
|
|
||||||
*/
|
|
||||||
t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mod_timer(&ehci->watchdog, t + jiffies);
|
mod_timer(&ehci->watchdog, t + jiffies);
|
||||||
|
|
|
@ -891,10 +891,11 @@ static int ehci_hub_control (
|
||||||
* power switching; they're allowed to just limit the
|
* power switching; they're allowed to just limit the
|
||||||
* current. khubd will turn the power back on.
|
* current. khubd will turn the power back on.
|
||||||
*/
|
*/
|
||||||
if (HCS_PPC (ehci->hcs_params)){
|
if ((temp & PORT_OC) && HCS_PPC(ehci->hcs_params)) {
|
||||||
ehci_writel(ehci,
|
ehci_writel(ehci,
|
||||||
temp & ~(PORT_RWC_BITS | PORT_POWER),
|
temp & ~(PORT_RWC_BITS | PORT_POWER),
|
||||||
status_reg);
|
status_reg);
|
||||||
|
temp = ehci_readl(ehci, status_reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
|
||||||
if (!(hw->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) {
|
if (!(hw->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) {
|
||||||
unsigned is_out, epnum;
|
unsigned is_out, epnum;
|
||||||
|
|
||||||
is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8));
|
is_out = qh->is_out;
|
||||||
epnum = (hc32_to_cpup(ehci, &hw->hw_info1) >> 8) & 0x0f;
|
epnum = (hc32_to_cpup(ehci, &hw->hw_info1) >> 8) & 0x0f;
|
||||||
if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
|
if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
|
||||||
hw->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
|
hw->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
|
||||||
|
@ -946,6 +946,7 @@ done:
|
||||||
hw = qh->hw;
|
hw = qh->hw;
|
||||||
hw->hw_info1 = cpu_to_hc32(ehci, info1);
|
hw->hw_info1 = cpu_to_hc32(ehci, info1);
|
||||||
hw->hw_info2 = cpu_to_hc32(ehci, info2);
|
hw->hw_info2 = cpu_to_hc32(ehci, info2);
|
||||||
|
qh->is_out = !is_input;
|
||||||
usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
|
usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
|
||||||
qh_refresh (ehci, qh);
|
qh_refresh (ehci, qh);
|
||||||
return qh;
|
return qh;
|
||||||
|
@ -1231,6 +1232,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
|
||||||
|
|
||||||
prev->hw->hw_next = qh->hw->hw_next;
|
prev->hw->hw_next = qh->hw->hw_next;
|
||||||
prev->qh_next = qh->qh_next;
|
prev->qh_next = qh->qh_next;
|
||||||
|
if (ehci->qh_scan_next == qh)
|
||||||
|
ehci->qh_scan_next = qh->qh_next.qh;
|
||||||
wmb ();
|
wmb ();
|
||||||
|
|
||||||
/* If the controller isn't running, we don't have to wait for it */
|
/* If the controller isn't running, we don't have to wait for it */
|
||||||
|
@ -1256,34 +1259,34 @@ static void scan_async (struct ehci_hcd *ehci)
|
||||||
struct ehci_qh *qh;
|
struct ehci_qh *qh;
|
||||||
enum ehci_timer_action action = TIMER_IO_WATCHDOG;
|
enum ehci_timer_action action = TIMER_IO_WATCHDOG;
|
||||||
|
|
||||||
ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index);
|
|
||||||
timer_action_done (ehci, TIMER_ASYNC_SHRINK);
|
timer_action_done (ehci, TIMER_ASYNC_SHRINK);
|
||||||
rescan:
|
|
||||||
stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state);
|
stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state);
|
||||||
qh = ehci->async->qh_next.qh;
|
|
||||||
if (likely (qh != NULL)) {
|
ehci->qh_scan_next = ehci->async->qh_next.qh;
|
||||||
do {
|
while (ehci->qh_scan_next) {
|
||||||
|
qh = ehci->qh_scan_next;
|
||||||
|
ehci->qh_scan_next = qh->qh_next.qh;
|
||||||
|
rescan:
|
||||||
/* clean any finished work for this qh */
|
/* clean any finished work for this qh */
|
||||||
if (!list_empty(&qh->qtd_list) && (stopped ||
|
if (!list_empty(&qh->qtd_list)) {
|
||||||
qh->stamp != ehci->stamp)) {
|
|
||||||
int temp;
|
int temp;
|
||||||
|
|
||||||
/* unlinks could happen here; completion
|
/*
|
||||||
* reporting drops the lock. rescan using
|
* Unlinks could happen here; completion reporting
|
||||||
* the latest schedule, but don't rescan
|
* drops the lock. That's why ehci->qh_scan_next
|
||||||
* qhs we already finished (no looping)
|
* always holds the next qh to scan; if the next qh
|
||||||
* unless the controller is stopped.
|
* gets unlinked then ehci->qh_scan_next is adjusted
|
||||||
|
* in start_unlink_async().
|
||||||
*/
|
*/
|
||||||
qh = qh_get (qh);
|
qh = qh_get(qh);
|
||||||
qh->stamp = ehci->stamp;
|
temp = qh_completions(ehci, qh);
|
||||||
temp = qh_completions (ehci, qh);
|
|
||||||
if (qh->needs_rescan)
|
if (qh->needs_rescan)
|
||||||
unlink_async(ehci, qh);
|
unlink_async(ehci, qh);
|
||||||
qh_put (qh);
|
qh->unlink_time = jiffies + EHCI_SHRINK_JIFFIES;
|
||||||
if (temp != 0) {
|
qh_put(qh);
|
||||||
|
if (temp != 0)
|
||||||
goto rescan;
|
goto rescan;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* unlink idle entries, reducing DMA usage as well
|
/* unlink idle entries, reducing DMA usage as well
|
||||||
* as HCD schedule-scanning costs. delay for any qh
|
* as HCD schedule-scanning costs. delay for any qh
|
||||||
|
@ -1294,15 +1297,11 @@ rescan:
|
||||||
if (list_empty(&qh->qtd_list)
|
if (list_empty(&qh->qtd_list)
|
||||||
&& qh->qh_state == QH_STATE_LINKED) {
|
&& qh->qh_state == QH_STATE_LINKED) {
|
||||||
if (!ehci->reclaim && (stopped ||
|
if (!ehci->reclaim && (stopped ||
|
||||||
((ehci->stamp - qh->stamp) & 0x1fff)
|
time_after_eq(jiffies, qh->unlink_time)))
|
||||||
>= EHCI_SHRINK_FRAMES * 8))
|
|
||||||
start_unlink_async(ehci, qh);
|
start_unlink_async(ehci, qh);
|
||||||
else
|
else
|
||||||
action = TIMER_ASYNC_SHRINK;
|
action = TIMER_ASYNC_SHRINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
qh = qh->qh_next.qh;
|
|
||||||
} while (qh);
|
|
||||||
}
|
}
|
||||||
if (action == TIMER_ASYNC_SHRINK)
|
if (action == TIMER_ASYNC_SHRINK)
|
||||||
timer_action (ehci, TIMER_ASYNC_SHRINK);
|
timer_action (ehci, TIMER_ASYNC_SHRINK);
|
||||||
|
|
|
@ -75,6 +75,7 @@ struct ehci_hcd { /* one per controller */
|
||||||
struct ehci_qh *async;
|
struct ehci_qh *async;
|
||||||
struct ehci_qh *dummy; /* For AMD quirk use */
|
struct ehci_qh *dummy; /* For AMD quirk use */
|
||||||
struct ehci_qh *reclaim;
|
struct ehci_qh *reclaim;
|
||||||
|
struct ehci_qh *qh_scan_next;
|
||||||
unsigned scanning : 1;
|
unsigned scanning : 1;
|
||||||
|
|
||||||
/* periodic schedule support */
|
/* periodic schedule support */
|
||||||
|
@ -117,7 +118,6 @@ struct ehci_hcd { /* one per controller */
|
||||||
struct timer_list iaa_watchdog;
|
struct timer_list iaa_watchdog;
|
||||||
struct timer_list watchdog;
|
struct timer_list watchdog;
|
||||||
unsigned long actions;
|
unsigned long actions;
|
||||||
unsigned stamp;
|
|
||||||
unsigned periodic_stamp;
|
unsigned periodic_stamp;
|
||||||
unsigned random_frame;
|
unsigned random_frame;
|
||||||
unsigned long next_statechange;
|
unsigned long next_statechange;
|
||||||
|
@ -343,6 +343,7 @@ struct ehci_qh {
|
||||||
struct ehci_qh *reclaim; /* next to reclaim */
|
struct ehci_qh *reclaim; /* next to reclaim */
|
||||||
|
|
||||||
struct ehci_hcd *ehci;
|
struct ehci_hcd *ehci;
|
||||||
|
unsigned long unlink_time;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do NOT use atomic operations for QH refcounting. On some CPUs
|
* Do NOT use atomic operations for QH refcounting. On some CPUs
|
||||||
|
@ -374,6 +375,7 @@ struct ehci_qh {
|
||||||
#define NO_FRAME ((unsigned short)~0) /* pick new start */
|
#define NO_FRAME ((unsigned short)~0) /* pick new start */
|
||||||
|
|
||||||
struct usb_device *dev; /* access to TT */
|
struct usb_device *dev; /* access to TT */
|
||||||
|
unsigned is_out:1; /* bulk or intr OUT */
|
||||||
unsigned clearing_tt:1; /* Clear-TT-Buf in progress */
|
unsigned clearing_tt:1; /* Clear-TT-Buf in progress */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#define OHCI_INTRSTATUS 0x0c
|
#define OHCI_INTRSTATUS 0x0c
|
||||||
#define OHCI_INTRENABLE 0x10
|
#define OHCI_INTRENABLE 0x10
|
||||||
#define OHCI_INTRDISABLE 0x14
|
#define OHCI_INTRDISABLE 0x14
|
||||||
|
#define OHCI_FMINTERVAL 0x34
|
||||||
|
#define OHCI_HCR (1 << 0) /* host controller reset */
|
||||||
#define OHCI_OCR (1 << 3) /* ownership change request */
|
#define OHCI_OCR (1 << 3) /* ownership change request */
|
||||||
#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
|
#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
|
||||||
#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
|
#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */
|
||||||
|
@ -497,6 +499,32 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
|
||||||
|
|
||||||
/* reset controller, preserving RWC (and possibly IR) */
|
/* reset controller, preserving RWC (and possibly IR) */
|
||||||
writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL);
|
writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL);
|
||||||
|
readl(base + OHCI_CONTROL);
|
||||||
|
|
||||||
|
/* Some NVIDIA controllers stop working if kept in RESET for too long */
|
||||||
|
if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) {
|
||||||
|
u32 fminterval;
|
||||||
|
int cnt;
|
||||||
|
|
||||||
|
/* drive reset for at least 50 ms (7.1.7.5) */
|
||||||
|
msleep(50);
|
||||||
|
|
||||||
|
/* software reset of the controller, preserving HcFmInterval */
|
||||||
|
fminterval = readl(base + OHCI_FMINTERVAL);
|
||||||
|
writel(OHCI_HCR, base + OHCI_CMDSTATUS);
|
||||||
|
|
||||||
|
/* reset requires max 10 us delay */
|
||||||
|
for (cnt = 30; cnt > 0; --cnt) { /* ... allow extra time */
|
||||||
|
if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0)
|
||||||
|
break;
|
||||||
|
udelay(1);
|
||||||
|
}
|
||||||
|
writel(fminterval, base + OHCI_FMINTERVAL);
|
||||||
|
|
||||||
|
/* Now we're in the SUSPEND state with all devices reset
|
||||||
|
* and wakeups and interrupts disabled
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* disable interrupts
|
* disable interrupts
|
||||||
|
|
|
@ -2329,6 +2329,7 @@ static void musb_restore_context(struct musb *musb)
|
||||||
musb->context.index_regs[i].rxhubport);
|
musb->context.index_regs[i].rxhubport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
musb_writeb(musb_base, MUSB_INDEX, musb->context.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int musb_suspend(struct device *dev)
|
static int musb_suspend(struct device *dev)
|
||||||
|
|
|
@ -91,6 +91,7 @@ static const struct usb_device_id id_table[] = {
|
||||||
{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
|
{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
|
||||||
{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
|
{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
|
||||||
{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
|
{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
|
||||||
|
{ USB_DEVICE(WINCHIPHEAD_VENDOR_ID, WINCHIPHEAD_USBSER_PRODUCT_ID) },
|
||||||
{ } /* Terminating entry */
|
{ } /* Terminating entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -144,3 +144,7 @@
|
||||||
/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */
|
/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */
|
||||||
#define ADLINK_VENDOR_ID 0x0b63
|
#define ADLINK_VENDOR_ID 0x0b63
|
||||||
#define ADLINK_ND6530_PRODUCT_ID 0x6530
|
#define ADLINK_ND6530_PRODUCT_ID 0x6530
|
||||||
|
|
||||||
|
/* WinChipHead USB->RS 232 adapter */
|
||||||
|
#define WINCHIPHEAD_VENDOR_ID 0x4348
|
||||||
|
#define WINCHIPHEAD_USBSER_PRODUCT_ID 0x5523
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
* misses its deadline, the kernel timer will allow the WDT to overflow.
|
* misses its deadline, the kernel timer will allow the WDT to overflow.
|
||||||
*/
|
*/
|
||||||
static int clock_division_ratio = WTCSR_CKS_4096;
|
static int clock_division_ratio = WTCSR_CKS_4096;
|
||||||
#define next_ping_period(cks) msecs_to_jiffies(cks - 4)
|
#define next_ping_period(cks) (jiffies + msecs_to_jiffies(cks - 4))
|
||||||
|
|
||||||
static const struct watchdog_info sh_wdt_info;
|
static const struct watchdog_info sh_wdt_info;
|
||||||
static struct platform_device *sh_wdt_dev;
|
static struct platform_device *sh_wdt_dev;
|
||||||
|
|
|
@ -641,7 +641,7 @@ lookup_out:
|
||||||
static int
|
static int
|
||||||
cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
|
cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
|
||||||
{
|
{
|
||||||
if (nd->flags & LOOKUP_RCU)
|
if (nd && (nd->flags & LOOKUP_RCU))
|
||||||
return -ECHILD;
|
return -ECHILD;
|
||||||
|
|
||||||
if (direntry->d_inode) {
|
if (direntry->d_inode) {
|
||||||
|
|
|
@ -69,6 +69,7 @@ static int ecryptfs_inode_set(struct inode *inode, void *opaque)
|
||||||
inode->i_ino = lower_inode->i_ino;
|
inode->i_ino = lower_inode->i_ino;
|
||||||
inode->i_version++;
|
inode->i_version++;
|
||||||
inode->i_mapping->a_ops = &ecryptfs_aops;
|
inode->i_mapping->a_ops = &ecryptfs_aops;
|
||||||
|
inode->i_mapping->backing_dev_info = inode->i_sb->s_bdi;
|
||||||
|
|
||||||
if (S_ISLNK(inode->i_mode))
|
if (S_ISLNK(inode->i_mode))
|
||||||
inode->i_op = &ecryptfs_symlink_iops;
|
inode->i_op = &ecryptfs_symlink_iops;
|
||||||
|
|
|
@ -1868,11 +1868,6 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
|
||||||
* just one will be sufficient to decrypt to get the FEK. */
|
* just one will be sufficient to decrypt to get the FEK. */
|
||||||
find_next_matching_auth_tok:
|
find_next_matching_auth_tok:
|
||||||
found_auth_tok = 0;
|
found_auth_tok = 0;
|
||||||
if (auth_tok_key) {
|
|
||||||
up_write(&(auth_tok_key->sem));
|
|
||||||
key_put(auth_tok_key);
|
|
||||||
auth_tok_key = NULL;
|
|
||||||
}
|
|
||||||
list_for_each_entry(auth_tok_list_item, &auth_tok_list, list) {
|
list_for_each_entry(auth_tok_list_item, &auth_tok_list, list) {
|
||||||
candidate_auth_tok = &auth_tok_list_item->auth_tok;
|
candidate_auth_tok = &auth_tok_list_item->auth_tok;
|
||||||
if (unlikely(ecryptfs_verbosity > 0)) {
|
if (unlikely(ecryptfs_verbosity > 0)) {
|
||||||
|
@ -1909,14 +1904,22 @@ found_matching_auth_tok:
|
||||||
memcpy(&(candidate_auth_tok->token.private_key),
|
memcpy(&(candidate_auth_tok->token.private_key),
|
||||||
&(matching_auth_tok->token.private_key),
|
&(matching_auth_tok->token.private_key),
|
||||||
sizeof(struct ecryptfs_private_key));
|
sizeof(struct ecryptfs_private_key));
|
||||||
|
up_write(&(auth_tok_key->sem));
|
||||||
|
key_put(auth_tok_key);
|
||||||
rc = decrypt_pki_encrypted_session_key(candidate_auth_tok,
|
rc = decrypt_pki_encrypted_session_key(candidate_auth_tok,
|
||||||
crypt_stat);
|
crypt_stat);
|
||||||
} else if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD) {
|
} else if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD) {
|
||||||
memcpy(&(candidate_auth_tok->token.password),
|
memcpy(&(candidate_auth_tok->token.password),
|
||||||
&(matching_auth_tok->token.password),
|
&(matching_auth_tok->token.password),
|
||||||
sizeof(struct ecryptfs_password));
|
sizeof(struct ecryptfs_password));
|
||||||
|
up_write(&(auth_tok_key->sem));
|
||||||
|
key_put(auth_tok_key);
|
||||||
rc = decrypt_passphrase_encrypted_session_key(
|
rc = decrypt_passphrase_encrypted_session_key(
|
||||||
candidate_auth_tok, crypt_stat);
|
candidate_auth_tok, crypt_stat);
|
||||||
|
} else {
|
||||||
|
up_write(&(auth_tok_key->sem));
|
||||||
|
key_put(auth_tok_key);
|
||||||
|
rc = -EINVAL;
|
||||||
}
|
}
|
||||||
if (rc) {
|
if (rc) {
|
||||||
struct ecryptfs_auth_tok_list_item *auth_tok_list_item_tmp;
|
struct ecryptfs_auth_tok_list_item *auth_tok_list_item_tmp;
|
||||||
|
@ -1956,15 +1959,12 @@ found_matching_auth_tok:
|
||||||
out_wipe_list:
|
out_wipe_list:
|
||||||
wipe_auth_tok_list(&auth_tok_list);
|
wipe_auth_tok_list(&auth_tok_list);
|
||||||
out:
|
out:
|
||||||
if (auth_tok_key) {
|
|
||||||
up_write(&(auth_tok_key->sem));
|
|
||||||
key_put(auth_tok_key);
|
|
||||||
}
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
|
pki_encrypt_session_key(struct key *auth_tok_key,
|
||||||
|
struct ecryptfs_auth_tok *auth_tok,
|
||||||
struct ecryptfs_crypt_stat *crypt_stat,
|
struct ecryptfs_crypt_stat *crypt_stat,
|
||||||
struct ecryptfs_key_record *key_rec)
|
struct ecryptfs_key_record *key_rec)
|
||||||
{
|
{
|
||||||
|
@ -1979,6 +1979,8 @@ pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
|
||||||
crypt_stat->cipher,
|
crypt_stat->cipher,
|
||||||
crypt_stat->key_size),
|
crypt_stat->key_size),
|
||||||
crypt_stat, &payload, &payload_len);
|
crypt_stat, &payload, &payload_len);
|
||||||
|
up_write(&(auth_tok_key->sem));
|
||||||
|
key_put(auth_tok_key);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n");
|
ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n");
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -2008,6 +2010,8 @@ out:
|
||||||
* write_tag_1_packet - Write an RFC2440-compatible tag 1 (public key) packet
|
* write_tag_1_packet - Write an RFC2440-compatible tag 1 (public key) packet
|
||||||
* @dest: Buffer into which to write the packet
|
* @dest: Buffer into which to write the packet
|
||||||
* @remaining_bytes: Maximum number of bytes that can be writtn
|
* @remaining_bytes: Maximum number of bytes that can be writtn
|
||||||
|
* @auth_tok_key: The authentication token key to unlock and put when done with
|
||||||
|
* @auth_tok
|
||||||
* @auth_tok: The authentication token used for generating the tag 1 packet
|
* @auth_tok: The authentication token used for generating the tag 1 packet
|
||||||
* @crypt_stat: The cryptographic context
|
* @crypt_stat: The cryptographic context
|
||||||
* @key_rec: The key record struct for the tag 1 packet
|
* @key_rec: The key record struct for the tag 1 packet
|
||||||
|
@ -2018,7 +2022,7 @@ out:
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
write_tag_1_packet(char *dest, size_t *remaining_bytes,
|
write_tag_1_packet(char *dest, size_t *remaining_bytes,
|
||||||
struct ecryptfs_auth_tok *auth_tok,
|
struct key *auth_tok_key, struct ecryptfs_auth_tok *auth_tok,
|
||||||
struct ecryptfs_crypt_stat *crypt_stat,
|
struct ecryptfs_crypt_stat *crypt_stat,
|
||||||
struct ecryptfs_key_record *key_rec, size_t *packet_size)
|
struct ecryptfs_key_record *key_rec, size_t *packet_size)
|
||||||
{
|
{
|
||||||
|
@ -2039,12 +2043,15 @@ write_tag_1_packet(char *dest, size_t *remaining_bytes,
|
||||||
memcpy(key_rec->enc_key,
|
memcpy(key_rec->enc_key,
|
||||||
auth_tok->session_key.encrypted_key,
|
auth_tok->session_key.encrypted_key,
|
||||||
auth_tok->session_key.encrypted_key_size);
|
auth_tok->session_key.encrypted_key_size);
|
||||||
|
up_write(&(auth_tok_key->sem));
|
||||||
|
key_put(auth_tok_key);
|
||||||
goto encrypted_session_key_set;
|
goto encrypted_session_key_set;
|
||||||
}
|
}
|
||||||
if (auth_tok->session_key.encrypted_key_size == 0)
|
if (auth_tok->session_key.encrypted_key_size == 0)
|
||||||
auth_tok->session_key.encrypted_key_size =
|
auth_tok->session_key.encrypted_key_size =
|
||||||
auth_tok->token.private_key.key_size;
|
auth_tok->token.private_key.key_size;
|
||||||
rc = pki_encrypt_session_key(auth_tok, crypt_stat, key_rec);
|
rc = pki_encrypt_session_key(auth_tok_key, auth_tok, crypt_stat,
|
||||||
|
key_rec);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printk(KERN_ERR "Failed to encrypt session key via a key "
|
printk(KERN_ERR "Failed to encrypt session key via a key "
|
||||||
"module; rc = [%d]\n", rc);
|
"module; rc = [%d]\n", rc);
|
||||||
|
@ -2421,6 +2428,8 @@ ecryptfs_generate_key_packet_set(char *dest_base,
|
||||||
&max, auth_tok,
|
&max, auth_tok,
|
||||||
crypt_stat, key_rec,
|
crypt_stat, key_rec,
|
||||||
&written);
|
&written);
|
||||||
|
up_write(&(auth_tok_key->sem));
|
||||||
|
key_put(auth_tok_key);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
ecryptfs_printk(KERN_WARNING, "Error "
|
ecryptfs_printk(KERN_WARNING, "Error "
|
||||||
"writing tag 3 packet\n");
|
"writing tag 3 packet\n");
|
||||||
|
@ -2438,8 +2447,8 @@ ecryptfs_generate_key_packet_set(char *dest_base,
|
||||||
}
|
}
|
||||||
(*len) += written;
|
(*len) += written;
|
||||||
} else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) {
|
} else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) {
|
||||||
rc = write_tag_1_packet(dest_base + (*len),
|
rc = write_tag_1_packet(dest_base + (*len), &max,
|
||||||
&max, auth_tok,
|
auth_tok_key, auth_tok,
|
||||||
crypt_stat, key_rec, &written);
|
crypt_stat, key_rec, &written);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
ecryptfs_printk(KERN_WARNING, "Error "
|
ecryptfs_printk(KERN_WARNING, "Error "
|
||||||
|
@ -2448,14 +2457,13 @@ ecryptfs_generate_key_packet_set(char *dest_base,
|
||||||
}
|
}
|
||||||
(*len) += written;
|
(*len) += written;
|
||||||
} else {
|
} else {
|
||||||
|
up_write(&(auth_tok_key->sem));
|
||||||
|
key_put(auth_tok_key);
|
||||||
ecryptfs_printk(KERN_WARNING, "Unsupported "
|
ecryptfs_printk(KERN_WARNING, "Unsupported "
|
||||||
"authentication token type\n");
|
"authentication token type\n");
|
||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
up_write(&(auth_tok_key->sem));
|
|
||||||
key_put(auth_tok_key);
|
|
||||||
auth_tok_key = NULL;
|
|
||||||
}
|
}
|
||||||
if (likely(max > 0)) {
|
if (likely(max > 0)) {
|
||||||
dest_base[(*len)] = 0x00;
|
dest_base[(*len)] = 0x00;
|
||||||
|
@ -2468,11 +2476,6 @@ out_free:
|
||||||
out:
|
out:
|
||||||
if (rc)
|
if (rc)
|
||||||
(*len) = 0;
|
(*len) = 0;
|
||||||
if (auth_tok_key) {
|
|
||||||
up_write(&(auth_tok_key->sem));
|
|
||||||
key_put(auth_tok_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_unlock(&crypt_stat->keysig_list_mutex);
|
mutex_unlock(&crypt_stat->keysig_list_mutex);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -803,8 +803,16 @@ inserted:
|
||||||
/* We need to allocate a new block */
|
/* We need to allocate a new block */
|
||||||
ext3_fsblk_t goal = ext3_group_first_block_no(sb,
|
ext3_fsblk_t goal = ext3_group_first_block_no(sb,
|
||||||
EXT3_I(inode)->i_block_group);
|
EXT3_I(inode)->i_block_group);
|
||||||
ext3_fsblk_t block = ext3_new_block(handle, inode,
|
ext3_fsblk_t block;
|
||||||
goal, &error);
|
|
||||||
|
/*
|
||||||
|
* Protect us agaist concurrent allocations to the
|
||||||
|
* same inode from ext3_..._writepage(). Reservation
|
||||||
|
* code does not expect racing allocations.
|
||||||
|
*/
|
||||||
|
mutex_lock(&EXT3_I(inode)->truncate_mutex);
|
||||||
|
block = ext3_new_block(handle, inode, goal, &error);
|
||||||
|
mutex_unlock(&EXT3_I(inode)->truncate_mutex);
|
||||||
if (error)
|
if (error)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
ea_idebug(inode, "creating block %d", block);
|
ea_idebug(inode, "creating block %d", block);
|
||||||
|
|
|
@ -526,6 +526,7 @@ struct ext4_new_group_data {
|
||||||
#define EXT4_FREE_BLOCKS_METADATA 0x0001
|
#define EXT4_FREE_BLOCKS_METADATA 0x0001
|
||||||
#define EXT4_FREE_BLOCKS_FORGET 0x0002
|
#define EXT4_FREE_BLOCKS_FORGET 0x0002
|
||||||
#define EXT4_FREE_BLOCKS_VALIDATED 0x0004
|
#define EXT4_FREE_BLOCKS_VALIDATED 0x0004
|
||||||
|
#define EXT4_FREE_BLOCKS_NO_QUOT_UPDATE 0x0008
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ioctl commands
|
* ioctl commands
|
||||||
|
|
|
@ -3596,17 +3596,18 @@ int ext4_ext_map_blocks(handle_t *handle, struct inode *inode,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = check_eofblocks_fl(handle, inode, map->m_lblk, path, ar.len);
|
err = check_eofblocks_fl(handle, inode, map->m_lblk, path, ar.len);
|
||||||
if (err)
|
if (!err)
|
||||||
goto out2;
|
err = ext4_ext_insert_extent(handle, inode, path,
|
||||||
|
&newex, flags);
|
||||||
err = ext4_ext_insert_extent(handle, inode, path, &newex, flags);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
|
int fb_flags = flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE ?
|
||||||
|
EXT4_FREE_BLOCKS_NO_QUOT_UPDATE : 0;
|
||||||
/* free data blocks we just allocated */
|
/* free data blocks we just allocated */
|
||||||
/* not a good idea to call discard here directly,
|
/* not a good idea to call discard here directly,
|
||||||
* but otherwise we'd need to call it every free() */
|
* but otherwise we'd need to call it every free() */
|
||||||
ext4_discard_preallocations(inode);
|
ext4_discard_preallocations(inode);
|
||||||
ext4_free_blocks(handle, inode, NULL, ext4_ext_pblock(&newex),
|
ext4_free_blocks(handle, inode, NULL, ext4_ext_pblock(&newex),
|
||||||
ext4_ext_get_actual_len(&newex), 0);
|
ext4_ext_get_actual_len(&newex), fb_flags);
|
||||||
goto out2;
|
goto out2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4637,7 +4637,7 @@ do_more:
|
||||||
}
|
}
|
||||||
ext4_mark_super_dirty(sb);
|
ext4_mark_super_dirty(sb);
|
||||||
error_return:
|
error_return:
|
||||||
if (freed)
|
if (freed && !(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE))
|
||||||
dquot_free_block(inode, freed);
|
dquot_free_block(inode, freed);
|
||||||
brelse(bitmap_bh);
|
brelse(bitmap_bh);
|
||||||
ext4_std_error(sb, err);
|
ext4_std_error(sb, err);
|
||||||
|
|
|
@ -1018,13 +1018,13 @@ hostdata_error:
|
||||||
fsname++;
|
fsname++;
|
||||||
if (lm->lm_mount == NULL) {
|
if (lm->lm_mount == NULL) {
|
||||||
fs_info(sdp, "Now mounting FS...\n");
|
fs_info(sdp, "Now mounting FS...\n");
|
||||||
complete(&sdp->sd_locking_init);
|
complete_all(&sdp->sd_locking_init);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ret = lm->lm_mount(sdp, fsname);
|
ret = lm->lm_mount(sdp, fsname);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
fs_info(sdp, "Joined cluster. Now mounting FS...\n");
|
fs_info(sdp, "Joined cluster. Now mounting FS...\n");
|
||||||
complete(&sdp->sd_locking_init);
|
complete_all(&sdp->sd_locking_init);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -398,12 +398,11 @@ int nfs_inode_return_delegation(struct inode *inode)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nfs_mark_return_delegation(struct nfs_delegation *delegation)
|
static void nfs_mark_return_delegation(struct nfs_server *server,
|
||||||
|
struct nfs_delegation *delegation)
|
||||||
{
|
{
|
||||||
struct nfs_client *clp = NFS_SERVER(delegation->inode)->nfs_client;
|
|
||||||
|
|
||||||
set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
|
set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
|
||||||
set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
|
set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -441,7 +440,7 @@ static void nfs_mark_return_all_delegation_types(struct nfs_server *server,
|
||||||
if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE))
|
if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE))
|
||||||
continue;
|
continue;
|
||||||
if (delegation->type & flags)
|
if (delegation->type & flags)
|
||||||
nfs_mark_return_delegation(delegation);
|
nfs_mark_return_delegation(server, delegation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +507,7 @@ static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server)
|
||||||
list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
|
list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
|
||||||
if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
|
if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
|
||||||
continue;
|
continue;
|
||||||
nfs_mark_return_delegation(delegation);
|
nfs_mark_return_delegation(server, delegation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,7 +538,8 @@ void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
|
||||||
int nfs_async_inode_return_delegation(struct inode *inode,
|
int nfs_async_inode_return_delegation(struct inode *inode,
|
||||||
const nfs4_stateid *stateid)
|
const nfs4_stateid *stateid)
|
||||||
{
|
{
|
||||||
struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
|
struct nfs_server *server = NFS_SERVER(inode);
|
||||||
|
struct nfs_client *clp = server->nfs_client;
|
||||||
struct nfs_delegation *delegation;
|
struct nfs_delegation *delegation;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
|
@ -549,7 +549,7 @@ int nfs_async_inode_return_delegation(struct inode *inode,
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
nfs_mark_return_delegation(delegation);
|
nfs_mark_return_delegation(server, delegation);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
nfs_delegation_run_state_manager(clp);
|
nfs_delegation_run_state_manager(clp);
|
||||||
|
|
54
fs/nfs/dir.c
54
fs/nfs/dir.c
|
@ -134,18 +134,19 @@ const struct inode_operations nfs4_dir_inode_operations = {
|
||||||
|
|
||||||
#endif /* CONFIG_NFS_V4 */
|
#endif /* CONFIG_NFS_V4 */
|
||||||
|
|
||||||
static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct rpc_cred *cred)
|
static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct inode *dir, struct rpc_cred *cred)
|
||||||
{
|
{
|
||||||
struct nfs_open_dir_context *ctx;
|
struct nfs_open_dir_context *ctx;
|
||||||
ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
|
ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
|
||||||
if (ctx != NULL) {
|
if (ctx != NULL) {
|
||||||
ctx->duped = 0;
|
ctx->duped = 0;
|
||||||
|
ctx->attr_gencount = NFS_I(dir)->attr_gencount;
|
||||||
ctx->dir_cookie = 0;
|
ctx->dir_cookie = 0;
|
||||||
ctx->dup_cookie = 0;
|
ctx->dup_cookie = 0;
|
||||||
ctx->cred = get_rpccred(cred);
|
ctx->cred = get_rpccred(cred);
|
||||||
} else
|
|
||||||
ctx = ERR_PTR(-ENOMEM);
|
|
||||||
return ctx;
|
return ctx;
|
||||||
|
}
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void put_nfs_open_dir_context(struct nfs_open_dir_context *ctx)
|
static void put_nfs_open_dir_context(struct nfs_open_dir_context *ctx)
|
||||||
|
@ -173,7 +174,7 @@ nfs_opendir(struct inode *inode, struct file *filp)
|
||||||
cred = rpc_lookup_cred();
|
cred = rpc_lookup_cred();
|
||||||
if (IS_ERR(cred))
|
if (IS_ERR(cred))
|
||||||
return PTR_ERR(cred);
|
return PTR_ERR(cred);
|
||||||
ctx = alloc_nfs_open_dir_context(cred);
|
ctx = alloc_nfs_open_dir_context(inode, cred);
|
||||||
if (IS_ERR(ctx)) {
|
if (IS_ERR(ctx)) {
|
||||||
res = PTR_ERR(ctx);
|
res = PTR_ERR(ctx);
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -323,7 +324,6 @@ int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descri
|
||||||
{
|
{
|
||||||
loff_t diff = desc->file->f_pos - desc->current_index;
|
loff_t diff = desc->file->f_pos - desc->current_index;
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
struct nfs_open_dir_context *ctx = desc->file->private_data;
|
|
||||||
|
|
||||||
if (diff < 0)
|
if (diff < 0)
|
||||||
goto out_eof;
|
goto out_eof;
|
||||||
|
@ -336,7 +336,6 @@ int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descri
|
||||||
index = (unsigned int)diff;
|
index = (unsigned int)diff;
|
||||||
*desc->dir_cookie = array->array[index].cookie;
|
*desc->dir_cookie = array->array[index].cookie;
|
||||||
desc->cache_entry_index = index;
|
desc->cache_entry_index = index;
|
||||||
ctx->duped = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
out_eof:
|
out_eof:
|
||||||
desc->eof = 1;
|
desc->eof = 1;
|
||||||
|
@ -349,14 +348,33 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
|
||||||
int i;
|
int i;
|
||||||
loff_t new_pos;
|
loff_t new_pos;
|
||||||
int status = -EAGAIN;
|
int status = -EAGAIN;
|
||||||
struct nfs_open_dir_context *ctx = desc->file->private_data;
|
|
||||||
|
|
||||||
for (i = 0; i < array->size; i++) {
|
for (i = 0; i < array->size; i++) {
|
||||||
if (array->array[i].cookie == *desc->dir_cookie) {
|
if (array->array[i].cookie == *desc->dir_cookie) {
|
||||||
|
struct nfs_inode *nfsi = NFS_I(desc->file->f_path.dentry->d_inode);
|
||||||
|
struct nfs_open_dir_context *ctx = desc->file->private_data;
|
||||||
|
|
||||||
new_pos = desc->current_index + i;
|
new_pos = desc->current_index + i;
|
||||||
if (new_pos < desc->file->f_pos) {
|
if (ctx->attr_gencount != nfsi->attr_gencount
|
||||||
|
|| (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))) {
|
||||||
|
ctx->duped = 0;
|
||||||
|
ctx->attr_gencount = nfsi->attr_gencount;
|
||||||
|
} else if (new_pos < desc->file->f_pos) {
|
||||||
|
if (ctx->duped > 0
|
||||||
|
&& ctx->dup_cookie == *desc->dir_cookie) {
|
||||||
|
if (printk_ratelimit()) {
|
||||||
|
pr_notice("NFS: directory %s/%s contains a readdir loop."
|
||||||
|
"Please contact your server vendor. "
|
||||||
|
"Offending cookie: %llu\n",
|
||||||
|
desc->file->f_dentry->d_parent->d_name.name,
|
||||||
|
desc->file->f_dentry->d_name.name,
|
||||||
|
*desc->dir_cookie);
|
||||||
|
}
|
||||||
|
status = -ELOOP;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
ctx->dup_cookie = *desc->dir_cookie;
|
ctx->dup_cookie = *desc->dir_cookie;
|
||||||
ctx->duped = 1;
|
ctx->duped = -1;
|
||||||
}
|
}
|
||||||
desc->file->f_pos = new_pos;
|
desc->file->f_pos = new_pos;
|
||||||
desc->cache_entry_index = i;
|
desc->cache_entry_index = i;
|
||||||
|
@ -368,6 +386,7 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
|
||||||
if (*desc->dir_cookie == array->last_cookie)
|
if (*desc->dir_cookie == array->last_cookie)
|
||||||
desc->eof = 1;
|
desc->eof = 1;
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,19 +759,6 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
|
||||||
struct nfs_cache_array *array = NULL;
|
struct nfs_cache_array *array = NULL;
|
||||||
struct nfs_open_dir_context *ctx = file->private_data;
|
struct nfs_open_dir_context *ctx = file->private_data;
|
||||||
|
|
||||||
if (ctx->duped != 0 && ctx->dup_cookie == *desc->dir_cookie) {
|
|
||||||
if (printk_ratelimit()) {
|
|
||||||
pr_notice("NFS: directory %s/%s contains a readdir loop. "
|
|
||||||
"Please contact your server vendor. "
|
|
||||||
"Offending cookie: %llu\n",
|
|
||||||
file->f_dentry->d_parent->d_name.name,
|
|
||||||
file->f_dentry->d_name.name,
|
|
||||||
*desc->dir_cookie);
|
|
||||||
}
|
|
||||||
res = -ELOOP;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
array = nfs_readdir_get_array(desc->page);
|
array = nfs_readdir_get_array(desc->page);
|
||||||
if (IS_ERR(array)) {
|
if (IS_ERR(array)) {
|
||||||
res = PTR_ERR(array);
|
res = PTR_ERR(array);
|
||||||
|
@ -774,6 +780,8 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
|
||||||
*desc->dir_cookie = array->array[i+1].cookie;
|
*desc->dir_cookie = array->array[i+1].cookie;
|
||||||
else
|
else
|
||||||
*desc->dir_cookie = array->last_cookie;
|
*desc->dir_cookie = array->last_cookie;
|
||||||
|
if (ctx->duped != 0)
|
||||||
|
ctx->duped = 1;
|
||||||
}
|
}
|
||||||
if (array->eof_index >= 0)
|
if (array->eof_index >= 0)
|
||||||
desc->eof = 1;
|
desc->eof = 1;
|
||||||
|
@ -805,6 +813,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
|
||||||
struct page *page = NULL;
|
struct page *page = NULL;
|
||||||
int status;
|
int status;
|
||||||
struct inode *inode = desc->file->f_path.dentry->d_inode;
|
struct inode *inode = desc->file->f_path.dentry->d_inode;
|
||||||
|
struct nfs_open_dir_context *ctx = desc->file->private_data;
|
||||||
|
|
||||||
dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n",
|
dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n",
|
||||||
(unsigned long long)*desc->dir_cookie);
|
(unsigned long long)*desc->dir_cookie);
|
||||||
|
@ -818,6 +827,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
|
||||||
desc->page_index = 0;
|
desc->page_index = 0;
|
||||||
desc->last_cookie = *desc->dir_cookie;
|
desc->last_cookie = *desc->dir_cookie;
|
||||||
desc->page = page;
|
desc->page = page;
|
||||||
|
ctx->duped = 0;
|
||||||
|
|
||||||
status = nfs_readdir_xdr_to_array(desc, page, inode);
|
status = nfs_readdir_xdr_to_array(desc, page, inode);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
|
|
|
@ -170,7 +170,7 @@ filelayout_set_layoutcommit(struct nfs_write_data *wdata)
|
||||||
|
|
||||||
pnfs_set_layoutcommit(wdata);
|
pnfs_set_layoutcommit(wdata);
|
||||||
dprintk("%s ionde %lu pls_end_pos %lu\n", __func__, wdata->inode->i_ino,
|
dprintk("%s ionde %lu pls_end_pos %lu\n", __func__, wdata->inode->i_ino,
|
||||||
(unsigned long) wdata->lseg->pls_end_pos);
|
(unsigned long) NFS_I(wdata->inode)->layout->plh_lwb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -5850,9 +5850,15 @@ nfs4_layoutcommit_done(struct rpc_task *task, void *calldata)
|
||||||
static void nfs4_layoutcommit_release(void *calldata)
|
static void nfs4_layoutcommit_release(void *calldata)
|
||||||
{
|
{
|
||||||
struct nfs4_layoutcommit_data *data = calldata;
|
struct nfs4_layoutcommit_data *data = calldata;
|
||||||
|
struct pnfs_layout_segment *lseg, *tmp;
|
||||||
|
|
||||||
/* Matched by references in pnfs_set_layoutcommit */
|
/* Matched by references in pnfs_set_layoutcommit */
|
||||||
put_lseg(data->lseg);
|
list_for_each_entry_safe(lseg, tmp, &data->lseg_list, pls_lc_list) {
|
||||||
|
list_del_init(&lseg->pls_lc_list);
|
||||||
|
if (test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT,
|
||||||
|
&lseg->pls_flags))
|
||||||
|
put_lseg(lseg);
|
||||||
|
}
|
||||||
put_rpccred(data->cred);
|
put_rpccred(data->cred);
|
||||||
kfree(data);
|
kfree(data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1888,7 +1888,7 @@ encode_layoutcommit(struct xdr_stream *xdr,
|
||||||
*p++ = cpu_to_be32(OP_LAYOUTCOMMIT);
|
*p++ = cpu_to_be32(OP_LAYOUTCOMMIT);
|
||||||
/* Only whole file layouts */
|
/* Only whole file layouts */
|
||||||
p = xdr_encode_hyper(p, 0); /* offset */
|
p = xdr_encode_hyper(p, 0); /* offset */
|
||||||
p = xdr_encode_hyper(p, NFS4_MAX_UINT64); /* length */
|
p = xdr_encode_hyper(p, args->lastbytewritten + 1); /* length */
|
||||||
*p++ = cpu_to_be32(0); /* reclaim */
|
*p++ = cpu_to_be32(0); /* reclaim */
|
||||||
p = xdr_encode_opaque_fixed(p, args->stateid.data, NFS4_STATEID_SIZE);
|
p = xdr_encode_opaque_fixed(p, args->stateid.data, NFS4_STATEID_SIZE);
|
||||||
*p++ = cpu_to_be32(1); /* newoffset = TRUE */
|
*p++ = cpu_to_be32(1); /* newoffset = TRUE */
|
||||||
|
|
|
@ -189,6 +189,7 @@ static void
|
||||||
pnfs_free_layout_hdr(struct pnfs_layout_hdr *lo)
|
pnfs_free_layout_hdr(struct pnfs_layout_hdr *lo)
|
||||||
{
|
{
|
||||||
struct pnfs_layoutdriver_type *ld = NFS_SERVER(lo->plh_inode)->pnfs_curr_ld;
|
struct pnfs_layoutdriver_type *ld = NFS_SERVER(lo->plh_inode)->pnfs_curr_ld;
|
||||||
|
put_rpccred(lo->plh_lc_cred);
|
||||||
return ld->alloc_layout_hdr ? ld->free_layout_hdr(lo) : kfree(lo);
|
return ld->alloc_layout_hdr ? ld->free_layout_hdr(lo) : kfree(lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +224,7 @@ static void
|
||||||
init_lseg(struct pnfs_layout_hdr *lo, struct pnfs_layout_segment *lseg)
|
init_lseg(struct pnfs_layout_hdr *lo, struct pnfs_layout_segment *lseg)
|
||||||
{
|
{
|
||||||
INIT_LIST_HEAD(&lseg->pls_list);
|
INIT_LIST_HEAD(&lseg->pls_list);
|
||||||
|
INIT_LIST_HEAD(&lseg->pls_lc_list);
|
||||||
atomic_set(&lseg->pls_refcount, 1);
|
atomic_set(&lseg->pls_refcount, 1);
|
||||||
smp_mb();
|
smp_mb();
|
||||||
set_bit(NFS_LSEG_VALID, &lseg->pls_flags);
|
set_bit(NFS_LSEG_VALID, &lseg->pls_flags);
|
||||||
|
@ -805,7 +807,9 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pnfs_layout_hdr *
|
static struct pnfs_layout_hdr *
|
||||||
alloc_init_layout_hdr(struct inode *ino, gfp_t gfp_flags)
|
alloc_init_layout_hdr(struct inode *ino,
|
||||||
|
struct nfs_open_context *ctx,
|
||||||
|
gfp_t gfp_flags)
|
||||||
{
|
{
|
||||||
struct pnfs_layout_hdr *lo;
|
struct pnfs_layout_hdr *lo;
|
||||||
|
|
||||||
|
@ -817,11 +821,14 @@ alloc_init_layout_hdr(struct inode *ino, gfp_t gfp_flags)
|
||||||
INIT_LIST_HEAD(&lo->plh_segs);
|
INIT_LIST_HEAD(&lo->plh_segs);
|
||||||
INIT_LIST_HEAD(&lo->plh_bulk_recall);
|
INIT_LIST_HEAD(&lo->plh_bulk_recall);
|
||||||
lo->plh_inode = ino;
|
lo->plh_inode = ino;
|
||||||
|
lo->plh_lc_cred = get_rpccred(ctx->state->owner->so_cred);
|
||||||
return lo;
|
return lo;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pnfs_layout_hdr *
|
static struct pnfs_layout_hdr *
|
||||||
pnfs_find_alloc_layout(struct inode *ino, gfp_t gfp_flags)
|
pnfs_find_alloc_layout(struct inode *ino,
|
||||||
|
struct nfs_open_context *ctx,
|
||||||
|
gfp_t gfp_flags)
|
||||||
{
|
{
|
||||||
struct nfs_inode *nfsi = NFS_I(ino);
|
struct nfs_inode *nfsi = NFS_I(ino);
|
||||||
struct pnfs_layout_hdr *new = NULL;
|
struct pnfs_layout_hdr *new = NULL;
|
||||||
|
@ -836,7 +843,7 @@ pnfs_find_alloc_layout(struct inode *ino, gfp_t gfp_flags)
|
||||||
return nfsi->layout;
|
return nfsi->layout;
|
||||||
}
|
}
|
||||||
spin_unlock(&ino->i_lock);
|
spin_unlock(&ino->i_lock);
|
||||||
new = alloc_init_layout_hdr(ino, gfp_flags);
|
new = alloc_init_layout_hdr(ino, ctx, gfp_flags);
|
||||||
spin_lock(&ino->i_lock);
|
spin_lock(&ino->i_lock);
|
||||||
|
|
||||||
if (likely(nfsi->layout == NULL)) /* Won the race? */
|
if (likely(nfsi->layout == NULL)) /* Won the race? */
|
||||||
|
@ -928,7 +935,7 @@ pnfs_update_layout(struct inode *ino,
|
||||||
if (!pnfs_enabled_sb(NFS_SERVER(ino)))
|
if (!pnfs_enabled_sb(NFS_SERVER(ino)))
|
||||||
return NULL;
|
return NULL;
|
||||||
spin_lock(&ino->i_lock);
|
spin_lock(&ino->i_lock);
|
||||||
lo = pnfs_find_alloc_layout(ino, gfp_flags);
|
lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags);
|
||||||
if (lo == NULL) {
|
if (lo == NULL) {
|
||||||
dprintk("%s ERROR: can't get pnfs_layout_hdr\n", __func__);
|
dprintk("%s ERROR: can't get pnfs_layout_hdr\n", __func__);
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
@ -1195,16 +1202,17 @@ pnfs_try_to_read_data(struct nfs_read_data *rdata,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Currently there is only one (whole file) write lseg.
|
* There can be multiple RW segments.
|
||||||
*/
|
*/
|
||||||
static struct pnfs_layout_segment *pnfs_list_write_lseg(struct inode *inode)
|
static void pnfs_list_write_lseg(struct inode *inode, struct list_head *listp)
|
||||||
{
|
{
|
||||||
struct pnfs_layout_segment *lseg, *rv = NULL;
|
struct pnfs_layout_segment *lseg;
|
||||||
|
|
||||||
list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list)
|
list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list) {
|
||||||
if (lseg->pls_range.iomode == IOMODE_RW)
|
if (lseg->pls_range.iomode == IOMODE_RW &&
|
||||||
rv = lseg;
|
test_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags))
|
||||||
return rv;
|
list_add(&lseg->pls_lc_list, listp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1216,17 +1224,19 @@ pnfs_set_layoutcommit(struct nfs_write_data *wdata)
|
||||||
|
|
||||||
spin_lock(&nfsi->vfs_inode.i_lock);
|
spin_lock(&nfsi->vfs_inode.i_lock);
|
||||||
if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
|
if (!test_and_set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
|
||||||
/* references matched in nfs4_layoutcommit_release */
|
|
||||||
get_lseg(wdata->lseg);
|
|
||||||
wdata->lseg->pls_lc_cred =
|
|
||||||
get_rpccred(wdata->args.context->state->owner->so_cred);
|
|
||||||
mark_as_dirty = true;
|
mark_as_dirty = true;
|
||||||
dprintk("%s: Set layoutcommit for inode %lu ",
|
dprintk("%s: Set layoutcommit for inode %lu ",
|
||||||
__func__, wdata->inode->i_ino);
|
__func__, wdata->inode->i_ino);
|
||||||
}
|
}
|
||||||
if (end_pos > wdata->lseg->pls_end_pos)
|
if (!test_and_set_bit(NFS_LSEG_LAYOUTCOMMIT, &wdata->lseg->pls_flags)) {
|
||||||
wdata->lseg->pls_end_pos = end_pos;
|
/* references matched in nfs4_layoutcommit_release */
|
||||||
|
get_lseg(wdata->lseg);
|
||||||
|
}
|
||||||
|
if (end_pos > nfsi->layout->plh_lwb)
|
||||||
|
nfsi->layout->plh_lwb = end_pos;
|
||||||
spin_unlock(&nfsi->vfs_inode.i_lock);
|
spin_unlock(&nfsi->vfs_inode.i_lock);
|
||||||
|
dprintk("%s: lseg %p end_pos %llu\n",
|
||||||
|
__func__, wdata->lseg, nfsi->layout->plh_lwb);
|
||||||
|
|
||||||
/* if pnfs_layoutcommit_inode() runs between inode locks, the next one
|
/* if pnfs_layoutcommit_inode() runs between inode locks, the next one
|
||||||
* will be a noop because NFS_INO_LAYOUTCOMMIT will not be set */
|
* will be a noop because NFS_INO_LAYOUTCOMMIT will not be set */
|
||||||
|
@ -1248,8 +1258,6 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
|
||||||
{
|
{
|
||||||
struct nfs4_layoutcommit_data *data;
|
struct nfs4_layoutcommit_data *data;
|
||||||
struct nfs_inode *nfsi = NFS_I(inode);
|
struct nfs_inode *nfsi = NFS_I(inode);
|
||||||
struct pnfs_layout_segment *lseg;
|
|
||||||
struct rpc_cred *cred;
|
|
||||||
loff_t end_pos;
|
loff_t end_pos;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
|
@ -1266,30 +1274,25 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&data->lseg_list);
|
||||||
spin_lock(&inode->i_lock);
|
spin_lock(&inode->i_lock);
|
||||||
if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
|
if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags)) {
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
kfree(data);
|
kfree(data);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* Currently only one (whole file) write lseg which is referenced
|
|
||||||
* in pnfs_set_layoutcommit and will be found.
|
|
||||||
*/
|
|
||||||
lseg = pnfs_list_write_lseg(inode);
|
|
||||||
|
|
||||||
end_pos = lseg->pls_end_pos;
|
pnfs_list_write_lseg(inode, &data->lseg_list);
|
||||||
cred = lseg->pls_lc_cred;
|
|
||||||
lseg->pls_end_pos = 0;
|
end_pos = nfsi->layout->plh_lwb;
|
||||||
lseg->pls_lc_cred = NULL;
|
nfsi->layout->plh_lwb = 0;
|
||||||
|
|
||||||
memcpy(&data->args.stateid.data, nfsi->layout->plh_stateid.data,
|
memcpy(&data->args.stateid.data, nfsi->layout->plh_stateid.data,
|
||||||
sizeof(nfsi->layout->plh_stateid.data));
|
sizeof(nfsi->layout->plh_stateid.data));
|
||||||
spin_unlock(&inode->i_lock);
|
spin_unlock(&inode->i_lock);
|
||||||
|
|
||||||
data->args.inode = inode;
|
data->args.inode = inode;
|
||||||
data->lseg = lseg;
|
data->cred = get_rpccred(nfsi->layout->plh_lc_cred);
|
||||||
data->cred = cred;
|
|
||||||
nfs_fattr_init(&data->fattr);
|
nfs_fattr_init(&data->fattr);
|
||||||
data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;
|
data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;
|
||||||
data->res.fattr = &data->fattr;
|
data->res.fattr = &data->fattr;
|
||||||
|
|
|
@ -36,16 +36,16 @@
|
||||||
enum {
|
enum {
|
||||||
NFS_LSEG_VALID = 0, /* cleared when lseg is recalled/returned */
|
NFS_LSEG_VALID = 0, /* cleared when lseg is recalled/returned */
|
||||||
NFS_LSEG_ROC, /* roc bit received from server */
|
NFS_LSEG_ROC, /* roc bit received from server */
|
||||||
|
NFS_LSEG_LAYOUTCOMMIT, /* layoutcommit bit set for layoutcommit */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pnfs_layout_segment {
|
struct pnfs_layout_segment {
|
||||||
struct list_head pls_list;
|
struct list_head pls_list;
|
||||||
|
struct list_head pls_lc_list;
|
||||||
struct pnfs_layout_range pls_range;
|
struct pnfs_layout_range pls_range;
|
||||||
atomic_t pls_refcount;
|
atomic_t pls_refcount;
|
||||||
unsigned long pls_flags;
|
unsigned long pls_flags;
|
||||||
struct pnfs_layout_hdr *pls_layout;
|
struct pnfs_layout_hdr *pls_layout;
|
||||||
struct rpc_cred *pls_lc_cred; /* LAYOUTCOMMIT credential */
|
|
||||||
loff_t pls_end_pos; /* LAYOUTCOMMIT write end */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum pnfs_try_status {
|
enum pnfs_try_status {
|
||||||
|
@ -124,6 +124,8 @@ struct pnfs_layout_hdr {
|
||||||
unsigned long plh_block_lgets; /* block LAYOUTGET if >0 */
|
unsigned long plh_block_lgets; /* block LAYOUTGET if >0 */
|
||||||
u32 plh_barrier; /* ignore lower seqids */
|
u32 plh_barrier; /* ignore lower seqids */
|
||||||
unsigned long plh_flags;
|
unsigned long plh_flags;
|
||||||
|
loff_t plh_lwb; /* last write byte for layoutcommit */
|
||||||
|
struct rpc_cred *plh_lc_cred; /* layoutcommit cred */
|
||||||
struct inode *plh_inode;
|
struct inode *plh_inode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -381,14 +381,6 @@ static int nfs4_access_to_omode(u32 access)
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nfs4_access_bmap_to_omode(struct nfs4_stateid *stp)
|
|
||||||
{
|
|
||||||
unsigned int access;
|
|
||||||
|
|
||||||
set_access(&access, stp->st_access_bmap);
|
|
||||||
return nfs4_access_to_omode(access);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void unhash_generic_stateid(struct nfs4_stateid *stp)
|
static void unhash_generic_stateid(struct nfs4_stateid *stp)
|
||||||
{
|
{
|
||||||
list_del(&stp->st_hash);
|
list_del(&stp->st_hash);
|
||||||
|
@ -398,11 +390,14 @@ static void unhash_generic_stateid(struct nfs4_stateid *stp)
|
||||||
|
|
||||||
static void free_generic_stateid(struct nfs4_stateid *stp)
|
static void free_generic_stateid(struct nfs4_stateid *stp)
|
||||||
{
|
{
|
||||||
int oflag;
|
int i;
|
||||||
|
|
||||||
if (stp->st_access_bmap) {
|
if (stp->st_access_bmap) {
|
||||||
oflag = nfs4_access_bmap_to_omode(stp);
|
for (i = 1; i < 4; i++) {
|
||||||
nfs4_file_put_access(stp->st_file, oflag);
|
if (test_bit(i, &stp->st_access_bmap))
|
||||||
|
nfs4_file_put_access(stp->st_file,
|
||||||
|
nfs4_access_to_omode(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
put_nfs4_file(stp->st_file);
|
put_nfs4_file(stp->st_file);
|
||||||
kmem_cache_free(stateid_slab, stp);
|
kmem_cache_free(stateid_slab, stp);
|
||||||
|
@ -2337,15 +2332,6 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
nfs4_file_downgrade(struct nfs4_file *fp, unsigned int share_access)
|
|
||||||
{
|
|
||||||
if (share_access & NFS4_SHARE_ACCESS_WRITE)
|
|
||||||
nfs4_file_put_access(fp, O_WRONLY);
|
|
||||||
if (share_access & NFS4_SHARE_ACCESS_READ)
|
|
||||||
nfs4_file_put_access(fp, O_RDONLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
|
static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
|
||||||
{
|
{
|
||||||
/* We're assuming the state code never drops its reference
|
/* We're assuming the state code never drops its reference
|
||||||
|
@ -2556,12 +2542,18 @@ static inline int nfs4_access_to_access(u32 nfs4_access)
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file
|
static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
|
||||||
*fp, struct svc_fh *cur_fh, u32 nfs4_access)
|
struct svc_fh *cur_fh, struct nfsd4_open *open)
|
||||||
{
|
{
|
||||||
__be32 status;
|
__be32 status;
|
||||||
int oflag = nfs4_access_to_omode(nfs4_access);
|
int oflag = nfs4_access_to_omode(open->op_share_access);
|
||||||
int access = nfs4_access_to_access(nfs4_access);
|
int access = nfs4_access_to_access(open->op_share_access);
|
||||||
|
|
||||||
|
/* CLAIM_DELEGATE_CUR is used in response to a broken lease;
|
||||||
|
* allowing it to break the lease and return EAGAIN leaves the
|
||||||
|
* client unable to make progress in returning the delegation */
|
||||||
|
if (open->op_claim_type == NFS4_OPEN_CLAIM_DELEGATE_CUR)
|
||||||
|
access |= NFSD_MAY_NOT_BREAK_LEASE;
|
||||||
|
|
||||||
if (!fp->fi_fds[oflag]) {
|
if (!fp->fi_fds[oflag]) {
|
||||||
status = nfsd_open(rqstp, cur_fh, S_IFREG, access,
|
status = nfsd_open(rqstp, cur_fh, S_IFREG, access,
|
||||||
|
@ -2586,7 +2578,7 @@ nfs4_new_open(struct svc_rqst *rqstp, struct nfs4_stateid **stpp,
|
||||||
if (stp == NULL)
|
if (stp == NULL)
|
||||||
return nfserr_resource;
|
return nfserr_resource;
|
||||||
|
|
||||||
status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open->op_share_access);
|
status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open);
|
||||||
if (status) {
|
if (status) {
|
||||||
kmem_cache_free(stateid_slab, stp);
|
kmem_cache_free(stateid_slab, stp);
|
||||||
return status;
|
return status;
|
||||||
|
@ -2619,14 +2611,14 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct nfs4_file *fp, struct svc_fh *c
|
||||||
|
|
||||||
new_access = !test_bit(op_share_access, &stp->st_access_bmap);
|
new_access = !test_bit(op_share_access, &stp->st_access_bmap);
|
||||||
if (new_access) {
|
if (new_access) {
|
||||||
status = nfs4_get_vfs_file(rqstp, fp, cur_fh, op_share_access);
|
status = nfs4_get_vfs_file(rqstp, fp, cur_fh, open);
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
status = nfsd4_truncate(rqstp, cur_fh, open);
|
status = nfsd4_truncate(rqstp, cur_fh, open);
|
||||||
if (status) {
|
if (status) {
|
||||||
if (new_access) {
|
if (new_access) {
|
||||||
int oflag = nfs4_access_to_omode(new_access);
|
int oflag = nfs4_access_to_omode(op_share_access);
|
||||||
nfs4_file_put_access(fp, oflag);
|
nfs4_file_put_access(fp, oflag);
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
|
@ -3384,18 +3376,15 @@ out:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void nfs4_file_downgrade(struct nfs4_stateid *stp, unsigned int to_access)
|
||||||
/*
|
|
||||||
* unset all bits in union bitmap (bmap) that
|
|
||||||
* do not exist in share (from successful OPEN_DOWNGRADE)
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
reset_union_bmap_access(unsigned long access, unsigned long *bmap)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 1; i < 4; i++) {
|
for (i = 1; i < 4; i++) {
|
||||||
if ((i & access) != i)
|
if (test_bit(i, &stp->st_access_bmap) && !(i & to_access)) {
|
||||||
__clear_bit(i, bmap);
|
nfs4_file_put_access(stp->st_file, i);
|
||||||
|
__clear_bit(i, &stp->st_access_bmap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3416,7 +3405,6 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
|
||||||
{
|
{
|
||||||
__be32 status;
|
__be32 status;
|
||||||
struct nfs4_stateid *stp;
|
struct nfs4_stateid *stp;
|
||||||
unsigned int share_access;
|
|
||||||
|
|
||||||
dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n",
|
dprintk("NFSD: nfsd4_open_downgrade on file %.*s\n",
|
||||||
(int)cstate->current_fh.fh_dentry->d_name.len,
|
(int)cstate->current_fh.fh_dentry->d_name.len,
|
||||||
|
@ -3445,10 +3433,8 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
|
||||||
stp->st_deny_bmap, od->od_share_deny);
|
stp->st_deny_bmap, od->od_share_deny);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
set_access(&share_access, stp->st_access_bmap);
|
nfs4_file_downgrade(stp, od->od_share_access);
|
||||||
nfs4_file_downgrade(stp->st_file, share_access & ~od->od_share_access);
|
|
||||||
|
|
||||||
reset_union_bmap_access(od->od_share_access, &stp->st_access_bmap);
|
|
||||||
reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap);
|
reset_union_bmap_deny(od->od_share_deny, &stp->st_deny_bmap);
|
||||||
|
|
||||||
update_stateid(&stp->st_stateid);
|
update_stateid(&stp->st_stateid);
|
||||||
|
|
|
@ -2747,9 +2747,16 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
|
||||||
{
|
{
|
||||||
struct task_io_accounting acct = task->ioac;
|
struct task_io_accounting acct = task->ioac;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
int result;
|
||||||
|
|
||||||
if (!ptrace_may_access(task, PTRACE_MODE_READ))
|
result = mutex_lock_killable(&task->signal->cred_guard_mutex);
|
||||||
return -EACCES;
|
if (result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
if (!ptrace_may_access(task, PTRACE_MODE_READ)) {
|
||||||
|
result = -EACCES;
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
if (whole && lock_task_sighand(task, &flags)) {
|
if (whole && lock_task_sighand(task, &flags)) {
|
||||||
struct task_struct *t = task;
|
struct task_struct *t = task;
|
||||||
|
@ -2760,7 +2767,7 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
|
||||||
|
|
||||||
unlock_task_sighand(task, &flags);
|
unlock_task_sighand(task, &flags);
|
||||||
}
|
}
|
||||||
return sprintf(buffer,
|
result = sprintf(buffer,
|
||||||
"rchar: %llu\n"
|
"rchar: %llu\n"
|
||||||
"wchar: %llu\n"
|
"wchar: %llu\n"
|
||||||
"syscr: %llu\n"
|
"syscr: %llu\n"
|
||||||
|
@ -2775,6 +2782,9 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole)
|
||||||
(unsigned long long)acct.read_bytes,
|
(unsigned long long)acct.read_bytes,
|
||||||
(unsigned long long)acct.write_bytes,
|
(unsigned long long)acct.write_bytes,
|
||||||
(unsigned long long)acct.cancelled_write_bytes);
|
(unsigned long long)acct.cancelled_write_bytes);
|
||||||
|
out_unlock:
|
||||||
|
mutex_unlock(&task->signal->cred_guard_mutex);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int proc_tid_io_accounting(struct task_struct *task, char *buffer)
|
static int proc_tid_io_accounting(struct task_struct *task, char *buffer)
|
||||||
|
|
|
@ -475,6 +475,9 @@ union fw_cdev_event {
|
||||||
* of the bus. This does not cause a bus reset to happen.
|
* of the bus. This does not cause a bus reset to happen.
|
||||||
* @bus_reset_closure: Value of &closure in this and subsequent bus reset events
|
* @bus_reset_closure: Value of &closure in this and subsequent bus reset events
|
||||||
* @card: The index of the card this device belongs to
|
* @card: The index of the card this device belongs to
|
||||||
|
*
|
||||||
|
* As a side effect, reception of %FW_CDEV_EVENT_BUS_RESET events to be read(2)
|
||||||
|
* is started by this ioctl.
|
||||||
*/
|
*/
|
||||||
struct fw_cdev_get_info {
|
struct fw_cdev_get_info {
|
||||||
__u32 version;
|
__u32 version;
|
||||||
|
|
|
@ -986,6 +986,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
|
||||||
int get_user_pages_fast(unsigned long start, int nr_pages, int write,
|
int get_user_pages_fast(unsigned long start, int nr_pages, int write,
|
||||||
struct page **pages);
|
struct page **pages);
|
||||||
struct page *get_dump_page(unsigned long addr);
|
struct page *get_dump_page(unsigned long addr);
|
||||||
|
extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm,
|
||||||
|
unsigned long address, unsigned int fault_flags);
|
||||||
|
|
||||||
extern int try_to_release_page(struct page * page, gfp_t gfp_mask);
|
extern int try_to_release_page(struct page * page, gfp_t gfp_mask);
|
||||||
extern void do_invalidatepage(struct page *page, unsigned long offset);
|
extern void do_invalidatepage(struct page *page, unsigned long offset);
|
||||||
|
|
|
@ -1688,9 +1688,12 @@ static inline int skb_gro_header_hard(struct sk_buff *skb, unsigned int hlen)
|
||||||
static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen,
|
static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen,
|
||||||
unsigned int offset)
|
unsigned int offset)
|
||||||
{
|
{
|
||||||
|
if (!pskb_may_pull(skb, hlen))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
NAPI_GRO_CB(skb)->frag0 = NULL;
|
NAPI_GRO_CB(skb)->frag0 = NULL;
|
||||||
NAPI_GRO_CB(skb)->frag0_len = 0;
|
NAPI_GRO_CB(skb)->frag0_len = 0;
|
||||||
return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL;
|
return skb->data + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *skb_gro_mac_header(struct sk_buff *skb)
|
static inline void *skb_gro_mac_header(struct sk_buff *skb)
|
||||||
|
|
|
@ -99,9 +99,10 @@ struct nfs_open_context {
|
||||||
|
|
||||||
struct nfs_open_dir_context {
|
struct nfs_open_dir_context {
|
||||||
struct rpc_cred *cred;
|
struct rpc_cred *cred;
|
||||||
|
unsigned long attr_gencount;
|
||||||
__u64 dir_cookie;
|
__u64 dir_cookie;
|
||||||
__u64 dup_cookie;
|
__u64 dup_cookie;
|
||||||
int duped;
|
signed char duped;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -262,7 +262,7 @@ struct nfs4_layoutcommit_res {
|
||||||
struct nfs4_layoutcommit_data {
|
struct nfs4_layoutcommit_data {
|
||||||
struct rpc_task task;
|
struct rpc_task task;
|
||||||
struct nfs_fattr fattr;
|
struct nfs_fattr fattr;
|
||||||
struct pnfs_layout_segment *lseg;
|
struct list_head lseg_list;
|
||||||
struct rpc_cred *cred;
|
struct rpc_cred *cred;
|
||||||
struct nfs4_layoutcommit_args args;
|
struct nfs4_layoutcommit_args args;
|
||||||
struct nfs4_layoutcommit_res res;
|
struct nfs4_layoutcommit_res res;
|
||||||
|
|
13
ipc/sem.c
13
ipc/sem.c
|
@ -1456,15 +1456,24 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
|
||||||
}
|
}
|
||||||
|
|
||||||
sma = sem_lock(ns, semid);
|
sma = sem_lock(ns, semid);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait until it's guaranteed that no wakeup_sem_queue_do() is ongoing.
|
||||||
|
*/
|
||||||
|
error = get_queue_result(&queue);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Array removed? If yes, leave without sem_unlock().
|
||||||
|
*/
|
||||||
if (IS_ERR(sma)) {
|
if (IS_ERR(sma)) {
|
||||||
error = -EIDRM;
|
error = -EIDRM;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = get_queue_result(&queue);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If queue.status != -EINTR we are woken up by another process
|
* If queue.status != -EINTR we are woken up by another process.
|
||||||
|
* Leave without unlink_queue(), but with sem_unlock().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (error != -EINTR) {
|
if (error != -EINTR) {
|
||||||
|
|
|
@ -5016,11 +5016,8 @@ static int __perf_event_overflow(struct perf_event *event, int nmi,
|
||||||
if (events && atomic_dec_and_test(&event->event_limit)) {
|
if (events && atomic_dec_and_test(&event->event_limit)) {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
event->pending_kill = POLL_HUP;
|
event->pending_kill = POLL_HUP;
|
||||||
if (nmi) {
|
|
||||||
event->pending_disable = 1;
|
event->pending_disable = 1;
|
||||||
irq_work_queue(&event->pending);
|
irq_work_queue(&event->pending);
|
||||||
} else
|
|
||||||
perf_event_disable(event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event->overflow_handler)
|
if (event->overflow_handler)
|
||||||
|
|
|
@ -355,8 +355,8 @@ static int fault_in_user_writeable(u32 __user *uaddr)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
down_read(&mm->mmap_sem);
|
down_read(&mm->mmap_sem);
|
||||||
ret = get_user_pages(current, mm, (unsigned long)uaddr,
|
ret = fixup_user_fault(current, mm, (unsigned long)uaddr,
|
||||||
1, 1, 0, NULL, NULL);
|
FAULT_FLAG_WRITE);
|
||||||
up_read(&mm->mmap_sem);
|
up_read(&mm->mmap_sem);
|
||||||
|
|
||||||
return ret < 0 ? ret : 0;
|
return ret < 0 ? ret : 0;
|
||||||
|
|
|
@ -677,6 +677,7 @@ struct event_subsystem {
|
||||||
struct dentry *entry;
|
struct dentry *entry;
|
||||||
struct event_filter *filter;
|
struct event_filter *filter;
|
||||||
int nr_events;
|
int nr_events;
|
||||||
|
int ref_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FILTER_PRED_INVALID ((unsigned short)-1)
|
#define FILTER_PRED_INVALID ((unsigned short)-1)
|
||||||
|
|
|
@ -244,6 +244,35 @@ static void ftrace_clear_events(void)
|
||||||
mutex_unlock(&event_mutex);
|
mutex_unlock(&event_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __put_system(struct event_subsystem *system)
|
||||||
|
{
|
||||||
|
struct event_filter *filter = system->filter;
|
||||||
|
|
||||||
|
WARN_ON_ONCE(system->ref_count == 0);
|
||||||
|
if (--system->ref_count)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (filter) {
|
||||||
|
kfree(filter->filter_string);
|
||||||
|
kfree(filter);
|
||||||
|
}
|
||||||
|
kfree(system->name);
|
||||||
|
kfree(system);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __get_system(struct event_subsystem *system)
|
||||||
|
{
|
||||||
|
WARN_ON_ONCE(system->ref_count == 0);
|
||||||
|
system->ref_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void put_system(struct event_subsystem *system)
|
||||||
|
{
|
||||||
|
mutex_lock(&event_mutex);
|
||||||
|
__put_system(system);
|
||||||
|
mutex_unlock(&event_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* __ftrace_set_clr_event(NULL, NULL, NULL, set) will set/unset all events.
|
* __ftrace_set_clr_event(NULL, NULL, NULL, set) will set/unset all events.
|
||||||
*/
|
*/
|
||||||
|
@ -528,7 +557,7 @@ system_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
|
||||||
loff_t *ppos)
|
loff_t *ppos)
|
||||||
{
|
{
|
||||||
const char set_to_char[4] = { '?', '0', '1', 'X' };
|
const char set_to_char[4] = { '?', '0', '1', 'X' };
|
||||||
const char *system = filp->private_data;
|
struct event_subsystem *system = filp->private_data;
|
||||||
struct ftrace_event_call *call;
|
struct ftrace_event_call *call;
|
||||||
char buf[2];
|
char buf[2];
|
||||||
int set = 0;
|
int set = 0;
|
||||||
|
@ -539,7 +568,7 @@ system_enable_read(struct file *filp, char __user *ubuf, size_t cnt,
|
||||||
if (!call->name || !call->class || !call->class->reg)
|
if (!call->name || !call->class || !call->class->reg)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (system && strcmp(call->class->system, system) != 0)
|
if (system && strcmp(call->class->system, system->name) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -569,7 +598,8 @@ static ssize_t
|
||||||
system_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
system_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
||||||
loff_t *ppos)
|
loff_t *ppos)
|
||||||
{
|
{
|
||||||
const char *system = filp->private_data;
|
struct event_subsystem *system = filp->private_data;
|
||||||
|
const char *name = NULL;
|
||||||
unsigned long val;
|
unsigned long val;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
@ -593,7 +623,14 @@ system_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
||||||
if (val != 0 && val != 1)
|
if (val != 0 && val != 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ret = __ftrace_set_clr_event(NULL, system, NULL, val);
|
/*
|
||||||
|
* Opening of "enable" adds a ref count to system,
|
||||||
|
* so the name is safe to use.
|
||||||
|
*/
|
||||||
|
if (system)
|
||||||
|
name = system->name;
|
||||||
|
|
||||||
|
ret = __ftrace_set_clr_event(NULL, name, NULL, val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -826,6 +863,52 @@ event_filter_write(struct file *filp, const char __user *ubuf, size_t cnt,
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LIST_HEAD(event_subsystems);
|
||||||
|
|
||||||
|
static int subsystem_open(struct inode *inode, struct file *filp)
|
||||||
|
{
|
||||||
|
struct event_subsystem *system = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!inode->i_private)
|
||||||
|
goto skip_search;
|
||||||
|
|
||||||
|
/* Make sure the system still exists */
|
||||||
|
mutex_lock(&event_mutex);
|
||||||
|
list_for_each_entry(system, &event_subsystems, list) {
|
||||||
|
if (system == inode->i_private) {
|
||||||
|
/* Don't open systems with no events */
|
||||||
|
if (!system->nr_events) {
|
||||||
|
system = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
__get_system(system);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mutex_unlock(&event_mutex);
|
||||||
|
|
||||||
|
if (system != inode->i_private)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
skip_search:
|
||||||
|
ret = tracing_open_generic(inode, filp);
|
||||||
|
if (ret < 0 && system)
|
||||||
|
put_system(system);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int subsystem_release(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
struct event_subsystem *system = inode->i_private;
|
||||||
|
|
||||||
|
if (system)
|
||||||
|
put_system(system);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
|
subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt,
|
||||||
loff_t *ppos)
|
loff_t *ppos)
|
||||||
|
@ -963,17 +1046,19 @@ static const struct file_operations ftrace_event_filter_fops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct file_operations ftrace_subsystem_filter_fops = {
|
static const struct file_operations ftrace_subsystem_filter_fops = {
|
||||||
.open = tracing_open_generic,
|
.open = subsystem_open,
|
||||||
.read = subsystem_filter_read,
|
.read = subsystem_filter_read,
|
||||||
.write = subsystem_filter_write,
|
.write = subsystem_filter_write,
|
||||||
.llseek = default_llseek,
|
.llseek = default_llseek,
|
||||||
|
.release = subsystem_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct file_operations ftrace_system_enable_fops = {
|
static const struct file_operations ftrace_system_enable_fops = {
|
||||||
.open = tracing_open_generic,
|
.open = subsystem_open,
|
||||||
.read = system_enable_read,
|
.read = system_enable_read,
|
||||||
.write = system_enable_write,
|
.write = system_enable_write,
|
||||||
.llseek = default_llseek,
|
.llseek = default_llseek,
|
||||||
|
.release = subsystem_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct file_operations ftrace_show_header_fops = {
|
static const struct file_operations ftrace_show_header_fops = {
|
||||||
|
@ -1002,8 +1087,6 @@ static struct dentry *event_trace_events_dir(void)
|
||||||
return d_events;
|
return d_events;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LIST_HEAD(event_subsystems);
|
|
||||||
|
|
||||||
static struct dentry *
|
static struct dentry *
|
||||||
event_subsystem_dir(const char *name, struct dentry *d_events)
|
event_subsystem_dir(const char *name, struct dentry *d_events)
|
||||||
{
|
{
|
||||||
|
@ -1013,6 +1096,7 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
|
||||||
/* First see if we did not already create this dir */
|
/* First see if we did not already create this dir */
|
||||||
list_for_each_entry(system, &event_subsystems, list) {
|
list_for_each_entry(system, &event_subsystems, list) {
|
||||||
if (strcmp(system->name, name) == 0) {
|
if (strcmp(system->name, name) == 0) {
|
||||||
|
__get_system(system);
|
||||||
system->nr_events++;
|
system->nr_events++;
|
||||||
return system->entry;
|
return system->entry;
|
||||||
}
|
}
|
||||||
|
@ -1035,6 +1119,7 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
|
||||||
}
|
}
|
||||||
|
|
||||||
system->nr_events = 1;
|
system->nr_events = 1;
|
||||||
|
system->ref_count = 1;
|
||||||
system->name = kstrdup(name, GFP_KERNEL);
|
system->name = kstrdup(name, GFP_KERNEL);
|
||||||
if (!system->name) {
|
if (!system->name) {
|
||||||
debugfs_remove(system->entry);
|
debugfs_remove(system->entry);
|
||||||
|
@ -1062,8 +1147,7 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
|
||||||
"'%s/filter' entry\n", name);
|
"'%s/filter' entry\n", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
trace_create_file("enable", 0644, system->entry,
|
trace_create_file("enable", 0644, system->entry, system,
|
||||||
(void *)system->name,
|
|
||||||
&ftrace_system_enable_fops);
|
&ftrace_system_enable_fops);
|
||||||
|
|
||||||
return system->entry;
|
return system->entry;
|
||||||
|
@ -1184,16 +1268,9 @@ static void remove_subsystem_dir(const char *name)
|
||||||
list_for_each_entry(system, &event_subsystems, list) {
|
list_for_each_entry(system, &event_subsystems, list) {
|
||||||
if (strcmp(system->name, name) == 0) {
|
if (strcmp(system->name, name) == 0) {
|
||||||
if (!--system->nr_events) {
|
if (!--system->nr_events) {
|
||||||
struct event_filter *filter = system->filter;
|
|
||||||
|
|
||||||
debugfs_remove_recursive(system->entry);
|
debugfs_remove_recursive(system->entry);
|
||||||
list_del(&system->list);
|
list_del(&system->list);
|
||||||
if (filter) {
|
__put_system(system);
|
||||||
kfree(filter->filter_string);
|
|
||||||
kfree(filter);
|
|
||||||
}
|
|
||||||
kfree(system->name);
|
|
||||||
kfree(system);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1886,6 +1886,12 @@ int apply_subsystem_event_filter(struct event_subsystem *system,
|
||||||
|
|
||||||
mutex_lock(&event_mutex);
|
mutex_lock(&event_mutex);
|
||||||
|
|
||||||
|
/* Make sure the system still has events */
|
||||||
|
if (!system->nr_events) {
|
||||||
|
err = -ENODEV;
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
if (!strcmp(strstrip(filter_string), "0")) {
|
if (!strcmp(strstrip(filter_string), "0")) {
|
||||||
filter_free_subsystem_preds(system);
|
filter_free_subsystem_preds(system);
|
||||||
remove_filter_string(system->filter);
|
remove_filter_string(system->filter);
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
# include <linux/xz.h>
|
# include <linux/xz.h>
|
||||||
# include <asm/byteorder.h>
|
# include <linux/kernel.h>
|
||||||
# include <asm/unaligned.h>
|
# include <asm/unaligned.h>
|
||||||
/* XZ_PREBOOT may be defined only via decompress_unxz.c. */
|
/* XZ_PREBOOT may be defined only via decompress_unxz.c. */
|
||||||
# ifndef XZ_PREBOOT
|
# ifndef XZ_PREBOOT
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue