Merge branch 'arch-arm64' into no-rebases

This commit is contained in:
Al Viro 2012-11-16 22:28:34 -05:00
commit 9526d9bc23
106 changed files with 1128 additions and 590 deletions

View File

@ -27,17 +27,17 @@ Start End Size Use
-----------------------------------------------------------------------
0000000000000000 0000007fffffffff 512GB user
ffffff8000000000 ffffffbbfffcffff ~240GB vmalloc
ffffff8000000000 ffffffbbfffeffff ~240GB vmalloc
ffffffbbfffd0000 ffffffbcfffdffff 64KB [guard page]
ffffffbbfffe0000 ffffffbcfffeffff 64KB PCI I/O space
ffffffbbffff0000 ffffffbcffffffff 64KB [guard page]
ffffffbbffff0000 ffffffbbffffffff 64KB [guard page]
ffffffbc00000000 ffffffbdffffffff 8GB vmemmap
ffffffbe00000000 ffffffbffbffffff ~8GB [guard, future vmmemap]
ffffffbe00000000 ffffffbffbbfffff ~8GB [guard, future vmmemap]
ffffffbffbe00000 ffffffbffbe0ffff 64KB PCI I/O space
ffffffbbffff0000 ffffffbcffffffff ~2MB [guard]
ffffffbffc000000 ffffffbfffffffff 64MB modules

View File

@ -0,0 +1,19 @@
* EETI eGalax Multiple Touch Controller
Required properties:
- compatible: must be "eeti,egalax_ts"
- reg: i2c slave address
- interrupt-parent: the phandle for the interrupt controller
- interrupts: touch controller interrupt
- wakeup-gpios: the gpio pin to be used for waking up the controller
as well as uased as irq pin
Example:
egalax_ts@04 {
compatible = "eeti,egalax_ts";
reg = <0x04>;
interrupt-parent = <&gpio1>;
interrupts = <9 2>;
wakeup-gpios = <&gpio1 9 0>;
};

View File

@ -10,7 +10,7 @@ Supported chips:
BIOS and Kernel Developer's Guide (BKDG) For AMD Family 15h Processors
(not yet published)
Author: Andreas Herrmann <andreas.herrmann3@amd.com>
Author: Andreas Herrmann <herrmann.der.user@googlemail.com>
Description
-----------

View File

@ -503,7 +503,7 @@ F: include/linux/altera_uart.h
F: include/linux/altera_jtaguart.h
AMD FAM15H PROCESSOR POWER MONITORING DRIVER
M: Andreas Herrmann <andreas.herrmann3@amd.com>
M: Andreas Herrmann <herrmann.der.user@googlemail.com>
L: lm-sensors@lm-sensors.org
S: Maintained
F: Documentation/hwmon/fam15h_power
@ -2507,6 +2507,7 @@ M: Joonyoung Shim <jy0922.shim@samsung.com>
M: Seung-Woo Kim <sw0312.kim@samsung.com>
M: Kyungmin Park <kyungmin.park@samsung.com>
L: dri-devel@lists.freedesktop.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git
S: Supported
F: drivers/gpu/drm/exynos
F: include/drm/exynos*

View File

@ -1,7 +1,7 @@
VERSION = 3
PATCHLEVEL = 7
SUBLEVEL = 0
EXTRAVERSION = -rc3
EXTRAVERSION = -rc4
NAME = Terrified Chipmunk
# *DOCUMENTATION*

View File

