This is the 4.19.101 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAl41RsgACgkQONu9yGCS aT4P7A/+PZVt4c6phHZ9tj0OV4TjAWfu3IX9nLypzyBxjmBeJu8yt1pkNrfKj6fT +N3MjDlmAYss5CV6SOACPWXdhAQF3SsM6PR+CSrzwpS3+iAVTqNTaHpZqJFBgr3R cDe+MksbMLDpw3x+hXWV1E6WKcJZZJVeANuaD09HQDRVqKw1hRGxGEdyPChEjT71 Ml3o9a2TYzOvRClBtBHPRQNy/MP4cVv06kS7jefDNh1z9PMsD2w01W54ur44WFJb aujt6bLyJlcs0cPdSkU7D8pmgzs/0cxW8N+4gCpfW66P6FJL8SU4RDTujUARlyvC oP5d62XrARXAO0hh1NYdWyUqpQjOFJRTWfEqW+lFGo5s9yL9oPW8vcCBKBuZfg+u HlVCCTCyU/IJN0DMeqdneThDg8sxirlzHu/NllgGIf7rhyMRqRmruQZXc1W3/7e8 UgqqAEFkgVmJgq3mVWlHsV5Fmgb+PQlqj4rSB05wlAbXsQwF0nbSS/lsvwDR8qqE 8nO/PQoxpQyAOYJ+iyaCsq51IsJUCwWOto8L/RpdYSbFpLTn+BRmNdDr7jHOVnPl FshugoXijE6IrVGIJhJBGGy/E+eG8Dru7IZEsi2UZLsw+bBvucqv7raIHAJ2YRaL 8ZuwwmvpZpCOdYSWa7lIgqZb0qOTyR+b6UQ57X8hS5U3MZ2jMOE= =+bpt -----END PGP SIGNATURE----- Merge 4.19.101 into android-4.19 Changes in 4.19.101 orinoco_usb: fix interface sanity check rsi_91x_usb: fix interface sanity check usb: dwc3: pci: add ID for the Intel Comet Lake -V variant USB: serial: ir-usb: add missing endpoint sanity check USB: serial: ir-usb: fix link-speed handling USB: serial: ir-usb: fix IrLAP framing usb: dwc3: turn off VBUS when leaving host mode staging: most: net: fix buffer overflow staging: wlan-ng: ensure error return is actually returned staging: vt6656: correct packet types for CTS protect, mode. staging: vt6656: use NULLFUCTION stack on mac80211 staging: vt6656: Fix false Tx excessive retries reporting. serial: 8250_bcm2835aux: Fix line mismatch on driver unbind component: do not dereference opaque pointer in debugfs mei: me: add comet point (lake) H device ids iio: st_gyro: Correct data for LSM9DS0 gyro crypto: chelsio - fix writing tfm flags to wrong place cifs: Fix memory allocation in __smb2_handle_cancelled_cmd() ath9k: fix storage endpoint lookup brcmfmac: fix interface sanity check rtl8xxxu: fix interface sanity check zd1211rw: fix storage endpoint lookup net_sched: ematch: reject invalid TCF_EM_SIMPLE net_sched: fix ops->bind_class() implementations HID: multitouch: Add LG MELF0410 I2C touchscreen support arc: eznps: fix allmodconfig kconfig warning HID: Add quirk for Xin-Mo Dual Controller HID: ite: Add USB id match for Acer SW5-012 keyboard dock HID: Add quirk for incorrect input length on Lenovo Y720 drivers/hid/hid-multitouch.c: fix a possible null pointer access. phy: qcom-qmp: Increase PHY ready timeout phy: cpcap-usb: Prevent USB line glitches from waking up modem watchdog: max77620_wdt: fix potential build errors watchdog: rn5t618_wdt: fix module aliases spi: spi-dw: Add lock protect dw_spi rx/tx to prevent concurrent calls drivers/net/b44: Change to non-atomic bit operations on pwol_mask net: wan: sdla: Fix cast from pointer to integer of different size gpio: max77620: Add missing dependency on GPIOLIB_IRQCHIP atm: eni: fix uninitialized variable warning HID: steam: Fix input device disappearing platform/x86: dell-laptop: disable kbd backlight on Inspiron 10xx PCI: Add DMA alias quirk for Intel VCA NTB iommu/amd: Support multiple PCI DMA aliases in IRQ Remapping ARM: OMAP2+: SmartReflex: add omap_sr_pdata definition usb-storage: Disable UAS on JMicron SATA enclosure sched/fair: Add tmp_alone_branch assertion sched/fair: Fix insertion in rq->leaf_cfs_rq_list rsi: fix use-after-free on probe errors rsi: fix memory leak on failed URB submission rsi: fix non-atomic allocation in completion handler crypto: af_alg - Use bh_lock_sock in sk_destruct random: try to actively add entropy rather than passively wait for it block: cleanup __blkdev_issue_discard() block: fix 32 bit overflow in __blkdev_issue_discard() KVM: arm64: Write arch.mdcr_el2 changes since last vcpu_load on VHE Linux 4.19.101 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I801cd8d04eea35b4b53957cc69c0987d88094992
This commit is contained in:
commit
1b44c9bd91
64 changed files with 701 additions and 241 deletions
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 19
|
||||
SUBLEVEL = 100
|
||||
SUBLEVEL = 101
|
||||
EXTRAVERSION =
|
||||
NAME = "People's Front"
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
menuconfig ARC_PLAT_EZNPS
|
||||
bool "\"EZchip\" ARC dev platform"
|
||||
select CPU_BIG_ENDIAN
|
||||
select CLKSRC_NPS
|
||||
select CLKSRC_NPS if !PHYS_ADDR_T_64BIT
|
||||
select EZNPS_GIC
|
||||
select EZCHIP_NPS_MANAGEMENT_ENET if ETHERNET
|
||||
help
|
||||
|
|
|
@ -112,7 +112,7 @@ void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu)
|
|||
void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
bool trap_debug = !(vcpu->arch.flags & KVM_ARM64_DEBUG_DIRTY);
|
||||
unsigned long mdscr;
|
||||
unsigned long mdscr, orig_mdcr_el2 = vcpu->arch.mdcr_el2;
|
||||
|
||||
trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug);
|
||||
|
||||
|
@ -208,6 +208,10 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
|
|||
if (vcpu_read_sys_reg(vcpu, MDSCR_EL1) & (DBG_MDSCR_KDE | DBG_MDSCR_MDE))
|
||||
vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY;
|
||||
|
||||
/* Write mdcr_el2 changes since vcpu_load on VHE systems */
|
||||
if (has_vhe() && orig_mdcr_el2 != vcpu->arch.mdcr_el2)
|
||||
write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
|
||||
|
||||
trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2);
|
||||
trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_read_sys_reg(vcpu, MDSCR_EL1));
|
||||
}
|
||||
|
|
|
@ -52,15 +52,14 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
|
|||
if ((sector | nr_sects) & bs_mask)
|
||||
return -EINVAL;
|
||||
|
||||
if (!nr_sects)
|
||||
return -EINVAL;
|
||||
|
||||
while (nr_sects) {
|
||||
unsigned int req_sects = nr_sects;
|
||||
sector_t end_sect;
|
||||
sector_t req_sects = min_t(sector_t, nr_sects,
|
||||
bio_allowed_max_sectors(q));
|
||||
|
||||
if (!req_sects)
|
||||
goto fail;
|
||||
req_sects = min(req_sects, bio_allowed_max_sectors(q));
|
||||
|
||||
end_sect = sector + req_sects;
|
||||
WARN_ON_ONCE((req_sects << 9) > UINT_MAX);
|
||||
|
||||
bio = next_bio(bio, 0, gfp_mask);
|
||||
bio->bi_iter.bi_sector = sector;
|
||||
|
@ -68,8 +67,8 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
|
|||
bio_set_op_attrs(bio, op, 0);
|
||||
|
||||
bio->bi_iter.bi_size = req_sects << 9;
|
||||
sector += req_sects;
|
||||
nr_sects -= req_sects;
|
||||
sector = end_sect;
|
||||
|
||||
/*
|
||||
* We can loop for a long time in here, if someone does
|
||||
|
@ -82,14 +81,6 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
|
|||
|
||||
*biop = bio;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
if (bio) {
|
||||
submit_bio_wait(bio);
|
||||
bio_put(bio);
|
||||
}
|
||||
*biop = NULL;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
EXPORT_SYMBOL(__blkdev_issue_discard);
|
||||
|
||||
|
|
|
@ -139,11 +139,13 @@ void af_alg_release_parent(struct sock *sk)
|
|||
sk = ask->parent;
|
||||
ask = alg_sk(sk);
|
||||
|
||||
lock_sock(sk);
|
||||
local_bh_disable();
|
||||
bh_lock_sock(sk);
|
||||
ask->nokey_refcnt -= nokey;
|
||||
if (!last)
|
||||
last = !--ask->refcnt;
|
||||
release_sock(sk);
|
||||
bh_unlock_sock(sk);
|
||||
local_bh_enable();
|
||||
|
||||
if (last)
|
||||
sock_put(sk);
|
||||
|
|
|
@ -372,7 +372,7 @@ static int do_rx_dma(struct atm_vcc *vcc,struct sk_buff *skb,
|
|||
here = (eni_vcc->descr+skip) & (eni_vcc->words-1);
|
||||
dma[j++] = (here << MID_DMA_COUNT_SHIFT) | (vcc->vci
|
||||
<< MID_DMA_VCI_SHIFT) | MID_DT_JK;
|
||||
j++;
|
||||
dma[j++] = 0;
|
||||
}
|
||||
here = (eni_vcc->descr+size+skip) & (eni_vcc->words-1);
|
||||
if (!eff) size += skip;
|
||||
|
@ -445,7 +445,7 @@ static int do_rx_dma(struct atm_vcc *vcc,struct sk_buff *skb,
|
|||
if (size != eff) {
|
||||
dma[j++] = (here << MID_DMA_COUNT_SHIFT) |
|
||||
(vcc->vci << MID_DMA_VCI_SHIFT) | MID_DT_JK;
|
||||
j++;
|
||||
dma[j++] = 0;
|
||||
}
|
||||
if (!j || j > 2*RX_DMA_BUF) {
|
||||
printk(KERN_CRIT DEV_LABEL "!j or j too big!!!\n");
|
||||
|
|
|
@ -74,11 +74,11 @@ static int component_devices_show(struct seq_file *s, void *data)
|
|||
seq_printf(s, "%-40s %20s\n", "device name", "status");
|
||||
seq_puts(s, "-------------------------------------------------------------\n");
|
||||
for (i = 0; i < match->num; i++) {
|
||||
struct device *d = (struct device *)match->compare[i].data;
|
||||
struct component *component = match->compare[i].component;
|
||||
|
||||
seq_printf(s, "%-40s %20s\n", dev_name(d),
|
||||
match->compare[i].component ?
|
||||
"registered" : "not registered");
|
||||
seq_printf(s, "%-40s %20s\n",
|
||||
component ? dev_name(component->dev) : "(unknown)",
|
||||
component ? (component->bound ? "bound" : "not bound") : "not registered");
|
||||
}
|
||||
mutex_unlock(&component_mutex);
|
||||
|
||||
|
|
|
@ -1652,6 +1652,56 @@ void get_random_bytes(void *buf, int nbytes)
|
|||
}
|
||||
EXPORT_SYMBOL(get_random_bytes);
|
||||
|
||||
|
||||
/*
|
||||
* Each time the timer fires, we expect that we got an unpredictable
|
||||
* jump in the cycle counter. Even if the timer is running on another
|
||||
* CPU, the timer activity will be touching the stack of the CPU that is
|
||||
* generating entropy..
|
||||
*
|
||||
* Note that we don't re-arm the timer in the timer itself - we are
|
||||
* happy to be scheduled away, since that just makes the load more
|
||||
* complex, but we do not want the timer to keep ticking unless the
|
||||
* entropy loop is running.
|
||||
*
|
||||
* So the re-arming always happens in the entropy loop itself.
|
||||
*/
|
||||
static void entropy_timer(struct timer_list *t)
|
||||
{
|
||||
credit_entropy_bits(&input_pool, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have an actual cycle counter, see if we can
|
||||
* generate enough entropy with timing noise
|
||||
*/
|
||||
static void try_to_generate_entropy(void)
|
||||
{
|
||||
struct {
|
||||
unsigned long now;
|
||||
struct timer_list timer;
|
||||
} stack;
|
||||
|
||||
stack.now = random_get_entropy();
|
||||
|
||||
/* Slow counter - or none. Don't even bother */
|
||||
if (stack.now == random_get_entropy())
|
||||
return;
|
||||
|
||||
timer_setup_on_stack(&stack.timer, entropy_timer, 0);
|
||||
while (!crng_ready()) {
|
||||
if (!timer_pending(&stack.timer))
|
||||
mod_timer(&stack.timer, jiffies+1);
|
||||
mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
|
||||
schedule();
|
||||
stack.now = random_get_entropy();
|
||||
}
|
||||
|
||||
del_timer_sync(&stack.timer);
|
||||
destroy_timer_on_stack(&stack.timer);
|
||||
mix_pool_bytes(&input_pool, &stack.now, sizeof(stack.now));
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the urandom pool to be seeded and thus guaranteed to supply
|
||||
* cryptographically secure random numbers. This applies to: the /dev/urandom
|
||||
|
@ -1666,7 +1716,17 @@ int wait_for_random_bytes(void)
|
|||
{
|
||||
if (likely(crng_ready()))
|
||||
return 0;
|
||||
return wait_event_interruptible(crng_init_wait, crng_ready());
|
||||
|
||||
do {
|
||||
int ret;
|
||||
ret = wait_event_interruptible_timeout(crng_init_wait, crng_ready(), HZ);
|
||||
if (ret)
|
||||
return ret > 0 ? 0 : ret;
|
||||
|
||||
try_to_generate_entropy();
|
||||
} while (!crng_ready());
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(wait_for_random_bytes);
|
||||
|
||||
|
|
|
@ -3135,9 +3135,6 @@ static int chcr_gcm_setauthsize(struct crypto_aead *tfm, unsigned int authsize)
|
|||
aeadctx->mayverify = VERIFY_SW;
|
||||
break;
|
||||
default:
|
||||
|
||||
crypto_tfm_set_flags((struct crypto_tfm *) tfm,
|
||||
CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
return crypto_aead_setauthsize(aeadctx->sw_cipher, authsize);
|
||||
|
@ -3162,8 +3159,6 @@ static int chcr_4106_4309_setauthsize(struct crypto_aead *tfm,
|
|||
aeadctx->mayverify = VERIFY_HW;
|
||||
break;
|
||||
default:
|
||||
crypto_tfm_set_flags((struct crypto_tfm *)tfm,
|
||||
CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
return crypto_aead_setauthsize(aeadctx->sw_cipher, authsize);
|
||||
|
@ -3204,8 +3199,6 @@ static int chcr_ccm_setauthsize(struct crypto_aead *tfm,
|
|||
aeadctx->mayverify = VERIFY_HW;
|
||||
break;
|
||||
default:
|
||||
crypto_tfm_set_flags((struct crypto_tfm *)tfm,
|
||||
CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
return crypto_aead_setauthsize(aeadctx->sw_cipher, authsize);
|
||||
|
@ -3230,8 +3223,7 @@ static int chcr_ccm_common_setkey(struct crypto_aead *aead,
|
|||
ck_size = CHCR_KEYCTX_CIPHER_KEY_SIZE_256;
|
||||
mk_size = CHCR_KEYCTX_MAC_KEY_SIZE_256;
|
||||
} else {
|
||||
crypto_tfm_set_flags((struct crypto_tfm *)aead,
|
||||
CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
aeadctx->enckey_len = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -3269,8 +3261,7 @@ static int chcr_aead_rfc4309_setkey(struct crypto_aead *aead, const u8 *key,
|
|||
int error;
|
||||
|
||||
if (keylen < 3) {
|
||||
crypto_tfm_set_flags((struct crypto_tfm *)aead,
|
||||
CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
aeadctx->enckey_len = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -3320,8 +3311,7 @@ static int chcr_gcm_setkey(struct crypto_aead *aead, const u8 *key,
|
|||
} else if (keylen == AES_KEYSIZE_256) {
|
||||
ck_size = CHCR_KEYCTX_CIPHER_KEY_SIZE_256;
|
||||
} else {
|
||||
crypto_tfm_set_flags((struct crypto_tfm *)aead,
|
||||
CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
pr_err("GCM: Invalid key length %d\n", keylen);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
|
|
|
@ -1058,6 +1058,7 @@ config GPIO_MADERA
|
|||
config GPIO_MAX77620
|
||||
tristate "GPIO support for PMIC MAX77620 and MAX20024"
|
||||
depends on MFD_MAX77620
|
||||
select GPIOLIB_IRQCHIP
|
||||
help
|
||||
GPIO driver for MAX77620 and MAX20024 PMIC from Maxim Semiconductor.
|
||||
MAX77620 PMIC has 8 pins that can be configured as GPIOs. The
|
||||
|
|
|
@ -620,6 +620,7 @@
|
|||
#define USB_VENDOR_ID_ITE 0x048d
|
||||
#define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386
|
||||
#define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350
|
||||
#define I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720 0x837a
|
||||
#define USB_DEVICE_ID_ITE_LENOVO_YOGA900 0x8396
|
||||
#define USB_DEVICE_ID_ITE8595 0x8595
|
||||
|
||||
|
@ -717,6 +718,7 @@
|
|||
#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064
|
||||
#define USB_DEVICE_ID_LG_MELFAS_MT 0x6007
|
||||
#define I2C_DEVICE_ID_LG_8001 0x8001
|
||||
#define I2C_DEVICE_ID_LG_7010 0x7010
|
||||
|
||||
#define USB_VENDOR_ID_LOGITECH 0x046d
|
||||
#define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e
|
||||
|
@ -1074,6 +1076,7 @@
|
|||
#define USB_DEVICE_ID_SYNAPTICS_LTS2 0x1d10
|
||||
#define USB_DEVICE_ID_SYNAPTICS_HD 0x0ac3
|
||||
#define USB_DEVICE_ID_SYNAPTICS_QUAD_HD 0x1ac3
|
||||
#define USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012 0x2968
|
||||
#define USB_DEVICE_ID_SYNAPTICS_TP_V103 0x5710
|
||||
|
||||
#define USB_VENDOR_ID_TEXAS_INSTRUMENTS 0x2047
|
||||
|
|
|
@ -43,6 +43,9 @@ static int ite_event(struct hid_device *hdev, struct hid_field *field,
|
|||
static const struct hid_device_id ite_devices[] = {
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) },
|
||||
/* ITE8595 USB kbd ctlr, with Synaptics touchpad connected to it. */
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS,
|
||||
USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(hid, ite_devices);
|
||||
|
|
|
@ -1007,7 +1007,7 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input,
|
|||
tool = MT_TOOL_DIAL;
|
||||
else if (unlikely(!confidence_state)) {
|
||||
tool = MT_TOOL_PALM;
|
||||
if (!active &&
|
||||
if (!active && mt &&
|
||||
input_mt_is_active(&mt->slots[slotnum])) {
|
||||
/*
|
||||
* The non-confidence was reported for
|
||||
|
@ -1972,6 +1972,9 @@ static const struct hid_device_id mt_devices[] = {
|
|||
{ .driver_data = MT_CLS_LG,
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LG,
|
||||
USB_DEVICE_ID_LG_MELFAS_MT) },
|
||||
{ .driver_data = MT_CLS_LG,
|
||||
HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC,
|
||||
USB_VENDOR_ID_LG, I2C_DEVICE_ID_LG_7010) },
|
||||
|
||||
/* MosArt panels */
|
||||
{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
|
||||
|
|
|
@ -175,6 +175,7 @@ static const struct hid_device_id hid_quirks[] = {
|
|||
{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET), HID_QUIRK_MULTI_INPUT },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
|
||||
{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE), HID_QUIRK_MULTI_INPUT },
|
||||
|
||||
{ 0 }
|
||||
};
|
||||
|
|
|
@ -768,8 +768,12 @@ static int steam_probe(struct hid_device *hdev,
|
|||
|
||||
if (steam->quirks & STEAM_QUIRK_WIRELESS) {
|
||||
hid_info(hdev, "Steam wireless receiver connected");
|
||||
/* If using a wireless adaptor ask for connection status */
|
||||
steam->connected = false;
|
||||
steam_request_conn_status(steam);
|
||||
} else {
|
||||
/* A wired connection is always present */
|
||||
steam->connected = true;
|
||||
ret = steam_register(steam);
|
||||
if (ret) {
|
||||
hid_err(hdev,
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
#define I2C_HID_QUIRK_DELAY_AFTER_SLEEP BIT(3)
|
||||
#define I2C_HID_QUIRK_BOGUS_IRQ BIT(4)
|
||||
#define I2C_HID_QUIRK_RESET_ON_RESUME BIT(5)
|
||||
#define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(6)
|
||||
|
||||
|
||||
/* flags */
|
||||
#define I2C_HID_STARTED 0
|
||||
|
@ -185,6 +187,8 @@ static const struct i2c_hid_quirks {
|
|||
I2C_HID_QUIRK_BOGUS_IRQ },
|
||||
{ USB_VENDOR_ID_ALPS_JP, HID_ANY_ID,
|
||||
I2C_HID_QUIRK_RESET_ON_RESUME },
|
||||
{ USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720,
|
||||
I2C_HID_QUIRK_BAD_INPUT_SIZE },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -516,9 +520,15 @@ static void i2c_hid_get_input(struct i2c_hid *ihid)
|
|||
}
|
||||
|
||||
if ((ret_size > size) || (ret_size < 2)) {
|
||||
dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n",
|
||||
__func__, size, ret_size);
|
||||
return;
|
||||
if (ihid->quirks & I2C_HID_QUIRK_BAD_INPUT_SIZE) {
|
||||
ihid->inbuf[0] = size & 0xff;
|
||||
ihid->inbuf[1] = size >> 8;
|
||||
ret_size = size;
|
||||
} else {
|
||||
dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n",
|
||||
__func__, size, ret_size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
i2c_hid_dbg(ihid, "input: %*ph\n", ret_size, ihid->inbuf);
|
||||
|
|
|
@ -141,7 +141,6 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = {
|
|||
[2] = LSM330DLC_GYRO_DEV_NAME,
|
||||
[3] = L3G4IS_GYRO_DEV_NAME,
|
||||
[4] = LSM330_GYRO_DEV_NAME,
|
||||
[5] = LSM9DS0_GYRO_DEV_NAME,
|
||||
},
|
||||
.ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
|
||||
.odr = {
|
||||
|
@ -211,6 +210,80 @@ static const struct st_sensor_settings st_gyro_sensors_settings[] = {
|
|||
.multi_read_bit = true,
|
||||
.bootime = 2,
|
||||
},
|
||||
{
|
||||
.wai = 0xd4,
|
||||
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
|
||||
.sensors_supported = {
|
||||
[0] = LSM9DS0_GYRO_DEV_NAME,
|
||||
},
|
||||
.ch = (struct iio_chan_spec *)st_gyro_16bit_channels,
|
||||
.odr = {
|
||||
.addr = 0x20,
|
||||
.mask = GENMASK(7, 6),
|
||||
.odr_avl = {
|
||||
{ .hz = 95, .value = 0x00, },
|
||||
{ .hz = 190, .value = 0x01, },
|
||||
{ .hz = 380, .value = 0x02, },
|
||||
{ .hz = 760, .value = 0x03, },
|
||||
},
|
||||
},
|
||||
.pw = {
|
||||
.addr = 0x20,
|
||||
.mask = BIT(3),
|
||||
.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
|
||||
.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
|
||||
},
|
||||
.enable_axis = {
|
||||
.addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
|
||||
.mask = ST_SENSORS_DEFAULT_AXIS_MASK,
|
||||
},
|
||||
.fs = {
|
||||
.addr = 0x23,
|
||||
.mask = GENMASK(5, 4),
|
||||
.fs_avl = {
|
||||
[0] = {
|
||||
.num = ST_GYRO_FS_AVL_245DPS,
|
||||
.value = 0x00,
|
||||
.gain = IIO_DEGREE_TO_RAD(8750),
|
||||
},
|
||||
[1] = {
|
||||
.num = ST_GYRO_FS_AVL_500DPS,
|
||||
.value = 0x01,
|
||||
.gain = IIO_DEGREE_TO_RAD(17500),
|
||||
},
|
||||
[2] = {
|
||||
.num = ST_GYRO_FS_AVL_2000DPS,
|
||||
.value = 0x02,
|
||||
.gain = IIO_DEGREE_TO_RAD(70000),
|
||||
},
|
||||
},
|
||||
},
|
||||
.bdu = {
|
||||
.addr = 0x23,
|
||||
.mask = BIT(7),
|
||||
},
|
||||
.drdy_irq = {
|
||||
.int2 = {
|
||||
.addr = 0x22,
|
||||
.mask = BIT(3),
|
||||
},
|
||||
/*
|
||||
* The sensor has IHL (active low) and open
|
||||
* drain settings, but only for INT1 and not
|
||||
* for the DRDY line on INT2.
|
||||
*/
|
||||
.stat_drdy = {
|
||||
.addr = ST_SENSORS_DEFAULT_STAT_ADDR,
|
||||
.mask = GENMASK(2, 0),
|
||||
},
|
||||
},
|
||||
.sim = {
|
||||
.addr = 0x23,
|
||||
.value = BIT(0),
|
||||
},
|
||||
.multi_read_bit = true,
|
||||
.bootime = 2,
|
||||
},
|
||||
{
|
||||
.wai = 0xd7,
|
||||
.wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
|
||||
|
|
|
@ -3709,7 +3709,20 @@ static void set_remap_table_entry(struct amd_iommu *iommu, u16 devid,
|
|||
iommu_flush_dte(iommu, devid);
|
||||
}
|
||||
|
||||
static struct irq_remap_table *alloc_irq_table(u16 devid)
|
||||
static int set_remap_table_entry_alias(struct pci_dev *pdev, u16 alias,
|
||||
void *data)
|
||||
{
|
||||
struct irq_remap_table *table = data;
|
||||
|
||||
irq_lookup_table[alias] = table;
|
||||
set_dte_irq_entry(alias, table);
|
||||
|
||||
iommu_flush_dte(amd_iommu_rlookup_table[alias], alias);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct irq_remap_table *alloc_irq_table(u16 devid, struct pci_dev *pdev)
|
||||
{
|
||||
struct irq_remap_table *table = NULL;
|
||||
struct irq_remap_table *new_table = NULL;
|
||||
|
@ -3755,7 +3768,12 @@ static struct irq_remap_table *alloc_irq_table(u16 devid)
|
|||
table = new_table;
|
||||
new_table = NULL;
|
||||
|
||||
set_remap_table_entry(iommu, devid, table);
|
||||
if (pdev)
|
||||
pci_for_each_dma_alias(pdev, set_remap_table_entry_alias,
|
||||
table);
|
||||
else
|
||||
set_remap_table_entry(iommu, devid, table);
|
||||
|
||||
if (devid != alias)
|
||||
set_remap_table_entry(iommu, alias, table);
|
||||
|
||||
|
@ -3772,7 +3790,8 @@ static struct irq_remap_table *alloc_irq_table(u16 devid)
|
|||
return table;
|
||||
}
|
||||
|
||||
static int alloc_irq_index(u16 devid, int count, bool align)
|
||||
static int alloc_irq_index(u16 devid, int count, bool align,
|
||||
struct pci_dev *pdev)
|
||||
{
|
||||
struct irq_remap_table *table;
|
||||
int index, c, alignment = 1;
|
||||
|
@ -3782,7 +3801,7 @@ static int alloc_irq_index(u16 devid, int count, bool align)
|
|||
if (!iommu)
|
||||
return -ENODEV;
|
||||
|
||||
table = alloc_irq_table(devid);
|
||||
table = alloc_irq_table(devid, pdev);
|
||||
if (!table)
|
||||
return -ENODEV;
|
||||
|
||||
|
@ -4215,7 +4234,7 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq,
|
|||
struct irq_remap_table *table;
|
||||
struct amd_iommu *iommu;
|
||||
|
||||
table = alloc_irq_table(devid);
|
||||
table = alloc_irq_table(devid, NULL);
|
||||
if (table) {
|
||||
if (!table->min_index) {
|
||||
/*
|
||||
|
@ -4232,11 +4251,15 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq,
|
|||
} else {
|
||||
index = -ENOMEM;
|
||||
}
|
||||
} else {
|
||||
} else if (info->type == X86_IRQ_ALLOC_TYPE_MSI ||
|
||||
info->type == X86_IRQ_ALLOC_TYPE_MSIX) {
|
||||
bool align = (info->type == X86_IRQ_ALLOC_TYPE_MSI);
|
||||
|
||||
index = alloc_irq_index(devid, nr_irqs, align);
|
||||
index = alloc_irq_index(devid, nr_irqs, align, info->msi_dev);
|
||||
} else {
|
||||
index = alloc_irq_index(devid, nr_irqs, false, NULL);
|
||||
}
|
||||
|
||||
if (index < 0) {
|
||||
pr_warn("Failed to allocate IRTE\n");
|
||||
ret = index;
|
||||
|
|
|
@ -141,8 +141,12 @@
|
|||
|
||||
#define MEI_DEV_ID_CMP_LP 0x02e0 /* Comet Point LP */
|
||||
#define MEI_DEV_ID_CMP_LP_3 0x02e4 /* Comet Point LP 3 (iTouch) */
|
||||
|
||||
#define MEI_DEV_ID_CMP_V 0xA3BA /* Comet Point Lake V */
|
||||
|
||||
#define MEI_DEV_ID_CMP_H 0x06e0 /* Comet Lake H */
|
||||
#define MEI_DEV_ID_CMP_H_3 0x06e4 /* Comet Lake H 3 (iTouch) */
|
||||
|
||||
#define MEI_DEV_ID_ICP_LP 0x34E0 /* Ice Lake Point LP */
|
||||
|
||||
#define MEI_DEV_ID_TGP_LP 0xA0E0 /* Tiger Lake Point LP */
|
||||
|
|
|
@ -108,6 +108,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
|
|||
{MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP, MEI_ME_PCH12_CFG)},
|
||||
{MEI_PCI_DEVICE(MEI_DEV_ID_CMP_LP_3, MEI_ME_PCH8_CFG)},
|
||||
{MEI_PCI_DEVICE(MEI_DEV_ID_CMP_V, MEI_ME_PCH12_CFG)},
|
||||
{MEI_PCI_DEVICE(MEI_DEV_ID_CMP_H, MEI_ME_PCH12_CFG)},
|
||||
{MEI_PCI_DEVICE(MEI_DEV_ID_CMP_H_3, MEI_ME_PCH8_CFG)},
|
||||
|
||||
{MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)},
|
||||
|
||||
|
|
|
@ -1519,8 +1519,10 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset)
|
|||
int ethaddr_bytes = ETH_ALEN;
|
||||
|
||||
memset(ppattern + offset, 0xff, magicsync);
|
||||
for (j = 0; j < magicsync; j++)
|
||||
set_bit(len++, (unsigned long *) pmask);
|
||||
for (j = 0; j < magicsync; j++) {
|
||||
pmask[len >> 3] |= BIT(len & 7);
|
||||
len++;
|
||||
}
|
||||
|
||||
for (j = 0; j < B44_MAX_PATTERNS; j++) {
|
||||
if ((B44_PATTERN_SIZE - len) >= ETH_ALEN)
|
||||
|
@ -1532,7 +1534,8 @@ static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset)
|
|||
for (k = 0; k< ethaddr_bytes; k++) {
|
||||
ppattern[offset + magicsync +
|
||||
(j * ETH_ALEN) + k] = macaddr[k];
|
||||
set_bit(len++, (unsigned long *) pmask);
|
||||
pmask[len >> 3] |= BIT(len & 7);
|
||||
len++;
|
||||
}
|
||||
}
|
||||
return len - 1;
|
||||
|
|
|
@ -711,7 +711,7 @@ static netdev_tx_t sdla_transmit(struct sk_buff *skb,
|
|||
|
||||
spin_lock_irqsave(&sdla_lock, flags);
|
||||
SDLA_WINDOW(dev, addr);
|
||||
pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK));
|
||||
pbuf = (void *)(dev->mem_start + (addr & SDLA_ADDR_MASK));
|
||||
__sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
|
||||
SDLA_WINDOW(dev, addr);
|
||||
pbuf->opp_flag = 1;
|
||||
|
|
|
@ -1216,7 +1216,7 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context)
|
|||
static int send_eject_command(struct usb_interface *interface)
|
||||
{
|
||||
struct usb_device *udev = interface_to_usbdev(interface);
|
||||
struct usb_host_interface *iface_desc = &interface->altsetting[0];
|
||||
struct usb_host_interface *iface_desc = interface->cur_altsetting;
|
||||
struct usb_endpoint_descriptor *endpoint;
|
||||
unsigned char *cmd;
|
||||
u8 bulk_out_ep;
|
||||
|
|
|
@ -1357,7 +1357,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
desc = &intf->altsetting[0].desc;
|
||||
desc = &intf->cur_altsetting->desc;
|
||||
if ((desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
|
||||
(desc->bInterfaceSubClass != 2) ||
|
||||
(desc->bInterfaceProtocol != 0xff)) {
|
||||
|
@ -1370,7 +1370,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
|
||||
num_of_eps = desc->bNumEndpoints;
|
||||
for (ep = 0; ep < num_of_eps; ep++) {
|
||||
endpoint = &intf->altsetting[0].endpoint[ep].desc;
|
||||
endpoint = &intf->cur_altsetting->endpoint[ep].desc;
|
||||
endpoint_num = usb_endpoint_num(endpoint);
|
||||
if (!usb_endpoint_xfer_bulk(endpoint))
|
||||
continue;
|
||||
|
|
|
@ -1611,9 +1611,9 @@ static int ezusb_probe(struct usb_interface *interface,
|
|||
/* set up the endpoint information */
|
||||
/* check out the endpoints */
|
||||
|
||||
iface_desc = &interface->altsetting[0].desc;
|
||||
iface_desc = &interface->cur_altsetting->desc;
|
||||
for (i = 0; i < iface_desc->bNumEndpoints; ++i) {
|
||||
ep = &interface->altsetting[0].endpoint[i].desc;
|
||||
ep = &interface->cur_altsetting->endpoint[i].desc;
|
||||
|
||||
if (usb_endpoint_is_bulk_in(ep)) {
|
||||
/* we found a bulk in endpoint */
|
||||
|
|
|
@ -5921,7 +5921,7 @@ static int rtl8xxxu_parse_usb(struct rtl8xxxu_priv *priv,
|
|||
u8 dir, xtype, num;
|
||||
int ret = 0;
|
||||
|
||||
host_interface = &interface->altsetting[0];
|
||||
host_interface = interface->cur_altsetting;
|
||||
interface_desc = &host_interface->desc;
|
||||
endpoints = interface_desc->bNumEndpoints;
|
||||
|
||||
|
|
|
@ -616,6 +616,7 @@ static int bl_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp, char *str)
|
|||
bl_start_cmd_timer(adapter, timeout);
|
||||
status = bl_write_cmd(adapter, cmd, exp_resp, ®out_val);
|
||||
if (status < 0) {
|
||||
bl_stop_cmd_timer(adapter);
|
||||
rsi_dbg(ERR_ZONE,
|
||||
"%s: Command %s (%0x) writing failed..\n",
|
||||
__func__, str, cmd);
|
||||
|
@ -731,10 +732,9 @@ static int ping_pong_write(struct rsi_hw *adapter, u8 cmd, u8 *addr, u32 size)
|
|||
}
|
||||
|
||||
status = bl_cmd(adapter, cmd_req, cmd_resp, str);
|
||||
if (status) {
|
||||
bl_stop_cmd_timer(adapter);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -822,10 +822,9 @@ static int auto_fw_upgrade(struct rsi_hw *adapter, u8 *flash_content,
|
|||
|
||||
status = bl_cmd(adapter, EOF_REACHED, FW_LOADING_SUCCESSFUL,
|
||||
"EOF_REACHED");
|
||||
if (status) {
|
||||
bl_stop_cmd_timer(adapter);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
|
||||
rsi_dbg(INFO_ZONE, "FW loading is done and FW is running..\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -846,6 +845,7 @@ static int rsi_load_firmware(struct rsi_hw *adapter)
|
|||
status = hif_ops->master_reg_read(adapter, SWBL_REGOUT,
|
||||
®out_val, 2);
|
||||
if (status < 0) {
|
||||
bl_stop_cmd_timer(adapter);
|
||||
rsi_dbg(ERR_ZONE,
|
||||
"%s: REGOUT read failed\n", __func__);
|
||||
return status;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <net/rsi_91x.h>
|
||||
#include "rsi_usb.h"
|
||||
#include "rsi_hal.h"
|
||||
|
@ -29,7 +30,7 @@ MODULE_PARM_DESC(dev_oper_mode,
|
|||
"9[Wi-Fi STA + BT LE], 13[Wi-Fi STA + BT classic + BT LE]\n"
|
||||
"6[AP + BT classic], 14[AP + BT classic + BT LE]");
|
||||
|
||||
static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num);
|
||||
static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num, gfp_t flags);
|
||||
|
||||
/**
|
||||
* rsi_usb_card_write() - This function writes to the USB Card.
|
||||
|
@ -117,7 +118,7 @@ static int rsi_find_bulk_in_and_out_endpoints(struct usb_interface *interface,
|
|||
__le16 buffer_size;
|
||||
int ii, bin_found = 0, bout_found = 0;
|
||||
|
||||
iface_desc = &(interface->altsetting[0]);
|
||||
iface_desc = interface->cur_altsetting;
|
||||
|
||||
for (ii = 0; ii < iface_desc->desc.bNumEndpoints; ++ii) {
|
||||
endpoint = &(iface_desc->endpoint[ii].desc);
|
||||
|
@ -283,7 +284,7 @@ static void rsi_rx_done_handler(struct urb *urb)
|
|||
status = 0;
|
||||
|
||||
out:
|
||||
if (rsi_rx_urb_submit(dev->priv, rx_cb->ep_num))
|
||||
if (rsi_rx_urb_submit(dev->priv, rx_cb->ep_num, GFP_ATOMIC))
|
||||
rsi_dbg(ERR_ZONE, "%s: Failed in urb submission", __func__);
|
||||
|
||||
if (status)
|
||||
|
@ -296,7 +297,7 @@ static void rsi_rx_done_handler(struct urb *urb)
|
|||
*
|
||||
* Return: 0 on success, a negative error code on failure.
|
||||
*/
|
||||
static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num)
|
||||
static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num, gfp_t mem_flags)
|
||||
{
|
||||
struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
|
||||
struct rx_usb_ctrl_block *rx_cb = &dev->rx_cb[ep_num - 1];
|
||||
|
@ -326,9 +327,11 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num)
|
|||
rsi_rx_done_handler,
|
||||
rx_cb);
|
||||
|
||||
status = usb_submit_urb(urb, GFP_KERNEL);
|
||||
if (status)
|
||||
status = usb_submit_urb(urb, mem_flags);
|
||||
if (status) {
|
||||
rsi_dbg(ERR_ZONE, "%s: Failed in urb submission\n", __func__);
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -781,12 +784,12 @@ static int rsi_probe(struct usb_interface *pfunction,
|
|||
rsi_dbg(INIT_ZONE, "%s: Device Init Done\n", __func__);
|
||||
}
|
||||
|
||||
status = rsi_rx_urb_submit(adapter, WLAN_EP);
|
||||
status = rsi_rx_urb_submit(adapter, WLAN_EP, GFP_KERNEL);
|
||||
if (status)
|
||||
goto err1;
|
||||
|
||||
if (adapter->priv->coex_mode > 1) {
|
||||
status = rsi_rx_urb_submit(adapter, BT_EP);
|
||||
status = rsi_rx_urb_submit(adapter, BT_EP, GFP_KERNEL);
|
||||
if (status)
|
||||
goto err1;
|
||||
}
|
||||
|
|
|
@ -1275,7 +1275,7 @@ static void print_id(struct usb_device *udev)
|
|||
static int eject_installer(struct usb_interface *intf)
|
||||
{
|
||||
struct usb_device *udev = interface_to_usbdev(intf);
|
||||
struct usb_host_interface *iface_desc = &intf->altsetting[0];
|
||||
struct usb_host_interface *iface_desc = intf->cur_altsetting;
|
||||
struct usb_endpoint_descriptor *endpoint;
|
||||
unsigned char *cmd;
|
||||
u8 bulk_out_ep;
|
||||
|
|
|
@ -3986,6 +3986,40 @@ static void quirk_mic_x200_dma_alias(struct pci_dev *pdev)
|
|||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2260, quirk_mic_x200_dma_alias);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2264, quirk_mic_x200_dma_alias);
|
||||
|
||||
/*
|
||||
* Intel Visual Compute Accelerator (VCA) is a family of PCIe add-in devices
|
||||
* exposing computational units via Non Transparent Bridges (NTB, PEX 87xx).
|
||||
*
|
||||
* Similarly to MIC x200, we need to add DMA aliases to allow buffer access
|
||||
* when IOMMU is enabled. These aliases allow computational unit access to
|
||||
* host memory. These aliases mark the whole VCA device as one IOMMU
|
||||
* group.
|
||||
*
|
||||
* All possible slot numbers (0x20) are used, since we are unable to tell
|
||||
* what slot is used on other side. This quirk is intended for both host
|
||||
* and computational unit sides. The VCA devices have up to five functions
|
||||
* (four for DMA channels and one additional).
|
||||
*/
|
||||
static void quirk_pex_vca_alias(struct pci_dev *pdev)
|
||||
{
|
||||
const unsigned int num_pci_slots = 0x20;
|
||||
unsigned int slot;
|
||||
|
||||
for (slot = 0; slot < num_pci_slots; slot++) {
|
||||
pci_add_dma_alias(pdev, PCI_DEVFN(slot, 0x0));
|
||||
pci_add_dma_alias(pdev, PCI_DEVFN(slot, 0x1));
|
||||
pci_add_dma_alias(pdev, PCI_DEVFN(slot, 0x2));
|
||||
pci_add_dma_alias(pdev, PCI_DEVFN(slot, 0x3));
|
||||
pci_add_dma_alias(pdev, PCI_DEVFN(slot, 0x4));
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2954, quirk_pex_vca_alias);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2955, quirk_pex_vca_alias);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2956, quirk_pex_vca_alias);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2958, quirk_pex_vca_alias);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2959, quirk_pex_vca_alias);
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x295A, quirk_pex_vca_alias);
|
||||
|
||||
/*
|
||||
* The IOMMU and interrupt controller on Broadcom Vulcan/Cavium ThunderX2 are
|
||||
* associated not at the root bus, but at a bridge below. This quirk avoids
|
||||
|
|
|
@ -115,7 +115,7 @@ struct cpcap_usb_ints_state {
|
|||
enum cpcap_gpio_mode {
|
||||
CPCAP_DM_DP,
|
||||
CPCAP_MDM_RX_TX,
|
||||
CPCAP_UNKNOWN,
|
||||
CPCAP_UNKNOWN_DISABLED, /* Seems to disable USB lines */
|
||||
CPCAP_OTG_DM_DP,
|
||||
};
|
||||
|
||||
|
@ -379,7 +379,8 @@ static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata)
|
|||
{
|
||||
int error;
|
||||
|
||||
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
|
||||
/* Disable lines to prevent glitches from waking up mdm6600 */
|
||||
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
|
@ -406,6 +407,11 @@ static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata)
|
|||
if (error)
|
||||
goto out_err;
|
||||
|
||||
/* Enable UART mode */
|
||||
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
|
@ -418,7 +424,8 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
|
|||
{
|
||||
int error;
|
||||
|
||||
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP);
|
||||
/* Disable lines to prevent glitches from waking up mdm6600 */
|
||||
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_UNKNOWN_DISABLED);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
@ -458,6 +465,11 @@ static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
|
|||
if (error)
|
||||
goto out_err;
|
||||
|
||||
/* Enable USB mode */
|
||||
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
/* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
|
||||
#define CLAMP_EN BIT(0) /* enables i/o clamp_n */
|
||||
|
||||
#define PHY_INIT_COMPLETE_TIMEOUT 1000
|
||||
#define PHY_INIT_COMPLETE_TIMEOUT 10000
|
||||
#define POWER_DOWN_DELAY_US_MIN 10
|
||||
#define POWER_DOWN_DELAY_US_MAX 11
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
struct quirk_entry {
|
||||
bool touchpad_led;
|
||||
bool kbd_led_not_present;
|
||||
bool kbd_led_levels_off_1;
|
||||
bool kbd_missing_ac_tag;
|
||||
|
||||
|
@ -77,6 +78,10 @@ static struct quirk_entry quirk_dell_latitude_e6410 = {
|
|||
.kbd_led_levels_off_1 = true,
|
||||
};
|
||||
|
||||
static struct quirk_entry quirk_dell_inspiron_1012 = {
|
||||
.kbd_led_not_present = true,
|
||||
};
|
||||
|
||||
static struct platform_driver platform_driver = {
|
||||
.driver = {
|
||||
.name = "dell-laptop",
|
||||
|
@ -314,6 +319,24 @@ static const struct dmi_system_id dell_quirks[] __initconst = {
|
|||
},
|
||||
.driver_data = &quirk_dell_latitude_e6410,
|
||||
},
|
||||
{
|
||||
.callback = dmi_matched,
|
||||
.ident = "Dell Inspiron 1012",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"),
|
||||
},
|
||||
.driver_data = &quirk_dell_inspiron_1012,
|
||||
},
|
||||
{
|
||||
.callback = dmi_matched,
|
||||
.ident = "Dell Inspiron 1018",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1018"),
|
||||
},
|
||||
.driver_data = &quirk_dell_inspiron_1012,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -1497,6 +1520,9 @@ static void kbd_init(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
if (quirks && quirks->kbd_led_not_present)
|
||||
return;
|
||||
|
||||
ret = kbd_init_info();
|
||||
kbd_init_tokens();
|
||||
|
||||
|
|
|
@ -179,9 +179,11 @@ static inline u32 rx_max(struct dw_spi *dws)
|
|||
|
||||
static void dw_writer(struct dw_spi *dws)
|
||||
{
|
||||
u32 max = tx_max(dws);
|
||||
u32 max;
|
||||
u16 txw = 0;
|
||||
|
||||
spin_lock(&dws->buf_lock);
|
||||
max = tx_max(dws);
|
||||
while (max--) {
|
||||
/* Set the tx word if the transfer's original "tx" is not null */
|
||||
if (dws->tx_end - dws->len) {
|
||||
|
@ -193,13 +195,16 @@ static void dw_writer(struct dw_spi *dws)
|
|||
dw_write_io_reg(dws, DW_SPI_DR, txw);
|
||||
dws->tx += dws->n_bytes;
|
||||
}
|
||||
spin_unlock(&dws->buf_lock);
|
||||
}
|
||||
|
||||
static void dw_reader(struct dw_spi *dws)
|
||||
{
|
||||
u32 max = rx_max(dws);
|
||||
u32 max;
|
||||
u16 rxw;
|
||||
|
||||
spin_lock(&dws->buf_lock);
|
||||
max = rx_max(dws);
|
||||
while (max--) {
|
||||
rxw = dw_read_io_reg(dws, DW_SPI_DR);
|
||||
/* Care rx only if the transfer's original "rx" is not null */
|
||||
|
@ -211,6 +216,7 @@ static void dw_reader(struct dw_spi *dws)
|
|||
}
|
||||
dws->rx += dws->n_bytes;
|
||||
}
|
||||
spin_unlock(&dws->buf_lock);
|
||||
}
|
||||
|
||||
static void int_error_stop(struct dw_spi *dws, const char *msg)
|
||||
|
@ -283,18 +289,20 @@ static int dw_spi_transfer_one(struct spi_controller *master,
|
|||
{
|
||||
struct dw_spi *dws = spi_controller_get_devdata(master);
|
||||
struct chip_data *chip = spi_get_ctldata(spi);
|
||||
unsigned long flags;
|
||||
u8 imask = 0;
|
||||
u16 txlevel = 0;
|
||||
u32 cr0;
|
||||
int ret;
|
||||
|
||||
dws->dma_mapped = 0;
|
||||
|
||||
spin_lock_irqsave(&dws->buf_lock, flags);
|
||||
dws->tx = (void *)transfer->tx_buf;
|
||||
dws->tx_end = dws->tx + transfer->len;
|
||||
dws->rx = transfer->rx_buf;
|
||||
dws->rx_end = dws->rx + transfer->len;
|
||||
dws->len = transfer->len;
|
||||
spin_unlock_irqrestore(&dws->buf_lock, flags);
|
||||
|
||||
spi_enable_chip(dws, 0);
|
||||
|
||||
|
@ -485,6 +493,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
|
|||
dws->type = SSI_MOTO_SPI;
|
||||
dws->dma_inited = 0;
|
||||
dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR);
|
||||
spin_lock_init(&dws->buf_lock);
|
||||
|
||||
spi_controller_set_devdata(master, dws);
|
||||
|
||||
|
|
|
@ -118,6 +118,7 @@ struct dw_spi {
|
|||
size_t len;
|
||||
void *tx;
|
||||
void *tx_end;
|
||||
spinlock_t buf_lock;
|
||||
void *rx;
|
||||
void *rx_end;
|
||||
int dma_mapped;
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
#define RATE_AUTO 12
|
||||
|
||||
#define MAX_RATE 12
|
||||
#define VNT_B_RATES (BIT(RATE_1M) | BIT(RATE_2M) |\
|
||||
BIT(RATE_5M) | BIT(RATE_11M))
|
||||
|
||||
/*
|
||||
* device specific
|
||||
|
|
|
@ -97,9 +97,11 @@ static int vnt_int_report_rate(struct vnt_private *priv, u8 pkt_no, u8 tsr)
|
|||
|
||||
info->status.rates[0].count = tx_retry;
|
||||
|
||||
if (!(tsr & (TSR_TMO | TSR_RETRYTMO))) {
|
||||
if (!(tsr & TSR_TMO)) {
|
||||
info->status.rates[0].idx = idx;
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
|
||||
if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
}
|
||||
|
||||
ieee80211_tx_status_irqsafe(priv->hw, context->skb);
|
||||
|
|
|
@ -978,6 +978,7 @@ vt6656_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
|||
ieee80211_hw_set(priv->hw, RX_INCLUDES_FCS);
|
||||
ieee80211_hw_set(priv->hw, REPORTS_TX_ACK_STATUS);
|
||||
ieee80211_hw_set(priv->hw, SUPPORTS_PS);
|
||||
ieee80211_hw_set(priv->hw, PS_NULLFUNC_STACK);
|
||||
|
||||
priv->hw->max_signal = 100;
|
||||
|
||||
|
|
|
@ -278,11 +278,9 @@ static u16 vnt_rxtx_datahead_g(struct vnt_usb_send_context *tx_context,
|
|||
PK_TYPE_11B, &buf->b);
|
||||
|
||||
/* Get Duration and TimeStamp */
|
||||
if (ieee80211_is_pspoll(hdr->frame_control)) {
|
||||
__le16 dur = cpu_to_le16(priv->current_aid | BIT(14) | BIT(15));
|
||||
|
||||
buf->duration_a = dur;
|
||||
buf->duration_b = dur;
|
||||
if (ieee80211_is_nullfunc(hdr->frame_control)) {
|
||||
buf->duration_a = hdr->duration_id;
|
||||
buf->duration_b = hdr->duration_id;
|
||||
} else {
|
||||
buf->duration_a = vnt_get_duration_le(priv,
|
||||
tx_context->pkt_type, need_ack);
|
||||
|
@ -371,10 +369,8 @@ static u16 vnt_rxtx_datahead_ab(struct vnt_usb_send_context *tx_context,
|
|||
tx_context->pkt_type, &buf->ab);
|
||||
|
||||
/* Get Duration and TimeStampOff */
|
||||
if (ieee80211_is_pspoll(hdr->frame_control)) {
|
||||
__le16 dur = cpu_to_le16(priv->current_aid | BIT(14) | BIT(15));
|
||||
|
||||
buf->duration = dur;
|
||||
if (ieee80211_is_nullfunc(hdr->frame_control)) {
|
||||
buf->duration = hdr->duration_id;
|
||||
} else {
|
||||
buf->duration = vnt_get_duration_le(priv, tx_context->pkt_type,
|
||||
need_ack);
|
||||
|
@ -815,10 +811,14 @@ int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
|
|||
if (info->band == NL80211_BAND_5GHZ) {
|
||||
pkt_type = PK_TYPE_11A;
|
||||
} else {
|
||||
if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
|
||||
pkt_type = PK_TYPE_11GB;
|
||||
else
|
||||
pkt_type = PK_TYPE_11GA;
|
||||
if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
|
||||
if (priv->basic_rates & VNT_B_RATES)
|
||||
pkt_type = PK_TYPE_11GB;
|
||||
else
|
||||
pkt_type = PK_TYPE_11GA;
|
||||
} else {
|
||||
pkt_type = PK_TYPE_11A;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pkt_type = PK_TYPE_11B;
|
||||
|
|
|
@ -959,7 +959,7 @@ int prism2mgmt_flashdl_state(struct wlandevice *wlandev, void *msgp)
|
|||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------
|
||||
|
|
|
@ -115,7 +115,7 @@ static int bcm2835aux_serial_remove(struct platform_device *pdev)
|
|||
{
|
||||
struct bcm2835aux_data *data = platform_get_drvdata(pdev);
|
||||
|
||||
serial8250_unregister_port(data->uart.port.line);
|
||||
serial8250_unregister_port(data->line);
|
||||
clk_disable_unprepare(data->clk);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1199,6 +1199,9 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
|
|||
/* do nothing */
|
||||
break;
|
||||
}
|
||||
|
||||
/* de-assert DRVVBUS for HOST and OTG mode */
|
||||
dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_DEVICE);
|
||||
}
|
||||
|
||||
static void dwc3_get_properties(struct dwc3 *dwc)
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#define PCI_DEVICE_ID_INTEL_GLK 0x31aa
|
||||
#define PCI_DEVICE_ID_INTEL_CNPLP 0x9dee
|
||||
#define PCI_DEVICE_ID_INTEL_CNPH 0xa36e
|
||||
#define PCI_DEVICE_ID_INTEL_CNPV 0xa3b0
|
||||
#define PCI_DEVICE_ID_INTEL_ICLLP 0x34ee
|
||||
|
||||
#define PCI_INTEL_BXT_DSM_GUID "732b85d5-b7a7-4a1b-9ba0-4bbd00ffd511"
|
||||
|
@ -340,6 +341,9 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
|
|||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CNPH),
|
||||
(kernel_ulong_t) &dwc3_pci_intel_properties, },
|
||||
|
||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_CNPV),
|
||||
(kernel_ulong_t) &dwc3_pci_intel_properties, },
|
||||
|
||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_ICLLP),
|
||||
(kernel_ulong_t) &dwc3_pci_intel_properties, },
|
||||
|
||||
|
|
|
@ -45,9 +45,10 @@ static int buffer_size;
|
|||
static int xbof = -1;
|
||||
|
||||
static int ir_startup (struct usb_serial *serial);
|
||||
static int ir_open(struct tty_struct *tty, struct usb_serial_port *port);
|
||||
static int ir_prepare_write_buffer(struct usb_serial_port *port,
|
||||
void *dest, size_t size);
|
||||
static int ir_write(struct tty_struct *tty, struct usb_serial_port *port,
|
||||
const unsigned char *buf, int count);
|
||||
static int ir_write_room(struct tty_struct *tty);
|
||||
static void ir_write_bulk_callback(struct urb *urb);
|
||||
static void ir_process_read_urb(struct urb *urb);
|
||||
static void ir_set_termios(struct tty_struct *tty,
|
||||
struct usb_serial_port *port, struct ktermios *old_termios);
|
||||
|
@ -77,8 +78,9 @@ static struct usb_serial_driver ir_device = {
|
|||
.num_ports = 1,
|
||||
.set_termios = ir_set_termios,
|
||||
.attach = ir_startup,
|
||||
.open = ir_open,
|
||||
.prepare_write_buffer = ir_prepare_write_buffer,
|
||||
.write = ir_write,
|
||||
.write_room = ir_write_room,
|
||||
.write_bulk_callback = ir_write_bulk_callback,
|
||||
.process_read_urb = ir_process_read_urb,
|
||||
};
|
||||
|
||||
|
@ -195,6 +197,9 @@ static int ir_startup(struct usb_serial *serial)
|
|||
struct usb_irda_cs_descriptor *irda_desc;
|
||||
int rates;
|
||||
|
||||
if (serial->num_bulk_in < 1 || serial->num_bulk_out < 1)
|
||||
return -ENODEV;
|
||||
|
||||
irda_desc = irda_usb_find_class_desc(serial, 0);
|
||||
if (!irda_desc) {
|
||||
dev_err(&serial->dev->dev,
|
||||
|
@ -251,35 +256,102 @@ static int ir_startup(struct usb_serial *serial)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ir_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
static int ir_write(struct tty_struct *tty, struct usb_serial_port *port,
|
||||
const unsigned char *buf, int count)
|
||||
{
|
||||
int i;
|
||||
struct urb *urb = NULL;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i)
|
||||
port->write_urbs[i]->transfer_flags = URB_ZERO_PACKET;
|
||||
if (port->bulk_out_size == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Start reading from the device */
|
||||
return usb_serial_generic_open(tty, port);
|
||||
}
|
||||
if (count == 0)
|
||||
return 0;
|
||||
|
||||
static int ir_prepare_write_buffer(struct usb_serial_port *port,
|
||||
void *dest, size_t size)
|
||||
{
|
||||
unsigned char *buf = dest;
|
||||
int count;
|
||||
count = min(count, port->bulk_out_size - 1);
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
if (__test_and_clear_bit(0, &port->write_urbs_free)) {
|
||||
urb = port->write_urbs[0];
|
||||
port->tx_bytes += count;
|
||||
}
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
|
||||
if (!urb)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The first byte of the packet we send to the device contains an
|
||||
* inbound header which indicates an additional number of BOFs and
|
||||
* outbound header which indicates an additional number of BOFs and
|
||||
* a baud rate change.
|
||||
*
|
||||
* See section 5.4.2.2 of the USB IrDA spec.
|
||||
*/
|
||||
*buf = ir_xbof | ir_baud;
|
||||
*(u8 *)urb->transfer_buffer = ir_xbof | ir_baud;
|
||||
|
||||
count = kfifo_out_locked(&port->write_fifo, buf + 1, size - 1,
|
||||
&port->lock);
|
||||
return count + 1;
|
||||
memcpy(urb->transfer_buffer + 1, buf, count);
|
||||
|
||||
urb->transfer_buffer_length = count + 1;
|
||||
urb->transfer_flags = URB_ZERO_PACKET;
|
||||
|
||||
ret = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (ret) {
|
||||
dev_err(&port->dev, "failed to submit write urb: %d\n", ret);
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
__set_bit(0, &port->write_urbs_free);
|
||||
port->tx_bytes -= count;
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void ir_write_bulk_callback(struct urb *urb)
|
||||
{
|
||||
struct usb_serial_port *port = urb->context;
|
||||
int status = urb->status;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&port->lock, flags);
|
||||
__set_bit(0, &port->write_urbs_free);
|
||||
port->tx_bytes -= urb->transfer_buffer_length - 1;
|
||||
spin_unlock_irqrestore(&port->lock, flags);
|
||||
|
||||
switch (status) {
|
||||
case 0:
|
||||
break;
|
||||
case -ENOENT:
|
||||
case -ECONNRESET:
|
||||
case -ESHUTDOWN:
|
||||
dev_dbg(&port->dev, "write urb stopped: %d\n", status);
|
||||
return;
|
||||
case -EPIPE:
|
||||
dev_err(&port->dev, "write urb stopped: %d\n", status);
|
||||
return;
|
||||
default:
|
||||
dev_err(&port->dev, "nonzero write-urb status: %d\n", status);
|
||||
break;
|
||||
}
|
||||
|
||||
usb_serial_port_softint(port);
|
||||
}
|
||||
|
||||
static int ir_write_room(struct tty_struct *tty)
|
||||
{
|
||||
struct usb_serial_port *port = tty->driver_data;
|
||||
int count = 0;
|
||||
|
||||
if (port->bulk_out_size == 0)
|
||||
return 0;
|
||||
|
||||
if (test_bit(0, &port->write_urbs_free))
|
||||
count = port->bulk_out_size - 1;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void ir_process_read_urb(struct urb *urb)
|
||||
|
@ -332,34 +404,34 @@ static void ir_set_termios(struct tty_struct *tty,
|
|||
|
||||
switch (baud) {
|
||||
case 2400:
|
||||
ir_baud = USB_IRDA_BR_2400;
|
||||
ir_baud = USB_IRDA_LS_2400;
|
||||
break;
|
||||
case 9600:
|
||||
ir_baud = USB_IRDA_BR_9600;
|
||||
ir_baud = USB_IRDA_LS_9600;
|
||||
break;
|
||||
case 19200:
|
||||
ir_baud = USB_IRDA_BR_19200;
|
||||
ir_baud = USB_IRDA_LS_19200;
|
||||
break;
|
||||
case 38400:
|
||||
ir_baud = USB_IRDA_BR_38400;
|
||||
ir_baud = USB_IRDA_LS_38400;
|
||||
break;
|
||||
case 57600:
|
||||
ir_baud = USB_IRDA_BR_57600;
|
||||
ir_baud = USB_IRDA_LS_57600;
|
||||
break;
|
||||
case 115200:
|
||||
ir_baud = USB_IRDA_BR_115200;
|
||||
ir_baud = USB_IRDA_LS_115200;
|
||||
break;
|
||||
case 576000:
|
||||
ir_baud = USB_IRDA_BR_576000;
|
||||
ir_baud = USB_IRDA_LS_576000;
|
||||
break;
|
||||
case 1152000:
|
||||
ir_baud = USB_IRDA_BR_1152000;
|
||||
ir_baud = USB_IRDA_LS_1152000;
|
||||
break;
|
||||
case 4000000:
|
||||
ir_baud = USB_IRDA_BR_4000000;
|
||||
ir_baud = USB_IRDA_LS_4000000;
|
||||
break;
|
||||
default:
|
||||
ir_baud = USB_IRDA_BR_9600;
|
||||
ir_baud = USB_IRDA_LS_9600;
|
||||
baud = 9600;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,12 +87,15 @@ UNUSUAL_DEV(0x2537, 0x1068, 0x0000, 0x9999,
|
|||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_IGNORE_UAS),
|
||||
|
||||
/* Reported-by: Takeo Nakayama <javhera@gmx.com> */
|
||||
/*
|
||||
* Initially Reported-by: Takeo Nakayama <javhera@gmx.com>
|
||||
* UAS Ignore Reported by Steven Ellis <sellis@redhat.com>
|
||||
*/
|
||||
UNUSUAL_DEV(0x357d, 0x7788, 0x0000, 0x9999,
|
||||
"JMicron",
|
||||
"JMS566",
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
US_FL_NO_REPORT_OPCODES),
|
||||
US_FL_NO_REPORT_OPCODES | US_FL_IGNORE_UAS),
|
||||
|
||||
/* Reported-by: Hans de Goede <hdegoede@redhat.com> */
|
||||
UNUSUAL_DEV(0x4971, 0x1012, 0x0000, 0x9999,
|
||||
|
|
|
@ -594,6 +594,7 @@ config MAX63XX_WATCHDOG
|
|||
config MAX77620_WATCHDOG
|
||||
tristate "Maxim Max77620 Watchdog Timer"
|
||||
depends on MFD_MAX77620 || COMPILE_TEST
|
||||
select WATCHDOG_CORE
|
||||
help
|
||||
This is the driver for the Max77620 watchdog timer.
|
||||
Say 'Y' here to enable the watchdog timer support for
|
||||
|
|
|
@ -193,6 +193,7 @@ static struct platform_driver rn5t618_wdt_driver = {
|
|||
|
||||
module_platform_driver(rn5t618_wdt_driver);
|
||||
|
||||
MODULE_ALIAS("platform:rn5t618-wdt");
|
||||
MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
|
||||
MODULE_DESCRIPTION("RN5T618 watchdog driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -750,7 +750,7 @@ __smb2_handle_cancelled_close(struct cifs_tcon *tcon, __u64 persistent_fid,
|
|||
{
|
||||
struct close_cancelled_open *cancelled;
|
||||
|
||||
cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL);
|
||||
cancelled = kzalloc(sizeof(*cancelled), GFP_ATOMIC);
|
||||
if (!cancelled)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
@ -296,6 +296,9 @@ struct omap_sr_data {
|
|||
struct voltagedomain *voltdm;
|
||||
};
|
||||
|
||||
|
||||
extern struct omap_sr_data omap_sr_pdata[OMAP_SR_NR];
|
||||
|
||||
#ifdef CONFIG_POWER_AVS_OMAP
|
||||
|
||||
/* Smartreflex module enable/disable interface */
|
||||
|
|
|
@ -119,11 +119,22 @@ struct usb_irda_cs_descriptor {
|
|||
* 6 - 115200 bps
|
||||
* 7 - 576000 bps
|
||||
* 8 - 1.152 Mbps
|
||||
* 9 - 5 mbps
|
||||
* 9 - 4 Mbps
|
||||
* 10..15 - Reserved
|
||||
*/
|
||||
#define USB_IRDA_STATUS_LINK_SPEED 0x0f
|
||||
|
||||
#define USB_IRDA_LS_NO_CHANGE 0
|
||||
#define USB_IRDA_LS_2400 1
|
||||
#define USB_IRDA_LS_9600 2
|
||||
#define USB_IRDA_LS_19200 3
|
||||
#define USB_IRDA_LS_38400 4
|
||||
#define USB_IRDA_LS_57600 5
|
||||
#define USB_IRDA_LS_115200 6
|
||||
#define USB_IRDA_LS_576000 7
|
||||
#define USB_IRDA_LS_1152000 8
|
||||
#define USB_IRDA_LS_4000000 9
|
||||
|
||||
/* The following is a 4-bit value used only for
|
||||
* outbound header:
|
||||
*
|
||||
|
|
|
@ -206,31 +206,38 @@ __cls_set_class(unsigned long *clp, unsigned long cl)
|
|||
return xchg(clp, cl);
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
cls_set_class(struct Qdisc *q, unsigned long *clp, unsigned long cl)
|
||||
static inline void
|
||||
__tcf_bind_filter(struct Qdisc *q, struct tcf_result *r, unsigned long base)
|
||||
{
|
||||
unsigned long old_cl;
|
||||
unsigned long cl;
|
||||
|
||||
sch_tree_lock(q);
|
||||
old_cl = __cls_set_class(clp, cl);
|
||||
sch_tree_unlock(q);
|
||||
return old_cl;
|
||||
cl = q->ops->cl_ops->bind_tcf(q, base, r->classid);
|
||||
cl = __cls_set_class(&r->class, cl);
|
||||
if (cl)
|
||||
q->ops->cl_ops->unbind_tcf(q, cl);
|
||||
}
|
||||
|
||||
static inline void
|
||||
tcf_bind_filter(struct tcf_proto *tp, struct tcf_result *r, unsigned long base)
|
||||
{
|
||||
struct Qdisc *q = tp->chain->block->q;
|
||||
unsigned long cl;
|
||||
|
||||
/* Check q as it is not set for shared blocks. In that case,
|
||||
* setting class is not supported.
|
||||
*/
|
||||
if (!q)
|
||||
return;
|
||||
cl = q->ops->cl_ops->bind_tcf(q, base, r->classid);
|
||||
cl = cls_set_class(q, &r->class, cl);
|
||||
if (cl)
|
||||
sch_tree_lock(q);
|
||||
__tcf_bind_filter(q, r, base);
|
||||
sch_tree_unlock(q);
|
||||
}
|
||||
|
||||
static inline void
|
||||
__tcf_unbind_filter(struct Qdisc *q, struct tcf_result *r)
|
||||
{
|
||||
unsigned long cl;
|
||||
|
||||
if ((cl = __cls_set_class(&r->class, 0)) != 0)
|
||||
q->ops->cl_ops->unbind_tcf(q, cl);
|
||||
}
|
||||
|
||||
|
@ -238,12 +245,10 @@ static inline void
|
|||
tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r)
|
||||
{
|
||||
struct Qdisc *q = tp->chain->block->q;
|
||||
unsigned long cl;
|
||||
|
||||
if (!q)
|
||||
return;
|
||||
if ((cl = __cls_set_class(&r->class, 0)) != 0)
|
||||
q->ops->cl_ops->unbind_tcf(q, cl);
|
||||
__tcf_unbind_filter(q, r);
|
||||
}
|
||||
|
||||
struct tcf_exts {
|
||||
|
|
|
@ -273,7 +273,8 @@ struct tcf_proto_ops {
|
|||
int (*reoffload)(struct tcf_proto *tp, bool add,
|
||||
tc_setup_cb_t *cb, void *cb_priv,
|
||||
struct netlink_ext_ack *extack);
|
||||
void (*bind_class)(void *, u32, unsigned long);
|
||||
void (*bind_class)(void *, u32, unsigned long,
|
||||
void *, unsigned long);
|
||||
void * (*tmplt_create)(struct net *net,
|
||||
struct tcf_chain *chain,
|
||||
struct nlattr **tca,
|
||||
|
|
|
@ -285,66 +285,72 @@ static inline struct cfs_rq *group_cfs_rq(struct sched_entity *grp)
|
|||
return grp->my_q;
|
||||
}
|
||||
|
||||
static inline void list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
|
||||
static inline bool list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
|
||||
{
|
||||
if (!cfs_rq->on_list) {
|
||||
struct rq *rq = rq_of(cfs_rq);
|
||||
int cpu = cpu_of(rq);
|
||||
/*
|
||||
* Ensure we either appear before our parent (if already
|
||||
* enqueued) or force our parent to appear after us when it is
|
||||
* enqueued. The fact that we always enqueue bottom-up
|
||||
* reduces this to two cases and a special case for the root
|
||||
* cfs_rq. Furthermore, it also means that we will always reset
|
||||
* tmp_alone_branch either when the branch is connected
|
||||
* to a tree or when we reach the beg of the tree
|
||||
*/
|
||||
if (cfs_rq->tg->parent &&
|
||||
cfs_rq->tg->parent->cfs_rq[cpu]->on_list) {
|
||||
/*
|
||||
* If parent is already on the list, we add the child
|
||||
* just before. Thanks to circular linked property of
|
||||
* the list, this means to put the child at the tail
|
||||
* of the list that starts by parent.
|
||||
*/
|
||||
list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list,
|
||||
&(cfs_rq->tg->parent->cfs_rq[cpu]->leaf_cfs_rq_list));
|
||||
/*
|
||||
* The branch is now connected to its tree so we can
|
||||
* reset tmp_alone_branch to the beginning of the
|
||||
* list.
|
||||
*/
|
||||
rq->tmp_alone_branch = &rq->leaf_cfs_rq_list;
|
||||
} else if (!cfs_rq->tg->parent) {
|
||||
/*
|
||||
* cfs rq without parent should be put
|
||||
* at the tail of the list.
|
||||
*/
|
||||
list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list,
|
||||
&rq->leaf_cfs_rq_list);
|
||||
/*
|
||||
* We have reach the beg of a tree so we can reset
|
||||
* tmp_alone_branch to the beginning of the list.
|
||||
*/
|
||||
rq->tmp_alone_branch = &rq->leaf_cfs_rq_list;
|
||||
} else {
|
||||
/*
|
||||
* The parent has not already been added so we want to
|
||||
* make sure that it will be put after us.
|
||||
* tmp_alone_branch points to the beg of the branch
|
||||
* where we will add parent.
|
||||
*/
|
||||
list_add_rcu(&cfs_rq->leaf_cfs_rq_list,
|
||||
rq->tmp_alone_branch);
|
||||
/*
|
||||
* update tmp_alone_branch to points to the new beg
|
||||
* of the branch
|
||||
*/
|
||||
rq->tmp_alone_branch = &cfs_rq->leaf_cfs_rq_list;
|
||||
}
|
||||
struct rq *rq = rq_of(cfs_rq);
|
||||
int cpu = cpu_of(rq);
|
||||
|
||||
cfs_rq->on_list = 1;
|
||||
if (cfs_rq->on_list)
|
||||
return rq->tmp_alone_branch == &rq->leaf_cfs_rq_list;
|
||||
|
||||
cfs_rq->on_list = 1;
|
||||
|
||||
/*
|
||||
* Ensure we either appear before our parent (if already
|
||||
* enqueued) or force our parent to appear after us when it is
|
||||
* enqueued. The fact that we always enqueue bottom-up
|
||||
* reduces this to two cases and a special case for the root
|
||||
* cfs_rq. Furthermore, it also means that we will always reset
|
||||
* tmp_alone_branch either when the branch is connected
|
||||
* to a tree or when we reach the top of the tree
|
||||
*/
|
||||
if (cfs_rq->tg->parent &&
|
||||
cfs_rq->tg->parent->cfs_rq[cpu]->on_list) {
|
||||
/*
|
||||
* If parent is already on the list, we add the child
|
||||
* just before. Thanks to circular linked property of
|
||||
* the list, this means to put the child at the tail
|
||||
* of the list that starts by parent.
|
||||
*/
|
||||
list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list,
|
||||
&(cfs_rq->tg->parent->cfs_rq[cpu]->leaf_cfs_rq_list));
|
||||
/*
|
||||
* The branch is now connected to its tree so we can
|
||||
* reset tmp_alone_branch to the beginning of the
|
||||
* list.
|
||||
*/
|
||||
rq->tmp_alone_branch = &rq->leaf_cfs_rq_list;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!cfs_rq->tg->parent) {
|
||||
/*
|
||||
* cfs rq without parent should be put
|
||||
* at the tail of the list.
|
||||
*/
|
||||
list_add_tail_rcu(&cfs_rq->leaf_cfs_rq_list,
|
||||
&rq->leaf_cfs_rq_list);
|
||||
/*
|
||||
* We have reach the top of a tree so we can reset
|
||||
* tmp_alone_branch to the beginning of the list.
|
||||
*/
|
||||
rq->tmp_alone_branch = &rq->leaf_cfs_rq_list;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* The parent has not already been added so we want to
|
||||
* make sure that it will be put after us.
|
||||
* tmp_alone_branch points to the begin of the branch
|
||||
* where we will add parent.
|
||||
*/
|
||||
list_add_rcu(&cfs_rq->leaf_cfs_rq_list, rq->tmp_alone_branch);
|
||||
/*
|
||||
* update tmp_alone_branch to points to the new begin
|
||||
* of the branch
|
||||
*/
|
||||
rq->tmp_alone_branch = &cfs_rq->leaf_cfs_rq_list;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void list_del_leaf_cfs_rq(struct cfs_rq *cfs_rq)
|
||||
|
@ -355,7 +361,12 @@ static inline void list_del_leaf_cfs_rq(struct cfs_rq *cfs_rq)
|
|||
}
|
||||
}
|
||||
|
||||
/* Iterate through all leaf cfs_rq's on a runqueue: */
|
||||
static inline void assert_list_leaf_cfs_rq(struct rq *rq)
|
||||
{
|
||||
SCHED_WARN_ON(rq->tmp_alone_branch != &rq->leaf_cfs_rq_list);
|
||||
}
|
||||
|
||||
/* Iterate through all cfs_rq's on a runqueue in bottom-up order */
|
||||
#define for_each_leaf_cfs_rq(rq, cfs_rq) \
|
||||
list_for_each_entry_rcu(cfs_rq, &rq->leaf_cfs_rq_list, leaf_cfs_rq_list)
|
||||
|
||||
|
@ -435,14 +446,19 @@ static inline struct cfs_rq *group_cfs_rq(struct sched_entity *grp)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline void list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
|
||||
static inline bool list_add_leaf_cfs_rq(struct cfs_rq *cfs_rq)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void list_del_leaf_cfs_rq(struct cfs_rq *cfs_rq)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void assert_list_leaf_cfs_rq(struct rq *rq)
|
||||
{
|
||||
}
|
||||
|
||||
#define for_each_leaf_cfs_rq(rq, cfs_rq) \
|
||||
for (cfs_rq = &rq->cfs; cfs_rq; cfs_rq = NULL)
|
||||
|
||||
|
@ -5078,6 +5094,12 @@ static void __maybe_unused unthrottle_offline_cfs_rqs(struct rq *rq)
|
|||
}
|
||||
|
||||
#else /* CONFIG_CFS_BANDWIDTH */
|
||||
|
||||
static inline bool cfs_bandwidth_used(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq)
|
||||
{
|
||||
return rq_clock_task(rq_of(cfs_rq));
|
||||
|
@ -5289,6 +5311,23 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
|
|||
|
||||
}
|
||||
|
||||
if (cfs_bandwidth_used()) {
|
||||
/*
|
||||
* When bandwidth control is enabled; the cfs_rq_throttled()
|
||||
* breaks in the above iteration can result in incomplete
|
||||
* leaf list maintenance, resulting in triggering the assertion
|
||||
* below.
|
||||
*/
|
||||
for_each_sched_entity(se) {
|
||||
cfs_rq = cfs_rq_of(se);
|
||||
|
||||
if (list_add_leaf_cfs_rq(cfs_rq))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert_list_leaf_cfs_rq(rq);
|
||||
|
||||
hrtick_update(rq);
|
||||
}
|
||||
|
||||
|
|
|
@ -254,12 +254,17 @@ static void basic_walk(struct tcf_proto *tp, struct tcf_walker *arg)
|
|||
}
|
||||
}
|
||||
|
||||
static void basic_bind_class(void *fh, u32 classid, unsigned long cl)
|
||||
static void basic_bind_class(void *fh, u32 classid, unsigned long cl, void *q,
|
||||
unsigned long base)
|
||||
{
|
||||
struct basic_filter *f = fh;
|
||||
|
||||
if (f && f->res.classid == classid)
|
||||
f->res.class = cl;
|
||||
if (f && f->res.classid == classid) {
|
||||
if (cl)
|
||||
__tcf_bind_filter(q, &f->res, base);
|
||||
else
|
||||
__tcf_unbind_filter(q, &f->res);
|
||||
}
|
||||
}
|
||||
|
||||
static int basic_dump(struct net *net, struct tcf_proto *tp, void *fh,
|
||||
|
|
|
@ -627,12 +627,17 @@ static int cls_bpf_dump(struct net *net, struct tcf_proto *tp, void *fh,
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void cls_bpf_bind_class(void *fh, u32 classid, unsigned long cl)
|
||||
static void cls_bpf_bind_class(void *fh, u32 classid, unsigned long cl,
|
||||
void *q, unsigned long base)
|
||||
{
|
||||
struct cls_bpf_prog *prog = fh;
|
||||
|
||||
if (prog && prog->res.classid == classid)
|
||||
prog->res.class = cl;
|
||||
if (prog && prog->res.classid == classid) {
|
||||
if (cl)
|
||||
__tcf_bind_filter(q, &prog->res, base);
|
||||
else
|
||||
__tcf_unbind_filter(q, &prog->res);
|
||||
}
|
||||
}
|
||||
|
||||
static void cls_bpf_walk(struct tcf_proto *tp, struct tcf_walker *arg)
|
||||
|
|
|
@ -1942,12 +1942,17 @@ static int fl_tmplt_dump(struct sk_buff *skb, struct net *net, void *tmplt_priv)
|
|||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static void fl_bind_class(void *fh, u32 classid, unsigned long cl)
|
||||
static void fl_bind_class(void *fh, u32 classid, unsigned long cl, void *q,
|
||||
unsigned long base)
|
||||
{
|
||||
struct cls_fl_filter *f = fh;
|
||||
|
||||
if (f && f->res.classid == classid)
|
||||
f->res.class = cl;
|
||||
if (f && f->res.classid == classid) {
|
||||
if (cl)
|
||||
__tcf_bind_filter(q, &f->res, base);
|
||||
else
|
||||
__tcf_unbind_filter(q, &f->res);
|
||||
}
|
||||
}
|
||||
|
||||
static struct tcf_proto_ops cls_fl_ops __read_mostly = {
|
||||
|
|
|
@ -432,12 +432,17 @@ static int fw_dump(struct net *net, struct tcf_proto *tp, void *fh,
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void fw_bind_class(void *fh, u32 classid, unsigned long cl)
|
||||
static void fw_bind_class(void *fh, u32 classid, unsigned long cl, void *q,
|
||||
unsigned long base)
|
||||
{
|
||||
struct fw_filter *f = fh;
|
||||
|
||||
if (f && f->res.classid == classid)
|
||||
f->res.class = cl;
|
||||
if (f && f->res.classid == classid) {
|
||||
if (cl)
|
||||
__tcf_bind_filter(q, &f->res, base);
|
||||
else
|
||||
__tcf_unbind_filter(q, &f->res);
|
||||
}
|
||||
}
|
||||
|
||||
static struct tcf_proto_ops cls_fw_ops __read_mostly = {
|
||||
|
|
|
@ -310,12 +310,17 @@ static int mall_dump(struct net *net, struct tcf_proto *tp, void *fh,
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void mall_bind_class(void *fh, u32 classid, unsigned long cl)
|
||||
static void mall_bind_class(void *fh, u32 classid, unsigned long cl, void *q,
|
||||
unsigned long base)
|
||||
{
|
||||
struct cls_mall_head *head = fh;
|
||||
|
||||
if (head && head->res.classid == classid)
|
||||
head->res.class = cl;
|
||||
if (head && head->res.classid == classid) {
|
||||
if (cl)
|
||||
__tcf_bind_filter(q, &head->res, base);
|
||||
else
|
||||
__tcf_unbind_filter(q, &head->res);
|
||||
}
|
||||
}
|
||||
|
||||
static struct tcf_proto_ops cls_mall_ops __read_mostly = {
|
||||
|
|
|
@ -645,12 +645,17 @@ static int route4_dump(struct net *net, struct tcf_proto *tp, void *fh,
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void route4_bind_class(void *fh, u32 classid, unsigned long cl)
|
||||
static void route4_bind_class(void *fh, u32 classid, unsigned long cl, void *q,
|
||||
unsigned long base)
|
||||
{
|
||||
struct route4_filter *f = fh;
|
||||
|
||||
if (f && f->res.classid == classid)
|
||||
f->res.class = cl;
|
||||
if (f && f->res.classid == classid) {
|
||||
if (cl)
|
||||
__tcf_bind_filter(q, &f->res, base);
|
||||
else
|
||||
__tcf_unbind_filter(q, &f->res);
|
||||
}
|
||||
}
|
||||
|
||||
static struct tcf_proto_ops cls_route4_ops __read_mostly = {
|
||||
|
|
|
@ -736,12 +736,17 @@ static int rsvp_dump(struct net *net, struct tcf_proto *tp, void *fh,
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void rsvp_bind_class(void *fh, u32 classid, unsigned long cl)
|
||||
static void rsvp_bind_class(void *fh, u32 classid, unsigned long cl, void *q,
|
||||
unsigned long base)
|
||||
{
|
||||
struct rsvp_filter *f = fh;
|
||||
|
||||
if (f && f->res.classid == classid)
|
||||
f->res.class = cl;
|
||||
if (f && f->res.classid == classid) {
|
||||
if (cl)
|
||||
__tcf_bind_filter(q, &f->res, base);
|
||||
else
|
||||
__tcf_unbind_filter(q, &f->res);
|
||||
}
|
||||
}
|
||||
|
||||
static struct tcf_proto_ops RSVP_OPS __read_mostly = {
|
||||
|
|
|
@ -652,12 +652,17 @@ static int tcindex_dump(struct net *net, struct tcf_proto *tp, void *fh,
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void tcindex_bind_class(void *fh, u32 classid, unsigned long cl)
|
||||
static void tcindex_bind_class(void *fh, u32 classid, unsigned long cl,
|
||||
void *q, unsigned long base)
|
||||
{
|
||||
struct tcindex_filter_result *r = fh;
|
||||
|
||||
if (r && r->res.classid == classid)
|
||||
r->res.class = cl;
|
||||
if (r && r->res.classid == classid) {
|
||||
if (cl)
|
||||
__tcf_bind_filter(q, &r->res, base);
|
||||
else
|
||||
__tcf_unbind_filter(q, &r->res);
|
||||
}
|
||||
}
|
||||
|
||||
static struct tcf_proto_ops cls_tcindex_ops __read_mostly = {
|
||||
|
|
|
@ -1315,12 +1315,17 @@ static int u32_reoffload(struct tcf_proto *tp, bool add, tc_setup_cb_t *cb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void u32_bind_class(void *fh, u32 classid, unsigned long cl)
|
||||
static void u32_bind_class(void *fh, u32 classid, unsigned long cl, void *q,
|
||||
unsigned long base)
|
||||
{
|
||||
struct tc_u_knode *n = fh;
|
||||
|
||||
if (n && n->res.classid == classid)
|
||||
n->res.class = cl;
|
||||
if (n && n->res.classid == classid) {
|
||||
if (cl)
|
||||
__tcf_bind_filter(q, &n->res, base);
|
||||
else
|
||||
__tcf_unbind_filter(q, &n->res);
|
||||
}
|
||||
}
|
||||
|
||||
static int u32_dump(struct net *net, struct tcf_proto *tp, void *fh,
|
||||
|
|
|
@ -242,6 +242,9 @@ static int tcf_em_validate(struct tcf_proto *tp,
|
|||
goto errout;
|
||||
|
||||
if (em->ops->change) {
|
||||
err = -EINVAL;
|
||||
if (em_hdr->flags & TCF_EM_SIMPLE)
|
||||
goto errout;
|
||||
err = em->ops->change(net, data, data_len, em);
|
||||
if (err < 0)
|
||||
goto errout;
|
||||
|
|
|
@ -1803,8 +1803,9 @@ static int tclass_del_notify(struct net *net,
|
|||
|
||||
struct tcf_bind_args {
|
||||
struct tcf_walker w;
|
||||
u32 classid;
|
||||
unsigned long base;
|
||||
unsigned long cl;
|
||||
u32 classid;
|
||||
};
|
||||
|
||||
static int tcf_node_bind(struct tcf_proto *tp, void *n, struct tcf_walker *arg)
|
||||
|
@ -1815,7 +1816,7 @@ static int tcf_node_bind(struct tcf_proto *tp, void *n, struct tcf_walker *arg)
|
|||
struct Qdisc *q = tcf_block_q(tp->chain->block);
|
||||
|
||||
sch_tree_lock(q);
|
||||
tp->ops->bind_class(n, a->classid, a->cl);
|
||||
tp->ops->bind_class(n, a->classid, a->cl, q, a->base);
|
||||
sch_tree_unlock(q);
|
||||
}
|
||||
return 0;
|
||||
|
@ -1846,6 +1847,7 @@ static void tc_bind_tclass(struct Qdisc *q, u32 portid, u32 clid,
|
|||
|
||||
arg.w.fn = tcf_node_bind;
|
||||
arg.classid = clid;
|
||||
arg.base = cl;
|
||||
arg.cl = new_cl;
|
||||
tp->ops->walk(tp, &arg.w);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue