mirror of
https://github.com/Fishwaldo/build.git
synced 2025-03-27 17:21:34 +00:00
2955 lines
98 KiB
Diff
2955 lines
98 KiB
Diff
diff --git a/Makefile b/Makefile
|
|
index e6c7990497e7..dc5df61ea4be 100644
|
|
--- a/Makefile
|
|
+++ b/Makefile
|
|
@@ -1,6 +1,6 @@
|
|
VERSION = 4
|
|
PATCHLEVEL = 4
|
|
-SUBLEVEL = 68
|
|
+SUBLEVEL = 69
|
|
EXTRAVERSION =
|
|
NAME = Blurry Fish Butt
|
|
|
|
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
|
|
index a9b3b905e661..443db0c43d7c 100644
|
|
--- a/arch/arm/kvm/psci.c
|
|
+++ b/arch/arm/kvm/psci.c
|
|
@@ -208,9 +208,10 @@ int kvm_psci_version(struct kvm_vcpu *vcpu)
|
|
|
|
static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
|
|
{
|
|
- int ret = 1;
|
|
+ struct kvm *kvm = vcpu->kvm;
|
|
unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
|
|
unsigned long val;
|
|
+ int ret = 1;
|
|
|
|
switch (psci_fn) {
|
|
case PSCI_0_2_FN_PSCI_VERSION:
|
|
@@ -230,7 +231,9 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
|
|
break;
|
|
case PSCI_0_2_FN_CPU_ON:
|
|
case PSCI_0_2_FN64_CPU_ON:
|
|
+ mutex_lock(&kvm->lock);
|
|
val = kvm_psci_vcpu_on(vcpu);
|
|
+ mutex_unlock(&kvm->lock);
|
|
break;
|
|
case PSCI_0_2_FN_AFFINITY_INFO:
|
|
case PSCI_0_2_FN64_AFFINITY_INFO:
|
|
@@ -279,6 +282,7 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
|
|
|
|
static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
|
|
{
|
|
+ struct kvm *kvm = vcpu->kvm;
|
|
unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
|
|
unsigned long val;
|
|
|
|
@@ -288,7 +292,9 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
|
|
val = PSCI_RET_SUCCESS;
|
|
break;
|
|
case KVM_PSCI_FN_CPU_ON:
|
|
+ mutex_lock(&kvm->lock);
|
|
val = kvm_psci_vcpu_on(vcpu);
|
|
+ mutex_unlock(&kvm->lock);
|
|
break;
|
|
default:
|
|
val = PSCI_RET_NOT_SUPPORTED;
|
|
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
|
|
index d2650e84faf2..c2489f62c4fb 100644
|
|
--- a/arch/arm64/kvm/sys_regs.c
|
|
+++ b/arch/arm64/kvm/sys_regs.c
|
|
@@ -1054,8 +1054,8 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu,
|
|
{
|
|
struct sys_reg_params params;
|
|
u32 hsr = kvm_vcpu_get_hsr(vcpu);
|
|
- int Rt = (hsr >> 5) & 0xf;
|
|
- int Rt2 = (hsr >> 10) & 0xf;
|
|
+ int Rt = (hsr >> 5) & 0x1f;
|
|
+ int Rt2 = (hsr >> 10) & 0x1f;
|
|
|
|
params.is_aarch32 = true;
|
|
params.is_32bit = false;
|
|
@@ -1106,7 +1106,7 @@ static int kvm_handle_cp_32(struct kvm_vcpu *vcpu,
|
|
{
|
|
struct sys_reg_params params;
|
|
u32 hsr = kvm_vcpu_get_hsr(vcpu);
|
|
- int Rt = (hsr >> 5) & 0xf;
|
|
+ int Rt = (hsr >> 5) & 0x1f;
|
|
|
|
params.is_aarch32 = true;
|
|
params.is_32bit = true;
|
|
diff --git a/arch/x86/boot/boot.h b/arch/x86/boot/boot.h
|
|
index 9011a88353de..ed1e9206f830 100644
|
|
--- a/arch/x86/boot/boot.h
|
|
+++ b/arch/x86/boot/boot.h
|
|
@@ -16,7 +16,7 @@
|
|
#ifndef BOOT_BOOT_H
|
|
#define BOOT_BOOT_H
|
|
|
|
-#define STACK_SIZE 512 /* Minimum number of bytes for stack */
|
|
+#define STACK_SIZE 1024 /* Minimum number of bytes for stack */
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h
|
|
index bd8ce6bcdfc9..6503526d7b24 100644
|
|
--- a/arch/x86/include/asm/pmem.h
|
|
+++ b/arch/x86/include/asm/pmem.h
|
|
@@ -122,7 +122,7 @@ static inline size_t arch_copy_from_iter_pmem(void __pmem *addr, size_t bytes,
|
|
|
|
if (bytes < 8) {
|
|
if (!IS_ALIGNED(dest, 4) || (bytes != 4))
|
|
- __arch_wb_cache_pmem(addr, 1);
|
|
+ __arch_wb_cache_pmem(addr, bytes);
|
|
} else {
|
|
if (!IS_ALIGNED(dest, 8)) {
|
|
dest = ALIGN(dest, boot_cpu_data.x86_clflush_size);
|
|
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
|
|
index e75095fa414e..281899da19d4 100644
|
|
--- a/arch/x86/kvm/x86.c
|
|
+++ b/arch/x86/kvm/x86.c
|
|
@@ -2960,6 +2960,12 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
|
|
| KVM_VCPUEVENT_VALID_SMM))
|
|
return -EINVAL;
|
|
|
|
+ /* INITs are latched while in SMM */
|
|
+ if (events->flags & KVM_VCPUEVENT_VALID_SMM &&
|
|
+ (events->smi.smm || events->smi.pending) &&
|
|
+ vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED)
|
|
+ return -EINVAL;
|
|
+
|
|
process_nmi(vcpu);
|
|
vcpu->arch.exception.pending = events->exception.injected;
|
|
vcpu->arch.exception.nr = events->exception.nr;
|
|
@@ -6993,6 +6999,12 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
|
|
mp_state->mp_state != KVM_MP_STATE_RUNNABLE)
|
|
return -EINVAL;
|
|
|
|
+ /* INITs are latched while in SMM */
|
|
+ if ((is_smm(vcpu) || vcpu->arch.smi_pending) &&
|
|
+ (mp_state->mp_state == KVM_MP_STATE_SIPI_RECEIVED ||
|
|
+ mp_state->mp_state == KVM_MP_STATE_INIT_RECEIVED))
|
|
+ return -EINVAL;
|
|
+
|
|
if (mp_state->mp_state == KVM_MP_STATE_SIPI_RECEIVED) {
|
|
vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED;
|
|
set_bit(KVM_APIC_SIPI, &vcpu->arch.apic->pending_events);
|
|
diff --git a/arch/x86/um/ptrace_64.c b/arch/x86/um/ptrace_64.c
|
|
index a629694ee750..e14c43a2d187 100644
|
|
--- a/arch/x86/um/ptrace_64.c
|
|
+++ b/arch/x86/um/ptrace_64.c
|
|
@@ -121,7 +121,7 @@ int poke_user(struct task_struct *child, long addr, long data)
|
|
else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
|
|
(addr <= offsetof(struct user, u_debugreg[7]))) {
|
|
addr -= offsetof(struct user, u_debugreg[0]);
|
|
- addr = addr >> 2;
|
|
+ addr = addr >> 3;
|
|
if ((addr == 4) || (addr == 5))
|
|
return -EIO;
|
|
child->thread.arch.debugregs[addr] = data;
|
|
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
|
|
index 1e56ff583459..63146c378f1e 100644
|
|
--- a/arch/x86/xen/mmu.c
|
|
+++ b/arch/x86/xen/mmu.c
|
|
@@ -2038,7 +2038,8 @@ static unsigned long __init xen_read_phys_ulong(phys_addr_t addr)
|
|
|
|
/*
|
|
* Translate a virtual address to a physical one without relying on mapped
|
|
- * page tables.
|
|
+ * page tables. Don't rely on big pages being aligned in (guest) physical
|
|
+ * space!
|
|
*/
|
|
static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
|
|
{
|
|
@@ -2059,7 +2060,7 @@ static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
|
|
sizeof(pud)));
|
|
if (!pud_present(pud))
|
|
return 0;
|
|
- pa = pud_pfn(pud) << PAGE_SHIFT;
|
|
+ pa = pud_val(pud) & PTE_PFN_MASK;
|
|
if (pud_large(pud))
|
|
return pa + (vaddr & ~PUD_MASK);
|
|
|
|
@@ -2067,7 +2068,7 @@ static phys_addr_t __init xen_early_virt_to_phys(unsigned long vaddr)
|
|
sizeof(pmd)));
|
|
if (!pmd_present(pmd))
|
|
return 0;
|
|
- pa = pmd_pfn(pmd) << PAGE_SHIFT;
|
|
+ pa = pmd_val(pmd) & PTE_PFN_MASK;
|
|
if (pmd_large(pmd))
|
|
return pa + (vaddr & ~PMD_MASK);
|
|
|
|
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
|
|
index 319f2e4f4a8b..478f572cb1e7 100644
|
|
--- a/block/blk-integrity.c
|
|
+++ b/block/blk-integrity.c
|
|
@@ -412,7 +412,8 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template
|
|
|
|
bi->flags = BLK_INTEGRITY_VERIFY | BLK_INTEGRITY_GENERATE |
|
|
template->flags;
|
|
- bi->interval_exp = ilog2(queue_logical_block_size(disk->queue));
|
|
+ bi->interval_exp = template->interval_exp ? :
|
|
+ ilog2(queue_logical_block_size(disk->queue));
|
|
bi->profile = template->profile ? template->profile : &nop_profile;
|
|
bi->tuple_size = template->tuple_size;
|
|
bi->tag_size = template->tag_size;
|
|
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
|
|
index 6d4d4569447e..faea9d728fd2 100644
|
|
--- a/crypto/algif_aead.c
|
|
+++ b/crypto/algif_aead.c
|
|
@@ -29,6 +29,11 @@ struct aead_sg_list {
|
|
struct scatterlist sg[ALG_MAX_PAGES];
|
|
};
|
|
|
|
+struct aead_tfm {
|
|
+ struct crypto_aead *aead;
|
|
+ bool has_key;
|
|
+};
|
|
+
|
|
struct aead_ctx {
|
|
struct aead_sg_list tsgl;
|
|
/*
|
|
@@ -513,24 +518,146 @@ static struct proto_ops algif_aead_ops = {
|
|
.poll = aead_poll,
|
|
};
|
|
|
|
+static int aead_check_key(struct socket *sock)
|
|
+{
|
|
+ int err = 0;
|
|
+ struct sock *psk;
|
|
+ struct alg_sock *pask;
|
|
+ struct aead_tfm *tfm;
|
|
+ struct sock *sk = sock->sk;
|
|
+ struct alg_sock *ask = alg_sk(sk);
|
|
+
|
|
+ lock_sock(sk);
|
|
+ if (ask->refcnt)
|
|
+ goto unlock_child;
|
|
+
|
|
+ psk = ask->parent;
|
|
+ pask = alg_sk(ask->parent);
|
|
+ tfm = pask->private;
|
|
+
|
|
+ err = -ENOKEY;
|
|
+ lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
|
|
+ if (!tfm->has_key)
|
|
+ goto unlock;
|
|
+
|
|
+ if (!pask->refcnt++)
|
|
+ sock_hold(psk);
|
|
+
|
|
+ ask->refcnt = 1;
|
|
+ sock_put(psk);
|
|
+
|
|
+ err = 0;
|
|
+
|
|
+unlock:
|
|
+ release_sock(psk);
|
|
+unlock_child:
|
|
+ release_sock(sk);
|
|
+
|
|
+ return err;
|
|
+}
|
|
+
|
|
+static int aead_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
|
|
+ size_t size)
|
|
+{
|
|
+ int err;
|
|
+
|
|
+ err = aead_check_key(sock);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ return aead_sendmsg(sock, msg, size);
|
|
+}
|
|
+
|
|
+static ssize_t aead_sendpage_nokey(struct socket *sock, struct page *page,
|
|
+ int offset, size_t size, int flags)
|
|
+{
|
|
+ int err;
|
|
+
|
|
+ err = aead_check_key(sock);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ return aead_sendpage(sock, page, offset, size, flags);
|
|
+}
|
|
+
|
|
+static int aead_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
|
|
+ size_t ignored, int flags)
|
|
+{
|
|
+ int err;
|
|
+
|
|
+ err = aead_check_key(sock);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ return aead_recvmsg(sock, msg, ignored, flags);
|
|
+}
|
|
+
|
|
+static struct proto_ops algif_aead_ops_nokey = {
|
|
+ .family = PF_ALG,
|
|
+
|
|
+ .connect = sock_no_connect,
|
|
+ .socketpair = sock_no_socketpair,
|
|
+ .getname = sock_no_getname,
|
|
+ .ioctl = sock_no_ioctl,
|
|
+ .listen = sock_no_listen,
|
|
+ .shutdown = sock_no_shutdown,
|
|
+ .getsockopt = sock_no_getsockopt,
|
|
+ .mmap = sock_no_mmap,
|
|
+ .bind = sock_no_bind,
|
|
+ .accept = sock_no_accept,
|
|
+ .setsockopt = sock_no_setsockopt,
|
|
+
|
|
+ .release = af_alg_release,
|
|
+ .sendmsg = aead_sendmsg_nokey,
|
|
+ .sendpage = aead_sendpage_nokey,
|
|
+ .recvmsg = aead_recvmsg_nokey,
|
|
+ .poll = aead_poll,
|
|
+};
|
|
+
|
|
static void *aead_bind(const char *name, u32 type, u32 mask)
|
|
{
|
|
- return crypto_alloc_aead(name, type, mask);
|
|
+ struct aead_tfm *tfm;
|
|
+ struct crypto_aead *aead;
|
|
+
|
|
+ tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
|
|
+ if (!tfm)
|
|
+ return ERR_PTR(-ENOMEM);
|
|
+
|
|
+ aead = crypto_alloc_aead(name, type, mask);
|
|
+ if (IS_ERR(aead)) {
|
|
+ kfree(tfm);
|
|
+ return ERR_CAST(aead);
|
|
+ }
|
|
+
|
|
+ tfm->aead = aead;
|
|
+
|
|
+ return tfm;
|
|
}
|
|
|
|
static void aead_release(void *private)
|
|
{
|
|
- crypto_free_aead(private);
|
|
+ struct aead_tfm *tfm = private;
|
|
+
|
|
+ crypto_free_aead(tfm->aead);
|
|
+ kfree(tfm);
|
|
}
|
|
|
|
static int aead_setauthsize(void *private, unsigned int authsize)
|
|
{
|
|
- return crypto_aead_setauthsize(private, authsize);
|
|
+ struct aead_tfm *tfm = private;
|
|
+
|
|
+ return crypto_aead_setauthsize(tfm->aead, authsize);
|
|
}
|
|
|
|
static int aead_setkey(void *private, const u8 *key, unsigned int keylen)
|
|
{
|
|
- return crypto_aead_setkey(private, key, keylen);
|
|
+ struct aead_tfm *tfm = private;
|
|
+ int err;
|
|
+
|
|
+ err = crypto_aead_setkey(tfm->aead, key, keylen);
|
|
+ tfm->has_key = !err;
|
|
+
|
|
+ return err;
|
|
}
|
|
|
|
static void aead_sock_destruct(struct sock *sk)
|
|
@@ -546,12 +673,14 @@ static void aead_sock_destruct(struct sock *sk)
|
|
af_alg_release_parent(sk);
|
|
}
|
|
|
|
-static int aead_accept_parent(void *private, struct sock *sk)
|
|
+static int aead_accept_parent_nokey(void *private, struct sock *sk)
|
|
{
|
|
struct aead_ctx *ctx;
|
|
struct alg_sock *ask = alg_sk(sk);
|
|
- unsigned int len = sizeof(*ctx) + crypto_aead_reqsize(private);
|
|
- unsigned int ivlen = crypto_aead_ivsize(private);
|
|
+ struct aead_tfm *tfm = private;
|
|
+ struct crypto_aead *aead = tfm->aead;
|
|
+ unsigned int len = sizeof(*ctx) + crypto_aead_reqsize(aead);
|
|
+ unsigned int ivlen = crypto_aead_ivsize(aead);
|
|
|
|
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
|
|
if (!ctx)
|
|
@@ -577,7 +706,7 @@ static int aead_accept_parent(void *private, struct sock *sk)
|
|
|
|
ask->private = ctx;
|
|
|
|
- aead_request_set_tfm(&ctx->aead_req, private);
|
|
+ aead_request_set_tfm(&ctx->aead_req, aead);
|
|
aead_request_set_callback(&ctx->aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
|
af_alg_complete, &ctx->completion);
|
|
|
|
@@ -586,13 +715,25 @@ static int aead_accept_parent(void *private, struct sock *sk)
|
|
return 0;
|
|
}
|
|
|
|
+static int aead_accept_parent(void *private, struct sock *sk)
|
|
+{
|
|
+ struct aead_tfm *tfm = private;
|
|
+
|
|
+ if (!tfm->has_key)
|
|
+ return -ENOKEY;
|
|
+
|
|
+ return aead_accept_parent_nokey(private, sk);
|
|
+}
|
|
+
|
|
static const struct af_alg_type algif_type_aead = {
|
|
.bind = aead_bind,
|
|
.release = aead_release,
|
|
.setkey = aead_setkey,
|
|
.setauthsize = aead_setauthsize,
|
|
.accept = aead_accept_parent,
|
|
+ .accept_nokey = aead_accept_parent_nokey,
|
|
.ops = &algif_aead_ops,
|
|
+ .ops_nokey = &algif_aead_ops_nokey,
|
|
.name = "aead",
|
|
.owner = THIS_MODULE
|
|
};
|
|
diff --git a/drivers/Makefile b/drivers/Makefile
|
|
index 795d0ca714bf..098997f2cc3a 100644
|
|
--- a/drivers/Makefile
|
|
+++ b/drivers/Makefile
|
|
@@ -98,6 +98,7 @@ obj-$(CONFIG_USB_PHY) += usb/
|
|
obj-$(CONFIG_USB) += usb/
|
|
obj-$(CONFIG_PCI) += usb/
|
|
obj-$(CONFIG_USB_GADGET) += usb/
|
|
+obj-$(CONFIG_OF) += usb/
|
|
obj-$(CONFIG_SERIO) += input/serio/
|
|
obj-$(CONFIG_GAMEPORT) += input/gameport/
|
|
obj-$(CONFIG_INPUT) += input/
|
|
diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c
|
|
index cb852cc750b7..f9b569ef3dd7 100644
|
|
--- a/drivers/bluetooth/hci_bcm.c
|
|
+++ b/drivers/bluetooth/hci_bcm.c
|
|
@@ -287,6 +287,9 @@ static int bcm_open(struct hci_uart *hu)
|
|
|
|
hu->priv = bcm;
|
|
|
|
+ if (!hu->tty->dev)
|
|
+ goto out;
|
|
+
|
|
mutex_lock(&bcm_device_lock);
|
|
list_for_each(p, &bcm_device_list) {
|
|
struct bcm_device *dev = list_entry(p, struct bcm_device, list);
|
|
@@ -307,7 +310,7 @@ static int bcm_open(struct hci_uart *hu)
|
|
}
|
|
|
|
mutex_unlock(&bcm_device_lock);
|
|
-
|
|
+out:
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c
|
|
index b9065506a847..0c63fce0c1e0 100644
|
|
--- a/drivers/bluetooth/hci_intel.c
|
|
+++ b/drivers/bluetooth/hci_intel.c
|
|
@@ -307,6 +307,9 @@ static int intel_set_power(struct hci_uart *hu, bool powered)
|
|
struct list_head *p;
|
|
int err = -ENODEV;
|
|
|
|
+ if (!hu->tty->dev)
|
|
+ return err;
|
|
+
|
|
mutex_lock(&intel_device_list_lock);
|
|
|
|
list_for_each(p, &intel_device_list) {
|
|
@@ -379,6 +382,9 @@ static void intel_busy_work(struct work_struct *work)
|
|
struct intel_data *intel = container_of(work, struct intel_data,
|
|
busy_work);
|
|
|
|
+ if (!intel->hu->tty->dev)
|
|
+ return;
|
|
+
|
|
/* Link is busy, delay the suspend */
|
|
mutex_lock(&intel_device_list_lock);
|
|
list_for_each(p, &intel_device_list) {
|
|
@@ -913,6 +919,8 @@ done:
|
|
list_for_each(p, &intel_device_list) {
|
|
struct intel_device *dev = list_entry(p, struct intel_device,
|
|
list);
|
|
+ if (!hu->tty->dev)
|
|
+ break;
|
|
if (hu->tty->dev->parent == dev->pdev->dev.parent) {
|
|
if (device_may_wakeup(&dev->pdev->dev))
|
|
idev = dev;
|
|
@@ -1094,6 +1102,9 @@ static int intel_enqueue(struct hci_uart *hu, struct sk_buff *skb)
|
|
|
|
BT_DBG("hu %p skb %p", hu, skb);
|
|
|
|
+ if (!hu->tty->dev)
|
|
+ goto out_enqueue;
|
|
+
|
|
/* Be sure our controller is resumed and potential LPM transaction
|
|
* completed before enqueuing any packet.
|
|
*/
|
|
@@ -1110,7 +1121,7 @@ static int intel_enqueue(struct hci_uart *hu, struct sk_buff *skb)
|
|
}
|
|
}
|
|
mutex_unlock(&intel_device_list_lock);
|
|
-
|
|
+out_enqueue:
|
|
skb_queue_tail(&intel->txq, skb);
|
|
|
|
return 0;
|
|
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
|
|
index 90e624662257..0d83cfb9708f 100644
|
|
--- a/drivers/char/ipmi/ipmi_ssif.c
|
|
+++ b/drivers/char/ipmi/ipmi_ssif.c
|
|
@@ -888,6 +888,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result,
|
|
* for details on the intricacies of this.
|
|
*/
|
|
int left;
|
|
+ unsigned char *data_to_send;
|
|
|
|
ssif_inc_stat(ssif_info, sent_messages_parts);
|
|
|
|
@@ -896,6 +897,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result,
|
|
left = 32;
|
|
/* Length byte. */
|
|
ssif_info->multi_data[ssif_info->multi_pos] = left;
|
|
+ data_to_send = ssif_info->multi_data + ssif_info->multi_pos;
|
|
ssif_info->multi_pos += left;
|
|
if (left < 32)
|
|
/*
|
|
@@ -909,7 +911,7 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result,
|
|
rv = ssif_i2c_send(ssif_info, msg_written_handler,
|
|
I2C_SMBUS_WRITE,
|
|
SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE,
|
|
- ssif_info->multi_data + ssif_info->multi_pos,
|
|
+ data_to_send,
|
|
I2C_SMBUS_BLOCK_DATA);
|
|
if (rv < 0) {
|
|
/* request failed, just return the error. */
|
|
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
|
|
index b1f37d4095fa..e76d52a203a7 100644
|
|
--- a/drivers/infiniband/core/sysfs.c
|
|
+++ b/drivers/infiniband/core/sysfs.c
|
|
@@ -863,7 +863,7 @@ err_put:
|
|
free_port_list_attributes(device);
|
|
|
|
err_unregister:
|
|
- device_unregister(class_dev);
|
|
+ device_del(class_dev);
|
|
|
|
err:
|
|
return ret;
|
|
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
|
|
index 77ddf2fa8625..8763fb832b01 100644
|
|
--- a/drivers/infiniband/hw/mlx4/main.c
|
|
+++ b/drivers/infiniband/hw/mlx4/main.c
|
|
@@ -2491,6 +2491,7 @@ err_counter:
|
|
mlx4_ib_delete_counters_table(ibdev, &ibdev->counters_table[i]);
|
|
|
|
err_map:
|
|
+ mlx4_ib_free_eqs(dev, ibdev);
|
|
iounmap(ibdev->uar_map);
|
|
|
|
err_uar:
|
|
diff --git a/drivers/infiniband/hw/mlx4/mcg.c b/drivers/infiniband/hw/mlx4/mcg.c
|
|
index 36ec8aa048aa..0b5bb0cee6f9 100644
|
|
--- a/drivers/infiniband/hw/mlx4/mcg.c
|
|
+++ b/drivers/infiniband/hw/mlx4/mcg.c
|
|
@@ -1105,7 +1105,8 @@ static void _mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy
|
|
while ((p = rb_first(&ctx->mcg_table)) != NULL) {
|
|
group = rb_entry(p, struct mcast_group, node);
|
|
if (atomic_read(&group->refcount))
|
|
- mcg_warn_group(group, "group refcount %d!!! (pointer %p)\n", atomic_read(&group->refcount), group);
|
|
+ mcg_debug_group(group, "group refcount %d!!! (pointer %p)\n",
|
|
+ atomic_read(&group->refcount), group);
|
|
|
|
force_clean_group(group);
|
|
}
|
|
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_fs.c b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
|
|
index 6bd5740e2691..09396bd7b02d 100644
|
|
--- a/drivers/infiniband/ulp/ipoib/ipoib_fs.c
|
|
+++ b/drivers/infiniband/ulp/ipoib/ipoib_fs.c
|
|
@@ -281,8 +281,11 @@ void ipoib_delete_debug_files(struct net_device *dev)
|
|
{
|
|
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
|
|
|
+ WARN_ONCE(!priv->mcg_dentry, "null mcg debug file\n");
|
|
+ WARN_ONCE(!priv->path_dentry, "null path debug file\n");
|
|
debugfs_remove(priv->mcg_dentry);
|
|
debugfs_remove(priv->path_dentry);
|
|
+ priv->mcg_dentry = priv->path_dentry = NULL;
|
|
}
|
|
|
|
int ipoib_register_debugfs(void)
|
|
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
|
|
index 8efcff1beb8f..6699ecd855f0 100644
|
|
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
|
|
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
|
|
@@ -106,6 +106,33 @@ static struct ib_client ipoib_client = {
|
|
.get_net_dev_by_params = ipoib_get_net_dev_by_params,
|
|
};
|
|
|
|
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
|
|
+static int ipoib_netdev_event(struct notifier_block *this,
|
|
+ unsigned long event, void *ptr)
|
|
+{
|
|
+ struct netdev_notifier_info *ni = ptr;
|
|
+ struct net_device *dev = ni->dev;
|
|
+
|
|
+ if (dev->netdev_ops->ndo_open != ipoib_open)
|
|
+ return NOTIFY_DONE;
|
|
+
|
|
+ switch (event) {
|
|
+ case NETDEV_REGISTER:
|
|
+ ipoib_create_debug_files(dev);
|
|
+ break;
|
|
+ case NETDEV_CHANGENAME:
|
|
+ ipoib_delete_debug_files(dev);
|
|
+ ipoib_create_debug_files(dev);
|
|
+ break;
|
|
+ case NETDEV_UNREGISTER:
|
|
+ ipoib_delete_debug_files(dev);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return NOTIFY_DONE;
|
|
+}
|
|
+#endif
|
|
+
|
|
int ipoib_open(struct net_device *dev)
|
|
{
|
|
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
|
@@ -1595,8 +1622,6 @@ void ipoib_dev_cleanup(struct net_device *dev)
|
|
|
|
ASSERT_RTNL();
|
|
|
|
- ipoib_delete_debug_files(dev);
|
|
-
|
|
/* Delete any child interfaces first */
|
|
list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list) {
|
|
/* Stop GC on child */
|
|
@@ -1908,8 +1933,6 @@ static struct net_device *ipoib_add_port(const char *format,
|
|
goto register_failed;
|
|
}
|
|
|
|
- ipoib_create_debug_files(priv->dev);
|
|
-
|
|
if (ipoib_cm_add_mode_attr(priv->dev))
|
|
goto sysfs_failed;
|
|
if (ipoib_add_pkey_attr(priv->dev))
|
|
@@ -1924,7 +1947,6 @@ static struct net_device *ipoib_add_port(const char *format,
|
|
return priv->dev;
|
|
|
|
sysfs_failed:
|
|
- ipoib_delete_debug_files(priv->dev);
|
|
unregister_netdev(priv->dev);
|
|
|
|
register_failed:
|
|
@@ -2006,6 +2028,12 @@ static void ipoib_remove_one(struct ib_device *device, void *client_data)
|
|
kfree(dev_list);
|
|
}
|
|
|
|
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
|
|
+static struct notifier_block ipoib_netdev_notifier = {
|
|
+ .notifier_call = ipoib_netdev_event,
|
|
+};
|
|
+#endif
|
|
+
|
|
static int __init ipoib_init_module(void)
|
|
{
|
|
int ret;
|
|
@@ -2057,6 +2085,9 @@ static int __init ipoib_init_module(void)
|
|
if (ret)
|
|
goto err_client;
|
|
|
|
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
|
|
+ register_netdevice_notifier(&ipoib_netdev_notifier);
|
|
+#endif
|
|
return 0;
|
|
|
|
err_client:
|
|
@@ -2074,6 +2105,9 @@ err_fs:
|
|
|
|
static void __exit ipoib_cleanup_module(void)
|
|
{
|
|
+#ifdef CONFIG_INFINIBAND_IPOIB_DEBUG
|
|
+ unregister_netdevice_notifier(&ipoib_netdev_notifier);
|
|
+#endif
|
|
ipoib_netlink_fini();
|
|
ib_unregister_client(&ipoib_client);
|
|
ib_sa_unregister_client(&ipoib_sa_client);
|
|
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
|
|
index fca1a882de27..57a34f87dedf 100644
|
|
--- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
|
|
+++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
|
|
@@ -85,8 +85,6 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv,
|
|
goto register_failed;
|
|
}
|
|
|
|
- ipoib_create_debug_files(priv->dev);
|
|
-
|
|
/* RTNL childs don't need proprietary sysfs entries */
|
|
if (type == IPOIB_LEGACY_CHILD) {
|
|
if (ipoib_cm_add_mode_attr(priv->dev))
|
|
@@ -107,7 +105,6 @@ int __ipoib_vlan_add(struct ipoib_dev_priv *ppriv, struct ipoib_dev_priv *priv,
|
|
|
|
sysfs_failed:
|
|
result = -ENOMEM;
|
|
- ipoib_delete_debug_files(priv->dev);
|
|
unregister_netdevice(priv->dev);
|
|
|
|
register_failed:
|
|
diff --git a/drivers/md/dm-era-target.c b/drivers/md/dm-era-target.c
|
|
index 665bf3285618..32e76c5ee741 100644
|
|
--- a/drivers/md/dm-era-target.c
|
|
+++ b/drivers/md/dm-era-target.c
|
|
@@ -961,15 +961,15 @@ static int metadata_commit(struct era_metadata *md)
|
|
}
|
|
}
|
|
|
|
- r = save_sm_root(md);
|
|
+ r = dm_tm_pre_commit(md->tm);
|
|
if (r) {
|
|
- DMERR("%s: save_sm_root failed", __func__);
|
|
+ DMERR("%s: pre commit failed", __func__);
|
|
return r;
|
|
}
|
|
|
|
- r = dm_tm_pre_commit(md->tm);
|
|
+ r = save_sm_root(md);
|
|
if (r) {
|
|
- DMERR("%s: pre commit failed", __func__);
|
|
+ DMERR("%s: save_sm_root failed", __func__);
|
|
return r;
|
|
}
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
|
|
index 1e1bef349487..6decf4a95ce1 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
|
@@ -6351,12 +6351,13 @@ static u64 ath10k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
|
|
|
static int ath10k_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
|
- u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
struct ath10k *ar = hw->priv;
|
|
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ampdu vdev_id %i sta %pM tid %hu action %d\n",
|
|
arvif->vdev_id, sta->addr, tid, action);
|
|
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
|
|
index a680a970b7f7..e4281438c04f 100644
|
|
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
|
|
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
|
|
@@ -1657,13 +1657,14 @@ static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw,
|
|
|
|
static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta,
|
|
- u16 tid, u16 *ssn, u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
struct ath9k_htc_priv *priv = hw->priv;
|
|
struct ath9k_htc_sta *ista;
|
|
int ret = 0;
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
|
|
mutex_lock(&priv->mutex);
|
|
ath9k_htc_ps_wakeup(priv);
|
|
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
|
|
index b114e57a823f..3abc64574116 100644
|
|
--- a/drivers/net/wireless/ath/ath9k/main.c
|
|
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
|
@@ -1855,14 +1855,16 @@ static void ath9k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
|
|
|
static int ath9k_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta,
|
|
- u16 tid, u16 *ssn, u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
struct ath_softc *sc = hw->priv;
|
|
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
|
bool flush = false;
|
|
int ret = 0;
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
+ u16 *ssn = ¶ms->ssn;
|
|
|
|
mutex_lock(&sc->mutex);
|
|
|
|
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
|
|
index 19d3d64416bf..4d1527a2e292 100644
|
|
--- a/drivers/net/wireless/ath/carl9170/main.c
|
|
+++ b/drivers/net/wireless/ath/carl9170/main.c
|
|
@@ -1413,10 +1413,12 @@ static void carl9170_ampdu_work(struct work_struct *work)
|
|
|
|
static int carl9170_op_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta,
|
|
- u16 tid, u16 *ssn, u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
+ u16 *ssn = ¶ms->ssn;
|
|
struct ar9170 *ar = hw->priv;
|
|
struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
|
|
struct carl9170_sta_tid *tid_info;
|
|
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
|
|
index 7c169abdbafe..a27279c2c695 100644
|
|
--- a/drivers/net/wireless/ath/wcn36xx/main.c
|
|
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
|
|
@@ -857,12 +857,14 @@ static int wcn36xx_resume(struct ieee80211_hw *hw)
|
|
|
|
static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
|
- u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
struct wcn36xx *wcn = hw->priv;
|
|
struct wcn36xx_sta *sta_priv = NULL;
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
+ u16 *ssn = ¶ms->ssn;
|
|
|
|
wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n",
|
|
action, tid);
|
|
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
|
|
index bec2dc1ca2e4..61ae2768132a 100644
|
|
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
|
|
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
|
|
@@ -818,13 +818,15 @@ brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
static int
|
|
brcms_ops_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
|
- u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
struct brcms_info *wl = hw->priv;
|
|
struct scb *scb = &wl->wlc->pri_scb;
|
|
int status;
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
+ u8 buf_size = params->buf_size;
|
|
|
|
if (WARN_ON(scb->magic != SCB_MAGIC))
|
|
return -EIDRM;
|
|
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c
|
|
index 95a7fdb3cc1c..c602a1e674ca 100644
|
|
--- a/drivers/net/wireless/cw1200/sta.c
|
|
+++ b/drivers/net/wireless/cw1200/sta.c
|
|
@@ -2135,9 +2135,7 @@ void cw1200_mcast_timeout(unsigned long arg)
|
|
|
|
int cw1200_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
|
- u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
/* Aggregation is implemented fully in firmware,
|
|
* including block ack negotiation. Do not allow
|
|
diff --git a/drivers/net/wireless/cw1200/sta.h b/drivers/net/wireless/cw1200/sta.h
|
|
index bebb3379017f..a0bacaa39b31 100644
|
|
--- a/drivers/net/wireless/cw1200/sta.h
|
|
+++ b/drivers/net/wireless/cw1200/sta.h
|
|
@@ -109,9 +109,7 @@ void cw1200_bss_info_changed(struct ieee80211_hw *dev,
|
|
u32 changed);
|
|
int cw1200_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
|
- u8 buf_size, bool amsdu);
|
|
+ struct ieee80211_ampdu_params *params);
|
|
|
|
void cw1200_suspend_resume(struct cw1200_common *priv,
|
|
struct wsm_suspend_resume *arg);
|
|
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
|
|
index 6656215a13a9..04b0349a6ad9 100644
|
|
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
|
|
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
|
|
@@ -5982,12 +5982,14 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|
|
|
int
|
|
il4965_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 * ssn,
|
|
- u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
struct il_priv *il = hw->priv;
|
|
int ret = -EINVAL;
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
+ u16 *ssn = ¶ms->ssn;
|
|
|
|
D_HT("A-MPDU action on addr %pM tid %d\n", sta->addr, tid);
|
|
|
|
diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h
|
|
index 8ab8706f9422..e432715e02d8 100644
|
|
--- a/drivers/net/wireless/iwlegacy/4965.h
|
|
+++ b/drivers/net/wireless/iwlegacy/4965.h
|
|
@@ -182,9 +182,7 @@ void il4965_mac_update_tkip_key(struct ieee80211_hw *hw,
|
|
struct ieee80211_sta *sta, u32 iv32,
|
|
u16 *phase1key);
|
|
int il4965_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 * ssn,
|
|
- u8 buf_size, bool amsdu);
|
|
+ struct ieee80211_ampdu_params *params);
|
|
int il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
struct ieee80211_sta *sta);
|
|
void
|
|
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
|
|
index b3ad34e8bf5a..1eb1a823a111 100644
|
|
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
|
|
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
|
|
@@ -729,12 +729,15 @@ static inline bool iwl_enable_tx_ampdu(const struct iwl_cfg *cfg)
|
|
|
|
static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
|
- u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
|
|
int ret = -EINVAL;
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
+ u16 *ssn = ¶ms->ssn;
|
|
+ u8 buf_size = params->buf_size;
|
|
struct iwl_station_priv *sta_priv = (void *) sta->drv_priv;
|
|
|
|
IWL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
|
|
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
|
|
index ce12717e656a..1a8ea775de08 100644
|
|
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
|
|
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
|
|
@@ -826,13 +826,16 @@ iwl_mvm_ampdu_check_trigger(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|
|
|
static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid,
|
|
- u16 *ssn, u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
|
int ret;
|
|
bool tx_agg_ref = false;
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
+ u16 *ssn = ¶ms->ssn;
|
|
+ u8 buf_size = params->buf_size;
|
|
|
|
IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n",
|
|
sta->addr, tid, action);
|
|
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
|
|
index 0cd95120bc78..d59769e858f4 100644
|
|
--- a/drivers/net/wireless/mac80211_hwsim.c
|
|
+++ b/drivers/net/wireless/mac80211_hwsim.c
|
|
@@ -1817,10 +1817,12 @@ static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw,
|
|
|
|
static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
|
- u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
+
|
|
switch (action) {
|
|
case IEEE80211_AMPDU_TX_START:
|
|
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
|
|
diff --git a/drivers/net/wireless/mediatek/mt7601u/main.c b/drivers/net/wireless/mediatek/mt7601u/main.c
|
|
index f715eee39851..e70dd9523911 100644
|
|
--- a/drivers/net/wireless/mediatek/mt7601u/main.c
|
|
+++ b/drivers/net/wireless/mediatek/mt7601u/main.c
|
|
@@ -334,11 +334,13 @@ static int mt7601u_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
|
|
|
static int
|
|
mt76_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size,
|
|
- bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
struct mt7601u_dev *dev = hw->priv;
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
+ u16 *ssn = ¶ms->ssn;
|
|
struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv;
|
|
|
|
WARN_ON(msta->wcid.idx > GROUP_WCID(0));
|
|
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
|
|
index 30e3aaae32e2..088429d0a634 100644
|
|
--- a/drivers/net/wireless/mwl8k.c
|
|
+++ b/drivers/net/wireless/mwl8k.c
|
|
@@ -5421,11 +5421,13 @@ static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx,
|
|
|
|
static int
|
|
mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
|
- u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
-
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
+ u16 *ssn = ¶ms->ssn;
|
|
+ u8 buf_size = params->buf_size;
|
|
int i, rc = 0;
|
|
struct mwl8k_priv *priv = hw->priv;
|
|
struct mwl8k_ampdu_stream *stream;
|
|
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c
|
|
index 6aed923a709a..7d820c395375 100644
|
|
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c
|
|
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c
|
|
@@ -5375,13 +5375,13 @@ static int rtl8xxxu_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|
|
|
static int
|
|
rtl8xxxu_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn, u8 buf_size,
|
|
- bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
struct rtl8xxxu_priv *priv = hw->priv;
|
|
struct device *dev = &priv->udev->dev;
|
|
u8 ampdu_factor, ampdu_density;
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
|
|
switch (action) {
|
|
case IEEE80211_AMPDU_TX_START:
|
|
diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c
|
|
index e36d8c456275..8b537a5a4b01 100644
|
|
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
|
|
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
|
|
@@ -1369,11 +1369,13 @@ static void rtl_op_sta_notify(struct ieee80211_hw *hw,
|
|
|
|
static int rtl_op_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
|
- u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
+ u16 *ssn = ¶ms->ssn;
|
|
|
|
switch (action) {
|
|
case IEEE80211_AMPDU_TX_START:
|
|
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
|
|
index b5bcc933a2a6..4df992de7d07 100644
|
|
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
|
|
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
|
|
@@ -659,29 +659,24 @@ static int rsi_mac80211_set_key(struct ieee80211_hw *hw,
|
|
* informs the f/w regarding this.
|
|
* @hw: Pointer to the ieee80211_hw structure.
|
|
* @vif: Pointer to the ieee80211_vif structure.
|
|
- * @action: ieee80211_ampdu_mlme_action enum.
|
|
- * @sta: Pointer to the ieee80211_sta structure.
|
|
- * @tid: Traffic identifier.
|
|
- * @ssn: Pointer to ssn value.
|
|
- * @buf_size: Buffer size (for kernel version > 2.6.38).
|
|
- * @amsdu: is AMSDU in AMPDU allowed
|
|
+ * @params: Pointer to A-MPDU action parameters
|
|
*
|
|
* Return: status: 0 on success, negative error code on failure.
|
|
*/
|
|
static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta,
|
|
- unsigned short tid,
|
|
- unsigned short *ssn,
|
|
- unsigned char buf_size,
|
|
- bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
int status = -EOPNOTSUPP;
|
|
struct rsi_hw *adapter = hw->priv;
|
|
struct rsi_common *common = adapter->priv;
|
|
u16 seq_no = 0;
|
|
u8 ii = 0;
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
+ u16 *ssn = ¶ms->ssn;
|
|
+ u8 buf_size = params->buf_size;
|
|
|
|
for (ii = 0; ii < RSI_MAX_VIFS; ii++) {
|
|
if (vif == adapter->vifs[ii])
|
|
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
|
|
index 9733b31a780d..69c1c09687a3 100644
|
|
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
|
|
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
|
|
@@ -7935,10 +7935,11 @@ u64 rt2800_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
|
EXPORT_SYMBOL_GPL(rt2800_get_tsf);
|
|
|
|
int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
|
- u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
struct rt2x00_sta *sta_priv = (struct rt2x00_sta *)sta->drv_priv;
|
|
int ret = 0;
|
|
|
|
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
|
|
index 440790b92b19..83f1a44fb9b4 100644
|
|
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
|
|
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
|
|
@@ -218,9 +218,7 @@ int rt2800_conf_tx(struct ieee80211_hw *hw,
|
|
const struct ieee80211_tx_queue_params *params);
|
|
u64 rt2800_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
|
|
int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
|
- u8 buf_size, bool amsdu);
|
|
+ struct ieee80211_ampdu_params *params);
|
|
int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
|
|
struct survey_info *survey);
|
|
void rt2800_disable_wpdma(struct rt2x00_dev *rt2x00dev);
|
|
diff --git a/drivers/net/wireless/ti/wl18xx/event.c b/drivers/net/wireless/ti/wl18xx/event.c
|
|
index 09c7e098f460..085ef5c87262 100644
|
|
--- a/drivers/net/wireless/ti/wl18xx/event.c
|
|
+++ b/drivers/net/wireless/ti/wl18xx/event.c
|
|
@@ -206,5 +206,33 @@ int wl18xx_process_mailbox_events(struct wl1271 *wl)
|
|
mbox->sc_pwd_len,
|
|
mbox->sc_pwd);
|
|
|
|
+ if (vector & RX_BA_WIN_SIZE_CHANGE_EVENT_ID) {
|
|
+ struct wl12xx_vif *wlvif;
|
|
+ struct ieee80211_vif *vif;
|
|
+ struct ieee80211_sta *sta;
|
|
+ u8 link_id = mbox->rx_ba_link_id;
|
|
+ u8 win_size = mbox->rx_ba_win_size;
|
|
+ const u8 *addr;
|
|
+
|
|
+ wlvif = wl->links[link_id].wlvif;
|
|
+ vif = wl12xx_wlvif_to_vif(wlvif);
|
|
+
|
|
+ /* Update RX aggregation window size and call
|
|
+ * MAC routine to stop active RX aggregations for this link
|
|
+ */
|
|
+ if (wlvif->bss_type != BSS_TYPE_AP_BSS)
|
|
+ addr = vif->bss_conf.bssid;
|
|
+ else
|
|
+ addr = wl->links[link_id].addr;
|
|
+
|
|
+ sta = ieee80211_find_sta(vif, addr);
|
|
+ if (sta) {
|
|
+ sta->max_rx_aggregation_subframes = win_size;
|
|
+ ieee80211_stop_rx_ba_session(vif,
|
|
+ wl->links[link_id].ba_bitmap,
|
|
+ addr);
|
|
+ }
|
|
+ }
|
|
+
|
|
return 0;
|
|
}
|
|
diff --git a/drivers/net/wireless/ti/wl18xx/event.h b/drivers/net/wireless/ti/wl18xx/event.h
|
|
index f3d4f13379cb..9495fadc8093 100644
|
|
--- a/drivers/net/wireless/ti/wl18xx/event.h
|
|
+++ b/drivers/net/wireless/ti/wl18xx/event.h
|
|
@@ -38,6 +38,7 @@ enum {
|
|
REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID = BIT(18),
|
|
DFS_CHANNELS_CONFIG_COMPLETE_EVENT = BIT(19),
|
|
PERIODIC_SCAN_REPORT_EVENT_ID = BIT(20),
|
|
+ RX_BA_WIN_SIZE_CHANGE_EVENT_ID = BIT(21),
|
|
SMART_CONFIG_SYNC_EVENT_ID = BIT(22),
|
|
SMART_CONFIG_DECODE_EVENT_ID = BIT(23),
|
|
TIME_SYNC_EVENT_ID = BIT(24),
|
|
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
|
|
index 50cce42089a5..47f355e92193 100644
|
|
--- a/drivers/net/wireless/ti/wl18xx/main.c
|
|
+++ b/drivers/net/wireless/ti/wl18xx/main.c
|
|
@@ -1029,7 +1029,8 @@ static int wl18xx_boot(struct wl1271 *wl)
|
|
DFS_CHANNELS_CONFIG_COMPLETE_EVENT |
|
|
SMART_CONFIG_SYNC_EVENT_ID |
|
|
SMART_CONFIG_DECODE_EVENT_ID |
|
|
- TIME_SYNC_EVENT_ID;
|
|
+ TIME_SYNC_EVENT_ID |
|
|
+ RX_BA_WIN_SIZE_CHANGE_EVENT_ID;
|
|
|
|
wl->ap_event_mask = MAX_TX_FAILURE_EVENT_ID;
|
|
|
|
diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
|
|
index f28fa3b5029d..0646c9b6f8d7 100644
|
|
--- a/drivers/net/wireless/ti/wlcore/acx.c
|
|
+++ b/drivers/net/wireless/ti/wlcore/acx.c
|
|
@@ -1419,7 +1419,8 @@ out:
|
|
|
|
/* setup BA session receiver setting in the FW. */
|
|
int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
|
|
- u16 ssn, bool enable, u8 peer_hlid)
|
|
+ u16 ssn, bool enable, u8 peer_hlid,
|
|
+ u8 win_size)
|
|
{
|
|
struct wl1271_acx_ba_receiver_setup *acx;
|
|
int ret;
|
|
@@ -1435,7 +1436,7 @@ int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
|
|
acx->hlid = peer_hlid;
|
|
acx->tid = tid_index;
|
|
acx->enable = enable;
|
|
- acx->win_size = wl->conf.ht.rx_ba_win_size;
|
|
+ acx->win_size = win_size;
|
|
acx->ssn = ssn;
|
|
|
|
ret = wlcore_cmd_configure_failsafe(wl, ACX_BA_SESSION_RX_SETUP, acx,
|
|
diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h
|
|
index 954d57ec98f4..524aea495dff 100644
|
|
--- a/drivers/net/wireless/ti/wlcore/acx.h
|
|
+++ b/drivers/net/wireless/ti/wlcore/acx.h
|
|
@@ -1112,7 +1112,8 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl,
|
|
int wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl,
|
|
struct wl12xx_vif *wlvif);
|
|
int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index,
|
|
- u16 ssn, bool enable, u8 peer_hlid);
|
|
+ u16 ssn, bool enable, u8 peer_hlid,
|
|
+ u8 win_size);
|
|
int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
|
u64 *mactime);
|
|
int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
|
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
|
|
index ec7f6af3fab2..7b27c7e23af2 100644
|
|
--- a/drivers/net/wireless/ti/wlcore/main.c
|
|
+++ b/drivers/net/wireless/ti/wlcore/main.c
|
|
@@ -5261,14 +5261,16 @@ out:
|
|
|
|
static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
|
- u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
struct wl1271 *wl = hw->priv;
|
|
struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
|
|
int ret;
|
|
u8 hlid, *ba_bitmap;
|
|
+ struct ieee80211_sta *sta = params->sta;
|
|
+ enum ieee80211_ampdu_mlme_action action = params->action;
|
|
+ u16 tid = params->tid;
|
|
+ u16 *ssn = ¶ms->ssn;
|
|
|
|
wl1271_debug(DEBUG_MAC80211, "mac80211 ampdu action %d tid %d", action,
|
|
tid);
|
|
@@ -5326,7 +5328,9 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
|
|
}
|
|
|
|
ret = wl12xx_acx_set_ba_receiver_session(wl, tid, *ssn, true,
|
|
- hlid);
|
|
+ hlid,
|
|
+ params->buf_size);
|
|
+
|
|
if (!ret) {
|
|
*ba_bitmap |= BIT(tid);
|
|
wl->ba_rx_session_count++;
|
|
@@ -5347,7 +5351,7 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
|
|
}
|
|
|
|
ret = wl12xx_acx_set_ba_receiver_session(wl, tid, 0, false,
|
|
- hlid);
|
|
+ hlid, 0);
|
|
if (!ret) {
|
|
*ba_bitmap &= ~BIT(tid);
|
|
wl->ba_rx_session_count--;
|
|
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
|
|
index b87192e0f9aa..109becdabc24 100644
|
|
--- a/drivers/staging/comedi/drivers/jr3_pci.c
|
|
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
|
|
@@ -610,7 +610,7 @@ static void jr3_pci_poll_dev(unsigned long data)
|
|
s = &dev->subdevices[i];
|
|
spriv = s->private;
|
|
|
|
- if (now > spriv->next_time_min) {
|
|
+ if (time_after_eq(now, spriv->next_time_min)) {
|
|
struct jr3_pci_poll_delay sub_delay;
|
|
|
|
sub_delay = jr3_pci_poll_subdevice(s);
|
|
@@ -726,11 +726,12 @@ static int jr3_pci_auto_attach(struct comedi_device *dev,
|
|
s->insn_read = jr3_pci_ai_insn_read;
|
|
|
|
spriv = jr3_pci_alloc_spriv(dev, s);
|
|
- if (spriv) {
|
|
- /* Channel specific range and maxdata */
|
|
- s->range_table_list = spriv->range_table_list;
|
|
- s->maxdata_list = spriv->maxdata_list;
|
|
- }
|
|
+ if (!spriv)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ /* Channel specific range and maxdata */
|
|
+ s->range_table_list = spriv->range_table_list;
|
|
+ s->maxdata_list = spriv->maxdata_list;
|
|
}
|
|
|
|
/* Reset DSP card */
|
|
diff --git a/drivers/staging/gdm724x/gdm_mux.c b/drivers/staging/gdm724x/gdm_mux.c
|
|
index 445f83615575..fb4f3fea6c66 100644
|
|
--- a/drivers/staging/gdm724x/gdm_mux.c
|
|
+++ b/drivers/staging/gdm724x/gdm_mux.c
|
|
@@ -670,14 +670,14 @@ static int __init gdm_usb_mux_init(void)
|
|
|
|
static void __exit gdm_usb_mux_exit(void)
|
|
{
|
|
- unregister_lte_tty_driver();
|
|
-
|
|
if (mux_rx_wq) {
|
|
flush_workqueue(mux_rx_wq);
|
|
destroy_workqueue(mux_rx_wq);
|
|
}
|
|
|
|
usb_deregister(&gdm_mux_driver);
|
|
+ unregister_lte_tty_driver();
|
|
+
|
|
}
|
|
|
|
module_init(gdm_usb_mux_init);
|
|
diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c
|
|
index c975c3b87093..cfc3017fd64a 100644
|
|
--- a/drivers/staging/vt6656/usbpipe.c
|
|
+++ b/drivers/staging/vt6656/usbpipe.c
|
|
@@ -50,15 +50,25 @@ int vnt_control_out(struct vnt_private *priv, u8 request, u16 value,
|
|
u16 index, u16 length, u8 *buffer)
|
|
{
|
|
int status = 0;
|
|
+ u8 *usb_buffer;
|
|
|
|
if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags))
|
|
return STATUS_FAILURE;
|
|
|
|
mutex_lock(&priv->usb_lock);
|
|
|
|
+ usb_buffer = kmemdup(buffer, length, GFP_KERNEL);
|
|
+ if (!usb_buffer) {
|
|
+ mutex_unlock(&priv->usb_lock);
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
status = usb_control_msg(priv->usb,
|
|
- usb_sndctrlpipe(priv->usb, 0), request, 0x40, value,
|
|
- index, buffer, length, USB_CTL_WAIT);
|
|
+ usb_sndctrlpipe(priv->usb, 0),
|
|
+ request, 0x40, value,
|
|
+ index, usb_buffer, length, USB_CTL_WAIT);
|
|
+
|
|
+ kfree(usb_buffer);
|
|
|
|
mutex_unlock(&priv->usb_lock);
|
|
|
|
@@ -78,15 +88,28 @@ int vnt_control_in(struct vnt_private *priv, u8 request, u16 value,
|
|
u16 index, u16 length, u8 *buffer)
|
|
{
|
|
int status;
|
|
+ u8 *usb_buffer;
|
|
|
|
if (test_bit(DEVICE_FLAGS_DISCONNECTED, &priv->flags))
|
|
return STATUS_FAILURE;
|
|
|
|
mutex_lock(&priv->usb_lock);
|
|
|
|
+ usb_buffer = kmalloc(length, GFP_KERNEL);
|
|
+ if (!usb_buffer) {
|
|
+ mutex_unlock(&priv->usb_lock);
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
status = usb_control_msg(priv->usb,
|
|
- usb_rcvctrlpipe(priv->usb, 0), request, 0xc0, value,
|
|
- index, buffer, length, USB_CTL_WAIT);
|
|
+ usb_rcvctrlpipe(priv->usb, 0),
|
|
+ request, 0xc0, value,
|
|
+ index, usb_buffer, length, USB_CTL_WAIT);
|
|
+
|
|
+ if (status == length)
|
|
+ memcpy(buffer, usb_buffer, length);
|
|
+
|
|
+ kfree(usb_buffer);
|
|
|
|
mutex_unlock(&priv->usb_lock);
|
|
|
|
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
|
|
index 6ed80b05d674..200d3de8bc1e 100644
|
|
--- a/drivers/target/iscsi/iscsi_target.c
|
|
+++ b/drivers/target/iscsi/iscsi_target.c
|
|
@@ -4821,6 +4821,7 @@ int iscsit_release_sessions_for_tpg(struct iscsi_portal_group *tpg, int force)
|
|
continue;
|
|
}
|
|
atomic_set(&sess->session_reinstatement, 1);
|
|
+ atomic_set(&sess->session_fall_back_to_erl0, 1);
|
|
spin_unlock(&sess->conn_lock);
|
|
|
|
list_move_tail(&se_sess->sess_list, &free_list);
|
|
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
|
|
index b4bfd706ac94..dc1bd1f1bdfe 100644
|
|
--- a/drivers/target/iscsi/iscsi_target_configfs.c
|
|
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
|
|
@@ -725,11 +725,8 @@ static ssize_t lio_target_nacl_cmdsn_depth_store(struct config_item *item,
|
|
|
|
if (iscsit_get_tpg(tpg) < 0)
|
|
return -EINVAL;
|
|
- /*
|
|
- * iscsit_tpg_set_initiator_node_queue_depth() assumes force=1
|
|
- */
|
|
- ret = iscsit_tpg_set_initiator_node_queue_depth(tpg,
|
|
- config_item_name(acl_ci), cmdsn_depth, 1);
|
|
+
|
|
+ ret = core_tpg_set_initiator_node_queue_depth(se_nacl, cmdsn_depth);
|
|
|
|
pr_debug("LIO_Target_ConfigFS: %s/%s Set CmdSN Window: %u for"
|
|
"InitiatorName: %s\n", config_item_name(wwn_ci),
|
|
@@ -1593,42 +1590,31 @@ static int lio_tpg_check_prot_fabric_only(
|
|
}
|
|
|
|
/*
|
|
- * Called with spin_lock_irq(struct se_portal_group->session_lock) held
|
|
- * or not held.
|
|
- *
|
|
- * Also, this function calls iscsit_inc_session_usage_count() on the
|
|
+ * This function calls iscsit_inc_session_usage_count() on the
|
|
* struct iscsi_session in question.
|
|
*/
|
|
static int lio_tpg_shutdown_session(struct se_session *se_sess)
|
|
{
|
|
struct iscsi_session *sess = se_sess->fabric_sess_ptr;
|
|
- struct se_portal_group *se_tpg = se_sess->se_tpg;
|
|
- bool local_lock = false;
|
|
-
|
|
- if (!spin_is_locked(&se_tpg->session_lock)) {
|
|
- spin_lock_irq(&se_tpg->session_lock);
|
|
- local_lock = true;
|
|
- }
|
|
+ struct se_portal_group *se_tpg = &sess->tpg->tpg_se_tpg;
|
|
|
|
+ spin_lock_bh(&se_tpg->session_lock);
|
|
spin_lock(&sess->conn_lock);
|
|
if (atomic_read(&sess->session_fall_back_to_erl0) ||
|
|
atomic_read(&sess->session_logout) ||
|
|
(sess->time2retain_timer_flags & ISCSI_TF_EXPIRED)) {
|
|
spin_unlock(&sess->conn_lock);
|
|
- if (local_lock)
|
|
- spin_unlock_irq(&sess->conn_lock);
|
|
+ spin_unlock_bh(&se_tpg->session_lock);
|
|
return 0;
|
|
}
|
|
atomic_set(&sess->session_reinstatement, 1);
|
|
+ atomic_set(&sess->session_fall_back_to_erl0, 1);
|
|
spin_unlock(&sess->conn_lock);
|
|
|
|
iscsit_stop_time2retain_timer(sess);
|
|
- spin_unlock_irq(&se_tpg->session_lock);
|
|
+ spin_unlock_bh(&se_tpg->session_lock);
|
|
|
|
iscsit_stop_session(sess, 1, 1);
|
|
- if (!local_lock)
|
|
- spin_lock_irq(&se_tpg->session_lock);
|
|
-
|
|
return 1;
|
|
}
|
|
|
|
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
|
|
index 316f66172335..4a137b0ae3dc 100644
|
|
--- a/drivers/target/iscsi/iscsi_target_login.c
|
|
+++ b/drivers/target/iscsi/iscsi_target_login.c
|
|
@@ -195,6 +195,7 @@ int iscsi_check_for_session_reinstatement(struct iscsi_conn *conn)
|
|
initiatorname_param->value) &&
|
|
(sess_p->sess_ops->SessionType == sessiontype))) {
|
|
atomic_set(&sess_p->session_reinstatement, 1);
|
|
+ atomic_set(&sess_p->session_fall_back_to_erl0, 1);
|
|
spin_unlock(&sess_p->conn_lock);
|
|
iscsit_inc_session_usage_count(sess_p);
|
|
iscsit_stop_time2retain_timer(sess_p);
|
|
diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c
|
|
index 68261b7dcefe..205a509b0dfb 100644
|
|
--- a/drivers/target/iscsi/iscsi_target_tpg.c
|
|
+++ b/drivers/target/iscsi/iscsi_target_tpg.c
|
|
@@ -589,16 +589,6 @@ int iscsit_tpg_del_network_portal(
|
|
return iscsit_tpg_release_np(tpg_np, tpg, np);
|
|
}
|
|
|
|
-int iscsit_tpg_set_initiator_node_queue_depth(
|
|
- struct iscsi_portal_group *tpg,
|
|
- unsigned char *initiatorname,
|
|
- u32 queue_depth,
|
|
- int force)
|
|
-{
|
|
- return core_tpg_set_initiator_node_queue_depth(&tpg->tpg_se_tpg,
|
|
- initiatorname, queue_depth, force);
|
|
-}
|
|
-
|
|
int iscsit_ta_authentication(struct iscsi_portal_group *tpg, u32 authentication)
|
|
{
|
|
unsigned char buf1[256], buf2[256], *none = NULL;
|
|
diff --git a/drivers/target/iscsi/iscsi_target_tpg.h b/drivers/target/iscsi/iscsi_target_tpg.h
|
|
index 9db32bd24cd4..2da211920c18 100644
|
|
--- a/drivers/target/iscsi/iscsi_target_tpg.h
|
|
+++ b/drivers/target/iscsi/iscsi_target_tpg.h
|
|
@@ -26,8 +26,6 @@ extern struct iscsi_tpg_np *iscsit_tpg_add_network_portal(struct iscsi_portal_gr
|
|
int);
|
|
extern int iscsit_tpg_del_network_portal(struct iscsi_portal_group *,
|
|
struct iscsi_tpg_np *);
|
|
-extern int iscsit_tpg_set_initiator_node_queue_depth(struct iscsi_portal_group *,
|
|
- unsigned char *, u32, int);
|
|
extern int iscsit_ta_authentication(struct iscsi_portal_group *, u32);
|
|
extern int iscsit_ta_login_timeout(struct iscsi_portal_group *, u32);
|
|
extern int iscsit_ta_netif_timeout(struct iscsi_portal_group *, u32);
|
|
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
|
|
index 79291869bce6..041a56987845 100644
|
|
--- a/drivers/target/target_core_file.c
|
|
+++ b/drivers/target/target_core_file.c
|
|
@@ -594,8 +594,7 @@ fd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
|
|
if (ret < 0)
|
|
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
|
|
|
- if (ret)
|
|
- target_complete_cmd(cmd, SAM_STAT_GOOD);
|
|
+ target_complete_cmd(cmd, SAM_STAT_GOOD);
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
|
|
index 90c5dffc9fa4..608117819366 100644
|
|
--- a/drivers/target/target_core_sbc.c
|
|
+++ b/drivers/target/target_core_sbc.c
|
|
@@ -498,8 +498,11 @@ static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool succes
|
|
* been failed with a non-zero SCSI status.
|
|
*/
|
|
if (cmd->scsi_status) {
|
|
- pr_err("compare_and_write_callback: non zero scsi_status:"
|
|
+ pr_debug("compare_and_write_callback: non zero scsi_status:"
|
|
" 0x%02x\n", cmd->scsi_status);
|
|
+ *post_ret = 1;
|
|
+ if (cmd->scsi_status == SAM_STAT_CHECK_CONDITION)
|
|
+ ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
|
goto out;
|
|
}
|
|
|
|
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
|
|
index 2794c6ec5c3c..899c33b3c734 100644
|
|
--- a/drivers/target/target_core_tpg.c
|
|
+++ b/drivers/target/target_core_tpg.c
|
|
@@ -169,28 +169,25 @@ void core_tpg_add_node_to_devs(
|
|
mutex_unlock(&tpg->tpg_lun_mutex);
|
|
}
|
|
|
|
-/* core_set_queue_depth_for_node():
|
|
- *
|
|
- *
|
|
- */
|
|
-static int core_set_queue_depth_for_node(
|
|
- struct se_portal_group *tpg,
|
|
- struct se_node_acl *acl)
|
|
+static void
|
|
+target_set_nacl_queue_depth(struct se_portal_group *tpg,
|
|
+ struct se_node_acl *acl, u32 queue_depth)
|
|
{
|
|
+ acl->queue_depth = queue_depth;
|
|
+
|
|
if (!acl->queue_depth) {
|
|
- pr_err("Queue depth for %s Initiator Node: %s is 0,"
|
|
+ pr_warn("Queue depth for %s Initiator Node: %s is 0,"
|
|
"defaulting to 1.\n", tpg->se_tpg_tfo->get_fabric_name(),
|
|
acl->initiatorname);
|
|
acl->queue_depth = 1;
|
|
}
|
|
-
|
|
- return 0;
|
|
}
|
|
|
|
static struct se_node_acl *target_alloc_node_acl(struct se_portal_group *tpg,
|
|
const unsigned char *initiatorname)
|
|
{
|
|
struct se_node_acl *acl;
|
|
+ u32 queue_depth;
|
|
|
|
acl = kzalloc(max(sizeof(*acl), tpg->se_tpg_tfo->node_acl_size),
|
|
GFP_KERNEL);
|
|
@@ -205,24 +202,20 @@ static struct se_node_acl *target_alloc_node_acl(struct se_portal_group *tpg,
|
|
spin_lock_init(&acl->nacl_sess_lock);
|
|
mutex_init(&acl->lun_entry_mutex);
|
|
atomic_set(&acl->acl_pr_ref_count, 0);
|
|
+
|
|
if (tpg->se_tpg_tfo->tpg_get_default_depth)
|
|
- acl->queue_depth = tpg->se_tpg_tfo->tpg_get_default_depth(tpg);
|
|
+ queue_depth = tpg->se_tpg_tfo->tpg_get_default_depth(tpg);
|
|
else
|
|
- acl->queue_depth = 1;
|
|
+ queue_depth = 1;
|
|
+ target_set_nacl_queue_depth(tpg, acl, queue_depth);
|
|
+
|
|
snprintf(acl->initiatorname, TRANSPORT_IQN_LEN, "%s", initiatorname);
|
|
acl->se_tpg = tpg;
|
|
acl->acl_index = scsi_get_new_index(SCSI_AUTH_INTR_INDEX);
|
|
|
|
tpg->se_tpg_tfo->set_default_node_attributes(acl);
|
|
|
|
- if (core_set_queue_depth_for_node(tpg, acl) < 0)
|
|
- goto out_free_acl;
|
|
-
|
|
return acl;
|
|
-
|
|
-out_free_acl:
|
|
- kfree(acl);
|
|
- return NULL;
|
|
}
|
|
|
|
static void target_add_node_acl(struct se_node_acl *acl)
|
|
@@ -369,7 +362,8 @@ void core_tpg_del_initiator_node_acl(struct se_node_acl *acl)
|
|
if (sess->sess_tearing_down != 0)
|
|
continue;
|
|
|
|
- target_get_session(sess);
|
|
+ if (!target_get_session(sess))
|
|
+ continue;
|
|
list_move(&sess->sess_acl_list, &sess_list);
|
|
}
|
|
spin_unlock_irqrestore(&acl->nacl_sess_lock, flags);
|
|
@@ -406,108 +400,52 @@ void core_tpg_del_initiator_node_acl(struct se_node_acl *acl)
|
|
*
|
|
*/
|
|
int core_tpg_set_initiator_node_queue_depth(
|
|
- struct se_portal_group *tpg,
|
|
- unsigned char *initiatorname,
|
|
- u32 queue_depth,
|
|
- int force)
|
|
+ struct se_node_acl *acl,
|
|
+ u32 queue_depth)
|
|
{
|
|
- struct se_session *sess, *init_sess = NULL;
|
|
- struct se_node_acl *acl;
|
|
+ LIST_HEAD(sess_list);
|
|
+ struct se_portal_group *tpg = acl->se_tpg;
|
|
+ struct se_session *sess, *sess_tmp;
|
|
unsigned long flags;
|
|
- int dynamic_acl = 0;
|
|
-
|
|
- mutex_lock(&tpg->acl_node_mutex);
|
|
- acl = __core_tpg_get_initiator_node_acl(tpg, initiatorname);
|
|
- if (!acl) {
|
|
- pr_err("Access Control List entry for %s Initiator"
|
|
- " Node %s does not exists for TPG %hu, ignoring"
|
|
- " request.\n", tpg->se_tpg_tfo->get_fabric_name(),
|
|
- initiatorname, tpg->se_tpg_tfo->tpg_get_tag(tpg));
|
|
- mutex_unlock(&tpg->acl_node_mutex);
|
|
- return -ENODEV;
|
|
- }
|
|
- if (acl->dynamic_node_acl) {
|
|
- acl->dynamic_node_acl = 0;
|
|
- dynamic_acl = 1;
|
|
- }
|
|
- mutex_unlock(&tpg->acl_node_mutex);
|
|
-
|
|
- spin_lock_irqsave(&tpg->session_lock, flags);
|
|
- list_for_each_entry(sess, &tpg->tpg_sess_list, sess_list) {
|
|
- if (sess->se_node_acl != acl)
|
|
- continue;
|
|
-
|
|
- if (!force) {
|
|
- pr_err("Unable to change queue depth for %s"
|
|
- " Initiator Node: %s while session is"
|
|
- " operational. To forcefully change the queue"
|
|
- " depth and force session reinstatement"
|
|
- " use the \"force=1\" parameter.\n",
|
|
- tpg->se_tpg_tfo->get_fabric_name(), initiatorname);
|
|
- spin_unlock_irqrestore(&tpg->session_lock, flags);
|
|
-
|
|
- mutex_lock(&tpg->acl_node_mutex);
|
|
- if (dynamic_acl)
|
|
- acl->dynamic_node_acl = 1;
|
|
- mutex_unlock(&tpg->acl_node_mutex);
|
|
- return -EEXIST;
|
|
- }
|
|
- /*
|
|
- * Determine if the session needs to be closed by our context.
|
|
- */
|
|
- if (!tpg->se_tpg_tfo->shutdown_session(sess))
|
|
- continue;
|
|
-
|
|
- init_sess = sess;
|
|
- break;
|
|
- }
|
|
+ int rc;
|
|
|
|
/*
|
|
* User has requested to change the queue depth for a Initiator Node.
|
|
* Change the value in the Node's struct se_node_acl, and call
|
|
- * core_set_queue_depth_for_node() to add the requested queue depth.
|
|
- *
|
|
- * Finally call tpg->se_tpg_tfo->close_session() to force session
|
|
- * reinstatement to occur if there is an active session for the
|
|
- * $FABRIC_MOD Initiator Node in question.
|
|
+ * target_set_nacl_queue_depth() to set the new queue depth.
|
|
*/
|
|
- acl->queue_depth = queue_depth;
|
|
+ target_set_nacl_queue_depth(tpg, acl, queue_depth);
|
|
+
|
|
+ spin_lock_irqsave(&acl->nacl_sess_lock, flags);
|
|
+ list_for_each_entry_safe(sess, sess_tmp, &acl->acl_sess_list,
|
|
+ sess_acl_list) {
|
|
+ if (sess->sess_tearing_down != 0)
|
|
+ continue;
|
|
+ if (!target_get_session(sess))
|
|
+ continue;
|
|
+ spin_unlock_irqrestore(&acl->nacl_sess_lock, flags);
|
|
|
|
- if (core_set_queue_depth_for_node(tpg, acl) < 0) {
|
|
- spin_unlock_irqrestore(&tpg->session_lock, flags);
|
|
/*
|
|
- * Force session reinstatement if
|
|
- * core_set_queue_depth_for_node() failed, because we assume
|
|
- * the $FABRIC_MOD has already the set session reinstatement
|
|
- * bit from tpg->se_tpg_tfo->shutdown_session() called above.
|
|
+ * Finally call tpg->se_tpg_tfo->close_session() to force session
|
|
+ * reinstatement to occur if there is an active session for the
|
|
+ * $FABRIC_MOD Initiator Node in question.
|
|
*/
|
|
- if (init_sess)
|
|
- tpg->se_tpg_tfo->close_session(init_sess);
|
|
-
|
|
- mutex_lock(&tpg->acl_node_mutex);
|
|
- if (dynamic_acl)
|
|
- acl->dynamic_node_acl = 1;
|
|
- mutex_unlock(&tpg->acl_node_mutex);
|
|
- return -EINVAL;
|
|
+ rc = tpg->se_tpg_tfo->shutdown_session(sess);
|
|
+ target_put_session(sess);
|
|
+ if (!rc) {
|
|
+ spin_lock_irqsave(&acl->nacl_sess_lock, flags);
|
|
+ continue;
|
|
+ }
|
|
+ target_put_session(sess);
|
|
+ spin_lock_irqsave(&acl->nacl_sess_lock, flags);
|
|
}
|
|
- spin_unlock_irqrestore(&tpg->session_lock, flags);
|
|
- /*
|
|
- * If the $FABRIC_MOD session for the Initiator Node ACL exists,
|
|
- * forcefully shutdown the $FABRIC_MOD session/nexus.
|
|
- */
|
|
- if (init_sess)
|
|
- tpg->se_tpg_tfo->close_session(init_sess);
|
|
+ spin_unlock_irqrestore(&acl->nacl_sess_lock, flags);
|
|
|
|
pr_debug("Successfully changed queue depth to: %d for Initiator"
|
|
- " Node: %s on %s Target Portal Group: %u\n", queue_depth,
|
|
- initiatorname, tpg->se_tpg_tfo->get_fabric_name(),
|
|
+ " Node: %s on %s Target Portal Group: %u\n", acl->queue_depth,
|
|
+ acl->initiatorname, tpg->se_tpg_tfo->get_fabric_name(),
|
|
tpg->se_tpg_tfo->tpg_get_tag(tpg));
|
|
|
|
- mutex_lock(&tpg->acl_node_mutex);
|
|
- if (dynamic_acl)
|
|
- acl->dynamic_node_acl = 1;
|
|
- mutex_unlock(&tpg->acl_node_mutex);
|
|
-
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(core_tpg_set_initiator_node_queue_depth);
|
|
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
|
|
index df2059984e14..af301414a9f3 100644
|
|
--- a/drivers/target/target_core_transport.c
|
|
+++ b/drivers/target/target_core_transport.c
|
|
@@ -383,9 +383,9 @@ static void target_release_session(struct kref *kref)
|
|
se_tpg->se_tpg_tfo->close_session(se_sess);
|
|
}
|
|
|
|
-void target_get_session(struct se_session *se_sess)
|
|
+int target_get_session(struct se_session *se_sess)
|
|
{
|
|
- kref_get(&se_sess->sess_kref);
|
|
+ return kref_get_unless_zero(&se_sess->sess_kref);
|
|
}
|
|
EXPORT_SYMBOL(target_get_session);
|
|
|
|
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
|
|
index 807d80145686..96aa0ad32497 100644
|
|
--- a/drivers/tty/pty.c
|
|
+++ b/drivers/tty/pty.c
|
|
@@ -216,16 +216,11 @@ static int pty_signal(struct tty_struct *tty, int sig)
|
|
static void pty_flush_buffer(struct tty_struct *tty)
|
|
{
|
|
struct tty_struct *to = tty->link;
|
|
- struct tty_ldisc *ld;
|
|
|
|
if (!to)
|
|
return;
|
|
|
|
- ld = tty_ldisc_ref(to);
|
|
- tty_buffer_flush(to, ld);
|
|
- if (ld)
|
|
- tty_ldisc_deref(ld);
|
|
-
|
|
+ tty_buffer_flush(to, NULL);
|
|
if (to->packet) {
|
|
spin_lock_irq(&tty->ctrl_lock);
|
|
tty->ctrl_status |= TIOCPKT_FLUSHWRITE;
|
|
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
|
|
index 24280d9a05e9..de1c143b475f 100644
|
|
--- a/drivers/tty/serial/omap-serial.c
|
|
+++ b/drivers/tty/serial/omap-serial.c
|
|
@@ -1712,7 +1712,8 @@ static int serial_omap_probe(struct platform_device *pdev)
|
|
return 0;
|
|
|
|
err_add_port:
|
|
- pm_runtime_put(&pdev->dev);
|
|
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
|
|
+ pm_runtime_put_sync(&pdev->dev);
|
|
pm_runtime_disable(&pdev->dev);
|
|
pm_qos_remove_request(&up->pm_qos_request);
|
|
device_init_wakeup(up->dev, false);
|
|
@@ -1725,9 +1726,13 @@ static int serial_omap_remove(struct platform_device *dev)
|
|
{
|
|
struct uart_omap_port *up = platform_get_drvdata(dev);
|
|
|
|
+ pm_runtime_get_sync(up->dev);
|
|
+
|
|
+ uart_remove_one_port(&serial_omap_reg, &up->port);
|
|
+
|
|
+ pm_runtime_dont_use_autosuspend(up->dev);
|
|
pm_runtime_put_sync(up->dev);
|
|
pm_runtime_disable(up->dev);
|
|
- uart_remove_one_port(&serial_omap_reg, &up->port);
|
|
pm_qos_remove_request(&up->pm_qos_request);
|
|
device_init_wakeup(&dev->dev, false);
|
|
|
|
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
|
|
index 6deb06147202..e6bc1a6be4a4 100644
|
|
--- a/drivers/tty/serial/samsung.c
|
|
+++ b/drivers/tty/serial/samsung.c
|
|
@@ -900,14 +900,13 @@ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
|
|
return -ENOMEM;
|
|
}
|
|
|
|
- dma->rx_addr = dma_map_single(dma->rx_chan->device->dev, dma->rx_buf,
|
|
+ dma->rx_addr = dma_map_single(p->port.dev, dma->rx_buf,
|
|
dma->rx_size, DMA_FROM_DEVICE);
|
|
|
|
spin_lock_irqsave(&p->port.lock, flags);
|
|
|
|
/* TX buffer */
|
|
- dma->tx_addr = dma_map_single(dma->tx_chan->device->dev,
|
|
- p->port.state->xmit.buf,
|
|
+ dma->tx_addr = dma_map_single(p->port.dev, p->port.state->xmit.buf,
|
|
UART_XMIT_SIZE, DMA_TO_DEVICE);
|
|
|
|
spin_unlock_irqrestore(&p->port.lock, flags);
|
|
@@ -921,7 +920,7 @@ static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p)
|
|
|
|
if (dma->rx_chan) {
|
|
dmaengine_terminate_all(dma->rx_chan);
|
|
- dma_unmap_single(dma->rx_chan->device->dev, dma->rx_addr,
|
|
+ dma_unmap_single(p->port.dev, dma->rx_addr,
|
|
dma->rx_size, DMA_FROM_DEVICE);
|
|
kfree(dma->rx_buf);
|
|
dma_release_channel(dma->rx_chan);
|
|
@@ -930,7 +929,7 @@ static void s3c24xx_serial_release_dma(struct s3c24xx_uart_port *p)
|
|
|
|
if (dma->tx_chan) {
|
|
dmaengine_terminate_all(dma->tx_chan);
|
|
- dma_unmap_single(dma->tx_chan->device->dev, dma->tx_addr,
|
|
+ dma_unmap_single(p->port.dev, dma->tx_addr,
|
|
UART_XMIT_SIZE, DMA_TO_DEVICE);
|
|
dma_release_channel(dma->tx_chan);
|
|
dma->tx_chan = NULL;
|
|
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
|
|
index dadd1e8dfe09..0bb380a9fcf7 100644
|
|
--- a/drivers/usb/core/driver.c
|
|
+++ b/drivers/usb/core/driver.c
|
|
@@ -1328,6 +1328,24 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
|
|
*/
|
|
if (udev->parent && !PMSG_IS_AUTO(msg))
|
|
status = 0;
|
|
+
|
|
+ /*
|
|
+ * If the device is inaccessible, don't try to resume
|
|
+ * suspended interfaces and just return the error.
|
|
+ */
|
|
+ if (status && status != -EBUSY) {
|
|
+ int err;
|
|
+ u16 devstat;
|
|
+
|
|
+ err = usb_get_status(udev, USB_RECIP_DEVICE, 0,
|
|
+ &devstat);
|
|
+ if (err) {
|
|
+ dev_err(&udev->dev,
|
|
+ "Failed to suspend device, error %d\n",
|
|
+ status);
|
|
+ goto done;
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
/* If the suspend failed, resume interfaces that did get suspended */
|
|
@@ -1760,6 +1778,9 @@ static int autosuspend_check(struct usb_device *udev)
|
|
int w, i;
|
|
struct usb_interface *intf;
|
|
|
|
+ if (udev->state == USB_STATE_NOTATTACHED)
|
|
+ return -ENODEV;
|
|
+
|
|
/* Fail if autosuspend is disabled, or any interfaces are in use, or
|
|
* any interface drivers require remote wakeup but it isn't available.
|
|
*/
|
|
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
|
|
index ea337a718cc1..b3de806085f0 100644
|
|
--- a/drivers/usb/core/file.c
|
|
+++ b/drivers/usb/core/file.c
|
|
@@ -26,6 +26,7 @@
|
|
#define MAX_USB_MINORS 256
|
|
static const struct file_operations *usb_minors[MAX_USB_MINORS];
|
|
static DECLARE_RWSEM(minor_rwsem);
|
|
+static DEFINE_MUTEX(init_usb_class_mutex);
|
|
|
|
static int usb_open(struct inode *inode, struct file *file)
|
|
{
|
|
@@ -108,8 +109,9 @@ static void release_usb_class(struct kref *kref)
|
|
|
|
static void destroy_usb_class(void)
|
|
{
|
|
- if (usb_class)
|
|
- kref_put(&usb_class->kref, release_usb_class);
|
|
+ mutex_lock(&init_usb_class_mutex);
|
|
+ kref_put(&usb_class->kref, release_usb_class);
|
|
+ mutex_unlock(&init_usb_class_mutex);
|
|
}
|
|
|
|
int usb_major_init(void)
|
|
@@ -171,7 +173,10 @@ int usb_register_dev(struct usb_interface *intf,
|
|
if (intf->minor >= 0)
|
|
return -EADDRINUSE;
|
|
|
|
+ mutex_lock(&init_usb_class_mutex);
|
|
retval = init_usb_class();
|
|
+ mutex_unlock(&init_usb_class_mutex);
|
|
+
|
|
if (retval)
|
|
return retval;
|
|
|
|
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
|
|
index 7c2d87befb51..67961231cbbd 100644
|
|
--- a/drivers/usb/core/hub.c
|
|
+++ b/drivers/usb/core/hub.c
|
|
@@ -1048,6 +1048,9 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
|
|
|
|
portstatus = portchange = 0;
|
|
status = hub_port_status(hub, port1, &portstatus, &portchange);
|
|
+ if (status)
|
|
+ goto abort;
|
|
+
|
|
if (udev || (portstatus & USB_PORT_STAT_CONNECTION))
|
|
dev_dbg(&port_dev->dev, "status %04x change %04x\n",
|
|
portstatus, portchange);
|
|
@@ -1180,7 +1183,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
|
|
|
|
/* Scan all ports that need attention */
|
|
kick_hub_wq(hub);
|
|
-
|
|
+ abort:
|
|
if (type == HUB_INIT2 || type == HUB_INIT3) {
|
|
/* Allow autosuspend if it was suppressed */
|
|
disconnected:
|
|
@@ -2068,6 +2071,12 @@ void usb_disconnect(struct usb_device **pdev)
|
|
dev_info(&udev->dev, "USB disconnect, device number %d\n",
|
|
udev->devnum);
|
|
|
|
+ /*
|
|
+ * Ensure that the pm runtime code knows that the USB device
|
|
+ * is in the process of being disconnected.
|
|
+ */
|
|
+ pm_runtime_barrier(&udev->dev);
|
|
+
|
|
usb_lock_device(udev);
|
|
|
|
hub_disconnect_children(udev);
|
|
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
|
|
index 998a738e6359..5d70d46239bb 100644
|
|
--- a/drivers/usb/host/xhci-mem.c
|
|
+++ b/drivers/usb/host/xhci-mem.c
|
|
@@ -2493,7 +2493,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
|
|
(xhci->cmd_ring->first_seg->dma & (u64) ~CMD_RING_RSVD_BITS) |
|
|
xhci->cmd_ring->cycle_state;
|
|
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
|
|
- "// Setting command ring address to 0x%x", val);
|
|
+ "// Setting command ring address to 0x%016llx", val_64);
|
|
xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring);
|
|
xhci_dbg_cmd_ptrs(xhci);
|
|
|
|
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
|
|
index 1624b09d9748..2e947dc94e32 100644
|
|
--- a/drivers/usb/misc/usbtest.c
|
|
+++ b/drivers/usb/misc/usbtest.c
|
|
@@ -135,6 +135,7 @@ get_endpoints(struct usbtest_dev *dev, struct usb_interface *intf)
|
|
case USB_ENDPOINT_XFER_INT:
|
|
if (dev->info->intr)
|
|
goto try_intr;
|
|
+ continue;
|
|
case USB_ENDPOINT_XFER_ISOC:
|
|
if (dev->info->iso)
|
|
goto try_iso;
|
|
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
|
|
index b3a21fcbbaf9..dbd441c1c2ad 100644
|
|
--- a/drivers/usb/serial/ftdi_sio.c
|
|
+++ b/drivers/usb/serial/ftdi_sio.c
|
|
@@ -873,6 +873,7 @@ static const struct usb_device_id id_table_combined[] = {
|
|
{ USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID,
|
|
USB_CLASS_VENDOR_SPEC,
|
|
USB_SUBCLASS_VENDOR_SPEC, 0x00) },
|
|
+ { USB_DEVICE_INTERFACE_NUMBER(ACTEL_VID, MICROSEMI_ARROW_SF2PLUS_BOARD_PID, 2) },
|
|
{ USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
|
|
{ USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),
|
|
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
|
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
|
|
index 48ee04c94a75..71fb9e59db71 100644
|
|
--- a/drivers/usb/serial/ftdi_sio_ids.h
|
|
+++ b/drivers/usb/serial/ftdi_sio_ids.h
|
|
@@ -873,6 +873,12 @@
|
|
#define FIC_VID 0x1457
|
|
#define FIC_NEO1973_DEBUG_PID 0x5118
|
|
|
|
+/*
|
|
+ * Actel / Microsemi
|
|
+ */
|
|
+#define ACTEL_VID 0x1514
|
|
+#define MICROSEMI_ARROW_SF2PLUS_BOARD_PID 0x2008
|
|
+
|
|
/* Olimex */
|
|
#define OLIMEX_VID 0x15BA
|
|
#define OLIMEX_ARM_USB_OCD_PID 0x0003
|
|
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
|
|
index ecb826eefe02..2fa280671c1e 100644
|
|
--- a/drivers/vfio/vfio_iommu_type1.c
|
|
+++ b/drivers/vfio/vfio_iommu_type1.c
|
|
@@ -130,57 +130,34 @@ static void vfio_unlink_dma(struct vfio_iommu *iommu, struct vfio_dma *old)
|
|
rb_erase(&old->node, &iommu->dma_list);
|
|
}
|
|
|
|
-struct vwork {
|
|
- struct mm_struct *mm;
|
|
- long npage;
|
|
- struct work_struct work;
|
|
-};
|
|
-
|
|
-/* delayed decrement/increment for locked_vm */
|
|
-static void vfio_lock_acct_bg(struct work_struct *work)
|
|
+static int vfio_lock_acct(long npage, bool *lock_cap)
|
|
{
|
|
- struct vwork *vwork = container_of(work, struct vwork, work);
|
|
- struct mm_struct *mm;
|
|
-
|
|
- mm = vwork->mm;
|
|
- down_write(&mm->mmap_sem);
|
|
- mm->locked_vm += vwork->npage;
|
|
- up_write(&mm->mmap_sem);
|
|
- mmput(mm);
|
|
- kfree(vwork);
|
|
-}
|
|
+ int ret = 0;
|
|
|
|
-static void vfio_lock_acct(long npage)
|
|
-{
|
|
- struct vwork *vwork;
|
|
- struct mm_struct *mm;
|
|
+ if (!npage)
|
|
+ return 0;
|
|
|
|
- if (!current->mm || !npage)
|
|
- return; /* process exited or nothing to do */
|
|
+ if (!current->mm)
|
|
+ return -ESRCH; /* process exited */
|
|
|
|
- if (down_write_trylock(¤t->mm->mmap_sem)) {
|
|
- current->mm->locked_vm += npage;
|
|
- up_write(¤t->mm->mmap_sem);
|
|
- return;
|
|
- }
|
|
+ down_write(¤t->mm->mmap_sem);
|
|
+ if (npage > 0) {
|
|
+ if (lock_cap ? !*lock_cap : !capable(CAP_IPC_LOCK)) {
|
|
+ unsigned long limit;
|
|
|
|
- /*
|
|
- * Couldn't get mmap_sem lock, so must setup to update
|
|
- * mm->locked_vm later. If locked_vm were atomic, we
|
|
- * wouldn't need this silliness
|
|
- */
|
|
- vwork = kmalloc(sizeof(struct vwork), GFP_KERNEL);
|
|
- if (!vwork)
|
|
- return;
|
|
- mm = get_task_mm(current);
|
|
- if (!mm) {
|
|
- kfree(vwork);
|
|
- return;
|
|
+ limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
|
|
+
|
|
+ if (current->mm->locked_vm + npage > limit)
|
|
+ ret = -ENOMEM;
|
|
+ }
|
|
}
|
|
- INIT_WORK(&vwork->work, vfio_lock_acct_bg);
|
|
- vwork->mm = mm;
|
|
- vwork->npage = npage;
|
|
- schedule_work(&vwork->work);
|
|
+
|
|
+ if (!ret)
|
|
+ current->mm->locked_vm += npage;
|
|
+
|
|
+ up_write(¤t->mm->mmap_sem);
|
|
+
|
|
+ return ret;
|
|
}
|
|
|
|
/*
|
|
@@ -262,9 +239,9 @@ static int vaddr_get_pfn(unsigned long vaddr, int prot, unsigned long *pfn)
|
|
static long vfio_pin_pages(unsigned long vaddr, long npage,
|
|
int prot, unsigned long *pfn_base)
|
|
{
|
|
- unsigned long limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
|
|
+ unsigned long pfn = 0, limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
|
|
bool lock_cap = capable(CAP_IPC_LOCK);
|
|
- long ret, i;
|
|
+ long ret, i = 1;
|
|
bool rsvd;
|
|
|
|
if (!current->mm)
|
|
@@ -283,16 +260,11 @@ static long vfio_pin_pages(unsigned long vaddr, long npage,
|
|
return -ENOMEM;
|
|
}
|
|
|
|
- if (unlikely(disable_hugepages)) {
|
|
- if (!rsvd)
|
|
- vfio_lock_acct(1);
|
|
- return 1;
|
|
- }
|
|
+ if (unlikely(disable_hugepages))
|
|
+ goto out;
|
|
|
|
/* Lock all the consecutive pages from pfn_base */
|
|
- for (i = 1, vaddr += PAGE_SIZE; i < npage; i++, vaddr += PAGE_SIZE) {
|
|
- unsigned long pfn = 0;
|
|
-
|
|
+ for (vaddr += PAGE_SIZE; i < npage; i++, vaddr += PAGE_SIZE) {
|
|
ret = vaddr_get_pfn(vaddr, prot, &pfn);
|
|
if (ret)
|
|
break;
|
|
@@ -308,12 +280,24 @@ static long vfio_pin_pages(unsigned long vaddr, long npage,
|
|
put_pfn(pfn, prot);
|
|
pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n",
|
|
__func__, limit << PAGE_SHIFT);
|
|
- break;
|
|
+ ret = -ENOMEM;
|
|
+ goto unpin_out;
|
|
}
|
|
}
|
|
|
|
+out:
|
|
if (!rsvd)
|
|
- vfio_lock_acct(i);
|
|
+ ret = vfio_lock_acct(i, &lock_cap);
|
|
+
|
|
+unpin_out:
|
|
+ if (ret) {
|
|
+ if (!rsvd) {
|
|
+ for (pfn = *pfn_base ; i ; pfn++, i--)
|
|
+ put_pfn(pfn, prot);
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+ }
|
|
|
|
return i;
|
|
}
|
|
@@ -328,7 +312,7 @@ static long vfio_unpin_pages(unsigned long pfn, long npage,
|
|
unlocked += put_pfn(pfn++, prot);
|
|
|
|
if (do_accounting)
|
|
- vfio_lock_acct(-unlocked);
|
|
+ vfio_lock_acct(-unlocked, NULL);
|
|
|
|
return unlocked;
|
|
}
|
|
@@ -390,7 +374,7 @@ static void vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma)
|
|
cond_resched();
|
|
}
|
|
|
|
- vfio_lock_acct(-unlocked);
|
|
+ vfio_lock_acct(-unlocked, NULL);
|
|
}
|
|
|
|
static void vfio_remove_dma(struct vfio_iommu *iommu, struct vfio_dma *dma)
|
|
diff --git a/fs/block_dev.c b/fs/block_dev.c
|
|
index e5733bb537c9..26bbaaefdff4 100644
|
|
--- a/fs/block_dev.c
|
|
+++ b/fs/block_dev.c
|
|
@@ -88,12 +88,11 @@ void invalidate_bdev(struct block_device *bdev)
|
|
{
|
|
struct address_space *mapping = bdev->bd_inode->i_mapping;
|
|
|
|
- if (mapping->nrpages == 0)
|
|
- return;
|
|
-
|
|
- invalidate_bh_lrus();
|
|
- lru_add_drain_all(); /* make sure all lru add caches are flushed */
|
|
- invalidate_mapping_pages(mapping, 0, -1);
|
|
+ if (mapping->nrpages) {
|
|
+ invalidate_bh_lrus();
|
|
+ lru_add_drain_all(); /* make sure all lru add caches are flushed */
|
|
+ invalidate_mapping_pages(mapping, 0, -1);
|
|
+ }
|
|
/* 99% of the time, we don't need to flush the cleancache on the bdev.
|
|
* But, for the strange corners, lets be cautious
|
|
*/
|
|
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c
|
|
index 819163d8313b..b24275ef97f7 100644
|
|
--- a/fs/ceph/xattr.c
|
|
+++ b/fs/ceph/xattr.c
|
|
@@ -369,6 +369,7 @@ static int __set_xattr(struct ceph_inode_info *ci,
|
|
|
|
if (update_xattr) {
|
|
int err = 0;
|
|
+
|
|
if (xattr && (flags & XATTR_CREATE))
|
|
err = -EEXIST;
|
|
else if (!xattr && (flags & XATTR_REPLACE))
|
|
@@ -376,12 +377,14 @@ static int __set_xattr(struct ceph_inode_info *ci,
|
|
if (err) {
|
|
kfree(name);
|
|
kfree(val);
|
|
+ kfree(*newxattr);
|
|
return err;
|
|
}
|
|
if (update_xattr < 0) {
|
|
if (xattr)
|
|
__remove_xattr(ci, xattr);
|
|
kfree(name);
|
|
+ kfree(*newxattr);
|
|
return 0;
|
|
}
|
|
}
|
|
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
|
|
index 02b071bf3732..a0b3e7d1be48 100644
|
|
--- a/fs/cifs/cifs_unicode.c
|
|
+++ b/fs/cifs/cifs_unicode.c
|
|
@@ -83,6 +83,9 @@ convert_sfm_char(const __u16 src_char, char *target)
|
|
case SFM_COLON:
|
|
*target = ':';
|
|
break;
|
|
+ case SFM_DOUBLEQUOTE:
|
|
+ *target = '"';
|
|
+ break;
|
|
case SFM_ASTERISK:
|
|
*target = '*';
|
|
break;
|
|
@@ -418,6 +421,9 @@ static __le16 convert_to_sfm_char(char src_char, bool end_of_string)
|
|
case ':':
|
|
dest_char = cpu_to_le16(SFM_COLON);
|
|
break;
|
|
+ case '"':
|
|
+ dest_char = cpu_to_le16(SFM_DOUBLEQUOTE);
|
|
+ break;
|
|
case '*':
|
|
dest_char = cpu_to_le16(SFM_ASTERISK);
|
|
break;
|
|
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h
|
|
index 479bc0a941f3..07ade707fa60 100644
|
|
--- a/fs/cifs/cifs_unicode.h
|
|
+++ b/fs/cifs/cifs_unicode.h
|
|
@@ -57,6 +57,7 @@
|
|
* not conflict (although almost does) with the mapping above.
|
|
*/
|
|
|
|
+#define SFM_DOUBLEQUOTE ((__u16) 0xF020)
|
|
#define SFM_ASTERISK ((__u16) 0xF021)
|
|
#define SFM_QUESTION ((__u16) 0xF025)
|
|
#define SFM_COLON ((__u16) 0xF022)
|
|
@@ -64,8 +65,8 @@
|
|
#define SFM_LESSTHAN ((__u16) 0xF023)
|
|
#define SFM_PIPE ((__u16) 0xF027)
|
|
#define SFM_SLASH ((__u16) 0xF026)
|
|
-#define SFM_PERIOD ((__u16) 0xF028)
|
|
-#define SFM_SPACE ((__u16) 0xF029)
|
|
+#define SFM_SPACE ((__u16) 0xF028)
|
|
+#define SFM_PERIOD ((__u16) 0xF029)
|
|
|
|
/*
|
|
* Mapping mechanism to use when one of the seven reserved characters is
|
|
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
|
|
index 5e2f8b8ca08a..b60150e5b5ce 100644
|
|
--- a/fs/cifs/cifssmb.c
|
|
+++ b/fs/cifs/cifssmb.c
|
|
@@ -717,6 +717,9 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
|
|
if (rc)
|
|
return rc;
|
|
|
|
+ if (server->capabilities & CAP_UNICODE)
|
|
+ smb->hdr.Flags2 |= SMBFLG2_UNICODE;
|
|
+
|
|
/* set up echo request */
|
|
smb->hdr.Tid = 0xffff;
|
|
smb->hdr.WordCount = 1;
|
|
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
|
|
index 35cf990f87d3..a8f5b31636dc 100644
|
|
--- a/fs/cifs/ioctl.c
|
|
+++ b/fs/cifs/ioctl.c
|
|
@@ -272,6 +272,8 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
|
|
rc = -EOPNOTSUPP;
|
|
break;
|
|
case CIFS_IOC_GET_MNT_INFO:
|
|
+ if (pSMBFile == NULL)
|
|
+ break;
|
|
tcon = tlink_tcon(pSMBFile->tlink);
|
|
rc = smb_mnt_get_fsinfo(xid, tcon, (void __user *)arg);
|
|
break;
|
|
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
|
|
index 6cb2603f8a5c..f4afa3b1cc56 100644
|
|
--- a/fs/cifs/smb2pdu.c
|
|
+++ b/fs/cifs/smb2pdu.c
|
|
@@ -564,8 +564,12 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
|
|
}
|
|
|
|
if (rsplen != sizeof(struct validate_negotiate_info_rsp)) {
|
|
- cifs_dbg(VFS, "invalid size of protocol negotiate response\n");
|
|
- return -EIO;
|
|
+ cifs_dbg(VFS, "invalid protocol negotiate response size: %d\n",
|
|
+ rsplen);
|
|
+
|
|
+ /* relax check since Mac returns max bufsize allowed on ioctl */
|
|
+ if (rsplen > CIFSMaxBufSize)
|
|
+ return -EIO;
|
|
}
|
|
|
|
/* check validate negotiate info response matches what we got earlier */
|
|
@@ -1518,8 +1522,12 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
|
|
* than one credit. Windows typically sets this smaller, but for some
|
|
* ioctls it may be useful to allow server to send more. No point
|
|
* limiting what the server can send as long as fits in one credit
|
|
+ * Unfortunately - we can not handle more than CIFS_MAX_MSG_SIZE
|
|
+ * (by default, note that it can be overridden to make max larger)
|
|
+ * in responses (except for read responses which can be bigger.
|
|
+ * We may want to bump this limit up
|
|
*/
|
|
- req->MaxOutputResponse = cpu_to_le32(0xFF00); /* < 64K uses 1 credit */
|
|
+ req->MaxOutputResponse = cpu_to_le32(CIFSMaxBufSize);
|
|
|
|
if (is_fsctl)
|
|
req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL);
|
|
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
|
|
index 817a937de733..ccae64dad40c 100644
|
|
--- a/fs/ext4/inode.c
|
|
+++ b/fs/ext4/inode.c
|
|
@@ -5393,6 +5393,11 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|
file_update_time(vma->vm_file);
|
|
|
|
down_read(&EXT4_I(inode)->i_mmap_sem);
|
|
+
|
|
+ ret = ext4_convert_inline_data(inode);
|
|
+ if (ret)
|
|
+ goto out_ret;
|
|
+
|
|
/* Delalloc case is easy... */
|
|
if (test_opt(inode->i_sb, DELALLOC) &&
|
|
!ext4_should_journal_data(inode) &&
|
|
diff --git a/fs/xattr.c b/fs/xattr.c
|
|
index 9b932b95d74e..f0da9d24e9ca 100644
|
|
--- a/fs/xattr.c
|
|
+++ b/fs/xattr.c
|
|
@@ -442,7 +442,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
|
|
size = XATTR_SIZE_MAX;
|
|
kvalue = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
|
|
if (!kvalue) {
|
|
- vvalue = vmalloc(size);
|
|
+ vvalue = vzalloc(size);
|
|
if (!vvalue)
|
|
return -ENOMEM;
|
|
kvalue = vvalue;
|
|
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
|
|
index 760bc4d5a2cf..4e51f9a5a177 100644
|
|
--- a/include/net/mac80211.h
|
|
+++ b/include/net/mac80211.h
|
|
@@ -1662,6 +1662,9 @@ struct ieee80211_sta_rates {
|
|
* @supp_rates: Bitmap of supported rates (per band)
|
|
* @ht_cap: HT capabilities of this STA; restricted to our own capabilities
|
|
* @vht_cap: VHT capabilities of this STA; restricted to our own capabilities
|
|
+ * @max_rx_aggregation_subframes: maximal amount of frames in a single AMPDU
|
|
+ * that this station is allowed to transmit to us.
|
|
+ * Can be modified by driver.
|
|
* @wme: indicates whether the STA supports QoS/WME (if local devices does,
|
|
* otherwise always false)
|
|
* @drv_priv: data area for driver use, will always be aligned to
|
|
@@ -1688,6 +1691,7 @@ struct ieee80211_sta {
|
|
u16 aid;
|
|
struct ieee80211_sta_ht_cap ht_cap;
|
|
struct ieee80211_sta_vht_cap vht_cap;
|
|
+ u8 max_rx_aggregation_subframes;
|
|
bool wme;
|
|
u8 uapsd_queues;
|
|
u8 max_sp;
|
|
@@ -2674,6 +2678,33 @@ enum ieee80211_ampdu_mlme_action {
|
|
};
|
|
|
|
/**
|
|
+ * struct ieee80211_ampdu_params - AMPDU action parameters
|
|
+ *
|
|
+ * @action: the ampdu action, value from %ieee80211_ampdu_mlme_action.
|
|
+ * @sta: peer of this AMPDU session
|
|
+ * @tid: tid of the BA session
|
|
+ * @ssn: start sequence number of the session. TX/RX_STOP can pass 0. When
|
|
+ * action is set to %IEEE80211_AMPDU_RX_START the driver passes back the
|
|
+ * actual ssn value used to start the session and writes the value here.
|
|
+ * @buf_size: reorder buffer size (number of subframes). Valid only when the
|
|
+ * action is set to %IEEE80211_AMPDU_RX_START or
|
|
+ * %IEEE80211_AMPDU_TX_OPERATIONAL
|
|
+ * @amsdu: indicates the peer's ability to receive A-MSDU within A-MPDU.
|
|
+ * valid when the action is set to %IEEE80211_AMPDU_TX_OPERATIONAL
|
|
+ * @timeout: BA session timeout. Valid only when the action is set to
|
|
+ * %IEEE80211_AMPDU_RX_START
|
|
+ */
|
|
+struct ieee80211_ampdu_params {
|
|
+ enum ieee80211_ampdu_mlme_action action;
|
|
+ struct ieee80211_sta *sta;
|
|
+ u16 tid;
|
|
+ u16 ssn;
|
|
+ u8 buf_size;
|
|
+ bool amsdu;
|
|
+ u16 timeout;
|
|
+};
|
|
+
|
|
+/**
|
|
* enum ieee80211_frame_release_type - frame release reason
|
|
* @IEEE80211_FRAME_RELEASE_PSPOLL: frame released for PS-Poll
|
|
* @IEEE80211_FRAME_RELEASE_UAPSD: frame(s) released due to
|
|
@@ -3017,13 +3048,9 @@ enum ieee80211_reconfig_type {
|
|
* @ampdu_action: Perform a certain A-MPDU action
|
|
* The RA/TID combination determines the destination and TID we want
|
|
* the ampdu action to be performed for. The action is defined through
|
|
- * ieee80211_ampdu_mlme_action. Starting sequence number (@ssn)
|
|
- * is the first frame we expect to perform the action on. Notice
|
|
- * that TX/RX_STOP can pass NULL for this parameter.
|
|
- * The @buf_size parameter is only valid when the action is set to
|
|
- * %IEEE80211_AMPDU_TX_OPERATIONAL and indicates the peer's reorder
|
|
- * buffer size (number of subframes) for this session -- the driver
|
|
- * may neither send aggregates containing more subframes than this
|
|
+ * ieee80211_ampdu_mlme_action.
|
|
+ * When the action is set to %IEEE80211_AMPDU_TX_OPERATIONAL the driver
|
|
+ * may neither send aggregates containing more subframes than @buf_size
|
|
* nor send aggregates in a way that lost frames would exceed the
|
|
* buffer size. If just limiting the aggregate size, this would be
|
|
* possible with a buf_size of 8:
|
|
@@ -3034,9 +3061,6 @@ enum ieee80211_reconfig_type {
|
|
* buffer size of 8. Correct ways to retransmit #1 would be:
|
|
* - TX: 1 or 18 or 81
|
|
* Even "189" would be wrong since 1 could be lost again.
|
|
- * The @amsdu parameter is valid when the action is set to
|
|
- * %IEEE80211_AMPDU_TX_OPERATIONAL and indicates the peer's ability
|
|
- * to receive A-MSDU within A-MPDU.
|
|
*
|
|
* Returns a negative error code on failure.
|
|
* The callback can sleep.
|
|
@@ -3378,9 +3402,7 @@ struct ieee80211_ops {
|
|
int (*tx_last_beacon)(struct ieee80211_hw *hw);
|
|
int (*ampdu_action)(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
|
- u8 buf_size, bool amsdu);
|
|
+ struct ieee80211_ampdu_params *params);
|
|
int (*get_survey)(struct ieee80211_hw *hw, int idx,
|
|
struct survey_info *survey);
|
|
void (*rfkill_poll)(struct ieee80211_hw *hw);
|
|
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
|
|
index 97069ecabe49..5f9b62c129fc 100644
|
|
--- a/include/target/target_core_fabric.h
|
|
+++ b/include/target/target_core_fabric.h
|
|
@@ -117,7 +117,7 @@ void __transport_register_session(struct se_portal_group *,
|
|
struct se_node_acl *, struct se_session *, void *);
|
|
void transport_register_session(struct se_portal_group *,
|
|
struct se_node_acl *, struct se_session *, void *);
|
|
-void target_get_session(struct se_session *);
|
|
+int target_get_session(struct se_session *);
|
|
void target_put_session(struct se_session *);
|
|
ssize_t target_show_dynamic_sessions(struct se_portal_group *, char *);
|
|
void transport_free_session(struct se_session *);
|
|
@@ -172,8 +172,7 @@ bool target_tpg_has_node_acl(struct se_portal_group *tpg,
|
|
const char *);
|
|
struct se_node_acl *core_tpg_check_initiator_node_acl(struct se_portal_group *,
|
|
unsigned char *);
|
|
-int core_tpg_set_initiator_node_queue_depth(struct se_portal_group *,
|
|
- unsigned char *, u32, int);
|
|
+int core_tpg_set_initiator_node_queue_depth(struct se_node_acl *, u32);
|
|
int core_tpg_set_initiator_node_tag(struct se_portal_group *,
|
|
struct se_node_acl *, const char *);
|
|
int core_tpg_register(struct se_wwn *, struct se_portal_group *, int);
|
|
diff --git a/kernel/padata.c b/kernel/padata.c
|
|
index 401227e3967c..ecc7b3f452c7 100644
|
|
--- a/kernel/padata.c
|
|
+++ b/kernel/padata.c
|
|
@@ -357,7 +357,7 @@ static int padata_setup_cpumasks(struct parallel_data *pd,
|
|
|
|
cpumask_and(pd->cpumask.pcpu, pcpumask, cpu_online_mask);
|
|
if (!alloc_cpumask_var(&pd->cpumask.cbcpu, GFP_KERNEL)) {
|
|
- free_cpumask_var(pd->cpumask.cbcpu);
|
|
+ free_cpumask_var(pd->cpumask.pcpu);
|
|
return -ENOMEM;
|
|
}
|
|
|
|
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
|
|
index b1eb8c09a660..c842f40c1173 100644
|
|
--- a/net/bluetooth/hci_sock.c
|
|
+++ b/net/bluetooth/hci_sock.c
|
|
@@ -1164,7 +1164,8 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
|
|
if (msg->msg_flags & MSG_OOB)
|
|
return -EOPNOTSUPP;
|
|
|
|
- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
|
|
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE|
|
|
+ MSG_CMSG_COMPAT))
|
|
return -EINVAL;
|
|
|
|
if (len < 4 || len > HCI_MAX_FRAME_SIZE)
|
|
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
|
|
index 367784be5df2..a830356b94ac 100644
|
|
--- a/net/mac80211/agg-rx.c
|
|
+++ b/net/mac80211/agg-rx.c
|
|
@@ -7,6 +7,7 @@
|
|
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
|
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
|
|
* Copyright 2007-2010, Intel Corporation
|
|
+ * Copyright(c) 2015 Intel Deutschland GmbH
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
@@ -61,6 +62,14 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
|
|
{
|
|
struct ieee80211_local *local = sta->local;
|
|
struct tid_ampdu_rx *tid_rx;
|
|
+ struct ieee80211_ampdu_params params = {
|
|
+ .sta = &sta->sta,
|
|
+ .action = IEEE80211_AMPDU_RX_STOP,
|
|
+ .tid = tid,
|
|
+ .amsdu = false,
|
|
+ .timeout = 0,
|
|
+ .ssn = 0,
|
|
+ };
|
|
|
|
lockdep_assert_held(&sta->ampdu_mlme.mtx);
|
|
|
|
@@ -78,8 +87,7 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
|
|
initiator == WLAN_BACK_RECIPIENT ? "recipient" : "inititator",
|
|
(int)reason);
|
|
|
|
- if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP,
|
|
- &sta->sta, tid, NULL, 0, false))
|
|
+ if (drv_ampdu_action(local, sta->sdata, ¶ms))
|
|
sdata_info(sta->sdata,
|
|
"HW problem - can not stop rx aggregation for %pM tid %d\n",
|
|
sta->sta.addr, tid);
|
|
@@ -237,6 +245,15 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
|
{
|
|
struct ieee80211_local *local = sta->sdata->local;
|
|
struct tid_ampdu_rx *tid_agg_rx;
|
|
+ struct ieee80211_ampdu_params params = {
|
|
+ .sta = &sta->sta,
|
|
+ .action = IEEE80211_AMPDU_RX_START,
|
|
+ .tid = tid,
|
|
+ .amsdu = false,
|
|
+ .timeout = timeout,
|
|
+ .ssn = start_seq_num,
|
|
+ };
|
|
+
|
|
int i, ret = -EOPNOTSUPP;
|
|
u16 status = WLAN_STATUS_REQUEST_DECLINED;
|
|
|
|
@@ -273,8 +290,12 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
|
buf_size = IEEE80211_MAX_AMPDU_BUF;
|
|
|
|
/* make sure the size doesn't exceed the maximum supported by the hw */
|
|
- if (buf_size > local->hw.max_rx_aggregation_subframes)
|
|
- buf_size = local->hw.max_rx_aggregation_subframes;
|
|
+ if (buf_size > sta->sta.max_rx_aggregation_subframes)
|
|
+ buf_size = sta->sta.max_rx_aggregation_subframes;
|
|
+ params.buf_size = buf_size;
|
|
+
|
|
+ ht_dbg(sta->sdata, "AddBA Req buf_size=%d for %pM\n",
|
|
+ buf_size, sta->sta.addr);
|
|
|
|
/* examine state machine */
|
|
mutex_lock(&sta->ampdu_mlme.mtx);
|
|
@@ -322,8 +343,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta,
|
|
for (i = 0; i < buf_size; i++)
|
|
__skb_queue_head_init(&tid_agg_rx->reorder_buf[i]);
|
|
|
|
- ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START,
|
|
- &sta->sta, tid, &start_seq_num, 0, false);
|
|
+ ret = drv_ampdu_action(local, sta->sdata, ¶ms);
|
|
ht_dbg(sta->sdata, "Rx A-MPDU request on %pM tid %d result %d\n",
|
|
sta->sta.addr, tid, ret);
|
|
if (ret) {
|
|
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
|
|
index ff757181b0a8..4932e9f243a2 100644
|
|
--- a/net/mac80211/agg-tx.c
|
|
+++ b/net/mac80211/agg-tx.c
|
|
@@ -7,6 +7,7 @@
|
|
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
|
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
|
|
* Copyright 2007-2010, Intel Corporation
|
|
+ * Copyright(c) 2015 Intel Deutschland GmbH
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
@@ -295,7 +296,14 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
|
|
{
|
|
struct ieee80211_local *local = sta->local;
|
|
struct tid_ampdu_tx *tid_tx;
|
|
- enum ieee80211_ampdu_mlme_action action;
|
|
+ struct ieee80211_ampdu_params params = {
|
|
+ .sta = &sta->sta,
|
|
+ .tid = tid,
|
|
+ .buf_size = 0,
|
|
+ .amsdu = false,
|
|
+ .timeout = 0,
|
|
+ .ssn = 0,
|
|
+ };
|
|
int ret;
|
|
|
|
lockdep_assert_held(&sta->ampdu_mlme.mtx);
|
|
@@ -304,10 +312,10 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
|
|
case AGG_STOP_DECLINED:
|
|
case AGG_STOP_LOCAL_REQUEST:
|
|
case AGG_STOP_PEER_REQUEST:
|
|
- action = IEEE80211_AMPDU_TX_STOP_CONT;
|
|
+ params.action = IEEE80211_AMPDU_TX_STOP_CONT;
|
|
break;
|
|
case AGG_STOP_DESTROY_STA:
|
|
- action = IEEE80211_AMPDU_TX_STOP_FLUSH;
|
|
+ params.action = IEEE80211_AMPDU_TX_STOP_FLUSH;
|
|
break;
|
|
default:
|
|
WARN_ON_ONCE(1);
|
|
@@ -330,9 +338,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
|
|
spin_unlock_bh(&sta->lock);
|
|
if (reason != AGG_STOP_DESTROY_STA)
|
|
return -EALREADY;
|
|
- ret = drv_ampdu_action(local, sta->sdata,
|
|
- IEEE80211_AMPDU_TX_STOP_FLUSH_CONT,
|
|
- &sta->sta, tid, NULL, 0, false);
|
|
+ params.action = IEEE80211_AMPDU_TX_STOP_FLUSH_CONT;
|
|
+ ret = drv_ampdu_action(local, sta->sdata, ¶ms);
|
|
WARN_ON_ONCE(ret);
|
|
return 0;
|
|
}
|
|
@@ -381,8 +388,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
|
|
WLAN_BACK_INITIATOR;
|
|
tid_tx->tx_stop = reason == AGG_STOP_LOCAL_REQUEST;
|
|
|
|
- ret = drv_ampdu_action(local, sta->sdata, action,
|
|
- &sta->sta, tid, NULL, 0, false);
|
|
+ ret = drv_ampdu_action(local, sta->sdata, ¶ms);
|
|
|
|
/* HW shall not deny going back to legacy */
|
|
if (WARN_ON(ret)) {
|
|
@@ -445,7 +451,14 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
|
|
struct tid_ampdu_tx *tid_tx;
|
|
struct ieee80211_local *local = sta->local;
|
|
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
|
- u16 start_seq_num;
|
|
+ struct ieee80211_ampdu_params params = {
|
|
+ .sta = &sta->sta,
|
|
+ .action = IEEE80211_AMPDU_TX_START,
|
|
+ .tid = tid,
|
|
+ .buf_size = 0,
|
|
+ .amsdu = false,
|
|
+ .timeout = 0,
|
|
+ };
|
|
int ret;
|
|
|
|
tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
|
|
@@ -467,10 +480,8 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
|
|
*/
|
|
synchronize_net();
|
|
|
|
- start_seq_num = sta->tid_seq[tid] >> 4;
|
|
-
|
|
- ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START,
|
|
- &sta->sta, tid, &start_seq_num, 0, false);
|
|
+ params.ssn = sta->tid_seq[tid] >> 4;
|
|
+ ret = drv_ampdu_action(local, sdata, ¶ms);
|
|
if (ret) {
|
|
ht_dbg(sdata,
|
|
"BA request denied - HW unavailable for %pM tid %d\n",
|
|
@@ -499,7 +510,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
|
|
|
|
/* send AddBA request */
|
|
ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
|
|
- tid_tx->dialog_token, start_seq_num,
|
|
+ tid_tx->dialog_token, params.ssn,
|
|
IEEE80211_MAX_AMPDU_BUF,
|
|
tid_tx->timeout);
|
|
}
|
|
@@ -684,18 +695,24 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
|
|
struct sta_info *sta, u16 tid)
|
|
{
|
|
struct tid_ampdu_tx *tid_tx;
|
|
+ struct ieee80211_ampdu_params params = {
|
|
+ .sta = &sta->sta,
|
|
+ .action = IEEE80211_AMPDU_TX_OPERATIONAL,
|
|
+ .tid = tid,
|
|
+ .timeout = 0,
|
|
+ .ssn = 0,
|
|
+ };
|
|
|
|
lockdep_assert_held(&sta->ampdu_mlme.mtx);
|
|
|
|
tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
|
|
+ params.buf_size = tid_tx->buf_size;
|
|
+ params.amsdu = tid_tx->amsdu;
|
|
|
|
ht_dbg(sta->sdata, "Aggregation is on for %pM tid %d\n",
|
|
sta->sta.addr, tid);
|
|
|
|
- drv_ampdu_action(local, sta->sdata,
|
|
- IEEE80211_AMPDU_TX_OPERATIONAL,
|
|
- &sta->sta, tid, NULL, tid_tx->buf_size,
|
|
- tid_tx->amsdu);
|
|
+ drv_ampdu_action(local, sta->sdata, ¶ms);
|
|
|
|
/*
|
|
* synchronize with TX path, while splicing the TX path
|
|
diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c
|
|
index ca1fe5576103..c258f1041d33 100644
|
|
--- a/net/mac80211/driver-ops.c
|
|
+++ b/net/mac80211/driver-ops.c
|
|
@@ -284,9 +284,7 @@ int drv_switch_vif_chanctx(struct ieee80211_local *local,
|
|
|
|
int drv_ampdu_action(struct ieee80211_local *local,
|
|
struct ieee80211_sub_if_data *sdata,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid,
|
|
- u16 *ssn, u8 buf_size, bool amsdu)
|
|
+ struct ieee80211_ampdu_params *params)
|
|
{
|
|
int ret = -EOPNOTSUPP;
|
|
|
|
@@ -296,12 +294,10 @@ int drv_ampdu_action(struct ieee80211_local *local,
|
|
if (!check_sdata_in_driver(sdata))
|
|
return -EIO;
|
|
|
|
- trace_drv_ampdu_action(local, sdata, action, sta, tid,
|
|
- ssn, buf_size, amsdu);
|
|
+ trace_drv_ampdu_action(local, sdata, params);
|
|
|
|
if (local->ops->ampdu_action)
|
|
- ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
|
|
- sta, tid, ssn, buf_size, amsdu);
|
|
+ ret = local->ops->ampdu_action(&local->hw, &sdata->vif, params);
|
|
|
|
trace_drv_return_int(local, ret);
|
|
|
|
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
|
|
index 154ce4b13406..18b0d65baff0 100644
|
|
--- a/net/mac80211/driver-ops.h
|
|
+++ b/net/mac80211/driver-ops.h
|
|
@@ -585,9 +585,7 @@ static inline int drv_tx_last_beacon(struct ieee80211_local *local)
|
|
|
|
int drv_ampdu_action(struct ieee80211_local *local,
|
|
struct ieee80211_sub_if_data *sdata,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid,
|
|
- u16 *ssn, u8 buf_size, bool amsdu);
|
|
+ struct ieee80211_ampdu_params *params);
|
|
|
|
static inline int drv_get_survey(struct ieee80211_local *local, int idx,
|
|
struct survey_info *survey)
|
|
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
|
|
index 67066d048e6f..63ea6cbac5ad 100644
|
|
--- a/net/mac80211/sta_info.c
|
|
+++ b/net/mac80211/sta_info.c
|
|
@@ -329,6 +329,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
|
|
|
|
memcpy(sta->addr, addr, ETH_ALEN);
|
|
memcpy(sta->sta.addr, addr, ETH_ALEN);
|
|
+ sta->sta.max_rx_aggregation_subframes =
|
|
+ local->hw.max_rx_aggregation_subframes;
|
|
+
|
|
sta->local = local;
|
|
sta->sdata = sdata;
|
|
sta->rx_stats.last_rx = jiffies;
|
|
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
|
|
index 56c6d6cfa5a1..913e959b03cf 100644
|
|
--- a/net/mac80211/trace.h
|
|
+++ b/net/mac80211/trace.h
|
|
@@ -80,7 +80,23 @@
|
|
#define KEY_PR_FMT " cipher:0x%x, flags=%#x, keyidx=%d, hw_key_idx=%d"
|
|
#define KEY_PR_ARG __entry->cipher, __entry->flags, __entry->keyidx, __entry->hw_key_idx
|
|
|
|
-
|
|
+#define AMPDU_ACTION_ENTRY __field(enum ieee80211_ampdu_mlme_action, \
|
|
+ ieee80211_ampdu_mlme_action) \
|
|
+ STA_ENTRY \
|
|
+ __field(u16, tid) \
|
|
+ __field(u16, ssn) \
|
|
+ __field(u8, buf_size) \
|
|
+ __field(bool, amsdu) \
|
|
+ __field(u16, timeout)
|
|
+#define AMPDU_ACTION_ASSIGN STA_NAMED_ASSIGN(params->sta); \
|
|
+ __entry->tid = params->tid; \
|
|
+ __entry->ssn = params->ssn; \
|
|
+ __entry->buf_size = params->buf_size; \
|
|
+ __entry->amsdu = params->amsdu; \
|
|
+ __entry->timeout = params->timeout;
|
|
+#define AMPDU_ACTION_PR_FMT STA_PR_FMT " tid %d, ssn %d, buf_size %u, amsdu %d, timeout %d"
|
|
+#define AMPDU_ACTION_PR_ARG STA_PR_ARG, __entry->tid, __entry->ssn, \
|
|
+ __entry->buf_size, __entry->amsdu, __entry->timeout
|
|
|
|
/*
|
|
* Tracing for driver callbacks.
|
|
@@ -970,38 +986,25 @@ DEFINE_EVENT(local_only_evt, drv_tx_last_beacon,
|
|
TRACE_EVENT(drv_ampdu_action,
|
|
TP_PROTO(struct ieee80211_local *local,
|
|
struct ieee80211_sub_if_data *sdata,
|
|
- enum ieee80211_ampdu_mlme_action action,
|
|
- struct ieee80211_sta *sta, u16 tid,
|
|
- u16 *ssn, u8 buf_size, bool amsdu),
|
|
+ struct ieee80211_ampdu_params *params),
|
|
|
|
- TP_ARGS(local, sdata, action, sta, tid, ssn, buf_size, amsdu),
|
|
+ TP_ARGS(local, sdata, params),
|
|
|
|
TP_STRUCT__entry(
|
|
LOCAL_ENTRY
|
|
- STA_ENTRY
|
|
- __field(u32, action)
|
|
- __field(u16, tid)
|
|
- __field(u16, ssn)
|
|
- __field(u8, buf_size)
|
|
- __field(bool, amsdu)
|
|
VIF_ENTRY
|
|
+ AMPDU_ACTION_ENTRY
|
|
),
|
|
|
|
TP_fast_assign(
|
|
LOCAL_ASSIGN;
|
|
VIF_ASSIGN;
|
|
- STA_ASSIGN;
|
|
- __entry->action = action;
|
|
- __entry->tid = tid;
|
|
- __entry->ssn = ssn ? *ssn : 0;
|
|
- __entry->buf_size = buf_size;
|
|
- __entry->amsdu = amsdu;
|
|
+ AMPDU_ACTION_ASSIGN;
|
|
),
|
|
|
|
TP_printk(
|
|
- LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " action:%d tid:%d buf:%d amsdu:%d",
|
|
- LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->action,
|
|
- __entry->tid, __entry->buf_size, __entry->amsdu
|
|
+ LOCAL_PR_FMT VIF_PR_FMT AMPDU_ACTION_PR_FMT,
|
|
+ LOCAL_PR_ARG, VIF_PR_ARG, AMPDU_ACTION_PR_ARG
|
|
)
|
|
);
|
|
|
|
diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c
|
|
index 31a3035cd4eb..923e59eb82c7 100644
|
|
--- a/tools/testing/selftests/x86/ldt_gdt.c
|
|
+++ b/tools/testing/selftests/x86/ldt_gdt.c
|
|
@@ -394,6 +394,51 @@ static void *threadproc(void *ctx)
|
|
}
|
|
}
|
|
|
|
+#ifdef __i386__
|
|
+
|
|
+#ifndef SA_RESTORE
|
|
+#define SA_RESTORER 0x04000000
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * The UAPI header calls this 'struct sigaction', which conflicts with
|
|
+ * glibc. Sigh.
|
|
+ */
|
|
+struct fake_ksigaction {
|
|
+ void *handler; /* the real type is nasty */
|
|
+ unsigned long sa_flags;
|
|
+ void (*sa_restorer)(void);
|
|
+ unsigned char sigset[8];
|
|
+};
|
|
+
|
|
+static void fix_sa_restorer(int sig)
|
|
+{
|
|
+ struct fake_ksigaction ksa;
|
|
+
|
|
+ if (syscall(SYS_rt_sigaction, sig, NULL, &ksa, 8) == 0) {
|
|
+ /*
|
|
+ * glibc has a nasty bug: it sometimes writes garbage to
|
|
+ * sa_restorer. This interacts quite badly with anything
|
|
+ * that fiddles with SS because it can trigger legacy
|
|
+ * stack switching. Patch it up. See:
|
|
+ *
|
|
+ * https://sourceware.org/bugzilla/show_bug.cgi?id=21269
|
|
+ */
|
|
+ if (!(ksa.sa_flags & SA_RESTORER) && ksa.sa_restorer) {
|
|
+ ksa.sa_restorer = NULL;
|
|
+ if (syscall(SYS_rt_sigaction, sig, &ksa, NULL,
|
|
+ sizeof(ksa.sigset)) != 0)
|
|
+ err(1, "rt_sigaction");
|
|
+ }
|
|
+ }
|
|
+}
|
|
+#else
|
|
+static void fix_sa_restorer(int sig)
|
|
+{
|
|
+ /* 64-bit glibc works fine. */
|
|
+}
|
|
+#endif
|
|
+
|
|
static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
|
|
int flags)
|
|
{
|
|
@@ -405,6 +450,7 @@ static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
|
|
if (sigaction(sig, &sa, 0))
|
|
err(1, "sigaction");
|
|
|
|
+ fix_sa_restorer(sig);
|
|
}
|
|
|
|
static jmp_buf jmpbuf;
|