@ -48,20 +48,16 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/opcodes-virt.h>
#include <xen/interface/xen.h>
/* HVC 0xEA1 */
#ifdef CONFIG_THUMB2_KERNEL
#define xen_hvc .word 0xf7e08ea1
#else
#define xen_hvc .word 0xe140ea71
#endif
#define XEN_IMM 0xEA1
#define HYPERCALL_SIMPLE(hypercall) \
ENTRY(HYPERVISOR_##hypercall) \
mov r12, #__HYPERVISOR_##hypercall; \
xen_hvc; \
__HVC(XEN_IMM); \
mov pc, lr; \
ENDPROC(HYPERVISOR_##hypercall)
@ -76,7 +72,7 @@ ENTRY(HYPERVISOR_##hypercall) \
stmdb sp!, {r4} \
ldr r4, [sp, #4] \
mov r12, #__HYPERVISOR_##hypercall; \
xen_hvc \
__HVC(XEN_IMM); \
ldm sp!, {r4} \
mov pc, lr \
ENDPROC(HYPERVISOR_##hypercall)
@ -100,7 +96,7 @@ ENTRY(privcmd_call)
mov r2, r3
ldr r3, [sp, #8]
ldr r4, [sp, #4]
xen_hvc
__HVC(XEN_IMM)
ldm sp!, {r4}
mov pc, lr
ENDPROC(privcmd_call);

View File

@ -25,12 +25,10 @@
#include <asm/user.h>
typedef unsigned long elf_greg_t;
typedef unsigned long elf_freg_t[3];
#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef struct user_fp elf_fpregset_t;
typedef struct user_fpsimd_state elf_fpregset_t;
#define EM_AARCH64 183
@ -87,7 +85,6 @@ typedef struct user_fp elf_fpregset_t;
#define R_AARCH64_MOVW_PREL_G2_NC 292
#define R_AARCH64_MOVW_PREL_G3 293
/*
* These are used to set parameters in the core dumps.
*/

View File

@ -25,9 +25,8 @@
* - FPSR and FPCR
* - 32 128-bit data registers
*
* Note that user_fp forms a prefix of this structure, which is relied
* upon in the ptrace FP/SIMD accessors. struct user_fpsimd_state must
* form a prefix of struct fpsimd_state.
* Note that user_fpsimd forms a prefix of this structure, which is
* relied upon in the ptrace FP/SIMD accessors.
*/
struct fpsimd_state {
union {

View File

@ -114,7 +114,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
* I/O port access primitives.
*/
#define IO_SPACE_LIMIT 0xffff
#define PCI_IOBASE ((void __iomem *)0xffffffbbfffe0000UL)
#define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_2M))
static inline u8 inb(unsigned long addr)
{
@ -225,9 +225,9 @@ extern void __iounmap(volatile void __iomem *addr);
#define PROT_DEVICE_nGnRE (PROT_DEFAULT | PTE_XN | PTE_ATTRINDX(MT_DEVICE_nGnRE))
#define PROT_NORMAL_NC (PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL_NC))
#define ioremap(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE)
#define ioremap_nocache(addr, size) __ioremap((addr), (size), PROT_DEVICE_nGnRE)
#define ioremap_wc(addr, size) __ioremap((addr), (size), PROT_NORMAL_NC)
#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
#define ioremap_wc(addr, size) __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
#define iounmap __iounmap
#define ARCH_HAS_IOREMAP_WC

View File

@ -23,15 +23,16 @@
/*
* System call wrappers implemented in kernel/entry.S.
*/
asmlinkage long sys_clone_wrapper(unsigned long clone_flags,
unsigned long newsp,
void __user *parent_tid,
unsigned long tls_val,
void __user *child_tid);
asmlinkage long sys_rt_sigreturn_wrapper(void);
asmlinkage long sys_sigaltstack_wrapper(const stack_t __user *uss,
stack_t __user *uoss);
/*
* AArch64 sys_clone implementation has a different prototype than the generic
* one (additional TLS value argument).
*/
#define sys_clone sys_clone
#include <asm-generic/syscalls.h>
#endif /* __ASM_SYSCALLS_H */

View File

@ -23,7 +23,7 @@
__SYSCALL(0, sys_restart_syscall)
__SYSCALL(1, sys_exit)
__SYSCALL(2, compat_sys_fork_wrapper)
__SYSCALL(2, compat_sys_fork)
__SYSCALL(3, sys_read)
__SYSCALL(4, sys_write)
__SYSCALL(5, compat_sys_open)
@ -141,7 +141,7 @@ __SYSCALL(116, compat_sys_sysinfo)
__SYSCALL(117, sys_ni_syscall) /* 117 was sys_ipc */
__SYSCALL(118, sys_fsync)
__SYSCALL(119, compat_sys_sigreturn_wrapper)
__SYSCALL(120, compat_sys_clone_wrapper)
__SYSCALL(120, sys_clone)
__SYSCALL(121, sys_setdomainname)
__SYSCALL(122, sys_newuname)
__SYSCALL(123, sys_ni_syscall) /* 123 was sys_modify_ldt */
@ -211,7 +211,7 @@ __SYSCALL(186, compat_sys_sigaltstack_wrapper)
__SYSCALL(187, compat_sys_sendfile)
__SYSCALL(188, sys_ni_syscall) /* 188 reserved */
__SYSCALL(189, sys_ni_syscall) /* 189 reserved */
__SYSCALL(190, compat_sys_vfork_wrapper)
__SYSCALL(190, compat_sys_vfork)
__SYSCALL(191, compat_sys_getrlimit) /* SuS compliant getrlimit */
__SYSCALL(192, sys_mmap_pgoff)
__SYSCALL(193, compat_sys_truncate64_wrapper)

View File

@ -676,11 +676,6 @@ __sys_trace_return:
/*
* Special system call wrappers.
*/
ENTRY(sys_clone_wrapper)
mov x5, sp
b sys_clone
ENDPROC(sys_clone_wrapper)
ENTRY(sys_rt_sigreturn_wrapper)
mov x0, sp
b sys_rt_sigreturn

View File

@ -613,17 +613,11 @@ enum armv8_pmuv3_perf_types {
ARMV8_PMUV3_PERFCTR_BUS_ACCESS = 0x19,
ARMV8_PMUV3_PERFCTR_MEM_ERROR = 0x1A,
ARMV8_PMUV3_PERFCTR_BUS_CYCLES = 0x1D,
/*
* This isn't an architected event.
* We detect this event number and use the cycle counter instead.
*/
ARMV8_PMUV3_PERFCTR_CPU_CYCLES = 0xFF,
};
/* PMUv3 HW events mapping. */
static const unsigned armv8_pmuv3_perf_map[PERF_COUNT_HW_MAX] = {
[PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CPU_CYCLES,
[PERF_COUNT_HW_CPU_CYCLES] = ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES,
[PERF_COUNT_HW_INSTRUCTIONS] = ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED,
[PERF_COUNT_HW_CACHE_REFERENCES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_ACCESS,
[PERF_COUNT_HW_CACHE_MISSES] = ARMV8_PMUV3_PERFCTR_L1_DCACHE_REFILL,
@ -1106,7 +1100,7 @@ static int armv8pmu_get_event_idx(struct pmu_hw_events *cpuc,
unsigned long evtype = event->config_base & ARMV8_EVTYPE_EVENT;
/* Always place a cycle counter into the cycle counter. */
if (evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) {
if (evtype == ARMV8_PMUV3_PERFCTR_CLOCK_CYCLES) {
if (test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask))
return -EAGAIN;

View File

@ -246,14 +246,20 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
*childregs = *regs;
childregs->regs[0] = 0;
if (is_compat_thread(task_thread_info(p))) {
childregs->compat_sp = stack_start;
if (stack_start)
childregs->compat_sp = stack_start;
} else {
/*
* Read the current TLS pointer from tpidr_el0 as it may be
* out-of-sync with the saved value.
*/
asm("mrs %0, tpidr_el0" : "=r" (tls));
childregs->sp = stack_start;
if (stack_start) {
/* 16-byte aligned stack mandatory on AArch64 */
if (stack_start & 15)
return -EINVAL;
childregs->sp = stack_start;
}
}
/*
* If a TLS pointer was passed to clone (4th argument), use it
@ -317,24 +323,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
return last;
}
/*
* Fill in the task's elfregs structure for a core dump.
*/
int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs)
{
elf_core_copy_regs(elfregs, task_pt_regs(t));
return 1;
}
/*
* fill in the fpe structure for a core dump...
*/
int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
{
return 0;
}
EXPORT_SYMBOL(dump_fpu);
unsigned long get_wchan(struct task_struct *p)
{
struct stackframe frame;

View File

@ -31,14 +31,10 @@
*/
asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp,
int __user *parent_tidptr, unsigned long tls_val,
int __user *child_tidptr, struct pt_regs *regs)
int __user *child_tidptr)
{
if (!newsp)
newsp = regs->sp;
/* 16-byte aligned stack mandatory on AArch64 */
if (newsp & 15)
return -EINVAL;
return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
return do_fork(clone_flags, newsp, current_pt_regs(), 0,
parent_tidptr, child_tidptr);
}
asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
@ -54,7 +50,6 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
/*
* Wrappers to pass the pt_regs argument.
*/
#define sys_clone sys_clone_wrapper
#define sys_rt_sigreturn sys_rt_sigreturn_wrapper
#define sys_sigaltstack sys_sigaltstack_wrapper

View File

@ -26,20 +26,6 @@
/*
* System call wrappers for the AArch32 compatibility layer.
*/
compat_sys_fork_wrapper:
mov x0, sp
b compat_sys_fork
ENDPROC(compat_sys_fork_wrapper)
compat_sys_vfork_wrapper:
mov x0, sp
b compat_sys_vfork
ENDPROC(compat_sys_vfork_wrapper)
compat_sys_clone_wrapper:
mov x5, sp
b compat_sys_clone
ENDPROC(compat_sys_clone_wrapper)
compat_sys_sigreturn_wrapper:
mov x0, sp

View File

@ -28,25 +28,15 @@
#include <asm/cacheflush.h>
#include <asm/unistd32.h>
asmlinkage int compat_sys_fork(struct pt_regs *regs)
asmlinkage int compat_sys_fork(void)
{
return do_fork(SIGCHLD, regs->compat_sp, regs, 0, NULL, NULL);
return do_fork(SIGCHLD, 0, current_pt_regs(), 0, NULL, NULL);
}
asmlinkage int compat_sys_clone(unsigned long clone_flags, unsigned long newsp,
int __user *parent_tidptr, int tls_val,
int __user *child_tidptr, struct pt_regs *regs)
asmlinkage int compat_sys_vfork(void)
{
if (!newsp)
newsp = regs->compat_sp;
return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
}
asmlinkage int compat_sys_vfork(struct pt_regs *regs)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->compat_sp,
regs, 0, NULL, NULL);
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0,
current_pt_regs(), 0, NULL, NULL);
}
asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,

View File

@ -33,7 +33,6 @@
#ifndef _ASM_X86_XEN_HYPERVISOR_H
#define _ASM_X86_XEN_HYPERVISOR_H
/* arch/i386/kernel/setup.c */
extern struct shared_info *HYPERVISOR_shared_info;
extern struct start_info *xen_start_info;

View File

@ -1288,6 +1288,25 @@ unsigned long xen_read_cr2_direct(void)
return this_cpu_read(xen_vcpu_info.arch.cr2);
}
void xen_flush_tlb_all(void)
{
struct mmuext_op *op;
struct multicall_space mcs;
trace_xen_mmu_flush_tlb_all(0);
preempt_disable();
mcs = xen_mc_entry(sizeof(*op));
op = mcs.args;
op->cmd = MMUEXT_TLB_FLUSH_ALL;
MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
xen_mc_issue(PARAVIRT_LAZY_MMU);
preempt_enable();
}
static void xen_flush_tlb(void)
{
struct mmuext_op *op;
@ -2518,7 +2537,7 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
err = 0;
out:
flush_tlb_all();
xen_flush_tlb_all();
return err;
}

View File

@ -1345,12 +1345,15 @@ static int
acpi_video_bus_get_devices(struct acpi_video_bus *video,
struct acpi_device *device)
{
int status;
int status = 0;
struct acpi_device *dev;
status = acpi_video_device_enumerate(video);
if (status)
return status;
/*
* There are systems where video module known to work fine regardless
* of broken _DOD and ignoring returned value here doesn't cause
* any issues later.
*/
acpi_video_device_enumerate(video);
list_for_each_entry(dev, &device->children, node) {

View File

@ -5,7 +5,7 @@
* http://www.gnu.org/licenses/gpl.html
*
* Maintainer:
* Andreas Herrmann <andreas.herrmann3@amd.com>
* Andreas Herrmann <herrmann.der.user@googlemail.com>
*
* Based on the powernow-k7.c module written by Dave Jones.
* (C) 2003 Dave Jones on behalf of SuSE Labs

View File

@ -1,6 +1,6 @@
config DRM_EXYNOS
tristate "DRM Support for Samsung SoC EXYNOS Series"
depends on DRM && PLAT_SAMSUNG
depends on DRM && (PLAT_SAMSUNG || ARCH_MULTIPLATFORM)
select DRM_KMS_HELPER
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA

View File

@ -374,6 +374,7 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
exynos_connector->encoder_id = encoder->base.id;
exynos_connector->manager = manager;
exynos_connector->dpms = DRM_MODE_DPMS_OFF;
connector->dpms = DRM_MODE_DPMS_OFF;
connector->encoder = encoder;
err = drm_mode_connector_attach_encoder(connector, encoder);

View File

@ -43,12 +43,14 @@
* @manager: specific encoder has its own manager to control a hardware
* appropriately and we can access a hardware drawing on this manager.
* @dpms: store the encoder dpms value.
* @updated: indicate whether overlay data updating is needed or not.
*/
struct exynos_drm_encoder {
struct drm_crtc *old_crtc;
struct drm_encoder drm_encoder;
struct exynos_drm_manager *manager;
int dpms;
int dpms;
bool updated;
};
static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode)
@ -85,7 +87,9 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
switch (mode) {
case DRM_MODE_DPMS_ON:
if (manager_ops && manager_ops->apply)
manager_ops->apply(manager->dev);
if (!exynos_encoder->updated)
manager_ops->apply(manager->dev);
exynos_drm_connector_power(encoder, mode);
exynos_encoder->dpms = mode;
break;
@ -94,6 +98,7 @@ static void exynos_drm_encoder_dpms(struct drm_encoder *encoder, int mode)
case DRM_MODE_DPMS_OFF:
exynos_drm_connector_power(encoder, mode);
exynos_encoder->dpms = mode;
exynos_encoder->updated = false;
break;
default:
DRM_ERROR("unspecified mode %d\n", mode);
@ -205,13 +210,22 @@ static void exynos_drm_encoder_prepare(struct drm_encoder *encoder)
static void exynos_drm_encoder_commit(struct drm_encoder *encoder)
{
struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
struct exynos_drm_manager *manager = exynos_encoder->manager;
struct exynos_drm_manager_ops *manager_ops = manager->ops;
DRM_DEBUG_KMS("%s\n", __FILE__);
if (manager_ops && manager_ops->commit)
manager_ops->commit(manager->dev);
/*
* this will avoid one issue that overlay data is updated to
* real hardware two times.
* And this variable will be used to check if the data was
* already updated or not by exynos_drm_encoder_dpms function.
*/
exynos_encoder->updated = true;
}
static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
@ -400,19 +414,6 @@ void exynos_drm_encoder_crtc_dpms(struct drm_encoder *encoder, void *data)
if (manager_ops && manager_ops->dpms)
manager_ops->dpms(manager->dev, mode);
/*
* set current mode to new one so that data aren't updated into
* registers by drm_helper_connector_dpms two times.
*
* in case that drm_crtc_helper_set_mode() is called,
* overlay_ops->commit() and manager_ops->commit() callbacks
* can be called two times, first at drm_crtc_helper_set_mode()
* and second at drm_helper_connector_dpms().
* so with this setting, when drm_helper_connector_dpms() is called
* encoder->funcs->dpms() will be ignored.
*/
exynos_encoder->dpms = mode;
/*
* if this condition is ok then it means that the crtc is already
* detached from encoder and last function for detaching is properly

View File

@ -1142,7 +1142,7 @@ static int __devinit mixer_probe(struct platform_device *pdev)
const struct of_device_id *match;
match = of_match_node(of_match_ptr(mixer_match_types),
pdev->dev.of_node);
drv = match->data;
drv = (struct mixer_drv_data *)match->data;
} else {
drv = (struct mixer_drv_data *)
platform_get_device_id(pdev)->driver_data;

View File

@ -1505,7 +1505,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto put_gmch;
}
i915_kick_out_firmware_fb(dev_priv);
if (drm_core_check_feature(dev, DRIVER_MODESET))
i915_kick_out_firmware_fb(dev_priv);
pci_set_master(dev->pdev);

View File

@ -729,7 +729,7 @@ void intel_crt_init(struct drm_device *dev)
crt->base.type = INTEL_OUTPUT_ANALOG;
crt->base.cloneable = true;
if (IS_HASWELL(dev))
if (IS_HASWELL(dev) || IS_I830(dev))
crt->base.crtc_mask = (1 << 0);
else
crt->base.crtc_mask = (1 << 0) | (1 << 1) | (1 << 2);

View File

@ -341,9 +341,17 @@ static int intel_overlay_off(struct intel_overlay *overlay)
intel_ring_emit(ring, flip_addr);
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
/* turn overlay off */
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
intel_ring_emit(ring, flip_addr);
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
if (IS_I830(dev)) {
/* Workaround: Don't disable the overlay fully, since otherwise
* it dies on the next OVERLAY_ON cmd. */
intel_ring_emit(ring, MI_NOOP);
intel_ring_emit(ring, MI_NOOP);
intel_ring_emit(ring, MI_NOOP);
} else {
intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
intel_ring_emit(ring, flip_addr);
intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
}
intel_ring_advance(ring);
return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);

View File

@ -435,7 +435,7 @@ int intel_panel_setup_backlight(struct drm_device *dev)
props.type = BACKLIGHT_RAW;
props.max_brightness = _intel_panel_get_max_backlight(dev);
if (props.max_brightness == 0) {
DRM_ERROR("Failed to get maximum backlight value\n");
DRM_DEBUG_DRIVER("Failed to get maximum backlight value\n");
return -ENODEV;
}
dev_priv->backlight =

View File

@ -894,6 +894,45 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo)
}
#endif
static bool intel_sdvo_write_infoframe(struct intel_sdvo *intel_sdvo,
unsigned if_index, uint8_t tx_rate,
uint8_t *data, unsigned length)
{
uint8_t set_buf_index[2] = { if_index, 0 };
uint8_t hbuf_size, tmp[8];
int i;
if (!intel_sdvo_set_value(intel_sdvo,
SDVO_CMD_SET_HBUF_INDEX,
set_buf_index, 2))
return false;
if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HBUF_INFO,
&hbuf_size, 1))
return false;
/* Buffer size is 0 based, hooray! */
hbuf_size++;
DRM_DEBUG_KMS("writing sdvo hbuf: %i, hbuf_size %i, hbuf_size: %i\n",
if_index, length, hbuf_size);
for (i = 0; i < hbuf_size; i += 8) {
memset(tmp, 0, 8);
if (i < length)
memcpy(tmp, data + i, min_t(unsigned, 8, length - i));
if (!intel_sdvo_set_value(intel_sdvo,
SDVO_CMD_SET_HBUF_DATA,
tmp, 8))
return false;
}
return intel_sdvo_set_value(intel_sdvo,
SDVO_CMD_SET_HBUF_TXRATE,
&tx_rate, 1);
}
static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
{
struct dip_infoframe avi_if = {
@ -901,11 +940,7 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
.ver = DIP_VERSION_AVI,
.len = DIP_LEN_AVI,
};
uint8_t tx_rate = SDVO_HBUF_TX_VSYNC;
uint8_t set_buf_index[2] = { 1, 0 };
uint8_t sdvo_data[4 + sizeof(avi_if.body.avi)];
uint64_t *data = (uint64_t *)sdvo_data;
unsigned i;
intel_dip_infoframe_csum(&avi_if);
@ -915,22 +950,9 @@ static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo)
sdvo_data[3] = avi_if.checksum;
memcpy(&sdvo_data[4], &avi_if.body, sizeof(avi_if.body.avi));
if (!intel_sdvo_set_value(intel_sdvo,
SDVO_CMD_SET_HBUF_INDEX,
set_buf_index, 2))
return false;
for (i = 0; i < sizeof(sdvo_data); i += 8) {
if (!intel_sdvo_set_value(intel_sdvo,
SDVO_CMD_SET_HBUF_DATA,
data, 8))
return false;
data++;
}
return intel_sdvo_set_value(intel_sdvo,
SDVO_CMD_SET_HBUF_TXRATE,
&tx_rate, 1);
return intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_AVI_IF,
SDVO_HBUF_TX_VSYNC,
sdvo_data, sizeof(sdvo_data));
}
static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo)

View File

@ -708,6 +708,8 @@ struct intel_sdvo_enhancements_arg {
#define SDVO_CMD_SET_AUDIO_STAT 0x91
#define SDVO_CMD_GET_AUDIO_STAT 0x92
#define SDVO_CMD_SET_HBUF_INDEX 0x93
#define SDVO_HBUF_INDEX_ELD 0
#define SDVO_HBUF_INDEX_AVI_IF 1
#define SDVO_CMD_GET_HBUF_INDEX 0x94
#define SDVO_CMD_GET_HBUF_INFO 0x95
#define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96

View File

@ -264,7 +264,7 @@ static int evergreen_surface_check_2d(struct radeon_cs_parser *p,
/* macro tile width & height */
palign = (8 * surf->bankw * track->npipes) * surf->mtilea;
halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea;
mtileb = (palign / 8) * (halign / 8) * tileb;;
mtileb = (palign / 8) * (halign / 8) * tileb;
mtile_pr = surf->nbx / palign;
mtile_ps = (mtile_pr * surf->nby) / halign;
surf->layer_size = mtile_ps * mtileb * slice_pt;

View File

@ -352,9 +352,9 @@ static int radeon_atpx_switchto(enum vga_switcheroo_client_id id)
}
/**
* radeon_atpx_switchto - switch to the requested GPU
* radeon_atpx_power_state - power down/up the requested GPU
*
* @id: GPU to switch to
* @id: GPU to power down/up
* @state: requested power state (0 = off, 1 = on)
*
* Execute the necessary ATPX function to power down/up the discrete GPU

View File

@ -941,7 +941,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
struct drm_mode_object *obj;
int i;
enum drm_connector_status ret = connector_status_disconnected;
bool dret = false;
bool dret = false, broken_edid = false;
if (!force && radeon_check_hpd_status_unchanged(connector))
return connector->status;
@ -965,6 +965,9 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
ret = connector_status_disconnected;
DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector));
radeon_connector->ddc_bus = NULL;
} else {
ret = connector_status_connected;
broken_edid = true; /* defer use_digital to later */
}
} else {
radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
@ -1047,13 +1050,24 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
encoder_funcs = encoder->helper_private;
if (encoder_funcs->detect) {
if (ret != connector_status_connected) {
ret = encoder_funcs->detect(encoder, connector);
if (ret == connector_status_connected) {
radeon_connector->use_digital = false;
if (!broken_edid) {
if (ret != connector_status_connected) {
/* deal with analog monitors without DDC */
ret = encoder_funcs->detect(encoder, connector);
if (ret == connector_status_connected) {
radeon_connector->use_digital = false;
}
if (ret != connector_status_disconnected)
radeon_connector->detected_by_load = true;
}
if (ret != connector_status_disconnected)
radeon_connector->detected_by_load = true;
} else {
enum drm_connector_status lret;
/* assume digital unless load detected otherwise */
radeon_connector->use_digital = true;
lret = encoder_funcs->detect(encoder, connector);
DRM_DEBUG_KMS("load_detect %x returned: %x\n",encoder->encoder_type,lret);
if (lret == connector_status_connected)
radeon_connector->use_digital = false;
}
break;
}

View File

@ -295,6 +295,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
uint32_t crtc_ext_cntl = 0;
uint32_t mask;
if (radeon_crtc->crtc_id)
@ -307,6 +308,16 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
RADEON_CRTC_VSYNC_DIS |
RADEON_CRTC_HSYNC_DIS);
/*
* On all dual CRTC GPUs this bit controls the CRTC of the primary DAC.
* Therefore it is set in the DAC DMPS function.
* This is different for GPU's with a single CRTC but a primary and a
* TV DAC: here it controls the single CRTC no matter where it is
* routed. Therefore we set it here.
*/
if (rdev->flags & RADEON_SINGLE_CRTC)
crtc_ext_cntl = RADEON_CRTC_CRT_ON;
switch (mode) {
case DRM_MODE_DPMS_ON:
radeon_crtc->enabled = true;
@ -317,7 +328,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
else {
WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_EN, ~(RADEON_CRTC_EN |
RADEON_CRTC_DISP_REQ_EN_B));
WREG32_P(RADEON_CRTC_EXT_CNTL, 0, ~mask);
WREG32_P(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl, ~(mask | crtc_ext_cntl));
}
drm_vblank_post_modeset(dev, radeon_crtc->crtc_id);
radeon_crtc_load_lut(crtc);
@ -331,7 +342,7 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode)
else {
WREG32_P(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~(RADEON_CRTC_EN |
RADEON_CRTC_DISP_REQ_EN_B));
WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~mask);
WREG32_P(RADEON_CRTC_EXT_CNTL, mask, ~(mask | crtc_ext_cntl));
}
radeon_crtc->enabled = false;
/* adjust pm to dpms changes AFTER disabling crtcs */

View File

@ -537,7 +537,9 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode
break;
}
WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
/* handled in radeon_crtc_dpms() */
if (!(rdev->flags & RADEON_SINGLE_CRTC))
WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
WREG32(RADEON_DAC_CNTL, dac_cntl);
WREG32(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
@ -662,6 +664,8 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc
if (ASIC_IS_R300(rdev))
tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
else if (ASIC_IS_RV100(rdev))
tmp |= (0x1ac << RADEON_DAC_FORCE_DATA_SHIFT);
else
tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
@ -671,6 +675,7 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc
tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
WREG32(RADEON_DAC_CNTL, tmp);
tmp = dac_macro_cntl;
tmp &= ~(RADEON_DAC_PDWN_R |
RADEON_DAC_PDWN_G |
RADEON_DAC_PDWN_B);
@ -1092,7 +1097,8 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode)
} else {
if (is_tv)
WREG32(RADEON_TV_MASTER_CNTL, tv_master_cntl);
else
/* handled in radeon_crtc_dpms() */
else if (!(rdev->flags & RADEON_SINGLE_CRTC))
WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
}
@ -1416,13 +1422,104 @@ static bool radeon_legacy_tv_detect(struct drm_encoder *encoder,
return found;
}
static bool radeon_legacy_ext_dac_detect(struct drm_encoder *encoder,
struct drm_connector *connector)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
uint32_t gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl;
uint32_t disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c;
uint32_t disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f;
uint32_t tmp, crtc2_h_total_disp, crtc2_v_total_disp;
uint32_t crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid;
bool found = false;
int i;
/* save the regs we need */
gpio_monid = RREG32(RADEON_GPIO_MONID);
fp2_gen_cntl = RREG32(RADEON_FP2_GEN_CNTL);
disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
disp_lin_trans_grph_a = RREG32(RADEON_DISP_LIN_TRANS_GRPH_A);
disp_lin_trans_grph_b = RREG32(RADEON_DISP_LIN_TRANS_GRPH_B);
disp_lin_trans_grph_c = RREG32(RADEON_DISP_LIN_TRANS_GRPH_C);
disp_lin_trans_grph_d = RREG32(RADEON_DISP_LIN_TRANS_GRPH_D);
disp_lin_trans_grph_e = RREG32(RADEON_DISP_LIN_TRANS_GRPH_E);
disp_lin_trans_grph_f = RREG32(RADEON_DISP_LIN_TRANS_GRPH_F);
crtc2_h_total_disp = RREG32(RADEON_CRTC2_H_TOTAL_DISP);
crtc2_v_total_disp = RREG32(RADEON_CRTC2_V_TOTAL_DISP);
crtc2_h_sync_strt_wid = RREG32(RADEON_CRTC2_H_SYNC_STRT_WID);
crtc2_v_sync_strt_wid = RREG32(RADEON_CRTC2_V_SYNC_STRT_WID);
tmp = RREG32(RADEON_GPIO_MONID);
tmp &= ~RADEON_GPIO_A_0;
WREG32(RADEON_GPIO_MONID, tmp);
WREG32(RADEON_FP2_GEN_CNTL, (RADEON_FP2_ON |
RADEON_FP2_PANEL_FORMAT |
R200_FP2_SOURCE_SEL_TRANS_UNIT |
RADEON_FP2_DVO_EN |
R200_FP2_DVO_RATE_SEL_SDR));
WREG32(RADEON_DISP_OUTPUT_CNTL, (RADEON_DISP_DAC_SOURCE_RMX |
RADEON_DISP_TRANS_MATRIX_GRAPHICS));
WREG32(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_EN |
RADEON_CRTC2_DISP_REQ_EN_B));
WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
WREG32(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
WREG32(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
for (i = 0; i < 200; i++) {
tmp = RREG32(RADEON_GPIO_MONID);
if (tmp & RADEON_GPIO_Y_0)
found = true;
if (found)
break;
if (!drm_can_sleep())
mdelay(1);
else
msleep(1);
}
/* restore the regs we used */
WREG32(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a);
WREG32(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b);
WREG32(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c);
WREG32(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d);
WREG32(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e);
WREG32(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f);
WREG32(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp);
WREG32(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp);
WREG32(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid);
WREG32(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid);
WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
WREG32(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
WREG32(RADEON_GPIO_MONID, gpio_monid);
return found;
}
static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder,
struct drm_connector *connector)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp;
uint32_t crtc2_gen_cntl = 0, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
uint32_t gpiopad_a = 0, pixclks_cntl, tmp;
uint32_t disp_output_cntl = 0, disp_hw_debug = 0, crtc_ext_cntl = 0;
enum drm_connector_status found = connector_status_disconnected;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_tv_dac *tv_dac = radeon_encoder->enc_priv;
@ -1459,12 +1556,27 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
return connector_status_disconnected;
}
/* R200 uses an external DAC for secondary DAC */
if (rdev->family == CHIP_R200) {
if (radeon_legacy_ext_dac_detect(encoder, connector))
found = connector_status_connected;
return found;
}
/* save the regs we need */
pixclks_cntl = RREG32_PLL(RADEON_PIXCLKS_CNTL);
gpiopad_a = ASIC_IS_R300(rdev) ? RREG32(RADEON_GPIOPAD_A) : 0;
disp_output_cntl = ASIC_IS_R300(rdev) ? RREG32(RADEON_DISP_OUTPUT_CNTL) : 0;
disp_hw_debug = ASIC_IS_R300(rdev) ? 0 : RREG32(RADEON_DISP_HW_DEBUG);
crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
if (rdev->flags & RADEON_SINGLE_CRTC) {
crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL);
} else {
if (ASIC_IS_R300(rdev)) {
gpiopad_a = RREG32(RADEON_GPIOPAD_A);
disp_output_cntl = RREG32(RADEON_DISP_OUTPUT_CNTL);
} else {
disp_hw_debug = RREG32(RADEON_DISP_HW_DEBUG);
}
crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL);
}
tv_dac_cntl = RREG32(RADEON_TV_DAC_CNTL);
dac_ext_cntl = RREG32(RADEON_DAC_EXT_CNTL);
dac_cntl2 = RREG32(RADEON_DAC_CNTL2);
@ -1473,22 +1585,24 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
| RADEON_PIX2CLK_DAC_ALWAYS_ONb);
WREG32_PLL(RADEON_PIXCLKS_CNTL, tmp);
if (ASIC_IS_R300(rdev))
WREG32_P(RADEON_GPIOPAD_A, 1, ~1);
tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
tmp |= RADEON_CRTC2_CRT2_ON |
(2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
WREG32(RADEON_CRTC2_GEN_CNTL, tmp);
if (ASIC_IS_R300(rdev)) {
tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
WREG32(RADEON_DISP_OUTPUT_CNTL, tmp);
if (rdev->flags & RADEON_SINGLE_CRTC) {
tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON;
WREG32(RADEON_CRTC_EXT_CNTL, tmp);
} else {
tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
WREG32(RADEON_DISP_HW_DEBUG, tmp);
tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
tmp |= RADEON_CRTC2_CRT2_ON |
(2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
WREG32(RADEON_CRTC2_GEN_CNTL, tmp);
if (ASIC_IS_R300(rdev)) {
WREG32_P(RADEON_GPIOPAD_A, 1, ~1);
tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
WREG32(RADEON_DISP_OUTPUT_CNTL, tmp);
} else {
tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
WREG32(RADEON_DISP_HW_DEBUG, tmp);
}
}
tmp = RADEON_TV_DAC_NBLANK |
@ -1530,14 +1644,19 @@ static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder
WREG32(RADEON_DAC_CNTL2, dac_cntl2);
WREG32(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
WREG32(RADEON_TV_DAC_CNTL, tv_dac_cntl);
WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
if (ASIC_IS_R300(rdev)) {
WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
if (rdev->flags & RADEON_SINGLE_CRTC) {
WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
} else {
WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
if (ASIC_IS_R300(rdev)) {
WREG32(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
WREG32_P(RADEON_GPIOPAD_A, gpiopad_a, ~1);
} else {
WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
}
}
WREG32_PLL(RADEON_PIXCLKS_CNTL, pixclks_cntl);
return found;

View File

@ -104,7 +104,7 @@ udl_fb_user_fb_create(struct drm_device *dev,
int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
const char *front, char **urb_buf_ptr,
u32 byte_offset, u32 byte_width,
u32 byte_offset, u32 device_byte_offset, u32 byte_width,
int *ident_ptr, int *sent_ptr);
int udl_dumb_create(struct drm_file *file_priv,

View File

@ -114,9 +114,10 @@ static void udlfb_dpy_deferred_io(struct fb_info *info,
list_for_each_entry(cur, &fbdefio->pagelist, lru) {
if (udl_render_hline(dev, (ufbdev->ufb.base.bits_per_pixel / 8),
&urb, (char *) info->fix.smem_start,
&cmd, cur->index << PAGE_SHIFT,
PAGE_SIZE, &bytes_identical, &bytes_sent))
&urb, (char *) info->fix.smem_start,
&cmd, cur->index << PAGE_SHIFT,
cur->index << PAGE_SHIFT,
PAGE_SIZE, &bytes_identical, &bytes_sent))
goto error;
bytes_rendered += PAGE_SIZE;
}
@ -187,10 +188,11 @@ int udl_handle_damage(struct udl_framebuffer *fb, int x, int y,
for (i = y; i < y + height ; i++) {
const int line_offset = fb->base.pitches[0] * i;
const int byte_offset = line_offset + (x * bpp);
const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp);
if (udl_render_hline(dev, bpp, &urb,
(char *) fb->obj->vmapping,
&cmd, byte_offset, width * bpp,
&cmd, byte_offset, dev_byte_offset,
width * bpp,
&bytes_identical, &bytes_sent))
goto error;
}

View File

@ -213,11 +213,12 @@ static void udl_compress_hline16(
*/
int udl_render_hline(struct drm_device *dev, int bpp, struct urb **urb_ptr,
const char *front, char **urb_buf_ptr,
u32 byte_offset, u32 byte_width,
u32 byte_offset, u32 device_byte_offset,
u32 byte_width,
int *ident_ptr, int *sent_ptr)
{
const u8 *line_start, *line_end, *next_pixel;
u32 base16 = 0 + (byte_offset / bpp) * 2;
u32 base16 = 0 + (device_byte_offset / bpp) * 2;
struct urb *urb = *urb_ptr;
u8 *cmd = *urb_buf_ptr;
u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length;

View File

@ -2,7 +2,7 @@
* fam15h_power.c - AMD Family 15h processor power monitoring
*
* Copyright (c) 2011 Advanced Micro Devices, Inc.
* Author: Andreas Herrmann <andreas.herrmann3@amd.com>
* Author: Andreas Herrmann <herrmann.der.user@googlemail.com>
*
*
* This driver is free software; you can redistribute it and/or
@ -28,7 +28,7 @@
#include <asm/processor.h>
MODULE_DESCRIPTION("AMD Family 15h CPU processor power monitor");
MODULE_AUTHOR("Andreas Herrmann <andreas.herrmann3@amd.com>");
MODULE_AUTHOR("Andreas Herrmann <herrmann.der.user@googlemail.com>");
MODULE_LICENSE("GPL");
/* D18F3 */

View File

@ -630,7 +630,9 @@ static struct platform_driver gpio_fan_driver = {
.driver = {
.name = "gpio-fan",
.pm = GPIO_FAN_PM,
#ifdef CONFIG_OF_GPIO
.of_match_table = of_match_ptr(of_gpio_fan_match),
#endif
},
};

View File

@ -1,7 +1,7 @@
/*
* Freescale MXS I2C bus driver
*
* Copyright (C) 2011 Wolfram Sang, Pengutronix e.K.
* Copyright (C) 2011-2012 Wolfram Sang, Pengutronix e.K.
*
* based on a (non-working) driver which was:
*
@ -35,10 +35,6 @@
#define DRIVER_NAME "mxs-i2c"
static bool use_pioqueue;
module_param(use_pioqueue, bool, 0);
MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA");
#define MXS_I2C_CTRL0 (0x00)
#define MXS_I2C_CTRL0_SET (0x04)
@ -75,23 +71,6 @@ MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA");
MXS_I2C_CTRL1_SLAVE_STOP_IRQ | \
MXS_I2C_CTRL1_SLAVE_IRQ)
#define MXS_I2C_QUEUECTRL (0x60)
#define MXS_I2C_QUEUECTRL_SET (0x64)
#define MXS_I2C_QUEUECTRL_CLR (0x68)
#define MXS_I2C_QUEUECTRL_QUEUE_RUN 0x20
#define MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE 0x04
#define MXS_I2C_QUEUESTAT (0x70)
#define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000
#define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK 0x0000001F
#define MXS_I2C_QUEUECMD (0x80)
#define MXS_I2C_QUEUEDATA (0x90)
#define MXS_I2C_DATA (0xa0)
#define MXS_CMD_I2C_SELECT (MXS_I2C_CTRL0_RETAIN_CLOCK | \
MXS_I2C_CTRL0_PRE_SEND_START | \
@ -153,7 +132,6 @@ struct mxs_i2c_dev {
const struct mxs_i2c_speed_config *speed;
/* DMA support components */
bool dma_mode;
int dma_channel;
struct dma_chan *dmach;
struct mxs_dma_data dma_data;
@ -172,99 +150,6 @@ static void mxs_i2c_reset(struct mxs_i2c_dev *i2c)
writel(i2c->speed->timing2, i2c->regs + MXS_I2C_TIMING2);
writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
if (i2c->dma_mode)
writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,
i2c->regs + MXS_I2C_QUEUECTRL_CLR);
else
writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,
i2c->regs + MXS_I2C_QUEUECTRL_SET);
}
static void mxs_i2c_pioq_setup_read(struct mxs_i2c_dev *i2c, u8 addr, int len,
int flags)
{
u32 data;
writel(MXS_CMD_I2C_SELECT, i2c->regs + MXS_I2C_QUEUECMD);
data = (addr << 1) | I2C_SMBUS_READ;
writel(data, i2c->regs + MXS_I2C_DATA);
data = MXS_CMD_I2C_READ | MXS_I2C_CTRL0_XFER_COUNT(len) | flags;
writel(data, i2c->regs + MXS_I2C_QUEUECMD);
}
static void mxs_i2c_pioq_setup_write(struct mxs_i2c_dev *i2c,
u8 addr, u8 *buf, int len, int flags)
{
u32 data;
int i, shifts_left;
data = MXS_CMD_I2C_WRITE | MXS_I2C_CTRL0_XFER_COUNT(len + 1) | flags;
writel(data, i2c->regs + MXS_I2C_QUEUECMD);
/*
* We have to copy the slave address (u8) and buffer (arbitrary number
* of u8) into the data register (u32). To achieve that, the u8 are put
* into the MSBs of 'data' which is then shifted for the next u8. When
* appropriate, 'data' is written to MXS_I2C_DATA. So, the first u32
* looks like this:
*
* 3 2 1 0
* 10987654|32109876|54321098|76543210
* --------+--------+--------+--------
* buffer+2|buffer+1|buffer+0|slave_addr
*/
data = ((addr << 1) | I2C_SMBUS_WRITE) << 24;
for (i = 0; i < len; i++) {
data >>= 8;
data |= buf[i] << 24;
if ((i & 3) == 2)
writel(data, i2c->regs + MXS_I2C_DATA);
}
/* Write out the remaining bytes if any */
shifts_left = 24 - (i & 3) * 8;
if (shifts_left)
writel(data >> shifts_left, i2c->regs + MXS_I2C_DATA);
}
/*
* TODO: should be replaceable with a waitqueue and RD_QUEUE_IRQ (setting the
* rd_threshold to 1). Couldn't get this to work, though.
*/
static int mxs_i2c_wait_for_data(struct mxs_i2c_dev *i2c)
{
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
while (readl(i2c->regs + MXS_I2C_QUEUESTAT)
& MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY) {
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
cond_resched();
}
return 0;
}
static int mxs_i2c_finish_read(struct mxs_i2c_dev *i2c, u8 *buf, int len)
{
u32 uninitialized_var(data);
int i;
for (i = 0; i < len; i++) {
if ((i & 3) == 0) {
if (mxs_i2c_wait_for_data(i2c))
return -ETIMEDOUT;
data = readl(i2c->regs + MXS_I2C_QUEUEDATA);
}
buf[i] = data & 0xff;
data >>= 8;
}
return 0;
}
static void mxs_i2c_dma_finish(struct mxs_i2c_dev *i2c)
@ -432,39 +317,17 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
init_completion(&i2c->cmd_complete);
i2c->cmd_err = 0;
if (i2c->dma_mode) {
ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
if (ret)
return ret;
} else {
if (msg->flags & I2C_M_RD) {
mxs_i2c_pioq_setup_read(i2c, msg->addr,
msg->len, flags);
} else {
mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf,
msg->len, flags);
}
writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
i2c->regs + MXS_I2C_QUEUECTRL_SET);
}
ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
if (ret)
return ret;
ret = wait_for_completion_timeout(&i2c->cmd_complete,
msecs_to_jiffies(1000));
if (ret == 0)
goto timeout;
if (!i2c->dma_mode && !i2c->cmd_err && (msg->flags & I2C_M_RD)) {
ret = mxs_i2c_finish_read(i2c, msg->buf, msg->len);
if (ret)
goto timeout;
}
if (i2c->cmd_err == -ENXIO)
mxs_i2c_reset(i2c);
else
writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
i2c->regs + MXS_I2C_QUEUECTRL_CLR);
dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err);
@ -472,8 +335,7 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
timeout:
dev_dbg(i2c->dev, "Timeout!\n");
if (i2c->dma_mode)
mxs_i2c_dma_finish(i2c);
mxs_i2c_dma_finish(i2c);
mxs_i2c_reset(i2c);
return -ETIMEDOUT;
}
@ -502,7 +364,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)
{
struct mxs_i2c_dev *i2c = dev_id;
u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK;
bool is_last_cmd;
if (!stat)
return IRQ_NONE;
@ -515,14 +376,6 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)
/* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */
i2c->cmd_err = -EIO;
if (!i2c->dma_mode) {
is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &
MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0;
if (is_last_cmd || i2c->cmd_err)
complete(&i2c->cmd_complete);
}
writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR);
return IRQ_HANDLED;
@ -555,15 +408,6 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)
struct device_node *node = dev->of_node;
int ret;
/*
* The MXS I2C DMA mode is prefered and enabled by default.
* The PIO mode is still supported, but should be used only
* for debuging purposes etc.
*/
i2c->dma_mode = !use_pioqueue;
if (!i2c->dma_mode)
dev_info(dev, "Using PIOQUEUE mode for I2C transfers!\n");
/*
* TODO: This is a temporary solution and should be changed
* to use generic DMA binding later when the helpers get in.
@ -571,8 +415,8 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)
ret = of_property_read_u32(node, "fsl,i2c-dma-channel",
&i2c->dma_channel);
if (ret) {
dev_warn(dev, "Failed to get DMA channel, using PIOQUEUE!\n");
i2c->dma_mode = 0;
dev_err(dev, "Failed to get DMA channel!\n");
return -ENODEV;
}
ret = of_property_read_u32(node, "clock-frequency", &speed);
@ -634,15 +478,13 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev)
}
/* Setup the DMA */
if (i2c->dma_mode) {
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
i2c->dma_data.chan_irq = dmairq;
i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c);
if (!i2c->dmach) {
dev_err(dev, "Failed to request dma\n");
return -ENODEV;
}
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
i2c->dma_data.chan_irq = dmairq;
i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c);
if (!i2c->dmach) {
dev_err(dev, "Failed to request dma\n");
return -ENODEV;
}
platform_set_drvdata(pdev, i2c);

