mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 22:14:04 +02:00
Merge tag 'v4.4.122' into linux-linaro-lsk-v4.4
This is the 4.4.122 stable release
This commit is contained in:
commit
06eb38abaf
2
Makefile
2
Makefile
|
|
@ -1,6 +1,6 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 121
|
||||
SUBLEVEL = 122
|
||||
EXTRAVERSION =
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
|
|
|
|||
|
|
@ -90,8 +90,6 @@ filesystem@680000 {
|
|||
};
|
||||
|
||||
&i2c1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c1_pins>;
|
||||
clock-frequency = <2600000>;
|
||||
|
||||
twl: twl@48 {
|
||||
|
|
@ -148,12 +146,6 @@ OMAP3630_CORE2_IOPAD(0x25d8, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_clk.sdmmc3_c
|
|||
OMAP3630_CORE2_IOPAD(0x25da, PIN_INPUT_PULLUP | MUX_MODE2) /* etk_ctl.sdmmc3_cmd */
|
||||
>;
|
||||
};
|
||||
i2c1_pins: pinmux_i2c1_pins {
|
||||
pinctrl-single,pins = <
|
||||
OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */
|
||||
OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0) /* i2c1_sda.i2c1_sda */
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
#include "twl4030.dtsi"
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ phys_addr_t omap_secure_ram_mempool_base(void)
|
|||
return omap_secure_memblock_base;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
|
||||
u32 omap3_save_secure_ram(void __iomem *addr, int size)
|
||||
{
|
||||
u32 ret;
|
||||
|
|
@ -91,6 +92,7 @@ u32 omap3_save_secure_ram(void __iomem *addr, int size)
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* rx51_secure_dispatcher: Routine to dispatch secure PPA API calls
|
||||
|
|
|
|||
|
|
@ -135,6 +135,8 @@ int __init ath25_find_config(phys_addr_t base, unsigned long size)
|
|||
}
|
||||
|
||||
board_data = kzalloc(BOARD_CONFIG_BUFSZ, GFP_KERNEL);
|
||||
if (!board_data)
|
||||
goto error;
|
||||
ath25_board.config = (struct ath25_boarddata *)board_data;
|
||||
memcpy_fromio(board_data, bcfg, 0x100);
|
||||
if (broken_boarddata) {
|
||||
|
|
|
|||
|
|
@ -2246,6 +2246,8 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node,
|
|||
}
|
||||
|
||||
host_data = kzalloc(sizeof(*host_data), GFP_KERNEL);
|
||||
if (!host_data)
|
||||
return -ENOMEM;
|
||||
raw_spin_lock_init(&host_data->lock);
|
||||
|
||||
addr = of_get_address(ciu_node, 0, NULL, NULL);
|
||||
|
|
|
|||
|
|
@ -166,11 +166,11 @@ static void bmips_prepare_cpus(unsigned int max_cpus)
|
|||
return;
|
||||
}
|
||||
|
||||
if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU,
|
||||
"smp_ipi0", NULL))
|
||||
if (request_irq(IPI0_IRQ, bmips_ipi_interrupt,
|
||||
IRQF_PERCPU | IRQF_NO_SUSPEND, "smp_ipi0", NULL))
|
||||
panic("Can't request IPI0 interrupt");
|
||||
if (request_irq(IPI1_IRQ, bmips_ipi_interrupt, IRQF_PERCPU,
|
||||
"smp_ipi1", NULL))
|
||||
if (request_irq(IPI1_IRQ, bmips_ipi_interrupt,
|
||||
IRQF_PERCPU | IRQF_NO_SUSPEND, "smp_ipi1", NULL))
|
||||
panic("Can't request IPI1 interrupt");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ static DEFINE_MUTEX(mce_chrdev_read_mutex);
|
|||
smp_load_acquire(&(p)); \
|
||||
})
|
||||
|
||||
/* sysfs synchronization */
|
||||
static DEFINE_MUTEX(mce_sysfs_mutex);
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/mce.h>
|
||||
|
||||
|
|
@ -2220,6 +2223,7 @@ static ssize_t set_ignore_ce(struct device *s,
|
|||
if (kstrtou64(buf, 0, &new) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&mce_sysfs_mutex);
|
||||
if (mca_cfg.ignore_ce ^ !!new) {
|
||||
if (new) {
|
||||
/* disable ce features */
|
||||
|
|
@ -2232,6 +2236,8 @@ static ssize_t set_ignore_ce(struct device *s,
|
|||
on_each_cpu(mce_enable_ce, (void *)1, 1);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&mce_sysfs_mutex);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
@ -2244,6 +2250,7 @@ static ssize_t set_cmci_disabled(struct device *s,
|
|||
if (kstrtou64(buf, 0, &new) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&mce_sysfs_mutex);
|
||||
if (mca_cfg.cmci_disabled ^ !!new) {
|
||||
if (new) {
|
||||
/* disable cmci */
|
||||
|
|
@ -2255,6 +2262,8 @@ static ssize_t set_cmci_disabled(struct device *s,
|
|||
on_each_cpu(mce_enable_ce, NULL, 1);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&mce_sysfs_mutex);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
@ -2262,8 +2271,19 @@ static ssize_t store_int_with_restart(struct device *s,
|
|||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
ssize_t ret = device_store_int(s, attr, buf, size);
|
||||
unsigned long old_check_interval = check_interval;
|
||||
ssize_t ret = device_store_ulong(s, attr, buf, size);
|
||||
|
||||
if (check_interval == old_check_interval)
|
||||
return ret;
|
||||
|
||||
if (check_interval < 1)
|
||||
check_interval = 1;
|
||||
|
||||
mutex_lock(&mce_sysfs_mutex);
|
||||
mce_restart();
|
||||
mutex_unlock(&mce_sysfs_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -519,6 +519,7 @@ int arch_kexec_apply_relocations_add(const Elf64_Ehdr *ehdr,
|
|||
goto overflow;
|
||||
break;
|
||||
case R_X86_64_PC32:
|
||||
case R_X86_64_PLT32:
|
||||
value -= (u64)address;
|
||||
*(u32 *)location = value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -170,19 +170,28 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
|
|||
case R_X86_64_NONE:
|
||||
break;
|
||||
case R_X86_64_64:
|
||||
if (*(u64 *)loc != 0)
|
||||
goto invalid_relocation;
|
||||
*(u64 *)loc = val;
|
||||
break;
|
||||
case R_X86_64_32:
|
||||
if (*(u32 *)loc != 0)
|
||||
goto invalid_relocation;
|
||||
*(u32 *)loc = val;
|
||||
if (val != *(u32 *)loc)
|
||||
goto overflow;
|
||||
break;
|
||||
case R_X86_64_32S:
|
||||
if (*(s32 *)loc != 0)
|
||||
goto invalid_relocation;
|
||||
*(s32 *)loc = val;
|
||||
if ((s64)val != *(s32 *)loc)
|
||||
goto overflow;
|
||||
break;
|
||||
case R_X86_64_PC32:
|
||||
case R_X86_64_PLT32:
|
||||
if (*(u32 *)loc != 0)
|
||||
goto invalid_relocation;
|
||||
val -= (u64)loc;
|
||||
*(u32 *)loc = val;
|
||||
#if 0
|
||||
|
|
@ -198,6 +207,11 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
|
|||
}
|
||||
return 0;
|
||||
|
||||
invalid_relocation:
|
||||
pr_err("x86/modules: Skipping invalid relocation target, existing value is nonzero for type %d, loc %p, val %Lx\n",
|
||||
(int)ELF64_R_TYPE(rel[i].r_info), loc, val);
|
||||
return -ENOEXEC;
|
||||
|
||||
overflow:
|
||||
pr_err("overflow in relocation type %d val %Lx\n",
|
||||
(int)ELF64_R_TYPE(rel[i].r_info), val);
|
||||
|
|
|
|||
|
|
@ -769,9 +769,12 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
|
|||
break;
|
||||
|
||||
case R_X86_64_PC32:
|
||||
case R_X86_64_PLT32:
|
||||
/*
|
||||
* PC relative relocations don't need to be adjusted unless
|
||||
* referencing a percpu symbol.
|
||||
*
|
||||
* NB: R_X86_64_PLT32 can be treated as R_X86_64_PC32.
|
||||
*/
|
||||
if (is_percpu_sym(sym, symname))
|
||||
add_reloc(&relocs32neg, offset);
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ static int lo_write_bvec(struct file *file, struct bio_vec *bvec, loff_t *ppos)
|
|||
struct iov_iter i;
|
||||
ssize_t bw;
|
||||
|
||||
iov_iter_bvec(&i, ITER_BVEC, bvec, 1, bvec->bv_len);
|
||||
iov_iter_bvec(&i, ITER_BVEC | WRITE, bvec, 1, bvec->bv_len);
|
||||
|
||||
file_start_write(file);
|
||||
bw = vfs_iter_write(file, &i, ppos);
|
||||
|
|
|
|||
|
|
@ -585,6 +585,9 @@ int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev,
|
|||
size_t size;
|
||||
u32 retry = 3;
|
||||
|
||||
if (amdgpu_acpi_pcie_notify_device_ready(adev))
|
||||
return -EINVAL;
|
||||
|
||||
/* Get the device handle */
|
||||
handle = ACPI_HANDLE(&adev->pdev->dev);
|
||||
if (!handle)
|
||||
|
|
|
|||
|
|
@ -739,9 +739,11 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force)
|
|||
enum drm_connector_status ret = connector_status_disconnected;
|
||||
int r;
|
||||
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
if (encoder) {
|
||||
struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);
|
||||
|
|
@ -760,8 +762,12 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force)
|
|||
/* check acpi lid status ??? */
|
||||
|
||||
amdgpu_connector_update_scratch_regs(connector, ret);
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -862,9 +868,11 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
|
|||
enum drm_connector_status ret = connector_status_disconnected;
|
||||
int r;
|
||||
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
encoder = amdgpu_connector_best_single_encoder(connector);
|
||||
if (!encoder)
|
||||
|
|
@ -918,8 +926,10 @@ amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)
|
|||
amdgpu_connector_update_scratch_regs(connector, ret);
|
||||
|
||||
out:
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -981,9 +991,11 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
|
|||
enum drm_connector_status ret = connector_status_disconnected;
|
||||
bool dret = false, broken_edid = false;
|
||||
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {
|
||||
ret = connector->status;
|
||||
|
|
@ -1108,8 +1120,10 @@ amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)
|
|||
amdgpu_connector_update_scratch_regs(connector, ret);
|
||||
|
||||
exit:
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1351,9 +1365,11 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
|
|||
struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);
|
||||
int r;
|
||||
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {
|
||||
ret = connector->status;
|
||||
|
|
@ -1421,8 +1437,10 @@ amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)
|
|||
|
||||
amdgpu_connector_update_scratch_regs(connector, ret);
|
||||
out:
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2104,34 +2104,8 @@ static void gfx_v7_0_gpu_init(struct amdgpu_device *adev)
|
|||
case CHIP_KAVERI:
|
||||
adev->gfx.config.max_shader_engines = 1;
|
||||
adev->gfx.config.max_tile_pipes = 4;
|
||||
if ((adev->pdev->device == 0x1304) ||
|
||||
(adev->pdev->device == 0x1305) ||
|
||||
(adev->pdev->device == 0x130C) ||
|
||||
(adev->pdev->device == 0x130F) ||
|
||||
(adev->pdev->device == 0x1310) ||
|
||||
(adev->pdev->device == 0x1311) ||
|
||||
(adev->pdev->device == 0x131C)) {
|
||||
adev->gfx.config.max_cu_per_sh = 8;
|
||||
adev->gfx.config.max_backends_per_se = 2;
|
||||
} else if ((adev->pdev->device == 0x1309) ||
|
||||
(adev->pdev->device == 0x130A) ||
|
||||
(adev->pdev->device == 0x130D) ||
|
||||
(adev->pdev->device == 0x1313) ||
|
||||
(adev->pdev->device == 0x131D)) {
|
||||
adev->gfx.config.max_cu_per_sh = 6;
|
||||
adev->gfx.config.max_backends_per_se = 2;
|
||||
} else if ((adev->pdev->device == 0x1306) ||
|
||||
(adev->pdev->device == 0x1307) ||
|
||||
(adev->pdev->device == 0x130B) ||
|
||||
(adev->pdev->device == 0x130E) ||
|
||||
(adev->pdev->device == 0x1315) ||
|
||||
(adev->pdev->device == 0x131B)) {
|
||||
adev->gfx.config.max_cu_per_sh = 4;
|
||||
adev->gfx.config.max_backends_per_se = 1;
|
||||
} else {
|
||||
adev->gfx.config.max_cu_per_sh = 3;
|
||||
adev->gfx.config.max_backends_per_se = 1;
|
||||
}
|
||||
adev->gfx.config.max_cu_per_sh = 8;
|
||||
adev->gfx.config.max_backends_per_se = 2;
|
||||
adev->gfx.config.max_sh_per_se = 1;
|
||||
adev->gfx.config.max_texture_channel_caches = 4;
|
||||
adev->gfx.config.max_gprs = 256;
|
||||
|
|
|
|||
|
|
@ -411,6 +411,26 @@ static void output_poll_execute(struct work_struct *work)
|
|||
schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_kms_helper_is_poll_worker - is %current task an output poll worker?
|
||||
*
|
||||
* Determine if %current task is an output poll worker. This can be used
|
||||
* to select distinct code paths for output polling versus other contexts.
|
||||
*
|
||||
* One use case is to avoid a deadlock between the output poll worker and
|
||||
* the autosuspend worker wherein the latter waits for polling to finish
|
||||
* upon calling drm_kms_helper_poll_disable(), while the former waits for
|
||||
* runtime suspend to finish upon calling pm_runtime_get_sync() in a
|
||||
* connector ->detect hook.
|
||||
*/
|
||||
bool drm_kms_helper_is_poll_worker(void)
|
||||
{
|
||||
struct work_struct *work = current_work();
|
||||
|
||||
return work && work->func == output_poll_execute;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_kms_helper_is_poll_worker);
|
||||
|
||||
/**
|
||||
* drm_kms_helper_poll_disable - disable output polling
|
||||
* @dev: drm_device
|
||||
|
|
|
|||
|
|
@ -253,9 +253,15 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
|
|||
nv_connector->edid = NULL;
|
||||
}
|
||||
|
||||
ret = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return conn_status;
|
||||
/* Outputs are only polled while runtime active, so acquiring a
|
||||
* runtime PM ref here is unnecessary (and would deadlock upon
|
||||
* runtime suspend because it waits for polling to finish).
|
||||
*/
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
ret = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return conn_status;
|
||||
}
|
||||
|
||||
nv_encoder = nouveau_connector_ddc_detect(connector);
|
||||
if (nv_encoder && (i2c = nv_encoder->i2c) != NULL) {
|
||||
|
|
@ -323,8 +329,10 @@ nouveau_connector_detect(struct drm_connector *connector, bool force)
|
|||
|
||||
out:
|
||||
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
}
|
||||
|
||||
return conn_status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3599,35 +3599,8 @@ static void cik_gpu_init(struct radeon_device *rdev)
|
|||
case CHIP_KAVERI:
|
||||
rdev->config.cik.max_shader_engines = 1;
|
||||
rdev->config.cik.max_tile_pipes = 4;
|
||||
if ((rdev->pdev->device == 0x1304) ||
|
||||
(rdev->pdev->device == 0x1305) ||
|
||||
(rdev->pdev->device == 0x130C) ||
|
||||
(rdev->pdev->device == 0x130F) ||
|
||||
(rdev->pdev->device == 0x1310) ||
|
||||
(rdev->pdev->device == 0x1311) ||
|
||||
(rdev->pdev->device == 0x131C)) {
|
||||
rdev->config.cik.max_cu_per_sh = 8;
|
||||
rdev->config.cik.max_backends_per_se = 2;
|
||||
} else if ((rdev->pdev->device == 0x1309) ||
|
||||
(rdev->pdev->device == 0x130A) ||
|
||||
(rdev->pdev->device == 0x130D) ||
|
||||
(rdev->pdev->device == 0x1313) ||
|
||||
(rdev->pdev->device == 0x131D)) {
|
||||
rdev->config.cik.max_cu_per_sh = 6;
|
||||
rdev->config.cik.max_backends_per_se = 2;
|
||||
} else if ((rdev->pdev->device == 0x1306) ||
|
||||
(rdev->pdev->device == 0x1307) ||
|
||||
(rdev->pdev->device == 0x130B) ||
|
||||
(rdev->pdev->device == 0x130E) ||
|
||||
(rdev->pdev->device == 0x1315) ||
|
||||
(rdev->pdev->device == 0x1318) ||
|
||||
(rdev->pdev->device == 0x131B)) {
|
||||
rdev->config.cik.max_cu_per_sh = 4;
|
||||
rdev->config.cik.max_backends_per_se = 1;
|
||||
} else {
|
||||
rdev->config.cik.max_cu_per_sh = 3;
|
||||
rdev->config.cik.max_backends_per_se = 1;
|
||||
}
|
||||
rdev->config.cik.max_cu_per_sh = 8;
|
||||
rdev->config.cik.max_backends_per_se = 2;
|
||||
rdev->config.cik.max_sh_per_se = 1;
|
||||
rdev->config.cik.max_texture_channel_caches = 4;
|
||||
rdev->config.cik.max_gprs = 256;
|
||||
|
|
|
|||
|
|
@ -891,9 +891,11 @@ radeon_lvds_detect(struct drm_connector *connector, bool force)
|
|||
enum drm_connector_status ret = connector_status_disconnected;
|
||||
int r;
|
||||
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
if (encoder) {
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
|
|
@ -916,8 +918,12 @@ radeon_lvds_detect(struct drm_connector *connector, bool force)
|
|||
/* check acpi lid status ??? */
|
||||
|
||||
radeon_connector_update_scratch_regs(connector, ret);
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1020,9 +1026,11 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
|
|||
enum drm_connector_status ret = connector_status_disconnected;
|
||||
int r;
|
||||
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
encoder = radeon_best_single_encoder(connector);
|
||||
if (!encoder)
|
||||
|
|
@ -1089,8 +1097,10 @@ radeon_vga_detect(struct drm_connector *connector, bool force)
|
|||
radeon_connector_update_scratch_regs(connector, ret);
|
||||
|
||||
out:
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1153,9 +1163,11 @@ radeon_tv_detect(struct drm_connector *connector, bool force)
|
|||
if (!radeon_connector->dac_load_detect)
|
||||
return ret;
|
||||
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
encoder = radeon_best_single_encoder(connector);
|
||||
if (!encoder)
|
||||
|
|
@ -1167,8 +1179,12 @@ radeon_tv_detect(struct drm_connector *connector, bool force)
|
|||
if (ret == connector_status_connected)
|
||||
ret = radeon_connector_analog_encoder_conflict_solve(connector, encoder, ret, false);
|
||||
radeon_connector_update_scratch_regs(connector, ret);
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1230,9 +1246,11 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
|
|||
enum drm_connector_status ret = connector_status_disconnected;
|
||||
bool dret = false, broken_edid = false;
|
||||
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
if (radeon_connector->detected_hpd_without_ddc) {
|
||||
force = true;
|
||||
|
|
@ -1415,8 +1433,10 @@ radeon_dvi_detect(struct drm_connector *connector, bool force)
|
|||
}
|
||||
|
||||
exit:
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1666,9 +1686,11 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
|
|||
if (radeon_dig_connector->is_mst)
|
||||
return connector_status_disconnected;
|
||||
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
r = pm_runtime_get_sync(connector->dev->dev);
|
||||
if (r < 0)
|
||||
return connector_status_disconnected;
|
||||
}
|
||||
|
||||
if (!force && radeon_check_hpd_status_unchanged(connector)) {
|
||||
ret = connector->status;
|
||||
|
|
@ -1755,8 +1777,10 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
|
|||
}
|
||||
|
||||
out:
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
if (!drm_kms_helper_is_poll_worker()) {
|
||||
pm_runtime_mark_last_busy(connector->dev->dev);
|
||||
pm_runtime_put_autosuspend(connector->dev->dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1138,6 +1138,9 @@ static ssize_t ucma_init_qp_attr(struct ucma_file *file,
|
|||
if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
|
||||
return -EFAULT;
|
||||
|
||||
if (cmd.qp_state > IB_QPS_ERR)
|
||||
return -EINVAL;
|
||||
|
||||
ctx = ucma_get_ctx(file, cmd.id);
|
||||
if (IS_ERR(ctx))
|
||||
return PTR_ERR(ctx);
|
||||
|
|
@ -1274,6 +1277,9 @@ static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf,
|
|||
if (IS_ERR(ctx))
|
||||
return PTR_ERR(ctx);
|
||||
|
||||
if (unlikely(cmd.optval > KMALLOC_MAX_SIZE))
|
||||
return -EINVAL;
|
||||
|
||||
optval = memdup_user((void __user *) (unsigned long) cmd.optval,
|
||||
cmd.optlen);
|
||||
if (IS_ERR(optval)) {
|
||||
|
|
|
|||
|
|
@ -972,7 +972,12 @@ static int resize_user(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
|
|||
if (ucmd.reserved0 || ucmd.reserved1)
|
||||
return -EINVAL;
|
||||
|
||||
umem = ib_umem_get(context, ucmd.buf_addr, entries * ucmd.cqe_size,
|
||||
/* check multiplication overflow */
|
||||
if (ucmd.cqe_size && SIZE_MAX / ucmd.cqe_size <= entries - 1)
|
||||
return -EINVAL;
|
||||
|
||||
umem = ib_umem_get(context, ucmd.buf_addr,
|
||||
(size_t)ucmd.cqe_size * entries,
|
||||
IB_ACCESS_LOCAL_WRITE, 1);
|
||||
if (IS_ERR(umem)) {
|
||||
err = PTR_ERR(umem);
|
||||
|
|
|
|||
|
|
@ -216,8 +216,10 @@ static void matrix_keypad_stop(struct input_dev *dev)
|
|||
{
|
||||
struct matrix_keypad *keypad = input_get_drvdata(dev);
|
||||
|
||||
spin_lock_irq(&keypad->lock);
|
||||
keypad->stopped = true;
|
||||
mb();
|
||||
spin_unlock_irq(&keypad->lock);
|
||||
|
||||
flush_work(&keypad->work.work);
|
||||
/*
|
||||
* matrix_keypad_scan() will leave IRQs enabled;
|
||||
|
|
|
|||
|
|
@ -189,8 +189,6 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
|
|||
input_event(input, EV_MSC, MSC_SCAN, code);
|
||||
input_report_key(input, keymap[code], state);
|
||||
|
||||
/* Read for next loop */
|
||||
error = tca8418_read_byte(keypad_data, REG_KEY_EVENT_A, ®);
|
||||
} while (1);
|
||||
|
||||
input_sync(input);
|
||||
|
|
|
|||
|
|
@ -935,6 +935,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c)
|
|||
uint32_t rtime = cpu_to_le32(get_seconds());
|
||||
struct uuid_entry *u;
|
||||
char buf[BDEVNAME_SIZE];
|
||||
struct cached_dev *exist_dc, *t;
|
||||
|
||||
bdevname(dc->bdev, buf);
|
||||
|
||||
|
|
@ -958,6 +959,16 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check whether already attached */
|
||||
list_for_each_entry_safe(exist_dc, t, &c->cached_devs, list) {
|
||||
if (!memcmp(dc->sb.uuid, exist_dc->sb.uuid, 16)) {
|
||||
pr_err("Tried to attach %s but duplicate UUID already attached",
|
||||
buf);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
u = uuid_find(c, dc->sb.uuid);
|
||||
|
||||
if (u &&
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ static void i2c_wr8(struct v4l2_subdev *sd, u16 reg, u8 val)
|
|||
static void i2c_wr8_and_or(struct v4l2_subdev *sd, u16 reg,
|
||||
u8 mask, u8 val)
|
||||
{
|
||||
i2c_wrreg(sd, reg, (i2c_rdreg(sd, reg, 2) & mask) | val, 2);
|
||||
i2c_wrreg(sd, reg, (i2c_rdreg(sd, reg, 1) & mask) | val, 1);
|
||||
}
|
||||
|
||||
static u16 i2c_rd16(struct v4l2_subdev *sd, u16 reg)
|
||||
|
|
|
|||
|
|
@ -265,6 +265,12 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
|
|||
vol->last_eb_bytes = vol->usable_leb_size;
|
||||
}
|
||||
|
||||
/* Make volume "available" before it becomes accessible via sysfs */
|
||||
spin_lock(&ubi->volumes_lock);
|
||||
ubi->volumes[vol_id] = vol;
|
||||
ubi->vol_count += 1;
|
||||
spin_unlock(&ubi->volumes_lock);
|
||||
|
||||
/* Register character device for the volume */
|
||||
cdev_init(&vol->cdev, &ubi_vol_cdev_operations);
|
||||
vol->cdev.owner = THIS_MODULE;
|
||||
|
|
@ -304,11 +310,6 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
|
|||
if (err)
|
||||
goto out_sysfs;
|
||||
|
||||
spin_lock(&ubi->volumes_lock);
|
||||
ubi->volumes[vol_id] = vol;
|
||||
ubi->vol_count += 1;
|
||||
spin_unlock(&ubi->volumes_lock);
|
||||
|
||||
ubi_volume_notify(ubi, vol, UBI_VOLUME_ADDED);
|
||||
self_check_volumes(ubi);
|
||||
return err;
|
||||
|
|
@ -328,6 +329,10 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
|
|||
out_cdev:
|
||||
cdev_del(&vol->cdev);
|
||||
out_mapping:
|
||||
spin_lock(&ubi->volumes_lock);
|
||||
ubi->volumes[vol_id] = NULL;
|
||||
ubi->vol_count -= 1;
|
||||
spin_unlock(&ubi->volumes_lock);
|
||||
if (do_free)
|
||||
kfree(vol->eba_tbl);
|
||||
out_acc:
|
||||
|
|
|
|||
|
|
@ -365,6 +365,7 @@ qla24xx_abort_sp_done(void *data, void *ptr, int res)
|
|||
srb_t *sp = (srb_t *)ptr;
|
||||
struct srb_iocb *abt = &sp->u.iocb_cmd;
|
||||
|
||||
del_timer(&sp->u.iocb_cmd.timer);
|
||||
complete(&abt->u.abt.comp);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5502,7 +5502,7 @@ static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha,
|
|||
fc_port_t *fcport;
|
||||
int rc;
|
||||
|
||||
fcport = kzalloc(sizeof(*fcport), GFP_KERNEL);
|
||||
fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
|
||||
if (!fcport) {
|
||||
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06f,
|
||||
"qla_target(%d): Allocation of tmp FC port failed",
|
||||
|
|
|
|||
|
|
@ -330,24 +330,23 @@ static loff_t ashmem_llseek(struct file *file, loff_t offset, int origin)
|
|||
mutex_lock(&ashmem_mutex);
|
||||
|
||||
if (asma->size == 0) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
mutex_unlock(&ashmem_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!asma->file) {
|
||||
ret = -EBADF;
|
||||
goto out;
|
||||
mutex_unlock(&ashmem_mutex);
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
mutex_unlock(&ashmem_mutex);
|
||||
|
||||
ret = vfs_llseek(asma->file, offset, origin);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
return ret;
|
||||
|
||||
/** Copy f_pos from backing file, since f_ops->llseek() sets it */
|
||||
file->f_pos = asma->file->f_pos;
|
||||
|
||||
out:
|
||||
mutex_unlock(&ashmem_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -484,8 +484,7 @@ unsigned int comedi_nsamples_left(struct comedi_subdevice *s,
|
|||
struct comedi_cmd *cmd = &async->cmd;
|
||||
|
||||
if (cmd->stop_src == TRIG_COUNT) {
|
||||
unsigned int nscans = nsamples / cmd->scan_end_arg;
|
||||
unsigned int scans_left = __comedi_nscans_left(s, nscans);
|
||||
unsigned int scans_left = __comedi_nscans_left(s, cmd->stop_arg);
|
||||
unsigned int scan_pos =
|
||||
comedi_bytes_to_samples(s, async->scan_progress);
|
||||
unsigned long long samples_left = 0;
|
||||
|
|
|
|||
|
|
@ -5299,6 +5299,17 @@ static struct pci_device_id serial_pci_tbl[] = {
|
|||
{ PCI_VENDOR_ID_INTASHIELD, PCI_DEVICE_ID_INTASHIELD_IS400,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0, /* 135a.0dc0 */
|
||||
pbn_b2_4_115200 },
|
||||
/*
|
||||
* BrainBoxes UC-260
|
||||
*/
|
||||
{ PCI_VENDOR_ID_INTASHIELD, 0x0D21,
|
||||
PCI_ANY_ID, PCI_ANY_ID,
|
||||
PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00,
|
||||
pbn_b2_4_115200 },
|
||||
{ PCI_VENDOR_ID_INTASHIELD, 0x0E34,
|
||||
PCI_ANY_ID, PCI_ANY_ID,
|
||||
PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00,
|
||||
pbn_b2_4_115200 },
|
||||
/*
|
||||
* Perle PCI-RAS cards
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1783,6 +1783,7 @@ static void atmel_get_ip_name(struct uart_port *port)
|
|||
switch (version) {
|
||||
case 0x302:
|
||||
case 0x10213:
|
||||
case 0x10302:
|
||||
dev_dbg(port->dev, "This version is usart\n");
|
||||
atmel_port->is_usart = true;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -847,6 +847,8 @@ static void sci_receive_chars(struct uart_port *port)
|
|||
/* Tell the rest of the system the news. New characters! */
|
||||
tty_flip_buffer_push(tport);
|
||||
} else {
|
||||
/* TTY buffers full; read from RX reg to prevent lockup */
|
||||
serial_port_in(port, SCxRDR);
|
||||
serial_port_in(port, SCxSR); /* dummy read */
|
||||
sci_clear_SCxSR(port, SCxSR_RDxF_CLEAR(port));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,6 +147,10 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
|
|||
|
||||
ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
|
||||
|
||||
/* Linger a bit, prior to the next control message. */
|
||||
if (dev->quirks & USB_QUIRK_DELAY_CTRL_MSG)
|
||||
msleep(200);
|
||||
|
||||
kfree(dr);
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -229,7 +229,8 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||
{ USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
|
||||
/* Corsair Strafe RGB */
|
||||
{ USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
{ USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT |
|
||||
USB_QUIRK_DELAY_CTRL_MSG },
|
||||
|
||||
/* Corsair K70 LUX */
|
||||
{ USB_DEVICE(0x1b1c, 0x1b36), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
|
|
|
|||
|
|
@ -1333,7 +1333,6 @@ ffs_fs_kill_sb(struct super_block *sb)
|
|||
if (sb->s_fs_info) {
|
||||
ffs_release_dev(sb->s_fs_info);
|
||||
ffs_data_closed(sb->s_fs_info);
|
||||
ffs_data_put(sb->s_fs_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ struct mon_reader_text {
|
|||
|
||||
wait_queue_head_t wait;
|
||||
int printf_size;
|
||||
size_t printf_offset;
|
||||
size_t printf_togo;
|
||||
char *printf_buf;
|
||||
struct mutex printf_lock;
|
||||
|
||||
|
|
@ -373,73 +375,103 @@ static int mon_text_open(struct inode *inode, struct file *file)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* For simplicity, we read one record in one system call and throw out
|
||||
* what does not fit. This means that the following does not work:
|
||||
* dd if=/dbg/usbmon/0t bs=10
|
||||
* Also, we do not allow seeks and do not bother advancing the offset.
|
||||
*/
|
||||
static ssize_t mon_text_read_t(struct file *file, char __user *buf,
|
||||
size_t nbytes, loff_t *ppos)
|
||||
static ssize_t mon_text_copy_to_user(struct mon_reader_text *rp,
|
||||
char __user * const buf, const size_t nbytes)
|
||||
{
|
||||
struct mon_reader_text *rp = file->private_data;
|
||||
struct mon_event_text *ep;
|
||||
struct mon_text_ptr ptr;
|
||||
const size_t togo = min(nbytes, rp->printf_togo);
|
||||
|
||||
if (IS_ERR(ep = mon_text_read_wait(rp, file)))
|
||||
return PTR_ERR(ep);
|
||||
mutex_lock(&rp->printf_lock);
|
||||
ptr.cnt = 0;
|
||||
ptr.pbuf = rp->printf_buf;
|
||||
ptr.limit = rp->printf_size;
|
||||
|
||||
mon_text_read_head_t(rp, &ptr, ep);
|
||||
mon_text_read_statset(rp, &ptr, ep);
|
||||
ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
|
||||
" %d", ep->length);
|
||||
mon_text_read_data(rp, &ptr, ep);
|
||||
|
||||
if (copy_to_user(buf, rp->printf_buf, ptr.cnt))
|
||||
ptr.cnt = -EFAULT;
|
||||
mutex_unlock(&rp->printf_lock);
|
||||
kmem_cache_free(rp->e_slab, ep);
|
||||
return ptr.cnt;
|
||||
if (copy_to_user(buf, &rp->printf_buf[rp->printf_offset], togo))
|
||||
return -EFAULT;
|
||||
rp->printf_togo -= togo;
|
||||
rp->printf_offset += togo;
|
||||
return togo;
|
||||
}
|
||||
|
||||
static ssize_t mon_text_read_u(struct file *file, char __user *buf,
|
||||
size_t nbytes, loff_t *ppos)
|
||||
/* ppos is not advanced since the llseek operation is not permitted. */
|
||||
static ssize_t mon_text_read_t(struct file *file, char __user *buf,
|
||||
size_t nbytes, loff_t *ppos)
|
||||
{
|
||||
struct mon_reader_text *rp = file->private_data;
|
||||
struct mon_event_text *ep;
|
||||
struct mon_text_ptr ptr;
|
||||
ssize_t ret;
|
||||
|
||||
if (IS_ERR(ep = mon_text_read_wait(rp, file)))
|
||||
return PTR_ERR(ep);
|
||||
mutex_lock(&rp->printf_lock);
|
||||
ptr.cnt = 0;
|
||||
ptr.pbuf = rp->printf_buf;
|
||||
ptr.limit = rp->printf_size;
|
||||
|
||||
mon_text_read_head_u(rp, &ptr, ep);
|
||||
if (ep->type == 'E') {
|
||||
mon_text_read_statset(rp, &ptr, ep);
|
||||
} else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) {
|
||||
mon_text_read_isostat(rp, &ptr, ep);
|
||||
mon_text_read_isodesc(rp, &ptr, ep);
|
||||
} else if (ep->xfertype == USB_ENDPOINT_XFER_INT) {
|
||||
mon_text_read_intstat(rp, &ptr, ep);
|
||||
} else {
|
||||
if (rp->printf_togo == 0) {
|
||||
|
||||
ep = mon_text_read_wait(rp, file);
|
||||
if (IS_ERR(ep)) {
|
||||
mutex_unlock(&rp->printf_lock);
|
||||
return PTR_ERR(ep);
|
||||
}
|
||||
ptr.cnt = 0;
|
||||
ptr.pbuf = rp->printf_buf;
|
||||
ptr.limit = rp->printf_size;
|
||||
|
||||
mon_text_read_head_t(rp, &ptr, ep);
|
||||
mon_text_read_statset(rp, &ptr, ep);
|
||||
ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
|
||||
" %d", ep->length);
|
||||
mon_text_read_data(rp, &ptr, ep);
|
||||
|
||||
rp->printf_togo = ptr.cnt;
|
||||
rp->printf_offset = 0;
|
||||
|
||||
kmem_cache_free(rp->e_slab, ep);
|
||||
}
|
||||
ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
|
||||
" %d", ep->length);
|
||||
mon_text_read_data(rp, &ptr, ep);
|
||||
|
||||
if (copy_to_user(buf, rp->printf_buf, ptr.cnt))
|
||||
ptr.cnt = -EFAULT;
|
||||
ret = mon_text_copy_to_user(rp, buf, nbytes);
|
||||
mutex_unlock(&rp->printf_lock);
|
||||
kmem_cache_free(rp->e_slab, ep);
|
||||
return ptr.cnt;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ppos is not advanced since the llseek operation is not permitted. */
|
||||
static ssize_t mon_text_read_u(struct file *file, char __user *buf,
|
||||
size_t nbytes, loff_t *ppos)
|
||||
{
|
||||
struct mon_reader_text *rp = file->private_data;
|
||||
struct mon_event_text *ep;
|
||||
struct mon_text_ptr ptr;
|
||||
ssize_t ret;
|
||||
|
||||
mutex_lock(&rp->printf_lock);
|
||||
|
||||
if (rp->printf_togo == 0) {
|
||||
|
||||
ep = mon_text_read_wait(rp, file);
|
||||
if (IS_ERR(ep)) {
|
||||
mutex_unlock(&rp->printf_lock);
|
||||
return PTR_ERR(ep);
|
||||
}
|
||||
ptr.cnt = 0;
|
||||
ptr.pbuf = rp->printf_buf;
|
||||
ptr.limit = rp->printf_size;
|
||||
|
||||
mon_text_read_head_u(rp, &ptr, ep);
|
||||
if (ep->type == 'E') {
|
||||
mon_text_read_statset(rp, &ptr, ep);
|
||||
} else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) {
|
||||
mon_text_read_isostat(rp, &ptr, ep);
|
||||
mon_text_read_isodesc(rp, &ptr, ep);
|
||||
} else if (ep->xfertype == USB_ENDPOINT_XFER_INT) {
|
||||
mon_text_read_intstat(rp, &ptr, ep);
|
||||
} else {
|
||||
mon_text_read_statset(rp, &ptr, ep);
|
||||
}
|
||||
ptr.cnt += snprintf(ptr.pbuf + ptr.cnt, ptr.limit - ptr.cnt,
|
||||
" %d", ep->length);
|
||||
mon_text_read_data(rp, &ptr, ep);
|
||||
|
||||
rp->printf_togo = ptr.cnt;
|
||||
rp->printf_offset = 0;
|
||||
|
||||
kmem_cache_free(rp->e_slab, ep);
|
||||
}
|
||||
|
||||
ret = mon_text_copy_to_user(rp, buf, nbytes);
|
||||
mutex_unlock(&rp->printf_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct mon_event_text *mon_text_read_wait(struct mon_reader_text *rp,
|
||||
|
|
|
|||
|
|
@ -1052,7 +1052,7 @@ static int uas_post_reset(struct usb_interface *intf)
|
|||
return 0;
|
||||
|
||||
err = uas_configure_endpoints(devinfo);
|
||||
if (err && err != ENODEV)
|
||||
if (err && err != -ENODEV)
|
||||
shost_printk(KERN_ERR, shost,
|
||||
"%s: alloc streams error %d after reset",
|
||||
__func__, err);
|
||||
|
|
|
|||
|
|
@ -2142,6 +2142,13 @@ UNUSUAL_DEV( 0x22b8, 0x3010, 0x0001, 0x0001,
|
|||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ),
|
||||
|
||||
/* Reported by Teijo Kinnunen <teijo.kinnunen@code-q.fi> */
|
||||
UNUSUAL_DEV( 0x152d, 0x2567, 0x0117, 0x0117,
|
||||
"JMicron",
|
||||
"USB to ATA/ATAPI Bridge",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_BROKEN_FUA ),
|
||||
|
||||
/* Reported-by George Cherian <george.cherian@cavium.com> */
|
||||
UNUSUAL_DEV(0x152d, 0x9561, 0x0000, 0x9999,
|
||||
"JMicron",
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ static char expect_release;
|
|||
static unsigned long hpwdt_is_open;
|
||||
|
||||
static void __iomem *pci_mem_addr; /* the PCI-memory address */
|
||||
static unsigned long __iomem *hpwdt_nmistat;
|
||||
static unsigned long __iomem *hpwdt_timer_reg;
|
||||
static unsigned long __iomem *hpwdt_timer_con;
|
||||
|
||||
|
|
@ -474,6 +475,11 @@ static int hpwdt_time_left(void)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_HPWDT_NMI_DECODING
|
||||
static int hpwdt_my_nmi(void)
|
||||
{
|
||||
return ioread8(hpwdt_nmistat) & 0x6;
|
||||
}
|
||||
|
||||
/*
|
||||
* NMI Handler
|
||||
*/
|
||||
|
|
@ -485,6 +491,9 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
|
|||
if (!hpwdt_nmi_decoding)
|
||||
goto out;
|
||||
|
||||
if ((ulReason == NMI_UNKNOWN) && !hpwdt_my_nmi())
|
||||
return NMI_DONE;
|
||||
|
||||
spin_lock_irqsave(&rom_lock, rom_pl);
|
||||
if (!die_nmi_called && !is_icru && !is_uefi)
|
||||
asminline_call(&cmn_regs, cru_rom_addr);
|
||||
|
|
@ -700,7 +709,7 @@ static void dmi_find_icru(const struct dmi_header *dm, void *dummy)
|
|||
smbios_proliant_ptr = (struct smbios_proliant_info *) dm;
|
||||
if (smbios_proliant_ptr->misc_features & 0x01)
|
||||
is_icru = 1;
|
||||
if (smbios_proliant_ptr->misc_features & 0x408)
|
||||
if (smbios_proliant_ptr->misc_features & 0x1400)
|
||||
is_uefi = 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -840,6 +849,7 @@ static int hpwdt_init_one(struct pci_dev *dev,
|
|||
retval = -ENOMEM;
|
||||
goto error_pci_iomap;
|
||||
}
|
||||
hpwdt_nmistat = pci_mem_addr + 0x6e;
|
||||
hpwdt_timer_reg = pci_mem_addr + 0x70;
|
||||
hpwdt_timer_con = pci_mem_addr + 0x72;
|
||||
|
||||
|
|
|
|||
|
|
@ -828,8 +828,6 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
|
|||
if (!IS_LAST_ENTRY(s->first))
|
||||
ext4_xattr_rehash(header(s->base),
|
||||
s->here);
|
||||
ext4_xattr_cache_insert(ext4_mb_cache,
|
||||
bs->bh);
|
||||
}
|
||||
unlock_buffer(bs->bh);
|
||||
if (error == -EFSCORRUPTED)
|
||||
|
|
@ -918,6 +916,7 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
|
|||
} else if (bs->bh && s->base == bs->bh->b_data) {
|
||||
/* We were modifying this block in-place. */
|
||||
ea_bdebug(bs->bh, "keeping this block");
|
||||
ext4_xattr_cache_insert(ext4_mb_cache, bs->bh);
|
||||
new_bh = bs->bh;
|
||||
get_bh(new_bh);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -86,9 +86,9 @@ struct nfs_direct_req {
|
|||
struct nfs_direct_mirror mirrors[NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX];
|
||||
int mirror_count;
|
||||
|
||||
loff_t io_start; /* Start offset for I/O */
|
||||
ssize_t count, /* bytes actually processed */
|
||||
bytes_left, /* bytes left to be sent */
|
||||
io_start, /* start of IO */
|
||||
error; /* any reported error */
|
||||
struct completion completion; /* wait for i/o completion */
|
||||
|
||||
|
|
|
|||
|
|
@ -241,5 +241,6 @@ extern void drm_kms_helper_hotplug_event(struct drm_device *dev);
|
|||
extern void drm_kms_helper_poll_disable(struct drm_device *dev);
|
||||
extern void drm_kms_helper_poll_enable(struct drm_device *dev);
|
||||
extern void drm_kms_helper_poll_enable_locked(struct drm_device *dev);
|
||||
extern bool drm_kms_helper_is_poll_worker(void);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -368,38 +368,14 @@ static inline unsigned long ifname_compare_aligned(const char *_a,
|
|||
return ret;
|
||||
}
|
||||
|
||||
struct xt_percpu_counter_alloc_state {
|
||||
unsigned int off;
|
||||
const char __percpu *mem;
|
||||
};
|
||||
|
||||
/* On SMP, ip(6)t_entry->counters.pcnt holds address of the
|
||||
* real (percpu) counter. On !SMP, its just the packet count,
|
||||
* so nothing needs to be done there.
|
||||
*
|
||||
* xt_percpu_counter_alloc returns the address of the percpu
|
||||
* counter, or 0 on !SMP. We force an alignment of 16 bytes
|
||||
* so that bytes/packets share a common cache line.
|
||||
*
|
||||
* Hence caller must use IS_ERR_VALUE to check for error, this
|
||||
* allows us to return 0 for single core systems without forcing
|
||||
* callers to deal with SMP vs. NONSMP issues.
|
||||
*/
|
||||
static inline unsigned long xt_percpu_counter_alloc(void)
|
||||
{
|
||||
if (nr_cpu_ids > 1) {
|
||||
void __percpu *res = __alloc_percpu(sizeof(struct xt_counters),
|
||||
sizeof(struct xt_counters));
|
||||
|
||||
if (res == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
return (__force unsigned long) res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static inline void xt_percpu_counter_free(u64 pcnt)
|
||||
{
|
||||
if (nr_cpu_ids > 1)
|
||||
free_percpu((void __percpu *) (unsigned long) pcnt);
|
||||
}
|
||||
bool xt_percpu_counter_alloc(struct xt_percpu_counter_alloc_state *state,
|
||||
struct xt_counters *counter);
|
||||
void xt_percpu_counter_free(struct xt_counters *cnt);
|
||||
|
||||
static inline struct xt_counters *
|
||||
xt_get_this_cpu_counter(struct xt_counters *cnt)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#ifndef _LINUX_NOSPEC_H
|
||||
#define _LINUX_NOSPEC_H
|
||||
#include <asm/barrier.h>
|
||||
|
||||
/**
|
||||
* array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise
|
||||
|
|
|
|||
|
|
@ -56,4 +56,7 @@
|
|||
*/
|
||||
#define USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL BIT(11)
|
||||
|
||||
/* Device needs a pause after every control message. */
|
||||
#define USB_QUIRK_DELAY_CTRL_MSG BIT(13)
|
||||
|
||||
#endif /* __LINUX_USB_QUIRKS_H */
|
||||
|
|
|
|||
|
|
@ -451,6 +451,7 @@ extern bool cancel_delayed_work_sync(struct delayed_work *dwork);
|
|||
|
||||
extern void workqueue_set_max_active(struct workqueue_struct *wq,
|
||||
int max_active);
|
||||
extern struct work_struct *current_work(void);
|
||||
extern bool current_is_workqueue_rescuer(void);
|
||||
extern bool workqueue_congested(int cpu, struct workqueue_struct *wq);
|
||||
extern unsigned int work_busy(struct work_struct *work);
|
||||
|
|
|
|||
|
|
@ -4047,6 +4047,22 @@ void workqueue_set_max_active(struct workqueue_struct *wq, int max_active)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(workqueue_set_max_active);
|
||||
|
||||
/**
|
||||
* current_work - retrieve %current task's work struct
|
||||
*
|
||||
* Determine if %current task is a workqueue worker and what it's working on.
|
||||
* Useful to find out the context that the %current task is running in.
|
||||
*
|
||||
* Return: work struct if %current task is a workqueue worker, %NULL otherwise.
|
||||
*/
|
||||
struct work_struct *current_work(void)
|
||||
{
|
||||
struct worker *worker = current_wq_worker();
|
||||
|
||||
return worker ? worker->current_work : NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(current_work);
|
||||
|
||||
/**
|
||||
* current_is_workqueue_rescuer - is %current workqueue rescuer?
|
||||
*
|
||||
|
|
|
|||
|
|
@ -172,18 +172,35 @@ ebt_among_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool poolsize_invalid(const struct ebt_mac_wormhash *w)
|
||||
{
|
||||
return w && w->poolsize >= (INT_MAX / sizeof(struct ebt_mac_wormhash_tuple));
|
||||
}
|
||||
|
||||
static int ebt_among_mt_check(const struct xt_mtchk_param *par)
|
||||
{
|
||||
const struct ebt_among_info *info = par->matchinfo;
|
||||
const struct ebt_entry_match *em =
|
||||
container_of(par->matchinfo, const struct ebt_entry_match, data);
|
||||
int expected_length = sizeof(struct ebt_among_info);
|
||||
unsigned int expected_length = sizeof(struct ebt_among_info);
|
||||
const struct ebt_mac_wormhash *wh_dst, *wh_src;
|
||||
int err;
|
||||
|
||||
if (expected_length > em->match_size)
|
||||
return -EINVAL;
|
||||
|
||||
wh_dst = ebt_among_wh_dst(info);
|
||||
wh_src = ebt_among_wh_src(info);
|
||||
if (poolsize_invalid(wh_dst))
|
||||
return -EINVAL;
|
||||
|
||||
expected_length += ebt_mac_wormhash_size(wh_dst);
|
||||
if (expected_length > em->match_size)
|
||||
return -EINVAL;
|
||||
|
||||
wh_src = ebt_among_wh_src(info);
|
||||
if (poolsize_invalid(wh_src))
|
||||
return -EINVAL;
|
||||
|
||||
expected_length += ebt_mac_wormhash_size(wh_src);
|
||||
|
||||
if (em->match_size != EBT_ALIGN(expected_length)) {
|
||||
|
|
|
|||
|
|
@ -2021,7 +2021,9 @@ static int ebt_size_mwt(struct compat_ebt_entry_mwt *match32,
|
|||
if (match_kern)
|
||||
match_kern->match_size = ret;
|
||||
|
||||
WARN_ON(type == EBT_COMPAT_TARGET && size_left);
|
||||
if (WARN_ON(type == EBT_COMPAT_TARGET && size_left))
|
||||
return -EINVAL;
|
||||
|
||||
match32 = (struct compat_ebt_entry_mwt *) buf;
|
||||
}
|
||||
|
||||
|
|
@ -2078,6 +2080,15 @@ static int size_entry_mwt(struct ebt_entry *entry, const unsigned char *base,
|
|||
*
|
||||
* offsets are relative to beginning of struct ebt_entry (i.e., 0).
|
||||
*/
|
||||
for (i = 0; i < 4 ; ++i) {
|
||||
if (offsets[i] >= *total)
|
||||
return -EINVAL;
|
||||
if (i == 0)
|
||||
continue;
|
||||
if (offsets[i-1] > offsets[i])
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0, j = 1 ; j < 4 ; j++, i++) {
|
||||
struct compat_ebt_entry_mwt *match32;
|
||||
unsigned int size;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned int addr_t
|
|||
struct rtable *rt;
|
||||
struct flowi4 fl4 = {};
|
||||
__be32 saddr = iph->saddr;
|
||||
__u8 flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
|
||||
const struct sock *sk = skb_to_full_sk(skb);
|
||||
__u8 flags = sk ? inet_sk_flowi_flags(sk) : 0;
|
||||
unsigned int hh_len;
|
||||
|
||||
if (addr_type == RTN_UNSPEC)
|
||||
|
|
@ -39,7 +40,7 @@ int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned int addr_t
|
|||
fl4.daddr = iph->daddr;
|
||||
fl4.saddr = saddr;
|
||||
fl4.flowi4_tos = RT_TOS(iph->tos);
|
||||
fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
|
||||
fl4.flowi4_oif = sk ? sk->sk_bound_dev_if : 0;
|
||||
fl4.flowi4_mark = skb->mark;
|
||||
fl4.flowi4_flags = flags;
|
||||
rt = ip_route_output_key(net, &fl4);
|
||||
|
|
@ -58,7 +59,7 @@ int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned int addr_t
|
|||
xfrm_decode_session(skb, flowi4_to_flowi(&fl4), AF_INET) == 0) {
|
||||
struct dst_entry *dst = skb_dst(skb);
|
||||
skb_dst_set(skb, NULL);
|
||||
dst = xfrm_lookup(net, dst, flowi4_to_flowi(&fl4), skb->sk, 0);
|
||||
dst = xfrm_lookup(net, dst, flowi4_to_flowi(&fl4), sk, 0);
|
||||
if (IS_ERR(dst))
|
||||
return PTR_ERR(dst);
|
||||
skb_dst_set(skb, dst);
|
||||
|
|
|
|||
|
|
@ -329,6 +329,10 @@ unsigned int arpt_do_table(struct sk_buff *skb,
|
|||
}
|
||||
if (table_base + v
|
||||
!= arpt_next_entry(e)) {
|
||||
if (unlikely(stackidx >= private->stacksize)) {
|
||||
verdict = NF_DROP;
|
||||
break;
|
||||
}
|
||||
jumpstack[stackidx++] = e;
|
||||
}
|
||||
|
||||
|
|
@ -507,17 +511,15 @@ static inline int check_target(struct arpt_entry *e, const char *name)
|
|||
}
|
||||
|
||||
static inline int
|
||||
find_check_entry(struct arpt_entry *e, const char *name, unsigned int size)
|
||||
find_check_entry(struct arpt_entry *e, const char *name, unsigned int size,
|
||||
struct xt_percpu_counter_alloc_state *alloc_state)
|
||||
{
|
||||
struct xt_entry_target *t;
|
||||
struct xt_target *target;
|
||||
unsigned long pcnt;
|
||||
int ret;
|
||||
|
||||
pcnt = xt_percpu_counter_alloc();
|
||||
if (IS_ERR_VALUE(pcnt))
|
||||
if (!xt_percpu_counter_alloc(alloc_state, &e->counters))
|
||||
return -ENOMEM;
|
||||
e->counters.pcnt = pcnt;
|
||||
|
||||
t = arpt_get_target(e);
|
||||
target = xt_request_find_target(NFPROTO_ARP, t->u.user.name,
|
||||
|
|
@ -536,7 +538,7 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size)
|
|||
err:
|
||||
module_put(t->u.kernel.target->me);
|
||||
out:
|
||||
xt_percpu_counter_free(e->counters.pcnt);
|
||||
xt_percpu_counter_free(&e->counters);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -624,7 +626,7 @@ static inline void cleanup_entry(struct arpt_entry *e)
|
|||
if (par.target->destroy != NULL)
|
||||
par.target->destroy(&par);
|
||||
module_put(par.target->me);
|
||||
xt_percpu_counter_free(e->counters.pcnt);
|
||||
xt_percpu_counter_free(&e->counters);
|
||||
}
|
||||
|
||||
/* Checks and translates the user-supplied table segment (held in
|
||||
|
|
@ -633,6 +635,7 @@ static inline void cleanup_entry(struct arpt_entry *e)
|
|||
static int translate_table(struct xt_table_info *newinfo, void *entry0,
|
||||
const struct arpt_replace *repl)
|
||||
{
|
||||
struct xt_percpu_counter_alloc_state alloc_state = { 0 };
|
||||
struct arpt_entry *iter;
|
||||
unsigned int *offsets;
|
||||
unsigned int i;
|
||||
|
|
@ -706,7 +709,8 @@ static int translate_table(struct xt_table_info *newinfo, void *entry0,
|
|||
/* Finally, each sanity check must pass */
|
||||
i = 0;
|
||||
xt_entry_foreach(iter, entry0, newinfo->size) {
|
||||
ret = find_check_entry(iter, repl->name, repl->size);
|
||||
ret = find_check_entry(iter, repl->name, repl->size,
|
||||
&alloc_state);
|
||||
if (ret != 0)
|
||||
break;
|
||||
++i;
|
||||
|
|
|
|||
|
|
@ -408,6 +408,10 @@ ipt_do_table(struct sk_buff *skb,
|
|||
}
|
||||
if (table_base + v != ipt_next_entry(e) &&
|
||||
!(e->ip.flags & IPT_F_GOTO)) {
|
||||
if (unlikely(stackidx >= private->stacksize)) {
|
||||
verdict = NF_DROP;
|
||||
break;
|
||||
}
|
||||
jumpstack[stackidx++] = e;
|
||||
pr_debug("Pushed %p into pos %u\n",
|
||||
e, stackidx - 1);
|
||||
|
|
@ -645,7 +649,8 @@ static int check_target(struct ipt_entry *e, struct net *net, const char *name)
|
|||
|
||||
static int
|
||||
find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
|
||||
unsigned int size)
|
||||
unsigned int size,
|
||||
struct xt_percpu_counter_alloc_state *alloc_state)
|
||||
{
|
||||
struct xt_entry_target *t;
|
||||
struct xt_target *target;
|
||||
|
|
@ -653,12 +658,9 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
|
|||
unsigned int j;
|
||||
struct xt_mtchk_param mtpar;
|
||||
struct xt_entry_match *ematch;
|
||||
unsigned long pcnt;
|
||||
|
||||
pcnt = xt_percpu_counter_alloc();
|
||||
if (IS_ERR_VALUE(pcnt))
|
||||
if (!xt_percpu_counter_alloc(alloc_state, &e->counters))
|
||||
return -ENOMEM;
|
||||
e->counters.pcnt = pcnt;
|
||||
|
||||
j = 0;
|
||||
mtpar.net = net;
|
||||
|
|
@ -697,7 +699,7 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
|
|||
cleanup_match(ematch, net);
|
||||
}
|
||||
|
||||
xt_percpu_counter_free(e->counters.pcnt);
|
||||
xt_percpu_counter_free(&e->counters);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -793,7 +795,7 @@ cleanup_entry(struct ipt_entry *e, struct net *net)
|
|||
if (par.target->destroy != NULL)
|
||||
par.target->destroy(&par);
|
||||
module_put(par.target->me);
|
||||
xt_percpu_counter_free(e->counters.pcnt);
|
||||
xt_percpu_counter_free(&e->counters);
|
||||
}
|
||||
|
||||
/* Checks and translates the user-supplied table segment (held in
|
||||
|
|
@ -802,6 +804,7 @@ static int
|
|||
translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
|
||||
const struct ipt_replace *repl)
|
||||
{
|
||||
struct xt_percpu_counter_alloc_state alloc_state = { 0 };
|
||||
struct ipt_entry *iter;
|
||||
unsigned int *offsets;
|
||||
unsigned int i;
|
||||
|
|
@ -871,7 +874,8 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
|
|||
/* Finally, each sanity check must pass */
|
||||
i = 0;
|
||||
xt_entry_foreach(iter, entry0, newinfo->size) {
|
||||
ret = find_check_entry(iter, net, repl->name, repl->size);
|
||||
ret = find_check_entry(iter, net, repl->name, repl->size,
|
||||
&alloc_state);
|
||||
if (ret != 0)
|
||||
break;
|
||||
++i;
|
||||
|
|
|
|||
|
|
@ -425,6 +425,10 @@ ip6t_do_table(struct sk_buff *skb,
|
|||
}
|
||||
if (table_base + v != ip6t_next_entry(e) &&
|
||||
!(e->ipv6.flags & IP6T_F_GOTO)) {
|
||||
if (unlikely(stackidx >= private->stacksize)) {
|
||||
verdict = NF_DROP;
|
||||
break;
|
||||
}
|
||||
jumpstack[stackidx++] = e;
|
||||
}
|
||||
|
||||
|
|
@ -658,7 +662,8 @@ static int check_target(struct ip6t_entry *e, struct net *net, const char *name)
|
|||
|
||||
static int
|
||||
find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
|
||||
unsigned int size)
|
||||
unsigned int size,
|
||||
struct xt_percpu_counter_alloc_state *alloc_state)
|
||||
{
|
||||
struct xt_entry_target *t;
|
||||
struct xt_target *target;
|
||||
|
|
@ -666,12 +671,9 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
|
|||
unsigned int j;
|
||||
struct xt_mtchk_param mtpar;
|
||||
struct xt_entry_match *ematch;
|
||||
unsigned long pcnt;
|
||||
|
||||
pcnt = xt_percpu_counter_alloc();
|
||||
if (IS_ERR_VALUE(pcnt))
|
||||
if (!xt_percpu_counter_alloc(alloc_state, &e->counters))
|
||||
return -ENOMEM;
|
||||
e->counters.pcnt = pcnt;
|
||||
|
||||
j = 0;
|
||||
mtpar.net = net;
|
||||
|
|
@ -709,7 +711,7 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name,
|
|||
cleanup_match(ematch, net);
|
||||
}
|
||||
|
||||
xt_percpu_counter_free(e->counters.pcnt);
|
||||
xt_percpu_counter_free(&e->counters);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -804,8 +806,7 @@ static void cleanup_entry(struct ip6t_entry *e, struct net *net)
|
|||
if (par.target->destroy != NULL)
|
||||
par.target->destroy(&par);
|
||||
module_put(par.target->me);
|
||||
|
||||
xt_percpu_counter_free(e->counters.pcnt);
|
||||
xt_percpu_counter_free(&e->counters);
|
||||
}
|
||||
|
||||
/* Checks and translates the user-supplied table segment (held in
|
||||
|
|
@ -814,6 +815,7 @@ static int
|
|||
translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
|
||||
const struct ip6t_replace *repl)
|
||||
{
|
||||
struct xt_percpu_counter_alloc_state alloc_state = { 0 };
|
||||
struct ip6t_entry *iter;
|
||||
unsigned int *offsets;
|
||||
unsigned int i;
|
||||
|
|
@ -883,7 +885,8 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
|
|||
/* Finally, each sanity check must pass */
|
||||
i = 0;
|
||||
xt_entry_foreach(iter, entry0, newinfo->size) {
|
||||
ret = find_check_entry(iter, net, repl->name, repl->size);
|
||||
ret = find_check_entry(iter, net, repl->name, repl->size,
|
||||
&alloc_state);
|
||||
if (ret != 0)
|
||||
break;
|
||||
++i;
|
||||
|
|
|
|||
|
|
@ -99,6 +99,10 @@ static bool nf_nat_ipv6_manip_pkt(struct sk_buff *skb,
|
|||
!l4proto->manip_pkt(skb, &nf_nat_l3proto_ipv6, iphdroff, hdroff,
|
||||
target, maniptype))
|
||||
return false;
|
||||
|
||||
/* must reload, offset might have changed */
|
||||
ipv6h = (void *)skb->data + iphdroff;
|
||||
|
||||
manip_addr:
|
||||
if (maniptype == NF_NAT_MANIP_SRC)
|
||||
ipv6h->saddr = target->src.u3.in6;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
|
|||
const struct nf_conn *ct,
|
||||
u16 *rover)
|
||||
{
|
||||
unsigned int range_size, min, i;
|
||||
unsigned int range_size, min, max, i;
|
||||
__be16 *portptr;
|
||||
u_int16_t off;
|
||||
|
||||
|
|
@ -71,7 +71,10 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
|
|||
}
|
||||
} else {
|
||||
min = ntohs(range->min_proto.all);
|
||||
range_size = ntohs(range->max_proto.all) - min + 1;
|
||||
max = ntohs(range->max_proto.all);
|
||||
if (unlikely(max < min))
|
||||
swap(max, min);
|
||||
range_size = max - min + 1;
|
||||
}
|
||||
|
||||
if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) {
|
||||
|
|
|
|||
|
|
@ -501,7 +501,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
|
|||
|
||||
if (entskb->tstamp.tv64) {
|
||||
struct nfqnl_msg_packet_timestamp ts;
|
||||
struct timespec64 kts = ktime_to_timespec64(skb->tstamp);
|
||||
struct timespec64 kts = ktime_to_timespec64(entskb->tstamp);
|
||||
|
||||
ts.sec = cpu_to_be64(kts.tv_sec);
|
||||
ts.usec = cpu_to_be64(kts.tv_nsec / NSEC_PER_USEC);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ MODULE_LICENSE("GPL");
|
|||
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
|
||||
MODULE_DESCRIPTION("{ip,ip6,arp,eb}_tables backend module");
|
||||
|
||||
#define XT_PCPU_BLOCK_SIZE 4096
|
||||
|
||||
struct compat_delta {
|
||||
unsigned int offset; /* offset in kernel */
|
||||
int delta; /* delta in 32bit user land */
|
||||
|
|
@ -1592,6 +1594,59 @@ void xt_proto_fini(struct net *net, u_int8_t af)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(xt_proto_fini);
|
||||
|
||||
/**
|
||||
* xt_percpu_counter_alloc - allocate x_tables rule counter
|
||||
*
|
||||
* @state: pointer to xt_percpu allocation state
|
||||
* @counter: pointer to counter struct inside the ip(6)/arpt_entry struct
|
||||
*
|
||||
* On SMP, the packet counter [ ip(6)t_entry->counters.pcnt ] will then
|
||||
* contain the address of the real (percpu) counter.
|
||||
*
|
||||
* Rule evaluation needs to use xt_get_this_cpu_counter() helper
|
||||
* to fetch the real percpu counter.
|
||||
*
|
||||
* To speed up allocation and improve data locality, a 4kb block is
|
||||
* allocated.
|
||||
*
|
||||
* xt_percpu_counter_alloc_state contains the base address of the
|
||||
* allocated page and the current sub-offset.
|
||||
*
|
||||
* returns false on error.
|
||||
*/
|
||||
bool xt_percpu_counter_alloc(struct xt_percpu_counter_alloc_state *state,
|
||||
struct xt_counters *counter)
|
||||
{
|
||||
BUILD_BUG_ON(XT_PCPU_BLOCK_SIZE < (sizeof(*counter) * 2));
|
||||
|
||||
if (nr_cpu_ids <= 1)
|
||||
return true;
|
||||
|
||||
if (!state->mem) {
|
||||
state->mem = __alloc_percpu(XT_PCPU_BLOCK_SIZE,
|
||||
XT_PCPU_BLOCK_SIZE);
|
||||
if (!state->mem)
|
||||
return false;
|
||||
}
|
||||
counter->pcnt = (__force unsigned long)(state->mem + state->off);
|
||||
state->off += sizeof(*counter);
|
||||
if (state->off > (XT_PCPU_BLOCK_SIZE - sizeof(*counter))) {
|
||||
state->mem = NULL;
|
||||
state->off = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_percpu_counter_alloc);
|
||||
|
||||
void xt_percpu_counter_free(struct xt_counters *counters)
|
||||
{
|
||||
unsigned long pcnt = counters->pcnt;
|
||||
|
||||
if (nr_cpu_ids > 1 && (pcnt & (XT_PCPU_BLOCK_SIZE - 1)) == 0)
|
||||
free_percpu((void __percpu *)pcnt);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xt_percpu_counter_free);
|
||||
|
||||
static int __net_init xt_net_init(struct net *net)
|
||||
{
|
||||
int i;
|
||||
|
|
|
|||
|
|
@ -147,11 +147,11 @@ static int idletimer_tg_create(struct idletimer_tg_info *info)
|
|||
(unsigned long) info->timer);
|
||||
info->timer->refcnt = 1;
|
||||
|
||||
INIT_WORK(&info->timer->work, idletimer_tg_work);
|
||||
|
||||
mod_timer(&info->timer->timer,
|
||||
msecs_to_jiffies(info->timeout * 1000) + jiffies);
|
||||
|
||||
INIT_WORK(&info->timer->work, idletimer_tg_work);
|
||||
|
||||
return 0;
|
||||
|
||||
out_free_attr:
|
||||
|
|
@ -192,7 +192,10 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par)
|
|||
pr_debug("timeout value is zero\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (info->timeout >= INT_MAX / 1000) {
|
||||
pr_debug("timeout value is too big\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (info->label[0] == '\0' ||
|
||||
strnlen(info->label,
|
||||
MAX_IDLETIMER_LABEL_SIZE) == MAX_IDLETIMER_LABEL_SIZE) {
|
||||
|
|
|
|||
|
|
@ -141,10 +141,11 @@ static int led_tg_check(const struct xt_tgchk_param *par)
|
|||
goto exit_alloc;
|
||||
}
|
||||
|
||||
/* See if we need to set up a timer */
|
||||
if (ledinfo->delay > 0)
|
||||
setup_timer(&ledinternal->timer, led_timeout_callback,
|
||||
(unsigned long)ledinternal);
|
||||
/* Since the letinternal timer can be shared between multiple targets,
|
||||
* always set it up, even if the current target does not need it
|
||||
*/
|
||||
setup_timer(&ledinternal->timer, led_timeout_callback,
|
||||
(unsigned long)ledinternal);
|
||||
|
||||
list_add_tail(&ledinternal->list, &xt_led_triggers);
|
||||
|
||||
|
|
@ -181,8 +182,7 @@ static void led_tg_destroy(const struct xt_tgdtor_param *par)
|
|||
|
||||
list_del(&ledinternal->list);
|
||||
|
||||
if (ledinfo->delay > 0)
|
||||
del_timer_sync(&ledinternal->timer);
|
||||
del_timer_sync(&ledinternal->timer);
|
||||
|
||||
led_trigger_unregister(&ledinternal->netfilter_led_trigger);
|
||||
|
||||
|
|
|
|||
|
|
@ -1369,7 +1369,7 @@ static struct sctp_chunk *_sctp_make_chunk(const struct sctp_association *asoc,
|
|||
struct sock *sk;
|
||||
int chunklen;
|
||||
|
||||
chunklen = sizeof(*chunk_hdr) + paylen;
|
||||
chunklen = WORD_ROUND(sizeof(*chunk_hdr) + paylen);
|
||||
if (chunklen > SCTP_MAX_CHUNK_LEN)
|
||||
goto nodata;
|
||||
|
||||
|
|
|
|||
|
|
@ -270,11 +270,11 @@ cmd_dt_S_dtb= \
|
|||
echo '\#include <asm-generic/vmlinux.lds.h>'; \
|
||||
echo '.section .dtb.init.rodata,"a"'; \
|
||||
echo '.balign STRUCT_ALIGNMENT'; \
|
||||
echo '.global __dtb_$(*F)_begin'; \
|
||||
echo '__dtb_$(*F)_begin:'; \
|
||||
echo '.global __dtb_$(subst -,_,$(*F))_begin'; \
|
||||
echo '__dtb_$(subst -,_,$(*F))_begin:'; \
|
||||
echo '.incbin "$<" '; \
|
||||
echo '__dtb_$(*F)_end:'; \
|
||||
echo '.global __dtb_$(*F)_end'; \
|
||||
echo '__dtb_$(subst -,_,$(*F))_end:'; \
|
||||
echo '.global __dtb_$(subst -,_,$(*F))_end'; \
|
||||
echo '.balign STRUCT_ALIGNMENT'; \
|
||||
) > $@
|
||||
|
||||
|
|
|
|||
|
|
@ -919,7 +919,8 @@ int snd_seq_dispatch_event(struct snd_seq_event_cell *cell, int atomic, int hop)
|
|||
static int snd_seq_client_enqueue_event(struct snd_seq_client *client,
|
||||
struct snd_seq_event *event,
|
||||
struct file *file, int blocking,
|
||||
int atomic, int hop)
|
||||
int atomic, int hop,
|
||||
struct mutex *mutexp)
|
||||
{
|
||||
struct snd_seq_event_cell *cell;
|
||||
int err;
|
||||
|
|
@ -957,7 +958,8 @@ static int snd_seq_client_enqueue_event(struct snd_seq_client *client,
|
|||
return -ENXIO; /* queue is not allocated */
|
||||
|
||||
/* allocate an event cell */
|
||||
err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic, file);
|
||||
err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic,
|
||||
file, mutexp);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
@ -1026,12 +1028,11 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
|
|||
return -ENXIO;
|
||||
|
||||
/* allocate the pool now if the pool is not allocated yet */
|
||||
mutex_lock(&client->ioctl_mutex);
|
||||
if (client->pool->size > 0 && !snd_seq_write_pool_allocated(client)) {
|
||||
mutex_lock(&client->ioctl_mutex);
|
||||
err = snd_seq_pool_init(client->pool);
|
||||
mutex_unlock(&client->ioctl_mutex);
|
||||
if (err < 0)
|
||||
return -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* only process whole events */
|
||||
|
|
@ -1082,7 +1083,7 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
|
|||
/* ok, enqueue it */
|
||||
err = snd_seq_client_enqueue_event(client, &event, file,
|
||||
!(file->f_flags & O_NONBLOCK),
|
||||
0, 0);
|
||||
0, 0, &client->ioctl_mutex);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
|
|
@ -1093,6 +1094,8 @@ static ssize_t snd_seq_write(struct file *file, const char __user *buf,
|
|||
written += len;
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&client->ioctl_mutex);
|
||||
return written ? written : err;
|
||||
}
|
||||
|
||||
|
|
@ -1924,6 +1927,9 @@ static int snd_seq_ioctl_set_client_pool(struct snd_seq_client *client,
|
|||
(! snd_seq_write_pool_allocated(client) ||
|
||||
info.output_pool != client->pool->size)) {
|
||||
if (snd_seq_write_pool_allocated(client)) {
|
||||
/* is the pool in use? */
|
||||
if (atomic_read(&client->pool->counter))
|
||||
return -EBUSY;
|
||||
/* remove all existing cells */
|
||||
snd_seq_pool_mark_closing(client->pool);
|
||||
snd_seq_queue_client_leave_cells(client->number);
|
||||
|
|
@ -2347,7 +2353,8 @@ static int kernel_client_enqueue(int client, struct snd_seq_event *ev,
|
|||
if (! cptr->accept_output)
|
||||
result = -EPERM;
|
||||
else /* send it */
|
||||
result = snd_seq_client_enqueue_event(cptr, ev, file, blocking, atomic, hop);
|
||||
result = snd_seq_client_enqueue_event(cptr, ev, file, blocking,
|
||||
atomic, hop, NULL);
|
||||
|
||||
snd_seq_client_unlock(cptr);
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ int snd_seq_fifo_event_in(struct snd_seq_fifo *f,
|
|||
return -EINVAL;
|
||||
|
||||
snd_use_lock_use(&f->use_lock);
|
||||
err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL); /* always non-blocking */
|
||||
err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL, NULL); /* always non-blocking */
|
||||
if (err < 0) {
|
||||
if ((err == -ENOMEM) || (err == -EAGAIN))
|
||||
atomic_inc(&f->overflow);
|
||||
|
|
|
|||
|
|
@ -221,7 +221,8 @@ void snd_seq_cell_free(struct snd_seq_event_cell * cell)
|
|||
*/
|
||||
static int snd_seq_cell_alloc(struct snd_seq_pool *pool,
|
||||
struct snd_seq_event_cell **cellp,
|
||||
int nonblock, struct file *file)
|
||||
int nonblock, struct file *file,
|
||||
struct mutex *mutexp)
|
||||
{
|
||||
struct snd_seq_event_cell *cell;
|
||||
unsigned long flags;
|
||||
|
|
@ -245,7 +246,11 @@ static int snd_seq_cell_alloc(struct snd_seq_pool *pool,
|
|||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
add_wait_queue(&pool->output_sleep, &wait);
|
||||
spin_unlock_irq(&pool->lock);
|
||||
if (mutexp)
|
||||
mutex_unlock(mutexp);
|
||||
schedule();
|
||||
if (mutexp)
|
||||
mutex_lock(mutexp);
|
||||
spin_lock_irq(&pool->lock);
|
||||
remove_wait_queue(&pool->output_sleep, &wait);
|
||||
/* interrupted? */
|
||||
|
|
@ -288,7 +293,7 @@ static int snd_seq_cell_alloc(struct snd_seq_pool *pool,
|
|||
*/
|
||||
int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
|
||||
struct snd_seq_event_cell **cellp, int nonblock,
|
||||
struct file *file)
|
||||
struct file *file, struct mutex *mutexp)
|
||||
{
|
||||
int ncells, err;
|
||||
unsigned int extlen;
|
||||
|
|
@ -305,7 +310,7 @@ int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
|
|||
if (ncells >= pool->total_elements)
|
||||
return -ENOMEM;
|
||||
|
||||
err = snd_seq_cell_alloc(pool, &cell, nonblock, file);
|
||||
err = snd_seq_cell_alloc(pool, &cell, nonblock, file, mutexp);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
@ -331,7 +336,8 @@ int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
|
|||
int size = sizeof(struct snd_seq_event);
|
||||
if (len < size)
|
||||
size = len;
|
||||
err = snd_seq_cell_alloc(pool, &tmp, nonblock, file);
|
||||
err = snd_seq_cell_alloc(pool, &tmp, nonblock, file,
|
||||
mutexp);
|
||||
if (err < 0)
|
||||
goto __error;
|
||||
if (cell->event.data.ext.ptr == NULL)
|
||||
|
|
|
|||
|
|
@ -66,7 +66,8 @@ struct snd_seq_pool {
|
|||
void snd_seq_cell_free(struct snd_seq_event_cell *cell);
|
||||
|
||||
int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event,
|
||||
struct snd_seq_event_cell **cellp, int nonblock, struct file *file);
|
||||
struct snd_seq_event_cell **cellp, int nonblock,
|
||||
struct file *file, struct mutex *mutexp);
|
||||
|
||||
/* return number of unused (free) cells */
|
||||
static inline int snd_seq_unused_cells(struct snd_seq_pool *pool)
|
||||
|
|
|
|||
|
|
@ -849,6 +849,8 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
|
|||
SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC),
|
||||
SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC),
|
||||
SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK),
|
||||
SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK),
|
||||
SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK),
|
||||
SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
|
||||
SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC),
|
||||
SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
|
||||
|
|
|
|||
|
|
@ -4722,6 +4722,16 @@ static void alc298_fixup_speaker_volume(struct hda_codec *codec,
|
|||
}
|
||||
}
|
||||
|
||||
/* disable DAC3 (0x06) selection on NID 0x17 as it has no volume amp control */
|
||||
static void alc295_fixup_disable_dac3(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
|
||||
hda_nid_t conn[2] = { 0x02, 0x03 };
|
||||
snd_hda_override_conn_list(codec, 0x17, 2, conn);
|
||||
}
|
||||
}
|
||||
|
||||
/* Hook to update amp GPIO4 for automute */
|
||||
static void alc280_hp_gpio4_automute_hook(struct hda_codec *codec,
|
||||
struct hda_jack_callback *jack)
|
||||
|
|
@ -4871,6 +4881,7 @@ enum {
|
|||
ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
|
||||
ALC255_FIXUP_DELL_SPK_NOISE,
|
||||
ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
|
||||
ALC295_FIXUP_DISABLE_DAC3,
|
||||
ALC280_FIXUP_HP_HEADSET_MIC,
|
||||
ALC221_FIXUP_HP_FRONT_MIC,
|
||||
ALC292_FIXUP_TPT460,
|
||||
|
|
@ -5560,6 +5571,10 @@ static const struct hda_fixup alc269_fixups[] = {
|
|||
.chained = true,
|
||||
.chain_id = ALC298_FIXUP_DELL_AIO_MIC_NO_PRESENCE,
|
||||
},
|
||||
[ALC295_FIXUP_DISABLE_DAC3] = {
|
||||
.type = HDA_FIXUP_FUNC,
|
||||
.v.func = alc295_fixup_disable_dac3,
|
||||
},
|
||||
[ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
|
||||
.type = HDA_FIXUP_PINS,
|
||||
.v.pins = (const struct hda_pintbl[]) {
|
||||
|
|
@ -5617,6 +5632,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
|||
SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
|
||||
SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
|
||||
SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
|
||||
SND_PCI_QUIRK(0x1028, 0x07b0, "Dell Precision 7520", ALC295_FIXUP_DISABLE_DAC3),
|
||||
SND_PCI_QUIRK(0x1028, 0x0798, "Dell Inspiron 17 7000 Gaming", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
|
||||
SND_PCI_QUIRK(0x1028, 0x082a, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
|
||||
SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user