Merge branch 'linus' into x86/urgent, to pick up dependent patches
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
@@ -88,7 +88,6 @@ Antonio Quartulli <antonio@mandelbit.com> <antonio@open-mesh.com>
|
||||
Antonio Quartulli <antonio@mandelbit.com> <antonio.quartulli@open-mesh.com>
|
||||
Antonio Quartulli <antonio@mandelbit.com> <ordex@autistici.org>
|
||||
Antonio Quartulli <antonio@mandelbit.com> <ordex@ritirata.org>
|
||||
Antonio Quartulli <antonio@mandelbit.com> <antonio@openvpn.net>
|
||||
Antonio Quartulli <antonio@mandelbit.com> <a@unstable.cc>
|
||||
Anup Patel <anup@brainfault.org> <anup.patel@wdc.com>
|
||||
Archit Taneja <archit@ti.com>
|
||||
|
||||
@@ -212,6 +212,17 @@ pid>/``).
|
||||
This value defaults to 0.
|
||||
|
||||
|
||||
core_sort_vma
|
||||
=============
|
||||
|
||||
The default coredump writes VMAs in address order. By setting
|
||||
``core_sort_vma`` to 1, VMAs will be written from smallest size
|
||||
to largest size. This is known to break at least elfutils, but
|
||||
can be handy when dealing with very large (and truncated)
|
||||
coredumps where the more useful debugging details are included
|
||||
in the smaller VMAs.
|
||||
|
||||
|
||||
core_uses_pid
|
||||
=============
|
||||
|
||||
|
||||
@@ -63,8 +63,8 @@ what id ``k11000`` corresponds to in the second or third idmapping. The
|
||||
straightforward algorithm to use is to apply the inverse of the first idmapping,
|
||||
mapping ``k11000`` up to ``u1000``. Afterwards, we can map ``u1000`` down using
|
||||
either the second idmapping mapping or third idmapping mapping. The second
|
||||
idmapping would map ``u1000`` down to ``21000``. The third idmapping would map
|
||||
``u1000`` down to ``u31000``.
|
||||
idmapping would map ``u1000`` down to ``k21000``. The third idmapping would map
|
||||
``u1000`` down to ``k31000``.
|
||||
|
||||
If we were given the same task for the following three idmappings::
|
||||
|
||||
|
||||
@@ -102,6 +102,9 @@ The system wide settings are configured under the /proc virtual file system:
|
||||
* sched_rt_period_us takes values from 1 to INT_MAX.
|
||||
* sched_rt_runtime_us takes values from -1 to sched_rt_period_us.
|
||||
* A run time of -1 specifies runtime == period, ie. no limit.
|
||||
* sched_rt_runtime_us/sched_rt_period_us > 0.05 inorder to preserve
|
||||
bandwidth for fair dl_server. For accurate value check average of
|
||||
runtime/period in /sys/kernel/debug/sched/fair_server/cpuX/
|
||||
|
||||
|
||||
2.2 Default behaviour
|
||||
|
||||
@@ -5775,6 +5775,7 @@ X: drivers/clk/clkdev.c
|
||||
|
||||
COMMON INTERNET FILE SYSTEM CLIENT (CIFS and SMB3)
|
||||
M: Steve French <sfrench@samba.org>
|
||||
M: Steve French <smfrench@gmail.com>
|
||||
R: Paulo Alcantara <pc@manguebit.com> (DFS, global name space)
|
||||
R: Ronnie Sahlberg <ronniesahlberg@gmail.com> (directory leases, sparse files)
|
||||
R: Shyam Prasad N <sprasad@microsoft.com> (multichannel)
|
||||
@@ -12655,7 +12656,9 @@ F: tools/testing/selftests/
|
||||
|
||||
KERNEL SMB3 SERVER (KSMBD)
|
||||
M: Namjae Jeon <linkinjeon@kernel.org>
|
||||
M: Namjae Jeon <linkinjeon@samba.org>
|
||||
M: Steve French <sfrench@samba.org>
|
||||
M: Steve French <smfrench@gmail.com>
|
||||
R: Sergey Senozhatsky <senozhatsky@chromium.org>
|
||||
R: Tom Talpey <tom@talpey.com>
|
||||
L: linux-cifs@vger.kernel.org
|
||||
|
||||
@@ -1341,6 +1341,7 @@ config X86_REBOOTFIXUPS
|
||||
config MICROCODE
|
||||
def_bool y
|
||||
depends on CPU_SUP_AMD || CPU_SUP_INTEL
|
||||
select CRYPTO_LIB_SHA256 if CPU_SUP_AMD
|
||||
|
||||
config MICROCODE_INITRD32
|
||||
def_bool y
|
||||
|
||||
@@ -23,14 +23,18 @@
|
||||
|
||||
#include <linux/earlycpio.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/bsearch.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/initrd.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <crypto/sha2.h>
|
||||
|
||||
#include <asm/microcode.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/cmdline.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/msr.h>
|
||||
@@ -145,6 +149,107 @@ ucode_path[] __maybe_unused = "kernel/x86/microcode/AuthenticAMD.bin";
|
||||
*/
|
||||
static u32 bsp_cpuid_1_eax __ro_after_init;
|
||||
|
||||
static bool sha_check = true;
|
||||
|
||||
struct patch_digest {
|
||||
u32 patch_id;
|
||||
u8 sha256[SHA256_DIGEST_SIZE];
|
||||
};
|
||||
|
||||
#include "amd_shas.c"
|
||||
|
||||
static int cmp_id(const void *key, const void *elem)
|
||||
{
|
||||
struct patch_digest *pd = (struct patch_digest *)elem;
|
||||
u32 patch_id = *(u32 *)key;
|
||||
|
||||
if (patch_id == pd->patch_id)
|
||||
return 0;
|
||||
else if (patch_id < pd->patch_id)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool need_sha_check(u32 cur_rev)
|
||||
{
|
||||
switch (cur_rev >> 8) {
|
||||
case 0x80012: return cur_rev <= 0x800126f; break;
|
||||
case 0x83010: return cur_rev <= 0x830107c; break;
|
||||
case 0x86001: return cur_rev <= 0x860010e; break;
|
||||
case 0x86081: return cur_rev <= 0x8608108; break;
|
||||
case 0x87010: return cur_rev <= 0x8701034; break;
|
||||
case 0x8a000: return cur_rev <= 0x8a0000a; break;
|
||||
case 0xa0011: return cur_rev <= 0xa0011da; break;
|
||||
case 0xa0012: return cur_rev <= 0xa001243; break;
|
||||
case 0xa1011: return cur_rev <= 0xa101153; break;
|
||||
case 0xa1012: return cur_rev <= 0xa10124e; break;
|
||||
case 0xa1081: return cur_rev <= 0xa108109; break;
|
||||
case 0xa2010: return cur_rev <= 0xa20102f; break;
|
||||
case 0xa2012: return cur_rev <= 0xa201212; break;
|
||||
case 0xa6012: return cur_rev <= 0xa60120a; break;
|
||||
case 0xa7041: return cur_rev <= 0xa704109; break;
|
||||
case 0xa7052: return cur_rev <= 0xa705208; break;
|
||||
case 0xa7080: return cur_rev <= 0xa708009; break;
|
||||
case 0xa70c0: return cur_rev <= 0xa70C009; break;
|
||||
case 0xaa002: return cur_rev <= 0xaa00218; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
pr_info("You should not be seeing this. Please send the following couple of lines to x86-<at>-kernel.org\n");
|
||||
pr_info("CPUID(1).EAX: 0x%x, current revision: 0x%x\n", bsp_cpuid_1_eax, cur_rev);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool verify_sha256_digest(u32 patch_id, u32 cur_rev, const u8 *data, unsigned int len)
|
||||
{
|
||||
struct patch_digest *pd = NULL;
|
||||
u8 digest[SHA256_DIGEST_SIZE];
|
||||
struct sha256_state s;
|
||||
int i;
|
||||
|
||||
if (x86_family(bsp_cpuid_1_eax) < 0x17 ||
|
||||
x86_family(bsp_cpuid_1_eax) > 0x19)
|
||||
return true;
|
||||
|
||||
if (!need_sha_check(cur_rev))
|
||||
return true;
|
||||
|
||||
if (!sha_check)
|
||||
return true;
|
||||
|
||||
pd = bsearch(&patch_id, phashes, ARRAY_SIZE(phashes), sizeof(struct patch_digest), cmp_id);
|
||||
if (!pd) {
|
||||
pr_err("No sha256 digest for patch ID: 0x%x found\n", patch_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
sha256_init(&s);
|
||||
sha256_update(&s, data, len);
|
||||
sha256_final(&s, digest);
|
||||
|
||||
if (memcmp(digest, pd->sha256, sizeof(digest))) {
|
||||
pr_err("Patch 0x%x SHA256 digest mismatch!\n", patch_id);
|
||||
|
||||
for (i = 0; i < SHA256_DIGEST_SIZE; i++)
|
||||
pr_cont("0x%x ", digest[i]);
|
||||
pr_info("\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static u32 get_patch_level(void)
|
||||
{
|
||||
u32 rev, dummy __always_unused;
|
||||
|
||||
native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
|
||||
|
||||
return rev;
|
||||
}
|
||||
|
||||
static union cpuid_1_eax ucode_rev_to_cpuid(unsigned int val)
|
||||
{
|
||||
union zen_patch_rev p;
|
||||
@@ -246,8 +351,7 @@ static bool verify_equivalence_table(const u8 *buf, size_t buf_size)
|
||||
* On success, @sh_psize returns the patch size according to the section header,
|
||||
* to the caller.
|
||||
*/
|
||||
static bool
|
||||
__verify_patch_section(const u8 *buf, size_t buf_size, u32 *sh_psize)
|
||||
static bool __verify_patch_section(const u8 *buf, size_t buf_size, u32 *sh_psize)
|
||||
{
|
||||
u32 p_type, p_size;
|
||||
const u32 *hdr;
|
||||
@@ -484,10 +588,13 @@ static void scan_containers(u8 *ucode, size_t size, struct cont_desc *desc)
|
||||
}
|
||||
}
|
||||
|
||||
static bool __apply_microcode_amd(struct microcode_amd *mc, unsigned int psize)
|
||||
static bool __apply_microcode_amd(struct microcode_amd *mc, u32 *cur_rev,
|
||||
unsigned int psize)
|
||||
{
|
||||
unsigned long p_addr = (unsigned long)&mc->hdr.data_code;
|
||||
u32 rev, dummy;
|
||||
|
||||
if (!verify_sha256_digest(mc->hdr.patch_id, *cur_rev, (const u8 *)p_addr, psize))
|
||||
return -1;
|
||||
|
||||
native_wrmsrl(MSR_AMD64_PATCH_LOADER, p_addr);
|
||||
|
||||
@@ -505,47 +612,13 @@ static bool __apply_microcode_amd(struct microcode_amd *mc, unsigned int psize)
|
||||
}
|
||||
|
||||
/* verify patch application was successful */
|
||||
native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
|
||||
|
||||
if (rev != mc->hdr.patch_id)
|
||||
*cur_rev = get_patch_level();
|
||||
if (*cur_rev != mc->hdr.patch_id)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Early load occurs before we can vmalloc(). So we look for the microcode
|
||||
* patch container file in initrd, traverse equivalent cpu table, look for a
|
||||
* matching microcode patch, and update, all in initrd memory in place.
|
||||
* When vmalloc() is available for use later -- on 64-bit during first AP load,
|
||||
* and on 32-bit during save_microcode_in_initrd_amd() -- we can call
|
||||
* load_microcode_amd() to save equivalent cpu table and microcode patches in
|
||||
* kernel heap memory.
|
||||
*
|
||||
* Returns true if container found (sets @desc), false otherwise.
|
||||
*/
|
||||
static bool early_apply_microcode(u32 old_rev, void *ucode, size_t size)
|
||||
{
|
||||
struct cont_desc desc = { 0 };
|
||||
struct microcode_amd *mc;
|
||||
|
||||
scan_containers(ucode, size, &desc);
|
||||
|
||||
mc = desc.mc;
|
||||
if (!mc)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Allow application of the same revision to pick up SMT-specific
|
||||
* changes even if the revision of the other SMT thread is already
|
||||
* up-to-date.
|
||||
*/
|
||||
if (old_rev > mc->hdr.patch_id)
|
||||
return false;
|
||||
|
||||
return __apply_microcode_amd(mc, desc.psize);
|
||||
}
|
||||
|
||||
static bool get_builtin_microcode(struct cpio_data *cp)
|
||||
{
|
||||
char fw_name[36] = "amd-ucode/microcode_amd.bin";
|
||||
@@ -583,14 +656,35 @@ static bool __init find_blobs_in_containers(struct cpio_data *ret)
|
||||
return found;
|
||||
}
|
||||
|
||||
/*
|
||||
* Early load occurs before we can vmalloc(). So we look for the microcode
|
||||
* patch container file in initrd, traverse equivalent cpu table, look for a
|
||||
* matching microcode patch, and update, all in initrd memory in place.
|
||||
* When vmalloc() is available for use later -- on 64-bit during first AP load,
|
||||
* and on 32-bit during save_microcode_in_initrd() -- we can call
|
||||
* load_microcode_amd() to save equivalent cpu table and microcode patches in
|
||||
* kernel heap memory.
|
||||
*/
|
||||
void __init load_ucode_amd_bsp(struct early_load_data *ed, unsigned int cpuid_1_eax)
|
||||
{
|
||||
struct cont_desc desc = { };
|
||||
struct microcode_amd *mc;
|
||||
struct cpio_data cp = { };
|
||||
u32 dummy;
|
||||
char buf[4];
|
||||
u32 rev;
|
||||
|
||||
if (cmdline_find_option(boot_command_line, "microcode.amd_sha_check", buf, 4)) {
|
||||
if (!strncmp(buf, "off", 3)) {
|
||||
sha_check = false;
|
||||
pr_warn_once("It is a very very bad idea to disable the blobs SHA check!\n");
|
||||
add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
|
||||
}
|
||||
}
|
||||
|
||||
bsp_cpuid_1_eax = cpuid_1_eax;
|
||||
|
||||
native_rdmsr(MSR_AMD64_PATCH_LEVEL, ed->old_rev, dummy);
|
||||
rev = get_patch_level();
|
||||
ed->old_rev = rev;
|
||||
|
||||
/* Needed in load_microcode_amd() */
|
||||
ucode_cpu_info[0].cpu_sig.sig = cpuid_1_eax;
|
||||
@@ -598,37 +692,23 @@ void __init load_ucode_amd_bsp(struct early_load_data *ed, unsigned int cpuid_1_
|
||||
if (!find_blobs_in_containers(&cp))
|
||||
return;
|
||||
|
||||
if (early_apply_microcode(ed->old_rev, cp.data, cp.size))
|
||||
native_rdmsr(MSR_AMD64_PATCH_LEVEL, ed->new_rev, dummy);
|
||||
}
|
||||
|
||||
static enum ucode_state _load_microcode_amd(u8 family, const u8 *data, size_t size);
|
||||
|
||||
static int __init save_microcode_in_initrd(void)
|
||||
{
|
||||
unsigned int cpuid_1_eax = native_cpuid_eax(1);
|
||||
struct cpuinfo_x86 *c = &boot_cpu_data;
|
||||
struct cont_desc desc = { 0 };
|
||||
enum ucode_state ret;
|
||||
struct cpio_data cp;
|
||||
|
||||
if (dis_ucode_ldr || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10)
|
||||
return 0;
|
||||
|
||||
if (!find_blobs_in_containers(&cp))
|
||||
return -EINVAL;
|
||||
|
||||
scan_containers(cp.data, cp.size, &desc);
|
||||
if (!desc.mc)
|
||||
return -EINVAL;
|
||||
|
||||
ret = _load_microcode_amd(x86_family(cpuid_1_eax), desc.data, desc.size);
|
||||
if (ret > UCODE_UPDATED)
|
||||
return -EINVAL;
|
||||
mc = desc.mc;
|
||||
if (!mc)
|
||||
return;
|
||||
|
||||
return 0;
|
||||
/*
|
||||
* Allow application of the same revision to pick up SMT-specific
|
||||
* changes even if the revision of the other SMT thread is already
|
||||
* up-to-date.
|
||||
*/
|
||||
if (ed->old_rev > mc->hdr.patch_id)
|
||||
return;
|
||||
|
||||
if (__apply_microcode_amd(mc, &rev, desc.psize))
|
||||
ed->new_rev = rev;
|
||||
}
|
||||
early_initcall(save_microcode_in_initrd);
|
||||
|
||||
static inline bool patch_cpus_equivalent(struct ucode_patch *p,
|
||||
struct ucode_patch *n,
|
||||
@@ -729,14 +809,9 @@ static void free_cache(void)
|
||||
static struct ucode_patch *find_patch(unsigned int cpu)
|
||||
{
|
||||
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
|
||||
u32 rev, dummy __always_unused;
|
||||
u16 equiv_id = 0;
|
||||
|
||||
/* fetch rev if not populated yet: */
|
||||
if (!uci->cpu_sig.rev) {
|
||||
rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
|
||||
uci->cpu_sig.rev = rev;
|
||||
}
|
||||
uci->cpu_sig.rev = get_patch_level();
|
||||
|
||||
if (x86_family(bsp_cpuid_1_eax) < 0x17) {
|
||||
equiv_id = find_equiv_id(&equiv_table, uci->cpu_sig.sig);
|
||||
@@ -759,22 +834,20 @@ void reload_ucode_amd(unsigned int cpu)
|
||||
|
||||
mc = p->data;
|
||||
|
||||
rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
|
||||
|
||||
rev = get_patch_level();
|
||||
if (rev < mc->hdr.patch_id) {
|
||||
if (__apply_microcode_amd(mc, p->size))
|
||||
pr_info_once("reload revision: 0x%08x\n", mc->hdr.patch_id);
|
||||
if (__apply_microcode_amd(mc, &rev, p->size))
|
||||
pr_info_once("reload revision: 0x%08x\n", rev);
|
||||
}
|
||||
}
|
||||
|
||||
static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
|
||||
struct ucode_patch *p;
|
||||
|
||||
csig->sig = cpuid_eax(0x00000001);
|
||||
csig->rev = c->microcode;
|
||||
csig->rev = get_patch_level();
|
||||
|
||||
/*
|
||||
* a patch could have been loaded early, set uci->mc so that
|
||||
@@ -815,7 +888,7 @@ static enum ucode_state apply_microcode_amd(int cpu)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!__apply_microcode_amd(mc_amd, p->size)) {
|
||||
if (!__apply_microcode_amd(mc_amd, &rev, p->size)) {
|
||||
pr_err("CPU%d: update failed for patch_level=0x%08x\n",
|
||||
cpu, mc_amd->hdr.patch_id);
|
||||
return UCODE_ERROR;
|
||||
@@ -937,8 +1010,7 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover,
|
||||
}
|
||||
|
||||
/* Scan the blob in @data and add microcode patches to the cache. */
|
||||
static enum ucode_state __load_microcode_amd(u8 family, const u8 *data,
|
||||
size_t size)
|
||||
static enum ucode_state __load_microcode_amd(u8 family, const u8 *data, size_t size)
|
||||
{
|
||||
u8 *fw = (u8 *)data;
|
||||
size_t offset;
|
||||
@@ -1013,6 +1085,32 @@ static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t siz
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init save_microcode_in_initrd(void)
|
||||
{
|
||||
unsigned int cpuid_1_eax = native_cpuid_eax(1);
|
||||
struct cpuinfo_x86 *c = &boot_cpu_data;
|
||||
struct cont_desc desc = { 0 };
|
||||
enum ucode_state ret;
|
||||
struct cpio_data cp;
|
||||
|
||||
if (dis_ucode_ldr || c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10)
|
||||
return 0;
|
||||
|
||||
if (!find_blobs_in_containers(&cp))
|
||||
return -EINVAL;
|
||||
|
||||
scan_containers(cp.data, cp.size, &desc);
|
||||
if (!desc.mc)
|
||||
return -EINVAL;
|
||||
|
||||
ret = _load_microcode_amd(x86_family(cpuid_1_eax), desc.data, desc.size);
|
||||
if (ret > UCODE_UPDATED)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
early_initcall(save_microcode_in_initrd);
|
||||
|
||||
/*
|
||||
* AMD microcode firmware naming convention, up to family 15h they are in
|
||||
* the legacy file:
|
||||
|
||||
@@ -0,0 +1,444 @@
|
||||
/* Keep 'em sorted. */
|
||||
static const struct patch_digest phashes[] = {
|
||||
{ 0x8001227, {
|
||||
0x99,0xc0,0x9b,0x2b,0xcc,0x9f,0x52,0x1b,
|
||||
0x1a,0x5f,0x1d,0x83,0xa1,0x6c,0xc4,0x46,
|
||||
0xe2,0x6c,0xda,0x73,0xfb,0x2d,0x23,0xa8,
|
||||
0x77,0xdc,0x15,0x31,0x33,0x4a,0x46,0x18,
|
||||
}
|
||||
},
|
||||
{ 0x8001250, {
|
||||
0xc0,0x0b,0x6b,0x19,0xfd,0x5c,0x39,0x60,
|
||||
0xd5,0xc3,0x57,0x46,0x54,0xe4,0xd1,0xaa,
|
||||
0xa8,0xf7,0x1f,0xa8,0x6a,0x60,0x3e,0xe3,
|
||||
0x27,0x39,0x8e,0x53,0x30,0xf8,0x49,0x19,
|
||||
}
|
||||
},
|
||||
{ 0x800126e, {
|
||||
0xf3,0x8b,0x2b,0xb6,0x34,0xe3,0xc8,0x2c,
|
||||
0xef,0xec,0x63,0x6d,0xc8,0x76,0x77,0xb3,
|
||||
0x25,0x5a,0xb7,0x52,0x8c,0x83,0x26,0xe6,
|
||||
0x4c,0xbe,0xbf,0xe9,0x7d,0x22,0x6a,0x43,
|
||||
}
|
||||
},
|
||||
{ 0x800126f, {
|
||||
0x2b,0x5a,0xf2,0x9c,0xdd,0xd2,0x7f,0xec,
|
||||
0xec,0x96,0x09,0x57,0xb0,0x96,0x29,0x8b,
|
||||
0x2e,0x26,0x91,0xf0,0x49,0x33,0x42,0x18,
|
||||
0xdd,0x4b,0x65,0x5a,0xd4,0x15,0x3d,0x33,
|
||||
}
|
||||
},
|
||||
{ 0x800820d, {
|
||||
0x68,0x98,0x83,0xcd,0x22,0x0d,0xdd,0x59,
|
||||
0x73,0x2c,0x5b,0x37,0x1f,0x84,0x0e,0x67,
|
||||
0x96,0x43,0x83,0x0c,0x46,0x44,0xab,0x7c,
|
||||
0x7b,0x65,0x9e,0x57,0xb5,0x90,0x4b,0x0e,
|
||||
}
|
||||
},
|
||||
{ 0x8301025, {
|
||||
0xe4,0x7d,0xdb,0x1e,0x14,0xb4,0x5e,0x36,
|
||||
0x8f,0x3e,0x48,0x88,0x3c,0x6d,0x76,0xa1,
|
||||
0x59,0xc6,0xc0,0x72,0x42,0xdf,0x6c,0x30,
|
||||
0x6f,0x0b,0x28,0x16,0x61,0xfc,0x79,0x77,
|
||||
}
|
||||
},
|
||||
{ 0x8301055, {
|
||||
0x81,0x7b,0x99,0x1b,0xae,0x2d,0x4f,0x9a,
|
||||
0xef,0x13,0xce,0xb5,0x10,0xaf,0x6a,0xea,
|
||||
0xe5,0xb0,0x64,0x98,0x10,0x68,0x34,0x3b,
|
||||
0x9d,0x7a,0xd6,0x22,0x77,0x5f,0xb3,0x5b,
|
||||
}
|
||||
},
|
||||
{ 0x8301072, {
|
||||
0xcf,0x76,0xa7,0x1a,0x49,0xdf,0x2a,0x5e,
|
||||
0x9e,0x40,0x70,0xe5,0xdd,0x8a,0xa8,0x28,
|
||||
0x20,0xdc,0x91,0xd8,0x2c,0xa6,0xa0,0xb1,
|
||||
0x2d,0x22,0x26,0x94,0x4b,0x40,0x85,0x30,
|
||||
}
|
||||
},
|
||||
{ 0x830107a, {
|
||||
0x2a,0x65,0x8c,0x1a,0x5e,0x07,0x21,0x72,
|
||||
0xdf,0x90,0xa6,0x51,0x37,0xd3,0x4b,0x34,
|
||||
0xc4,0xda,0x03,0xe1,0x8a,0x6c,0xfb,0x20,
|
||||
0x04,0xb2,0x81,0x05,0xd4,0x87,0xf4,0x0a,
|
||||
}
|
||||
},
|
||||
{ 0x830107b, {
|
||||
0xb3,0x43,0x13,0x63,0x56,0xc1,0x39,0xad,
|
||||
0x10,0xa6,0x2b,0xcc,0x02,0xe6,0x76,0x2a,
|
||||
0x1e,0x39,0x58,0x3e,0x23,0x6e,0xa4,0x04,
|
||||
0x95,0xea,0xf9,0x6d,0xc2,0x8a,0x13,0x19,
|
||||
}
|
||||
},
|
||||
{ 0x830107c, {
|
||||
0x21,0x64,0xde,0xfb,0x9f,0x68,0x96,0x47,
|
||||
0x70,0x5c,0xe2,0x8f,0x18,0x52,0x6a,0xac,
|
||||
0xa4,0xd2,0x2e,0xe0,0xde,0x68,0x66,0xc3,
|
||||
0xeb,0x1e,0xd3,0x3f,0xbc,0x51,0x1d,0x38,
|
||||
}
|
||||
},
|
||||
{ 0x860010d, {
|
||||
0x86,0xb6,0x15,0x83,0xbc,0x3b,0x9c,0xe0,
|
||||
0xb3,0xef,0x1d,0x99,0x84,0x35,0x15,0xf7,
|
||||
0x7c,0x2a,0xc6,0x42,0xdb,0x73,0x07,0x5c,
|
||||
0x7d,0xc3,0x02,0xb5,0x43,0x06,0x5e,0xf8,
|
||||
}
|
||||
},
|
||||
{ 0x8608108, {
|
||||
0x14,0xfe,0x57,0x86,0x49,0xc8,0x68,0xe2,
|
||||
0x11,0xa3,0xcb,0x6e,0xff,0x6e,0xd5,0x38,
|
||||
0xfe,0x89,0x1a,0xe0,0x67,0xbf,0xc4,0xcc,
|
||||
0x1b,0x9f,0x84,0x77,0x2b,0x9f,0xaa,0xbd,
|
||||
}
|
||||
},
|
||||
{ 0x8701034, {
|
||||
0xc3,0x14,0x09,0xa8,0x9c,0x3f,0x8d,0x83,
|
||||
0x9b,0x4c,0xa5,0xb7,0x64,0x8b,0x91,0x5d,
|
||||
0x85,0x6a,0x39,0x26,0x1e,0x14,0x41,0xa8,
|
||||
0x75,0xea,0xa6,0xf9,0xc9,0xd1,0xea,0x2b,
|
||||
}
|
||||
},
|
||||
{ 0x8a00008, {
|
||||
0xd7,0x2a,0x93,0xdc,0x05,0x2f,0xa5,0x6e,
|
||||
0x0c,0x61,0x2c,0x07,0x9f,0x38,0xe9,0x8e,
|
||||
0xef,0x7d,0x2a,0x05,0x4d,0x56,0xaf,0x72,
|
||||
0xe7,0x56,0x47,0x6e,0x60,0x27,0xd5,0x8c,
|
||||
}
|
||||
},
|
||||
{ 0x8a0000a, {
|
||||
0x73,0x31,0x26,0x22,0xd4,0xf9,0xee,0x3c,
|
||||
0x07,0x06,0xe7,0xb9,0xad,0xd8,0x72,0x44,
|
||||
0x33,0x31,0xaa,0x7d,0xc3,0x67,0x0e,0xdb,
|
||||
0x47,0xb5,0xaa,0xbc,0xf5,0xbb,0xd9,0x20,
|
||||
}
|
||||
},
|
||||
{ 0xa00104c, {
|
||||
0x3c,0x8a,0xfe,0x04,0x62,0xd8,0x6d,0xbe,
|
||||
0xa7,0x14,0x28,0x64,0x75,0xc0,0xa3,0x76,
|
||||
0xb7,0x92,0x0b,0x97,0x0a,0x8e,0x9c,0x5b,
|
||||
0x1b,0xc8,0x9d,0x3a,0x1e,0x81,0x3d,0x3b,
|
||||
}
|
||||
},
|
||||
{ 0xa00104e, {
|
||||
0xc4,0x35,0x82,0x67,0xd2,0x86,0xe5,0xb2,
|
||||
0xfd,0x69,0x12,0x38,0xc8,0x77,0xba,0xe0,
|
||||
0x70,0xf9,0x77,0x89,0x10,0xa6,0x74,0x4e,
|
||||
0x56,0x58,0x13,0xf5,0x84,0x70,0x28,0x0b,
|
||||
}
|
||||
},
|
||||
{ 0xa001053, {
|
||||
0x92,0x0e,0xf4,0x69,0x10,0x3b,0xf9,0x9d,
|
||||
0x31,0x1b,0xa6,0x99,0x08,0x7d,0xd7,0x25,
|
||||
0x7e,0x1e,0x89,0xba,0x35,0x8d,0xac,0xcb,
|
||||
0x3a,0xb4,0xdf,0x58,0x12,0xcf,0xc0,0xc3,
|
||||
}
|
||||
},
|
||||
{ 0xa001058, {
|
||||
0x33,0x7d,0xa9,0xb5,0x4e,0x62,0x13,0x36,
|
||||
0xef,0x66,0xc9,0xbd,0x0a,0xa6,0x3b,0x19,
|
||||
0xcb,0xf5,0xc2,0xc3,0x55,0x47,0x20,0xec,
|
||||
0x1f,0x7b,0xa1,0x44,0x0e,0x8e,0xa4,0xb2,
|
||||
}
|
||||
},
|
||||
{ 0xa001075, {
|
||||
0x39,0x02,0x82,0xd0,0x7c,0x26,0x43,0xe9,
|
||||
0x26,0xa3,0xd9,0x96,0xf7,0x30,0x13,0x0a,
|
||||
0x8a,0x0e,0xac,0xe7,0x1d,0xdc,0xe2,0x0f,
|
||||
0xcb,0x9e,0x8d,0xbc,0xd2,0xa2,0x44,0xe0,
|
||||
}
|
||||
},
|
||||
{ 0xa001078, {
|
||||
0x2d,0x67,0xc7,0x35,0xca,0xef,0x2f,0x25,
|
||||
0x4c,0x45,0x93,0x3f,0x36,0x01,0x8c,0xce,
|
||||
0xa8,0x5b,0x07,0xd3,0xc1,0x35,0x3c,0x04,
|
||||
0x20,0xa2,0xfc,0xdc,0xe6,0xce,0x26,0x3e,
|
||||
}
|
||||
},
|
||||
{ 0xa001079, {
|
||||
0x43,0xe2,0x05,0x9c,0xfd,0xb7,0x5b,0xeb,
|
||||
0x5b,0xe9,0xeb,0x3b,0x96,0xf4,0xe4,0x93,
|
||||
0x73,0x45,0x3e,0xac,0x8d,0x3b,0xe4,0xdb,
|
||||
0x10,0x31,0xc1,0xe4,0xa2,0xd0,0x5a,0x8a,
|
||||
}
|
||||
},
|
||||
{ 0xa00107a, {
|
||||
0x5f,0x92,0xca,0xff,0xc3,0x59,0x22,0x5f,
|
||||
0x02,0xa0,0x91,0x3b,0x4a,0x45,0x10,0xfd,
|
||||
0x19,0xe1,0x8a,0x6d,0x9a,0x92,0xc1,0x3f,
|
||||
0x75,0x78,0xac,0x78,0x03,0x1d,0xdb,0x18,
|
||||
}
|
||||
},
|
||||
{ 0xa001143, {
|
||||
0x56,0xca,0xf7,0x43,0x8a,0x4c,0x46,0x80,
|
||||
0xec,0xde,0xe5,0x9c,0x50,0x84,0x9a,0x42,
|
||||
0x27,0xe5,0x51,0x84,0x8f,0x19,0xc0,0x8d,
|
||||
0x0c,0x25,0xb4,0xb0,0x8f,0x10,0xf3,0xf8,
|
||||
}
|
||||
},
|
||||
{ 0xa001144, {
|
||||
0x42,0xd5,0x9b,0xa7,0xd6,0x15,0x29,0x41,
|
||||
0x61,0xc4,0x72,0x3f,0xf3,0x06,0x78,0x4b,
|
||||
0x65,0xf3,0x0e,0xfa,0x9c,0x87,0xde,0x25,
|
||||
0xbd,0xb3,0x9a,0xf4,0x75,0x13,0x53,0xdc,
|
||||
}
|
||||
},
|
||||
{ 0xa00115d, {
|
||||
0xd4,0xc4,0x49,0x36,0x89,0x0b,0x47,0xdd,
|
||||
0xfb,0x2f,0x88,0x3b,0x5f,0xf2,0x8e,0x75,
|
||||
0xc6,0x6c,0x37,0x5a,0x90,0x25,0x94,0x3e,
|
||||
0x36,0x9c,0xae,0x02,0x38,0x6c,0xf5,0x05,
|
||||
}
|
||||
},
|
||||
{ 0xa001173, {
|
||||
0x28,0xbb,0x9b,0xd1,0xa0,0xa0,0x7e,0x3a,
|
||||
0x59,0x20,0xc0,0xa9,0xb2,0x5c,0xc3,0x35,
|
||||
0x53,0x89,0xe1,0x4c,0x93,0x2f,0x1d,0xc3,
|
||||
0xe5,0xf7,0xf3,0xc8,0x9b,0x61,0xaa,0x9e,
|
||||
}
|
||||
},
|
||||
{ 0xa0011a8, {
|
||||
0x97,0xc6,0x16,0x65,0x99,0xa4,0x85,0x3b,
|
||||
0xf6,0xce,0xaa,0x49,0x4a,0x3a,0xc5,0xb6,
|
||||
0x78,0x25,0xbc,0x53,0xaf,0x5d,0xcf,0xf4,
|
||||
0x23,0x12,0xbb,0xb1,0xbc,0x8a,0x02,0x2e,
|
||||
}
|
||||
},
|
||||
{ 0xa0011ce, {
|
||||
0xcf,0x1c,0x90,0xa3,0x85,0x0a,0xbf,0x71,
|
||||
0x94,0x0e,0x80,0x86,0x85,0x4f,0xd7,0x86,
|
||||
0xae,0x38,0x23,0x28,0x2b,0x35,0x9b,0x4e,
|
||||
0xfe,0xb8,0xcd,0x3d,0x3d,0x39,0xc9,0x6a,
|
||||
}
|
||||
},
|
||||
{ 0xa0011d1, {
|
||||
0xdf,0x0e,0xca,0xde,0xf6,0xce,0x5c,0x1e,
|
||||
0x4c,0xec,0xd7,0x71,0x83,0xcc,0xa8,0x09,
|
||||
0xc7,0xc5,0xfe,0xb2,0xf7,0x05,0xd2,0xc5,
|
||||
0x12,0xdd,0xe4,0xf3,0x92,0x1c,0x3d,0xb8,
|
||||
}
|
||||
},
|
||||
{ 0xa0011d3, {
|
||||
0x91,0xe6,0x10,0xd7,0x57,0xb0,0x95,0x0b,
|
||||
0x9a,0x24,0xee,0xf7,0xcf,0x56,0xc1,0xa6,
|
||||
0x4a,0x52,0x7d,0x5f,0x9f,0xdf,0xf6,0x00,
|
||||
0x65,0xf7,0xea,0xe8,0x2a,0x88,0xe2,0x26,
|
||||
}
|
||||
},
|
||||
{ 0xa0011d5, {
|
||||
0xed,0x69,0x89,0xf4,0xeb,0x64,0xc2,0x13,
|
||||
0xe0,0x51,0x1f,0x03,0x26,0x52,0x7d,0xb7,
|
||||
0x93,0x5d,0x65,0xca,0xb8,0x12,0x1d,0x62,
|
||||
0x0d,0x5b,0x65,0x34,0x69,0xb2,0x62,0x21,
|
||||
}
|
||||
},
|
||||
{ 0xa001223, {
|
||||
0xfb,0x32,0x5f,0xc6,0x83,0x4f,0x8c,0xb8,
|
||||
0xa4,0x05,0xf9,0x71,0x53,0x01,0x16,0xc4,
|
||||
0x83,0x75,0x94,0xdd,0xeb,0x7e,0xb7,0x15,
|
||||
0x8e,0x3b,0x50,0x29,0x8a,0x9c,0xcc,0x45,
|
||||
}
|
||||
},
|
||||
{ 0xa001224, {
|
||||
0x0e,0x0c,0xdf,0xb4,0x89,0xee,0x35,0x25,
|
||||
0xdd,0x9e,0xdb,0xc0,0x69,0x83,0x0a,0xad,
|
||||
0x26,0xa9,0xaa,0x9d,0xfc,0x3c,0xea,0xf9,
|
||||
0x6c,0xdc,0xd5,0x6d,0x8b,0x6e,0x85,0x4a,
|
||||
}
|
||||
},
|
||||
{ 0xa001227, {
|
||||
0xab,0xc6,0x00,0x69,0x4b,0x50,0x87,0xad,
|
||||
0x5f,0x0e,0x8b,0xea,0x57,0x38,0xce,0x1d,
|
||||
0x0f,0x75,0x26,0x02,0xf6,0xd6,0x96,0xe9,
|
||||
0x87,0xb9,0xd6,0x20,0x27,0x7c,0xd2,0xe0,
|
||||
}
|
||||
},
|
||||
{ 0xa001229, {
|
||||
0x7f,0x49,0x49,0x48,0x46,0xa5,0x50,0xa6,
|
||||
0x28,0x89,0x98,0xe2,0x9e,0xb4,0x7f,0x75,
|
||||
0x33,0xa7,0x04,0x02,0xe4,0x82,0xbf,0xb4,
|
||||
0xa5,0x3a,0xba,0x24,0x8d,0x31,0x10,0x1d,
|
||||
}
|
||||
},
|
||||
{ 0xa00122e, {
|
||||
0x56,0x94,0xa9,0x5d,0x06,0x68,0xfe,0xaf,
|
||||
0xdf,0x7a,0xff,0x2d,0xdf,0x74,0x0f,0x15,
|
||||
0x66,0xfb,0x00,0xb5,0x51,0x97,0x9b,0xfa,
|
||||
0xcb,0x79,0x85,0x46,0x25,0xb4,0xd2,0x10,
|
||||
}
|
||||
},
|
||||
{ 0xa001231, {
|
||||
0x0b,0x46,0xa5,0xfc,0x18,0x15,0xa0,0x9e,
|
||||
0xa6,0xdc,0xb7,0xff,0x17,0xf7,0x30,0x64,
|
||||
0xd4,0xda,0x9e,0x1b,0xc3,0xfc,0x02,0x3b,
|
||||
0xe2,0xc6,0x0e,0x41,0x54,0xb5,0x18,0xdd,
|
||||
}
|
||||
},
|
||||
{ 0xa001234, {
|
||||
0x88,0x8d,0xed,0xab,0xb5,0xbd,0x4e,0xf7,
|
||||
0x7f,0xd4,0x0e,0x95,0x34,0x91,0xff,0xcc,
|
||||
0xfb,0x2a,0xcd,0xf7,0xd5,0xdb,0x4c,0x9b,
|
||||
0xd6,0x2e,0x73,0x50,0x8f,0x83,0x79,0x1a,
|
||||
}
|
||||
},
|
||||
{ 0xa001236, {
|
||||
0x3d,0x30,0x00,0xb9,0x71,0xba,0x87,0x78,
|
||||
0xa8,0x43,0x55,0xc4,0x26,0x59,0xcf,0x9d,
|
||||
0x93,0xce,0x64,0x0e,0x8b,0x72,0x11,0x8b,
|
||||
0xa3,0x8f,0x51,0xe9,0xca,0x98,0xaa,0x25,
|
||||
}
|
||||
},
|
||||
{ 0xa001238, {
|
||||
0x72,0xf7,0x4b,0x0c,0x7d,0x58,0x65,0xcc,
|
||||
0x00,0xcc,0x57,0x16,0x68,0x16,0xf8,0x2a,
|
||||
0x1b,0xb3,0x8b,0xe1,0xb6,0x83,0x8c,0x7e,
|
||||
0xc0,0xcd,0x33,0xf2,0x8d,0xf9,0xef,0x59,
|
||||
}
|
||||
},
|
||||
{ 0xa00820c, {
|
||||
0xa8,0x0c,0x81,0xc0,0xa6,0x00,0xe7,0xf3,
|
||||
0x5f,0x65,0xd3,0xb9,0x6f,0xea,0x93,0x63,
|
||||
0xf1,0x8c,0x88,0x45,0xd7,0x82,0x80,0xd1,
|
||||
0xe1,0x3b,0x8d,0xb2,0xf8,0x22,0x03,0xe2,
|
||||
}
|
||||
},
|
||||
{ 0xa10113e, {
|
||||
0x05,0x3c,0x66,0xd7,0xa9,0x5a,0x33,0x10,
|
||||
0x1b,0xf8,0x9c,0x8f,0xed,0xfc,0xa7,0xa0,
|
||||
0x15,0xe3,0x3f,0x4b,0x1d,0x0d,0x0a,0xd5,
|
||||
0xfa,0x90,0xc4,0xed,0x9d,0x90,0xaf,0x53,
|
||||
}
|
||||
},
|
||||
{ 0xa101144, {
|
||||
0xb3,0x0b,0x26,0x9a,0xf8,0x7c,0x02,0x26,
|
||||
0x35,0x84,0x53,0xa4,0xd3,0x2c,0x7c,0x09,
|
||||
0x68,0x7b,0x96,0xb6,0x93,0xef,0xde,0xbc,
|
||||
0xfd,0x4b,0x15,0xd2,0x81,0xd3,0x51,0x47,
|
||||
}
|
||||
},
|
||||
{ 0xa101148, {
|
||||
0x20,0xd5,0x6f,0x40,0x4a,0xf6,0x48,0x90,
|
||||
0xc2,0x93,0x9a,0xc2,0xfd,0xac,0xef,0x4f,
|
||||
0xfa,0xc0,0x3d,0x92,0x3c,0x6d,0x01,0x08,
|
||||
0xf1,0x5e,0xb0,0xde,0xb4,0x98,0xae,0xc4,
|
||||
}
|
||||
},
|
||||
{ 0xa10123e, {
|
||||
0x03,0xb9,0x2c,0x76,0x48,0x93,0xc9,0x18,
|
||||
0xfb,0x56,0xfd,0xf7,0xe2,0x1d,0xca,0x4d,
|
||||
0x1d,0x13,0x53,0x63,0xfe,0x42,0x6f,0xfc,
|
||||
0x19,0x0f,0xf1,0xfc,0xa7,0xdd,0x89,0x1b,
|
||||
}
|
||||
},
|
||||
{ 0xa101244, {
|
||||
0x71,0x56,0xb5,0x9f,0x21,0xbf,0xb3,0x3c,
|
||||
0x8c,0xd7,0x36,0xd0,0x34,0x52,0x1b,0xb1,
|
||||
0x46,0x2f,0x04,0xf0,0x37,0xd8,0x1e,0x72,
|
||||
0x24,0xa2,0x80,0x84,0x83,0x65,0x84,0xc0,
|
||||
}
|
||||
},
|
||||
{ 0xa101248, {
|
||||
0xed,0x3b,0x95,0xa6,0x68,0xa7,0x77,0x3e,
|
||||
0xfc,0x17,0x26,0xe2,0x7b,0xd5,0x56,0x22,
|
||||
0x2c,0x1d,0xef,0xeb,0x56,0xdd,0xba,0x6e,
|
||||
0x1b,0x7d,0x64,0x9d,0x4b,0x53,0x13,0x75,
|
||||
}
|
||||
},
|
||||
{ 0xa108108, {
|
||||
0xed,0xc2,0xec,0xa1,0x15,0xc6,0x65,0xe9,
|
||||
0xd0,0xef,0x39,0xaa,0x7f,0x55,0x06,0xc6,
|
||||
0xf5,0xd4,0x3f,0x7b,0x14,0xd5,0x60,0x2c,
|
||||
0x28,0x1e,0x9c,0x59,0x69,0x99,0x4d,0x16,
|
||||
}
|
||||
},
|
||||
{ 0xa20102d, {
|
||||
0xf9,0x6e,0xf2,0x32,0xd3,0x0f,0x5f,0x11,
|
||||
0x59,0xa1,0xfe,0xcc,0xcd,0x9b,0x42,0x89,
|
||||
0x8b,0x89,0x2f,0xb5,0xbb,0x82,0xef,0x23,
|
||||
0x8c,0xe9,0x19,0x3e,0xcc,0x3f,0x7b,0xb4,
|
||||
}
|
||||
},
|
||||
{ 0xa201210, {
|
||||
0xe8,0x6d,0x51,0x6a,0x8e,0x72,0xf3,0xfe,
|
||||
0x6e,0x16,0xbc,0x62,0x59,0x40,0x17,0xe9,
|
||||
0x6d,0x3d,0x0e,0x6b,0xa7,0xac,0xe3,0x68,
|
||||
0xf7,0x55,0xf0,0x13,0xbb,0x22,0xf6,0x41,
|
||||
}
|
||||
},
|
||||
{ 0xa404107, {
|
||||
0xbb,0x04,0x4e,0x47,0xdd,0x5e,0x26,0x45,
|
||||
0x1a,0xc9,0x56,0x24,0xa4,0x4c,0x82,0xb0,
|
||||
0x8b,0x0d,0x9f,0xf9,0x3a,0xdf,0xc6,0x81,
|
||||
0x13,0xbc,0xc5,0x25,0xe4,0xc5,0xc3,0x99,
|
||||
}
|
||||
},
|
||||
{ 0xa500011, {
|
||||
0x23,0x3d,0x70,0x7d,0x03,0xc3,0xc4,0xf4,
|
||||
0x2b,0x82,0xc6,0x05,0xda,0x80,0x0a,0xf1,
|
||||
0xd7,0x5b,0x65,0x3a,0x7d,0xab,0xdf,0xa2,
|
||||
0x11,0x5e,0x96,0x7e,0x71,0xe9,0xfc,0x74,
|
||||
}
|
||||
},
|
||||
{ 0xa601209, {
|
||||
0x66,0x48,0xd4,0x09,0x05,0xcb,0x29,0x32,
|
||||
0x66,0xb7,0x9a,0x76,0xcd,0x11,0xf3,0x30,
|
||||
0x15,0x86,0xcc,0x5d,0x97,0x0f,0xc0,0x46,
|
||||
0xe8,0x73,0xe2,0xd6,0xdb,0xd2,0x77,0x1d,
|
||||
}
|
||||
},
|
||||
{ 0xa704107, {
|
||||
0xf3,0xc6,0x58,0x26,0xee,0xac,0x3f,0xd6,
|
||||
0xce,0xa1,0x72,0x47,0x3b,0xba,0x2b,0x93,
|
||||
0x2a,0xad,0x8e,0x6b,0xea,0x9b,0xb7,0xc2,
|
||||
0x64,0x39,0x71,0x8c,0xce,0xe7,0x41,0x39,
|
||||
}
|
||||
},
|
||||
{ 0xa705206, {
|
||||
0x8d,0xc0,0x76,0xbd,0x58,0x9f,0x8f,0xa4,
|
||||
0x12,0x9d,0x21,0xfb,0x48,0x21,0xbc,0xe7,
|
||||
0x67,0x6f,0x04,0x18,0xae,0x20,0x87,0x4b,
|
||||
0x03,0x35,0xe9,0xbe,0xfb,0x06,0xdf,0xfc,
|
||||
}
|
||||
},
|
||||
{ 0xa708007, {
|
||||
0x6b,0x76,0xcc,0x78,0xc5,0x8a,0xa3,0xe3,
|
||||
0x32,0x2d,0x79,0xe4,0xc3,0x80,0xdb,0xb2,
|
||||
0x07,0xaa,0x3a,0xe0,0x57,0x13,0x72,0x80,
|
||||
0xdf,0x92,0x73,0x84,0x87,0x3c,0x73,0x93,
|
||||
}
|
||||
},
|
||||
{ 0xa70c005, {
|
||||
0x88,0x5d,0xfb,0x79,0x64,0xd8,0x46,0x3b,
|
||||
0x4a,0x83,0x8e,0x77,0x7e,0xcf,0xb3,0x0f,
|
||||
0x1f,0x1f,0xf1,0x97,0xeb,0xfe,0x56,0x55,
|
||||
0xee,0x49,0xac,0xe1,0x8b,0x13,0xc5,0x13,
|
||||
}
|
||||
},
|
||||
{ 0xaa00116, {
|
||||
0xe8,0x4c,0x2c,0x88,0xa1,0xac,0x24,0x63,
|
||||
0x65,0xe5,0xaa,0x2d,0x16,0xa9,0xc3,0xf5,
|
||||
0xfe,0x1d,0x5e,0x65,0xc7,0xaa,0x92,0x4d,
|
||||
0x91,0xee,0x76,0xbb,0x4c,0x66,0x78,0xc9,
|
||||
}
|
||||
},
|
||||
{ 0xaa00212, {
|
||||
0xbd,0x57,0x5d,0x0a,0x0a,0x30,0xc1,0x75,
|
||||
0x95,0x58,0x5e,0x93,0x02,0x28,0x43,0x71,
|
||||
0xed,0x42,0x29,0xc8,0xec,0x34,0x2b,0xb2,
|
||||
0x1a,0x65,0x4b,0xfe,0x07,0x0f,0x34,0xa1,
|
||||
}
|
||||
},
|
||||
{ 0xaa00213, {
|
||||
0xed,0x58,0xb7,0x76,0x81,0x7f,0xd9,0x3a,
|
||||
0x1a,0xff,0x8b,0x34,0xb8,0x4a,0x99,0x0f,
|
||||
0x28,0x49,0x6c,0x56,0x2b,0xdc,0xb7,0xed,
|
||||
0x96,0xd5,0x9d,0xc1,0x7a,0xd4,0x51,0x9b,
|
||||
}
|
||||
},
|
||||
{ 0xaa00215, {
|
||||
0x55,0xd3,0x28,0xcb,0x87,0xa9,0x32,0xe9,
|
||||
0x4e,0x85,0x4b,0x7c,0x6b,0xd5,0x7c,0xd4,
|
||||
0x1b,0x51,0x71,0x3a,0x0e,0x0b,0xdc,0x9b,
|
||||
0x68,0x2f,0x46,0xee,0xfe,0xc6,0x6d,0xef,
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -100,14 +100,12 @@ extern bool force_minrev;
|
||||
#ifdef CONFIG_CPU_SUP_AMD
|
||||
void load_ucode_amd_bsp(struct early_load_data *ed, unsigned int family);
|
||||
void load_ucode_amd_ap(unsigned int family);
|
||||
int save_microcode_in_initrd_amd(unsigned int family);
|
||||
void reload_ucode_amd(unsigned int cpu);
|
||||
struct microcode_ops *init_amd_microcode(void);
|
||||
void exit_amd_microcode(void);
|
||||
#else /* CONFIG_CPU_SUP_AMD */
|
||||
static inline void load_ucode_amd_bsp(struct early_load_data *ed, unsigned int family) { }
|
||||
static inline void load_ucode_amd_ap(unsigned int family) { }
|
||||
static inline int save_microcode_in_initrd_amd(unsigned int family) { return -EINVAL; }
|
||||
static inline void reload_ucode_amd(unsigned int cpu) { }
|
||||
static inline struct microcode_ops *init_amd_microcode(void) { return NULL; }
|
||||
static inline void exit_amd_microcode(void) { }
|
||||
|
||||
@@ -682,7 +682,7 @@ static void utf16_le_to_7bit(const __le16 *in, unsigned int size, u8 *out)
|
||||
out[size] = 0;
|
||||
|
||||
while (i < size) {
|
||||
u8 c = le16_to_cpu(in[i]) & 0xff;
|
||||
u8 c = le16_to_cpu(in[i]) & 0x7f;
|
||||
|
||||
if (c && !isprint(c))
|
||||
c = '!';
|
||||
|
||||
@@ -21,9 +21,15 @@ struct platform_profile_handler {
|
||||
struct device dev;
|
||||
int minor;
|
||||
unsigned long choices[BITS_TO_LONGS(PLATFORM_PROFILE_LAST)];
|
||||
unsigned long hidden_choices[BITS_TO_LONGS(PLATFORM_PROFILE_LAST)];
|
||||
const struct platform_profile_ops *ops;
|
||||
};
|
||||
|
||||
struct aggregate_choices_data {
|
||||
unsigned long aggregate[BITS_TO_LONGS(PLATFORM_PROFILE_LAST)];
|
||||
int count;
|
||||
};
|
||||
|
||||
static const char * const profile_names[] = {
|
||||
[PLATFORM_PROFILE_LOW_POWER] = "low-power",
|
||||
[PLATFORM_PROFILE_COOL] = "cool",
|
||||
@@ -73,7 +79,7 @@ static int _store_class_profile(struct device *dev, void *data)
|
||||
|
||||
lockdep_assert_held(&profile_lock);
|
||||
handler = to_pprof_handler(dev);
|
||||
if (!test_bit(*bit, handler->choices))
|
||||
if (!test_bit(*bit, handler->choices) && !test_bit(*bit, handler->hidden_choices))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return handler->ops->profile_set(dev, *bit);
|
||||
@@ -239,21 +245,44 @@ static const struct class platform_profile_class = {
|
||||
/**
|
||||
* _aggregate_choices - Aggregate the available profile choices
|
||||
* @dev: The device
|
||||
* @data: The available profile choices
|
||||
* @arg: struct aggregate_choices_data
|
||||
*
|
||||
* Return: 0 on success, -errno on failure
|
||||
*/
|
||||
static int _aggregate_choices(struct device *dev, void *data)
|
||||
static int _aggregate_choices(struct device *dev, void *arg)
|
||||
{
|
||||
unsigned long tmp[BITS_TO_LONGS(PLATFORM_PROFILE_LAST)];
|
||||
struct aggregate_choices_data *data = arg;
|
||||
struct platform_profile_handler *handler;
|
||||
unsigned long *aggregate = data;
|
||||
|
||||
lockdep_assert_held(&profile_lock);
|
||||
handler = to_pprof_handler(dev);
|
||||
if (test_bit(PLATFORM_PROFILE_LAST, aggregate))
|
||||
bitmap_copy(aggregate, handler->choices, PLATFORM_PROFILE_LAST);
|
||||
bitmap_or(tmp, handler->choices, handler->hidden_choices, PLATFORM_PROFILE_LAST);
|
||||
if (test_bit(PLATFORM_PROFILE_LAST, data->aggregate))
|
||||
bitmap_copy(data->aggregate, tmp, PLATFORM_PROFILE_LAST);
|
||||
else
|
||||
bitmap_and(aggregate, handler->choices, aggregate, PLATFORM_PROFILE_LAST);
|
||||
bitmap_and(data->aggregate, tmp, data->aggregate, PLATFORM_PROFILE_LAST);
|
||||
data->count++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* _remove_hidden_choices - Remove hidden choices from aggregate data
|
||||
* @dev: The device
|
||||
* @arg: struct aggregate_choices_data
|
||||
*
|
||||
* Return: 0 on success, -errno on failure
|
||||
*/
|
||||
static int _remove_hidden_choices(struct device *dev, void *arg)
|
||||
{
|
||||
struct aggregate_choices_data *data = arg;
|
||||
struct platform_profile_handler *handler;
|
||||
|
||||
lockdep_assert_held(&profile_lock);
|
||||
handler = to_pprof_handler(dev);
|
||||
bitmap_andnot(data->aggregate, handler->choices,
|
||||
handler->hidden_choices, PLATFORM_PROFILE_LAST);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -270,22 +299,31 @@ static ssize_t platform_profile_choices_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
unsigned long aggregate[BITS_TO_LONGS(PLATFORM_PROFILE_LAST)];
|
||||
struct aggregate_choices_data data = {
|
||||
.aggregate = { [0 ... BITS_TO_LONGS(PLATFORM_PROFILE_LAST) - 1] = ~0UL },
|
||||
.count = 0,
|
||||
};
|
||||
int err;
|
||||
|
||||
set_bit(PLATFORM_PROFILE_LAST, aggregate);
|
||||
set_bit(PLATFORM_PROFILE_LAST, data.aggregate);
|
||||
scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) {
|
||||
err = class_for_each_device(&platform_profile_class, NULL,
|
||||
aggregate, _aggregate_choices);
|
||||
&data, _aggregate_choices);
|
||||
if (err)
|
||||
return err;
|
||||
if (data.count == 1) {
|
||||
err = class_for_each_device(&platform_profile_class, NULL,
|
||||
&data, _remove_hidden_choices);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* no profile handler registered any more */
|
||||
if (bitmap_empty(aggregate, PLATFORM_PROFILE_LAST))
|
||||
if (bitmap_empty(data.aggregate, PLATFORM_PROFILE_LAST))
|
||||
return -EINVAL;
|
||||
|
||||
return _commmon_choices_show(aggregate, buf);
|
||||
return _commmon_choices_show(data.aggregate, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -373,7 +411,10 @@ static ssize_t platform_profile_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long choices[BITS_TO_LONGS(PLATFORM_PROFILE_LAST)];
|
||||
struct aggregate_choices_data data = {
|
||||
.aggregate = { [0 ... BITS_TO_LONGS(PLATFORM_PROFILE_LAST) - 1] = ~0UL },
|
||||
.count = 0,
|
||||
};
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
@@ -381,13 +422,13 @@ static ssize_t platform_profile_store(struct device *dev,
|
||||
i = sysfs_match_string(profile_names, buf);
|
||||
if (i < 0 || i == PLATFORM_PROFILE_CUSTOM)
|
||||
return -EINVAL;
|
||||
set_bit(PLATFORM_PROFILE_LAST, choices);
|
||||
set_bit(PLATFORM_PROFILE_LAST, data.aggregate);
|
||||
scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) {
|
||||
ret = class_for_each_device(&platform_profile_class, NULL,
|
||||
choices, _aggregate_choices);
|
||||
&data, _aggregate_choices);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!test_bit(i, choices))
|
||||
if (!test_bit(i, data.aggregate))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = class_for_each_device(&platform_profile_class, NULL, &i,
|
||||
@@ -453,12 +494,15 @@ EXPORT_SYMBOL_GPL(platform_profile_notify);
|
||||
*/
|
||||
int platform_profile_cycle(void)
|
||||
{
|
||||
struct aggregate_choices_data data = {
|
||||
.aggregate = { [0 ... BITS_TO_LONGS(PLATFORM_PROFILE_LAST) - 1] = ~0UL },
|
||||
.count = 0,
|
||||
};
|
||||
enum platform_profile_option next = PLATFORM_PROFILE_LAST;
|
||||
enum platform_profile_option profile = PLATFORM_PROFILE_LAST;
|
||||
unsigned long choices[BITS_TO_LONGS(PLATFORM_PROFILE_LAST)];
|
||||
int err;
|
||||
|
||||
set_bit(PLATFORM_PROFILE_LAST, choices);
|
||||
set_bit(PLATFORM_PROFILE_LAST, data.aggregate);
|
||||
scoped_cond_guard(mutex_intr, return -ERESTARTSYS, &profile_lock) {
|
||||
err = class_for_each_device(&platform_profile_class, NULL,
|
||||
&profile, _aggregate_profiles);
|
||||
@@ -470,14 +514,14 @@ int platform_profile_cycle(void)
|
||||
return -EINVAL;
|
||||
|
||||
err = class_for_each_device(&platform_profile_class, NULL,
|
||||
choices, _aggregate_choices);
|
||||
&data, _aggregate_choices);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* never iterate into a custom if all drivers supported it */
|
||||
clear_bit(PLATFORM_PROFILE_CUSTOM, choices);
|
||||
clear_bit(PLATFORM_PROFILE_CUSTOM, data.aggregate);
|
||||
|
||||
next = find_next_bit_wrap(choices,
|
||||
next = find_next_bit_wrap(data.aggregate,
|
||||
PLATFORM_PROFILE_LAST,
|
||||
profile + 1);
|
||||
|
||||
@@ -532,6 +576,14 @@ struct device *platform_profile_register(struct device *dev, const char *name,
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (ops->hidden_choices) {
|
||||
err = ops->hidden_choices(drvdata, pprof->hidden_choices);
|
||||
if (err) {
|
||||
dev_err(dev, "platform_profile hidden_choices failed\n");
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
}
|
||||
|
||||
guard(mutex)(&profile_lock);
|
||||
|
||||
/* create class interface for individual handler */
|
||||
|
||||
@@ -2715,9 +2715,12 @@ static int ublk_ctrl_set_params(struct ublk_device *ub,
|
||||
if (ph.len > sizeof(struct ublk_params))
|
||||
ph.len = sizeof(struct ublk_params);
|
||||
|
||||
/* parameters can only be changed when device isn't live */
|
||||
mutex_lock(&ub->mutex);
|
||||
if (ub->dev_info.state == UBLK_S_DEV_LIVE) {
|
||||
if (test_bit(UB_STATE_USED, &ub->state)) {
|
||||
/*
|
||||
* Parameters can only be changed when device hasn't
|
||||
* been started yet
|
||||
*/
|
||||
ret = -EACCES;
|
||||
} else if (copy_from_user(&ub->params, argp, ph.len)) {
|
||||
ret = -EFAULT;
|
||||
|
||||
@@ -3644,6 +3644,7 @@ static ssize_t force_poll_sync_write(struct file *file,
|
||||
}
|
||||
|
||||
static const struct file_operations force_poll_sync_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = force_poll_sync_read,
|
||||
.write = force_poll_sync_write,
|
||||
|
||||
@@ -923,14 +923,14 @@ static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe,
|
||||
|
||||
pipe_lock(pipe);
|
||||
ret = 0;
|
||||
if (pipe_empty(pipe->head, pipe->tail))
|
||||
if (pipe_is_empty(pipe))
|
||||
goto error_out;
|
||||
|
||||
ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK);
|
||||
if (ret < 0)
|
||||
goto error_out;
|
||||
|
||||
occupancy = pipe_occupancy(pipe->head, pipe->tail);
|
||||
occupancy = pipe_buf_usage(pipe);
|
||||
buf = alloc_buf(port->portdev->vdev, 0, occupancy);
|
||||
|
||||
if (!buf) {
|
||||
|
||||
@@ -119,10 +119,15 @@ static ssize_t new_device_store(struct device_driver *driver, const char *buf,
|
||||
struct platform_device *pdev;
|
||||
int res, id;
|
||||
|
||||
if (!try_module_get(THIS_MODULE))
|
||||
return -ENOENT;
|
||||
|
||||
/* kernfs guarantees string termination, so count + 1 is safe */
|
||||
aggr = kzalloc(sizeof(*aggr) + count + 1, GFP_KERNEL);
|
||||
if (!aggr)
|
||||
return -ENOMEM;
|
||||
if (!aggr) {
|
||||
res = -ENOMEM;
|
||||
goto put_module;
|
||||
}
|
||||
|
||||
memcpy(aggr->args, buf, count + 1);
|
||||
|
||||
@@ -161,6 +166,7 @@ static ssize_t new_device_store(struct device_driver *driver, const char *buf,
|
||||
}
|
||||
|
||||
aggr->pdev = pdev;
|
||||
module_put(THIS_MODULE);
|
||||
return count;
|
||||
|
||||
remove_table:
|
||||
@@ -175,6 +181,8 @@ free_table:
|
||||
kfree(aggr->lookups);
|
||||
free_ga:
|
||||
kfree(aggr);
|
||||
put_module:
|
||||
module_put(THIS_MODULE);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -203,13 +211,19 @@ static ssize_t delete_device_store(struct device_driver *driver,
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (!try_module_get(THIS_MODULE))
|
||||
return -ENOENT;
|
||||
|
||||
mutex_lock(&gpio_aggregator_lock);
|
||||
aggr = idr_remove(&gpio_aggregator_idr, id);
|
||||
mutex_unlock(&gpio_aggregator_lock);
|
||||
if (!aggr)
|
||||
if (!aggr) {
|
||||
module_put(THIS_MODULE);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
gpio_aggregator_free(aggr);
|
||||
module_put(THIS_MODULE);
|
||||
return count;
|
||||
}
|
||||
static DRIVER_ATTR_WO(delete_device);
|
||||
|
||||
+18
-13
@@ -40,7 +40,7 @@ struct gpio_rcar_info {
|
||||
|
||||
struct gpio_rcar_priv {
|
||||
void __iomem *base;
|
||||
spinlock_t lock;
|
||||
raw_spinlock_t lock;
|
||||
struct device *dev;
|
||||
struct gpio_chip gpio_chip;
|
||||
unsigned int irq_parent;
|
||||
@@ -123,7 +123,7 @@ static void gpio_rcar_config_interrupt_input_mode(struct gpio_rcar_priv *p,
|
||||
* "Setting Level-Sensitive Interrupt Input Mode"
|
||||
*/
|
||||
|
||||
spin_lock_irqsave(&p->lock, flags);
|
||||
raw_spin_lock_irqsave(&p->lock, flags);
|
||||
|
||||
/* Configure positive or negative logic in POSNEG */
|
||||
gpio_rcar_modify_bit(p, POSNEG, hwirq, !active_high_rising_edge);
|
||||
@@ -142,7 +142,7 @@ static void gpio_rcar_config_interrupt_input_mode(struct gpio_rcar_priv *p,
|
||||
if (!level_trigger)
|
||||
gpio_rcar_write(p, INTCLR, BIT(hwirq));
|
||||
|
||||
spin_unlock_irqrestore(&p->lock, flags);
|
||||
raw_spin_unlock_irqrestore(&p->lock, flags);
|
||||
}
|
||||
|
||||
static int gpio_rcar_irq_set_type(struct irq_data *d, unsigned int type)
|
||||
@@ -246,7 +246,7 @@ static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip,
|
||||
* "Setting General Input Mode"
|
||||
*/
|
||||
|
||||
spin_lock_irqsave(&p->lock, flags);
|
||||
raw_spin_lock_irqsave(&p->lock, flags);
|
||||
|
||||
/* Configure positive logic in POSNEG */
|
||||
gpio_rcar_modify_bit(p, POSNEG, gpio, false);
|
||||
@@ -261,7 +261,7 @@ static void gpio_rcar_config_general_input_output_mode(struct gpio_chip *chip,
|
||||
if (p->info.has_outdtsel && output)
|
||||
gpio_rcar_modify_bit(p, OUTDTSEL, gpio, false);
|
||||
|
||||
spin_unlock_irqrestore(&p->lock, flags);
|
||||
raw_spin_unlock_irqrestore(&p->lock, flags);
|
||||
}
|
||||
|
||||
static int gpio_rcar_request(struct gpio_chip *chip, unsigned offset)
|
||||
@@ -347,7 +347,7 @@ static int gpio_rcar_get_multiple(struct gpio_chip *chip, unsigned long *mask,
|
||||
return 0;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&p->lock, flags);
|
||||
raw_spin_lock_irqsave(&p->lock, flags);
|
||||
outputs = gpio_rcar_read(p, INOUTSEL);
|
||||
m = outputs & bankmask;
|
||||
if (m)
|
||||
@@ -356,7 +356,7 @@ static int gpio_rcar_get_multiple(struct gpio_chip *chip, unsigned long *mask,
|
||||
m = ~outputs & bankmask;
|
||||
if (m)
|
||||
val |= gpio_rcar_read(p, INDT) & m;
|
||||
spin_unlock_irqrestore(&p->lock, flags);
|
||||
raw_spin_unlock_irqrestore(&p->lock, flags);
|
||||
|
||||
bits[0] = val;
|
||||
return 0;
|
||||
@@ -367,9 +367,9 @@ static void gpio_rcar_set(struct gpio_chip *chip, unsigned offset, int value)
|
||||
struct gpio_rcar_priv *p = gpiochip_get_data(chip);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&p->lock, flags);
|
||||
raw_spin_lock_irqsave(&p->lock, flags);
|
||||
gpio_rcar_modify_bit(p, OUTDT, offset, value);
|
||||
spin_unlock_irqrestore(&p->lock, flags);
|
||||
raw_spin_unlock_irqrestore(&p->lock, flags);
|
||||
}
|
||||
|
||||
static void gpio_rcar_set_multiple(struct gpio_chip *chip, unsigned long *mask,
|
||||
@@ -386,12 +386,12 @@ static void gpio_rcar_set_multiple(struct gpio_chip *chip, unsigned long *mask,
|
||||
if (!bankmask)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&p->lock, flags);
|
||||
raw_spin_lock_irqsave(&p->lock, flags);
|
||||
val = gpio_rcar_read(p, OUTDT);
|
||||
val &= ~bankmask;
|
||||
val |= (bankmask & bits[0]);
|
||||
gpio_rcar_write(p, OUTDT, val);
|
||||
spin_unlock_irqrestore(&p->lock, flags);
|
||||
raw_spin_unlock_irqrestore(&p->lock, flags);
|
||||
}
|
||||
|
||||
static int gpio_rcar_direction_output(struct gpio_chip *chip, unsigned offset,
|
||||
@@ -468,7 +468,12 @@ static int gpio_rcar_parse_dt(struct gpio_rcar_priv *p, unsigned int *npins)
|
||||
p->info = *info;
|
||||
|
||||
ret = of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &args);
|
||||
*npins = ret == 0 ? args.args[2] : RCAR_MAX_GPIO_PER_BANK;
|
||||
if (ret) {
|
||||
*npins = RCAR_MAX_GPIO_PER_BANK;
|
||||
} else {
|
||||
*npins = args.args[2];
|
||||
of_node_put(args.np);
|
||||
}
|
||||
|
||||
if (*npins == 0 || *npins > RCAR_MAX_GPIO_PER_BANK) {
|
||||
dev_warn(p->dev, "Invalid number of gpio lines %u, using %u\n",
|
||||
@@ -505,7 +510,7 @@ static int gpio_rcar_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
p->dev = dev;
|
||||
spin_lock_init(&p->lock);
|
||||
raw_spin_lock_init(&p->lock);
|
||||
|
||||
/* Get device configuration from DT node */
|
||||
ret = gpio_rcar_parse_dt(p, &npins);
|
||||
|
||||
@@ -266,8 +266,8 @@ int kfd_queue_acquire_buffers(struct kfd_process_device *pdd, struct queue_prope
|
||||
/* EOP buffer is not required for all ASICs */
|
||||
if (properties->eop_ring_buffer_address) {
|
||||
if (properties->eop_ring_buffer_size != topo_dev->node_props.eop_buffer_size) {
|
||||
pr_debug("queue eop bo size 0x%lx not equal to node eop buf size 0x%x\n",
|
||||
properties->eop_buf_bo->tbo.base.size,
|
||||
pr_debug("queue eop bo size 0x%x not equal to node eop buf size 0x%x\n",
|
||||
properties->eop_ring_buffer_size,
|
||||
topo_dev->node_props.eop_buffer_size);
|
||||
err = -EINVAL;
|
||||
goto out_err_unreserve;
|
||||
|
||||
@@ -1455,7 +1455,8 @@ bool resource_build_scaling_params(struct pipe_ctx *pipe_ctx)
|
||||
DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
|
||||
|
||||
/* Invalid input */
|
||||
if (!plane_state->dst_rect.width ||
|
||||
if (!plane_state ||
|
||||
!plane_state->dst_rect.width ||
|
||||
!plane_state->dst_rect.height ||
|
||||
!plane_state->src_rect.width ||
|
||||
!plane_state->src_rect.height) {
|
||||
|
||||
@@ -1895,16 +1895,6 @@ static int smu_v14_0_allow_ih_interrupt(struct smu_context *smu)
|
||||
NULL);
|
||||
}
|
||||
|
||||
static int smu_v14_0_process_pending_interrupt(struct smu_context *smu)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_ACDC_BIT))
|
||||
ret = smu_v14_0_allow_ih_interrupt(smu);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int smu_v14_0_enable_thermal_alert(struct smu_context *smu)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -1916,7 +1906,7 @@ int smu_v14_0_enable_thermal_alert(struct smu_context *smu)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return smu_v14_0_process_pending_interrupt(smu);
|
||||
return smu_v14_0_allow_ih_interrupt(smu);
|
||||
}
|
||||
|
||||
int smu_v14_0_disable_thermal_alert(struct smu_context *smu)
|
||||
|
||||
@@ -1867,7 +1867,8 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id)
|
||||
/* create encoders */
|
||||
mst_stream_encoders_create(dig_port);
|
||||
ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, display->drm,
|
||||
&intel_dp->aux, 16, 3, conn_base_id);
|
||||
&intel_dp->aux, 16,
|
||||
INTEL_NUM_PIPES(display), conn_base_id);
|
||||
if (ret) {
|
||||
intel_dp->mst_mgr.cbs = NULL;
|
||||
return ret;
|
||||
|
||||
@@ -527,8 +527,10 @@ pvr_meta_vm_map(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj)
|
||||
static void
|
||||
pvr_meta_vm_unmap(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj)
|
||||
{
|
||||
pvr_vm_unmap(pvr_dev->kernel_vm_ctx, fw_obj->fw_mm_node.start,
|
||||
fw_obj->fw_mm_node.size);
|
||||
struct pvr_gem_object *pvr_obj = fw_obj->gem;
|
||||
|
||||
pvr_vm_unmap_obj(pvr_dev->kernel_vm_ctx, pvr_obj,
|
||||
fw_obj->fw_mm_node.start, fw_obj->fw_mm_node.size);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
||||
@@ -333,8 +333,8 @@ static int fw_trace_seq_show(struct seq_file *s, void *v)
|
||||
if (sf_id == ROGUE_FW_SF_LAST)
|
||||
return -EINVAL;
|
||||
|
||||
timestamp = read_fw_trace(trace_seq_data, 1) |
|
||||
((u64)read_fw_trace(trace_seq_data, 2) << 32);
|
||||
timestamp = ((u64)read_fw_trace(trace_seq_data, 1) << 32) |
|
||||
read_fw_trace(trace_seq_data, 2);
|
||||
timestamp = (timestamp & ~ROGUE_FWT_TIMESTAMP_TIME_CLRMSK) >>
|
||||
ROGUE_FWT_TIMESTAMP_TIME_SHIFT;
|
||||
|
||||
|
||||
@@ -109,12 +109,20 @@ pvr_queue_fence_get_driver_name(struct dma_fence *f)
|
||||
return PVR_DRIVER_NAME;
|
||||
}
|
||||
|
||||
static void pvr_queue_fence_release_work(struct work_struct *w)
|
||||
{
|
||||
struct pvr_queue_fence *fence = container_of(w, struct pvr_queue_fence, release_work);
|
||||
|
||||
pvr_context_put(fence->queue->ctx);
|
||||
dma_fence_free(&fence->base);
|
||||
}
|
||||
|
||||
static void pvr_queue_fence_release(struct dma_fence *f)
|
||||
{
|
||||
struct pvr_queue_fence *fence = container_of(f, struct pvr_queue_fence, base);
|
||||
struct pvr_device *pvr_dev = fence->queue->ctx->pvr_dev;
|
||||
|
||||
pvr_context_put(fence->queue->ctx);
|
||||
dma_fence_free(f);
|
||||
queue_work(pvr_dev->sched_wq, &fence->release_work);
|
||||
}
|
||||
|
||||
static const char *
|
||||
@@ -268,6 +276,7 @@ pvr_queue_fence_init(struct dma_fence *f,
|
||||
|
||||
pvr_context_get(queue->ctx);
|
||||
fence->queue = queue;
|
||||
INIT_WORK(&fence->release_work, pvr_queue_fence_release_work);
|
||||
dma_fence_init(&fence->base, fence_ops,
|
||||
&fence_ctx->lock, fence_ctx->id,
|
||||
atomic_inc_return(&fence_ctx->seqno));
|
||||
@@ -304,8 +313,9 @@ pvr_queue_cccb_fence_init(struct dma_fence *fence, struct pvr_queue *queue)
|
||||
static void
|
||||
pvr_queue_job_fence_init(struct dma_fence *fence, struct pvr_queue *queue)
|
||||
{
|
||||
pvr_queue_fence_init(fence, queue, &pvr_queue_job_fence_ops,
|
||||
&queue->job_fence_ctx);
|
||||
if (!fence->ops)
|
||||
pvr_queue_fence_init(fence, queue, &pvr_queue_job_fence_ops,
|
||||
&queue->job_fence_ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#define PVR_QUEUE_H
|
||||
|
||||
#include <drm/gpu_scheduler.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include "pvr_cccb.h"
|
||||
#include "pvr_device.h"
|
||||
@@ -63,6 +64,9 @@ struct pvr_queue_fence {
|
||||
|
||||
/** @queue: Queue that created this fence. */
|
||||
struct pvr_queue *queue;
|
||||
|
||||
/** @release_work: Fence release work structure. */
|
||||
struct work_struct release_work;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -293,8 +293,9 @@ err_bind_op_fini:
|
||||
|
||||
static int
|
||||
pvr_vm_bind_op_unmap_init(struct pvr_vm_bind_op *bind_op,
|
||||
struct pvr_vm_context *vm_ctx, u64 device_addr,
|
||||
u64 size)
|
||||
struct pvr_vm_context *vm_ctx,
|
||||
struct pvr_gem_object *pvr_obj,
|
||||
u64 device_addr, u64 size)
|
||||
{
|
||||
int err;
|
||||
|
||||
@@ -318,6 +319,7 @@ pvr_vm_bind_op_unmap_init(struct pvr_vm_bind_op *bind_op,
|
||||
goto err_bind_op_fini;
|
||||
}
|
||||
|
||||
bind_op->pvr_obj = pvr_obj;
|
||||
bind_op->vm_ctx = vm_ctx;
|
||||
bind_op->device_addr = device_addr;
|
||||
bind_op->size = size;
|
||||
@@ -597,20 +599,6 @@ err_free:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
/**
|
||||
* pvr_vm_unmap_all() - Unmap all mappings associated with a VM context.
|
||||
* @vm_ctx: Target VM context.
|
||||
*
|
||||
* This function ensures that no mappings are left dangling by unmapping them
|
||||
* all in order of ascending device-virtual address.
|
||||
*/
|
||||
void
|
||||
pvr_vm_unmap_all(struct pvr_vm_context *vm_ctx)
|
||||
{
|
||||
WARN_ON(pvr_vm_unmap(vm_ctx, vm_ctx->gpuvm_mgr.mm_start,
|
||||
vm_ctx->gpuvm_mgr.mm_range));
|
||||
}
|
||||
|
||||
/**
|
||||
* pvr_vm_context_release() - Teardown a VM context.
|
||||
* @ref_count: Pointer to reference counter of the VM context.
|
||||
@@ -703,11 +691,7 @@ pvr_vm_lock_extra(struct drm_gpuvm_exec *vm_exec)
|
||||
struct pvr_vm_bind_op *bind_op = vm_exec->extra.priv;
|
||||
struct pvr_gem_object *pvr_obj = bind_op->pvr_obj;
|
||||
|
||||
/* Unmap operations don't have an object to lock. */
|
||||
if (!pvr_obj)
|
||||
return 0;
|
||||
|
||||
/* Acquire lock on the GEM being mapped. */
|
||||
/* Acquire lock on the GEM object being mapped/unmapped. */
|
||||
return drm_exec_lock_obj(&vm_exec->exec, gem_from_pvr_gem(pvr_obj));
|
||||
}
|
||||
|
||||
@@ -772,8 +756,10 @@ err_cleanup:
|
||||
}
|
||||
|
||||
/**
|
||||
* pvr_vm_unmap() - Unmap an already mapped section of device-virtual memory.
|
||||
* pvr_vm_unmap_obj_locked() - Unmap an already mapped section of device-virtual
|
||||
* memory.
|
||||
* @vm_ctx: Target VM context.
|
||||
* @pvr_obj: Target PowerVR memory object.
|
||||
* @device_addr: Virtual device address at the start of the target mapping.
|
||||
* @size: Size of the target mapping.
|
||||
*
|
||||
@@ -784,9 +770,13 @@ err_cleanup:
|
||||
* * Any error encountered while performing internal operations required to
|
||||
* destroy the mapping (returned from pvr_vm_gpuva_unmap or
|
||||
* pvr_vm_gpuva_remap).
|
||||
*
|
||||
* The vm_ctx->lock must be held when calling this function.
|
||||
*/
|
||||
int
|
||||
pvr_vm_unmap(struct pvr_vm_context *vm_ctx, u64 device_addr, u64 size)
|
||||
static int
|
||||
pvr_vm_unmap_obj_locked(struct pvr_vm_context *vm_ctx,
|
||||
struct pvr_gem_object *pvr_obj,
|
||||
u64 device_addr, u64 size)
|
||||
{
|
||||
struct pvr_vm_bind_op bind_op = {0};
|
||||
struct drm_gpuvm_exec vm_exec = {
|
||||
@@ -799,11 +789,13 @@ pvr_vm_unmap(struct pvr_vm_context *vm_ctx, u64 device_addr, u64 size)
|
||||
},
|
||||
};
|
||||
|
||||
int err = pvr_vm_bind_op_unmap_init(&bind_op, vm_ctx, device_addr,
|
||||
size);
|
||||
int err = pvr_vm_bind_op_unmap_init(&bind_op, vm_ctx, pvr_obj,
|
||||
device_addr, size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
pvr_gem_object_get(pvr_obj);
|
||||
|
||||
err = drm_gpuvm_exec_lock(&vm_exec);
|
||||
if (err)
|
||||
goto err_cleanup;
|
||||
@@ -818,6 +810,96 @@ err_cleanup:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* pvr_vm_unmap_obj() - Unmap an already mapped section of device-virtual
|
||||
* memory.
|
||||
* @vm_ctx: Target VM context.
|
||||
* @pvr_obj: Target PowerVR memory object.
|
||||
* @device_addr: Virtual device address at the start of the target mapping.
|
||||
* @size: Size of the target mapping.
|
||||
*
|
||||
* Return:
|
||||
* * 0 on success,
|
||||
* * Any error encountered by pvr_vm_unmap_obj_locked.
|
||||
*/
|
||||
int
|
||||
pvr_vm_unmap_obj(struct pvr_vm_context *vm_ctx, struct pvr_gem_object *pvr_obj,
|
||||
u64 device_addr, u64 size)
|
||||
{
|
||||
int err;
|
||||
|
||||
mutex_lock(&vm_ctx->lock);
|
||||
err = pvr_vm_unmap_obj_locked(vm_ctx, pvr_obj, device_addr, size);
|
||||
mutex_unlock(&vm_ctx->lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* pvr_vm_unmap() - Unmap an already mapped section of device-virtual memory.
|
||||
* @vm_ctx: Target VM context.
|
||||
* @device_addr: Virtual device address at the start of the target mapping.
|
||||
* @size: Size of the target mapping.
|
||||
*
|
||||
* Return:
|
||||
* * 0 on success,
|
||||
* * Any error encountered by drm_gpuva_find,
|
||||
* * Any error encountered by pvr_vm_unmap_obj_locked.
|
||||
*/
|
||||
int
|
||||
pvr_vm_unmap(struct pvr_vm_context *vm_ctx, u64 device_addr, u64 size)
|
||||
{
|
||||
struct pvr_gem_object *pvr_obj;
|
||||
struct drm_gpuva *va;
|
||||
int err;
|
||||
|
||||
mutex_lock(&vm_ctx->lock);
|
||||
|
||||
va = drm_gpuva_find(&vm_ctx->gpuvm_mgr, device_addr, size);
|
||||
if (va) {
|
||||
pvr_obj = gem_to_pvr_gem(va->gem.obj);
|
||||
err = pvr_vm_unmap_obj_locked(vm_ctx, pvr_obj,
|
||||
va->va.addr, va->va.range);
|
||||
} else {
|
||||
err = -ENOENT;
|
||||
}
|
||||
|
||||
mutex_unlock(&vm_ctx->lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* pvr_vm_unmap_all() - Unmap all mappings associated with a VM context.
|
||||
* @vm_ctx: Target VM context.
|
||||
*
|
||||
* This function ensures that no mappings are left dangling by unmapping them
|
||||
* all in order of ascending device-virtual address.
|
||||
*/
|
||||
void
|
||||
pvr_vm_unmap_all(struct pvr_vm_context *vm_ctx)
|
||||
{
|
||||
mutex_lock(&vm_ctx->lock);
|
||||
|
||||
for (;;) {
|
||||
struct pvr_gem_object *pvr_obj;
|
||||
struct drm_gpuva *va;
|
||||
|
||||
va = drm_gpuva_find_first(&vm_ctx->gpuvm_mgr,
|
||||
vm_ctx->gpuvm_mgr.mm_start,
|
||||
vm_ctx->gpuvm_mgr.mm_range);
|
||||
if (!va)
|
||||
break;
|
||||
|
||||
pvr_obj = gem_to_pvr_gem(va->gem.obj);
|
||||
|
||||
WARN_ON(pvr_vm_unmap_obj_locked(vm_ctx, pvr_obj,
|
||||
va->va.addr, va->va.range));
|
||||
}
|
||||
|
||||
mutex_unlock(&vm_ctx->lock);
|
||||
}
|
||||
|
||||
/* Static data areas are determined by firmware. */
|
||||
static const struct drm_pvr_static_data_area static_data_areas[] = {
|
||||
{
|
||||
|
||||
@@ -38,6 +38,9 @@ struct pvr_vm_context *pvr_vm_create_context(struct pvr_device *pvr_dev,
|
||||
int pvr_vm_map(struct pvr_vm_context *vm_ctx,
|
||||
struct pvr_gem_object *pvr_obj, u64 pvr_obj_offset,
|
||||
u64 device_addr, u64 size);
|
||||
int pvr_vm_unmap_obj(struct pvr_vm_context *vm_ctx,
|
||||
struct pvr_gem_object *pvr_obj,
|
||||
u64 device_addr, u64 size);
|
||||
int pvr_vm_unmap(struct pvr_vm_context *vm_ctx, u64 device_addr, u64 size);
|
||||
void pvr_vm_unmap_all(struct pvr_vm_context *vm_ctx);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ config DRM_NOUVEAU
|
||||
depends on DRM && PCI && MMU
|
||||
select IOMMU_API
|
||||
select FW_LOADER
|
||||
select FW_CACHE if PM_SLEEP
|
||||
select DRM_CLIENT_SELECTION
|
||||
select DRM_DISPLAY_DP_HELPER
|
||||
select DRM_DISPLAY_HDMI_HELPER
|
||||
|
||||
@@ -359,7 +359,8 @@ int r300_mc_wait_for_idle(struct radeon_device *rdev)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void r300_gpu_init(struct radeon_device *rdev)
|
||||
/* rs400_gpu_init also calls this! */
|
||||
void r300_gpu_init(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t gb_tile_config, tmp;
|
||||
|
||||
|
||||
@@ -165,6 +165,7 @@ void r200_set_safe_registers(struct radeon_device *rdev);
|
||||
*/
|
||||
extern int r300_init(struct radeon_device *rdev);
|
||||
extern void r300_fini(struct radeon_device *rdev);
|
||||
extern void r300_gpu_init(struct radeon_device *rdev);
|
||||
extern int r300_suspend(struct radeon_device *rdev);
|
||||
extern int r300_resume(struct radeon_device *rdev);
|
||||
extern int r300_asic_reset(struct radeon_device *rdev, bool hard);
|
||||
|
||||
@@ -256,8 +256,22 @@ int rs400_mc_wait_for_idle(struct radeon_device *rdev)
|
||||
|
||||
static void rs400_gpu_init(struct radeon_device *rdev)
|
||||
{
|
||||
/* FIXME: is this correct ? */
|
||||
r420_pipes_init(rdev);
|
||||
/* Earlier code was calling r420_pipes_init and then
|
||||
* rs400_mc_wait_for_idle(rdev). The problem is that
|
||||
* at least on my Mobility Radeon Xpress 200M RC410 card
|
||||
* that ends up in this code path ends up num_gb_pipes == 3
|
||||
* while the card seems to have only one pipe. With the
|
||||
* r420 pipe initialization method.
|
||||
*
|
||||
* Problems shown up as HyperZ glitches, see:
|
||||
* https://bugs.freedesktop.org/show_bug.cgi?id=110897
|
||||
*
|
||||
* Delegating initialization to r300 code seems to work
|
||||
* and results in proper pipe numbers. The rs400 cards
|
||||
* are said to be not r400, but r300 kind of cards.
|
||||
*/
|
||||
r300_gpu_init(rdev);
|
||||
|
||||
if (rs400_mc_wait_for_idle(rdev)) {
|
||||
pr_warn("rs400: Failed to wait MC idle while programming pipes. Bad things might happen. %08x\n",
|
||||
RREG32(RADEON_MC_STATUS));
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(_GPU_SCHED_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#if !defined(_GPU_SCHED_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define _GPU_SCHED_TRACE_H_
|
||||
|
||||
#include <linux/stringify.h>
|
||||
@@ -106,7 +106,7 @@ TRACE_EVENT(drm_sched_job_wait_dep,
|
||||
__entry->seqno)
|
||||
);
|
||||
|
||||
#endif
|
||||
#endif /* _GPU_SCHED_TRACE_H_ */
|
||||
|
||||
/* This part must be outside protection */
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
|
||||
@@ -335,8 +335,6 @@ static void bochs_hw_setmode(struct bochs_device *bochs, struct drm_display_mode
|
||||
bochs->xres, bochs->yres, bochs->bpp,
|
||||
bochs->yres_virtual);
|
||||
|
||||
bochs_hw_blank(bochs, false);
|
||||
|
||||
bochs_dispi_write(bochs, VBE_DISPI_INDEX_ENABLE, 0);
|
||||
bochs_dispi_write(bochs, VBE_DISPI_INDEX_BPP, bochs->bpp);
|
||||
bochs_dispi_write(bochs, VBE_DISPI_INDEX_XRES, bochs->xres);
|
||||
@@ -506,6 +504,9 @@ static int bochs_crtc_helper_atomic_check(struct drm_crtc *crtc,
|
||||
static void bochs_crtc_helper_atomic_enable(struct drm_crtc *crtc,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct bochs_device *bochs = to_bochs_device(crtc->dev);
|
||||
|
||||
bochs_hw_blank(bochs, false);
|
||||
}
|
||||
|
||||
static void bochs_crtc_helper_atomic_disable(struct drm_crtc *crtc,
|
||||
|
||||
@@ -194,8 +194,6 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
|
||||
to_intel_plane(crtc->base.primary);
|
||||
struct intel_plane_state *plane_state =
|
||||
to_intel_plane_state(plane->base.state);
|
||||
struct intel_crtc_state *crtc_state =
|
||||
to_intel_crtc_state(crtc->base.state);
|
||||
struct drm_framebuffer *fb;
|
||||
struct i915_vma *vma;
|
||||
|
||||
@@ -241,14 +239,6 @@ intel_find_initial_plane_obj(struct intel_crtc *crtc,
|
||||
atomic_or(plane->frontbuffer_bit, &to_intel_frontbuffer(fb)->bits);
|
||||
|
||||
plane_config->vma = vma;
|
||||
|
||||
/*
|
||||
* Flip to the newly created mapping ASAP, so we can re-use the
|
||||
* first part of GGTT for WOPCM, prevent flickering, and prevent
|
||||
* the lookup of sysmem scratch pages.
|
||||
*/
|
||||
plane->check_plane(crtc_state, plane_state);
|
||||
plane->async_flip(NULL, plane, crtc_state, plane_state, true);
|
||||
return;
|
||||
|
||||
nofb:
|
||||
|
||||
@@ -380,9 +380,7 @@ int xe_gt_init_early(struct xe_gt *gt)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
xe_wa_process_gt(gt);
|
||||
xe_wa_process_oob(gt);
|
||||
xe_tuning_process_gt(gt);
|
||||
|
||||
xe_force_wake_init_gt(gt, gt_to_fw(gt));
|
||||
spin_lock_init(>->global_invl_lock);
|
||||
@@ -474,6 +472,8 @@ static int all_fw_domain_init(struct xe_gt *gt)
|
||||
}
|
||||
|
||||
xe_gt_mcr_set_implicit_defaults(gt);
|
||||
xe_wa_process_gt(gt);
|
||||
xe_tuning_process_gt(gt);
|
||||
xe_reg_sr_apply_mmio(>->reg_sr, gt);
|
||||
|
||||
err = xe_gt_clock_init(gt);
|
||||
|
||||
+143
-51
@@ -19,11 +19,10 @@ static u64 xe_npages_in_range(unsigned long start, unsigned long end)
|
||||
return (end - start) >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* xe_mark_range_accessed() - mark a range is accessed, so core mm
|
||||
* have such information for memory eviction or write back to
|
||||
* hard disk
|
||||
*
|
||||
* @range: the range to mark
|
||||
* @write: if write to this range, we mark pages in this range
|
||||
* as dirty
|
||||
@@ -43,15 +42,51 @@ static void xe_mark_range_accessed(struct hmm_range *range, bool write)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static int xe_alloc_sg(struct xe_device *xe, struct sg_table *st,
|
||||
struct hmm_range *range, struct rw_semaphore *notifier_sem)
|
||||
{
|
||||
unsigned long i, npages, hmm_pfn;
|
||||
unsigned long num_chunks = 0;
|
||||
int ret;
|
||||
|
||||
/* HMM docs says this is needed. */
|
||||
ret = down_read_interruptible(notifier_sem);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (mmu_interval_read_retry(range->notifier, range->notifier_seq)) {
|
||||
up_read(notifier_sem);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
npages = xe_npages_in_range(range->start, range->end);
|
||||
for (i = 0; i < npages;) {
|
||||
unsigned long len;
|
||||
|
||||
hmm_pfn = range->hmm_pfns[i];
|
||||
xe_assert(xe, hmm_pfn & HMM_PFN_VALID);
|
||||
|
||||
len = 1UL << hmm_pfn_to_map_order(hmm_pfn);
|
||||
|
||||
/* If order > 0 the page may extend beyond range->start */
|
||||
len -= (hmm_pfn & ~HMM_PFN_FLAGS) & (len - 1);
|
||||
i += len;
|
||||
num_chunks++;
|
||||
}
|
||||
up_read(notifier_sem);
|
||||
|
||||
return sg_alloc_table(st, num_chunks, GFP_KERNEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_build_sg() - build a scatter gather table for all the physical pages/pfn
|
||||
* in a hmm_range. dma-map pages if necessary. dma-address is save in sg table
|
||||
* and will be used to program GPU page table later.
|
||||
*
|
||||
* @xe: the xe device who will access the dma-address in sg table
|
||||
* @range: the hmm range that we build the sg table from. range->hmm_pfns[]
|
||||
* has the pfn numbers of pages that back up this hmm address range.
|
||||
* @st: pointer to the sg table.
|
||||
* @notifier_sem: The xe notifier lock.
|
||||
* @write: whether we write to this range. This decides dma map direction
|
||||
* for system pages. If write we map it bi-diretional; otherwise
|
||||
* DMA_TO_DEVICE
|
||||
@@ -78,43 +113,84 @@ static void xe_mark_range_accessed(struct hmm_range *range, bool write)
|
||||
* Returns 0 if successful; -ENOMEM if fails to allocate memory
|
||||
*/
|
||||
static int xe_build_sg(struct xe_device *xe, struct hmm_range *range,
|
||||
struct sg_table *st, bool write)
|
||||
struct sg_table *st,
|
||||
struct rw_semaphore *notifier_sem,
|
||||
bool write)
|
||||
{
|
||||
unsigned long npages = xe_npages_in_range(range->start, range->end);
|
||||
struct device *dev = xe->drm.dev;
|
||||
struct page **pages;
|
||||
u64 i, npages;
|
||||
int ret;
|
||||
struct scatterlist *sgl;
|
||||
struct page *page;
|
||||
unsigned long i, j;
|
||||
|
||||
npages = xe_npages_in_range(range->start, range->end);
|
||||
pages = kvmalloc_array(npages, sizeof(*pages), GFP_KERNEL);
|
||||
if (!pages)
|
||||
return -ENOMEM;
|
||||
lockdep_assert_held(notifier_sem);
|
||||
|
||||
for (i = 0; i < npages; i++) {
|
||||
pages[i] = hmm_pfn_to_page(range->hmm_pfns[i]);
|
||||
xe_assert(xe, !is_device_private_page(pages[i]));
|
||||
i = 0;
|
||||
for_each_sg(st->sgl, sgl, st->nents, j) {
|
||||
unsigned long hmm_pfn, size;
|
||||
|
||||
hmm_pfn = range->hmm_pfns[i];
|
||||
page = hmm_pfn_to_page(hmm_pfn);
|
||||
xe_assert(xe, !is_device_private_page(page));
|
||||
|
||||
size = 1UL << hmm_pfn_to_map_order(hmm_pfn);
|
||||
size -= page_to_pfn(page) & (size - 1);
|
||||
i += size;
|
||||
|
||||
if (unlikely(j == st->nents - 1)) {
|
||||
if (i > npages)
|
||||
size -= (i - npages);
|
||||
sg_mark_end(sgl);
|
||||
}
|
||||
sg_set_page(sgl, page, size << PAGE_SHIFT, 0);
|
||||
}
|
||||
xe_assert(xe, i == npages);
|
||||
|
||||
ret = sg_alloc_table_from_pages_segment(st, pages, npages, 0, npages << PAGE_SHIFT,
|
||||
xe_sg_segment_size(dev), GFP_KERNEL);
|
||||
if (ret)
|
||||
goto free_pages;
|
||||
|
||||
ret = dma_map_sgtable(dev, st, write ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE,
|
||||
DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_NO_KERNEL_MAPPING);
|
||||
if (ret) {
|
||||
sg_free_table(st);
|
||||
st = NULL;
|
||||
}
|
||||
|
||||
free_pages:
|
||||
kvfree(pages);
|
||||
return ret;
|
||||
return dma_map_sgtable(dev, st, write ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE,
|
||||
DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_NO_KERNEL_MAPPING);
|
||||
}
|
||||
|
||||
/*
|
||||
static void xe_hmm_userptr_set_mapped(struct xe_userptr_vma *uvma)
|
||||
{
|
||||
struct xe_userptr *userptr = &uvma->userptr;
|
||||
struct xe_vm *vm = xe_vma_vm(&uvma->vma);
|
||||
|
||||
lockdep_assert_held_write(&vm->lock);
|
||||
lockdep_assert_held(&vm->userptr.notifier_lock);
|
||||
|
||||
mutex_lock(&userptr->unmap_mutex);
|
||||
xe_assert(vm->xe, !userptr->mapped);
|
||||
userptr->mapped = true;
|
||||
mutex_unlock(&userptr->unmap_mutex);
|
||||
}
|
||||
|
||||
void xe_hmm_userptr_unmap(struct xe_userptr_vma *uvma)
|
||||
{
|
||||
struct xe_userptr *userptr = &uvma->userptr;
|
||||
struct xe_vma *vma = &uvma->vma;
|
||||
bool write = !xe_vma_read_only(vma);
|
||||
struct xe_vm *vm = xe_vma_vm(vma);
|
||||
struct xe_device *xe = vm->xe;
|
||||
|
||||
if (!lockdep_is_held_type(&vm->userptr.notifier_lock, 0) &&
|
||||
!lockdep_is_held_type(&vm->lock, 0) &&
|
||||
!(vma->gpuva.flags & XE_VMA_DESTROYED)) {
|
||||
/* Don't unmap in exec critical section. */
|
||||
xe_vm_assert_held(vm);
|
||||
/* Don't unmap while mapping the sg. */
|
||||
lockdep_assert_held(&vm->lock);
|
||||
}
|
||||
|
||||
mutex_lock(&userptr->unmap_mutex);
|
||||
if (userptr->sg && userptr->mapped)
|
||||
dma_unmap_sgtable(xe->drm.dev, userptr->sg,
|
||||
write ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE, 0);
|
||||
userptr->mapped = false;
|
||||
mutex_unlock(&userptr->unmap_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* xe_hmm_userptr_free_sg() - Free the scatter gather table of userptr
|
||||
*
|
||||
* @uvma: the userptr vma which hold the scatter gather table
|
||||
*
|
||||
* With function xe_userptr_populate_range, we allocate storage of
|
||||
@@ -124,16 +200,9 @@ free_pages:
|
||||
void xe_hmm_userptr_free_sg(struct xe_userptr_vma *uvma)
|
||||
{
|
||||
struct xe_userptr *userptr = &uvma->userptr;
|
||||
struct xe_vma *vma = &uvma->vma;
|
||||
bool write = !xe_vma_read_only(vma);
|
||||
struct xe_vm *vm = xe_vma_vm(vma);
|
||||
struct xe_device *xe = vm->xe;
|
||||
struct device *dev = xe->drm.dev;
|
||||
|
||||
xe_assert(xe, userptr->sg);
|
||||
dma_unmap_sgtable(dev, userptr->sg,
|
||||
write ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE, 0);
|
||||
|
||||
xe_assert(xe_vma_vm(&uvma->vma)->xe, userptr->sg);
|
||||
xe_hmm_userptr_unmap(uvma);
|
||||
sg_free_table(userptr->sg);
|
||||
userptr->sg = NULL;
|
||||
}
|
||||
@@ -166,13 +235,20 @@ int xe_hmm_userptr_populate_range(struct xe_userptr_vma *uvma,
|
||||
{
|
||||
unsigned long timeout =
|
||||
jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
|
||||
unsigned long *pfns, flags = HMM_PFN_REQ_FAULT;
|
||||
unsigned long *pfns;
|
||||
struct xe_userptr *userptr;
|
||||
struct xe_vma *vma = &uvma->vma;
|
||||
u64 userptr_start = xe_vma_userptr(vma);
|
||||
u64 userptr_end = userptr_start + xe_vma_size(vma);
|
||||
struct xe_vm *vm = xe_vma_vm(vma);
|
||||
struct hmm_range hmm_range;
|
||||
struct hmm_range hmm_range = {
|
||||
.pfn_flags_mask = 0, /* ignore pfns */
|
||||
.default_flags = HMM_PFN_REQ_FAULT,
|
||||
.start = userptr_start,
|
||||
.end = userptr_end,
|
||||
.notifier = &uvma->userptr.notifier,
|
||||
.dev_private_owner = vm->xe,
|
||||
};
|
||||
bool write = !xe_vma_read_only(vma);
|
||||
unsigned long notifier_seq;
|
||||
u64 npages;
|
||||
@@ -199,19 +275,14 @@ int xe_hmm_userptr_populate_range(struct xe_userptr_vma *uvma,
|
||||
return -ENOMEM;
|
||||
|
||||
if (write)
|
||||
flags |= HMM_PFN_REQ_WRITE;
|
||||
hmm_range.default_flags |= HMM_PFN_REQ_WRITE;
|
||||
|
||||
if (!mmget_not_zero(userptr->notifier.mm)) {
|
||||
ret = -EFAULT;
|
||||
goto free_pfns;
|
||||
}
|
||||
|
||||
hmm_range.default_flags = flags;
|
||||
hmm_range.hmm_pfns = pfns;
|
||||
hmm_range.notifier = &userptr->notifier;
|
||||
hmm_range.start = userptr_start;
|
||||
hmm_range.end = userptr_end;
|
||||
hmm_range.dev_private_owner = vm->xe;
|
||||
|
||||
while (true) {
|
||||
hmm_range.notifier_seq = mmu_interval_read_begin(&userptr->notifier);
|
||||
@@ -238,16 +309,37 @@ int xe_hmm_userptr_populate_range(struct xe_userptr_vma *uvma,
|
||||
if (ret)
|
||||
goto free_pfns;
|
||||
|
||||
ret = xe_build_sg(vm->xe, &hmm_range, &userptr->sgt, write);
|
||||
ret = xe_alloc_sg(vm->xe, &userptr->sgt, &hmm_range, &vm->userptr.notifier_lock);
|
||||
if (ret)
|
||||
goto free_pfns;
|
||||
|
||||
ret = down_read_interruptible(&vm->userptr.notifier_lock);
|
||||
if (ret)
|
||||
goto free_st;
|
||||
|
||||
if (mmu_interval_read_retry(hmm_range.notifier, hmm_range.notifier_seq)) {
|
||||
ret = -EAGAIN;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = xe_build_sg(vm->xe, &hmm_range, &userptr->sgt,
|
||||
&vm->userptr.notifier_lock, write);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
xe_mark_range_accessed(&hmm_range, write);
|
||||
userptr->sg = &userptr->sgt;
|
||||
xe_hmm_userptr_set_mapped(uvma);
|
||||
userptr->notifier_seq = hmm_range.notifier_seq;
|
||||
up_read(&vm->userptr.notifier_lock);
|
||||
kvfree(pfns);
|
||||
return 0;
|
||||
|
||||
out_unlock:
|
||||
up_read(&vm->userptr.notifier_lock);
|
||||
free_st:
|
||||
sg_free_table(&userptr->sgt);
|
||||
free_pfns:
|
||||
kvfree(pfns);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,16 @@
|
||||
* Copyright © 2024 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef _XE_HMM_H_
|
||||
#define _XE_HMM_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct xe_userptr_vma;
|
||||
|
||||
int xe_hmm_userptr_populate_range(struct xe_userptr_vma *uvma, bool is_mm_mmap_locked);
|
||||
|
||||
void xe_hmm_userptr_free_sg(struct xe_userptr_vma *uvma);
|
||||
|
||||
void xe_hmm_userptr_unmap(struct xe_userptr_vma *uvma);
|
||||
#endif
|
||||
|
||||
+49
-47
@@ -28,6 +28,8 @@ struct xe_pt_dir {
|
||||
struct xe_pt pt;
|
||||
/** @children: Array of page-table child nodes */
|
||||
struct xe_ptw *children[XE_PDES];
|
||||
/** @staging: Array of page-table staging nodes */
|
||||
struct xe_ptw *staging[XE_PDES];
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_XE_DEBUG_VM)
|
||||
@@ -48,9 +50,10 @@ static struct xe_pt_dir *as_xe_pt_dir(struct xe_pt *pt)
|
||||
return container_of(pt, struct xe_pt_dir, pt);
|
||||
}
|
||||
|
||||
static struct xe_pt *xe_pt_entry(struct xe_pt_dir *pt_dir, unsigned int index)
|
||||
static struct xe_pt *
|
||||
xe_pt_entry_staging(struct xe_pt_dir *pt_dir, unsigned int index)
|
||||
{
|
||||
return container_of(pt_dir->children[index], struct xe_pt, base);
|
||||
return container_of(pt_dir->staging[index], struct xe_pt, base);
|
||||
}
|
||||
|
||||
static u64 __xe_pt_empty_pte(struct xe_tile *tile, struct xe_vm *vm,
|
||||
@@ -125,6 +128,7 @@ struct xe_pt *xe_pt_create(struct xe_vm *vm, struct xe_tile *tile,
|
||||
}
|
||||
pt->bo = bo;
|
||||
pt->base.children = level ? as_xe_pt_dir(pt)->children : NULL;
|
||||
pt->base.staging = level ? as_xe_pt_dir(pt)->staging : NULL;
|
||||
|
||||
if (vm->xef)
|
||||
xe_drm_client_add_bo(vm->xef->client, pt->bo);
|
||||
@@ -206,8 +210,8 @@ void xe_pt_destroy(struct xe_pt *pt, u32 flags, struct llist_head *deferred)
|
||||
struct xe_pt_dir *pt_dir = as_xe_pt_dir(pt);
|
||||
|
||||
for (i = 0; i < XE_PDES; i++) {
|
||||
if (xe_pt_entry(pt_dir, i))
|
||||
xe_pt_destroy(xe_pt_entry(pt_dir, i), flags,
|
||||
if (xe_pt_entry_staging(pt_dir, i))
|
||||
xe_pt_destroy(xe_pt_entry_staging(pt_dir, i), flags,
|
||||
deferred);
|
||||
}
|
||||
}
|
||||
@@ -376,8 +380,10 @@ xe_pt_insert_entry(struct xe_pt_stage_bind_walk *xe_walk, struct xe_pt *parent,
|
||||
/* Continue building a non-connected subtree. */
|
||||
struct iosys_map *map = &parent->bo->vmap;
|
||||
|
||||
if (unlikely(xe_child))
|
||||
if (unlikely(xe_child)) {
|
||||
parent->base.children[offset] = &xe_child->base;
|
||||
parent->base.staging[offset] = &xe_child->base;
|
||||
}
|
||||
|
||||
xe_pt_write(xe_walk->vm->xe, map, offset, pte);
|
||||
parent->num_live++;
|
||||
@@ -614,6 +620,7 @@ xe_pt_stage_bind(struct xe_tile *tile, struct xe_vma *vma,
|
||||
.ops = &xe_pt_stage_bind_ops,
|
||||
.shifts = xe_normal_pt_shifts,
|
||||
.max_level = XE_PT_HIGHEST_LEVEL,
|
||||
.staging = true,
|
||||
},
|
||||
.vm = xe_vma_vm(vma),
|
||||
.tile = tile,
|
||||
@@ -873,7 +880,7 @@ static void xe_pt_cancel_bind(struct xe_vma *vma,
|
||||
}
|
||||
}
|
||||
|
||||
static void xe_pt_commit_locks_assert(struct xe_vma *vma)
|
||||
static void xe_pt_commit_prepare_locks_assert(struct xe_vma *vma)
|
||||
{
|
||||
struct xe_vm *vm = xe_vma_vm(vma);
|
||||
|
||||
@@ -885,6 +892,16 @@ static void xe_pt_commit_locks_assert(struct xe_vma *vma)
|
||||
xe_vm_assert_held(vm);
|
||||
}
|
||||
|
||||
static void xe_pt_commit_locks_assert(struct xe_vma *vma)
|
||||
{
|
||||
struct xe_vm *vm = xe_vma_vm(vma);
|
||||
|
||||
xe_pt_commit_prepare_locks_assert(vma);
|
||||
|
||||
if (xe_vma_is_userptr(vma))
|
||||
lockdep_assert_held_read(&vm->userptr.notifier_lock);
|
||||
}
|
||||
|
||||
static void xe_pt_commit(struct xe_vma *vma,
|
||||
struct xe_vm_pgtable_update *entries,
|
||||
u32 num_entries, struct llist_head *deferred)
|
||||
@@ -895,13 +912,17 @@ static void xe_pt_commit(struct xe_vma *vma,
|
||||
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
struct xe_pt *pt = entries[i].pt;
|
||||
struct xe_pt_dir *pt_dir;
|
||||
|
||||
if (!pt->level)
|
||||
continue;
|
||||
|
||||
pt_dir = as_xe_pt_dir(pt);
|
||||
for (j = 0; j < entries[i].qwords; j++) {
|
||||
struct xe_pt *oldpte = entries[i].pt_entries[j].pt;
|
||||
int j_ = j + entries[i].ofs;
|
||||
|
||||
pt_dir->children[j_] = pt_dir->staging[j_];
|
||||
xe_pt_destroy(oldpte, xe_vma_vm(vma)->flags, deferred);
|
||||
}
|
||||
}
|
||||
@@ -913,7 +934,7 @@ static void xe_pt_abort_bind(struct xe_vma *vma,
|
||||
{
|
||||
int i, j;
|
||||
|
||||
xe_pt_commit_locks_assert(vma);
|
||||
xe_pt_commit_prepare_locks_assert(vma);
|
||||
|
||||
for (i = num_entries - 1; i >= 0; --i) {
|
||||
struct xe_pt *pt = entries[i].pt;
|
||||
@@ -928,10 +949,10 @@ static void xe_pt_abort_bind(struct xe_vma *vma,
|
||||
pt_dir = as_xe_pt_dir(pt);
|
||||
for (j = 0; j < entries[i].qwords; j++) {
|
||||
u32 j_ = j + entries[i].ofs;
|
||||
struct xe_pt *newpte = xe_pt_entry(pt_dir, j_);
|
||||
struct xe_pt *newpte = xe_pt_entry_staging(pt_dir, j_);
|
||||
struct xe_pt *oldpte = entries[i].pt_entries[j].pt;
|
||||
|
||||
pt_dir->children[j_] = oldpte ? &oldpte->base : 0;
|
||||
pt_dir->staging[j_] = oldpte ? &oldpte->base : 0;
|
||||
xe_pt_destroy(newpte, xe_vma_vm(vma)->flags, NULL);
|
||||
}
|
||||
}
|
||||
@@ -943,7 +964,7 @@ static void xe_pt_commit_prepare_bind(struct xe_vma *vma,
|
||||
{
|
||||
u32 i, j;
|
||||
|
||||
xe_pt_commit_locks_assert(vma);
|
||||
xe_pt_commit_prepare_locks_assert(vma);
|
||||
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
struct xe_pt *pt = entries[i].pt;
|
||||
@@ -961,10 +982,10 @@ static void xe_pt_commit_prepare_bind(struct xe_vma *vma,
|
||||
struct xe_pt *newpte = entries[i].pt_entries[j].pt;
|
||||
struct xe_pt *oldpte = NULL;
|
||||
|
||||
if (xe_pt_entry(pt_dir, j_))
|
||||
oldpte = xe_pt_entry(pt_dir, j_);
|
||||
if (xe_pt_entry_staging(pt_dir, j_))
|
||||
oldpte = xe_pt_entry_staging(pt_dir, j_);
|
||||
|
||||
pt_dir->children[j_] = &newpte->base;
|
||||
pt_dir->staging[j_] = &newpte->base;
|
||||
entries[i].pt_entries[j].pt = oldpte;
|
||||
}
|
||||
}
|
||||
@@ -1213,42 +1234,22 @@ static int vma_check_userptr(struct xe_vm *vm, struct xe_vma *vma,
|
||||
return 0;
|
||||
|
||||
uvma = to_userptr_vma(vma);
|
||||
if (xe_pt_userptr_inject_eagain(uvma))
|
||||
xe_vma_userptr_force_invalidate(uvma);
|
||||
|
||||
notifier_seq = uvma->userptr.notifier_seq;
|
||||
|
||||
if (uvma->userptr.initial_bind && !xe_vm_in_fault_mode(vm))
|
||||
return 0;
|
||||
|
||||
if (!mmu_interval_read_retry(&uvma->userptr.notifier,
|
||||
notifier_seq) &&
|
||||
!xe_pt_userptr_inject_eagain(uvma))
|
||||
notifier_seq))
|
||||
return 0;
|
||||
|
||||
if (xe_vm_in_fault_mode(vm)) {
|
||||
if (xe_vm_in_fault_mode(vm))
|
||||
return -EAGAIN;
|
||||
} else {
|
||||
spin_lock(&vm->userptr.invalidated_lock);
|
||||
list_move_tail(&uvma->userptr.invalidate_link,
|
||||
&vm->userptr.invalidated);
|
||||
spin_unlock(&vm->userptr.invalidated_lock);
|
||||
|
||||
if (xe_vm_in_preempt_fence_mode(vm)) {
|
||||
struct dma_resv_iter cursor;
|
||||
struct dma_fence *fence;
|
||||
long err;
|
||||
|
||||
dma_resv_iter_begin(&cursor, xe_vm_resv(vm),
|
||||
DMA_RESV_USAGE_BOOKKEEP);
|
||||
dma_resv_for_each_fence_unlocked(&cursor, fence)
|
||||
dma_fence_enable_sw_signaling(fence);
|
||||
dma_resv_iter_end(&cursor);
|
||||
|
||||
err = dma_resv_wait_timeout(xe_vm_resv(vm),
|
||||
DMA_RESV_USAGE_BOOKKEEP,
|
||||
false, MAX_SCHEDULE_TIMEOUT);
|
||||
XE_WARN_ON(err <= 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Just continue the operation since exec or rebind worker
|
||||
* will take care of rebinding.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1514,6 +1515,7 @@ static unsigned int xe_pt_stage_unbind(struct xe_tile *tile, struct xe_vma *vma,
|
||||
.ops = &xe_pt_stage_unbind_ops,
|
||||
.shifts = xe_normal_pt_shifts,
|
||||
.max_level = XE_PT_HIGHEST_LEVEL,
|
||||
.staging = true,
|
||||
},
|
||||
.tile = tile,
|
||||
.modified_start = xe_vma_start(vma),
|
||||
@@ -1555,7 +1557,7 @@ static void xe_pt_abort_unbind(struct xe_vma *vma,
|
||||
{
|
||||
int i, j;
|
||||
|
||||
xe_pt_commit_locks_assert(vma);
|
||||
xe_pt_commit_prepare_locks_assert(vma);
|
||||
|
||||
for (i = num_entries - 1; i >= 0; --i) {
|
||||
struct xe_vm_pgtable_update *entry = &entries[i];
|
||||
@@ -1568,7 +1570,7 @@ static void xe_pt_abort_unbind(struct xe_vma *vma,
|
||||
continue;
|
||||
|
||||
for (j = entry->ofs; j < entry->ofs + entry->qwords; j++)
|
||||
pt_dir->children[j] =
|
||||
pt_dir->staging[j] =
|
||||
entries[i].pt_entries[j - entry->ofs].pt ?
|
||||
&entries[i].pt_entries[j - entry->ofs].pt->base : NULL;
|
||||
}
|
||||
@@ -1581,7 +1583,7 @@ xe_pt_commit_prepare_unbind(struct xe_vma *vma,
|
||||
{
|
||||
int i, j;
|
||||
|
||||
xe_pt_commit_locks_assert(vma);
|
||||
xe_pt_commit_prepare_locks_assert(vma);
|
||||
|
||||
for (i = 0; i < num_entries; ++i) {
|
||||
struct xe_vm_pgtable_update *entry = &entries[i];
|
||||
@@ -1595,8 +1597,8 @@ xe_pt_commit_prepare_unbind(struct xe_vma *vma,
|
||||
pt_dir = as_xe_pt_dir(pt);
|
||||
for (j = entry->ofs; j < entry->ofs + entry->qwords; j++) {
|
||||
entry->pt_entries[j - entry->ofs].pt =
|
||||
xe_pt_entry(pt_dir, j);
|
||||
pt_dir->children[j] = NULL;
|
||||
xe_pt_entry_staging(pt_dir, j);
|
||||
pt_dir->staging[j] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,8 @@ int xe_pt_walk_range(struct xe_ptw *parent, unsigned int level,
|
||||
u64 addr, u64 end, struct xe_pt_walk *walk)
|
||||
{
|
||||
pgoff_t offset = xe_pt_offset(addr, level, walk);
|
||||
struct xe_ptw **entries = parent->children ? parent->children : NULL;
|
||||
struct xe_ptw **entries = walk->staging ? (parent->staging ?: NULL) :
|
||||
(parent->children ?: NULL);
|
||||
const struct xe_pt_walk_ops *ops = walk->ops;
|
||||
enum page_walk_action action;
|
||||
struct xe_ptw *child;
|
||||
|
||||
@@ -11,12 +11,14 @@
|
||||
/**
|
||||
* struct xe_ptw - base class for driver pagetable subclassing.
|
||||
* @children: Pointer to an array of children if any.
|
||||
* @staging: Pointer to an array of staging if any.
|
||||
*
|
||||
* Drivers could subclass this, and if it's a page-directory, typically
|
||||
* embed an array of xe_ptw pointers.
|
||||
*/
|
||||
struct xe_ptw {
|
||||
struct xe_ptw **children;
|
||||
struct xe_ptw **staging;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -41,6 +43,8 @@ struct xe_pt_walk {
|
||||
* as shared pagetables.
|
||||
*/
|
||||
bool shared_pt_mode;
|
||||
/** @staging: Walk staging PT structure */
|
||||
bool staging;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+70
-30
@@ -579,51 +579,26 @@ out_unlock_outer:
|
||||
trace_xe_vm_rebind_worker_exit(vm);
|
||||
}
|
||||
|
||||
static bool vma_userptr_invalidate(struct mmu_interval_notifier *mni,
|
||||
const struct mmu_notifier_range *range,
|
||||
unsigned long cur_seq)
|
||||
static void __vma_userptr_invalidate(struct xe_vm *vm, struct xe_userptr_vma *uvma)
|
||||
{
|
||||
struct xe_userptr *userptr = container_of(mni, typeof(*userptr), notifier);
|
||||
struct xe_userptr_vma *uvma = container_of(userptr, typeof(*uvma), userptr);
|
||||
struct xe_userptr *userptr = &uvma->userptr;
|
||||
struct xe_vma *vma = &uvma->vma;
|
||||
struct xe_vm *vm = xe_vma_vm(vma);
|
||||
struct dma_resv_iter cursor;
|
||||
struct dma_fence *fence;
|
||||
long err;
|
||||
|
||||
xe_assert(vm->xe, xe_vma_is_userptr(vma));
|
||||
trace_xe_vma_userptr_invalidate(vma);
|
||||
|
||||
if (!mmu_notifier_range_blockable(range))
|
||||
return false;
|
||||
|
||||
vm_dbg(&xe_vma_vm(vma)->xe->drm,
|
||||
"NOTIFIER: addr=0x%016llx, range=0x%016llx",
|
||||
xe_vma_start(vma), xe_vma_size(vma));
|
||||
|
||||
down_write(&vm->userptr.notifier_lock);
|
||||
mmu_interval_set_seq(mni, cur_seq);
|
||||
|
||||
/* No need to stop gpu access if the userptr is not yet bound. */
|
||||
if (!userptr->initial_bind) {
|
||||
up_write(&vm->userptr.notifier_lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell exec and rebind worker they need to repin and rebind this
|
||||
* userptr.
|
||||
*/
|
||||
if (!xe_vm_in_fault_mode(vm) &&
|
||||
!(vma->gpuva.flags & XE_VMA_DESTROYED) && vma->tile_present) {
|
||||
!(vma->gpuva.flags & XE_VMA_DESTROYED)) {
|
||||
spin_lock(&vm->userptr.invalidated_lock);
|
||||
list_move_tail(&userptr->invalidate_link,
|
||||
&vm->userptr.invalidated);
|
||||
spin_unlock(&vm->userptr.invalidated_lock);
|
||||
}
|
||||
|
||||
up_write(&vm->userptr.notifier_lock);
|
||||
|
||||
/*
|
||||
* Preempt fences turn into schedule disables, pipeline these.
|
||||
* Note that even in fault mode, we need to wait for binds and
|
||||
@@ -641,11 +616,37 @@ static bool vma_userptr_invalidate(struct mmu_interval_notifier *mni,
|
||||
false, MAX_SCHEDULE_TIMEOUT);
|
||||
XE_WARN_ON(err <= 0);
|
||||
|
||||
if (xe_vm_in_fault_mode(vm)) {
|
||||
if (xe_vm_in_fault_mode(vm) && userptr->initial_bind) {
|
||||
err = xe_vm_invalidate_vma(vma);
|
||||
XE_WARN_ON(err);
|
||||
}
|
||||
|
||||
xe_hmm_userptr_unmap(uvma);
|
||||
}
|
||||
|
||||
static bool vma_userptr_invalidate(struct mmu_interval_notifier *mni,
|
||||
const struct mmu_notifier_range *range,
|
||||
unsigned long cur_seq)
|
||||
{
|
||||
struct xe_userptr_vma *uvma = container_of(mni, typeof(*uvma), userptr.notifier);
|
||||
struct xe_vma *vma = &uvma->vma;
|
||||
struct xe_vm *vm = xe_vma_vm(vma);
|
||||
|
||||
xe_assert(vm->xe, xe_vma_is_userptr(vma));
|
||||
trace_xe_vma_userptr_invalidate(vma);
|
||||
|
||||
if (!mmu_notifier_range_blockable(range))
|
||||
return false;
|
||||
|
||||
vm_dbg(&xe_vma_vm(vma)->xe->drm,
|
||||
"NOTIFIER: addr=0x%016llx, range=0x%016llx",
|
||||
xe_vma_start(vma), xe_vma_size(vma));
|
||||
|
||||
down_write(&vm->userptr.notifier_lock);
|
||||
mmu_interval_set_seq(mni, cur_seq);
|
||||
|
||||
__vma_userptr_invalidate(vm, uvma);
|
||||
up_write(&vm->userptr.notifier_lock);
|
||||
trace_xe_vma_userptr_invalidate_complete(vma);
|
||||
|
||||
return true;
|
||||
@@ -655,6 +656,34 @@ static const struct mmu_interval_notifier_ops vma_userptr_notifier_ops = {
|
||||
.invalidate = vma_userptr_invalidate,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_XE_USERPTR_INVAL_INJECT)
|
||||
/**
|
||||
* xe_vma_userptr_force_invalidate() - force invalidate a userptr
|
||||
* @uvma: The userptr vma to invalidate
|
||||
*
|
||||
* Perform a forced userptr invalidation for testing purposes.
|
||||
*/
|
||||
void xe_vma_userptr_force_invalidate(struct xe_userptr_vma *uvma)
|
||||
{
|
||||
struct xe_vm *vm = xe_vma_vm(&uvma->vma);
|
||||
|
||||
/* Protect against concurrent userptr pinning */
|
||||
lockdep_assert_held(&vm->lock);
|
||||
/* Protect against concurrent notifiers */
|
||||
lockdep_assert_held(&vm->userptr.notifier_lock);
|
||||
/*
|
||||
* Protect against concurrent instances of this function and
|
||||
* the critical exec sections
|
||||
*/
|
||||
xe_vm_assert_held(vm);
|
||||
|
||||
if (!mmu_interval_read_retry(&uvma->userptr.notifier,
|
||||
uvma->userptr.notifier_seq))
|
||||
uvma->userptr.notifier_seq -= 2;
|
||||
__vma_userptr_invalidate(vm, uvma);
|
||||
}
|
||||
#endif
|
||||
|
||||
int xe_vm_userptr_pin(struct xe_vm *vm)
|
||||
{
|
||||
struct xe_userptr_vma *uvma, *next;
|
||||
@@ -1012,6 +1041,7 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm,
|
||||
INIT_LIST_HEAD(&userptr->invalidate_link);
|
||||
INIT_LIST_HEAD(&userptr->repin_link);
|
||||
vma->gpuva.gem.offset = bo_offset_or_userptr;
|
||||
mutex_init(&userptr->unmap_mutex);
|
||||
|
||||
err = mmu_interval_notifier_insert(&userptr->notifier,
|
||||
current->mm,
|
||||
@@ -1053,6 +1083,7 @@ static void xe_vma_destroy_late(struct xe_vma *vma)
|
||||
* them anymore
|
||||
*/
|
||||
mmu_interval_notifier_remove(&userptr->notifier);
|
||||
mutex_destroy(&userptr->unmap_mutex);
|
||||
xe_vm_put(vm);
|
||||
} else if (xe_vma_is_null(vma)) {
|
||||
xe_vm_put(vm);
|
||||
@@ -2286,8 +2317,17 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
|
||||
break;
|
||||
}
|
||||
case DRM_GPUVA_OP_UNMAP:
|
||||
xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
|
||||
break;
|
||||
case DRM_GPUVA_OP_PREFETCH:
|
||||
/* FIXME: Need to skip some prefetch ops */
|
||||
vma = gpuva_to_vma(op->base.prefetch.va);
|
||||
|
||||
if (xe_vma_is_userptr(vma)) {
|
||||
err = xe_vma_userptr_pin_pages(to_userptr_vma(vma));
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
xe_vma_ops_incr_pt_update_ops(vops, op->tile_mask);
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -274,9 +274,17 @@ static inline void vm_dbg(const struct drm_device *dev,
|
||||
const char *format, ...)
|
||||
{ /* noop */ }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct xe_vm_snapshot *xe_vm_snapshot_capture(struct xe_vm *vm);
|
||||
void xe_vm_snapshot_capture_delayed(struct xe_vm_snapshot *snap);
|
||||
void xe_vm_snapshot_print(struct xe_vm_snapshot *snap, struct drm_printer *p);
|
||||
void xe_vm_snapshot_free(struct xe_vm_snapshot *snap);
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_XE_USERPTR_INVAL_INJECT)
|
||||
void xe_vma_userptr_force_invalidate(struct xe_userptr_vma *uvma);
|
||||
#else
|
||||
static inline void xe_vma_userptr_force_invalidate(struct xe_userptr_vma *uvma)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -59,12 +59,16 @@ struct xe_userptr {
|
||||
struct sg_table *sg;
|
||||
/** @notifier_seq: notifier sequence number */
|
||||
unsigned long notifier_seq;
|
||||
/** @unmap_mutex: Mutex protecting dma-unmapping */
|
||||
struct mutex unmap_mutex;
|
||||
/**
|
||||
* @initial_bind: user pointer has been bound at least once.
|
||||
* write: vm->userptr.notifier_lock in read mode and vm->resv held.
|
||||
* read: vm->userptr.notifier_lock in write mode or vm->resv held.
|
||||
*/
|
||||
bool initial_bind;
|
||||
/** @mapped: Whether the @sgt sg-table is dma-mapped. Protected by @unmap_mutex. */
|
||||
bool mapped;
|
||||
#if IS_ENABLED(CONFIG_DRM_XE_USERPTR_INVAL_INJECT)
|
||||
u32 divisor;
|
||||
#endif
|
||||
@@ -227,8 +231,8 @@ struct xe_vm {
|
||||
* up for revalidation. Protected from access with the
|
||||
* @invalidated_lock. Removing items from the list
|
||||
* additionally requires @lock in write mode, and adding
|
||||
* items to the list requires the @userptr.notifer_lock in
|
||||
* write mode.
|
||||
* items to the list requires either the @userptr.notifer_lock in
|
||||
* write mode, OR @lock in write mode.
|
||||
*/
|
||||
struct list_head invalidated;
|
||||
} userptr;
|
||||
|
||||
@@ -378,6 +378,12 @@ static bool apple_is_non_apple_keyboard(struct hid_device *hdev)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool apple_is_omoton_kb066(struct hid_device *hdev)
|
||||
{
|
||||
return hdev->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI &&
|
||||
strcmp(hdev->name, "Bluetooth Keyboard") == 0;
|
||||
}
|
||||
|
||||
static inline void apple_setup_key_translation(struct input_dev *input,
|
||||
const struct apple_key_translation *table)
|
||||
{
|
||||
@@ -546,9 +552,6 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
|
||||
}
|
||||
}
|
||||
|
||||
if (usage->hid == 0xc0301) /* Omoton KB066 quirk */
|
||||
code = KEY_F6;
|
||||
|
||||
if (usage->code != code) {
|
||||
input_event_with_scancode(input, usage->type, code, usage->hid, value);
|
||||
|
||||
@@ -728,7 +731,7 @@ static int apple_input_configured(struct hid_device *hdev,
|
||||
{
|
||||
struct apple_sc *asc = hid_get_drvdata(hdev);
|
||||
|
||||
if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) {
|
||||
if (((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) || apple_is_omoton_kb066(hdev)) {
|
||||
hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n");
|
||||
asc->quirks &= ~APPLE_HAS_FN;
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ static int appleir_raw_event(struct hid_device *hid, struct hid_report *report,
|
||||
static const u8 flatbattery[] = { 0x25, 0x87, 0xe0 };
|
||||
unsigned long flags;
|
||||
|
||||
if (len != 5)
|
||||
if (len != 5 || !(hid->claimed & HID_CLAIMED_INPUT))
|
||||
goto out;
|
||||
|
||||
if (!memcmp(data, keydown, sizeof(keydown))) {
|
||||
|
||||
@@ -71,11 +71,9 @@
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/hid.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/workqueue.h>
|
||||
@@ -120,6 +118,12 @@ enum {
|
||||
CORSAIR_VOID_BATTERY_CHARGING = 5,
|
||||
};
|
||||
|
||||
enum {
|
||||
CORSAIR_VOID_ADD_BATTERY = 0,
|
||||
CORSAIR_VOID_REMOVE_BATTERY = 1,
|
||||
CORSAIR_VOID_UPDATE_BATTERY = 2,
|
||||
};
|
||||
|
||||
static enum power_supply_property corsair_void_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
@@ -155,12 +159,12 @@ struct corsair_void_drvdata {
|
||||
|
||||
struct power_supply *battery;
|
||||
struct power_supply_desc battery_desc;
|
||||
struct mutex battery_mutex;
|
||||
|
||||
struct delayed_work delayed_status_work;
|
||||
struct delayed_work delayed_firmware_work;
|
||||
struct work_struct battery_remove_work;
|
||||
struct work_struct battery_add_work;
|
||||
|
||||
unsigned long battery_work_flags;
|
||||
struct work_struct battery_work;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -260,11 +264,9 @@ success:
|
||||
|
||||
/* Inform power supply if battery values changed */
|
||||
if (memcmp(&orig_battery_data, battery_data, sizeof(*battery_data))) {
|
||||
scoped_guard(mutex, &drvdata->battery_mutex) {
|
||||
if (drvdata->battery) {
|
||||
power_supply_changed(drvdata->battery);
|
||||
}
|
||||
}
|
||||
set_bit(CORSAIR_VOID_UPDATE_BATTERY,
|
||||
&drvdata->battery_work_flags);
|
||||
schedule_work(&drvdata->battery_work);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,29 +538,11 @@ static void corsair_void_firmware_work_handler(struct work_struct *work)
|
||||
|
||||
}
|
||||
|
||||
static void corsair_void_battery_remove_work_handler(struct work_struct *work)
|
||||
static void corsair_void_add_battery(struct corsair_void_drvdata *drvdata)
|
||||
{
|
||||
struct corsair_void_drvdata *drvdata;
|
||||
|
||||
drvdata = container_of(work, struct corsair_void_drvdata,
|
||||
battery_remove_work);
|
||||
scoped_guard(mutex, &drvdata->battery_mutex) {
|
||||
if (drvdata->battery) {
|
||||
power_supply_unregister(drvdata->battery);
|
||||
drvdata->battery = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void corsair_void_battery_add_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct corsair_void_drvdata *drvdata;
|
||||
struct power_supply_config psy_cfg = {};
|
||||
struct power_supply *new_supply;
|
||||
|
||||
drvdata = container_of(work, struct corsair_void_drvdata,
|
||||
battery_add_work);
|
||||
guard(mutex)(&drvdata->battery_mutex);
|
||||
if (drvdata->battery)
|
||||
return;
|
||||
|
||||
@@ -583,16 +567,42 @@ static void corsair_void_battery_add_work_handler(struct work_struct *work)
|
||||
drvdata->battery = new_supply;
|
||||
}
|
||||
|
||||
static void corsair_void_battery_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct corsair_void_drvdata *drvdata = container_of(work,
|
||||
struct corsair_void_drvdata, battery_work);
|
||||
|
||||
bool add_battery = test_and_clear_bit(CORSAIR_VOID_ADD_BATTERY,
|
||||
&drvdata->battery_work_flags);
|
||||
bool remove_battery = test_and_clear_bit(CORSAIR_VOID_REMOVE_BATTERY,
|
||||
&drvdata->battery_work_flags);
|
||||
bool update_battery = test_and_clear_bit(CORSAIR_VOID_UPDATE_BATTERY,
|
||||
&drvdata->battery_work_flags);
|
||||
|
||||
if (add_battery && !remove_battery) {
|
||||
corsair_void_add_battery(drvdata);
|
||||
} else if (remove_battery && !add_battery && drvdata->battery) {
|
||||
power_supply_unregister(drvdata->battery);
|
||||
drvdata->battery = NULL;
|
||||
}
|
||||
|
||||
if (update_battery && drvdata->battery)
|
||||
power_supply_changed(drvdata->battery);
|
||||
|
||||
}
|
||||
|
||||
static void corsair_void_headset_connected(struct corsair_void_drvdata *drvdata)
|
||||
{
|
||||
schedule_work(&drvdata->battery_add_work);
|
||||
set_bit(CORSAIR_VOID_ADD_BATTERY, &drvdata->battery_work_flags);
|
||||
schedule_work(&drvdata->battery_work);
|
||||
schedule_delayed_work(&drvdata->delayed_firmware_work,
|
||||
msecs_to_jiffies(100));
|
||||
}
|
||||
|
||||
static void corsair_void_headset_disconnected(struct corsair_void_drvdata *drvdata)
|
||||
{
|
||||
schedule_work(&drvdata->battery_remove_work);
|
||||
set_bit(CORSAIR_VOID_REMOVE_BATTERY, &drvdata->battery_work_flags);
|
||||
schedule_work(&drvdata->battery_work);
|
||||
|
||||
corsair_void_set_unknown_wireless_data(drvdata);
|
||||
corsair_void_set_unknown_batt(drvdata);
|
||||
@@ -678,13 +688,7 @@ static int corsair_void_probe(struct hid_device *hid_dev,
|
||||
drvdata->battery_desc.get_property = corsair_void_battery_get_property;
|
||||
|
||||
drvdata->battery = NULL;
|
||||
INIT_WORK(&drvdata->battery_remove_work,
|
||||
corsair_void_battery_remove_work_handler);
|
||||
INIT_WORK(&drvdata->battery_add_work,
|
||||
corsair_void_battery_add_work_handler);
|
||||
ret = devm_mutex_init(drvdata->dev, &drvdata->battery_mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
INIT_WORK(&drvdata->battery_work, corsair_void_battery_work_handler);
|
||||
|
||||
ret = sysfs_create_group(&hid_dev->dev.kobj, &corsair_void_attr_group);
|
||||
if (ret)
|
||||
@@ -721,8 +725,7 @@ static void corsair_void_remove(struct hid_device *hid_dev)
|
||||
struct corsair_void_drvdata *drvdata = hid_get_drvdata(hid_dev);
|
||||
|
||||
hid_hw_stop(hid_dev);
|
||||
cancel_work_sync(&drvdata->battery_remove_work);
|
||||
cancel_work_sync(&drvdata->battery_add_work);
|
||||
cancel_work_sync(&drvdata->battery_work);
|
||||
if (drvdata->battery)
|
||||
power_supply_unregister(drvdata->battery);
|
||||
|
||||
|
||||
@@ -3450,7 +3450,7 @@ static const char *keys[KEY_MAX + 1] = {
|
||||
[KEY_MACRO_RECORD_START] = "MacroRecordStart",
|
||||
[KEY_MACRO_RECORD_STOP] = "MacroRecordStop",
|
||||
[KEY_MARK_WAYPOINT] = "MarkWayPoint", [KEY_MEDIA_REPEAT] = "MediaRepeat",
|
||||
[KEY_MEDIA_TOP_MENU] = "MediaTopMenu", [KEY_MESSENGER] = "Messanger",
|
||||
[KEY_MEDIA_TOP_MENU] = "MediaTopMenu", [KEY_MESSENGER] = "Messenger",
|
||||
[KEY_NAV_CHART] = "NavChar", [KEY_NAV_INFO] = "NavInfo",
|
||||
[KEY_NEWS] = "News", [KEY_NEXT_ELEMENT] = "NextElement",
|
||||
[KEY_NEXT_FAVORITE] = "NextFavorite", [KEY_NOTIFICATION_CENTER] = "NotificationCenter",
|
||||
|
||||
@@ -268,11 +268,13 @@ static void cbas_ec_remove(struct platform_device *pdev)
|
||||
mutex_unlock(&cbas_ec_reglock);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static const struct acpi_device_id cbas_ec_acpi_ids[] = {
|
||||
{ "GOOG000B", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, cbas_ec_acpi_ids);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id cbas_ec_of_match[] = {
|
||||
|
||||
@@ -457,13 +457,13 @@ static const struct joycon_ctlr_button_mapping snescon_button_mappings[] = {
|
||||
};
|
||||
|
||||
static const struct joycon_ctlr_button_mapping gencon_button_mappings[] = {
|
||||
{ BTN_A, JC_BTN_A, },
|
||||
{ BTN_B, JC_BTN_B, },
|
||||
{ BTN_C, JC_BTN_R, },
|
||||
{ BTN_X, JC_BTN_X, }, /* MD/GEN 6B Only */
|
||||
{ BTN_Y, JC_BTN_Y, }, /* MD/GEN 6B Only */
|
||||
{ BTN_Z, JC_BTN_L, }, /* MD/GEN 6B Only */
|
||||
{ BTN_SELECT, JC_BTN_ZR, },
|
||||
{ BTN_WEST, JC_BTN_A, }, /* A */
|
||||
{ BTN_SOUTH, JC_BTN_B, }, /* B */
|
||||
{ BTN_EAST, JC_BTN_R, }, /* C */
|
||||
{ BTN_TL, JC_BTN_X, }, /* X MD/GEN 6B Only */
|
||||
{ BTN_NORTH, JC_BTN_Y, }, /* Y MD/GEN 6B Only */
|
||||
{ BTN_TR, JC_BTN_L, }, /* Z MD/GEN 6B Only */
|
||||
{ BTN_SELECT, JC_BTN_ZR, }, /* Mode */
|
||||
{ BTN_START, JC_BTN_PLUS, },
|
||||
{ BTN_MODE, JC_BTN_HOME, },
|
||||
{ BTN_Z, JC_BTN_CAP, },
|
||||
|
||||
@@ -1327,11 +1327,11 @@ static void steam_remove(struct hid_device *hdev)
|
||||
return;
|
||||
}
|
||||
|
||||
hid_destroy_device(steam->client_hdev);
|
||||
cancel_delayed_work_sync(&steam->mode_switch);
|
||||
cancel_work_sync(&steam->work_connect);
|
||||
cancel_work_sync(&steam->rumble_work);
|
||||
cancel_work_sync(&steam->unregister_work);
|
||||
hid_destroy_device(steam->client_hdev);
|
||||
steam->client_hdev = NULL;
|
||||
steam->client_opened = 0;
|
||||
if (steam->quirks & STEAM_QUIRK_WIRELESS) {
|
||||
|
||||
@@ -290,7 +290,7 @@ static int i2c_hid_get_report(struct i2c_hid *ihid,
|
||||
ihid->rawbuf, recv_len + sizeof(__le16));
|
||||
if (error) {
|
||||
dev_err(&ihid->client->dev,
|
||||
"failed to set a report to device: %d\n", error);
|
||||
"failed to get a report from device: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -832,9 +832,9 @@ static void hid_ishtp_cl_remove(struct ishtp_cl_device *cl_device)
|
||||
hid_ishtp_cl);
|
||||
|
||||
dev_dbg(ishtp_device(cl_device), "%s\n", __func__);
|
||||
hid_ishtp_cl_deinit(hid_ishtp_cl);
|
||||
ishtp_put_device(cl_device);
|
||||
ishtp_hid_remove(client_data);
|
||||
hid_ishtp_cl_deinit(hid_ishtp_cl);
|
||||
|
||||
hid_ishtp_cl = NULL;
|
||||
|
||||
|
||||
@@ -261,12 +261,14 @@ err_hid_data:
|
||||
*/
|
||||
void ishtp_hid_remove(struct ishtp_cl_data *client_data)
|
||||
{
|
||||
void *data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < client_data->num_hid_devices; ++i) {
|
||||
if (client_data->hid_sensor_hubs[i]) {
|
||||
kfree(client_data->hid_sensor_hubs[i]->driver_data);
|
||||
data = client_data->hid_sensor_hubs[i]->driver_data;
|
||||
hid_destroy_device(client_data->hid_sensor_hubs[i]);
|
||||
kfree(data);
|
||||
client_data->hid_sensor_hubs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -909,6 +909,8 @@ static int quickspi_restore(struct device *device)
|
||||
|
||||
thc_change_ltr_mode(qsdev->thc_hw, THC_LTR_MODE_ACTIVE);
|
||||
|
||||
qsdev->state = QUICKSPI_ENABLED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ static int quickspi_get_device_descriptor(struct quickspi_device *qsdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_err_once(qsdev->dev, "Unexpected intput report type: %d\n", input_rep_type);
|
||||
dev_err_once(qsdev->dev, "Unexpected input report type: %d\n", input_rep_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,11 +22,13 @@
|
||||
*/
|
||||
#define AD7314_TEMP_MASK 0x7FE0
|
||||
#define AD7314_TEMP_SHIFT 5
|
||||
#define AD7314_LEADING_ZEROS_MASK BIT(15)
|
||||
|
||||
/*
|
||||
* ADT7301 and ADT7302 temperature masks
|
||||
*/
|
||||
#define ADT7301_TEMP_MASK 0x3FFF
|
||||
#define ADT7301_LEADING_ZEROS_MASK (BIT(15) | BIT(14))
|
||||
|
||||
enum ad7314_variant {
|
||||
adt7301,
|
||||
@@ -65,12 +67,20 @@ static ssize_t ad7314_temperature_show(struct device *dev,
|
||||
return ret;
|
||||
switch (spi_get_device_id(chip->spi_dev)->driver_data) {
|
||||
case ad7314:
|
||||
if (ret & AD7314_LEADING_ZEROS_MASK) {
|
||||
/* Invalid read-out, leading zero part is missing */
|
||||
return -EIO;
|
||||
}
|
||||
data = (ret & AD7314_TEMP_MASK) >> AD7314_TEMP_SHIFT;
|
||||
data = sign_extend32(data, 9);
|
||||
|
||||
return sprintf(buf, "%d\n", 250 * data);
|
||||
case adt7301:
|
||||
case adt7302:
|
||||
if (ret & ADT7301_LEADING_ZEROS_MASK) {
|
||||
/* Invalid read-out, leading zero part is missing */
|
||||
return -EIO;
|
||||
}
|
||||
/*
|
||||
* Documented as a 13 bit twos complement register
|
||||
* with a sign bit - which is a 14 bit 2's complement
|
||||
|
||||
@@ -181,40 +181,40 @@ static const struct ntc_compensation ncpXXwf104[] = {
|
||||
};
|
||||
|
||||
static const struct ntc_compensation ncpXXxh103[] = {
|
||||
{ .temp_c = -40, .ohm = 247565 },
|
||||
{ .temp_c = -35, .ohm = 181742 },
|
||||
{ .temp_c = -30, .ohm = 135128 },
|
||||
{ .temp_c = -25, .ohm = 101678 },
|
||||
{ .temp_c = -20, .ohm = 77373 },
|
||||
{ .temp_c = -15, .ohm = 59504 },
|
||||
{ .temp_c = -10, .ohm = 46222 },
|
||||
{ .temp_c = -5, .ohm = 36244 },
|
||||
{ .temp_c = 0, .ohm = 28674 },
|
||||
{ .temp_c = 5, .ohm = 22878 },
|
||||
{ .temp_c = 10, .ohm = 18399 },
|
||||
{ .temp_c = 15, .ohm = 14910 },
|
||||
{ .temp_c = 20, .ohm = 12169 },
|
||||
{ .temp_c = -40, .ohm = 195652 },
|
||||
{ .temp_c = -35, .ohm = 148171 },
|
||||
{ .temp_c = -30, .ohm = 113347 },
|
||||
{ .temp_c = -25, .ohm = 87559 },
|
||||
{ .temp_c = -20, .ohm = 68237 },
|
||||
{ .temp_c = -15, .ohm = 53650 },
|
||||
{ .temp_c = -10, .ohm = 42506 },
|
||||
{ .temp_c = -5, .ohm = 33892 },
|
||||
{ .temp_c = 0, .ohm = 27219 },
|
||||
{ .temp_c = 5, .ohm = 22021 },
|
||||
{ .temp_c = 10, .ohm = 17926 },
|
||||
{ .temp_c = 15, .ohm = 14674 },
|
||||
{ .temp_c = 20, .ohm = 12081 },
|
||||
{ .temp_c = 25, .ohm = 10000 },
|
||||
{ .temp_c = 30, .ohm = 8271 },
|
||||
{ .temp_c = 35, .ohm = 6883 },
|
||||
{ .temp_c = 40, .ohm = 5762 },
|
||||
{ .temp_c = 45, .ohm = 4851 },
|
||||
{ .temp_c = 50, .ohm = 4105 },
|
||||
{ .temp_c = 55, .ohm = 3492 },
|
||||
{ .temp_c = 60, .ohm = 2985 },
|
||||
{ .temp_c = 65, .ohm = 2563 },
|
||||
{ .temp_c = 70, .ohm = 2211 },
|
||||
{ .temp_c = 75, .ohm = 1915 },
|
||||
{ .temp_c = 80, .ohm = 1666 },
|
||||
{ .temp_c = 85, .ohm = 1454 },
|
||||
{ .temp_c = 90, .ohm = 1275 },
|
||||
{ .temp_c = 95, .ohm = 1121 },
|
||||
{ .temp_c = 100, .ohm = 990 },
|
||||
{ .temp_c = 105, .ohm = 876 },
|
||||
{ .temp_c = 110, .ohm = 779 },
|
||||
{ .temp_c = 115, .ohm = 694 },
|
||||
{ .temp_c = 120, .ohm = 620 },
|
||||
{ .temp_c = 125, .ohm = 556 },
|
||||
{ .temp_c = 30, .ohm = 8315 },
|
||||
{ .temp_c = 35, .ohm = 6948 },
|
||||
{ .temp_c = 40, .ohm = 5834 },
|
||||
{ .temp_c = 45, .ohm = 4917 },
|
||||
{ .temp_c = 50, .ohm = 4161 },
|
||||
{ .temp_c = 55, .ohm = 3535 },
|
||||
{ .temp_c = 60, .ohm = 3014 },
|
||||
{ .temp_c = 65, .ohm = 2586 },
|
||||
{ .temp_c = 70, .ohm = 2228 },
|
||||
{ .temp_c = 75, .ohm = 1925 },
|
||||
{ .temp_c = 80, .ohm = 1669 },
|
||||
{ .temp_c = 85, .ohm = 1452 },
|
||||
{ .temp_c = 90, .ohm = 1268 },
|
||||
{ .temp_c = 95, .ohm = 1110 },
|
||||
{ .temp_c = 100, .ohm = 974 },
|
||||
{ .temp_c = 105, .ohm = 858 },
|
||||
{ .temp_c = 110, .ohm = 758 },
|
||||
{ .temp_c = 115, .ohm = 672 },
|
||||
{ .temp_c = 120, .ohm = 596 },
|
||||
{ .temp_c = 125, .ohm = 531 },
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -127,8 +127,6 @@ static int update_thresholds(struct peci_dimmtemp *priv, int dimm_no)
|
||||
return 0;
|
||||
|
||||
ret = priv->gen_info->read_thresholds(priv, dimm_order, chan_rank, &data);
|
||||
if (ret == -ENODATA) /* Use default or previous value */
|
||||
return 0;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -509,11 +507,11 @@ read_thresholds_icx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u
|
||||
|
||||
ret = peci_ep_pci_local_read(priv->peci_dev, 0, 13, 0, 2, 0xd4, ®_val);
|
||||
if (ret || !(reg_val & BIT(31)))
|
||||
return -ENODATA; /* Use default or previous value */
|
||||
return -ENODATA;
|
||||
|
||||
ret = peci_ep_pci_local_read(priv->peci_dev, 0, 13, 0, 2, 0xd0, ®_val);
|
||||
if (ret)
|
||||
return -ENODATA; /* Use default or previous value */
|
||||
return -ENODATA;
|
||||
|
||||
/*
|
||||
* Device 26, Offset 224e0: IMC 0 channel 0 -> rank 0
|
||||
@@ -546,11 +544,11 @@ read_thresholds_spr(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u
|
||||
|
||||
ret = peci_ep_pci_local_read(priv->peci_dev, 0, 30, 0, 2, 0xd4, ®_val);
|
||||
if (ret || !(reg_val & BIT(31)))
|
||||
return -ENODATA; /* Use default or previous value */
|
||||
return -ENODATA;
|
||||
|
||||
ret = peci_ep_pci_local_read(priv->peci_dev, 0, 30, 0, 2, 0xd0, ®_val);
|
||||
if (ret)
|
||||
return -ENODATA; /* Use default or previous value */
|
||||
return -ENODATA;
|
||||
|
||||
/*
|
||||
* Device 26, Offset 219a8: IMC 0 channel 0 -> rank 0
|
||||
|
||||
@@ -103,6 +103,8 @@ static int pmbus_identify(struct i2c_client *client,
|
||||
if (pmbus_check_byte_register(client, 0, PMBUS_PAGE)) {
|
||||
int page;
|
||||
|
||||
info->pages = PMBUS_PAGES;
|
||||
|
||||
for (page = 1; page < PMBUS_PAGES; page++) {
|
||||
if (pmbus_set_page(client, page, 0xff) < 0)
|
||||
break;
|
||||
|
||||
@@ -706,7 +706,7 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ctx->pcc_comm_addr) {
|
||||
if (IS_ERR_OR_NULL(ctx->pcc_comm_addr)) {
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to ioremap PCC comm region\n");
|
||||
rc = -ENOMEM;
|
||||
|
||||
@@ -745,7 +745,7 @@ err:
|
||||
|
||||
if (cfv->vr_rx)
|
||||
vdev->vringh_config->del_vrhs(cfv->vdev);
|
||||
if (cfv->vdev)
|
||||
if (cfv->vq_tx)
|
||||
vdev->config->del_vqs(cfv->vdev);
|
||||
free_netdev(netdev);
|
||||
return err;
|
||||
|
||||
@@ -2591,7 +2591,8 @@ mt7531_setup_common(struct dsa_switch *ds)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
/* Setup VLAN ID 0 for VLAN-unaware bridges */
|
||||
return mt7530_setup_vlan0(priv);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -2687,11 +2688,6 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Setup VLAN ID 0 for VLAN-unaware bridges */
|
||||
ret = mt7530_setup_vlan0(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ds->assisted_learning_on_cpu_port = true;
|
||||
ds->mtu_enforcement_ingress = true;
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ config NET_DSA_REALTEK_RTL8366RB
|
||||
Select to enable support for Realtek RTL8366RB.
|
||||
|
||||
config NET_DSA_REALTEK_RTL8366RB_LEDS
|
||||
bool "Support RTL8366RB LED control"
|
||||
bool
|
||||
depends on (LEDS_CLASS=y || LEDS_CLASS=NET_DSA_REALTEK_RTL8366RB)
|
||||
depends on NET_DSA_REALTEK_RTL8366RB
|
||||
default NET_DSA_REALTEK_RTL8366RB
|
||||
|
||||
@@ -562,7 +562,7 @@ struct be_adapter {
|
||||
struct be_dma_mem mbox_mem_alloced;
|
||||
|
||||
struct be_mcc_obj mcc_obj;
|
||||
struct mutex mcc_lock; /* For serializing mcc cmds to BE card */
|
||||
spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */
|
||||
spinlock_t mcc_cq_lock;
|
||||
|
||||
u16 cfg_num_rx_irqs; /* configured via set-channels */
|
||||
|
||||
@@ -575,7 +575,7 @@ int be_process_mcc(struct be_adapter *adapter)
|
||||
/* Wait till no more pending mcc requests are present */
|
||||
static int be_mcc_wait_compl(struct be_adapter *adapter)
|
||||
{
|
||||
#define mcc_timeout 12000 /* 12s timeout */
|
||||
#define mcc_timeout 120000 /* 12s timeout */
|
||||
int i, status = 0;
|
||||
struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
|
||||
|
||||
@@ -589,7 +589,7 @@ static int be_mcc_wait_compl(struct be_adapter *adapter)
|
||||
|
||||
if (atomic_read(&mcc_obj->q.used) == 0)
|
||||
break;
|
||||
usleep_range(500, 1000);
|
||||
udelay(100);
|
||||
}
|
||||
if (i == mcc_timeout) {
|
||||
dev_err(&adapter->pdev->dev, "FW not responding\n");
|
||||
@@ -866,7 +866,7 @@ static bool use_mcc(struct be_adapter *adapter)
|
||||
static int be_cmd_lock(struct be_adapter *adapter)
|
||||
{
|
||||
if (use_mcc(adapter)) {
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
return 0;
|
||||
} else {
|
||||
return mutex_lock_interruptible(&adapter->mbox_lock);
|
||||
@@ -877,7 +877,7 @@ static int be_cmd_lock(struct be_adapter *adapter)
|
||||
static void be_cmd_unlock(struct be_adapter *adapter)
|
||||
{
|
||||
if (use_mcc(adapter))
|
||||
return mutex_unlock(&adapter->mcc_lock);
|
||||
return spin_unlock_bh(&adapter->mcc_lock);
|
||||
else
|
||||
return mutex_unlock(&adapter->mbox_lock);
|
||||
}
|
||||
@@ -1047,7 +1047,7 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
|
||||
struct be_cmd_req_mac_query *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -1076,7 +1076,7 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
|
||||
}
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1088,7 +1088,7 @@ int be_cmd_pmac_add(struct be_adapter *adapter, const u8 *mac_addr,
|
||||
struct be_cmd_req_pmac_add *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -1113,7 +1113,7 @@ int be_cmd_pmac_add(struct be_adapter *adapter, const u8 *mac_addr,
|
||||
}
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
|
||||
if (base_status(status) == MCC_STATUS_UNAUTHORIZED_REQUEST)
|
||||
status = -EPERM;
|
||||
@@ -1131,7 +1131,7 @@ int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, int pmac_id, u32 dom)
|
||||
if (pmac_id == -1)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -1151,7 +1151,7 @@ int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, int pmac_id, u32 dom)
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1414,7 +1414,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter,
|
||||
struct be_dma_mem *q_mem = &rxq->dma_mem;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -1444,7 +1444,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter,
|
||||
}
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1508,7 +1508,7 @@ int be_cmd_rxq_destroy(struct be_adapter *adapter, struct be_queue_info *q)
|
||||
struct be_cmd_req_q_destroy *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -1525,7 +1525,7 @@ int be_cmd_rxq_destroy(struct be_adapter *adapter, struct be_queue_info *q)
|
||||
q->created = false;
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1593,7 +1593,7 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
|
||||
struct be_cmd_req_hdr *hdr;
|
||||
int status = 0;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -1621,7 +1621,7 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
|
||||
adapter->stats_cmd_sent = true;
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1637,7 +1637,7 @@ int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
|
||||
CMD_SUBSYSTEM_ETH))
|
||||
return -EPERM;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -1660,7 +1660,7 @@ int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
|
||||
adapter->stats_cmd_sent = true;
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1697,7 +1697,7 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u16 *link_speed,
|
||||
struct be_cmd_req_link_status *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
if (link_status)
|
||||
*link_status = LINK_DOWN;
|
||||
@@ -1736,7 +1736,7 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u16 *link_speed,
|
||||
}
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1747,7 +1747,7 @@ int be_cmd_get_die_temperature(struct be_adapter *adapter)
|
||||
struct be_cmd_req_get_cntl_addnl_attribs *req;
|
||||
int status = 0;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -1762,7 +1762,7 @@ int be_cmd_get_die_temperature(struct be_adapter *adapter)
|
||||
|
||||
status = be_mcc_notify(adapter);
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1811,7 +1811,7 @@ int be_cmd_get_fat_dump(struct be_adapter *adapter, u32 buf_len, void *buf)
|
||||
if (!get_fat_cmd.va)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
while (total_size) {
|
||||
buf_size = min(total_size, (u32)60 * 1024);
|
||||
@@ -1849,9 +1849,9 @@ int be_cmd_get_fat_dump(struct be_adapter *adapter, u32 buf_len, void *buf)
|
||||
log_offset += buf_size;
|
||||
}
|
||||
err:
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
dma_free_coherent(&adapter->pdev->dev, get_fat_cmd.size,
|
||||
get_fat_cmd.va, get_fat_cmd.dma);
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1862,7 +1862,7 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter)
|
||||
struct be_cmd_req_get_fw_version *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -1885,7 +1885,7 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter)
|
||||
sizeof(adapter->fw_on_flash));
|
||||
}
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1899,7 +1899,7 @@ static int __be_cmd_modify_eqd(struct be_adapter *adapter,
|
||||
struct be_cmd_req_modify_eq_delay *req;
|
||||
int status = 0, i;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -1922,7 +1922,7 @@ static int __be_cmd_modify_eqd(struct be_adapter *adapter,
|
||||
|
||||
status = be_mcc_notify(adapter);
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1949,7 +1949,7 @@ int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
|
||||
struct be_cmd_req_vlan_config *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -1971,7 +1971,7 @@ int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array,
|
||||
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1982,7 +1982,7 @@ static int __be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
|
||||
struct be_cmd_req_rx_filter *req = mem->va;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -2015,7 +2015,7 @@ static int __be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
|
||||
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -2046,7 +2046,7 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
|
||||
CMD_SUBSYSTEM_COMMON))
|
||||
return -EPERM;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -2066,7 +2066,7 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc)
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
|
||||
if (base_status(status) == MCC_STATUS_FEATURE_NOT_SUPPORTED)
|
||||
return -EOPNOTSUPP;
|
||||
@@ -2085,7 +2085,7 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
|
||||
CMD_SUBSYSTEM_COMMON))
|
||||
return -EPERM;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -2108,7 +2108,7 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc)
|
||||
}
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -2189,7 +2189,7 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
|
||||
if (!(be_if_cap_flags(adapter) & BE_IF_FLAGS_RSS))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -2214,7 +2214,7 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
|
||||
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -2226,7 +2226,7 @@ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num,
|
||||
struct be_cmd_req_enable_disable_beacon *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -2247,7 +2247,7 @@ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num,
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -2258,7 +2258,7 @@ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state)
|
||||
struct be_cmd_req_get_beacon_state *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -2282,7 +2282,7 @@ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state)
|
||||
}
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -2306,7 +2306,7 @@ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -2328,7 +2328,7 @@ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
|
||||
memcpy(data, resp->page_data + off, len);
|
||||
}
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma);
|
||||
return status;
|
||||
}
|
||||
@@ -2345,7 +2345,7 @@ static int lancer_cmd_write_object(struct be_adapter *adapter,
|
||||
void *ctxt = NULL;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
adapter->flash_status = 0;
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
@@ -2387,7 +2387,7 @@ static int lancer_cmd_write_object(struct be_adapter *adapter,
|
||||
if (status)
|
||||
goto err_unlock;
|
||||
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
|
||||
if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
|
||||
msecs_to_jiffies(60000)))
|
||||
@@ -2406,7 +2406,7 @@ static int lancer_cmd_write_object(struct be_adapter *adapter,
|
||||
return status;
|
||||
|
||||
err_unlock:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -2460,7 +2460,7 @@ static int lancer_cmd_delete_object(struct be_adapter *adapter,
|
||||
struct be_mcc_wrb *wrb;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -2478,7 +2478,7 @@ static int lancer_cmd_delete_object(struct be_adapter *adapter,
|
||||
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -2491,7 +2491,7 @@ int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
|
||||
struct lancer_cmd_resp_read_object *resp;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -2525,7 +2525,7 @@ int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
|
||||
}
|
||||
|
||||
err_unlock:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -2537,7 +2537,7 @@ static int be_cmd_write_flashrom(struct be_adapter *adapter,
|
||||
struct be_cmd_write_flashrom *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
adapter->flash_status = 0;
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
@@ -2562,7 +2562,7 @@ static int be_cmd_write_flashrom(struct be_adapter *adapter,
|
||||
if (status)
|
||||
goto err_unlock;
|
||||
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
|
||||
if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
|
||||
msecs_to_jiffies(40000)))
|
||||
@@ -2573,7 +2573,7 @@ static int be_cmd_write_flashrom(struct be_adapter *adapter,
|
||||
return status;
|
||||
|
||||
err_unlock:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -2584,7 +2584,7 @@ static int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
|
||||
struct be_mcc_wrb *wrb;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -2611,7 +2611,7 @@ static int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
|
||||
memcpy(flashed_crc, req->crc, 4);
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -3217,7 +3217,7 @@ int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
|
||||
struct be_cmd_req_acpi_wol_magic_config *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -3234,7 +3234,7 @@ int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -3249,7 +3249,7 @@ int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
|
||||
CMD_SUBSYSTEM_LOWLEVEL))
|
||||
return -EPERM;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -3272,7 +3272,7 @@ int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
|
||||
if (status)
|
||||
goto err_unlock;
|
||||
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
|
||||
if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
|
||||
msecs_to_jiffies(SET_LB_MODE_TIMEOUT)))
|
||||
@@ -3281,7 +3281,7 @@ int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
|
||||
return status;
|
||||
|
||||
err_unlock:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -3298,7 +3298,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
|
||||
CMD_SUBSYSTEM_LOWLEVEL))
|
||||
return -EPERM;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -3324,7 +3324,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
|
||||
if (status)
|
||||
goto err;
|
||||
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
|
||||
wait_for_completion(&adapter->et_cmd_compl);
|
||||
resp = embedded_payload(wrb);
|
||||
@@ -3332,7 +3332,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
|
||||
|
||||
return status;
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -3348,7 +3348,7 @@ int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
|
||||
CMD_SUBSYSTEM_LOWLEVEL))
|
||||
return -EPERM;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -3382,7 +3382,7 @@ int be_cmd_ddr_dma_test(struct be_adapter *adapter, u64 pattern,
|
||||
}
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -3393,7 +3393,7 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter,
|
||||
struct be_cmd_req_seeprom_read *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -3409,7 +3409,7 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter,
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -3424,7 +3424,7 @@ int be_cmd_get_phy_info(struct be_adapter *adapter)
|
||||
CMD_SUBSYSTEM_COMMON))
|
||||
return -EPERM;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -3469,7 +3469,7 @@ int be_cmd_get_phy_info(struct be_adapter *adapter)
|
||||
}
|
||||
dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma);
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -3479,7 +3479,7 @@ static int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain)
|
||||
struct be_cmd_req_set_qos *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -3499,7 +3499,7 @@ static int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain)
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -3611,7 +3611,7 @@ int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege,
|
||||
struct be_cmd_req_get_fn_privileges *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -3643,7 +3643,7 @@ int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege,
|
||||
}
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -3655,7 +3655,7 @@ int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 privileges,
|
||||
struct be_cmd_req_set_fn_privileges *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -3675,7 +3675,7 @@ int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 privileges,
|
||||
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -3707,7 +3707,7 @@ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -3771,7 +3771,7 @@ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
dma_free_coherent(&adapter->pdev->dev, get_mac_list_cmd.size,
|
||||
get_mac_list_cmd.va, get_mac_list_cmd.dma);
|
||||
return status;
|
||||
@@ -3831,7 +3831,7 @@ int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
|
||||
if (!cmd.va)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -3853,7 +3853,7 @@ int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array,
|
||||
|
||||
err:
|
||||
dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma);
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -3889,7 +3889,7 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
|
||||
CMD_SUBSYSTEM_COMMON))
|
||||
return -EPERM;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -3930,7 +3930,7 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid,
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -3944,7 +3944,7 @@ int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
|
||||
int status;
|
||||
u16 vid;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -3991,7 +3991,7 @@ int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
|
||||
}
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -4190,7 +4190,7 @@ int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
|
||||
struct be_cmd_req_set_ext_fat_caps *req;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -4206,7 +4206,7 @@ int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
|
||||
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -4684,7 +4684,7 @@ int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op)
|
||||
if (iface == 0xFFFFFFFF)
|
||||
return -1;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -4701,7 +4701,7 @@ int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op)
|
||||
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -4735,7 +4735,7 @@ int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
|
||||
struct be_cmd_resp_get_iface_list *resp;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -4756,7 +4756,7 @@ int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
|
||||
}
|
||||
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -4850,7 +4850,7 @@ int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain)
|
||||
if (BEx_chip(adapter))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -4868,7 +4868,7 @@ int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain)
|
||||
req->enable = 1;
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -4941,7 +4941,7 @@ __be_cmd_set_logical_link_config(struct be_adapter *adapter,
|
||||
u32 link_config = 0;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -4969,7 +4969,7 @@ __be_cmd_set_logical_link_config(struct be_adapter *adapter,
|
||||
|
||||
status = be_mcc_notify_wait(adapter);
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -5000,8 +5000,7 @@ int be_cmd_set_features(struct be_adapter *adapter)
|
||||
struct be_mcc_wrb *wrb;
|
||||
int status;
|
||||
|
||||
if (mutex_lock_interruptible(&adapter->mcc_lock))
|
||||
return -1;
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -5039,7 +5038,7 @@ err:
|
||||
dev_info(&adapter->pdev->dev,
|
||||
"Adapter does not support HW error recovery\n");
|
||||
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -5053,7 +5052,7 @@ int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload,
|
||||
struct be_cmd_resp_hdr *resp;
|
||||
int status;
|
||||
|
||||
mutex_lock(&adapter->mcc_lock);
|
||||
spin_lock_bh(&adapter->mcc_lock);
|
||||
|
||||
wrb = wrb_from_mccq(adapter);
|
||||
if (!wrb) {
|
||||
@@ -5076,7 +5075,7 @@ int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload,
|
||||
memcpy(wrb_payload, resp, sizeof(*resp) + resp->response_length);
|
||||
be_dws_le_to_cpu(wrb_payload, sizeof(*resp) + resp->response_length);
|
||||
err:
|
||||
mutex_unlock(&adapter->mcc_lock);
|
||||
spin_unlock_bh(&adapter->mcc_lock);
|
||||
return status;
|
||||
}
|
||||
EXPORT_SYMBOL(be_roce_mcc_cmd);
|
||||
|
||||
@@ -5667,8 +5667,8 @@ static int be_drv_init(struct be_adapter *adapter)
|
||||
}
|
||||
|
||||
mutex_init(&adapter->mbox_lock);
|
||||
mutex_init(&adapter->mcc_lock);
|
||||
mutex_init(&adapter->rx_filter_lock);
|
||||
spin_lock_init(&adapter->mcc_lock);
|
||||
spin_lock_init(&adapter->mcc_cq_lock);
|
||||
init_completion(&adapter->et_cmd_compl);
|
||||
|
||||
|
||||
@@ -483,7 +483,7 @@ int hclge_ptp_init(struct hclge_dev *hdev)
|
||||
|
||||
ret = hclge_ptp_get_cycle(hdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = hclge_ptp_int_en(hdev, true);
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "dwmac_dma.h"
|
||||
#include "dwmac1000.h"
|
||||
|
||||
#define DRIVER_NAME "dwmac-loongson-pci"
|
||||
|
||||
/* Normal Loongson Tx Summary */
|
||||
#define DMA_INTR_ENA_NIE_TX_LOONGSON 0x00040000
|
||||
/* Normal Loongson Rx Summary */
|
||||
@@ -568,7 +570,7 @@ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id
|
||||
for (i = 0; i < PCI_STD_NUM_BARS; i++) {
|
||||
if (pci_resource_len(pdev, i) == 0)
|
||||
continue;
|
||||
ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
|
||||
ret = pcim_iomap_regions(pdev, BIT(0), DRIVER_NAME);
|
||||
if (ret)
|
||||
goto err_disable_device;
|
||||
break;
|
||||
@@ -687,7 +689,7 @@ static const struct pci_device_id loongson_dwmac_id_table[] = {
|
||||
MODULE_DEVICE_TABLE(pci, loongson_dwmac_id_table);
|
||||
|
||||
static struct pci_driver loongson_dwmac_driver = {
|
||||
.name = "dwmac-loongson-pci",
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = loongson_dwmac_id_table,
|
||||
.probe = loongson_dwmac_probe,
|
||||
.remove = loongson_dwmac_remove,
|
||||
|
||||
@@ -28,20 +28,18 @@ enum ipa_resource_type {
|
||||
enum ipa_rsrc_group_id {
|
||||
/* Source resource group identifiers */
|
||||
IPA_RSRC_GROUP_SRC_UL_DL = 0,
|
||||
IPA_RSRC_GROUP_SRC_UC_RX_Q,
|
||||
IPA_RSRC_GROUP_SRC_COUNT, /* Last in set; not a source group */
|
||||
|
||||
/* Destination resource group identifiers */
|
||||
IPA_RSRC_GROUP_DST_UL_DL_DPL = 0,
|
||||
IPA_RSRC_GROUP_DST_UNUSED_1,
|
||||
IPA_RSRC_GROUP_DST_UL_DL = 0,
|
||||
IPA_RSRC_GROUP_DST_COUNT, /* Last; not a destination group */
|
||||
};
|
||||
|
||||
/* QSB configuration data for an SoC having IPA v4.7 */
|
||||
static const struct ipa_qsb_data ipa_qsb_data[] = {
|
||||
[IPA_QSB_MASTER_DDR] = {
|
||||
.max_writes = 8,
|
||||
.max_reads = 0, /* no limit (hardware max) */
|
||||
.max_writes = 12,
|
||||
.max_reads = 13,
|
||||
.max_reads_beats = 120,
|
||||
},
|
||||
};
|
||||
@@ -81,7 +79,7 @@ static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = {
|
||||
},
|
||||
.endpoint = {
|
||||
.config = {
|
||||
.resource_group = IPA_RSRC_GROUP_DST_UL_DL_DPL,
|
||||
.resource_group = IPA_RSRC_GROUP_DST_UL_DL,
|
||||
.aggregation = true,
|
||||
.status_enable = true,
|
||||
.rx = {
|
||||
@@ -106,6 +104,7 @@ static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = {
|
||||
.filter_support = true,
|
||||
.config = {
|
||||
.resource_group = IPA_RSRC_GROUP_SRC_UL_DL,
|
||||
.checksum = true,
|
||||
.qmap = true,
|
||||
.status_enable = true,
|
||||
.tx = {
|
||||
@@ -128,7 +127,8 @@ static const struct ipa_gsi_endpoint_data ipa_gsi_endpoint_data[] = {
|
||||
},
|
||||
.endpoint = {
|
||||
.config = {
|
||||
.resource_group = IPA_RSRC_GROUP_DST_UL_DL_DPL,
|
||||
.resource_group = IPA_RSRC_GROUP_DST_UL_DL,
|
||||
.checksum = true,
|
||||
.qmap = true,
|
||||
.aggregation = true,
|
||||
.rx = {
|
||||
@@ -197,12 +197,12 @@ static const struct ipa_resource ipa_resource_src[] = {
|
||||
/* Destination resource configuration data for an SoC having IPA v4.7 */
|
||||
static const struct ipa_resource ipa_resource_dst[] = {
|
||||
[IPA_RESOURCE_TYPE_DST_DATA_SECTORS] = {
|
||||
.limits[IPA_RSRC_GROUP_DST_UL_DL_DPL] = {
|
||||
.limits[IPA_RSRC_GROUP_DST_UL_DL] = {
|
||||
.min = 7, .max = 7,
|
||||
},
|
||||
},
|
||||
[IPA_RESOURCE_TYPE_DST_DPS_DMARS] = {
|
||||
.limits[IPA_RSRC_GROUP_DST_UL_DL_DPL] = {
|
||||
.limits[IPA_RSRC_GROUP_DST_UL_DL] = {
|
||||
.min = 2, .max = 2,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -507,6 +507,9 @@ static int mctp_i3c_header_create(struct sk_buff *skb, struct net_device *dev,
|
||||
{
|
||||
struct mctp_i3c_internal_hdr *ihdr;
|
||||
|
||||
if (!daddr || !saddr)
|
||||
return -EINVAL;
|
||||
|
||||
skb_push(skb, sizeof(struct mctp_i3c_internal_hdr));
|
||||
skb_reset_mac_header(skb);
|
||||
ihdr = (void *)skb_mac_header(skb);
|
||||
|
||||
@@ -72,6 +72,17 @@
|
||||
#define PPP_PROTO_LEN 2
|
||||
#define PPP_LCP_HDRLEN 4
|
||||
|
||||
/* The filter instructions generated by libpcap are constructed
|
||||
* assuming a four-byte PPP header on each packet, where the last
|
||||
* 2 bytes are the protocol field defined in the RFC and the first
|
||||
* byte of the first 2 bytes indicates the direction.
|
||||
* The second byte is currently unused, but we still need to initialize
|
||||
* it to prevent crafted BPF programs from reading them which would
|
||||
* cause reading of uninitialized data.
|
||||
*/
|
||||
#define PPP_FILTER_OUTBOUND_TAG 0x0100
|
||||
#define PPP_FILTER_INBOUND_TAG 0x0000
|
||||
|
||||
/*
|
||||
* An instance of /dev/ppp can be associated with either a ppp
|
||||
* interface unit or a ppp channel. In both cases, file->private_data
|
||||
@@ -1762,10 +1773,10 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
|
||||
|
||||
if (proto < 0x8000) {
|
||||
#ifdef CONFIG_PPP_FILTER
|
||||
/* check if we should pass this packet */
|
||||
/* the filter instructions are constructed assuming
|
||||
a four-byte PPP header on each packet */
|
||||
*(u8 *)skb_push(skb, 2) = 1;
|
||||
/* check if the packet passes the pass and active filters.
|
||||
* See comment for PPP_FILTER_OUTBOUND_TAG above.
|
||||
*/
|
||||
*(__be16 *)skb_push(skb, 2) = htons(PPP_FILTER_OUTBOUND_TAG);
|
||||
if (ppp->pass_filter &&
|
||||
bpf_prog_run(ppp->pass_filter, skb) == 0) {
|
||||
if (ppp->debug & 1)
|
||||
@@ -2482,14 +2493,13 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
|
||||
/* network protocol frame - give it to the kernel */
|
||||
|
||||
#ifdef CONFIG_PPP_FILTER
|
||||
/* check if the packet passes the pass and active filters */
|
||||
/* the filter instructions are constructed assuming
|
||||
a four-byte PPP header on each packet */
|
||||
if (ppp->pass_filter || ppp->active_filter) {
|
||||
if (skb_unclone(skb, GFP_ATOMIC))
|
||||
goto err;
|
||||
|
||||
*(u8 *)skb_push(skb, 2) = 0;
|
||||
/* Check if the packet passes the pass and active filters.
|
||||
* See comment for PPP_FILTER_INBOUND_TAG above.
|
||||
*/
|
||||
*(__be16 *)skb_push(skb, 2) = htons(PPP_FILTER_INBOUND_TAG);
|
||||
if (ppp->pass_filter &&
|
||||
bpf_prog_run(ppp->pass_filter, skb) == 0) {
|
||||
if (ppp->debug & 1)
|
||||
|
||||
@@ -1172,6 +1172,7 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
|
||||
struct brcmf_bus *bus_if;
|
||||
struct brcmf_sdio_dev *sdiodev;
|
||||
mmc_pm_flag_t sdio_flags;
|
||||
bool cap_power_off;
|
||||
int ret = 0;
|
||||
|
||||
func = container_of(dev, struct sdio_func, dev);
|
||||
@@ -1179,19 +1180,23 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
|
||||
if (func->num != 1)
|
||||
return 0;
|
||||
|
||||
cap_power_off = !!(func->card->host->caps & MMC_CAP_POWER_OFF_CARD);
|
||||
|
||||
bus_if = dev_get_drvdata(dev);
|
||||
sdiodev = bus_if->bus_priv.sdio;
|
||||
|
||||
if (sdiodev->wowl_enabled) {
|
||||
if (sdiodev->wowl_enabled || !cap_power_off) {
|
||||
brcmf_sdiod_freezer_on(sdiodev);
|
||||
brcmf_sdio_wd_timer(sdiodev->bus, 0);
|
||||
|
||||
sdio_flags = MMC_PM_KEEP_POWER;
|
||||
if (sdiodev->settings->bus.sdio.oob_irq_supported)
|
||||
enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
|
||||
else
|
||||
sdio_flags |= MMC_PM_WAKE_SDIO_IRQ;
|
||||
|
||||
if (sdiodev->wowl_enabled) {
|
||||
if (sdiodev->settings->bus.sdio.oob_irq_supported)
|
||||
enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
|
||||
else
|
||||
sdio_flags |= MMC_PM_WAKE_SDIO_IRQ;
|
||||
}
|
||||
|
||||
if (sdio_set_host_pm_flags(sdiodev->func1, sdio_flags))
|
||||
brcmf_err("Failed to set pm_flags %x\n", sdio_flags);
|
||||
@@ -1213,18 +1218,19 @@ static int brcmf_ops_sdio_resume(struct device *dev)
|
||||
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
struct sdio_func *func = container_of(dev, struct sdio_func, dev);
|
||||
int ret = 0;
|
||||
bool cap_power_off = !!(func->card->host->caps & MMC_CAP_POWER_OFF_CARD);
|
||||
|
||||
brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
|
||||
if (func->num != 2)
|
||||
return 0;
|
||||
|
||||
if (!sdiodev->wowl_enabled) {
|
||||
if (!sdiodev->wowl_enabled && cap_power_off) {
|
||||
/* bus was powered off and device removed, probe again */
|
||||
ret = brcmf_sdiod_probe(sdiodev);
|
||||
if (ret)
|
||||
brcmf_err("Failed to probe device on resume\n");
|
||||
} else {
|
||||
if (sdiodev->settings->bus.sdio.oob_irq_supported)
|
||||
if (sdiodev->wowl_enabled && sdiodev->settings->bus.sdio.oob_irq_supported)
|
||||
disable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
|
||||
|
||||
brcmf_sdiod_freezer_off(sdiodev);
|
||||
|
||||
@@ -558,41 +558,71 @@ static void iwl_dump_prph(struct iwl_fw_runtime *fwrt,
|
||||
}
|
||||
|
||||
/*
|
||||
* alloc_sgtable - allocates scallerlist table in the given size,
|
||||
* fills it with pages and returns it
|
||||
* alloc_sgtable - allocates (chained) scatterlist in the given size,
|
||||
* fills it with pages and returns it
|
||||
* @size: the size (in bytes) of the table
|
||||
*/
|
||||
static struct scatterlist *alloc_sgtable(int size)
|
||||
*/
|
||||
static struct scatterlist *alloc_sgtable(ssize_t size)
|
||||
{
|
||||
int alloc_size, nents, i;
|
||||
struct page *new_page;
|
||||
struct scatterlist *iter;
|
||||
struct scatterlist *table;
|
||||
struct scatterlist *result = NULL, *prev;
|
||||
int nents, i, n_prev;
|
||||
|
||||
nents = DIV_ROUND_UP(size, PAGE_SIZE);
|
||||
table = kcalloc(nents, sizeof(*table), GFP_KERNEL);
|
||||
if (!table)
|
||||
return NULL;
|
||||
sg_init_table(table, nents);
|
||||
iter = table;
|
||||
for_each_sg(table, iter, sg_nents(table), i) {
|
||||
new_page = alloc_page(GFP_KERNEL);
|
||||
if (!new_page) {
|
||||
/* release all previous allocated pages in the table */
|
||||
iter = table;
|
||||
for_each_sg(table, iter, sg_nents(table), i) {
|
||||
new_page = sg_page(iter);
|
||||
if (new_page)
|
||||
__free_page(new_page);
|
||||
}
|
||||
kfree(table);
|
||||
|
||||
#define N_ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(*result))
|
||||
/*
|
||||
* We need an additional entry for table chaining,
|
||||
* this ensures the loop can finish i.e. we can
|
||||
* fit at least two entries per page (obviously,
|
||||
* many more really fit.)
|
||||
*/
|
||||
BUILD_BUG_ON(N_ENTRIES_PER_PAGE < 2);
|
||||
|
||||
while (nents > 0) {
|
||||
struct scatterlist *new, *iter;
|
||||
int n_fill, n_alloc;
|
||||
|
||||
if (nents <= N_ENTRIES_PER_PAGE) {
|
||||
/* last needed table */
|
||||
n_fill = nents;
|
||||
n_alloc = nents;
|
||||
nents = 0;
|
||||
} else {
|
||||
/* fill a page with entries */
|
||||
n_alloc = N_ENTRIES_PER_PAGE;
|
||||
/* reserve one for chaining */
|
||||
n_fill = n_alloc - 1;
|
||||
nents -= n_fill;
|
||||
}
|
||||
|
||||
new = kcalloc(n_alloc, sizeof(*new), GFP_KERNEL);
|
||||
if (!new) {
|
||||
if (result)
|
||||
_devcd_free_sgtable(result);
|
||||
return NULL;
|
||||
}
|
||||
alloc_size = min_t(int, size, PAGE_SIZE);
|
||||
size -= PAGE_SIZE;
|
||||
sg_set_page(iter, new_page, alloc_size, 0);
|
||||
sg_init_table(new, n_alloc);
|
||||
|
||||
if (!result)
|
||||
result = new;
|
||||
else
|
||||
sg_chain(prev, n_prev, new);
|
||||
prev = new;
|
||||
n_prev = n_alloc;
|
||||
|
||||
for_each_sg(new, iter, n_fill, i) {
|
||||
struct page *new_page = alloc_page(GFP_KERNEL);
|
||||
|
||||
if (!new_page) {
|
||||
_devcd_free_sgtable(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sg_set_page(iter, new_page, PAGE_SIZE, 0);
|
||||
}
|
||||
}
|
||||
return table;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void iwl_fw_get_prph_len(struct iwl_fw_runtime *fwrt,
|
||||
|
||||
@@ -540,6 +540,9 @@ bool iwl_fwrt_read_err_table(struct iwl_trans *trans, u32 base, u32 *err_id)
|
||||
} err_info = {};
|
||||
int ret;
|
||||
|
||||
if (err_id)
|
||||
*err_id = 0;
|
||||
|
||||
if (!base)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -1181,7 +1181,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
|
||||
if (tlv_len != sizeof(*fseq_ver))
|
||||
goto invalid_tlv_len;
|
||||
IWL_INFO(drv, "TLV_FW_FSEQ_VERSION: %s\n",
|
||||
IWL_INFO(drv, "TLV_FW_FSEQ_VERSION: %.32s\n",
|
||||
fseq_ver->version);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -3092,8 +3092,14 @@ static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
|
||||
ieee80211_resume_disconnect(vif);
|
||||
}
|
||||
|
||||
static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
enum rt_status {
|
||||
FW_ALIVE,
|
||||
FW_NEEDS_RESET,
|
||||
FW_ERROR,
|
||||
};
|
||||
|
||||
static enum rt_status iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
u32 err_id;
|
||||
|
||||
@@ -3101,29 +3107,35 @@ static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
|
||||
if (iwl_fwrt_read_err_table(mvm->trans,
|
||||
mvm->trans->dbg.lmac_error_event_table[0],
|
||||
&err_id)) {
|
||||
if (err_id == RF_KILL_INDICATOR_FOR_WOWLAN && vif) {
|
||||
struct cfg80211_wowlan_wakeup wakeup = {
|
||||
.rfkill_release = true,
|
||||
};
|
||||
ieee80211_report_wowlan_wakeup(vif, &wakeup,
|
||||
GFP_KERNEL);
|
||||
if (err_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
|
||||
IWL_WARN(mvm, "Rfkill was toggled during suspend\n");
|
||||
if (vif) {
|
||||
struct cfg80211_wowlan_wakeup wakeup = {
|
||||
.rfkill_release = true,
|
||||
};
|
||||
|
||||
ieee80211_report_wowlan_wakeup(vif, &wakeup,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
|
||||
return FW_NEEDS_RESET;
|
||||
}
|
||||
return true;
|
||||
return FW_ERROR;
|
||||
}
|
||||
|
||||
/* check if we have lmac2 set and check for error */
|
||||
if (iwl_fwrt_read_err_table(mvm->trans,
|
||||
mvm->trans->dbg.lmac_error_event_table[1],
|
||||
NULL))
|
||||
return true;
|
||||
return FW_ERROR;
|
||||
|
||||
/* check for umac error */
|
||||
if (iwl_fwrt_read_err_table(mvm->trans,
|
||||
mvm->trans->dbg.umac_error_event_table,
|
||||
NULL))
|
||||
return true;
|
||||
return FW_ERROR;
|
||||
|
||||
return false;
|
||||
return FW_ALIVE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3492,6 +3504,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
|
||||
bool d0i3_first = fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_D0I3_END_FIRST);
|
||||
bool resume_notif_based = iwl_mvm_d3_resume_notif_based(mvm);
|
||||
enum rt_status rt_status;
|
||||
bool keep = false;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
@@ -3515,14 +3528,19 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
|
||||
|
||||
iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
|
||||
|
||||
if (iwl_mvm_check_rt_status(mvm, vif)) {
|
||||
IWL_ERR(mvm, "FW Error occurred during suspend. Restarting.\n");
|
||||
rt_status = iwl_mvm_check_rt_status(mvm, vif);
|
||||
if (rt_status != FW_ALIVE) {
|
||||
set_bit(STATUS_FW_ERROR, &mvm->trans->status);
|
||||
iwl_mvm_dump_nic_error_log(mvm);
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt,
|
||||
IWL_FW_INI_TIME_POINT_FW_ASSERT, NULL);
|
||||
iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert,
|
||||
false, 0);
|
||||
if (rt_status == FW_ERROR) {
|
||||
IWL_ERR(mvm, "FW Error occurred during suspend. Restarting.\n");
|
||||
iwl_mvm_dump_nic_error_log(mvm);
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt,
|
||||
IWL_FW_INI_TIME_POINT_FW_ASSERT,
|
||||
NULL);
|
||||
iwl_fw_dbg_collect_desc(&mvm->fwrt,
|
||||
&iwl_dump_desc_assert,
|
||||
false, 0);
|
||||
}
|
||||
ret = 1;
|
||||
goto err;
|
||||
}
|
||||
@@ -3679,6 +3697,7 @@ int iwl_mvm_fast_resume(struct iwl_mvm *mvm)
|
||||
.notif_expected =
|
||||
IWL_D3_NOTIF_D3_END_NOTIF,
|
||||
};
|
||||
enum rt_status rt_status;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
@@ -3688,14 +3707,20 @@ int iwl_mvm_fast_resume(struct iwl_mvm *mvm)
|
||||
mvm->last_reset_or_resume_time_jiffies = jiffies;
|
||||
iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
|
||||
|
||||
if (iwl_mvm_check_rt_status(mvm, NULL)) {
|
||||
IWL_ERR(mvm, "FW Error occurred during suspend. Restarting.\n");
|
||||
rt_status = iwl_mvm_check_rt_status(mvm, NULL);
|
||||
if (rt_status != FW_ALIVE) {
|
||||
set_bit(STATUS_FW_ERROR, &mvm->trans->status);
|
||||
iwl_mvm_dump_nic_error_log(mvm);
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt,
|
||||
IWL_FW_INI_TIME_POINT_FW_ASSERT, NULL);
|
||||
iwl_fw_dbg_collect_desc(&mvm->fwrt, &iwl_dump_desc_assert,
|
||||
false, 0);
|
||||
if (rt_status == FW_ERROR) {
|
||||
IWL_ERR(mvm,
|
||||
"iwl_mvm_check_rt_status failed, device is gone during suspend\n");
|
||||
iwl_mvm_dump_nic_error_log(mvm);
|
||||
iwl_dbg_tlv_time_point(&mvm->fwrt,
|
||||
IWL_FW_INI_TIME_POINT_FW_ASSERT,
|
||||
NULL);
|
||||
iwl_fw_dbg_collect_desc(&mvm->fwrt,
|
||||
&iwl_dump_desc_assert,
|
||||
false, 0);
|
||||
}
|
||||
mvm->trans->state = IWL_TRANS_NO_FW;
|
||||
ret = -ENODEV;
|
||||
|
||||
|
||||
@@ -1479,6 +1479,13 @@ static ssize_t iwl_dbgfs_fw_dbg_clear_write(struct iwl_mvm *mvm,
|
||||
if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/*
|
||||
* If the firmware is not running, silently succeed since there is
|
||||
* no data to clear.
|
||||
*/
|
||||
if (!iwl_mvm_firmware_running(mvm))
|
||||
return count;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
iwl_fw_dbg_clear_monitor_buf(&mvm->fwrt);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
@@ -995,7 +995,7 @@ iwl_mvm_decode_he_phy_ru_alloc(struct iwl_mvm_rx_phy_data *phy_data,
|
||||
*/
|
||||
u8 ru = le32_get_bits(phy_data->d1, IWL_RX_PHY_DATA1_HE_RU_ALLOC_MASK);
|
||||
u32 rate_n_flags = phy_data->rate_n_flags;
|
||||
u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK_V1;
|
||||
u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK;
|
||||
u8 offs = 0;
|
||||
|
||||
rx_status->bw = RATE_INFO_BW_HE_RU;
|
||||
@@ -1050,13 +1050,13 @@ iwl_mvm_decode_he_phy_ru_alloc(struct iwl_mvm_rx_phy_data *phy_data,
|
||||
|
||||
if (he_mu)
|
||||
he_mu->flags2 |=
|
||||
le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK_V1,
|
||||
le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK,
|
||||
rate_n_flags),
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW);
|
||||
else if (he_type == RATE_MCS_HE_TYPE_TRIG_V1)
|
||||
else if (he_type == RATE_MCS_HE_TYPE_TRIG)
|
||||
he->data6 |=
|
||||
cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW_KNOWN) |
|
||||
le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK_V1,
|
||||
le16_encode_bits(FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK,
|
||||
rate_n_flags),
|
||||
IEEE80211_RADIOTAP_HE_DATA6_TB_PPDU_BW);
|
||||
}
|
||||
|
||||
@@ -1030,6 +1030,8 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,
|
||||
/* End TE, notify mac80211 */
|
||||
mvmvif->time_event_data.id = SESSION_PROTECT_CONF_MAX_ID;
|
||||
mvmvif->time_event_data.link_id = -1;
|
||||
/* set the bit so the ROC cleanup will actually clean up */
|
||||
set_bit(IWL_MVM_STATUS_ROC_P2P_RUNNING, &mvm->status);
|
||||
iwl_mvm_roc_finished(mvm);
|
||||
ieee80211_remain_on_channel_expired(mvm->hw);
|
||||
} else if (le32_to_cpu(notif->start)) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
|
||||
/*
|
||||
* Copyright (C) 2003-2015, 2018-2024 Intel Corporation
|
||||
* Copyright (C) 2003-2015, 2018-2025 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
@@ -646,7 +646,8 @@ dma_addr_t iwl_pcie_get_sgt_tb_phys(struct sg_table *sgt, unsigned int offset,
|
||||
unsigned int len);
|
||||
struct sg_table *iwl_pcie_prep_tso(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
struct iwl_cmd_meta *cmd_meta,
|
||||
u8 **hdr, unsigned int hdr_room);
|
||||
u8 **hdr, unsigned int hdr_room,
|
||||
unsigned int offset);
|
||||
|
||||
void iwl_pcie_free_tso_pages(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
struct iwl_cmd_meta *cmd_meta);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018-2020, 2023-2024 Intel Corporation
|
||||
* Copyright (C) 2018-2020, 2023-2025 Intel Corporation
|
||||
*/
|
||||
#include <net/tso.h>
|
||||
#include <linux/tcp.h>
|
||||
@@ -188,7 +188,8 @@ static int iwl_txq_gen2_build_amsdu(struct iwl_trans *trans,
|
||||
(3 + snap_ip_tcp_hdrlen + sizeof(struct ethhdr));
|
||||
|
||||
/* Our device supports 9 segments at most, it will fit in 1 page */
|
||||
sgt = iwl_pcie_prep_tso(trans, skb, out_meta, &start_hdr, hdr_room);
|
||||
sgt = iwl_pcie_prep_tso(trans, skb, out_meta, &start_hdr, hdr_room,
|
||||
snap_ip_tcp_hdrlen + hdr_len);
|
||||
if (!sgt)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -347,6 +348,7 @@ iwl_tfh_tfd *iwl_txq_gen2_build_tx_amsdu(struct iwl_trans *trans,
|
||||
return tfd;
|
||||
|
||||
out_err:
|
||||
iwl_pcie_free_tso_pages(trans, skb, out_meta);
|
||||
iwl_txq_gen2_tfd_unmap(trans, out_meta, tfd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2003-2014, 2018-2021, 2023-2024 Intel Corporation
|
||||
* Copyright (C) 2003-2014, 2018-2021, 2023-2025 Intel Corporation
|
||||
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2016-2017 Intel Deutschland GmbH
|
||||
*/
|
||||
@@ -1855,6 +1855,7 @@ dma_addr_t iwl_pcie_get_sgt_tb_phys(struct sg_table *sgt, unsigned int offset,
|
||||
* @cmd_meta: command meta to store the scatter list information for unmapping
|
||||
* @hdr: output argument for TSO headers
|
||||
* @hdr_room: requested length for TSO headers
|
||||
* @offset: offset into the data from which mapping should start
|
||||
*
|
||||
* Allocate space for a scatter gather list and TSO headers and map the SKB
|
||||
* using the scatter gather list. The SKB is unmapped again when the page is
|
||||
@@ -1864,18 +1865,20 @@ dma_addr_t iwl_pcie_get_sgt_tb_phys(struct sg_table *sgt, unsigned int offset,
|
||||
*/
|
||||
struct sg_table *iwl_pcie_prep_tso(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
struct iwl_cmd_meta *cmd_meta,
|
||||
u8 **hdr, unsigned int hdr_room)
|
||||
u8 **hdr, unsigned int hdr_room,
|
||||
unsigned int offset)
|
||||
{
|
||||
struct sg_table *sgt;
|
||||
unsigned int n_segments;
|
||||
|
||||
if (WARN_ON_ONCE(skb_has_frag_list(skb)))
|
||||
return NULL;
|
||||
|
||||
n_segments = DIV_ROUND_UP(skb->len - offset, skb_shinfo(skb)->gso_size);
|
||||
*hdr = iwl_pcie_get_page_hdr(trans,
|
||||
hdr_room + __alignof__(struct sg_table) +
|
||||
sizeof(struct sg_table) +
|
||||
(skb_shinfo(skb)->nr_frags + 1) *
|
||||
sizeof(struct scatterlist),
|
||||
n_segments * sizeof(struct scatterlist),
|
||||
skb);
|
||||
if (!*hdr)
|
||||
return NULL;
|
||||
@@ -1883,11 +1886,11 @@ struct sg_table *iwl_pcie_prep_tso(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
sgt = (void *)PTR_ALIGN(*hdr + hdr_room, __alignof__(struct sg_table));
|
||||
sgt->sgl = (void *)(sgt + 1);
|
||||
|
||||
sg_init_table(sgt->sgl, skb_shinfo(skb)->nr_frags + 1);
|
||||
sg_init_table(sgt->sgl, n_segments);
|
||||
|
||||
/* Only map the data, not the header (it is copied to the TSO page) */
|
||||
sgt->orig_nents = skb_to_sgvec(skb, sgt->sgl, skb_headlen(skb),
|
||||
skb->data_len);
|
||||
sgt->orig_nents = skb_to_sgvec(skb, sgt->sgl, offset,
|
||||
skb->len - offset);
|
||||
if (WARN_ON_ONCE(sgt->orig_nents <= 0))
|
||||
return NULL;
|
||||
|
||||
@@ -1939,7 +1942,8 @@ static int iwl_fill_data_tbs_amsdu(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
(3 + snap_ip_tcp_hdrlen + sizeof(struct ethhdr)) + iv_len;
|
||||
|
||||
/* Our device supports 9 segments at most, it will fit in 1 page */
|
||||
sgt = iwl_pcie_prep_tso(trans, skb, out_meta, &start_hdr, hdr_room);
|
||||
sgt = iwl_pcie_prep_tso(trans, skb, out_meta, &start_hdr, hdr_room,
|
||||
snap_ip_tcp_hdrlen + hdr_len + iv_len);
|
||||
if (!sgt)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -128,8 +128,10 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
|
||||
if (!nvme_ctrl_sgl_supported(ctrl))
|
||||
dev_warn_once(ctrl->device, "using unchecked data buffer\n");
|
||||
if (has_metadata) {
|
||||
if (!supports_metadata)
|
||||
return -EINVAL;
|
||||
if (!supports_metadata) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (!nvme_ctrl_meta_sgl_supported(ctrl))
|
||||
dev_warn_once(ctrl->device,
|
||||
"using unchecked metadata buffer\n");
|
||||
@@ -139,8 +141,10 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
|
||||
struct iov_iter iter;
|
||||
|
||||
/* fixedbufs is only for non-vectored io */
|
||||
if (WARN_ON_ONCE(flags & NVME_IOCTL_VEC))
|
||||
return -EINVAL;
|
||||
if (WARN_ON_ONCE(flags & NVME_IOCTL_VEC)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
ret = io_uring_cmd_import_fixed(ubuffer, bufflen,
|
||||
rq_data_dir(req), &iter, ioucmd);
|
||||
if (ret < 0)
|
||||
|
||||
+13
-8
@@ -1982,6 +1982,18 @@ static void nvme_map_cmb(struct nvme_dev *dev)
|
||||
if (offset > bar_size)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Controllers may support a CMB size larger than their BAR, for
|
||||
* example, due to being behind a bridge. Reduce the CMB to the
|
||||
* reported size of the BAR
|
||||
*/
|
||||
size = min(size, bar_size - offset);
|
||||
|
||||
if (!IS_ALIGNED(size, memremap_compat_align()) ||
|
||||
!IS_ALIGNED(pci_resource_start(pdev, bar),
|
||||
memremap_compat_align()))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Tell the controller about the host side address mapping the CMB,
|
||||
* and enable CMB decoding for the NVMe 1.4+ scheme:
|
||||
@@ -1992,17 +2004,10 @@ static void nvme_map_cmb(struct nvme_dev *dev)
|
||||
dev->bar + NVME_REG_CMBMSC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Controllers may support a CMB size larger than their BAR,
|
||||
* for example, due to being behind a bridge. Reduce the CMB to
|
||||
* the reported size of the BAR
|
||||
*/
|
||||
if (size > bar_size - offset)
|
||||
size = bar_size - offset;
|
||||
|
||||
if (pci_p2pdma_add_resource(pdev, bar, size, offset)) {
|
||||
dev_warn(dev->ctrl.device,
|
||||
"failed to register the CMB\n");
|
||||
hi_lo_writeq(0, dev->bar + NVME_REG_CMBMSC);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+36
-9
@@ -217,6 +217,19 @@ static inline int nvme_tcp_queue_id(struct nvme_tcp_queue *queue)
|
||||
return queue - queue->ctrl->queues;
|
||||
}
|
||||
|
||||
static inline bool nvme_tcp_recv_pdu_supported(enum nvme_tcp_pdu_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case nvme_tcp_c2h_term:
|
||||
case nvme_tcp_c2h_data:
|
||||
case nvme_tcp_r2t:
|
||||
case nvme_tcp_rsp:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the queue is TLS encrypted
|
||||
*/
|
||||
@@ -775,7 +788,7 @@ static void nvme_tcp_handle_c2h_term(struct nvme_tcp_queue *queue,
|
||||
[NVME_TCP_FES_PDU_SEQ_ERR] = "PDU Sequence Error",
|
||||
[NVME_TCP_FES_HDR_DIGEST_ERR] = "Header Digest Error",
|
||||
[NVME_TCP_FES_DATA_OUT_OF_RANGE] = "Data Transfer Out Of Range",
|
||||
[NVME_TCP_FES_R2T_LIMIT_EXCEEDED] = "R2T Limit Exceeded",
|
||||
[NVME_TCP_FES_DATA_LIMIT_EXCEEDED] = "Data Transfer Limit Exceeded",
|
||||
[NVME_TCP_FES_UNSUPPORTED_PARAM] = "Unsupported Parameter",
|
||||
};
|
||||
|
||||
@@ -818,6 +831,16 @@ static int nvme_tcp_recv_pdu(struct nvme_tcp_queue *queue, struct sk_buff *skb,
|
||||
return 0;
|
||||
|
||||
hdr = queue->pdu;
|
||||
if (unlikely(hdr->hlen != sizeof(struct nvme_tcp_rsp_pdu))) {
|
||||
if (!nvme_tcp_recv_pdu_supported(hdr->type))
|
||||
goto unsupported_pdu;
|
||||
|
||||
dev_err(queue->ctrl->ctrl.device,
|
||||
"pdu type %d has unexpected header length (%d)\n",
|
||||
hdr->type, hdr->hlen);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
if (unlikely(hdr->type == nvme_tcp_c2h_term)) {
|
||||
/*
|
||||
* C2HTermReq never includes Header or Data digests.
|
||||
@@ -850,10 +873,13 @@ static int nvme_tcp_recv_pdu(struct nvme_tcp_queue *queue, struct sk_buff *skb,
|
||||
nvme_tcp_init_recv_ctx(queue);
|
||||
return nvme_tcp_handle_r2t(queue, (void *)queue->pdu);
|
||||
default:
|
||||
dev_err(queue->ctrl->ctrl.device,
|
||||
"unsupported pdu type (%d)\n", hdr->type);
|
||||
return -EINVAL;
|
||||
goto unsupported_pdu;
|
||||
}
|
||||
|
||||
unsupported_pdu:
|
||||
dev_err(queue->ctrl->ctrl.device,
|
||||
"unsupported pdu type (%d)\n", hdr->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline void nvme_tcp_end_request(struct request *rq, u16 status)
|
||||
@@ -1495,11 +1521,11 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
|
||||
msg.msg_flags = MSG_WAITALL;
|
||||
ret = kernel_recvmsg(queue->sock, &msg, &iov, 1,
|
||||
iov.iov_len, msg.msg_flags);
|
||||
if (ret < sizeof(*icresp)) {
|
||||
if (ret >= 0 && ret < sizeof(*icresp))
|
||||
ret = -ECONNRESET;
|
||||
if (ret < 0) {
|
||||
pr_warn("queue %d: failed to receive icresp, error %d\n",
|
||||
nvme_tcp_queue_id(queue), ret);
|
||||
if (ret >= 0)
|
||||
ret = -ECONNRESET;
|
||||
goto free_icresp;
|
||||
}
|
||||
ret = -ENOTCONN;
|
||||
@@ -2699,6 +2725,7 @@ static int nvme_tcp_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob)
|
||||
{
|
||||
struct nvme_tcp_queue *queue = hctx->driver_data;
|
||||
struct sock *sk = queue->sock->sk;
|
||||
int ret;
|
||||
|
||||
if (!test_bit(NVME_TCP_Q_LIVE, &queue->flags))
|
||||
return 0;
|
||||
@@ -2706,9 +2733,9 @@ static int nvme_tcp_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob)
|
||||
set_bit(NVME_TCP_Q_POLLING, &queue->flags);
|
||||
if (sk_can_busy_loop(sk) && skb_queue_empty_lockless(&sk->sk_receive_queue))
|
||||
sk_busy_loop(sk, true);
|
||||
nvme_tcp_try_recv(queue);
|
||||
ret = nvme_tcp_try_recv(queue);
|
||||
clear_bit(NVME_TCP_Q_POLLING, &queue->flags);
|
||||
return queue->nr_cqe;
|
||||
return ret < 0 ? ret : queue->nr_cqe;
|
||||
}
|
||||
|
||||
static int nvme_tcp_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
|
||||
|
||||
@@ -647,7 +647,6 @@ void nvmet_subsys_disc_changed(struct nvmet_subsys *subsys,
|
||||
struct nvmet_host *host);
|
||||
void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
|
||||
u8 event_info, u8 log_page);
|
||||
bool nvmet_subsys_nsid_exists(struct nvmet_subsys *subsys, u32 nsid);
|
||||
|
||||
#define NVMET_MIN_QUEUE_SIZE 16
|
||||
#define NVMET_MAX_QUEUE_SIZE 1024
|
||||
|
||||
@@ -571,10 +571,16 @@ static void nvmet_tcp_queue_response(struct nvmet_req *req)
|
||||
struct nvmet_tcp_cmd *cmd =
|
||||
container_of(req, struct nvmet_tcp_cmd, req);
|
||||
struct nvmet_tcp_queue *queue = cmd->queue;
|
||||
enum nvmet_tcp_recv_state queue_state;
|
||||
struct nvmet_tcp_cmd *queue_cmd;
|
||||
struct nvme_sgl_desc *sgl;
|
||||
u32 len;
|
||||
|
||||
if (unlikely(cmd == queue->cmd)) {
|
||||
/* Pairs with store_release in nvmet_prepare_receive_pdu() */
|
||||
queue_state = smp_load_acquire(&queue->rcv_state);
|
||||
queue_cmd = READ_ONCE(queue->cmd);
|
||||
|
||||
if (unlikely(cmd == queue_cmd)) {
|
||||
sgl = &cmd->req.cmd->common.dptr.sgl;
|
||||
len = le32_to_cpu(sgl->length);
|
||||
|
||||
@@ -583,7 +589,7 @@ static void nvmet_tcp_queue_response(struct nvmet_req *req)
|
||||
* Avoid using helpers, this might happen before
|
||||
* nvmet_req_init is completed.
|
||||
*/
|
||||
if (queue->rcv_state == NVMET_TCP_RECV_PDU &&
|
||||
if (queue_state == NVMET_TCP_RECV_PDU &&
|
||||
len && len <= cmd->req.port->inline_data_size &&
|
||||
nvme_is_write(cmd->req.cmd))
|
||||
return;
|
||||
@@ -847,8 +853,9 @@ static void nvmet_prepare_receive_pdu(struct nvmet_tcp_queue *queue)
|
||||
{
|
||||
queue->offset = 0;
|
||||
queue->left = sizeof(struct nvme_tcp_hdr);
|
||||
queue->cmd = NULL;
|
||||
queue->rcv_state = NVMET_TCP_RECV_PDU;
|
||||
WRITE_ONCE(queue->cmd, NULL);
|
||||
/* Ensure rcv_state is visible only after queue->cmd is set */
|
||||
smp_store_release(&queue->rcv_state, NVMET_TCP_RECV_PDU);
|
||||
}
|
||||
|
||||
static void nvmet_tcp_free_crypto(struct nvmet_tcp_queue *queue)
|
||||
|
||||
@@ -415,12 +415,12 @@ static int __init __reserved_mem_alloc_size(unsigned long node, const char *unam
|
||||
|
||||
prop = of_get_flat_dt_prop(node, "alignment", &len);
|
||||
if (prop) {
|
||||
if (len != dt_root_size_cells * sizeof(__be32)) {
|
||||
if (len != dt_root_addr_cells * sizeof(__be32)) {
|
||||
pr_err("invalid alignment property in '%s' node.\n",
|
||||
uname);
|
||||
return -EINVAL;
|
||||
}
|
||||
align = dt_mem_next_cell(dt_root_size_cells, &prop);
|
||||
align = dt_mem_next_cell(dt_root_addr_cells, &prop);
|
||||
}
|
||||
|
||||
nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
|
||||
|
||||
@@ -452,6 +452,7 @@ static int amd_pmf_probe(struct platform_device *pdev)
|
||||
|
||||
mutex_init(&dev->lock);
|
||||
mutex_init(&dev->update_mutex);
|
||||
mutex_init(&dev->cb_mutex);
|
||||
|
||||
apmf_acpi_init(dev);
|
||||
platform_set_drvdata(pdev, dev);
|
||||
@@ -477,6 +478,7 @@ static void amd_pmf_remove(struct platform_device *pdev)
|
||||
amd_pmf_dbgfs_unregister(dev);
|
||||
mutex_destroy(&dev->lock);
|
||||
mutex_destroy(&dev->update_mutex);
|
||||
mutex_destroy(&dev->cb_mutex);
|
||||
kfree(dev->buf);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,9 +106,12 @@ struct cookie_header {
|
||||
#define PMF_TA_IF_VERSION_MAJOR 1
|
||||
#define TA_PMF_ACTION_MAX 32
|
||||
#define TA_PMF_UNDO_MAX 8
|
||||
#define TA_OUTPUT_RESERVED_MEM 906
|
||||
#define TA_OUTPUT_RESERVED_MEM 922
|
||||
#define MAX_OPERATION_PARAMS 4
|
||||
|
||||
#define TA_ERROR_CRYPTO_INVALID_PARAM 0x20002
|
||||
#define TA_ERROR_CRYPTO_BIN_TOO_LARGE 0x2000d
|
||||
|
||||
#define PMF_IF_V1 1
|
||||
#define PMF_IF_V2 2
|
||||
|
||||
|
||||
@@ -297,12 +297,14 @@ int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf)
|
||||
|
||||
switch (pmf->current_profile) {
|
||||
case PLATFORM_PROFILE_PERFORMANCE:
|
||||
case PLATFORM_PROFILE_BALANCED_PERFORMANCE:
|
||||
mode = POWER_MODE_PERFORMANCE;
|
||||
break;
|
||||
case PLATFORM_PROFILE_BALANCED:
|
||||
mode = POWER_MODE_BALANCED_POWER;
|
||||
break;
|
||||
case PLATFORM_PROFILE_LOW_POWER:
|
||||
case PLATFORM_PROFILE_QUIET:
|
||||
mode = POWER_MODE_POWER_SAVER;
|
||||
break;
|
||||
default:
|
||||
@@ -387,6 +389,14 @@ static int amd_pmf_profile_set(struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amd_pmf_hidden_choices(void *drvdata, unsigned long *choices)
|
||||
{
|
||||
set_bit(PLATFORM_PROFILE_QUIET, choices);
|
||||
set_bit(PLATFORM_PROFILE_BALANCED_PERFORMANCE, choices);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amd_pmf_profile_probe(void *drvdata, unsigned long *choices)
|
||||
{
|
||||
set_bit(PLATFORM_PROFILE_LOW_POWER, choices);
|
||||
@@ -398,6 +408,7 @@ static int amd_pmf_profile_probe(void *drvdata, unsigned long *choices)
|
||||
|
||||
static const struct platform_profile_ops amd_pmf_profile_ops = {
|
||||
.probe = amd_pmf_profile_probe,
|
||||
.hidden_choices = amd_pmf_hidden_choices,
|
||||
.profile_get = amd_pmf_profile_get,
|
||||
.profile_set = amd_pmf_profile_set,
|
||||
};
|
||||
|
||||
@@ -27,8 +27,11 @@ module_param(pb_side_load, bool, 0444);
|
||||
MODULE_PARM_DESC(pb_side_load, "Sideload policy binaries debug policy failures");
|
||||
#endif
|
||||
|
||||
static const uuid_t amd_pmf_ta_uuid = UUID_INIT(0x6fd93b77, 0x3fb8, 0x524d,
|
||||
0xb1, 0x2d, 0xc5, 0x29, 0xb1, 0x3d, 0x85, 0x43);
|
||||
static const uuid_t amd_pmf_ta_uuid[] = { UUID_INIT(0xd9b39bf2, 0x66bd, 0x4154, 0xaf, 0xb8, 0x8a,
|
||||
0xcc, 0x2b, 0x2b, 0x60, 0xd6),
|
||||
UUID_INIT(0x6fd93b77, 0x3fb8, 0x524d, 0xb1, 0x2d, 0xc5,
|
||||
0x29, 0xb1, 0x3d, 0x85, 0x43),
|
||||
};
|
||||
|
||||
static const char *amd_pmf_uevent_as_str(unsigned int state)
|
||||
{
|
||||
@@ -321,9 +324,9 @@ static int amd_pmf_start_policy_engine(struct amd_pmf_dev *dev)
|
||||
*/
|
||||
schedule_delayed_work(&dev->pb_work, msecs_to_jiffies(pb_actions_ms * 3));
|
||||
} else {
|
||||
dev_err(dev->dev, "ta invoke cmd init failed err: %x\n", res);
|
||||
dev_dbg(dev->dev, "ta invoke cmd init failed err: %x\n", res);
|
||||
dev->smart_pc_enabled = false;
|
||||
return -EIO;
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -390,12 +393,12 @@ static int amd_pmf_amdtee_ta_match(struct tee_ioctl_version_data *ver, const voi
|
||||
return ver->impl_id == TEE_IMPL_ID_AMDTEE;
|
||||
}
|
||||
|
||||
static int amd_pmf_ta_open_session(struct tee_context *ctx, u32 *id)
|
||||
static int amd_pmf_ta_open_session(struct tee_context *ctx, u32 *id, const uuid_t *uuid)
|
||||
{
|
||||
struct tee_ioctl_open_session_arg sess_arg = {};
|
||||
int rc;
|
||||
|
||||
export_uuid(sess_arg.uuid, &amd_pmf_ta_uuid);
|
||||
export_uuid(sess_arg.uuid, uuid);
|
||||
sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC;
|
||||
sess_arg.num_params = 0;
|
||||
|
||||
@@ -434,7 +437,7 @@ static int amd_pmf_register_input_device(struct amd_pmf_dev *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amd_pmf_tee_init(struct amd_pmf_dev *dev)
|
||||
static int amd_pmf_tee_init(struct amd_pmf_dev *dev, const uuid_t *uuid)
|
||||
{
|
||||
u32 size;
|
||||
int ret;
|
||||
@@ -445,7 +448,7 @@ static int amd_pmf_tee_init(struct amd_pmf_dev *dev)
|
||||
return PTR_ERR(dev->tee_ctx);
|
||||
}
|
||||
|
||||
ret = amd_pmf_ta_open_session(dev->tee_ctx, &dev->session_id);
|
||||
ret = amd_pmf_ta_open_session(dev->tee_ctx, &dev->session_id, uuid);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "Failed to open TA session (%d)\n", ret);
|
||||
ret = -EINVAL;
|
||||
@@ -489,7 +492,8 @@ static void amd_pmf_tee_deinit(struct amd_pmf_dev *dev)
|
||||
|
||||
int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev)
|
||||
{
|
||||
int ret;
|
||||
bool status;
|
||||
int ret, i;
|
||||
|
||||
ret = apmf_check_smart_pc(dev);
|
||||
if (ret) {
|
||||
@@ -502,10 +506,6 @@ int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = amd_pmf_tee_init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
INIT_DELAYED_WORK(&dev->pb_work, amd_pmf_invoke_cmd);
|
||||
|
||||
ret = amd_pmf_set_dram_addr(dev, true);
|
||||
@@ -534,8 +534,30 @@ int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev)
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = amd_pmf_start_policy_engine(dev);
|
||||
if (ret)
|
||||
for (i = 0; i < ARRAY_SIZE(amd_pmf_ta_uuid); i++) {
|
||||
ret = amd_pmf_tee_init(dev, &amd_pmf_ta_uuid[i]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = amd_pmf_start_policy_engine(dev);
|
||||
switch (ret) {
|
||||
case TA_PMF_TYPE_SUCCESS:
|
||||
status = true;
|
||||
break;
|
||||
case TA_ERROR_CRYPTO_INVALID_PARAM:
|
||||
case TA_ERROR_CRYPTO_BIN_TOO_LARGE:
|
||||
amd_pmf_tee_deinit(dev);
|
||||
status = false;
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (status)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!status && !pb_side_load)
|
||||
goto error;
|
||||
|
||||
if (pb_side_load)
|
||||
|
||||
@@ -139,6 +139,13 @@ static const struct dmi_system_id button_array_table[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go 3"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Microsoft Surface Go 4",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go 4"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@@ -404,6 +404,11 @@ static const struct intel_vsec_platform_info oobmsm_info = {
|
||||
.caps = VSEC_CAP_TELEMETRY | VSEC_CAP_SDSI | VSEC_CAP_TPMI,
|
||||
};
|
||||
|
||||
/* DMR OOBMSM info */
|
||||
static const struct intel_vsec_platform_info dmr_oobmsm_info = {
|
||||
.caps = VSEC_CAP_TELEMETRY | VSEC_CAP_TPMI,
|
||||
};
|
||||
|
||||
/* TGL info */
|
||||
static const struct intel_vsec_platform_info tgl_info = {
|
||||
.caps = VSEC_CAP_TELEMETRY,
|
||||
@@ -420,6 +425,7 @@ static const struct intel_vsec_platform_info lnl_info = {
|
||||
#define PCI_DEVICE_ID_INTEL_VSEC_MTL_M 0x7d0d
|
||||
#define PCI_DEVICE_ID_INTEL_VSEC_MTL_S 0xad0d
|
||||
#define PCI_DEVICE_ID_INTEL_VSEC_OOBMSM 0x09a7
|
||||
#define PCI_DEVICE_ID_INTEL_VSEC_OOBMSM_DMR 0x09a1
|
||||
#define PCI_DEVICE_ID_INTEL_VSEC_RPL 0xa77d
|
||||
#define PCI_DEVICE_ID_INTEL_VSEC_TGL 0x9a0d
|
||||
#define PCI_DEVICE_ID_INTEL_VSEC_LNL_M 0x647d
|
||||
@@ -430,6 +436,7 @@ static const struct pci_device_id intel_vsec_pci_ids[] = {
|
||||
{ PCI_DEVICE_DATA(INTEL, VSEC_MTL_M, &mtl_info) },
|
||||
{ PCI_DEVICE_DATA(INTEL, VSEC_MTL_S, &mtl_info) },
|
||||
{ PCI_DEVICE_DATA(INTEL, VSEC_OOBMSM, &oobmsm_info) },
|
||||
{ PCI_DEVICE_DATA(INTEL, VSEC_OOBMSM_DMR, &dmr_oobmsm_info) },
|
||||
{ PCI_DEVICE_DATA(INTEL, VSEC_RPL, &tgl_info) },
|
||||
{ PCI_DEVICE_DATA(INTEL, VSEC_TGL, &tgl_info) },
|
||||
{ PCI_DEVICE_DATA(INTEL, VSEC_LNL_M, &lnl_info) },
|
||||
|
||||
@@ -9972,6 +9972,7 @@ static const struct tpacpi_quirk battery_quirk_table[] __initconst = {
|
||||
* Individual addressing is broken on models that expose the
|
||||
* primary battery as BAT1.
|
||||
*/
|
||||
TPACPI_Q_LNV('G', '8', true), /* ThinkPad X131e */
|
||||
TPACPI_Q_LNV('8', 'F', true), /* Thinkpad X120e */
|
||||
TPACPI_Q_LNV('J', '7', true), /* B5400 */
|
||||
TPACPI_Q_LNV('J', 'I', true), /* Thinkpad 11e */
|
||||
|
||||
+5
-4
@@ -596,7 +596,7 @@ affs_extent_file_ofs(struct inode *inode, u32 newsize)
|
||||
BUG_ON(tmp > bsize);
|
||||
AFFS_DATA_HEAD(bh)->ptype = cpu_to_be32(T_DATA);
|
||||
AFFS_DATA_HEAD(bh)->key = cpu_to_be32(inode->i_ino);
|
||||
AFFS_DATA_HEAD(bh)->sequence = cpu_to_be32(bidx);
|
||||
AFFS_DATA_HEAD(bh)->sequence = cpu_to_be32(bidx + 1);
|
||||
AFFS_DATA_HEAD(bh)->size = cpu_to_be32(tmp);
|
||||
affs_fix_checksum(sb, bh);
|
||||
bh->b_state &= ~(1UL << BH_New);
|
||||
@@ -724,7 +724,8 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
|
||||
tmp = min(bsize - boff, to - from);
|
||||
BUG_ON(boff + tmp > bsize || tmp > bsize);
|
||||
memcpy(AFFS_DATA(bh) + boff, data + from, tmp);
|
||||
be32_add_cpu(&AFFS_DATA_HEAD(bh)->size, tmp);
|
||||
AFFS_DATA_HEAD(bh)->size = cpu_to_be32(
|
||||
max(boff + tmp, be32_to_cpu(AFFS_DATA_HEAD(bh)->size)));
|
||||
affs_fix_checksum(sb, bh);
|
||||
mark_buffer_dirty_inode(bh, inode);
|
||||
written += tmp;
|
||||
@@ -746,7 +747,7 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
|
||||
if (buffer_new(bh)) {
|
||||
AFFS_DATA_HEAD(bh)->ptype = cpu_to_be32(T_DATA);
|
||||
AFFS_DATA_HEAD(bh)->key = cpu_to_be32(inode->i_ino);
|
||||
AFFS_DATA_HEAD(bh)->sequence = cpu_to_be32(bidx);
|
||||
AFFS_DATA_HEAD(bh)->sequence = cpu_to_be32(bidx + 1);
|
||||
AFFS_DATA_HEAD(bh)->size = cpu_to_be32(bsize);
|
||||
AFFS_DATA_HEAD(bh)->next = 0;
|
||||
bh->b_state &= ~(1UL << BH_New);
|
||||
@@ -780,7 +781,7 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
|
||||
if (buffer_new(bh)) {
|
||||
AFFS_DATA_HEAD(bh)->ptype = cpu_to_be32(T_DATA);
|
||||
AFFS_DATA_HEAD(bh)->key = cpu_to_be32(inode->i_ino);
|
||||
AFFS_DATA_HEAD(bh)->sequence = cpu_to_be32(bidx);
|
||||
AFFS_DATA_HEAD(bh)->sequence = cpu_to_be32(bidx + 1);
|
||||
AFFS_DATA_HEAD(bh)->size = cpu_to_be32(tmp);
|
||||
AFFS_DATA_HEAD(bh)->next = 0;
|
||||
bh->b_state &= ~(1UL << BH_New);
|
||||
|
||||
+32
-27
@@ -1021,8 +1021,8 @@ struct journal_buf *bch2_next_write_buffer_flush_journal_buf(struct journal *j,
|
||||
|
||||
/* allocate journal on a device: */
|
||||
|
||||
static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr,
|
||||
bool new_fs, struct closure *cl)
|
||||
static int bch2_set_nr_journal_buckets_iter(struct bch_dev *ca, unsigned nr,
|
||||
bool new_fs, struct closure *cl)
|
||||
{
|
||||
struct bch_fs *c = ca->fs;
|
||||
struct journal_device *ja = &ca->journal;
|
||||
@@ -1150,26 +1150,20 @@ err_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate more journal space at runtime - not currently making use if it, but
|
||||
* the code works:
|
||||
*/
|
||||
int bch2_set_nr_journal_buckets(struct bch_fs *c, struct bch_dev *ca,
|
||||
unsigned nr)
|
||||
static int bch2_set_nr_journal_buckets_loop(struct bch_fs *c, struct bch_dev *ca,
|
||||
unsigned nr, bool new_fs)
|
||||
{
|
||||
struct journal_device *ja = &ca->journal;
|
||||
struct closure cl;
|
||||
int ret = 0;
|
||||
|
||||
struct closure cl;
|
||||
closure_init_stack(&cl);
|
||||
|
||||
down_write(&c->state_lock);
|
||||
|
||||
/* don't handle reducing nr of buckets yet: */
|
||||
if (nr < ja->nr)
|
||||
goto unlock;
|
||||
return 0;
|
||||
|
||||
while (ja->nr < nr) {
|
||||
while (!ret && ja->nr < nr) {
|
||||
struct disk_reservation disk_res = { 0, 0, 0 };
|
||||
|
||||
/*
|
||||
@@ -1182,27 +1176,38 @@ int bch2_set_nr_journal_buckets(struct bch_fs *c, struct bch_dev *ca,
|
||||
* filesystem-wide allocation will succeed, this is a device
|
||||
* specific allocation - we can hang here:
|
||||
*/
|
||||
if (!new_fs) {
|
||||
ret = bch2_disk_reservation_get(c, &disk_res,
|
||||
bucket_to_sector(ca, nr - ja->nr), 1, 0);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
ret = bch2_disk_reservation_get(c, &disk_res,
|
||||
bucket_to_sector(ca, nr - ja->nr), 1, 0);
|
||||
if (ret)
|
||||
break;
|
||||
ret = bch2_set_nr_journal_buckets_iter(ca, nr, new_fs, &cl);
|
||||
|
||||
ret = __bch2_set_nr_journal_buckets(ca, nr, false, &cl);
|
||||
if (ret == -BCH_ERR_bucket_alloc_blocked ||
|
||||
ret == -BCH_ERR_open_buckets_empty)
|
||||
ret = 0; /* wait and retry */
|
||||
|
||||
bch2_disk_reservation_put(c, &disk_res);
|
||||
|
||||
closure_sync(&cl);
|
||||
|
||||
if (ret &&
|
||||
ret != -BCH_ERR_bucket_alloc_blocked &&
|
||||
ret != -BCH_ERR_open_buckets_empty)
|
||||
break;
|
||||
}
|
||||
|
||||
bch_err_fn(c, ret);
|
||||
unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate more journal space at runtime - not currently making use if it, but
|
||||
* the code works:
|
||||
*/
|
||||
int bch2_set_nr_journal_buckets(struct bch_fs *c, struct bch_dev *ca,
|
||||
unsigned nr)
|
||||
{
|
||||
down_write(&c->state_lock);
|
||||
int ret = bch2_set_nr_journal_buckets_loop(c, ca, nr, false);
|
||||
up_write(&c->state_lock);
|
||||
|
||||
bch_err_fn(c, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1228,7 +1233,7 @@ int bch2_dev_journal_alloc(struct bch_dev *ca, bool new_fs)
|
||||
min(1 << 13,
|
||||
(1 << 24) / ca->mi.bucket_size));
|
||||
|
||||
ret = __bch2_set_nr_journal_buckets(ca, nr, new_fs, NULL);
|
||||
ret = bch2_set_nr_journal_buckets_loop(ca->fs, ca, nr, new_fs);
|
||||
err:
|
||||
bch_err_fn(ca, ret);
|
||||
return ret;
|
||||
|
||||
+12
-13
@@ -74,20 +74,14 @@ static int bch2_bucket_is_movable(struct btree_trans *trans,
|
||||
struct move_bucket *b, u64 time)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bch_alloc_v4 _a;
|
||||
const struct bch_alloc_v4 *a;
|
||||
int ret;
|
||||
|
||||
if (bch2_bucket_is_open(trans->c,
|
||||
b->k.bucket.inode,
|
||||
b->k.bucket.offset))
|
||||
if (bch2_bucket_is_open(c, b->k.bucket.inode, b->k.bucket.offset))
|
||||
return 0;
|
||||
|
||||
k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_alloc,
|
||||
b->k.bucket, BTREE_ITER_cached);
|
||||
ret = bkey_err(k);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k = bch2_bkey_get_iter(trans, &iter, BTREE_ID_alloc,
|
||||
b->k.bucket, BTREE_ITER_cached);
|
||||
int ret = bkey_err(k);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -95,13 +89,18 @@ static int bch2_bucket_is_movable(struct btree_trans *trans,
|
||||
if (!ca)
|
||||
goto out;
|
||||
|
||||
a = bch2_alloc_to_v4(k, &_a);
|
||||
if (ca->mi.state != BCH_MEMBER_STATE_rw ||
|
||||
!bch2_dev_is_online(ca))
|
||||
goto out_put;
|
||||
|
||||
struct bch_alloc_v4 _a;
|
||||
const struct bch_alloc_v4 *a = bch2_alloc_to_v4(k, &_a);
|
||||
b->k.gen = a->gen;
|
||||
b->sectors = bch2_bucket_sectors_dirty(*a);
|
||||
u64 lru_idx = alloc_lru_idx_fragmentation(*a, ca);
|
||||
|
||||
ret = lru_idx && lru_idx <= time;
|
||||
|
||||
out_put:
|
||||
bch2_dev_put(ca);
|
||||
out:
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
+16
-8
@@ -69,14 +69,20 @@ enum bcachefs_metadata_version bch2_latest_compatible_version(enum bcachefs_meta
|
||||
return v;
|
||||
}
|
||||
|
||||
void bch2_set_version_incompat(struct bch_fs *c, enum bcachefs_metadata_version version)
|
||||
bool bch2_set_version_incompat(struct bch_fs *c, enum bcachefs_metadata_version version)
|
||||
{
|
||||
mutex_lock(&c->sb_lock);
|
||||
SET_BCH_SB_VERSION_INCOMPAT(c->disk_sb.sb,
|
||||
max(BCH_SB_VERSION_INCOMPAT(c->disk_sb.sb), version));
|
||||
c->disk_sb.sb->features[0] |= cpu_to_le64(BCH_FEATURE_incompat_version_field);
|
||||
bch2_write_super(c);
|
||||
mutex_unlock(&c->sb_lock);
|
||||
bool ret = (c->sb.features & BIT_ULL(BCH_FEATURE_incompat_version_field)) &&
|
||||
version <= c->sb.version_incompat_allowed;
|
||||
|
||||
if (ret) {
|
||||
mutex_lock(&c->sb_lock);
|
||||
SET_BCH_SB_VERSION_INCOMPAT(c->disk_sb.sb,
|
||||
max(BCH_SB_VERSION_INCOMPAT(c->disk_sb.sb), version));
|
||||
bch2_write_super(c);
|
||||
mutex_unlock(&c->sb_lock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char * const bch2_sb_fields[] = {
|
||||
@@ -1219,9 +1225,11 @@ void bch2_sb_upgrade(struct bch_fs *c, unsigned new_version, bool incompat)
|
||||
c->disk_sb.sb->version = cpu_to_le16(new_version);
|
||||
c->disk_sb.sb->features[0] |= cpu_to_le64(BCH_SB_FEATURES_ALL);
|
||||
|
||||
if (incompat)
|
||||
if (incompat) {
|
||||
SET_BCH_SB_VERSION_INCOMPAT_ALLOWED(c->disk_sb.sb,
|
||||
max(BCH_SB_VERSION_INCOMPAT_ALLOWED(c->disk_sb.sb), new_version));
|
||||
c->disk_sb.sb->features[0] |= cpu_to_le64(BCH_FEATURE_incompat_version_field);
|
||||
}
|
||||
}
|
||||
|
||||
static int bch2_sb_ext_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||
|
||||
@@ -21,17 +21,14 @@ static inline bool bch2_version_compatible(u16 version)
|
||||
void bch2_version_to_text(struct printbuf *, enum bcachefs_metadata_version);
|
||||
enum bcachefs_metadata_version bch2_latest_compatible_version(enum bcachefs_metadata_version);
|
||||
|
||||
void bch2_set_version_incompat(struct bch_fs *, enum bcachefs_metadata_version);
|
||||
bool bch2_set_version_incompat(struct bch_fs *, enum bcachefs_metadata_version);
|
||||
|
||||
static inline bool bch2_request_incompat_feature(struct bch_fs *c,
|
||||
enum bcachefs_metadata_version version)
|
||||
{
|
||||
if (unlikely(version > c->sb.version_incompat)) {
|
||||
if (version > c->sb.version_incompat_allowed)
|
||||
return false;
|
||||
bch2_set_version_incompat(c, version);
|
||||
}
|
||||
return true;
|
||||
return likely(version <= c->sb.version_incompat)
|
||||
? true
|
||||
: bch2_set_version_incompat(c, version);
|
||||
}
|
||||
|
||||
static inline size_t bch2_sb_field_bytes(struct bch_sb_field *f)
|
||||
|
||||
+7
-2
@@ -1382,8 +1382,13 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
|
||||
continue;
|
||||
}
|
||||
if (done_offset) {
|
||||
*done_offset = start - 1;
|
||||
return 0;
|
||||
/*
|
||||
* Move @end to the end of the processed range,
|
||||
* and exit the loop to unlock the processed extents.
|
||||
*/
|
||||
end = start - 1;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
ret = -ENOSPC;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user