View File

@ -644,7 +644,11 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
pm_runtime_get_sync(&dev->adev->dev);
clk_enable(dev->clk);
status = clk_prepare_enable(dev->clk);
if (status) {
dev_err(&dev->adev->dev, "can't prepare_enable clock\n");
goto out_clk;
}
status = init_hw(dev);
if (status)
@ -671,7 +675,8 @@ static int nmk_i2c_xfer(struct i2c_adapter *i2c_adap,
}
out:
clk_disable(dev->clk);
clk_disable_unprepare(dev->clk);
out_clk:
pm_runtime_put_sync(&dev->adev->dev);
dev->busy = false;

View File

@ -742,7 +742,7 @@ static int __devinit tegra_i2c_probe(struct platform_device *pdev)
}
ret = devm_request_irq(&pdev->dev, i2c_dev->irq,
tegra_i2c_isr, 0, pdev->name, i2c_dev);
tegra_i2c_isr, 0, dev_name(&pdev->dev), i2c_dev);
if (ret) {
dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq);
return ret;

View File

@ -335,6 +335,7 @@ config KEYBOARD_LOCOMO
config KEYBOARD_LPC32XX
tristate "LPC32XX matrix key scanner support"
depends on ARCH_LPC32XX && OF
select INPUT_MATRIXKMAP
help
Say Y here if you want to use NXP LPC32XX SoC key scanner interface,
connected to a key matrix.

