Merge remote-tracking branch 'sm8250/lineage-20' into lineage-21

* sm8250/lineage-20:
  msm/sde: prevent double register of input handler
  scsi: ufs: Use WQ_HIGHPRI for gating work.
  scsi: ufs: disable clock scaling
  scsi: ufs: atomic update for clkgating_enable
  scsi: ufs: call single_release to avoid memory leak
  scsi: ufs: Disable interrupt in reset path
  cpuidle: Do not select menu and ladder governors
  msm: ipa3: Changes to fix memory leak issue
  msm: ipa: avoid OOM Killer for temp allocations
  msm: ipa: use lower order pages
  UPSTREAM: HID: playstation: support updated DualSense rumble mode.
  UPSTREAM: HID: playstation: add initial DualSense Edge controller support
  UPSTREAM: HID: playstation: add DualSense player LED support.
  UPSTREAM: HID: playstation: add microphone mute support for DualSense.
  UPSTREAM: HID: playstation: add initial DualSense lightbar support.
  UPSTREAM: HID: playstation: fix array size comparison (off-by-one)
  UPSTREAM: HID: playstation: fix unused variable in ps_battery_get_property.
  BACKPORT: HID: playstation: report DualSense hardware and firmware version.
  BACKPORT: HID: playstation: add DualSense classic rumble support.
  UPSTREAM: HID: playstation: add DualSense Bluetooth support.
  ...

Change-Id: I8299aa7e799947d78ec126259d58aa956f49ca72
This commit is contained in:
Michael Bestas committed 2024-06-22 23:04:28 +03:00
commit 4788d52aae
159 files changed
+2254 -1230

No files matched your search