View File

@ -368,6 +368,9 @@ static void pxa27x_keypad_config(struct pxa27x_keypad *keypad)
unsigned int mask = 0, direct_key_num = 0;
unsigned long kpc = 0;
/* clear pending interrupt bit */
keypad_readl(KPC);
/* enable matrix keys with automatic scan */
if (pdata->matrix_key_rows && pdata->matrix_key_cols) {
kpc |= KPC_ASACT | KPC_MIE | KPC_ME | KPC_MS_ALL;

View File

@ -311,7 +311,6 @@ static void xenkbd_backend_changed(struct xenbus_device *dev,
case XenbusStateReconfiguring:
case XenbusStateReconfigured:
case XenbusStateUnknown:
case XenbusStateClosed:
break;
case XenbusStateInitWait:
@ -350,6 +349,10 @@ InitWait:
break;
case XenbusStateClosed:
if (dev->state == XenbusStateClosed)
break;
/* Missed the backend's CLOSING state -- fallthrough */
case XenbusStateClosing:
xenbus_frontend_closed(dev);
break;

View File

@ -391,7 +391,7 @@ static int wacom_parse_hid(struct usb_interface *intf,
features->pktlen = WACOM_PKGLEN_TPC2FG;
}
if (features->type == MTSCREEN || WACOM_24HDT)
if (features->type == MTSCREEN || features->type == WACOM_24HDT)
features->pktlen = WACOM_PKGLEN_MTOUCH;
if (features->type == BAMBOO_PT) {

View File

@ -1518,6 +1518,9 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev,
input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
input_set_abs_params(input_dev, ABS_THROTTLE, 0, 71, 0, 0);
__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
wacom_setup_cintiq(wacom_wac);
break;

View File

@ -239,7 +239,7 @@ config TOUCHSCREEN_EETI
config TOUCHSCREEN_EGALAX
tristate "EETI eGalax multi-touch panel support"
depends on I2C
depends on I2C && OF
help
Say Y here to enable support for I2C connected EETI
eGalax multi-touch panels.

View File

@ -28,6 +28,7 @@
#include <linux/slab.h>
#include <linux/bitops.h>
#include <linux/input/mt.h>
#include <linux/of_gpio.h>
/*
* Mouse Mode: some panel may configure the controller to mouse mode,
@ -122,9 +123,17 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
/* wake up controller by an falling edge of interrupt gpio. */
static int egalax_wake_up_device(struct i2c_client *client)
{
int gpio = irq_to_gpio(client->irq);
struct device_node *np = client->dev.of_node;
int gpio;
int ret;
if (!np)
return -ENODEV;
gpio = of_get_named_gpio(np, "wakeup-gpios", 0);
if (!gpio_is_valid(gpio))
return -ENODEV;
ret = gpio_request(gpio, "egalax_irq");
if (ret < 0) {
dev_err(&client->dev,
@ -181,7 +190,11 @@ static int __devinit egalax_ts_probe(struct i2c_client *client,
ts->input_dev = input_dev;
/* controller may be in sleep, wake it up. */
egalax_wake_up_device(client);
error = egalax_wake_up_device(client);
if (error) {
dev_err(&client->dev, "Failed to wake up the controller\n");
goto err_free_dev;
}
ret = egalax_firmware_version(client);
if (ret < 0) {
@ -274,11 +287,17 @@ static int egalax_ts_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(egalax_ts_pm_ops, egalax_ts_suspend, egalax_ts_resume);
static struct of_device_id egalax_ts_dt_ids[] = {
{ .compatible = "eeti,egalax_ts" },
{ /* sentinel */ }
};
static struct i2c_driver egalax_ts_driver = {
.driver = {
.name = "egalax_ts",
.owner = THIS_MODULE,
.pm = &egalax_ts_pm_ops,
.of_match_table = of_match_ptr(egalax_ts_dt_ids),
},
.id_table = egalax_ts_id,
.probe = egalax_ts_probe,

View File

@ -107,7 +107,6 @@ static int tsc_connect(struct serio *serio, struct serio_driver *drv)
__set_bit(BTN_TOUCH, input_dev->keybit);
input_set_abs_params(ptsc->dev, ABS_X, 0, 0x3ff, 0, 0);
input_set_abs_params(ptsc->dev, ABS_Y, 0, 0x3ff, 0, 0);
input_set_abs_params(ptsc->dev, ABS_PRESSURE, 0, 0, 0, 0);
serio_set_drvdata(serio, ptsc);

View File

@ -1060,7 +1060,7 @@ static ssize_t bonding_store_primary(struct device *d,
goto out;
}
sscanf(buf, "%16s", ifname); /* IFNAMSIZ */
sscanf(buf, "%15s", ifname); /* IFNAMSIZ */
/* check to see if we are clearing primary */
if (!strlen(ifname) || buf[0] == '\n') {
@ -1237,7 +1237,7 @@ static ssize_t bonding_store_active_slave(struct device *d,
goto out;
}
sscanf(buf, "%16s", ifname); /* IFNAMSIZ */
sscanf(buf, "%15s", ifname); /* IFNAMSIZ */
/* check to see if we are clearing active */
if (!strlen(ifname) || buf[0] == '\n') {

View File

@ -137,7 +137,16 @@
#define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
#define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
#define LINK_UPDATE_MASK \
(LINK_STATUS_SPEED_AND_DUPLEX_MASK | \
LINK_STATUS_LINK_UP | \
LINK_STATUS_PHYSICAL_LINK_FLAG | \
LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \
LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \
LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \
LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \
LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \
LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE)
#define SFP_EEPROM_CON_TYPE_ADDR 0x2
#define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
@ -3295,6 +3304,21 @@ static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
DEFAULT_PHY_DEV_ADDR);
}
static void bnx2x_xgxs_specific_func(struct bnx2x_phy *phy,
struct link_params *params,
u32 action)
{
struct bnx2x *bp = params->bp;
switch (action) {
case PHY_INIT:
/* Set correct devad */
REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + params->port*0x18, 0);
REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
phy->def_md_devad);
break;
}
}
static void bnx2x_xgxs_deassert(struct link_params *params)
{
struct bnx2x *bp = params->bp;
@ -3309,10 +3333,8 @@ static void bnx2x_xgxs_deassert(struct link_params *params)
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
udelay(500);
REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0);
REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
params->phy[INT_PHY].def_md_devad);
bnx2x_xgxs_specific_func(&params->phy[INT_PHY], params,
PHY_INIT);
}
static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
@ -3545,14 +3567,11 @@ static void bnx2x_warpcore_set_lpi_passthrough(struct bnx2x_phy *phy,
static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
struct link_params *params,
struct link_vars *vars) {
u16 val16 = 0, lane, i;
u16 lane, i, cl72_ctrl, an_adv = 0;
u16 ucode_ver;
struct bnx2x *bp = params->bp;
static struct bnx2x_reg_set reg_set[] = {
{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
{MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0},
{MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0},
{MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0xff},
{MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0x5555},
{MDIO_PMA_DEVAD, MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0},
{MDIO_WC_DEVAD, MDIO_WC_REG_RX66_CONTROL, 0x7415},
{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190},
@ -3565,12 +3584,19 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg,
reg_set[i].val);
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, &cl72_ctrl);
cl72_ctrl &= 0xf8ff;
cl72_ctrl |= 0x3800;
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, cl72_ctrl);
/* Check adding advertisement for 1G KX */
if (((vars->line_speed == SPEED_AUTO_NEG) &&
(phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
(vars->line_speed == SPEED_1000)) {
u32 addr = MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2;
val16 |= (1<<5);
an_adv |= (1<<5);
/* Enable CL37 1G Parallel Detect */
bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD, addr, 0x1);
@ -3580,11 +3606,14 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
(phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
(vars->line_speed == SPEED_10000)) {
/* Check adding advertisement for 10G KR */
val16 |= (1<<7);
an_adv |= (1<<7);
/* Enable 10G Parallel Detect */
CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
MDIO_AER_BLOCK_AER_REG, 0);
bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
bnx2x_set_aer_mmd(params, phy);
DP(NETIF_MSG_LINK, "Advertize 10G\n");
}
@ -3604,7 +3633,7 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
/* Advertised speeds */
bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16);
MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, an_adv);
/* Advertised and set FEC (Forward Error Correction) */
bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
@ -3628,9 +3657,10 @@ static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
/* Set KR Autoneg Work-Around flag for Warpcore version older than D108
*/
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_UC_INFO_B1_VERSION, &val16);
if (val16 < 0xd108) {
DP(NETIF_MSG_LINK, "Enable AN KR work-around\n");
MDIO_WC_REG_UC_INFO_B1_VERSION, &ucode_ver);
if (ucode_ver < 0xd108) {
DP(NETIF_MSG_LINK, "Enable AN KR work-around. WC ver:0x%x\n",
ucode_ver);
vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
}
bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
@ -3651,21 +3681,16 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy,
struct link_vars *vars)
{
struct bnx2x *bp = params->bp;
u16 i;
u16 val16, i, lane;
static struct bnx2x_reg_set reg_set[] = {
/* Disable Autoneg */
{MDIO_WC_DEVAD, MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7},
{MDIO_AN_DEVAD, MDIO_WC_REG_PAR_DET_10G_CTRL, 0},
{MDIO_WC_DEVAD, MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
0x3f00},
{MDIO_AN_DEVAD, MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0},
{MDIO_AN_DEVAD, MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0},
{MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL3_UP1, 0x1},
{MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC7, 0xa},
/* Disable CL36 PCS Tx */
{MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0},
/* Double Wide Single Data Rate @ pll rate */
{MDIO_WC_DEVAD, MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF},
/* Leave cl72 training enable, needed for KR */
{MDIO_PMA_DEVAD,
MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150,
@ -3676,11 +3701,24 @@ static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy,
bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg,
reg_set[i].val);
/* Leave CL72 enabled */
bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
0x3800);
lane = bnx2x_get_warpcore_lane(phy, params);
/* Global registers */
CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
MDIO_AER_BLOCK_AER_REG, 0);
/* Disable CL36 PCS Tx */
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
val16 &= ~(0x0011 << lane);
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
val16 |= (0x0303 << (lane << 1));
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
/* Restore AER */
bnx2x_set_aer_mmd(params, phy);
/* Set speed via PMA/PMD register */
bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
@ -4303,7 +4341,7 @@ static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
struct link_params *params)
{
struct bnx2x *bp = params->bp;
u16 val16;
u16 val16, lane;
bnx2x_sfp_e3_set_transmitter(params, phy, 0);
bnx2x_set_mdio_clk(bp, params->chip_id, params->port);
bnx2x_set_aer_mmd(params, phy);
@ -4340,6 +4378,30 @@ static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
MDIO_WC_REG_XGXSBLK1_LANECTRL2,
val16 & 0xff00);
lane = bnx2x_get_warpcore_lane(phy, params);
/* Disable CL36 PCS Tx */
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_XGXSBLK1_LANECTRL0, &val16);
val16 |= (0x11 << lane);
if (phy->flags & FLAGS_WC_DUAL_MODE)
val16 |= (0x22 << lane);
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_XGXSBLK1_LANECTRL0, val16);
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_XGXSBLK1_LANECTRL1, &val16);
val16 &= ~(0x0303 << (lane << 1));
val16 |= (0x0101 << (lane << 1));
if (phy->flags & FLAGS_WC_DUAL_MODE) {
val16 &= ~(0x0c0c << (lane << 1));
val16 |= (0x0404 << (lane << 1));
}
bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_XGXSBLK1_LANECTRL1, val16);
/* Restore AER */
bnx2x_set_aer_mmd(params, phy);
}
static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy,
@ -6296,15 +6358,7 @@ static int bnx2x_update_link_down(struct link_params *params,
vars->mac_type = MAC_TYPE_NONE;
/* Update shared memory */
vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK |
LINK_STATUS_LINK_UP |
LINK_STATUS_PHYSICAL_LINK_FLAG |
LINK_STATUS_AUTO_NEGOTIATE_COMPLETE |
LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK |
LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK |
LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK |
LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE |
LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE);
vars->link_status &= ~LINK_UPDATE_MASK;
vars->line_speed = 0;
bnx2x_update_mng(params, vars->link_status);
@ -6452,6 +6506,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
u8 active_external_phy = INT_PHY;
vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
vars->link_status &= ~LINK_UPDATE_MASK;
for (phy_index = INT_PHY; phy_index < params->num_phys;
phy_index++) {
phy_vars[phy_index].flow_ctrl = 0;
@ -7579,7 +7634,7 @@ static void bnx2x_warpcore_power_module(struct link_params *params,
static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
struct link_params *params,
u16 addr, u8 byte_cnt,
u8 *o_buf)
u8 *o_buf, u8 is_init)
{
int rc = 0;
u8 i, j = 0, cnt = 0;
@ -7596,10 +7651,10 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
/* 4 byte aligned address */
addr32 = addr & (~0x3);
do {
if (cnt == I2C_WA_PWR_ITER) {
if ((!is_init) && (cnt == I2C_WA_PWR_ITER)) {
bnx2x_warpcore_power_module(params, phy, 0);
/* Note that 100us are not enough here */
usleep_range(1000,1000);
usleep_range(1000, 2000);
bnx2x_warpcore_power_module(params, phy, 1);
}
rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt,
@ -7719,7 +7774,7 @@ int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
break;
case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr,
byte_cnt, o_buf);
byte_cnt, o_buf, 0);
break;
}
return rc;
@ -7923,6 +7978,7 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
{
u8 val;
int rc;
struct bnx2x *bp = params->bp;
u16 timeout;
/* Initialization time after hot-plug may take up to 300ms for
@ -7930,8 +7986,14 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
*/
for (timeout = 0; timeout < 60; timeout++) {
if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
== 0) {
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
rc = bnx2x_warpcore_read_sfp_module_eeprom(phy,
params, 1,
1, &val, 1);
else
rc = bnx2x_read_sfp_module_eeprom(phy, params, 1, 1,
&val);
if (rc == 0) {
DP(NETIF_MSG_LINK,
"SFP+ module initialization took %d ms\n",
timeout * 5);
@ -7939,7 +8001,8 @@ static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
}
usleep_range(5000, 10000);
}
return -EINVAL;
rc = bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val);
return rc;
}
static void bnx2x_8727_power_module(struct bnx2x *bp,
@ -10993,7 +11056,7 @@ static struct bnx2x_phy phy_xgxs = {
.format_fw_ver = (format_fw_ver_t)NULL,
.hw_reset = (hw_reset_t)NULL,
.set_link_led = (set_link_led_t)NULL,
.phy_specific_func = (phy_specific_func_t)NULL
.phy_specific_func = (phy_specific_func_t)bnx2x_xgxs_specific_func
};
static struct bnx2x_phy phy_warpcore = {
.type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
@ -11465,6 +11528,11 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
phy->media_type = ETH_PHY_BASE_T;
break;
case PORT_HW_CFG_NET_SERDES_IF_XFI:
phy->supported &= (SUPPORTED_1000baseT_Full |
SUPPORTED_10000baseT_Full |
SUPPORTED_FIBRE |
SUPPORTED_Pause |
SUPPORTED_Asym_Pause);
phy->media_type = ETH_PHY_XFP_FIBER;
break;
case PORT_HW_CFG_NET_SERDES_IF_SFI:

View File

@ -6794,8 +6794,9 @@ static int bnx2x_init_hw_port(struct bnx2x *bp)
bnx2x_init_block(bp, BLOCK_DORQ, init_phase);
bnx2x_init_block(bp, BLOCK_BRB1, init_phase);
if (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) {
bnx2x_init_block(bp, BLOCK_BRB1, init_phase);
if (IS_MF(bp))
low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246);
@ -11902,7 +11903,15 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
/* disable FCOE L2 queue for E1x */
if (CHIP_IS_E1x(bp))
bp->flags |= NO_FCOE_FLAG;
/* disable FCOE for 57840 device, until FW supports it */
switch (ent->driver_data) {
case BCM57840_O:
case BCM57840_4_10:
case BCM57840_2_20:
case BCM57840_MFO:
case BCM57840_MF:
bp->flags |= NO_FCOE_FLAG;
}
#endif

View File

@ -3415,16 +3415,6 @@ static int adap_init0_config(struct adapter *adapter, int reset)
"mismatch: [fini] csum=%#x, computed csum=%#x\n",
finicsum, cfcsum);
/*
* If we're a pure NIC driver then disable all offloading facilities.
* This will allow the firmware to optimize aspects of the hardware
* configuration which will result in improved performance.
*/
caps_cmd.ofldcaps = 0;
caps_cmd.iscsicaps = 0;
caps_cmd.rdmacaps = 0;
caps_cmd.fcoecaps = 0;
/*
* And now tell the firmware to use the configuration we just loaded.
*/

View File

@ -2673,6 +2673,9 @@ static int ixgbe_get_ts_info(struct net_device *dev,
case ixgbe_mac_X540:
case ixgbe_mac_82599EB:
info->so_timestamping =
SOF_TIMESTAMPING_TX_SOFTWARE |
SOF_TIMESTAMPING_RX_SOFTWARE |
SOF_TIMESTAMPING_SOFTWARE |
SOF_TIMESTAMPING_TX_HARDWARE |
SOF_TIMESTAMPING_RX_HARDWARE |
SOF_TIMESTAMPING_RAW_HARDWARE;

View File

@ -1524,6 +1524,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev)
pldat->dma_buff_base_p);
free_irq(ndev->irq, ndev);
iounmap(pldat->net_base);
mdiobus_unregister(pldat->mii_bus);
mdiobus_free(pldat->mii_bus);
clk_disable(pldat->clk);
clk_put(pldat->clk);

View File

@ -234,6 +234,7 @@ void free_mdio_bitbang(struct mii_bus *bus)
struct mdiobb_ctrl *ctrl = bus->priv;
module_put(ctrl->ops->owner);
mdiobus_unregister(bus);
mdiobus_free(bus);
}
EXPORT_SYMBOL(free_mdio_bitbang);

View File

@ -744,28 +744,43 @@ vmxnet3_map_pkt(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx,
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
u32 buf_size;
tbi = tq->buf_info + tq->tx_ring.next2fill;
tbi->map_type = VMXNET3_MAP_PAGE;
tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag,
0, skb_frag_size(frag),
DMA_TO_DEVICE);
buf_offset = 0;
len = skb_frag_size(frag);
while (len) {
tbi = tq->buf_info + tq->tx_ring.next2fill;
if (len < VMXNET3_MAX_TX_BUF_SIZE) {
buf_size = len;
dw2 |= len;
} else {
buf_size = VMXNET3_MAX_TX_BUF_SIZE;
/* spec says that for TxDesc.len, 0 == 2^14 */
}
tbi->map_type = VMXNET3_MAP_PAGE;
tbi->dma_addr = skb_frag_dma_map(&adapter->pdev->dev, frag,
buf_offset, buf_size,
DMA_TO_DEVICE);
tbi->len = skb_frag_size(frag);
tbi->len = buf_size;
gdesc = tq->tx_ring.base + tq->tx_ring.next2fill;
BUG_ON(gdesc->txd.gen == tq->tx_ring.gen);
gdesc = tq->tx_ring.base + tq->tx_ring.next2fill;
BUG_ON(gdesc->txd.gen == tq->tx_ring.gen);
gdesc->txd.addr = cpu_to_le64(tbi->dma_addr);
gdesc->dword[2] = cpu_to_le32(dw2 | skb_frag_size(frag));
gdesc->dword[3] = 0;
gdesc->txd.addr = cpu_to_le64(tbi->dma_addr);
gdesc->dword[2] = cpu_to_le32(dw2);
gdesc->dword[3] = 0;
dev_dbg(&adapter->netdev->dev,
"txd[%u]: 0x%llu %u %u\n",
tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr),
le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]);
vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
dev_dbg(&adapter->netdev->dev,
"txd[%u]: 0x%llu %u %u\n",
tq->tx_ring.next2fill, le64_to_cpu(gdesc->txd.addr),
le32_to_cpu(gdesc->dword[2]), gdesc->dword[3]);
vmxnet3_cmd_ring_adv_next2fill(&tq->tx_ring);
dw2 = tq->tx_ring.gen << VMXNET3_TXD_GEN_SHIFT;
len -= buf_size;
buf_offset += buf_size;
}
}
ctx->eop_txd = gdesc;
@ -886,6 +901,18 @@ vmxnet3_prepare_tso(struct sk_buff *skb,
}
}
static int txd_estimate(const struct sk_buff *skb)
{
int count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) + 1;
int i;
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
const struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i];
count += VMXNET3_TXD_NEEDED(skb_frag_size(frag));
}
return count;
}
/*
* Transmits a pkt thru a given tq
@ -914,9 +941,7 @@ vmxnet3_tq_xmit(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
union Vmxnet3_GenericDesc tempTxDesc;
#endif
/* conservatively estimate # of descriptors to use */
count = VMXNET3_TXD_NEEDED(skb_headlen(skb)) +
skb_shinfo(skb)->nr_frags + 1;
count = txd_estimate(skb);
ctx.ipv4 = (vlan_get_protocol(skb) == cpu_to_be16(ETH_P_IP));