-1
View File
@@ -94,7 +94,6 @@ class KernelInclude(Include):
# HINT: this is the only line I had to change / commented out:
#path = utils.relative_path(None, path)
path = nodes.reprunicode(path)
encoding = self.options.get(
'encoding', self.state.document.settings.input_encoding)
e_handler=self.state.document.settings.input_encoding_error_handler
+1 -1
View File
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
VERSION = 4
PATCHLEVEL = 19
SUBLEVEL = 312
SUBLEVEL = 315
EXTRAVERSION =
NAME = "People's Front"
+1 -1
View File
@@ -964,7 +964,7 @@ put_tv32(struct timeval32 __user *o, struct timespec64 *i)
}
static inline long
put_tv_to_tv32(struct timeval32 __user *o, struct __kernel_old_timeval *i)
put_tv_to_tv32(struct timeval32 __user *o, struct timeval *i)
{
return copy_to_user(o, &(struct timeval32){
.tv_sec = i->tv_sec,
-1
View File
@@ -170,7 +170,6 @@
};
gmac: ethernet@8000 {
#interrupt-cells = <1>;
compatible = "snps,dwmac";
reg = <0x8000 0x2000>;
interrupts = <10>;
+2 -5
View File
@@ -232,7 +232,7 @@
clock-names = "hif_sel";
};
cir: cir@10009000 {
cir: ir-receiver@10009000 {
compatible = "mediatek,mt7622-cir";
reg = <0 0x10009000 0 0x1000>;
interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_LOW>;
@@ -459,7 +459,6 @@
<&pericfg CLK_PERI_AUXADC_PD>;
clock-names = "therm", "auxadc";
resets = <&pericfg MT7622_PERI_THERM_SW_RST>;
reset-names = "therm";
mediatek,auxadc = <&auxadc>;
mediatek,apmixedsys = <&apmixedsys>;
nvmem-cells = <&thermal_calibration>;
@@ -846,9 +845,7 @@
};
eth: ethernet@1b100000 {
compatible = "mediatek,mt7622-eth",
"mediatek,mt2701-eth",
"syscon";
compatible = "mediatek,mt7622-eth";
reg = <0 0x1b100000 0 0x20000>;
interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 224 IRQ_TYPE_LEVEL_LOW>,
+22 -7
View File
@@ -426,16 +426,22 @@
gpio1830-supply = <&vcc_1v8>;
};
&pmu_io_domains {
status = "okay";
pmu1830-supply = <&vcc_1v8>;
};
&pwm2 {
status = "okay";
&pcie_clkreqn_cpm {
rockchip,pins =
<2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>;
};
&pinctrl {
pinctrl-names = "default";
pinctrl-0 = <&q7_thermal_pin>;
gpios {
q7_thermal_pin: q7-thermal-pin {
rockchip,pins =
<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
};
};
i2c8 {
i2c8_xfer_a: i2c8-xfer {
rockchip,pins =
@@ -466,6 +472,15 @@
};
};
&pmu_io_domains {
status = "okay";
pmu1830-supply = <&vcc_1v8>;
};
&pwm2 {
status = "okay";
};
&sdhci {
/*
* Signal integrity isn't great at 200MHz but 100MHz has proven stable
+1 -1
View File
@@ -2583,7 +2583,7 @@ static int __s390_enable_skey_hugetlb(pte_t *pte, unsigned long addr,
return 0;
start = pmd_val(*pmd) & HPAGE_MASK;
end = start + HPAGE_SIZE - 1;
end = start + HPAGE_SIZE;
__storage_key_init_range(start, end);
set_bit(PG_arch_1, &page->flags);
return 0;
+1 -1
View File
@@ -146,7 +146,7 @@ static void clear_huge_pte_skeys(struct mm_struct *mm, unsigned long rste)
}
if (!test_and_set_bit(PG_arch_1, &page->flags))
__storage_key_init_range(paddr, paddr + size - 1);
__storage_key_init_range(paddr, paddr + size);
}
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+2 -1
View File
@@ -11,6 +11,7 @@
#include <asm/mpspec.h>
#include <asm/msr.h>
#include <asm/hardirq.h>
#include <asm/io.h>
#define ARCH_APICTIMER_STOPS_ON_C3 1
@@ -110,7 +111,7 @@ static inline void native_apic_mem_write(u32 reg, u32 v)
static inline u32 native_apic_mem_read(u32 reg)
{
return *((volatile u32 *)(APIC_BASE + reg));
return readl((void __iomem *)(APIC_BASE + reg));
}
extern void native_apic_wait_icr_idle(void);
-1
View File
@@ -236,7 +236,6 @@ static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
}
if (!strcmp(q->cra_driver_name, alg->cra_name) ||
!strcmp(q->cra_driver_name, alg->cra_driver_name) ||
!strcmp(q->cra_name, alg->cra_driver_name))
goto err;
}
+4 -1
View File
@@ -200,7 +200,10 @@ int gemini_sata_start_bridge(struct sata_gemini *sg, unsigned int bridge)
pclk = sg->sata0_pclk;
else
pclk = sg->sata1_pclk;
clk_enable(pclk);
ret = clk_enable(pclk);
if (ret)
return ret;
msleep(10);
/* Do not keep clocking a bridge that is not online */
-2
View File
@@ -3,8 +3,6 @@ menu "CPU Idle"
config CPU_IDLE
bool "CPU idle PM support"
default y if ACPI || PPC_PSERIES
select CPU_IDLE_GOV_LADDER if (!NO_HZ && !NO_HZ_IDLE)
select CPU_IDLE_GOV_MENU if (NO_HZ || NO_HZ_IDLE)
help
CPU idle is a generic framework for supporting software-controlled
idle processor power management. It includes modular cross-platform
+4
View File
@@ -172,6 +172,10 @@ static irqreturn_t idma64_irq(int irq, void *dev)
u32 status_err;
unsigned short i;
/* Since IRQ may be shared, check if DMA controller is powered on */
if (status == GENMASK(31, 0))
return IRQ_NONE;
dev_vdbg(idma64->dma.dev, "%s: status=%#x\n", __func__, status);
/* Check if we have any interrupt from the DMA controller */
+2 -2
View File
@@ -230,7 +230,7 @@ static void pchan_update(struct owl_dma_pchan *pchan, u32 reg,
else
regval &= ~val;
writel(val, pchan->base + reg);
writel(regval, pchan->base + reg);
}
static void pchan_writel(struct owl_dma_pchan *pchan, u32 reg, u32 data)
@@ -254,7 +254,7 @@ static void dma_update(struct owl_dma *od, u32 reg, u32 val, bool state)
else
regval &= ~val;
writel(val, od->base + reg);
writel(regval, od->base + reg);
}
static void dma_writel(struct owl_dma *od, u32 reg, u32 data)
+4 -2
View File
@@ -161,10 +161,12 @@ packet_buffer_get(struct client *client, char __user *data, size_t user_length)
if (atomic_read(&buffer->size) == 0)
return -ENODEV;
/* FIXME: Check length <= user_length. */
length = buffer->head->length;
if (length > user_length)
return 0;
end = buffer->data + buffer->capacity;
length = buffer->head->length;
if (&buffer->head->data[length] < end) {
if (copy_to_user(data, buffer->head->data, length))
+5 -1
View File
@@ -2066,6 +2066,8 @@ static void bus_reset_work(struct work_struct *work)
ohci->generation = generation;
reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS)
reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset);
if (ohci->quirks & QUIRK_RESET_PACKET)
ohci->request_generation = generation;
@@ -2132,12 +2134,14 @@ static irqreturn_t irq_handler(int irq, void *data)
return IRQ_NONE;
/*
* busReset and postedWriteErr must not be cleared yet
* busReset and postedWriteErr events must not be cleared yet
* (OHCI 1.1 clauses 7.2.3.2 and 13.2.8.1)
*/
reg_write(ohci, OHCI1394_IntEventClear,
event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr));
log_irqs(ohci, event);
if (event & OHCI1394_busReset)
reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset);
if (event & OHCI1394_selfIDComplete)
queue_work(selfid_workqueue, &ohci->bus_reset_work);
+1 -1
View File
@@ -99,7 +99,7 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type)
case 0x5e:
return GPIOPANELCTL;
default:
return -EOPNOTSUPP;
return -ENOTSUPP;
}
}
+1 -1
View File
@@ -110,7 +110,7 @@ static inline unsigned int to_reg(int gpio, enum ctrl_register reg_type)
unsigned int reg;
if (gpio >= WCOVE_GPIO_NUM)
return -EOPNOTSUPP;
return -ENOTSUPP;
if (reg_type == CTRL_IN)
reg = GPIO_IN_CTRL_BASE + gpio;
@@ -46,9 +46,9 @@
/* Impose limit on how much memory KFD can use */
static struct {
uint64_t max_system_mem_limit;
uint64_t max_userptr_mem_limit;
uint64_t max_ttm_mem_limit;
int64_t system_mem_used;
int64_t userptr_mem_used;
int64_t ttm_mem_used;
spinlock_t mem_limit_lock;
} kfd_mem_limit;
@@ -90,8 +90,8 @@ static bool check_if_add_bo_to_vm(struct amdgpu_vm *avm,
}
/* Set memory usage limits. Current, limits are
* System (kernel) memory - 3/8th System RAM
* Userptr memory - 3/4th System RAM
* System (TTM + userptr) memory - 3/4th System RAM
* TTM memory - 3/8th System RAM
*/
void amdgpu_amdkfd_gpuvm_init_mem_limits(void)
{
@@ -103,48 +103,54 @@ void amdgpu_amdkfd_gpuvm_init_mem_limits(void)
mem *= si.mem_unit;
spin_lock_init(&kfd_mem_limit.mem_limit_lock);
kfd_mem_limit.max_system_mem_limit = (mem >> 1) - (mem >> 3);
kfd_mem_limit.max_userptr_mem_limit = mem - (mem >> 2);
pr_debug("Kernel memory limit %lluM, userptr limit %lluM\n",
kfd_mem_limit.max_system_mem_limit = (mem >> 1) + (mem >> 2);
kfd_mem_limit.max_ttm_mem_limit = (mem >> 1) - (mem >> 3);
pr_debug("Kernel memory limit %lluM, TTM limit %lluM\n",
(kfd_mem_limit.max_system_mem_limit >> 20),
(kfd_mem_limit.max_userptr_mem_limit >> 20));
(kfd_mem_limit.max_ttm_mem_limit >> 20));
}
static int amdgpu_amdkfd_reserve_system_mem_limit(struct amdgpu_device *adev,
uint64_t size, u32 domain)
uint64_t size, u32 domain, bool sg)
{
size_t acc_size;
size_t acc_size, system_mem_needed, ttm_mem_needed;
int ret = 0;
acc_size = ttm_bo_dma_acc_size(&adev->mman.bdev, size,
sizeof(struct amdgpu_bo));
spin_lock(&kfd_mem_limit.mem_limit_lock);
if (domain == AMDGPU_GEM_DOMAIN_GTT) {
if (kfd_mem_limit.system_mem_used + (acc_size + size) >
kfd_mem_limit.max_system_mem_limit) {
ret = -ENOMEM;
goto err_no_mem;
}
kfd_mem_limit.system_mem_used += (acc_size + size);
} else if (domain == AMDGPU_GEM_DOMAIN_CPU) {
if ((kfd_mem_limit.system_mem_used + acc_size >
kfd_mem_limit.max_system_mem_limit) ||
(kfd_mem_limit.userptr_mem_used + (size + acc_size) >
kfd_mem_limit.max_userptr_mem_limit)) {
ret = -ENOMEM;
goto err_no_mem;
}
kfd_mem_limit.system_mem_used += acc_size;
kfd_mem_limit.userptr_mem_used += size;
/* TTM GTT memory */
system_mem_needed = acc_size + size;
ttm_mem_needed = acc_size + size;
} else if (domain == AMDGPU_GEM_DOMAIN_CPU && !sg) {
/* Userptr */
system_mem_needed = acc_size + size;
ttm_mem_needed = acc_size;
} else {
/* VRAM and SG */
system_mem_needed = acc_size;
ttm_mem_needed = acc_size;
}
err_no_mem:
if ((kfd_mem_limit.system_mem_used + system_mem_needed >
kfd_mem_limit.max_system_mem_limit) ||
(kfd_mem_limit.ttm_mem_used + ttm_mem_needed >
kfd_mem_limit.max_ttm_mem_limit))
ret = -ENOMEM;
else {
kfd_mem_limit.system_mem_used += system_mem_needed;
kfd_mem_limit.ttm_mem_used += ttm_mem_needed;
}
spin_unlock(&kfd_mem_limit.mem_limit_lock);
return ret;
}
static void unreserve_system_mem_limit(struct amdgpu_device *adev,
uint64_t size, u32 domain)
uint64_t size, u32 domain, bool sg)
{
size_t acc_size;
@@ -154,14 +160,18 @@ static void unreserve_system_mem_limit(struct amdgpu_device *adev,
spin_lock(&kfd_mem_limit.mem_limit_lock);
if (domain == AMDGPU_GEM_DOMAIN_GTT) {
kfd_mem_limit.system_mem_used -= (acc_size + size);
} else if (domain == AMDGPU_GEM_DOMAIN_CPU) {
kfd_mem_limit.ttm_mem_used -= (acc_size + size);
} else if (domain == AMDGPU_GEM_DOMAIN_CPU && !sg) {
kfd_mem_limit.system_mem_used -= (acc_size + size);
kfd_mem_limit.ttm_mem_used -= acc_size;
} else {
kfd_mem_limit.system_mem_used -= acc_size;
kfd_mem_limit.userptr_mem_used -= size;
kfd_mem_limit.ttm_mem_used -= acc_size;
}
WARN_ONCE(kfd_mem_limit.system_mem_used < 0,
"kfd system memory accounting unbalanced");
WARN_ONCE(kfd_mem_limit.userptr_mem_used < 0,
"kfd userptr memory accounting unbalanced");
WARN_ONCE(kfd_mem_limit.ttm_mem_used < 0,
"kfd TTM memory accounting unbalanced");
spin_unlock(&kfd_mem_limit.mem_limit_lock);
}
@@ -171,16 +181,22 @@ void amdgpu_amdkfd_unreserve_system_memory_limit(struct amdgpu_bo *bo)
spin_lock(&kfd_mem_limit.mem_limit_lock);
if (bo->flags & AMDGPU_AMDKFD_USERPTR_BO) {
kfd_mem_limit.system_mem_used -= bo->tbo.acc_size;
kfd_mem_limit.userptr_mem_used -= amdgpu_bo_size(bo);
kfd_mem_limit.system_mem_used -=
(bo->tbo.acc_size + amdgpu_bo_size(bo));
kfd_mem_limit.ttm_mem_used -= bo->tbo.acc_size;
} else if (bo->preferred_domains == AMDGPU_GEM_DOMAIN_GTT) {
kfd_mem_limit.system_mem_used -=
(bo->tbo.acc_size + amdgpu_bo_size(bo));
kfd_mem_limit.ttm_mem_used -=
(bo->tbo.acc_size + amdgpu_bo_size(bo));
} else {
kfd_mem_limit.system_mem_used -= bo->tbo.acc_size;
kfd_mem_limit.ttm_mem_used -= bo->tbo.acc_size;
}
WARN_ONCE(kfd_mem_limit.system_mem_used < 0,
"kfd system memory accounting unbalanced");
WARN_ONCE(kfd_mem_limit.userptr_mem_used < 0,
"kfd userptr memory accounting unbalanced");
WARN_ONCE(kfd_mem_limit.ttm_mem_used < 0,
"kfd TTM memory accounting unbalanced");
spin_unlock(&kfd_mem_limit.mem_limit_lock);
}
@@ -1201,10 +1217,11 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
amdgpu_sync_create(&(*mem)->sync);
ret = amdgpu_amdkfd_reserve_system_mem_limit(adev, size, alloc_domain);
ret = amdgpu_amdkfd_reserve_system_mem_limit(adev, size,
alloc_domain, false);
if (ret) {
pr_debug("Insufficient system memory\n");
goto err_reserve_system_mem;
goto err_reserve_limit;
}
pr_debug("\tcreate BO VA 0x%llx size 0x%llx domain %s\n",
@@ -1252,10 +1269,11 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu(
allocate_init_user_pages_failed:
amdgpu_bo_unref(&bo);
/* Don't unreserve system mem limit twice */
goto err_reserve_system_mem;
goto err_reserve_limit;
err_bo_create:
unreserve_system_mem_limit(adev, size, alloc_domain);
err_reserve_system_mem:
unreserve_system_mem_limit(adev, size, alloc_domain, false);
err_reserve_limit:
amdgpu_sync_free(&(*mem)->sync);
mutex_destroy(&(*mem)->lock);
kfree(*mem);
return ret;
+46 -24
View File
@@ -2048,6 +2048,37 @@ static void amdgpu_vm_bo_insert_map(struct amdgpu_device *adev,
trace_amdgpu_vm_bo_map(bo_va, mapping);
}
/* Validate operation parameters to prevent potential abuse */
static int amdgpu_vm_verify_parameters(struct amdgpu_device *adev,
struct amdgpu_bo *bo,
uint64_t saddr,
uint64_t offset,
uint64_t size)
{
uint64_t tmp, lpfn;
if (saddr & AMDGPU_GPU_PAGE_MASK
|| offset & AMDGPU_GPU_PAGE_MASK
|| size & AMDGPU_GPU_PAGE_MASK)
return -EINVAL;
if (check_add_overflow(saddr, size, &tmp)
|| check_add_overflow(offset, size, &tmp)
|| size == 0 /* which also leads to end < begin */)
return -EINVAL;
/* make sure object fit at this offset */
if (bo && offset + size > amdgpu_bo_size(bo))
return -EINVAL;
/* Ensure last pfn not exceed max_pfn */
lpfn = (saddr + size - 1) >> AMDGPU_GPU_PAGE_SHIFT;
if (lpfn >= adev->vm_manager.max_pfn)
return -EINVAL;
return 0;
}
/**
* amdgpu_vm_bo_map - map bo inside a vm
*
@@ -2074,20 +2105,14 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
struct amdgpu_bo *bo = bo_va->base.bo;
struct amdgpu_vm *vm = bo_va->base.vm;
uint64_t eaddr;
int r;
/* validate the parameters */
if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK ||
size == 0 || size & ~PAGE_MASK)
return -EINVAL;
/* make sure object fit at this offset */
eaddr = saddr + size - 1;
if (saddr >= eaddr ||
(bo && offset + size > amdgpu_bo_size(bo)))
return -EINVAL;
r = amdgpu_vm_verify_parameters(adev, bo, saddr, offset, size);
if (r)
return r;
saddr /= AMDGPU_GPU_PAGE_SIZE;
eaddr /= AMDGPU_GPU_PAGE_SIZE;
eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE;
tmp = amdgpu_vm_it_iter_first(&vm->va, saddr, eaddr);
if (tmp) {
@@ -2140,16 +2165,9 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
uint64_t eaddr;
int r;
/* validate the parameters */
if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK ||
size == 0 || size & ~PAGE_MASK)
return -EINVAL;
/* make sure object fit at this offset */
eaddr = saddr + size - 1;
if (saddr >= eaddr ||
(bo && offset + size > amdgpu_bo_size(bo)))
return -EINVAL;
r = amdgpu_vm_verify_parameters(adev, bo, saddr, offset, size);
if (r)
return r;
/* Allocate all the needed memory */
mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
@@ -2163,7 +2181,7 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
}
saddr /= AMDGPU_GPU_PAGE_SIZE;
eaddr /= AMDGPU_GPU_PAGE_SIZE;
eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE;
mapping->start = saddr;
mapping->last = eaddr;
@@ -2250,10 +2268,14 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
struct amdgpu_bo_va_mapping *before, *after, *tmp, *next;
LIST_HEAD(removed);
uint64_t eaddr;
int r;
r = amdgpu_vm_verify_parameters(adev, NULL, saddr, 0, size);
if (r)
return r;
eaddr = saddr + size - 1;
saddr /= AMDGPU_GPU_PAGE_SIZE;
eaddr /= AMDGPU_GPU_PAGE_SIZE;
eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE;
/* Allocate all the needed memory */
before = kzalloc(sizeof(*before), GFP_KERNEL);
+7 -6
View File
@@ -25,6 +25,7 @@
#include <drm/drmP.h>
#include "nouveau_drv.h"
#include "nouveau_bios.h"
#include "nouveau_reg.h"
#include "dispnv04/hw.h"
#include "nouveau_encoder.h"
@@ -1674,7 +1675,7 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf)
*/
if (nv_match_device(dev, 0x0201, 0x1462, 0x8851)) {
if (*conn == 0xf2005014 && *conf == 0xffffffff) {
fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 1, 1, 1);
fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 1, 1, DCB_OUTPUT_B);
return false;
}
}
@@ -1760,26 +1761,26 @@ fabricate_dcb_encoder_table(struct drm_device *dev, struct nvbios *bios)
#ifdef __powerpc__
/* Apple iMac G4 NV17 */
if (of_machine_is_compatible("PowerMac4,5")) {
fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 0, all_heads, 1);
fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG, 1, all_heads, 2);
fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 0, all_heads, DCB_OUTPUT_B);
fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG, 1, all_heads, DCB_OUTPUT_C);
return;
}
#endif
/* Make up some sane defaults */
fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG,
bios->legacy.i2c_indices.crt, 1, 1);
bios->legacy.i2c_indices.crt, 1, DCB_OUTPUT_B);
if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0)
fabricate_dcb_output(dcb, DCB_OUTPUT_TV,
bios->legacy.i2c_indices.tv,
all_heads, 0);
all_heads, DCB_OUTPUT_A);
else if (bios->tmds.output0_script_ptr ||
bios->tmds.output1_script_ptr)
fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS,
bios->legacy.i2c_indices.panel,
all_heads, 1);
all_heads, DCB_OUTPUT_B);
}
static int
@@ -66,11 +66,16 @@ of_init(struct nvkm_bios *bios, const char *name)
return ERR_PTR(-EINVAL);
}
static void of_fini(void *p)
{
kfree(p);
}
const struct nvbios_source
nvbios_of = {
.name = "OpenFirmware",
.init = of_init,
.fini = (void(*)(void *))kfree,
.fini = of_fini,
.read = of_read,
.size = of_size,
.rw = false,
@@ -221,8 +221,11 @@ nv50_instobj_acquire(struct nvkm_memory *memory)
void __iomem *map = NULL;
/* Already mapped? */
if (refcount_inc_not_zero(&iobj->maps))
if (refcount_inc_not_zero(&iobj->maps)) {
/* read barrier match the wmb on refcount set */
smp_rmb();
return iobj->map;
}
/* Take the lock, and re-check that another thread hasn't
* already mapped the object in the meantime.
@@ -249,6 +252,8 @@ nv50_instobj_acquire(struct nvkm_memory *memory)
iobj->base.memory.ptrs = &nv50_instobj_fast;
else
iobj->base.memory.ptrs = &nv50_instobj_slow;
/* barrier to ensure the ptrs are written before refcount is set */
smp_wmb();
refcount_set(&iobj->maps, 1);
}
+1 -1
View File
@@ -1064,7 +1064,7 @@ static int vmw_event_fence_action_create(struct drm_file *file_priv,
}
event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED;
event->event.base.length = sizeof(*event);
event->event.base.length = sizeof(event->event);
event->event.user_data = user_data;
ret = drm_event_reserve_init(dev, file_priv, &event->base, &event->event.base);
+6 -9
View File
@@ -803,21 +803,18 @@ config HID_PLAYSTATION
depends on HID
select CRC32
select POWER_SUPPLY
---help---
Provides support for Sony PS5 controllers including support for
its special functionalities e.g. touchpad, lights and motion
sensors.
help
Provides support for Sony PS5 controllers including support for
its special functionalities e.g. touchpad, lights and motion
sensors.
config PLAYSTATION_FF
bool "PlayStation force feedback support"
depends on HID_PLAYSTATION
select INPUT_FF_MEMLESS
help
Provides the force feedback support for Playstation game
controllers.
Say Y here if you would like to enable force feedback support for
PlayStation game controllers.
Say Y here if you would like to enable force feedback support for
PlayStation game controllers.
config HID_PRIMAX
tristate "Primax non-fully HID-compliant devices"
+1
View File
@@ -1056,6 +1056,7 @@
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_2 0x09cc
#define USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE 0x0ba0
#define USB_DEVICE_ID_SONY_PS5_CONTROLLER 0x0ce6
#define USB_DEVICE_ID_SONY_PS5_CONTROLLER_2 0x0df2
#define USB_DEVICE_ID_SONY_MOTION_CONTROLLER 0x03d5
#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
#define USB_DEVICE_ID_SONY_BUZZ_CONTROLLER 0x0002
+160 -147
View File
@@ -4,6 +4,7 @@
*
* Copyright (c) 2020 Sony Interactive Entertainment
*/
#include <linux/bits.h>
#include <linux/crc32.h>
#include <linux/device.h>
@@ -36,17 +37,15 @@ struct ps_device {
struct power_supply *battery;
uint8_t battery_capacity;
int battery_status;
uint8_t mac_address[6]; /* Note: stored in little endian order. */
int32_t hw_version;
int32_t fw_version;
uint32_t hw_version;
uint32_t fw_version;
int (*parse_report)(struct ps_device *dev, struct hid_report *report, u8 *data, int size);
};
/* Seed values for DualShock4 / DualSense CRC32 for different report types. */
#define PS_INPUT_CRC32_SEED 0xA1
#define PS_OUTPUT_CRC32_SEED 0xA2
#define PS_FEATURE_CRC32_SEED 0xA3
/* Calibration data for playstation motion sensors. */
struct ps_calibration_data {
int abs_code;
short bias;
@@ -54,24 +53,26 @@ struct ps_calibration_data {
int sens_denom;
};
/* Seed values for DualShock4 / DualSense CRC32 for different report types. */
#define PS_INPUT_CRC32_SEED 0xA1
#define PS_OUTPUT_CRC32_SEED 0xA2
#define PS_FEATURE_CRC32_SEED 0xA3
#define DS_INPUT_REPORT_USB 0x01
#define DS_INPUT_REPORT_USB_SIZE 64
#define DS_INPUT_REPORT_BT 0x31
#define DS_INPUT_REPORT_BT_SIZE 78
#define DS_OUTPUT_REPORT_USB 0x02
#define DS_OUTPUT_REPORT_USB_SIZE 63
#define DS_OUTPUT_REPORT_BT 0x31
#define DS_OUTPUT_REPORT_BT_SIZE 78
#define DS_FEATURE_REPORT_CALIBRATION 0x05
#define DS_FEATURE_REPORT_CALIBRATION_SIZE 41
#define DS_INPUT_REPORT_BT 0x31
#define DS_INPUT_REPORT_BT_SIZE 78
#define DS_OUTPUT_REPORT_USB 0x02
#define DS_OUTPUT_REPORT_USB_SIZE 63
#define DS_OUTPUT_REPORT_BT 0x31
#define DS_OUTPUT_REPORT_BT_SIZE 78
#define DS_FEATURE_REPORT_PAIRING_INFO 0x09
#define DS_FEATURE_REPORT_PAIRING_INFO_SIZE 20
#define DS_FEATURE_REPORT_FIRMWARE_INFO 0x20
#define DS_FEATURE_REPORT_FIRMWARE_INFO_SIZE 64
#define DS_FEATURE_REPORT_CALIBRATION 0x05
#define DS_FEATURE_REPORT_CALIBRATION_SIZE 41
#define DS_FEATURE_REPORT_PAIRING_INFO 0x09
#define DS_FEATURE_REPORT_PAIRING_INFO_SIZE 20
#define DS_FEATURE_REPORT_FIRMWARE_INFO 0x20
#define DS_FEATURE_REPORT_FIRMWARE_INFO_SIZE 64
/* Button masks for DualSense input report. */
#define DS_BUTTONS0_HAT_SWITCH GENMASK(3, 0)
@@ -96,14 +97,17 @@ struct ps_calibration_data {
#define DS_STATUS_CHARGING GENMASK(7, 4)
#define DS_STATUS_CHARGING_SHIFT 4
/* Feature version from DualSense Firmware Info report. */
#define DS_FEATURE_VERSION(major, minor) ((major & 0xff) << 8 | (minor & 0xff))
/*
+ * Status of a DualSense touch point contact.
+ * Contact IDs, with highest bit set are 'inactive'
+ * and any associated data is then invalid.
+ */
* Status of a DualSense touch point contact.
* Contact IDs, with highest bit set are 'inactive'
* and any associated data is then invalid.
*/
#define DS_TOUCH_POINT_INACTIVE BIT(7)
/* Magic value required in tag field of Bluetooth output report. */
/* Magic value required in tag field of Bluetooth output report. */
#define DS_OUTPUT_TAG 0x10
/* Flags for DualSense output report. */
#define DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION BIT(0)
@@ -114,17 +118,17 @@ struct ps_calibration_data {
#define DS_OUTPUT_VALID_FLAG1_RELEASE_LEDS BIT(3)
#define DS_OUTPUT_VALID_FLAG1_PLAYER_INDICATOR_CONTROL_ENABLE BIT(4)
#define DS_OUTPUT_VALID_FLAG2_LIGHTBAR_SETUP_CONTROL_ENABLE BIT(1)
#define DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2 BIT(2)
#define DS_OUTPUT_POWER_SAVE_CONTROL_MIC_MUTE BIT(4)
#define DS_OUTPUT_LIGHTBAR_SETUP_LIGHT_OUT BIT(1)
#define DS_ACC_RES_PER_G 8192
#define DS_ACC_RANGE (4*DS_ACC_RES_PER_G)
#define DS_GYRO_RES_PER_DEG_S 1024
#define DS_GYRO_RANGE (2048*DS_GYRO_RES_PER_DEG_S)
/* DualSense hardware limits */
#define DS_TOUCHPAD_WIDTH 1920
#define DS_TOUCHPAD_HEIGHT 1080
#define DS_ACC_RES_PER_G 8192
#define DS_ACC_RANGE (4*DS_ACC_RES_PER_G)
#define DS_GYRO_RES_PER_DEG_S 1024
#define DS_GYRO_RANGE (2048*DS_GYRO_RES_PER_DEG_S)
#define DS_TOUCHPAD_WIDTH 1920
#define DS_TOUCHPAD_HEIGHT 1080
struct dualsense {
struct ps_device base;
@@ -132,15 +136,20 @@ struct dualsense {
struct input_dev *sensors;
struct input_dev *touchpad;
/* Update version is used as a feature/capability version. */
uint16_t update_version;
/* Calibration data for accelerometer and gyroscope. */
struct ps_calibration_data accel_calib_data[3];
struct ps_calibration_data gyro_calib_data[3];
/* Timestamp for sensor data */
bool sensor_timestamp_initialized;
uint32_t prev_sensor_timestamp;
uint32_t sensor_timestamp_us;
/* Compatible rumble state */
bool use_vibration_v2;
bool update_rumble;
uint8_t motor_left;
uint8_t motor_right;
@@ -173,6 +182,29 @@ struct dualsense_touch_point {
uint8_t y_hi;
} __packed;
/* Main DualSense input report excluding any BT/USB specific headers. */
struct dualsense_input_report {
uint8_t x, y;
uint8_t rx, ry;
uint8_t z, rz;
uint8_t seq_number;
uint8_t buttons[4];
uint8_t reserved[4];
/* Motion sensors */
__le16 gyro[3]; /* x, y, z */
__le16 accel[3]; /* x, y, z */
__le32 sensor_timestamp;
uint8_t reserved2;
/* Touchpad */
struct dualsense_touch_point points[2];
uint8_t reserved3[12];
uint8_t status;
uint8_t reserved4[10];
} __packed;
/* Common data between DualSense BT/USB main output report. */
struct dualsense_output_report_common {
uint8_t valid_flag0;
@@ -216,18 +248,15 @@ struct dualsense_output_report_usb {
} __packed;
/*
* The DualSense has a main output report used to control most features.
* It is largely the same between Bluetooth and USB except for different
* headers and CRC. This structure hide the differences between the two to
* simplify sending output reports.
* The DualSense has a main output report used to control most features. It is
* largely the same between Bluetooth and USB except for different headers and CRC.
* This structure hide the differences between the two to simplify sending output reports.
*/
struct dualsense_output_report {
uint8_t *data; /* Start of data */
uint8_t len; /* Size of output report */
/* Points to Bluetooth data payload
* in case for a Bluetooth report else NULL.
*/
/* Points to Bluetooth data payload in case for a Bluetooth report else NULL. */
struct dualsense_output_report_bt *bt;
/* Points to USB data payload in case for a USB report else NULL. */
struct dualsense_output_report_usb *usb;
@@ -235,29 +264,6 @@ struct dualsense_output_report {
struct dualsense_output_report_common *common;
};
/* Main DualSense input report excluding any BT/USB specific headers. */
struct dualsense_input_report {
uint8_t x, y;
uint8_t rx, ry;
uint8_t z, rz;
uint8_t seq_number;
uint8_t buttons[4];
uint8_t reserved[4];
/* Motion sensors */
__le16 gyro[3]; /* x, y, z */
__le16 accel[3]; /* x, y, z */
__le32 sensor_timestamp;
uint8_t reserved2;
/* Touchpad */
struct dualsense_touch_point points[2];
uint8_t reserved3[12];
uint8_t status;
uint8_t reserved4[10];
} __packed;
/*
* Common gamepad buttons across DualShock 3 / 4 and DualSense.
* Note: for device with a touchpad, touchpad button is not included
@@ -362,17 +368,6 @@ static struct input_dev *ps_allocate_input_dev(struct hid_device *hdev, const ch
return input_dev;
}
/* Compute crc32 of HID data and compare against expected CRC. */
static bool ps_check_crc32(uint8_t seed, uint8_t *data, size_t len, uint32_t report_crc)
{
uint32_t crc;
crc = crc32_le(0xFFFFFFFF, &seed, 1);
crc = ~crc32_le(crc, data, len);
return crc == report_crc;
}
static enum power_supply_property ps_power_supply_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_PRESENT,
@@ -381,8 +376,8 @@ static enum power_supply_property ps_power_supply_props[] = {
};
static int ps_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
enum power_supply_property psp,
union power_supply_propval *val)
{
struct ps_device *dev = power_supply_get_drvdata(psy);
uint8_t battery_capacity;
@@ -427,7 +422,7 @@ static int ps_device_register_battery(struct ps_device *dev)
dev->battery_desc.num_properties = ARRAY_SIZE(ps_power_supply_props);
dev->battery_desc.get_property = ps_battery_get_property;
dev->battery_desc.name = devm_kasprintf(&dev->hdev->dev, GFP_KERNEL,
"ps-controller-battery-%pMR", dev->mac_address);
"ps-controller-battery-%pMR", dev->mac_address);
if (!dev->battery_desc.name)
return -ENOMEM;
@@ -448,8 +443,19 @@ static int ps_device_register_battery(struct ps_device *dev)
return 0;
}
/* Compute crc32 of HID data and compare against expected CRC. */
static bool ps_check_crc32(uint8_t seed, uint8_t *data, size_t len, uint32_t report_crc)
{
uint32_t crc;
crc = crc32_le(0xFFFFFFFF, &seed, 1);
crc = ~crc32_le(crc, data, len);
return crc == report_crc;
}
static struct input_dev *ps_gamepad_create(struct hid_device *hdev,
int (*play_effect)(struct input_dev *, void *, struct ff_effect *))
int (*play_effect)(struct input_dev *, void *, struct ff_effect *))
{
struct input_dev *gamepad;
unsigned int i;
@@ -486,25 +492,24 @@ static struct input_dev *ps_gamepad_create(struct hid_device *hdev,
return gamepad;
}
static int ps_get_report(struct hid_device *hdev, uint8_t report_id,
uint8_t *buf, size_t size)
static int ps_get_report(struct hid_device *hdev, uint8_t report_id, uint8_t *buf, size_t size)
{
int ret;
ret = hid_hw_raw_request(hdev, report_id, buf, size, HID_FEATURE_REPORT,
HID_REQ_GET_REPORT);
HID_REQ_GET_REPORT);
if (ret < 0) {
hid_err(hdev, "Failed to retrieve: reportID %d: %d\n", report_id, ret);
hid_err(hdev, "Failed to retrieve feature with reportID %d: %d\n", report_id, ret);
return ret;
}
if (ret != size) {
hid_err(hdev, "Invalid byte count, expected %zu got %d\n", size, ret);
hid_err(hdev, "Invalid byte count transferred, expected %zu got %d\n", size, ret);
return -EINVAL;
}
if (buf[0] != report_id) {
hid_err(hdev, "Invalid reportID: expected %d got %d\n", report_id, buf[0]);
hid_err(hdev, "Invalid reportID received, expected %d got %d\n", report_id, buf[0]);
return -EINVAL;
}
@@ -522,8 +527,8 @@ static int ps_get_report(struct hid_device *hdev, uint8_t report_id,
return 0;
}
static struct input_dev *ps_sensors_create(struct hid_device *hdev,
int accel_range, int accel_res, int gyro_range, int gyro_res)
static struct input_dev *ps_sensors_create(struct hid_device *hdev, int accel_range, int accel_res,
int gyro_range, int gyro_res)
{
struct input_dev *sensors;
int ret;
@@ -594,7 +599,7 @@ static ssize_t firmware_version_show(struct device *dev,
struct hid_device *hdev = to_hid_device(dev);
struct ps_device *ps_dev = hid_get_drvdata(hdev);
return scnprintf(buf, PAGE_SIZE, "0x%08x\n", ps_dev->fw_version);
return snprintf(buf, PAGE_SIZE, "0x%08x\n", ps_dev->fw_version);
}
static DEVICE_ATTR_RO(firmware_version);
@@ -606,7 +611,7 @@ static ssize_t hardware_version_show(struct device *dev,
struct hid_device *hdev = to_hid_device(dev);
struct ps_device *ps_dev = hid_get_drvdata(hdev);
return scnprintf(buf, PAGE_SIZE, "0x%08x\n", ps_dev->hw_version);
return snprintf(buf, PAGE_SIZE, "0x%08x\n", ps_dev->hw_version);
}
static DEVICE_ATTR_RO(hardware_version);
@@ -642,7 +647,7 @@ static int dualsense_get_calibration_data(struct dualsense *ds)
ret = ps_get_report(ds->base.hdev, DS_FEATURE_REPORT_CALIBRATION, buf,
DS_FEATURE_REPORT_CALIBRATION_SIZE);
if (ret) {
hid_err(ds->base.hdev, "Failed: DualSense cal info: %d\n", ret);
hid_err(ds->base.hdev, "Failed to retrieve DualSense calibration info: %d\n", ret);
goto err_free;
}
@@ -730,6 +735,15 @@ static int dualsense_get_firmware_info(struct dualsense *ds)
ds->base.hw_version = get_unaligned_le32(&buf[24]);
ds->base.fw_version = get_unaligned_le32(&buf[28]);
/* Update version is some kind of feature version. It is distinct from
* the firmware version as there can be many different variations of a
* controller over time with the same physical shell, but with different
* PCBs and other internal changes. The update version (internal name) is
* used as a means to detect what features are available and change behavior.
* Note: the version is different between DualSense and DualSense Edge.
*/
ds->update_version = get_unaligned_le16(&buf[44]);
err_free:
kfree(buf);
return ret;
@@ -747,7 +761,7 @@ static int dualsense_get_mac_address(struct dualsense *ds)
ret = ps_get_report(ds->base.hdev, DS_FEATURE_REPORT_PAIRING_INFO, buf,
DS_FEATURE_REPORT_PAIRING_INFO_SIZE);
if (ret) {
hid_err(ds->base.hdev, "Failed to retrieve DualSense pair: %d\n", ret);
hid_err(ds->base.hdev, "Failed to retrieve DualSense pairing info: %d\n", ret);
goto err_free;
}
@@ -758,8 +772,8 @@ err_free:
return ret;
}
static void dualsense_init_output_report(struct dualsense *ds,
struct dualsense_output_report *rp, void *buf)
static void dualsense_init_output_report(struct dualsense *ds, struct dualsense_output_report *rp,
void *buf)
{
struct hid_device *hdev = ds->base.hdev;
@@ -768,12 +782,11 @@ static void dualsense_init_output_report(struct dualsense *ds,
memset(bt, 0, sizeof(*bt));
bt->report_id = DS_OUTPUT_REPORT_BT;
bt->tag = DS_OUTPUT_TAG; /* Tag to be set. It is unclear. */
bt->tag = DS_OUTPUT_TAG; /* Tag must be set. Exact meaning is unclear. */
/*
* Highest 4-bit is a sequence number, which needs to be
* increased every report. Lowest 4-bit is tag and can be
* zero for now.
* Highest 4-bit is a sequence number, which needs to be increased
* every report. Lowest 4-bit is tag and can be zero for now.
*/
bt->seq_tag = (ds->output_seq << 4) | 0x0;
if (++ds->output_seq == 16)
@@ -799,17 +812,15 @@ static void dualsense_init_output_report(struct dualsense *ds,
}
/*
* Helper function to send DualSense output reports. Applies a CRC
* at the end of a report for Bluetooth reports.
* Helper function to send DualSense output reports. Applies a CRC at the end of a report
* for Bluetooth reports.
*/
static void dualsense_send_output_report(struct dualsense *ds,
struct dualsense_output_report *report)
{
struct hid_device *hdev = ds->base.hdev;
/* Bluetooth packets need to be signed
* with a CRC in the last 4 bytes.
*/
/* Bluetooth packets need to be signed with a CRC in the last 4 bytes. */
if (report->bt) {
uint32_t crc;
uint8_t seed = PS_OUTPUT_CRC32_SEED;
@@ -825,8 +836,7 @@ static void dualsense_send_output_report(struct dualsense *ds,
static void dualsense_output_worker(struct work_struct *work)
{
struct dualsense *ds = container_of(work, struct dualsense,
output_worker);
struct dualsense *ds = container_of(work, struct dualsense, output_worker);
struct dualsense_output_report report;
struct dualsense_output_report_common *common;
unsigned long flags;
@@ -839,8 +849,10 @@ static void dualsense_output_worker(struct work_struct *work)
if (ds->update_rumble) {
/* Select classic rumble style haptics and enable it. */
common->valid_flag0 |= DS_OUTPUT_VALID_FLAG0_HAPTICS_SELECT;
common->valid_flag0 |=
DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION;
if (ds->use_vibration_v2)
common->valid_flag2 |= DS_OUTPUT_VALID_FLAG2_COMPATIBLE_VIBRATION2;
else
common->valid_flag0 |= DS_OUTPUT_VALID_FLAG0_COMPATIBLE_VIBRATION;
common->motor_left = ds->motor_left;
common->motor_right = ds->motor_right;
ds->update_rumble = false;
@@ -863,22 +875,17 @@ static void dualsense_output_worker(struct work_struct *work)
}
if (ds->update_mic_mute) {
common->valid_flag1 |=
DS_OUTPUT_VALID_FLAG1_MIC_MUTE_LED_CONTROL_ENABLE;
common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_MIC_MUTE_LED_CONTROL_ENABLE;
common->mute_button_led = ds->mic_muted;
if (ds->mic_muted) {
/* Disable microphone */
common->valid_flag1 |=
DS_OUTPUT_VALID_FLAG1_POWER_SAVE_CONTROL_ENABLE;
common->power_save_control |=
DS_OUTPUT_POWER_SAVE_CONTROL_MIC_MUTE;
common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_POWER_SAVE_CONTROL_ENABLE;
common->power_save_control |= DS_OUTPUT_POWER_SAVE_CONTROL_MIC_MUTE;
} else {
/* Enable microphone */
common->valid_flag1 |=
DS_OUTPUT_VALID_FLAG1_POWER_SAVE_CONTROL_ENABLE;
common->power_save_control &=
~DS_OUTPUT_POWER_SAVE_CONTROL_MIC_MUTE;
common->valid_flag1 |= DS_OUTPUT_VALID_FLAG1_POWER_SAVE_CONTROL_ENABLE;
common->power_save_control &= ~DS_OUTPUT_POWER_SAVE_CONTROL_MIC_MUTE;
}
ds->update_mic_mute = false;
@@ -889,17 +896,17 @@ static void dualsense_output_worker(struct work_struct *work)
dualsense_send_output_report(ds, &report);
}
static int dualsense_parse_report(struct ps_device *ps_dev,
struct hid_report *report, u8 *data, int size)
static int dualsense_parse_report(struct ps_device *ps_dev, struct hid_report *report,
u8 *data, int size)
{
struct hid_device *hdev = ps_dev->hdev;
struct dualsense *ds = container_of(ps_dev, struct dualsense, base);
struct dualsense_input_report *ds_report;
uint8_t battery_data, battery_capacity, charging_status, value;
int battery_status;
unsigned long flags;
bool btn_mic_state;
uint32_t sensor_timestamp;
bool btn_mic_state;
unsigned long flags;
int i;
/*
@@ -910,14 +917,12 @@ static int dualsense_parse_report(struct ps_device *ps_dev,
if (hdev->bus == BUS_USB && report->id == DS_INPUT_REPORT_USB &&
size == DS_INPUT_REPORT_USB_SIZE) {
ds_report = (struct dualsense_input_report *)&data[1];
} else if (hdev->bus == BUS_BLUETOOTH &&
report->id == DS_INPUT_REPORT_BT &&
} else if (hdev->bus == BUS_BLUETOOTH && report->id == DS_INPUT_REPORT_BT &&
size == DS_INPUT_REPORT_BT_SIZE) {
/* Last 4 bytes of input report contain crc32 */
uint32_t report_crc = get_unaligned_le32(&data[size - 4]);
if (!ps_check_crc32(PS_INPUT_CRC32_SEED, data, size - 4,
report_crc)) {
if (!ps_check_crc32(PS_INPUT_CRC32_SEED, data, size - 4, report_crc)) {
hid_err(hdev, "DualSense input CRC's check failed\n");
return -EILSEQ;
}
@@ -957,9 +962,8 @@ static int dualsense_parse_report(struct ps_device *ps_dev,
input_sync(ds->gamepad);
/*
* The DualSense has an internal microphone, which can bemuted
* through a mute button on the device. The driver is expected
* to read the button state and program the device
* The DualSense has an internal microphone, which can be muted through a mute button
* on the device. The driver is expected to read the button state and program the device
* to mute/unmute audio at the hardware level.
*/
btn_mic_state = !!(ds_report->buttons[2] & DS_BUTTONS2_MIC_MUTE);
@@ -981,8 +985,7 @@ static int dualsense_parse_report(struct ps_device *ps_dev,
raw_data - ds->gyro_calib_data[i].bias,
ds->gyro_calib_data[i].sens_denom);
input_report_abs(ds->sensors, ds->gyro_calib_data[i].abs_code,
calib_data);
input_report_abs(ds->sensors, ds->gyro_calib_data[i].abs_code, calib_data);
}
/* Parse and calibrate accelerometer data. */
@@ -992,35 +995,30 @@ static int dualsense_parse_report(struct ps_device *ps_dev,
raw_data - ds->accel_calib_data[i].bias,
ds->accel_calib_data[i].sens_denom);
input_report_abs(ds->sensors, ds->accel_calib_data[i].abs_code,
calib_data);
input_report_abs(ds->sensors, ds->accel_calib_data[i].abs_code, calib_data);
}
/* Convert timestamp (in 0.33us unit) to timestamp_us */
sensor_timestamp = le32_to_cpu(ds_report->sensor_timestamp);
if (!ds->sensor_timestamp_initialized) {
ds->sensor_timestamp_us =
DIV_ROUND_CLOSEST(sensor_timestamp, 3);
ds->sensor_timestamp_us = DIV_ROUND_CLOSEST(sensor_timestamp, 3);
ds->sensor_timestamp_initialized = true;
} else {
uint32_t delta;
if (ds->prev_sensor_timestamp > sensor_timestamp)
delta = (U32_MAX - ds->prev_sensor_timestamp +
sensor_timestamp + 1);
delta = (U32_MAX - ds->prev_sensor_timestamp + sensor_timestamp + 1);
else
delta = sensor_timestamp - ds->prev_sensor_timestamp;
ds->sensor_timestamp_us += DIV_ROUND_CLOSEST(delta, 3);
}
ds->prev_sensor_timestamp = sensor_timestamp;
input_event(ds->sensors, EV_MSC, MSC_TIMESTAMP,
ds->sensor_timestamp_us);
input_event(ds->sensors, EV_MSC, MSC_TIMESTAMP, ds->sensor_timestamp_us);
input_sync(ds->sensors);
for (i = 0; i < ARRAY_SIZE(ds_report->points); i++) {
struct dualsense_touch_point *point = &ds_report->points[i];
bool active = (point->contact &
DS_TOUCH_POINT_INACTIVE) ? false : true;
bool active = (point->contact & DS_TOUCH_POINT_INACTIVE) ? false : true;
input_mt_slot(ds->touchpad, i);
input_mt_report_slot_state(ds->touchpad, MT_TOOL_FINGER, active);
@@ -1076,8 +1074,7 @@ static int dualsense_parse_report(struct ps_device *ps_dev,
return 0;
}
static int dualsense_play_effect(struct input_dev *dev,
void *data, struct ff_effect *effect)
static int dualsense_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
{
struct hid_device *hdev = input_get_drvdata(dev);
struct dualsense *ds = hid_get_drvdata(hdev);
@@ -1181,8 +1178,7 @@ static struct ps_device *dualsense_create(struct hid_device *hdev)
hid_set_drvdata(hdev, ds);
max_output_report_size = sizeof(struct dualsense_output_report_bt);
ds->output_report_dmabuf = devm_kzalloc(&hdev->dev,
max_output_report_size, GFP_KERNEL);
ds->output_report_dmabuf = devm_kzalloc(&hdev->dev, max_output_report_size, GFP_KERNEL);
if (!ds->output_report_dmabuf)
return ERR_PTR(-ENOMEM);
@@ -1199,6 +1195,21 @@ static struct ps_device *dualsense_create(struct hid_device *hdev)
return ERR_PTR(ret);
}
/* Original DualSense firmware simulated classic controller rumble through
* its new haptics hardware. It felt different from classic rumble users
* were used to. Since then new firmwares were introduced to change behavior
* and make this new 'v2' behavior default on PlayStation and other platforms.
* The original DualSense requires a new enough firmware as bundled with PS5
* software released in 2021. DualSense edge supports it out of the box.
* Both devices also support the old mode, but it is not really used.
*/
if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER) {
/* Feature version 2.21 introduced new vibration method. */
ds->use_vibration_v2 = ds->update_version >= DS_FEATURE_VERSION(2, 21);
} else if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) {
ds->use_vibration_v2 = true;
}
ret = ps_devices_list_add(ps_dev);
if (ret)
return ERR_PTR(ret);
@@ -1222,8 +1233,7 @@ static struct ps_device *dualsense_create(struct hid_device *hdev)
goto err;
}
ds->touchpad = ps_touchpad_create(hdev, DS_TOUCHPAD_WIDTH,
DS_TOUCHPAD_HEIGHT, 2);
ds->touchpad = ps_touchpad_create(hdev, DS_TOUCHPAD_WIDTH, DS_TOUCHPAD_HEIGHT, 2);
if (IS_ERR(ds->touchpad)) {
ret = PTR_ERR(ds->touchpad);
goto err;
@@ -1301,7 +1311,8 @@ static int ps_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto err_stop;
}
if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER) {
if (hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER ||
hdev->product == USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) {
dev = dualsense_create(hdev);
if (IS_ERR(dev)) {
hid_err(hdev, "Failed to create dualsense.\n");
@@ -1339,6 +1350,8 @@ static void ps_remove(struct hid_device *hdev)
static const struct hid_device_id ps_devices[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS5_CONTROLLER_2) },
{ }
};
MODULE_DEVICE_TABLE(hid, ps_devices);
@@ -1367,4 +1380,4 @@ module_exit(ps_exit);
MODULE_AUTHOR("Sony Interactive Entertainment");
MODULE_DESCRIPTION("HID Driver for PlayStation peripherals.");
MODULE_LICENSE("GPL v2");
MODULE_LICENSE("GPL");
-8
View File
@@ -58,7 +58,6 @@
/* flags */
#define I2C_HID_STARTED 0
#define I2C_HID_RESET_PENDING 1
#define I2C_HID_READ_PENDING 2
#define I2C_HID_PWR_ON 0x00
#define I2C_HID_PWR_SLEEP 0x01
@@ -259,7 +258,6 @@ static int __i2c_hid_command(struct i2c_client *client,
msg[1].len = data_len;
msg[1].buf = buf_recv;
msg_num = 2;
set_bit(I2C_HID_READ_PENDING, &ihid->flags);
}
if (wait)
@@ -267,9 +265,6 @@ static int __i2c_hid_command(struct i2c_client *client,
ret = i2c_transfer(client->adapter, msg, msg_num);
if (data_len > 0)
clear_bit(I2C_HID_READ_PENDING, &ihid->flags);
if (ret != msg_num)
return ret < 0 ? ret : -EIO;
@@ -550,9 +545,6 @@ static irqreturn_t i2c_hid_irq(int irq, void *dev_id)
{
struct i2c_hid *ihid = dev_id;
if (test_bit(I2C_HID_READ_PENDING, &ihid->flags))
return IRQ_HANDLED;
i2c_hid_get_input(ihid);
return IRQ_HANDLED;
+6 -1
View File
@@ -1872,13 +1872,18 @@ static int i2c_check_for_quirks(struct i2c_adapter *adap, struct i2c_msg *msgs,
* Returns negative errno, else the number of messages executed.
*
* Adapter lock must be held when calling this function. No debug logging
* takes place. adap->algo->master_xfer existence isn't checked.
* takes place.
*/
int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
unsigned long orig_jiffies;
int ret, try;
if (!adap->algo->master_xfer) {
dev_dbg(&adap->dev, "I2C level transfers not supported\n");
return -EOPNOTSUPP;
}
if (WARN_ON(!msgs || num < 1))
return -EINVAL;
+2 -1
View File
@@ -216,7 +216,8 @@ static int process_pma_cmd(struct mlx5_ib_dev *dev, u8 port_num,
mdev = dev->mdev;
mdev_port_num = 1;
}
if (MLX5_CAP_GEN(dev->mdev, num_ports) == 1) {
if (MLX5_CAP_GEN(dev->mdev, num_ports) == 1 &&
!mlx5_core_mp_enabled(mdev)) {
/* set local port to one for Function-Per-Port HCA. */
mdev = dev->mdev;
mdev_port_num = 1;
+2 -7
View File
@@ -2994,13 +2994,8 @@ static int its_vpe_irq_domain_alloc(struct irq_domain *domain, unsigned int virq
set_bit(i, bitmap);
}
if (err) {
if (i > 0)
its_vpe_irq_domain_free(domain, virq, i);
its_lpi_free(bitmap, base, nr_ids);
its_free_prop_table(vprop_page);
}
if (err)
its_vpe_irq_domain_free(domain, virq, i);
return err;
}
+2
View File
@@ -18,6 +18,8 @@
#include "dm.h"
#define DM_RESERVED_MAX_IOS 1024
#define DM_MAX_TARGETS 1048576
#define DM_MAX_TARGET_PARAMS 1024
struct dm_kobject_holder {
struct kobject kobj;
+2 -1
View File
@@ -1734,7 +1734,8 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl *param_kern
if (copy_from_user(param_kernel, user, minimum_data_size))
return -EFAULT;
if (param_kernel->data_size < minimum_data_size)
if (unlikely(param_kernel->data_size < minimum_data_size) ||
unlikely(param_kernel->data_size > DM_MAX_TARGETS * DM_MAX_TARGET_PARAMS))
return -EINVAL;
secure_data = param_kernel->flags & DM_SECURE_DATA_FLAG;
+7 -2
View File
@@ -190,7 +190,12 @@ static int alloc_targets(struct dm_table *t, unsigned int num)
int dm_table_create(struct dm_table **result, fmode_t mode,
unsigned num_targets, struct mapped_device *md)
{
struct dm_table *t = kzalloc(sizeof(*t), GFP_KERNEL);
struct dm_table *t;
if (num_targets > DM_MAX_TARGETS)
return -EOVERFLOW;
t = kzalloc(sizeof(*t), GFP_KERNEL);
if (!t)
return -ENOMEM;
@@ -205,7 +210,7 @@ int dm_table_create(struct dm_table **result, fmode_t mode,
if (!num_targets) {
kfree(t);
return -ENOMEM;
return -EOVERFLOW;
}
if (alloc_targets(t, num_targets)) {
+2 -2
View File
@@ -52,7 +52,7 @@ static unsigned long doc_locations[] __initdata = {
0xe8000, 0xea000, 0xec000, 0xee000,
#endif
#endif
0xffffffff };
};
static struct mtd_info *doclist = NULL;
@@ -1678,7 +1678,7 @@ static int __init init_nanddoc(void)
if (ret < 0)
return ret;
} else {
for (i = 0; (doc_locations[i] != 0xffffffff); i++) {
for (i = 0; i < ARRAY_SIZE(doc_locations); i++) {
doc_probe(doc_locations[i]);
}
}
+27 -2
View File
@@ -3933,6 +3933,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6097,
.name = "Marvell 88E6085",
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 10,
.num_internal_phys = 5,
.max_vid = 4095,
@@ -3955,6 +3956,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6095,
.name = "Marvell 88E6095/88E6095F",
.num_databases = 256,
.num_macs = 8192,
.num_ports = 11,
.num_internal_phys = 0,
.max_vid = 4095,
@@ -3975,6 +3977,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6097,
.name = "Marvell 88E6097/88E6097F",
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 11,
.num_internal_phys = 8,
.max_vid = 4095,
@@ -3997,6 +4000,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6123",
.num_databases = 4096,
.num_macs = 1024,
.num_ports = 3,
.num_internal_phys = 5,
.max_vid = 4095,
@@ -4019,6 +4023,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6185,
.name = "Marvell 88E6131",
.num_databases = 256,
.num_macs = 8192,
.num_ports = 8,
.num_internal_phys = 0,
.max_vid = 4095,
@@ -4038,7 +4043,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
.family = MV88E6XXX_FAMILY_6341,
.name = "Marvell 88E6141",
.num_databases = 4096,
.num_databases = 256,
.num_macs = 2048,
.num_ports = 6,
.num_internal_phys = 5,
.num_gpio = 11,
@@ -4062,6 +4068,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6161",
.num_databases = 4096,
.num_macs = 1024,
.num_ports = 6,
.num_internal_phys = 5,
.max_vid = 4095,
@@ -4085,6 +4092,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6165,
.name = "Marvell 88E6165",
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 6,
.num_internal_phys = 0,
.max_vid = 4095,
@@ -4108,6 +4116,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6171",
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
.max_vid = 4095,
@@ -4130,6 +4139,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6172",
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
.num_gpio = 15,
@@ -4153,6 +4163,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6175",
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
.max_vid = 4095,
@@ -4175,6 +4186,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6176",
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
.num_gpio = 15,
@@ -4198,6 +4210,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6185,
.name = "Marvell 88E6185",
.num_databases = 256,
.num_macs = 8192,
.num_ports = 10,
.num_internal_phys = 0,
.max_vid = 4095,
@@ -4218,6 +4231,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6390,
.name = "Marvell 88E6190",
.num_databases = 4096,
.num_macs = 16384,
.num_ports = 11, /* 10 + Z80 */
.num_internal_phys = 9,
.num_gpio = 16,
@@ -4241,6 +4255,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6390,
.name = "Marvell 88E6190X",
.num_databases = 4096,
.num_macs = 16384,
.num_ports = 11, /* 10 + Z80 */
.num_internal_phys = 9,
.num_gpio = 16,
@@ -4264,6 +4279,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6390,
.name = "Marvell 88E6191",
.num_databases = 4096,
.num_macs = 16384,
.num_ports = 11, /* 10 + Z80 */
.num_internal_phys = 9,
.max_vid = 8191,
@@ -4287,6 +4303,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6240",
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
.num_gpio = 15,
@@ -4335,6 +4352,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6320,
.name = "Marvell 88E6320",
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
.num_gpio = 15,
@@ -4359,6 +4377,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6320,
.name = "Marvell 88E6321",
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
.num_gpio = 15,
@@ -4381,7 +4400,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
.family = MV88E6XXX_FAMILY_6341,
.name = "Marvell 88E6341",
.num_databases = 4096,
.num_databases = 256,
.num_macs = 2048,
.num_internal_phys = 5,
.num_ports = 6,
.num_gpio = 11,
@@ -4406,6 +4426,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6350",
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
.max_vid = 4095,
@@ -4428,6 +4449,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6351,
.name = "Marvell 88E6351",
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
.max_vid = 4095,
@@ -4450,6 +4472,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6352,
.name = "Marvell 88E6352",
.num_databases = 4096,
.num_macs = 8192,
.num_ports = 7,
.num_internal_phys = 5,
.num_gpio = 15,
@@ -4473,6 +4496,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6390,
.name = "Marvell 88E6390",
.num_databases = 4096,
.num_macs = 16384,
.num_ports = 11, /* 10 + Z80 */
.num_internal_phys = 9,
.num_gpio = 16,
@@ -4496,6 +4520,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.family = MV88E6XXX_FAMILY_6390,
.name = "Marvell 88E6390X",
.num_databases = 4096,
.num_macs = 16384,
.num_ports = 11, /* 10 + Z80 */
.num_internal_phys = 9,
.num_gpio = 16,
+6
View File
@@ -105,6 +105,7 @@ struct mv88e6xxx_info {
u16 prod_num;
const char *name;
unsigned int num_databases;
unsigned int num_macs;
unsigned int num_ports;
unsigned int num_internal_phys;
unsigned int num_gpio;
@@ -559,6 +560,11 @@ static inline unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_chip *chip)
return chip->info->num_databases;
}
static inline unsigned int mv88e6xxx_num_macs(struct mv88e6xxx_chip *chip)
{
return chip->info->num_macs;
}
static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip)
{
return chip->info->num_ports;
+8 -6
View File
@@ -2033,12 +2033,14 @@ static int b44_set_pauseparam(struct net_device *dev,
bp->flags |= B44_FLAG_TX_PAUSE;
else
bp->flags &= ~B44_FLAG_TX_PAUSE;
if (bp->flags & B44_FLAG_PAUSE_AUTO) {
b44_halt(bp);
b44_init_rings(bp);
b44_init_hw(bp, B44_FULL_RESET);
} else {
__b44_set_flow_ctrl(bp, bp->flags);
if (netif_running(dev)) {
if (bp->flags & B44_FLAG_PAUSE_AUTO) {
b44_halt(bp);
b44_init_rings(bp);
b44_init_hw(bp, B44_FULL_RESET);
} else {
__b44_set_flow_ctrl(bp, bp->flags);
}
}
spin_unlock_irq(&bp->lock);
+12 -4
View File
@@ -2806,7 +2806,7 @@ static void bcmgenet_set_hw_addr(struct bcmgenet_priv *priv,
}
/* Returns a reusable dma control register value */
static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv)
static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv, bool flush_rx)
{
unsigned int i;
u32 reg;
@@ -2831,6 +2831,14 @@ static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv)
udelay(10);
bcmgenet_umac_writel(priv, 0, UMAC_TX_FLUSH);
if (flush_rx) {
reg = bcmgenet_rbuf_ctrl_get(priv);
bcmgenet_rbuf_ctrl_set(priv, reg | BIT(0));
udelay(10);
bcmgenet_rbuf_ctrl_set(priv, reg);
udelay(10);
}
return dma_ctrl;
}
@@ -2926,8 +2934,8 @@ static int bcmgenet_open(struct net_device *dev)
bcmgenet_set_hw_addr(priv, dev->dev_addr);
/* Disable RX/TX DMA and flush TX queues */
dma_ctrl = bcmgenet_dma_disable(priv);
/* Disable RX/TX DMA and flush TX and RX queues */
dma_ctrl = bcmgenet_dma_disable(priv, true);
/* Reinitialize TDMA and RDMA and SW housekeeping */
ret = bcmgenet_init_dma(priv);
@@ -3682,7 +3690,7 @@ static int bcmgenet_resume(struct device *d)
bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC);
/* Disable RX/TX DMA and flush TX queues */
dma_ctrl = bcmgenet_dma_disable(priv);
dma_ctrl = bcmgenet_dma_disable(priv, false);
/* Reinitialize TDMA and RDMA and SW housekeeping */
ret = bcmgenet_init_dma(priv);
@@ -320,7 +320,7 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf,
void *kern_buf;
/* Copy the user space buf */
kern_buf = memdup_user(buf, nbytes);
kern_buf = memdup_user_nul(buf, nbytes);
if (IS_ERR(kern_buf))
return PTR_ERR(kern_buf);
@@ -380,7 +380,7 @@ bnad_debugfs_write_regwr(struct file *file, const char __user *buf,
void *kern_buf;
/* Copy the user space buf */
kern_buf = memdup_user(buf, nbytes);
kern_buf = memdup_user_nul(buf, nbytes);
if (IS_ERR(kern_buf))
return PTR_ERR(kern_buf);
+1 -1
View File
@@ -14728,7 +14728,7 @@ static int __init i40e_init_module(void)
* since we need to be able to guarantee forward progress even under
* memory pressure.
*/
i40e_wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, i40e_driver_name);
i40e_wq = alloc_workqueue("%s", 0, 0, i40e_driver_name);
if (!i40e_wq) {
pr_err("%s: Failed to create workqueue\n", i40e_driver_name);
return -ENOMEM;
@@ -1452,8 +1452,9 @@ static struct mlx5_flow_handle *add_rule_fg(struct mlx5_flow_group *fg,
}
trace_mlx5_fs_set_fte(fte, false);
/* Link newly added rules into the tree. */
for (i = 0; i < handle->num_rules; i++) {
if (refcount_read(&handle->rule[i]->node.refcount) == 1) {
if (!handle->rule[i]->node.parent) {
tree_add_node(&handle->rule[i]->node, &fte->node);
trace_mlx5_fs_add_rule(handle->rule[i]);
}
+1 -1
View File
@@ -561,7 +561,7 @@ free_skb:
static const struct mlxsw_listener mlxsw_emad_rx_listener =
MLXSW_RXL(mlxsw_emad_rx_listener_func, ETHEMAD, TRAP_TO_CPU, false,
EMAD, DISCARD);
EMAD, FORWARD);
static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core)
{
+2 -2
View File
@@ -838,7 +838,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
__be16 df;
int err;
if (!pskb_inet_may_pull(skb))
if (!skb_vlan_inet_prepare(skb))
return -EINVAL;
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
@@ -884,7 +884,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
__be16 sport;
int err;
if (!pskb_inet_may_pull(skb))
if (!skb_vlan_inet_prepare(skb))
return -EINVAL;
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
+2 -1
View File
@@ -710,11 +710,12 @@ out_hashtable:
static void gtp_dellink(struct net_device *dev, struct list_head *head)
{
struct gtp_dev *gtp = netdev_priv(dev);
struct hlist_node *next;
struct pdp_ctx *pctx;
int i;
for (i = 0; i < gtp->hash_size; i++)
hlist_for_each_entry_rcu(pctx, &gtp->tid_hash[i], hlist_tid)
hlist_for_each_entry_safe(pctx, next, &gtp->tid_hash[i], hlist_tid)
pdp_context_delete(pctx);
gtp_encap_disable(gtp);
+10 -8
View File
@@ -2172,14 +2172,16 @@ static ssize_t tun_put_user(struct tun_struct *tun,
tun_is_little_endian(tun), true,
vlan_hlen)) {
struct skb_shared_info *sinfo = skb_shinfo(skb);
pr_err("unexpected GSO type: "
"0x%x, gso_size %d, hdr_len %d\n",
sinfo->gso_type, tun16_to_cpu(tun, gso.gso_size),
tun16_to_cpu(tun, gso.hdr_len));
print_hex_dump(KERN_ERR, "tun: ",
DUMP_PREFIX_NONE,
16, 1, skb->head,
min((int)tun16_to_cpu(tun, gso.hdr_len), 64), true);
if (net_ratelimit()) {
netdev_err(tun->dev, "unexpected GSO type: 0x%x, gso_size %d, hdr_len %d\n",
sinfo->gso_type, tun16_to_cpu(tun, gso.gso_size),
tun16_to_cpu(tun, gso.hdr_len));
print_hex_dump(KERN_ERR, "tun: ",
DUMP_PREFIX_NONE,
16, 1, skb->head,
min((int)tun16_to_cpu(tun, gso.hdr_len), 64), true);
}
WARN_ON_ONCE(1);
return -EINVAL;
}
+1
View File
@@ -1383,6 +1383,7 @@ static const struct usb_device_id products[] = {
{QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/
{QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */
{QMI_QUIRK_SET_DTR(0x1546, 0x1342, 4)}, /* u-blox LARA-L6 */
{QMI_QUIRK_SET_DTR(0x33f8, 0x0104, 4)}, /* Rolling RW101 RMNET */
/* 4. Gobi 1000 devices */
{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */
+4
View File
@@ -1320,6 +1320,10 @@ static bool vxlan_set_mac(struct vxlan_dev *vxlan,
if (ether_addr_equal(eth_hdr(skb)->h_source, vxlan->dev->dev_addr))
return false;
/* Ignore packets from invalid src-address */
if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
return false;
/* Get address from the outer IP header */
if (vxlan_get_sk_family(vs) == AF_INET) {
saddr.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
+23 -19
View File
@@ -427,7 +427,8 @@ struct trf7970a {
enum trf7970a_state state;
struct device *dev;
struct spi_device *spi;
struct regulator *regulator;
struct regulator *vin_regulator;
struct regulator *vddio_regulator;
struct nfc_digital_dev *ddev;
u32 quirks;
bool is_initiator;
@@ -1886,7 +1887,7 @@ static int trf7970a_power_up(struct trf7970a *trf)
if (trf->state != TRF7970A_ST_PWR_OFF)
return 0;
ret = regulator_enable(trf->regulator);
ret = regulator_enable(trf->vin_regulator);
if (ret) {
dev_err(trf->dev, "%s - Can't enable VIN: %d\n", __func__, ret);
return ret;
@@ -1929,7 +1930,7 @@ static int trf7970a_power_down(struct trf7970a *trf)
if (trf->en2_gpiod && !(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW))
gpiod_set_value_cansleep(trf->en2_gpiod, 0);
ret = regulator_disable(trf->regulator);
ret = regulator_disable(trf->vin_regulator);
if (ret)
dev_err(trf->dev, "%s - Can't disable VIN: %d\n", __func__,
ret);
@@ -2068,37 +2069,37 @@ static int trf7970a_probe(struct spi_device *spi)
mutex_init(&trf->lock);
INIT_DELAYED_WORK(&trf->timeout_work, trf7970a_timeout_work_handler);
trf->regulator = devm_regulator_get(&spi->dev, "vin");
if (IS_ERR(trf->regulator)) {
ret = PTR_ERR(trf->regulator);
trf->vin_regulator = devm_regulator_get(&spi->dev, "vin");
if (IS_ERR(trf->vin_regulator)) {
ret = PTR_ERR(trf->vin_regulator);
dev_err(trf->dev, "Can't get VIN regulator: %d\n", ret);
goto err_destroy_lock;
}
ret = regulator_enable(trf->regulator);
ret = regulator_enable(trf->vin_regulator);
if (ret) {
dev_err(trf->dev, "Can't enable VIN: %d\n", ret);
goto err_destroy_lock;
}
uvolts = regulator_get_voltage(trf->regulator);
uvolts = regulator_get_voltage(trf->vin_regulator);
if (uvolts > 4000000)
trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3;
trf->regulator = devm_regulator_get(&spi->dev, "vdd-io");
if (IS_ERR(trf->regulator)) {
ret = PTR_ERR(trf->regulator);
trf->vddio_regulator = devm_regulator_get(&spi->dev, "vdd-io");
if (IS_ERR(trf->vddio_regulator)) {
ret = PTR_ERR(trf->vddio_regulator);
dev_err(trf->dev, "Can't get VDD_IO regulator: %d\n", ret);
goto err_destroy_lock;
goto err_disable_vin_regulator;
}
ret = regulator_enable(trf->regulator);
ret = regulator_enable(trf->vddio_regulator);
if (ret) {
dev_err(trf->dev, "Can't enable VDD_IO: %d\n", ret);
goto err_destroy_lock;
goto err_disable_vin_regulator;
}
if (regulator_get_voltage(trf->regulator) == 1800000) {
if (regulator_get_voltage(trf->vddio_regulator) == 1800000) {
trf->io_ctrl = TRF7970A_REG_IO_CTRL_IO_LOW;
dev_dbg(trf->dev, "trf7970a config vdd_io to 1.8V\n");
}
@@ -2111,7 +2112,7 @@ static int trf7970a_probe(struct spi_device *spi)
if (!trf->ddev) {
dev_err(trf->dev, "Can't allocate NFC digital device\n");
ret = -ENOMEM;
goto err_disable_regulator;
goto err_disable_vddio_regulator;
}
nfc_digital_set_parent_dev(trf->ddev, trf->dev);
@@ -2140,8 +2141,10 @@ err_shutdown:
trf7970a_shutdown(trf);
err_free_ddev:
nfc_digital_free_device(trf->ddev);
err_disable_regulator:
regulator_disable(trf->regulator);
err_disable_vddio_regulator:
regulator_disable(trf->vddio_regulator);
err_disable_vin_regulator:
regulator_disable(trf->vin_regulator);
err_destroy_lock:
mutex_destroy(&trf->lock);
return ret;
@@ -2160,7 +2163,8 @@ static int trf7970a_remove(struct spi_device *spi)
nfc_digital_unregister_device(trf->ddev);
nfc_digital_free_device(trf->ddev);
regulator_disable(trf->regulator);
regulator_disable(trf->vddio_regulator);
regulator_disable(trf->vin_regulator);
mutex_destroy(&trf->lock);
+1 -7
View File
@@ -2036,13 +2036,7 @@ int pinctrl_enable(struct pinctrl_dev *pctldev)
error = pinctrl_claim_hogs(pctldev);
if (error) {
dev_err(pctldev->dev, "could not claim hogs: %i\n",
error);
pinctrl_free_pindescs(pctldev, pctldev->desc->pins,
pctldev->desc->npins);
mutex_destroy(&pctldev->mutex);
kfree(pctldev);
dev_err(pctldev->dev, "could not claim hogs: %i\n", error);
return error;
}
+6 -4
View File
@@ -235,14 +235,16 @@ int pinctrl_dt_to_map(struct pinctrl *p, struct pinctrl_dev *pctldev)
for (state = 0; ; state++) {
/* Retrieve the pinctrl-* property */
propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state);
if (!propname)
return -ENOMEM;
if (!propname) {
ret = -ENOMEM;
goto err;
}
prop = of_find_property(np, propname, &size);
kfree(propname);
if (!prop) {
if (state == 0) {
of_node_put(np);
return -ENODEV;
ret = -ENODEV;
goto err;
}
break;
}
@@ -1252,6 +1252,7 @@ static ssize_t ipa3_read_stats(struct file *file, char __user *ubuf,
"flow_disable=%u\n"
"rx_page_drop_cnt=%u\n"
"zero_len_frag_pkt_cnt=%u\n",
"lower_order=%u\n",
ipa3_ctx->stats.tx_sw_pkts,
ipa3_ctx->stats.tx_hw_pkts,
ipa3_ctx->stats.tx_non_linear,
@@ -1269,7 +1270,8 @@ static ssize_t ipa3_read_stats(struct file *file, char __user *ubuf,
ipa3_ctx->stats.flow_enable,
ipa3_ctx->stats.flow_disable,
ipa3_ctx->stats.rx_page_drop_cnt,
ipa3_ctx->stats.zero_len_frag_pkt_cnt);
ipa3_ctx->stats.zero_len_frag_pkt_cnt,
ipa3_ctx->stats.lower_order);
cnt += nbytes;
for (i = 0; i < IPAHAL_PKT_STATUS_EXCEPTION_MAX; i++) {
+39 -11
View File
@@ -1923,6 +1923,26 @@ fail_kmem_cache_alloc:
}
}
static struct page *ipa3_alloc_page(
gfp_t flag, u32 *page_order, bool try_lower)
{
struct page *page = NULL;
u32 p_order = *page_order;
page = __dev_alloc_pages(flag, p_order);
/* We will only try 1 page order lower. */
if (unlikely(!page)) {
if (try_lower && p_order > 0) {
p_order = p_order - 1;
page = __dev_alloc_pages(flag, p_order);
if (likely(page))
ipa3_ctx->stats.lower_order++;
}
}
*page_order = p_order;
return page;
}
static struct ipa3_rx_pkt_wrapper *ipa3_alloc_rx_pkt_page(
gfp_t flag, bool is_tmp_alloc)
{
@@ -1933,12 +1953,21 @@ static struct ipa3_rx_pkt_wrapper *ipa3_alloc_rx_pkt_page(
flag);
if (unlikely(!rx_pkt))
return NULL;
rx_pkt->len = PAGE_SIZE << IPA_WAN_PAGE_ORDER;
rx_pkt->page_data.page = __dev_alloc_pages(flag,
IPA_WAN_PAGE_ORDER);
rx_pkt->page_data.page_order = IPA_WAN_PAGE_ORDER;
/* For temporary allocations, avoid triggering OOM Killer. */
if (is_tmp_alloc)
flag |= __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
/* Try a lower order page for order 3 pages in case allocation fails. */
rx_pkt->page_data.page = ipa3_alloc_page(flag,
&rx_pkt->page_data.page_order,
(is_tmp_alloc && rx_pkt->page_data.page_order == 3));
if (unlikely(!rx_pkt->page_data.page))
goto fail_page_alloc;
rx_pkt->len = PAGE_SIZE << rx_pkt->page_data.page_order;
rx_pkt->page_data.dma_addr = dma_map_page(ipa3_ctx->pdev,
rx_pkt->page_data.page, 0,
rx_pkt->len, DMA_FROM_DEVICE);
@@ -1956,7 +1985,7 @@ static struct ipa3_rx_pkt_wrapper *ipa3_alloc_rx_pkt_page(
return rx_pkt;
fail_dma_mapping:
__free_pages(rx_pkt->page_data.page, IPA_WAN_PAGE_ORDER);
__free_pages(rx_pkt->page_data.page, rx_pkt->page_data.page_order);
fail_page_alloc:
kmem_cache_free(ipa3_ctx->rx_pkt_wrapper_cache, rx_pkt);
return NULL;
@@ -2643,8 +2672,7 @@ static void free_rx_page(void *chan_user_data, void *xfer_user_data)
}
dma_unmap_page(ipa3_ctx->pdev, rx_pkt->page_data.dma_addr,
rx_pkt->len, DMA_FROM_DEVICE);
__free_pages(rx_pkt->page_data.page,
IPA_WAN_PAGE_ORDER);
__free_pages(rx_pkt->page_data.page, rx_pkt->page_data.page_order);
kmem_cache_free(ipa3_ctx->rx_pkt_wrapper_cache, rx_pkt);
}
@@ -2696,7 +2724,7 @@ static void ipa3_cleanup_rx(struct ipa3_sys_context *sys)
rx_pkt->len,
DMA_FROM_DEVICE);
__free_pages(rx_pkt->page_data.page,
IPA_WAN_PAGE_ORDER);
rx_pkt->page_data.page_order);
}
kmem_cache_free(ipa3_ctx->rx_pkt_wrapper_cache,
rx_pkt);
@@ -2716,7 +2744,7 @@ static void ipa3_cleanup_rx(struct ipa3_sys_context *sys)
rx_pkt->len,
DMA_FROM_DEVICE);
__free_pages(rx_pkt->page_data.page,
IPA_WAN_PAGE_ORDER);
rx_pkt->page_data.page_order);
kmem_cache_free(
ipa3_ctx->rx_pkt_wrapper_cache,
rx_pkt);
@@ -3489,7 +3517,7 @@ static struct sk_buff *handle_page_completion(struct gsi_chan_xfer_notify
dma_unmap_page(ipa3_ctx->pdev, rx_page.dma_addr,
rx_pkt->len, DMA_FROM_DEVICE);
__free_pages(rx_pkt->page_data.page,
IPA_WAN_PAGE_ORDER);
rx_pkt->page_data.page_order);
}
rx_pkt->sys->free_rx_wrapper(rx_pkt);
IPA_STATS_INC_CNT(ipa3_ctx->stats.rx_page_drop_cnt);
@@ -3517,7 +3545,7 @@ static struct sk_buff *handle_page_completion(struct gsi_chan_xfer_notify
rx_page.dma_addr,
rx_pkt->len, DMA_FROM_DEVICE);
__free_pages(rx_pkt->page_data.page,
IPA_WAN_PAGE_ORDER);
rx_pkt->page_data.page_order);
}
rx_pkt->sys->free_rx_wrapper(rx_pkt);
}
@@ -3542,7 +3570,7 @@ static struct sk_buff *handle_page_completion(struct gsi_chan_xfer_notify
skb_shinfo(rx_skb)->nr_frags,
rx_page.page, 0,
notify->bytes_xfered,
PAGE_SIZE << IPA_WAN_PAGE_ORDER);
PAGE_SIZE << rx_page.page_order);
}
} else {
return NULL;
+11 -3
View File
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2012-2019,2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include "ipa_i.h"
@@ -98,8 +98,10 @@ static int ipa3_hdr_proc_ctx_to_hw_format(struct ipa_mem_buffer *mem,
!entry->offset_entry ||
entry->hdr->hdr_len == 0 ||
entry->hdr->hdr_len >
ipa_hdr_bin_sz[IPA_HDR_BIN_MAX - 1]))
ipa_hdr_bin_sz[IPA_HDR_BIN_MAX - 1])) {
IPAERR_RL("Found invalid hdr entry\n");
return -EINVAL;
}
ret = ipahal_cp_proc_ctx_to_hw_buff(entry->type, mem->base,
entry->offset_entry->offset,
@@ -132,6 +134,7 @@ static int ipa3_generate_hdr_proc_ctx_hw_tbl(u64 hdr_sys_addr,
{
u64 hdr_base_addr;
gfp_t flag = GFP_KERNEL;
int ret;
mem->size = (ipa3_ctx->hdr_proc_ctx_tbl.end) ? : 4;
@@ -160,7 +163,12 @@ alloc:
memset(aligned_mem->base, 0, aligned_mem->size);
hdr_base_addr = (ipa3_ctx->hdr_tbl_lcl) ? IPA_MEM_PART(apps_hdr_ofst) :
hdr_sys_addr;
return ipa3_hdr_proc_ctx_to_hw_format(aligned_mem, hdr_base_addr);
ret = ipa3_hdr_proc_ctx_to_hw_format(aligned_mem, hdr_base_addr);
if (ret) {
dma_free_coherent(ipa3_ctx->pdev, mem->size, mem->base, mem->phys_base);
return ret;
}
return ret;
}
/**
+1
View File
@@ -1383,6 +1383,7 @@ struct ipa3_stats {
u32 rx_page_drop_cnt;
u32 zero_len_frag_pkt_cnt;
struct ipa3_page_recycle_stats page_recycle_stats[2];
u64 lower_order;
};
/* offset for each stats */
+2
View File
@@ -202,6 +202,7 @@ static const int rt9455_voreg_values[] = {
4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000, 4450000
};
#if IS_ENABLED(CONFIG_USB_PHY)
/*
* When the charger is in boost mode, REG02[7:2] represent boost output
* voltage.
@@ -217,6 +218,7 @@ static const int rt9455_boost_voltage_values[] = {
5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000,
5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000, 5600000,
};
#endif
/* REG07[3:0] (VMREG) in uV */
static const int rt9455_vmreg_values[] = {
-2
View File
@@ -834,7 +834,6 @@ static void bnx2fc_free_session_resc(struct bnx2fc_hba *hba,
BNX2FC_TGT_DBG(tgt, "Freeing up session resources\n");
spin_lock_bh(&tgt->cq_lock);
ctx_base_ptr = tgt->ctx_base;
tgt->ctx_base = NULL;
@@ -890,7 +889,6 @@ static void bnx2fc_free_session_resc(struct bnx2fc_hba *hba,
tgt->sq, tgt->sq_dma);
tgt->sq = NULL;
}
spin_unlock_bh(&tgt->cq_lock);
if (ctx_base_ptr)
iounmap(ctx_base_ptr);
-1
View File
@@ -989,7 +989,6 @@ struct lpfc_hba {
unsigned long bit_flags;
#define FABRIC_COMANDS_BLOCKED 0
atomic_t num_rsrc_err;
atomic_t num_cmd_success;
unsigned long last_rsrc_error_time;
unsigned long last_ramp_down_time;
#ifdef CONFIG_SCSI_LPFC_DEBUG_FS
+4 -9
View File
@@ -303,11 +303,10 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
struct Scsi_Host *shost;
struct scsi_device *sdev;
unsigned long new_queue_depth;
unsigned long num_rsrc_err, num_cmd_success;
unsigned long num_rsrc_err;
int i;
num_rsrc_err = atomic_read(&phba->num_rsrc_err);
num_cmd_success = atomic_read(&phba->num_cmd_success);
/*
* The error and success command counters are global per
@@ -322,20 +321,16 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
shost = lpfc_shost_from_vport(vports[i]);
shost_for_each_device(sdev, shost) {
new_queue_depth =
sdev->queue_depth * num_rsrc_err /
(num_rsrc_err + num_cmd_success);
if (!new_queue_depth)
new_queue_depth = sdev->queue_depth - 1;
if (num_rsrc_err >= sdev->queue_depth)
new_queue_depth = 1;
else
new_queue_depth = sdev->queue_depth -
new_queue_depth;
num_rsrc_err;
scsi_change_queue_depth(sdev, new_queue_depth);
}
}
lpfc_destroy_vport_work_array(phba, vports);
atomic_set(&phba->num_rsrc_err, 0);
atomic_set(&phba->num_cmd_success, 0);
}
/**
+10
View File
@@ -390,6 +390,7 @@ static const struct file_operations ufsdbg_err_inj_scenario_ops = {
.open = ufsdbg_err_inj_scenario_open,
.read = seq_read,
.write = ufsdbg_err_inj_scenario_write,
.release = single_release,
};
static int ufsdbg_err_inj_stats_read(struct seq_file *file, void *data)
@@ -431,6 +432,7 @@ static const struct file_operations ufsdbg_err_inj_stats_ops = {
.open = ufsdbg_err_inj_stats_open,
.read = seq_read,
.write = ufsdbg_err_inj_stats_write,
.release = single_release,
};
static void ufsdbg_setup_fault_injection(struct ufs_hba *hba)
@@ -614,6 +616,7 @@ static const struct file_operations ufsdbg_tag_stats_fops = {
.open = ufsdbg_tag_stats_open,
.read = seq_read,
.write = ufsdbg_tag_stats_write,
.release = single_release,
};
static int ufsdbg_query_stats_show(struct seq_file *file, void *data)
@@ -685,6 +688,7 @@ static const struct file_operations ufsdbg_query_stats_fops = {
.open = ufsdbg_query_stats_open,
.read = seq_read,
.write = ufsdbg_query_stats_write,
.release = single_release,
};
static int ufsdbg_err_stats_show(struct seq_file *file, void *data)
@@ -789,6 +793,7 @@ static const struct file_operations ufsdbg_err_stats_fops = {
.open = ufsdbg_err_stats_open,
.read = seq_read,
.write = ufsdbg_err_stats_write,
.release = single_release,
};
static int ufshcd_init_statistics(struct ufs_hba *hba)
@@ -868,6 +873,7 @@ static int ufsdbg_host_regs_open(struct inode *inode, struct file *file)
static const struct file_operations ufsdbg_host_regs_fops = {
.open = ufsdbg_host_regs_open,
.read = seq_read,
.release = single_release,
};
static int ufsdbg_dump_device_desc_show(struct seq_file *file, void *data)
@@ -1032,6 +1038,7 @@ static int ufsdbg_show_hba_open(struct inode *inode, struct file *file)
static const struct file_operations ufsdbg_show_hba_fops = {
.open = ufsdbg_show_hba_open,
.read = seq_read,
.release = single_release,
};
static int ufsdbg_dump_device_desc_open(struct inode *inode, struct file *file)
@@ -1043,6 +1050,7 @@ static int ufsdbg_dump_device_desc_open(struct inode *inode, struct file *file)
static const struct file_operations ufsdbg_dump_device_desc = {
.open = ufsdbg_dump_device_desc_open,
.read = seq_read,
.release = single_release,
};
static int ufsdbg_power_mode_show(struct seq_file *file, void *data)
@@ -1330,6 +1338,7 @@ static const struct file_operations ufsdbg_power_mode_desc = {
.open = ufsdbg_power_mode_open,
.read = seq_read,
.write = ufsdbg_power_mode_write,
.release = single_release,
};
static int ufsdbg_dme_read(void *data, u64 *attr_val, bool peer)
@@ -1509,6 +1518,7 @@ static const struct file_operations ufsdbg_req_stats_desc = {
.open = ufsdbg_req_stats_open,
.read = seq_read,
.write = ufsdbg_req_stats_write,
.release = single_release,
};
static int ufsdbg_clear_err_state(void *data, u64 val)
+3
View File
@@ -188,6 +188,7 @@ static const struct file_operations ufs_qcom_dbg_testbus_cfg_desc = {
.open = ufs_qcom_dbg_testbus_cfg_open,
.read = seq_read,
.write = ufs_qcom_dbg_testbus_cfg_write,
.release = single_release,
};
static int ufs_qcom_dbg_testbus_bus_read(void *data, u64 *attr_val)
@@ -242,6 +243,7 @@ static int ufs_qcom_dbg_dbg_regs_open(struct inode *inode,
static const struct file_operations ufs_qcom_dbg_dbg_regs_desc = {
.open = ufs_qcom_dbg_dbg_regs_open,
.read = seq_read,
.release = single_release,
};
static int ufs_qcom_dbg_pm_qos_show(struct seq_file *file, void *data)
@@ -275,6 +277,7 @@ static int ufs_qcom_dbg_pm_qos_open(struct inode *inode,
static const struct file_operations ufs_qcom_dbg_pm_qos_desc = {
.open = ufs_qcom_dbg_pm_qos_open,
.read = seq_read,
.release = single_release,
};
void ufs_qcom_dbg_add_debugfs(struct ufs_hba *hba, struct dentry *root)
+10 -1
View File
@@ -910,6 +910,7 @@ out:
static int ufs_qcom_full_reset(struct ufs_hba *hba)
{
int ret = -ENOTSUPP;
bool reenable_intr = false;
if (!hba->core_reset) {
dev_err(hba->dev, "%s: failed, err = %d\n", __func__,
@@ -917,6 +918,10 @@ static int ufs_qcom_full_reset(struct ufs_hba *hba)
goto out;
}
reenable_intr = hba->is_irq_enabled;
disable_irq(hba->irq);
hba->is_irq_enabled = false;
ret = reset_control_assert(hba->core_reset);
if (ret) {
dev_err(hba->dev, "%s: core_reset assert failed, err = %d\n",
@@ -936,6 +941,11 @@ static int ufs_qcom_full_reset(struct ufs_hba *hba)
dev_err(hba->dev, "%s: core_reset deassert failed, err = %d\n",
__func__, ret);
if (reenable_intr) {
enable_irq(hba->irq);
hba->is_irq_enabled = true;
}
out:
return ret;
}
@@ -1497,7 +1507,6 @@ static void ufs_qcom_set_caps(struct ufs_hba *hba)
if (!host->disable_lpm) {
hba->caps |= UFSHCD_CAP_CLK_GATING;
hba->caps |= UFSHCD_CAP_HIBERN8_WITH_CLK_GATING;
hba->caps |= UFSHCD_CAP_CLK_SCALING;
}
hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
+1
View File
@@ -75,6 +75,7 @@ const struct file_operations ufs_test_ ## test_name ## _ops = { \
.open = ufs_test_ ## test_name ## _open, \
.read = seq_read, \
.write = ufs_test_ ## test_name ## _write, \
.release = single_release, \
}
#define add_test(utd, test_name, upper_case_name) \
+7 -7
View File
@@ -2514,19 +2514,19 @@ static ssize_t ufshcd_clkgate_enable_store(struct device *dev,
return -EINVAL;
value = !!value;
spin_lock_irqsave(hba->host->host_lock, flags);
if (value == hba->clk_gating.is_enabled)
goto out;
if (value) {
ufshcd_release(hba, false);
} else {
spin_lock_irqsave(hba->host->host_lock, flags);
if (value)
hba->clk_gating.active_reqs--;
else
hba->clk_gating.active_reqs++;
spin_unlock_irqrestore(hba->host->host_lock, flags);
}
hba->clk_gating.is_enabled = value;
out:
spin_unlock_irqrestore(hba->host->host_lock, flags);
return count;
}
@@ -2598,7 +2598,7 @@ static void ufshcd_init_clk_gating(struct ufs_hba *hba)
snprintf(wq_name, ARRAY_SIZE(wq_name), "ufs_clk_gating_%d",
hba->host->host_no);
hba->clk_gating.clk_gating_workq = alloc_ordered_workqueue(wq_name,
WQ_MEM_RECLAIM);
WQ_MEM_RECLAIM | WQ_HIGHPRI);
gating->is_enabled = true;
+12 -23
View File
@@ -642,32 +642,21 @@ static int vmk80xx_find_usb_endpoints(struct comedi_device *dev)
struct vmk80xx_private *devpriv = dev->private;
struct usb_interface *intf = comedi_to_usb_interface(dev);
struct usb_host_interface *iface_desc = intf->cur_altsetting;
struct usb_endpoint_descriptor *ep_desc;
int i;
struct usb_endpoint_descriptor *ep_rx_desc, *ep_tx_desc;
int ret;
if (iface_desc->desc.bNumEndpoints != 2)
if (devpriv->model == VMK8061_MODEL)
ret = usb_find_common_endpoints(iface_desc, &ep_rx_desc,
&ep_tx_desc, NULL, NULL);
else
ret = usb_find_common_endpoints(iface_desc, NULL, NULL,
&ep_rx_desc, &ep_tx_desc);
if (ret)
return -ENODEV;
for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
ep_desc = &iface_desc->endpoint[i].desc;
if (usb_endpoint_is_int_in(ep_desc) ||
usb_endpoint_is_bulk_in(ep_desc)) {
if (!devpriv->ep_rx)
devpriv->ep_rx = ep_desc;
continue;
}
if (usb_endpoint_is_int_out(ep_desc) ||
usb_endpoint_is_bulk_out(ep_desc)) {
if (!devpriv->ep_tx)
devpriv->ep_tx = ep_desc;
continue;
}
}
if (!devpriv->ep_rx || !devpriv->ep_tx)
return -ENODEV;
devpriv->ep_rx = ep_rx_desc;
devpriv->ep_tx = ep_tx_desc;
if (!usb_endpoint_maxp(devpriv->ep_rx) || !usb_endpoint_maxp(devpriv->ep_tx))
return -EINVAL;
+1 -1
View File
@@ -577,7 +577,7 @@ static u_long get_word(struct vc_data *vc)
}
attr_ch = get_char(vc, (u_short *)tmp_pos, &spk_attr);
buf[cnt++] = attr_ch;
while (tmpx < vc->vc_cols - 1) {
while (tmpx < vc->vc_cols - 1 && cnt < sizeof(buf) - 1) {
tmp_pos += 2;
tmpx++;
ch = get_char(vc, (u_short *)tmp_pos, &temp);
+12
View File
@@ -3240,6 +3240,8 @@ static int __init target_core_init_configfs(void)
{
struct configfs_subsystem *subsys = &target_core_fabrics;
struct t10_alua_lu_gp *lu_gp;
struct cred *kern_cred;
const struct cred *old_cred;
int ret;
pr_debug("TARGET_CORE[0]: Loading Generic Kernel Storage"
@@ -3316,11 +3318,21 @@ static int __init target_core_init_configfs(void)
if (ret < 0)
goto out;
/* We use the kernel credentials to access the target directory */
kern_cred = prepare_kernel_cred(&init_task);
if (!kern_cred) {
ret = -ENOMEM;
goto out;
}
old_cred = override_creds(kern_cred);
target_init_dbroot();
revert_creds(old_cred);
put_cred(kern_cred);
return 0;
out:
target_xcopy_release_pt();
configfs_unregister_subsystem(subsys);
core_dev_release_virtual_lun0();
rd_module_exit();
+29 -1
View File
@@ -16,6 +16,7 @@
#include <linux/console.h>
#include <linux/vt_kern.h>
#include <linux/input.h>
#include <linux/irq_work.h>
#include <linux/module.h>
#define MAX_CONFIG_LEN 40
@@ -35,6 +36,25 @@ static int kgdboc_use_kms; /* 1 if we use kernel mode switching */
static struct tty_driver *kgdb_tty_driver;
static int kgdb_tty_line;
/*
* When we leave the debug trap handler we need to reset the keyboard status
* (since the original keyboard state gets partially clobbered by kdb use of
* the keyboard).
*
* The path to deliver the reset is somewhat circuitous.
*
* To deliver the reset we register an input handler, reset the keyboard and
* then deregister the input handler. However, to get this done right, we do
* have to carefully manage the calling context because we can only register
* input handlers from task context.
*
* In particular we need to trigger the action from the debug trap handler with
* all its NMI and/or NMI-like oddities. To solve this the kgdboc trap exit code
* (the "post_exception" callback) uses irq_work_queue(), which is NMI-safe, to
* schedule a callback from a hardirq context. From there we have to defer the
* work again, this time using schedule_work(), to get a callback using the
* system workqueue, which runs in task context.
*/
#ifdef CONFIG_KDB_KEYBOARD
static int kgdboc_reset_connect(struct input_handler *handler,
struct input_dev *dev,
@@ -86,10 +106,17 @@ static void kgdboc_restore_input_helper(struct work_struct *dummy)
static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper);
static void kgdboc_queue_restore_input_helper(struct irq_work *unused)
{
schedule_work(&kgdboc_restore_input_work);
}
static DEFINE_IRQ_WORK(kgdboc_restore_input_irq_work, kgdboc_queue_restore_input_helper);
static void kgdboc_restore_input(void)
{
if (likely(system_state == SYSTEM_RUNNING))
schedule_work(&kgdboc_restore_input_work);
irq_work_queue(&kgdboc_restore_input_irq_work);
}
static int kgdboc_register_kbd(char **cptr)
@@ -120,6 +147,7 @@ static void kgdboc_unregister_kbd(void)
i--;
}
}
irq_work_sync(&kgdboc_restore_input_irq_work);
flush_work(&kgdboc_restore_input_work);
}
#else /* ! CONFIG_KDB_KEYBOARD */
+6 -2
View File
@@ -1128,11 +1128,13 @@ static void mxs_auart_set_ldisc(struct uart_port *port,
static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
{
u32 istat;
u32 istat, stat;
struct mxs_auart_port *s = context;
u32 mctrl_temp = s->mctrl_prev;
u32 stat = mxs_read(s, REG_STAT);
uart_port_lock(&s->port);
stat = mxs_read(s, REG_STAT);
istat = mxs_read(s, REG_INTR);
/* ack irq */
@@ -1168,6 +1170,8 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
istat &= ~AUART_INTR_TXIS;
}
uart_port_unlock(&s->port);
return IRQ_HANDLED;
}
-14
View File
@@ -220,7 +220,6 @@ static bool pmz_receive_chars(struct uart_pmac_port *uap)
{
struct tty_port *port;
unsigned char ch, r1, drop, error, flag;
int loops = 0;
/* Sanity check, make sure the old bug is no longer happening */
if (uap->port.state == NULL) {
@@ -303,24 +302,11 @@ static bool pmz_receive_chars(struct uart_pmac_port *uap)
if (r1 & Rx_OVR)
tty_insert_flip_char(port, 0, TTY_OVERRUN);
next_char:
/* We can get stuck in an infinite loop getting char 0 when the
* line is in a wrong HW state, we break that here.
* When that happens, I disable the receive side of the driver.
* Note that what I've been experiencing is a real irq loop where
* I'm getting flooded regardless of the actual port speed.
* Something strange is going on with the HW
*/
if ((++loops) > 1000)
goto flood;
ch = read_zsreg(uap, R0);
if (!(ch & Rx_CH_AV))
break;
}
return true;
flood:
pmz_interrupt_control(uap, 0);
pmz_error("pmz: rx irq flood !\n");
return true;
}
+1 -5
View File
@@ -471,7 +471,6 @@ out_free_mem:
static int service_outstanding_interrupt(struct wdm_device *desc)
{
int rv = 0;
int used;
/* submit read urb only if the device is waiting for it */
if (!desc->resp_count || !--desc->resp_count)
@@ -486,10 +485,7 @@ static int service_outstanding_interrupt(struct wdm_device *desc)
goto out;
}
used = test_and_set_bit(WDM_RESPONDING, &desc->flags);
if (used)
goto out;
set_bit(WDM_RESPONDING, &desc->flags);
spin_unlock_irq(&desc->iuspin);
rv = usb_submit_urb(desc->response, GFP_KERNEL);
spin_lock_irq(&desc->iuspin);
+3 -1
View File
@@ -897,13 +897,15 @@ static int dwc2_cmpl_host_isoc_dma_desc(struct dwc2_hsotg *hsotg,
struct dwc2_dma_desc *dma_desc;
struct dwc2_hcd_iso_packet_desc *frame_desc;
u16 frame_desc_idx;
struct urb *usb_urb = qtd->urb->priv;
struct urb *usb_urb;
u16 remain = 0;
int rc = 0;
if (!qtd->urb)
return -EINVAL;
usb_urb = qtd->urb->priv;
dma_sync_single_for_cpu(hsotg->dev, qh->desc_list_dma + (idx *
sizeof(struct dwc2_dma_desc)),
sizeof(struct dwc2_dma_desc),
+3 -3
View File
@@ -2062,7 +2062,7 @@ unknown:
buf[5] = 0x01;
switch (ctrl->bRequestType & USB_RECIP_MASK) {
case USB_RECIP_DEVICE:
if (w_index != 0x4 || (w_value >> 8))
if (w_index != 0x4 || (w_value & 0xff))
break;
buf[6] = w_index;
/* Number of ext compat interfaces */
@@ -2084,9 +2084,9 @@ unknown:
}
break;
case USB_RECIP_INTERFACE:
if (w_index != 0x5 || (w_value >> 8))
if (w_index != 0x5 || (w_value & 0xff))
break;
interface = w_value & 0xFF;
interface = w_value >> 8;
if (interface >= MAX_CONFIG_INTERFACES ||
!os_desc_cfg->interface[interface])
break;
+1 -1
View File
@@ -3621,7 +3621,7 @@ static int ffs_func_setup(struct usb_function *f,
__ffs_event_add(ffs, FUNCTIONFS_SETUP);
spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags);
return creq->wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0;
return ffs->ev.setup.wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0;
}
static bool ffs_func_req_match(struct usb_function *f,
+40
View File
@@ -255,6 +255,10 @@ static void option_instat_callback(struct urb *urb);
#define QUECTEL_PRODUCT_EM061K_LMS 0x0124
#define QUECTEL_PRODUCT_EC25 0x0125
#define QUECTEL_PRODUCT_EM060K_128 0x0128
#define QUECTEL_PRODUCT_EM060K_129 0x0129
#define QUECTEL_PRODUCT_EM060K_12a 0x012a
#define QUECTEL_PRODUCT_EM060K_12b 0x012b
#define QUECTEL_PRODUCT_EM060K_12c 0x012c
#define QUECTEL_PRODUCT_EG91 0x0191
#define QUECTEL_PRODUCT_EG95 0x0195
#define QUECTEL_PRODUCT_BG96 0x0296
@@ -1218,6 +1222,18 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0x00, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_129, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_129, 0xff, 0x00, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_129, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12a, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12a, 0xff, 0x00, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12a, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12b, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12b, 0xff, 0x00, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12b, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12c, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12c, 0xff, 0x00, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_12c, 0xff, 0xff, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0x00, 0x40) },
{ USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x40) },
@@ -1360,6 +1376,12 @@ static const struct usb_device_id option_ids[] = {
.driver_info = NCTRL(2) | RSVD(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1083, 0xff), /* Telit FE990 (ECM) */
.driver_info = NCTRL(0) | RSVD(1) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a0, 0xff), /* Telit FN20C04 (rmnet) */
.driver_info = RSVD(0) | NCTRL(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a4, 0xff), /* Telit FN20C04 (rmnet) */
.driver_info = RSVD(0) | NCTRL(3) },
{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a9, 0xff), /* Telit FN20C04 (rmnet) */
.driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
.driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
@@ -2052,6 +2074,10 @@ static const struct usb_device_id option_ids[] = {
.driver_info = RSVD(3) },
{ USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9803, 0xff),
.driver_info = RSVD(4) },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, 0x9b05), /* Longsung U8300 */
.driver_info = RSVD(4) | RSVD(5) },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, 0x9b3c), /* Longsung U9300 */
.driver_info = RSVD(0) | RSVD(4) },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) },
{ USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) },
@@ -2272,15 +2298,29 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) }, /* Fibocom FG150 Diag */
{ USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) }, /* Fibocom FG150 AT */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0111, 0xff) }, /* Fibocom FM160 (MBIM mode) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0115, 0xff), /* Fibocom FM135 (laptop MBIM) */
.driver_info = RSVD(5) },
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a2, 0xff) }, /* Fibocom FM101-GL (laptop MBIM) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a3, 0xff) }, /* Fibocom FM101-GL (laptop MBIM) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a4, 0xff), /* Fibocom FM101-GL (laptop MBIM) */
.driver_info = RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a04, 0xff) }, /* Fibocom FM650-CN (ECM mode) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a05, 0xff) }, /* Fibocom FM650-CN (NCM mode) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a06, 0xff) }, /* Fibocom FM650-CN (RNDIS mode) */
{ USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0a07, 0xff) }, /* Fibocom FM650-CN (MBIM mode) */
{ USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */
{ USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */
{ USB_DEVICE(0x33f8, 0x0104), /* Rolling RW101-GL (laptop RMNET) */
.driver_info = RSVD(4) | RSVD(5) },
{ USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a2, 0xff) }, /* Rolling RW101-GL (laptop MBIM) */
{ USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a3, 0xff) }, /* Rolling RW101-GL (laptop MBIM) */
{ USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x01a4, 0xff), /* Rolling RW101-GL (laptop MBIM) */
.driver_info = RSVD(4) },
{ USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0115, 0xff), /* Rolling RW135-GL (laptop MBIM) */
.driver_info = RSVD(5) },
{ USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) },
{ USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) },
+12 -2
View File
@@ -2432,9 +2432,19 @@ bool vhost_vq_avail_empty(struct vhost_dev *dev, struct vhost_virtqueue *vq)
r = vhost_get_avail(vq, avail_idx, &vq->avail->idx);
if (unlikely(r))
return false;
vq->avail_idx = vhost16_to_cpu(vq, avail_idx);
return vq->avail_idx == vq->last_avail_idx;
vq->avail_idx = vhost16_to_cpu(vq, avail_idx);
if (vq->avail_idx != vq->last_avail_idx) {
/* Since we have updated avail_idx, the following
* call to vhost_get_vq_desc() will read available
* ring entries. Make sure that read happens after
* the avail_idx read.
*/
smp_rmb();
return false;
}
return true;
}
EXPORT_SYMBOL_GPL(vhost_vq_avail_empty);
+2
View File
@@ -691,6 +691,7 @@ const struct file_operations v9fs_file_operations = {
.lock = v9fs_file_lock,
.mmap = generic_file_readonly_mmap,
.fsync = v9fs_file_fsync,
.setlease = simple_nosetlease,
};
const struct file_operations v9fs_file_operations_dotl = {
@@ -726,4 +727,5 @@ const struct file_operations v9fs_mmap_file_operations_dotl = {
.flock = v9fs_file_flock_dotl,
.mmap = v9fs_mmap_file_mmap,
.fsync = v9fs_file_fsync_dotl,
.setlease = simple_nosetlease,
};
+4 -1
View File
@@ -101,7 +101,7 @@ static int p9mode2perm(struct v9fs_session_info *v9ses,
int res;
int mode = stat->mode;
res = mode & S_IALLUGO;
res = mode & 0777; /* S_IRWXUGO */
if (v9fs_proto_dotu(v9ses)) {
if ((mode & P9_DMSETUID) == P9_DMSETUID)
res |= S_ISUID;
@@ -192,6 +192,9 @@ int v9fs_uflags2omode(int uflags, int extended)
break;
}
if (uflags & O_TRUNC)
ret |= P9_OTRUNC;
if (extended) {
if (uflags & O_EXCL)
ret |= P9_OEXCL;
+1
View File
@@ -346,6 +346,7 @@ static const struct super_operations v9fs_super_ops = {
.alloc_inode = v9fs_alloc_inode,
.destroy_inode = v9fs_destroy_inode,
.statfs = simple_statfs,
.drop_inode = v9fs_drop_inode,
.evict_inode = v9fs_evict_inode,
.show_options = v9fs_show_options,
.umount_begin = v9fs_umount_begin,
+3 -9
View File
@@ -2236,20 +2236,14 @@ struct btrfs_data_container *init_data_container(u32 total_bytes)
size_t alloc_bytes;
alloc_bytes = max_t(size_t, total_bytes, sizeof(*data));
data = kvmalloc(alloc_bytes, GFP_KERNEL);
data = kvzalloc(alloc_bytes, GFP_KERNEL);
if (!data)
return ERR_PTR(-ENOMEM);
if (total_bytes >= sizeof(*data)) {
if (total_bytes >= sizeof(*data))
data->bytes_left = total_bytes - sizeof(*data);
data->bytes_missing = 0;
} else {
else
data->bytes_missing = sizeof(*data) - total_bytes;
data->bytes_left = 0;
}
data->elem_cnt = 0;
data->elem_missed = 0;
return data;
}
+3
View File
@@ -1133,6 +1133,9 @@ __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
if (ret)
return ret;
ret = btrfs_record_root_in_trans(trans, node->root);
if (ret)
return ret;
ret = btrfs_update_delayed_inode(trans, node->root, path, node);
return ret;
}
+1 -1
View File
@@ -1906,7 +1906,7 @@ static void btrfs_clear_bit_hook(void *private_data,
*/
if (*bits & EXTENT_CLEAR_META_RESV &&
root != fs_info->tree_root)
btrfs_delalloc_release_metadata(inode, len, false);
btrfs_delalloc_release_metadata(inode, len, true);
/* For sanity tests. */
if (btrfs_is_testing(fs_info))
+1 -1
View File
@@ -1271,6 +1271,7 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans)
radix_tree_tag_clear(&fs_info->fs_roots_radix,
(unsigned long)root->root_key.objectid,
BTRFS_ROOT_TRANS_TAG);
btrfs_qgroup_free_meta_all_pertrans(root);
spin_unlock(&fs_info->fs_roots_radix_lock);
btrfs_free_log(trans, root);
@@ -1295,7 +1296,6 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans)
if (ret2)
return ret2;
spin_lock(&fs_info->fs_roots_radix_lock);
btrfs_qgroup_free_meta_all_pertrans(root);
}
}
spin_unlock(&fs_info->fs_roots_radix_lock);
+1
View File
@@ -2957,6 +2957,7 @@ again:
* alignment and size).
*/
ret = -EUCLEAN;
mutex_unlock(&fs_info->delete_unused_bgs_mutex);
goto error;
}
+3 -2
View File
@@ -1751,7 +1751,8 @@ static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length)
struct buffer_head *dibh, *bh;
struct gfs2_holder rd_gh;
unsigned int bsize_shift = sdp->sd_sb.sb_bsize_shift;
u64 lblock = (offset + (1 << bsize_shift) - 1) >> bsize_shift;
unsigned int bsize = 1 << bsize_shift;
u64 lblock = (offset + bsize - 1) >> bsize_shift;
__u16 start_list[GFS2_MAX_META_HEIGHT];
__u16 __end_list[GFS2_MAX_META_HEIGHT], *end_list = NULL;
unsigned int start_aligned, end_aligned;
@@ -1762,7 +1763,7 @@ static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length)
u64 prev_bnr = 0;
__be64 *start, *end;
if (offset >= maxsize) {
if (offset + bsize - 1 >= maxsize) {
/*
* The starting point lies beyond the allocated meta-data;
* there are no blocks do deallocate.
+1 -1
View File
@@ -243,7 +243,7 @@ nilfs_filetype_table[NILFS_FT_MAX] = {
#define S_SHIFT 12
static unsigned char
nilfs_type_by_mode[S_IFMT >> S_SHIFT] = {
nilfs_type_by_mode[(S_IFMT >> S_SHIFT) + 1] = {
[S_IFREG >> S_SHIFT] = NILFS_FT_REG_FILE,
[S_IFDIR >> S_SHIFT] = NILFS_FT_DIR,
[S_IFCHR >> S_SHIFT] = NILFS_FT_CHRDEV,
+2
View File
@@ -431,6 +431,8 @@ struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj,
kn = kernfs_find_and_get(kobj->sd, attr->name);
if (kn)
kernfs_break_active_protection(kn);
else
kobject_put(kobj);
return kn;
}
EXPORT_SYMBOL_GPL(sysfs_break_active_protection);
+46
View File
@@ -522,6 +522,52 @@ static inline unsigned long compare_ether_header(const void *a, const void *b)
#endif
}
/**
* eth_hw_addr_gen - Generate and assign Ethernet address to a port
* @dev: pointer to port's net_device structure
* @base_addr: base Ethernet address
* @id: offset to add to the base address
*
* Generate a MAC address using a base address and an offset and assign it
* to a net_device. Commonly used by switch drivers which need to compute
* addresses for all their ports. addr_assign_type is not changed.
*/
static inline void eth_hw_addr_gen(struct net_device *dev, const u8 *base_addr,
unsigned int id)
{
u64 u = ether_addr_to_u64(base_addr);
u8 addr[ETH_ALEN];
u += id;
u64_to_ether_addr(u, addr);
eth_hw_addr_set(dev, addr);
}
/**
* eth_skb_pkt_type - Assign packet type if destination address does not match
* @skb: Assigned a packet type if address does not match @dev address
* @dev: Network device used to compare packet address against
*
* If the destination MAC address of the packet does not match the network
* device address, assign an appropriate packet type.
*/
static inline void eth_skb_pkt_type(struct sk_buff *skb,
const struct net_device *dev)
{
const struct ethhdr *eth = eth_hdr(skb);
if (unlikely(!ether_addr_equal_64bits(eth->h_dest, dev->dev_addr))) {
if (unlikely(is_multicast_ether_addr_64bits(eth->h_dest))) {
if (ether_addr_equal_64bits(eth->h_dest, dev->broadcast))
skb->pkt_type = PACKET_BROADCAST;
else
skb->pkt_type = PACKET_MULTICAST;
} else {
skb->pkt_type = PACKET_OTHERHOST;
}
}
}
/**
* eth_skb_pad - Pad buffer to mininum number of octets for Ethernet frame
* @skb: Buffer to pad
+2
View File
@@ -890,11 +890,13 @@ struct ipa_rx_data {
* @page: skb page
* @dma_addr: DMA address of this Rx packet
* @is_tmp_alloc: skb page from tmp_alloc or recycle_list
* @page_order: page order associated with the page.
*/
struct ipa_rx_page_data {
struct page *page;
dma_addr_t dma_addr;
bool is_tmp_alloc;
u32 page_order;
};
+79
View File
@@ -264,6 +264,85 @@ struct uart_port {
void *private_data; /* generic platform data pointer */
};
/**
* uart_port_lock - Lock the UART port
* @up: Pointer to UART port structure
*/
static inline void uart_port_lock(struct uart_port *up)
{
spin_lock(&up->lock);
}
/**
* uart_port_lock_irq - Lock the UART port and disable interrupts
* @up: Pointer to UART port structure
*/
static inline void uart_port_lock_irq(struct uart_port *up)
{
spin_lock_irq(&up->lock);
}
/**
* uart_port_lock_irqsave - Lock the UART port, save and disable interrupts
* @up: Pointer to UART port structure
* @flags: Pointer to interrupt flags storage
*/
static inline void uart_port_lock_irqsave(struct uart_port *up, unsigned long *flags)
{
spin_lock_irqsave(&up->lock, *flags);
}
/**
* uart_port_trylock - Try to lock the UART port
* @up: Pointer to UART port structure
*
* Returns: True if lock was acquired, false otherwise
*/
static inline bool uart_port_trylock(struct uart_port *up)
{
return spin_trylock(&up->lock);
}
/**
* uart_port_trylock_irqsave - Try to lock the UART port, save and disable interrupts
* @up: Pointer to UART port structure
* @flags: Pointer to interrupt flags storage
*
* Returns: True if lock was acquired, false otherwise
*/
static inline bool uart_port_trylock_irqsave(struct uart_port *up, unsigned long *flags)
{
return spin_trylock_irqsave(&up->lock, *flags);
}
/**
* uart_port_unlock - Unlock the UART port
* @up: Pointer to UART port structure
*/
static inline void uart_port_unlock(struct uart_port *up)
{
spin_unlock(&up->lock);
}
/**
* uart_port_unlock_irq - Unlock the UART port and re-enable interrupts
* @up: Pointer to UART port structure
*/
static inline void uart_port_unlock_irq(struct uart_port *up)
{
spin_unlock_irq(&up->lock);
}
/**
* uart_port_unlock_irqrestore - Unlock the UART port, restore interrupts
* @up: Pointer to UART port structure
* @flags: The saved interrupt flags for restore
*/
static inline void uart_port_unlock_irqrestore(struct uart_port *up, unsigned long flags)
{
spin_unlock_irqrestore(&up->lock, flags);
}
static inline int serial_port_in(struct uart_port *up, int offset)
{
return up->serial_in(up, offset);
+20
View File
@@ -494,4 +494,24 @@ static inline void memcpy_and_pad(void *dest, size_t dest_len,
memcpy(dest, src, dest_len);
}
/**
* str_has_prefix - Test if a string has a given prefix
* @str: The string to test
* @prefix: The string to see if @str starts with
*
* A common way to test a prefix of a string is to do:
* strncmp(str, prefix, sizeof(prefix) - 1)
*
* But this can lead to bugs due to typos, or if prefix is a pointer
* and not a constant. Instead use str_has_prefix().
*
* Returns: 0 if @str does not start with @prefix
strlen(@prefix) if @str does start with @prefix
*/
static __always_inline size_t str_has_prefix(const char *str, const char *prefix)
{
size_t len = strlen(prefix);
return strncmp(str, prefix, len) == 0 ? len : 0;
}
#endif /* _LINUX_STRING_H_ */
+1 -3
View File
@@ -416,7 +416,7 @@ struct trace_event_file {
} \
early_initcall(trace_init_perf_perm_##name);
#define PERF_MAX_TRACE_SIZE 2048
#define PERF_MAX_TRACE_SIZE 8192
#define MAX_FILTER_STR_VAL 256 /* Should handle KSYM_SYMBOL_LEN */
@@ -531,8 +531,6 @@ extern int trace_event_raw_init(struct trace_event_call *call);
extern int trace_define_field(struct trace_event_call *call, const char *type,
const char *name, int offset, int size,
int is_signed, int filter_type);
extern int trace_add_event_call_nolock(struct trace_event_call *call);
extern int trace_remove_event_call_nolock(struct trace_event_call *call);
extern int trace_add_event_call(struct trace_event_call *call);
extern int trace_remove_event_call(struct trace_event_call *call);
extern int trace_event_get_offsets(struct trace_event_call *call);
+4
View File
@@ -455,6 +455,10 @@ static inline void in6_ifa_hold(struct inet6_ifaddr *ifp)
refcount_inc(&ifp->refcnt);
}
static inline bool in6_ifa_hold_safe(struct inet6_ifaddr *ifp)
{
return refcount_inc_not_zero(&ifp->refcnt);
}
/*
* compute link-local solicited-node multicast address
+4 -1
View File
@@ -52,7 +52,7 @@ struct unix_sock {
struct mutex iolock, bindlock;
struct sock *peer;
struct list_head link;
atomic_long_t inflight;
unsigned long inflight;
spinlock_t lock;
unsigned long gc_flags;
#define UNIX_GC_CANDIDATE 0
@@ -72,6 +72,9 @@ enum unix_socket_lock_class {
U_LOCK_NORMAL,
U_LOCK_SECOND, /* for double locking, see unix_state_double_lock(). */
U_LOCK_DIAG, /* used while dumping icons, see sk_diag_dump_icons(). */
U_LOCK_GC_LISTENER, /* used for listening socket while determining gc
* candidates to close a small race window.
*/
};
static inline void unix_state_lock_nested(struct sock *sk,
+1 -1
View File
@@ -24,7 +24,7 @@ struct dst_ops {
void (*destroy)(struct dst_entry *);
void (*ifdown)(struct dst_entry *,
struct net_device *dev, int how);
struct dst_entry * (*negative_advice)(struct dst_entry *);
void (*negative_advice)(struct sock *sk, struct dst_entry *);
void (*link_failure)(struct sk_buff *);
void (*update_pmtu)(struct dst_entry *dst, struct sock *sk,
struct sk_buff *skb, u32 mtu,
+33
View File
@@ -348,6 +348,39 @@ static inline bool pskb_inet_may_pull(struct sk_buff *skb)
return pskb_network_may_pull(skb, nhlen);
}
/* Variant of pskb_inet_may_pull().
*/
static inline bool skb_vlan_inet_prepare(struct sk_buff *skb)
{
int nhlen = 0, maclen = ETH_HLEN;
__be16 type = skb->protocol;
/* Essentially this is skb_protocol(skb, true)
* And we get MAC len.
*/
if (eth_type_vlan(type))
type = __vlan_get_protocol(skb, type, &maclen);
switch (type) {
#if IS_ENABLED(CONFIG_IPV6)
case htons(ETH_P_IPV6):
nhlen = sizeof(struct ipv6hdr);
break;
#endif
case htons(ETH_P_IP):
nhlen = sizeof(struct iphdr);
break;
}
/* For ETH_P_IPV6/ETH_P_IP we make sure to pull
* a base network header in skb->head.
*/
if (!pskb_may_pull(skb, maclen + nhlen))
return false;
skb_set_network_header(skb, maclen);
return true;
}
static inline int ip_encap_hlen(struct ip_tunnel_encap *e)
{
const struct ip_tunnel_encap_ops *ops;
+3 -10
View File
@@ -1924,19 +1924,12 @@ sk_dst_get(struct sock *sk)
static inline void dst_negative_advice(struct sock *sk)
{
struct dst_entry *ndst, *dst = __sk_dst_get(sk);
struct dst_entry *dst = __sk_dst_get(sk);
sk_rethink_txhash(sk);
if (dst && dst->ops->negative_advice) {
ndst = dst->ops->negative_advice(dst);
if (ndst != dst) {
rcu_assign_pointer(sk->sk_dst_cache, ndst);
sk_tx_queue_clear(sk);
WRITE_ONCE(sk->sk_dst_pending_confirm, 0);
}
}
if (dst && dst->ops->negative_advice)
dst->ops->negative_advice(sk, dst);
}
static inline void
+2 -2
View File
@@ -22,8 +22,8 @@
#define RUSAGE_THREAD 1 /* only the calling thread */
struct rusage {
struct __kernel_old_timeval ru_utime; /* user time used */
struct __kernel_old_timeval ru_stime; /* system time used */
struct timeval ru_utime; /* user time used */
struct timeval ru_stime; /* system time used */
__kernel_long_t ru_maxrss; /* maximum resident set size */
__kernel_long_t ru_ixrss; /* integral shared memory size */
__kernel_long_t ru_idrss; /* integral unshared data size */
+31
View File
@@ -167,6 +167,24 @@ done:
}
return res;
}
/**
* match_dev_by_label - callback for finding a partition using its label
* @dev: device passed in by the caller
* @data: opaque pointer to the label to match
*
* Returns 1 if the device matches, and 0 otherwise.
*/
static int match_dev_by_label(struct device *dev, const void *data)
{
const char *label = data;
struct hd_struct *part = dev_to_part(dev);
if (part->info && !strcmp(label, part->info->volname))
return 1;
return 0;
}
#endif
/*
@@ -190,6 +208,8 @@ done:
* a partition with a known unique id.
* 8) <major>:<minor> major and minor number of the device separated by
* a colon.
* 9) PARTLABEL=<name> with name being the GPT partition label.
* MSDOS partitions do not support labels!
*
* If name doesn't have fall into the categories above, we return (0,0).
* block_class is used to check if something is a disk name. If the disk
@@ -211,6 +231,17 @@ dev_t name_to_dev_t(const char *name)
if (!res)
goto fail;
goto done;
} else if (strncmp(name, "PARTLABEL=", 10) == 0) {
struct device *dev;
dev = class_find_device(&block_class, NULL, name + 10,
&match_dev_by_label);
if (!dev)
goto fail;
res = dev->devt;
put_device(dev);
goto done;
}
#endif
+12 -6
View File
@@ -1565,10 +1565,17 @@ static int check_kprobe_address_safe(struct kprobe *p,
jump_label_lock();
preempt_disable();
/* Ensure it is not in reserved area nor out of text */
if (!(core_kernel_text((unsigned long) p->addr) ||
is_module_text_address((unsigned long) p->addr)) ||
in_gate_area_no_mm((unsigned long) p->addr) ||
/* Ensure the address is in a text area, and find a module if exists. */
*probed_mod = NULL;
if (!core_kernel_text((unsigned long) p->addr)) {
*probed_mod = __module_text_address((unsigned long) p->addr);
if (!(*probed_mod)) {
ret = -EINVAL;
goto out;
}
}
/* Ensure it is not in reserved area. */
if (in_gate_area_no_mm((unsigned long) p->addr) ||
within_kprobe_blacklist((unsigned long) p->addr) ||
jump_label_text_reserved(p->addr, p->addr) ||
find_bug((unsigned long)p->addr)) {
@@ -1576,8 +1583,7 @@ static int check_kprobe_address_safe(struct kprobe *p,
goto out;
}
/* Check if are we probing a module */
*probed_mod = __module_text_address((unsigned long) p->addr);
/* Get module refcount and reject __init functions for loaded modules. */
if (*probed_mod) {
/*
* We must hold a refcount of the probed module while updating
Loaded 100 of 159 files, more files were not shown because too many files have changed in this diff. Show more