View File

@ -816,7 +816,7 @@ static void vxlan_cleanup(unsigned long arg)
= container_of(p, struct vxlan_fdb, hlist);
unsigned long timeout;
if (f->state == NUD_PERMANENT)
if (f->state & NUD_PERMANENT)
continue;
timeout = f->used + vxlan->age_interval * HZ;

View File

@ -312,6 +312,7 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
}
bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
bf->bf_next = NULL;
list_del(&bf->list);
spin_unlock_bh(&sc->tx.txbuflock);
@ -393,7 +394,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first;
u32 ba[WME_BA_BMP_SIZE >> 5];
int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
bool rc_update = true;
bool rc_update = true, isba;
struct ieee80211_tx_rate rates[4];
struct ath_frame_info *fi;
int nframes;
@ -437,13 +438,17 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
tid = ATH_AN_2_TID(an, tidno);
seq_first = tid->seq_start;
isba = ts->ts_flags & ATH9K_TX_BA;
/*
* The hardware occasionally sends a tx status for the wrong TID.
* In this case, the BA status cannot be considered valid and all
* subframes need to be retransmitted
*
* Only BlockAcks have a TID and therefore normal Acks cannot be
* checked
*/
if (tidno != ts->tid)
if (isba && tidno != ts->tid)
txok = false;
isaggr = bf_isaggr(bf);
@ -1774,6 +1779,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
list_add_tail(&bf->list, &bf_head);
bf->bf_state.bf_type = 0;
bf->bf_next = NULL;
bf->bf_lastbf = bf;
ath_tx_fill_desc(sc, bf, txq, fi->framelen);
ath_tx_txqaddbuf(sc, txq, &bf_head, false);

View File

@ -2449,7 +2449,7 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
/*
* Check if temperature compensation is supported.
*/
if (tssi_bounds[4] == 0xff)
if (tssi_bounds[4] == 0xff || step == 0xff)
return 0;
/*

View File

@ -3719,7 +3719,9 @@ restart:
*/
iscsit_thread_check_cpumask(conn, current, 1);
schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
wait_event_interruptible(conn->queues_wq,
!iscsit_conn_all_queues_empty(conn) ||
ts->status == ISCSI_THREAD_SET_RESET);
if ((ts->status == ISCSI_THREAD_SET_RESET) ||
signal_pending(current))

View File

@ -486,6 +486,7 @@ struct iscsi_tmr_req {
};
struct iscsi_conn {
wait_queue_head_t queues_wq;
/* Authentication Successful for this connection */
u8 auth_complete;
/* State connection is currently in */

View File

@ -41,6 +41,7 @@
static int iscsi_login_init_conn(struct iscsi_conn *conn)
{
init_waitqueue_head(&conn->queues_wq);
INIT_LIST_HEAD(&conn->conn_list);
INIT_LIST_HEAD(&conn->conn_cmd_list);
INIT_LIST_HEAD(&conn->immed_queue_list);

View File

@ -488,7 +488,7 @@ void iscsit_add_cmd_to_immediate_queue(
atomic_set(&conn->check_immediate_queue, 1);
spin_unlock_bh(&conn->immed_queue_lock);
wake_up_process(conn->thread_set->tx_thread);
wake_up(&conn->queues_wq);
}
struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn)
@ -562,7 +562,7 @@ void iscsit_add_cmd_to_response_queue(
atomic_inc(&cmd->response_queue_count);
spin_unlock_bh(&conn->response_queue_lock);
wake_up_process(conn->thread_set->tx_thread);
wake_up(&conn->queues_wq);
}
struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn)
@ -616,6 +616,24 @@ static void iscsit_remove_cmd_from_response_queue(
}
}
bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn)
{
bool empty;
spin_lock_bh(&conn->immed_queue_lock);
empty = list_empty(&conn->immed_queue_list);
spin_unlock_bh(&conn->immed_queue_lock);
if (!empty)
return empty;
spin_lock_bh(&conn->response_queue_lock);
empty = list_empty(&conn->response_queue_list);
spin_unlock_bh(&conn->response_queue_lock);
return empty;
}
void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn)
{
struct iscsi_queue_req *qr, *qr_tmp;

View File

@ -25,6 +25,7 @@ extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_
extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8);
extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *);
extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *);
extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *);
extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *);
extern void iscsit_release_cmd(struct iscsi_cmd *);
extern void iscsit_free_cmd(struct iscsi_cmd *);

View File

@ -3206,7 +3206,8 @@ static int __init target_core_init_configfs(void)
if (ret < 0)
goto out;
if (core_dev_setup_virtual_lun0() < 0)
ret = core_dev_setup_virtual_lun0();
if (ret < 0)
goto out;
return 0;

View File

@ -850,20 +850,20 @@ int se_dev_check_shutdown(struct se_device *dev)
static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size)
{
u32 tmp, aligned_max_sectors;
u32 aligned_max_sectors;
u32 alignment;
/*
* Limit max_sectors to a PAGE_SIZE aligned value for modern
* transport_allocate_data_tasks() operation.
*/
tmp = rounddown((max_sectors * block_size), PAGE_SIZE);
aligned_max_sectors = (tmp / block_size);
if (max_sectors != aligned_max_sectors) {
printk(KERN_INFO "Rounding down aligned max_sectors from %u"
" to %u\n", max_sectors, aligned_max_sectors);
return aligned_max_sectors;
}
alignment = max(1ul, PAGE_SIZE / block_size);
aligned_max_sectors = rounddown(max_sectors, alignment);
return max_sectors;
if (max_sectors != aligned_max_sectors)
pr_info("Rounding down aligned max_sectors from %u to %u\n",
max_sectors, aligned_max_sectors);
return aligned_max_sectors;
}
void se_dev_set_default_attribs(

View File

@ -605,6 +605,8 @@ static int spc_emulate_inquiry(struct se_cmd *cmd)
unsigned char buf[SE_INQUIRY_BUF];
int p, ret;
memset(buf, 0, SE_INQUIRY_BUF);
if (dev == tpg->tpg_virt_lun0.lun_se_dev)
buf[0] = 0x3f; /* Not connected */
else

View File

@ -140,15 +140,15 @@ void core_tmr_abort_task(
printk("ABORT_TASK: Found referenced %s task_tag: %u\n",
se_cmd->se_tfo->get_fabric_name(), ref_tag);
spin_lock_irq(&se_cmd->t_state_lock);
spin_lock(&se_cmd->t_state_lock);
if (se_cmd->transport_state & CMD_T_COMPLETE) {
printk("ABORT_TASK: ref_tag: %u already complete, skipping\n", ref_tag);
spin_unlock_irq(&se_cmd->t_state_lock);
spin_unlock(&se_cmd->t_state_lock);
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
goto out;
}
se_cmd->transport_state |= CMD_T_ABORTED;
spin_unlock_irq(&se_cmd->t_state_lock);
spin_unlock(&se_cmd->t_state_lock);
list_del_init(&se_cmd->se_cmd_list);
kref_get(&se_cmd->cmd_kref);

View File

@ -815,7 +815,7 @@ static struct platform_device_id exynos_tmu_driver_ids[] = {
},
{ },
};
MODULE_DEVICE_TABLE(platform, exynos4_tmu_driver_ids);
MODULE_DEVICE_TABLE(platform, exynos_tmu_driver_ids);
static inline struct exynos_tmu_platform_data *exynos_get_driver_data(
struct platform_device *pdev)

View File

@ -210,7 +210,7 @@ static int rcar_thermal_probe(struct platform_device *pdev)
goto error_free_priv;
}
zone = thermal_zone_device_register("rcar_thermal", 0, priv,
zone = thermal_zone_device_register("rcar_thermal", 0, 0, priv,
&rcar_thermal_zone_ops, 0, 0);
if (IS_ERR(zone)) {
dev_err(&pdev->dev, "thermal zone device is NULL\n");

View File

@ -641,7 +641,6 @@ static void xenfb_backend_changed(struct xenbus_device *dev,
case XenbusStateReconfiguring:
case XenbusStateReconfigured:
case XenbusStateUnknown:
case XenbusStateClosed:
break;
case XenbusStateInitWait:
@ -670,6 +669,10 @@ InitWait:
info->feature_resize = val;
break;
case XenbusStateClosed:
if (dev->state == XenbusStateClosed)
break;
/* Missed the backend's CLOSING state -- fallthrough */
case XenbusStateClosing:
xenbus_frontend_closed(dev);
break;

View File

@ -105,6 +105,21 @@ static void gntdev_print_maps(struct gntdev_priv *priv,
#endif
}
static void gntdev_free_map(struct grant_map *map)
{
if (map == NULL)
return;
if (map->pages)
free_xenballooned_pages(map->count, map->pages);
kfree(map->pages);
kfree(map->grants);
kfree(map->map_ops);
kfree(map->unmap_ops);
kfree(map->kmap_ops);
kfree(map);
}
static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
{
struct grant_map *add;
@ -142,12 +157,7 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
return add;
err:
kfree(add->pages);
kfree(add->grants);
kfree(add->map_ops);
kfree(add->unmap_ops);
kfree(add->kmap_ops);
kfree(add);
gntdev_free_map(add);
return NULL;
}
@ -198,17 +208,9 @@ static void gntdev_put_map(struct grant_map *map)
evtchn_put(map->notify.event);
}
if (map->pages) {
if (!use_ptemod)
unmap_grant_pages(map, 0, map->count);
free_xenballooned_pages(map->count, map->pages);
}
kfree(map->pages);
kfree(map->grants);
kfree(map->map_ops);
kfree(map->unmap_ops);
kfree(map);
if (map->pages && !use_ptemod)
unmap_grant_pages(map, 0, map->count);
gntdev_free_map(map);
}
/* ------------------------------------------------------------------ */

View File

@ -458,7 +458,7 @@ static ssize_t xenbus_file_write(struct file *filp,
goto out;
/* Can't write a xenbus message larger we can buffer */
if ((len + u->len) > sizeof(u->u.buffer)) {
if (len > sizeof(u->u.buffer) - u->len) {
/* On error, dump existing buffer */
u->len = 0;
rc = -EINVAL;

View File

@ -217,7 +217,7 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen)
{
char buf1[NFS_DNS_HOSTNAME_MAXLEN+1];
struct nfs_dns_ent key, *item;
unsigned long ttl;
unsigned int ttl;
ssize_t len;
int ret = -EINVAL;
@ -240,7 +240,8 @@ static int nfs_dns_parse(struct cache_detail *cd, char *buf, int buflen)
key.namelen = len;
memset(&key.h, 0, sizeof(key.h));
ttl = get_expiry(&buf);
if (get_uint(&buf, &ttl) < 0)
goto out;
if (ttl == 0)
goto out;
key.h.expiry_time = ttl + seconds_since_boot();

View File

@ -685,7 +685,10 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
if (ctx->cred != NULL)
put_rpccred(ctx->cred);
dput(ctx->dentry);
nfs_sb_deactive(sb);
if (is_sync)
nfs_sb_deactive(sb);
else
nfs_sb_deactive_async(sb);
kfree(ctx->mdsthreshold);
kfree(ctx);
}

View File

@ -351,10 +351,12 @@ extern int __init register_nfs_fs(void);
extern void __exit unregister_nfs_fs(void);
extern void nfs_sb_active(struct super_block *sb);
extern void nfs_sb_deactive(struct super_block *sb);
extern void nfs_sb_deactive_async(struct super_block *sb);
/* namespace.c */
#define NFS_PATH_CANONICAL 1
extern char *nfs_path(char **p, struct dentry *dentry,
char *buffer, ssize_t buflen);
char *buffer, ssize_t buflen, unsigned flags);
extern struct vfsmount *nfs_d_automount(struct path *path);
struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *,
struct nfs_fh *, struct nfs_fattr *);
@ -498,7 +500,7 @@ static inline char *nfs_devname(struct dentry *dentry,
char *buffer, ssize_t buflen)
{
char *dummy;
return nfs_path(&dummy, dentry, buffer, buflen);
return nfs_path(&dummy, dentry, buffer, buflen, NFS_PATH_CANONICAL);
}
/*

View File

@ -181,7 +181,7 @@ int nfs_mount(struct nfs_mount_request *info)
else
msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT];
status = rpc_call_sync(mnt_clnt, &msg, 0);
status = rpc_call_sync(mnt_clnt, &msg, RPC_TASK_SOFT|RPC_TASK_TIMEOUT);
rpc_shutdown_client(mnt_clnt);
if (status < 0)

View File

@ -33,6 +33,7 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
* @dentry - pointer to dentry
* @buffer - result buffer
* @buflen - length of buffer
* @flags - options (see below)
*
* Helper function for constructing the server pathname
* by arbitrary hashed dentry.
@ -40,8 +41,14 @@ int nfs_mountpoint_expiry_timeout = 500 * HZ;
* This is mainly for use in figuring out the path on the
* server side when automounting on top of an existing partition
* and in generating /proc/mounts and friends.
*
* Supported flags:
* NFS_PATH_CANONICAL: ensure there is exactly one slash after
* the original device (export) name
* (if unset, the original name is returned verbatim)
*/
char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen)
char *nfs_path(char **p, struct dentry *dentry, char *buffer, ssize_t buflen,
unsigned flags)
{
char *end;
int namelen;
@ -74,7 +81,7 @@ rename_retry:
rcu_read_unlock();
goto rename_retry;
}
if (*end != '/') {
if ((flags & NFS_PATH_CANONICAL) && *end != '/') {
if (--buflen < 0) {
spin_unlock(&dentry->d_lock);
rcu_read_unlock();
@ -91,9 +98,11 @@ rename_retry:
return end;
}
namelen = strlen(base);
/* Strip off excess slashes in base string */
while (namelen > 0 && base[namelen - 1] == '/')
namelen--;
if (flags & NFS_PATH_CANONICAL) {
/* Strip off excess slashes in base string */
while (namelen > 0 && base[namelen - 1] == '/')
namelen--;
}
buflen -= namelen;
if (buflen < 0) {
spin_unlock(&dentry->d_lock);

View File

@ -81,7 +81,8 @@ static char *nfs_path_component(const char *nfspath, const char *end)
static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen)
{
char *limit;
char *path = nfs_path(&limit, dentry, buffer, buflen);
char *path = nfs_path(&limit, dentry, buffer, buflen,
NFS_PATH_CANONICAL);
if (!IS_ERR(path)) {
char *path_component = nfs_path_component(path, limit);
if (path_component)

View File

@ -339,8 +339,7 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
dprintk("%s ERROR: %d Reset session\n", __func__,
errorcode);
nfs4_schedule_session_recovery(clp->cl_session, errorcode);
exception->retry = 1;
break;
goto wait_on_recovery;
#endif /* defined(CONFIG_NFS_V4_1) */
case -NFS4ERR_FILE_OPEN:
if (exception->timeout > HZ) {
@ -1572,9 +1571,11 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
data->timestamp = jiffies;
if (nfs4_setup_sequence(data->o_arg.server,
&data->o_arg.seq_args,
&data->o_res.seq_res, task))
return;
rpc_call_start(task);
&data->o_res.seq_res,
task) != 0)
nfs_release_seqid(data->o_arg.seqid);
else
rpc_call_start(task);
return;
unlock_no_action:
rcu_read_unlock();
@ -1748,7 +1749,7 @@ static int nfs4_opendata_access(struct rpc_cred *cred,
/* even though OPEN succeeded, access is denied. Close the file */
nfs4_close_state(state, fmode);
return -NFS4ERR_ACCESS;
return -EACCES;
}
/*
@ -2196,7 +2197,7 @@ static void nfs4_free_closedata(void *data)
nfs4_put_open_state(calldata->state);
nfs_free_seqid(calldata->arg.seqid);
nfs4_put_state_owner(sp);
nfs_sb_deactive(sb);
nfs_sb_deactive_async(sb);
kfree(calldata);
}
@ -2296,9 +2297,10 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
if (nfs4_setup_sequence(NFS_SERVER(inode),
&calldata->arg.seq_args,
&calldata->res.seq_res,
task))
goto out;
rpc_call_start(task);
task) != 0)
nfs_release_seqid(calldata->arg.seqid);
else
rpc_call_start(task);
out:
dprintk("%s: done!\n", __func__);
}
@ -4529,6 +4531,7 @@ static void nfs4_locku_done(struct rpc_task *task, void *data)
if (nfs4_async_handle_error(task, calldata->server, NULL) == -EAGAIN)
rpc_restart_call_prepare(task);
}
nfs_release_seqid(calldata->arg.seqid);
}
static void nfs4_locku_prepare(struct rpc_task *task, void *data)
@ -4545,9 +4548,11 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
calldata->timestamp = jiffies;
if (nfs4_setup_sequence(calldata->server,
&calldata->arg.seq_args,
&calldata->res.seq_res, task))
return;
rpc_call_start(task);
&calldata->res.seq_res,
task) != 0)
nfs_release_seqid(calldata->arg.seqid);
else
rpc_call_start(task);
}
static const struct rpc_call_ops nfs4_locku_ops = {
@ -4692,7 +4697,7 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
/* Do we need to do an open_to_lock_owner? */
if (!(data->arg.lock_seqid->sequence->flags & NFS_SEQID_CONFIRMED)) {
if (nfs_wait_on_sequence(data->arg.open_seqid, task) != 0)
return;
goto out_release_lock_seqid;
data->arg.open_stateid = &state->stateid;
data->arg.new_lock_owner = 1;
data->res.open_seqid = data->arg.open_seqid;
@ -4701,10 +4706,15 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
data->timestamp = jiffies;
if (nfs4_setup_sequence(data->server,
&data->arg.seq_args,
&data->res.seq_res, task))
&data->res.seq_res,
task) == 0) {
rpc_call_start(task);
return;
rpc_call_start(task);
dprintk("%s: done!, ret = %d\n", __func__, data->rpc_status);
}
nfs_release_seqid(data->arg.open_seqid);
out_release_lock_seqid:
nfs_release_seqid(data->arg.lock_seqid);
dprintk("%s: done!, ret = %d\n", __func__, task->tk_status);
}
static void nfs4_recover_lock_prepare(struct rpc_task *task, void *calldata)
@ -5667,7 +5677,7 @@ static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl,
tbl->slots = new;
tbl->max_slots = max_slots;
}
tbl->highest_used_slotid = -1; /* no slot is currently used */
tbl->highest_used_slotid = NFS4_NO_SLOT;
for (i = 0; i < tbl->max_slots; i++)
tbl->slots[i].seq_nr = ivalue;
spin_unlock(&tbl->slot_tbl_lock);

View File

@ -925,8 +925,8 @@ pnfs_find_alloc_layout(struct inode *ino,
if (likely(nfsi->layout == NULL)) { /* Won the race? */
nfsi->layout = new;
return new;
}
pnfs_free_layout_hdr(new);
} else if (new != NULL)
pnfs_free_layout_hdr(new);
out_existing:
pnfs_get_layout_hdr(nfsi->layout);
return nfsi->layout;

View File

@ -54,6 +54,7 @@
#include <linux/parser.h>
#include <linux/nsproxy.h>
#include <linux/rcupdate.h>
#include <linux/kthread.h>
#include <asm/uaccess.h>
@ -415,6 +416,54 @@ void nfs_sb_deactive(struct super_block *sb)
}
EXPORT_SYMBOL_GPL(nfs_sb_deactive);
static int nfs_deactivate_super_async_work(void *ptr)
{
struct super_block *sb = ptr;
deactivate_super(sb);
module_put_and_exit(0);
return 0;
}
/*
* same effect as deactivate_super, but will do final unmount in kthread
* context
*/
static void nfs_deactivate_super_async(struct super_block *sb)
{
struct task_struct *task;
char buf[INET6_ADDRSTRLEN + 1];
struct nfs_server *server = NFS_SB(sb);
struct nfs_client *clp = server->nfs_client;
if (!atomic_add_unless(&sb->s_active, -1, 1)) {
rcu_read_lock();
snprintf(buf, sizeof(buf),
rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR));
rcu_read_unlock();
__module_get(THIS_MODULE);
task = kthread_run(nfs_deactivate_super_async_work, sb,
"%s-deactivate-super", buf);
if (IS_ERR(task)) {
pr_err("%s: kthread_run: %ld\n",
__func__, PTR_ERR(task));
/* make synchronous call and hope for the best */
deactivate_super(sb);
module_put(THIS_MODULE);
}
}
}
void nfs_sb_deactive_async(struct super_block *sb)
{
struct nfs_server *server = NFS_SB(sb);
if (atomic_dec_and_test(&server->active))
nfs_deactivate_super_async(sb);
}
EXPORT_SYMBOL_GPL(nfs_sb_deactive_async);
/*
* Deliver file system statistics to userspace
*/
@ -771,7 +820,7 @@ int nfs_show_devname(struct seq_file *m, struct dentry *root)
int err = 0;
if (!page)
return -ENOMEM;
devname = nfs_path(&dummy, root, page, PAGE_SIZE);
devname = nfs_path(&dummy, root, page, PAGE_SIZE, 0);
if (IS_ERR(devname))
err = PTR_ERR(devname);
else

View File

@ -95,7 +95,7 @@ static void nfs_async_unlink_release(void *calldata)
nfs_dec_sillycount(data->dir);
nfs_free_unlinkdata(data);
nfs_sb_deactive(sb);
nfs_sb_deactive_async(sb);
}
static void nfs_unlink_prepare(struct rpc_task *task, void *calldata)

192
include/linux/hashtable.h Normal file
View File

@ -0,0 +1,192 @@
/*
* Statically sized hash table implementation
* (C) 2012 Sasha Levin <levinsasha928@gmail.com>
*/
#ifndef _LINUX_HASHTABLE_H
#define _LINUX_HASHTABLE_H
#include <linux/list.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/hash.h>
#include <linux/rculist.h>
#define DEFINE_HASHTABLE(name, bits) \
struct hlist_head name[1 << (bits)] = \
{ [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
#define DECLARE_HASHTABLE(name, bits) \
struct hlist_head name[1 << (bits)]
#define HASH_SIZE(name) (ARRAY_SIZE(name))
#define HASH_BITS(name) ilog2(HASH_SIZE(name))
/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */
#define hash_min(val, bits) \
(sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits))
static inline void __hash_init(struct hlist_head *ht, unsigned int sz)
{
unsigned int i;
for (i = 0; i < sz; i++)
INIT_HLIST_HEAD(&ht[i]);
}
/**
* hash_init - initialize a hash table
* @hashtable: hashtable to be initialized
*
* Calculates the size of the hashtable from the given parameter, otherwise
* same as hash_init_size.
*
* This has to be a macro since HASH_BITS() will not work on pointers since
* it calculates the size during preprocessing.
*/
#define hash_init(hashtable) __hash_init(hashtable, HASH_SIZE(hashtable))
/**
* hash_add - add an object to a hashtable
* @hashtable: hashtable to add to
* @node: the &struct hlist_node of the object to be added
* @key: the key of the object to be added
*/
#define hash_add(hashtable, node, key) \
hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))])
/**
* hash_add_rcu - add an object to a rcu enabled hashtable
* @hashtable: hashtable to add to
* @node: the &struct hlist_node of the object to be added
* @key: the key of the object to be added
*/
#define hash_add_rcu(hashtable, node, key) \
hlist_add_head_rcu(node, &hashtable[hash_min(key, HASH_BITS(hashtable))])
/**
* hash_hashed - check whether an object is in any hashtable
* @node: the &struct hlist_node of the object to be checked
*/
static inline bool hash_hashed(struct hlist_node *node)
{
return !hlist_unhashed(node);
}
static inline bool __hash_empty(struct hlist_head *ht, unsigned int sz)
{
unsigned int i;
for (i = 0; i < sz; i++)
if (!hlist_empty(&ht[i]))
return false;
return true;
}
/**
* hash_empty - check whether a hashtable is empty
* @hashtable: hashtable to check
*
* This has to be a macro since HASH_BITS() will not work on pointers since
* it calculates the size during preprocessing.
*/
#define hash_empty(hashtable) __hash_empty(hashtable, HASH_SIZE(hashtable))
/**
* hash_del - remove an object from a hashtable
* @node: &struct hlist_node of the object to remove
*/
static inline void hash_del(struct hlist_node *node)
{
hlist_del_init(node);
}
/**
* hash_del_rcu - remove an object from a rcu enabled hashtable
* @node: &struct hlist_node of the object to remove
*/
static inline void hash_del_rcu(struct hlist_node *node)
{
hlist_del_init_rcu(node);
}
/**
* hash_for_each - iterate over a hashtable
* @name: hashtable to iterate
* @bkt: integer to use as bucket loop cursor
* @node: the &struct list_head to use as a loop cursor for each entry
* @obj: the type * to use as a loop cursor for each entry
* @member: the name of the hlist_node within the struct
*/
#define hash_for_each(name, bkt, node, obj, member) \
for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\
hlist_for_each_entry(obj, node, &name[bkt], member)
/**
* hash_for_each_rcu - iterate over a rcu enabled hashtable
* @name: hashtable to iterate
* @bkt: integer to use as bucket loop cursor
* @node: the &struct list_head to use as a loop cursor for each entry
* @obj: the type * to use as a loop cursor for each entry
* @member: the name of the hlist_node within the struct
*/
#define hash_for_each_rcu(name, bkt, node, obj, member) \
for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\
hlist_for_each_entry_rcu(obj, node, &name[bkt], member)
/**
* hash_for_each_safe - iterate over a hashtable safe against removal of
* hash entry
* @name: hashtable to iterate
* @bkt: integer to use as bucket loop cursor
* @node: the &struct list_head to use as a loop cursor for each entry
* @tmp: a &struct used for temporary storage
* @obj: the type * to use as a loop cursor for each entry
* @member: the name of the hlist_node within the struct
*/
#define hash_for_each_safe(name, bkt, node, tmp, obj, member) \
for ((bkt) = 0, node = NULL; node == NULL && (bkt) < HASH_SIZE(name); (bkt)++)\
hlist_for_each_entry_safe(obj, node, tmp, &name[bkt], member)
/**
* hash_for_each_possible - iterate over all possible objects hashing to the
* same bucket
* @name: hashtable to iterate
* @obj: the type * to use as a loop cursor for each entry
* @node: the &struct list_head to use as a loop cursor for each entry
* @member: the name of the hlist_node within the struct
* @key: the key of the objects to iterate over
*/
#define hash_for_each_possible(name, obj, node, member, key) \
hlist_for_each_entry(obj, node, &name[hash_min(key, HASH_BITS(name))], member)
/**
* hash_for_each_possible_rcu - iterate over all possible objects hashing to the
* same bucket in an rcu enabled hashtable
* in a rcu enabled hashtable
* @name: hashtable to iterate
* @obj: the type * to use as a loop cursor for each entry
* @node: the &struct list_head to use as a loop cursor for each entry
* @member: the name of the hlist_node within the struct
* @key: the key of the objects to iterate over
*/
#define hash_for_each_possible_rcu(name, obj, node, member, key) \
hlist_for_each_entry_rcu(obj, node, &name[hash_min(key, HASH_BITS(name))], member)
/**
* hash_for_each_possible_safe - iterate over all possible objects hashing to the
* same bucket safe against removals
* @name: hashtable to iterate
* @obj: the type * to use as a loop cursor for each entry
* @node: the &struct list_head to use as a loop cursor for each entry
* @tmp: a &struct used for temporary storage
* @member: the name of the hlist_node within the struct
* @key: the key of the objects to iterate over
*/
#define hash_for_each_possible_safe(name, obj, node, tmp, member, key) \
hlist_for_each_entry_safe(obj, node, tmp, \
&name[hash_min(key, HASH_BITS(name))], member)
#endif

View File

@ -2651,6 +2651,15 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb);
*/
unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc);
/**
* ieee80211_get_mesh_hdrlen - get mesh extension header length
* @meshhdr: the mesh extension header, only the flags field
* (first byte) will be accessed
* Returns the length of the extension header, which is always at
* least 6 bytes and at most 18 if address 5 and 6 are present.
*/
unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
/**
* DOC: Data path helpers
*

View File

@ -377,6 +377,14 @@ DECLARE_EVENT_CLASS(xen_mmu_pgd,
DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_pin);
DEFINE_XEN_MMU_PGD_EVENT(xen_mmu_pgd_unpin);
TRACE_EVENT(xen_mmu_flush_tlb_all,
TP_PROTO(int x),
TP_ARGS(x),
TP_STRUCT__entry(__array(char, x, 0)),
TP_fast_assign((void)x),
TP_printk("%s", "")
);
TRACE_EVENT(xen_mmu_flush_tlb,
TP_PROTO(int x),
TP_ARGS(x),

View File

@ -184,7 +184,8 @@ nf_nat_ipv4_out(unsigned int hooknum,
if ((ct->tuplehash[dir].tuple.src.u3.ip !=
ct->tuplehash[!dir].tuple.dst.u3.ip) ||
(ct->tuplehash[dir].tuple.src.u.all !=
(ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
ct->tuplehash[dir].tuple.src.u.all !=
ct->tuplehash[!dir].tuple.dst.u.all))
if (nf_xfrm_me_harder(skb, AF_INET) < 0)
ret = NF_DROP;
@ -221,6 +222,7 @@ nf_nat_ipv4_local_fn(unsigned int hooknum,
}
#ifdef CONFIG_XFRM
else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
ct->tuplehash[dir].tuple.dst.u.all !=
ct->tuplehash[!dir].tuple.src.u.all)
if (nf_xfrm_me_harder(skb, AF_INET) < 0)

View File

@ -313,11 +313,13 @@ static void tcp_illinois_info(struct sock *sk, u32 ext,
.tcpv_rttcnt = ca->cnt_rtt,
.tcpv_minrtt = ca->base_rtt,
};
u64 t = ca->sum_rtt;
do_div(t, ca->cnt_rtt);
info.tcpv_rtt = t;
if (info.tcpv_rttcnt > 0) {
u64 t = ca->sum_rtt;
do_div(t, info.tcpv_rttcnt);
info.tcpv_rtt = t;
}
nla_put(skb, INET_DIAG_VEGASINFO, sizeof(info), &info);
}
}

View File

@ -4529,6 +4529,9 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
struct tcphdr *th;
bool fragstolen;
if (size == 0)
return 0;
skb = alloc_skb(size + sizeof(*th), sk->sk_allocation);
if (!skb)
goto err;

View File

@ -864,7 +864,7 @@ static int parse_nl_addr(struct genl_info *info, struct inetpeer_addr *addr,
}
a = info->attrs[TCP_METRICS_ATTR_ADDR_IPV6];
if (a) {
if (nla_len(a) != sizeof(sizeof(struct in6_addr)))
if (nla_len(a) != sizeof(struct in6_addr))
return -EINVAL;
addr->family = AF_INET6;
memcpy(addr->addr.a6, nla_data(a), sizeof(addr->addr.a6));

View File

@ -186,7 +186,8 @@ nf_nat_ipv6_out(unsigned int hooknum,
if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3,
&ct->tuplehash[!dir].tuple.dst.u3) ||
(ct->tuplehash[dir].tuple.src.u.all !=
(ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
ct->tuplehash[dir].tuple.src.u.all !=
ct->tuplehash[!dir].tuple.dst.u.all))
if (nf_xfrm_me_harder(skb, AF_INET6) < 0)
ret = NF_DROP;
@ -222,6 +223,7 @@ nf_nat_ipv6_local_fn(unsigned int hooknum,
}
#ifdef CONFIG_XFRM
else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
ct->tuplehash[dir].tuple.dst.u.all !=
ct->tuplehash[!dir].tuple.src.u.all)
if (nf_xfrm_me_harder(skb, AF_INET6))

View File

@ -85,7 +85,7 @@ static struct ctl_table nf_ct_frag6_sysctl_table[] = {
{ }
};
static int __net_init nf_ct_frag6_sysctl_register(struct net *net)
static int nf_ct_frag6_sysctl_register(struct net *net)
{
struct ctl_table *table;
struct ctl_table_header *hdr;
@ -127,7 +127,7 @@ static void __net_exit nf_ct_frags6_sysctl_unregister(struct net *net)
}
#else
static int __net_init nf_ct_frag6_sysctl_register(struct net *net)
static int nf_ct_frag6_sysctl_register(struct net *net)
{
return 0;
}

View File

@ -291,6 +291,7 @@ static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 p
out_del_dev:
free_netdev(dev);
spriv->dev = NULL;
out_del_session:
l2tp_session_delete(session);
out:

View File

@ -1108,7 +1108,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
sdata->u.ibss.ibss_join_req = jiffies;
memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);
memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len);
sdata->u.ibss.ssid_len = params->ssid_len;
mutex_unlock(&sdata->u.ibss.mtx);

View File

@ -531,6 +531,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
if (ieee80211_is_action(hdr->frame_control)) {
u8 category;
/* make sure category field is present */
if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE)
return RX_DROP_MONITOR;
mgmt = (struct ieee80211_mgmt *)hdr;
category = mgmt->u.action.category;
if (category != WLAN_CATEGORY_MESH_ACTION &&
@ -883,14 +888,16 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
*/
if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
ieee80211_is_data_present(hdr->frame_control)) {
u16 ethertype;
u8 *payload;
unsigned int hdrlen;
__be16 ethertype;
payload = rx->skb->data +
ieee80211_hdrlen(hdr->frame_control);
ethertype = (payload[6] << 8) | payload[7];
if (cpu_to_be16(ethertype) ==
rx->sdata->control_port_protocol)
hdrlen = ieee80211_hdrlen(hdr->frame_control);
if (rx->skb->len < hdrlen + 8)
return RX_DROP_MONITOR;
skb_copy_bits(rx->skb, hdrlen + 6, &ethertype, 2);
if (ethertype == rx->sdata->control_port_protocol)
return RX_CONTINUE;
}
@ -1462,11 +1469,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
hdr = (struct ieee80211_hdr *)rx->skb->data;
fc = hdr->frame_control;
if (ieee80211_is_ctl(fc))
return RX_CONTINUE;
sc = le16_to_cpu(hdr->seq_ctrl);
frag = sc & IEEE80211_SCTL_FRAG;
if (likely((!ieee80211_has_morefrags(fc) && frag == 0) ||
(rx->skb)->len < 24 ||
is_multicast_ether_addr(hdr->addr1))) {
/* not fragmented */
goto out;
@ -1889,6 +1899,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
/* make sure fixed part of mesh header is there, also checks skb len */
if (!pskb_may_pull(rx->skb, hdrlen + 6))
return RX_DROP_MONITOR;
mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
/* make sure full mesh header is there, also checks skb len */
if (!pskb_may_pull(rx->skb,
hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr)))
return RX_DROP_MONITOR;
/* reload pointers */
hdr = (struct ieee80211_hdr *) skb->data;
mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
/* frame is in RMC, don't forward */
@ -1897,7 +1921,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata))
return RX_DROP_MONITOR;
if (!ieee80211_is_data(hdr->frame_control))
if (!ieee80211_is_data(hdr->frame_control) ||
!(status->rx_flags & IEEE80211_RX_RA_MATCH))
return RX_CONTINUE;
if (!mesh_hdr->ttl)
@ -1911,9 +1936,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
if (is_multicast_ether_addr(hdr->addr1)) {
mpp_addr = hdr->addr3;
proxied_addr = mesh_hdr->eaddr1;
} else {
} else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) {
/* has_a4 already checked in ieee80211_rx_mesh_check */
mpp_addr = hdr->addr4;
proxied_addr = mesh_hdr->eaddr2;
} else {
return RX_DROP_MONITOR;
}
rcu_read_lock();
@ -1941,12 +1969,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
}
skb_set_queue_mapping(skb, q);
if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
goto out;
if (!--mesh_hdr->ttl) {
IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
return RX_DROP_MONITOR;
goto out;
}
if (!ifmsh->mshcfg.dot11MeshForwarding)
@ -2353,6 +2378,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
}
break;
case WLAN_CATEGORY_SELF_PROTECTED:
if (len < (IEEE80211_MIN_ACTION_SIZE +
sizeof(mgmt->u.action.u.self_prot.action_code)))
break;
switch (mgmt->u.action.u.self_prot.action_code) {
case WLAN_SP_MESH_PEERING_OPEN:
case WLAN_SP_MESH_PEERING_CLOSE:
@ -2371,6 +2400,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
}
break;
case WLAN_CATEGORY_MESH_ACTION:
if (len < (IEEE80211_MIN_ACTION_SIZE +
sizeof(mgmt->u.action.u.mesh_action.action_code)))
break;
if (!ieee80211_vif_is_mesh(&sdata->vif))
break;
if (mesh_action_is_path_sel(mgmt) &&
@ -2913,10 +2946,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
local->dot11ReceivedFragmentCount++;
if (ieee80211_is_mgmt(fc))
err = skb_linearize(skb);
else
if (ieee80211_is_mgmt(fc)) {
/* drop frame if too short for header */
if (skb->len < ieee80211_hdrlen(fc))
err = -ENOBUFS;
else
err = skb_linearize(skb);
} else {
err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
}
if (err) {
dev_kfree_skb(skb);

View File

@ -643,13 +643,41 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
break;
}
if (id != WLAN_EID_VENDOR_SPECIFIC &&
id != WLAN_EID_QUIET &&
test_bit(id, seen_elems)) {
elems->parse_error = true;
left -= elen;
pos += elen;
continue;
switch (id) {
case WLAN_EID_SSID:
case WLAN_EID_SUPP_RATES:
case WLAN_EID_FH_PARAMS:
case WLAN_EID_DS_PARAMS:
case WLAN_EID_CF_PARAMS:
case WLAN_EID_TIM:
case WLAN_EID_IBSS_PARAMS:
case WLAN_EID_CHALLENGE:
case WLAN_EID_RSN:
case WLAN_EID_ERP_INFO:
case WLAN_EID_EXT_SUPP_RATES:
case WLAN_EID_HT_CAPABILITY:
case WLAN_EID_HT_OPERATION:
case WLAN_EID_VHT_CAPABILITY:
case WLAN_EID_VHT_OPERATION:
case WLAN_EID_MESH_ID:
case WLAN_EID_MESH_CONFIG:
case WLAN_EID_PEER_MGMT:
case WLAN_EID_PREQ:
case WLAN_EID_PREP:
case WLAN_EID_PERR:
case WLAN_EID_RANN:
case WLAN_EID_CHANNEL_SWITCH:
case WLAN_EID_EXT_CHANSWITCH_ANN:
case WLAN_EID_COUNTRY:
case WLAN_EID_PWR_CONSTRAINT:
case WLAN_EID_TIMEOUT_INTERVAL:
if (test_bit(id, seen_elems)) {
elems->parse_error = true;
left -= elen;
pos += elen;
continue;
}
break;
}
if (calc_crc && id < 64 && (filter & (1ULL << id)))

Some files were not shown because too many files have changed in this diff Show More