Merge tag 'v4.4.69' into linux-linaro-lsk-v4.4
authorAlex Shi <alex.shi@linaro.org>
Thu, 25 May 2017 02:05:39 +0000 (10:05 +0800)
committerAlex Shi <alex.shi@linaro.org>
Thu, 25 May 2017 02:05:39 +0000 (10:05 +0800)
 This is the 4.4.69 stable release

90 files changed:
Makefile
arch/arm/kvm/psci.c
arch/arm64/kvm/sys_regs.c
arch/x86/boot/boot.h
arch/x86/include/asm/pmem.h
arch/x86/kvm/x86.c
arch/x86/um/ptrace_64.c
arch/x86/xen/mmu.c
block/blk-integrity.c
crypto/algif_aead.c
drivers/Makefile
drivers/bluetooth/hci_bcm.c
drivers/bluetooth/hci_intel.c
drivers/char/ipmi/ipmi_ssif.c
drivers/infiniband/core/sysfs.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/mcg.c
drivers/infiniband/ulp/ipoib/ipoib_fs.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_vlan.c
drivers/md/dm-era-target.c
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/carl9170/main.c
drivers/net/wireless/ath/wcn36xx/main.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/cw1200/sta.c
drivers/net/wireless/cw1200/sta.h
drivers/net/wireless/iwlegacy/4965-mac.c
drivers/net/wireless/iwlegacy/4965.h
drivers/net/wireless/iwlwifi/dvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mediatek/mt7601u/main.c
drivers/net/wireless/mwl8k.c
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c
drivers/net/wireless/realtek/rtlwifi/core.c
drivers/net/wireless/rsi/rsi_91x_mac80211.c
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt2800lib.h
drivers/net/wireless/ti/wl18xx/event.c
drivers/net/wireless/ti/wl18xx/event.h
drivers/net/wireless/ti/wl18xx/main.c
drivers/net/wireless/ti/wlcore/acx.c
drivers/net/wireless/ti/wlcore/acx.h
drivers/net/wireless/ti/wlcore/main.c
drivers/staging/comedi/drivers/jr3_pci.c
drivers/staging/gdm724x/gdm_mux.c
drivers/staging/vt6656/usbpipe.c
drivers/target/iscsi/iscsi_target.c
drivers/target/iscsi/iscsi_target_configfs.c
drivers/target/iscsi/iscsi_target_login.c
drivers/target/iscsi/iscsi_target_tpg.c
drivers/target/iscsi/iscsi_target_tpg.h
drivers/target/target_core_file.c
drivers/target/target_core_sbc.c
drivers/target/target_core_tpg.c
drivers/target/target_core_transport.c
drivers/tty/pty.c
drivers/tty/serial/omap-serial.c
drivers/tty/serial/samsung.c
drivers/usb/core/driver.c
drivers/usb/core/file.c
drivers/usb/core/hub.c
drivers/usb/host/xhci-mem.c
drivers/usb/misc/usbtest.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/vfio/vfio_iommu_type1.c
fs/block_dev.c
fs/ceph/xattr.c
fs/cifs/cifs_unicode.c
fs/cifs/cifs_unicode.h
fs/cifs/cifssmb.c
fs/cifs/ioctl.c
fs/cifs/smb2pdu.c
fs/ext4/inode.c
fs/xattr.c
include/net/mac80211.h
include/target/target_core_fabric.h
kernel/padata.c
net/bluetooth/hci_sock.c
net/mac80211/agg-rx.c
net/mac80211/agg-tx.c
net/mac80211/driver-ops.c
net/mac80211/driver-ops.h
net/mac80211/sta_info.c
net/mac80211/trace.h
tools/testing/selftests/x86/ldt_gdt.c

index e6c7990497e78f000e94cbd7ab2ffd56d50e150f..dc5df61ea4be40000df1159a5e916758cf9d5143 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 4
 PATCHLEVEL = 4
-SUBLEVEL = 68
+SUBLEVEL = 69
 EXTRAVERSION =
 NAME = Blurry Fish Butt
 
index a9b3b905e661dec55672e459f1119b3eb466b373..443db0c43d7c67f1b7fc43913b3c71477ddb2fcc 100644 (file)
@@ -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;
index eec3598b4184077b83b5a1f24321891cb110f5bb..3ff507c177a5a0acd545c003f14ac317f9723477 100644 (file)
@@ -1055,8 +1055,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;
@@ -1107,7 +1107,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;
index 9011a88353ded70ece09718a04349464ee8467ec..ed1e9206f8301f813d0764643055f8edc77685f9 100644 (file)
@@ -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__
 
index bd8ce6bcdfc9769a40fd315bcffa030da6638edc..6503526d7b2486d9ecbb0b9c110b3dc6e0631b29 100644 (file)
@@ -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);
index e75095fa414ef5d48d15eb8fce32cac55ea5fc0c..281899da19d42f840dfb24e32763dd6a446b9a57 100644 (file)
@@ -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);
index a629694ee750ff7c6c245bd6166a7264c0d36e85..e14c43a2d187e6659f089b2fca5f8d1429f8be64 100644 (file)
@@ -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;
index 1e56ff58345982b99185db7f25d598f46875c300..63146c378f1e75182dd15a2bc25e5285f71247c7 100644 (file)
@@ -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);
 
index 319f2e4f4a8b39c09f487e641b65feea4ae149a3..478f572cb1e7d6bb78c4dcbbf650012107c6e1a0 100644 (file)
@@ -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;
index 6d4d4569447ee080ef44eb7c8c17d782bec23103..faea9d728fd20445758eccd8c070fdead856f709 100644 (file)
@@ -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
 };
index 795d0ca714bfe45f25b97d3e6f566088925f5875..098997f2cc3a8ebbd3af013c3217c004913bb837 100644 (file)
@@ -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/
index cb852cc750b78256cd05fb62eda18dfb28c246aa..f9b569ef3dd78ab9ec822816b8cea09636efe438 100644 (file)
@@ -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;
 }
 
index b9065506a847da6f3eaf0c6ccb1cfd2f3640d74a..0c63fce0c1e0880a9a298e3a5d25b8ebe4b0f439 100644 (file)
@@ -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;
index 90e6246622572966a9037350e8fdabed743d7961..0d83cfb9708f0359c05bafca98e5d96931628360 100644 (file)
@@ -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. */
index b1f37d4095fa1e15f7402c35a367b00e1f24b6b5..e76d52a203a73cde26d2cb1ab57b5607713eb8b2 100644 (file)
@@ -863,7 +863,7 @@ err_put:
        free_port_list_attributes(device);
 
 err_unregister:
-       device_unregister(class_dev);
+       device_del(class_dev);
 
 err:
        return ret;
index 77ddf2fa8625205c7ba2c79011d1532f9ea0ba28..8763fb832b016c67b227f1424ba196f824ec13e8 100644 (file)
@@ -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:
index 36ec8aa048aacafdd17f89e1cb66a360d344ad0b..0b5bb0cee6f95cdce50b6dd3db416df801240df6 100644 (file)
@@ -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);
        }
index 6bd5740e26913df2662bad05a754ad6e88b3bb50..09396bd7b02d282321fa0b015b0ec33cef350ed9 100644 (file)
@@ -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)
index 8efcff1beb8ff5f93e19d8098693f7f8f13904c9..6699ecd855f04666a8ef4acbf6d48512deb37f12 100644 (file)
@@ -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);
index fca1a882de27d14e6338e0fbe7210c3393dd8f05..57a34f87dedf79b4e559aded7491b2ed872116af 100644 (file)
@@ -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:
index 665bf32856182e73bb390e3446b8280982bae020..32e76c5ee74172bef19f43a23b8f1cf9e5df20bc 100644 (file)
@@ -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;
        }
 
index 1e1bef3494872f5bef72184206a18365b86a0486..6decf4a95ce155c1100eb0605894a03e8fd4b3d4 100644 (file)
@@ -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);
index a680a970b7f7ef065bc09b83e2c80c4844d24c94..e4281438c04fb2976c91e2fc7eba474ac44d5b98 100644 (file)
@@ -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);
index b114e57a823fd2fb79a8d2195785f3f51bc86d29..3abc64574116f17b913c94ec4738a11cf1ef785d 100644 (file)
@@ -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 = &params->ssn;
 
        mutex_lock(&sc->mutex);
 
index 19d3d64416bf66825eb113590474b4e4a68f8ec2..4d1527a2e292a2ba2d29907554625cf0fbb980f4 100644 (file)
@@ -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 = &params->ssn;
        struct ar9170 *ar = hw->priv;
        struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
        struct carl9170_sta_tid *tid_info;
index 7c169abdbafee95ccfe8f461e670fbb8ab5ca5eb..a27279c2c6950913c0b1f14fd4cacdd3bc650428 100644 (file)
@@ -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 = &params->ssn;
 
        wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n",
                    action, tid);
index bec2dc1ca2e406bcf4ac0ee0d00fa27a704cf7f2..61ae2768132a0b16f0f98a57b3319c82adfda95b 100644 (file)
@@ -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;
index 95a7fdb3cc1cd83fcda337527d153580789391b2..c602a1e674ca87d3caaa07bf21e55fee1aae36b7 100644 (file)
@@ -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
index bebb3379017f6d40c3cd58b92ddfaabab1259f59..a0bacaa39b3193f230c61526afe6bdc68f38b7a0 100644 (file)
@@ -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);
index 6656215a13a9239334b9eca21f510342bb28f0d7..04b0349a6ad9f232d8d5456c7436cdc1a847d99c 100644 (file)
@@ -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 = &params->ssn;
 
        D_HT("A-MPDU action on addr %pM tid %d\n", sta->addr, tid);
 
index 8ab8706f942267fcd2467928b1cbdf248a05921f..e432715e02d89dedcce89615d855233662c26d82 100644 (file)
@@ -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
index b3ad34e8bf5a023756fc51b261565ae99f0fee1a..1eb1a823a111df00fbbe5207301673a61f267821 100644 (file)
@@ -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 = &params->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",
index ce12717e656ad771350c8b50a5e820e9d4da63a0..1a8ea775de08e3315a0d94eae7d842032b9f48a0 100644 (file)
@@ -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 = &params->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);
index 0cd95120bc786c46288cd36eb442f5a7933b67bc..d59769e858f4c6ff4778dc1e80f738ba69d9d6df 100644 (file)
@@ -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);
index f715eee398510df829a61ba0f431610d1ab32baa..e70dd95239117f7e0ef8a2d668b6798727a06b46 100644 (file)
@@ -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 = &params->ssn;
        struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv;
 
        WARN_ON(msta->wcid.idx > GROUP_WCID(0));
index 30e3aaae32e2288ed1f7541b6da7a42eb6a8729a..088429d0a634d8c4372d45e2dc1cd3b7d2fabf1e 100644 (file)
@@ -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 = &params->ssn;
+       u8 buf_size = params->buf_size;
        int i, rc = 0;
        struct mwl8k_priv *priv = hw->priv;
        struct mwl8k_ampdu_stream *stream;
index 6aed923a709ae3606225307cdcb2b7170442e11d..7d820c3953754260c05a5f7e21478e1cbf14555e 100644 (file)
@@ -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:
index e36d8c45627577acfebf6554cc72a09394e59c21..8b537a5a4b010ad41af539876866c7e1b7db725c 100644 (file)
@@ -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 = &params->ssn;
 
        switch (action) {
        case IEEE80211_AMPDU_TX_START:
index b5bcc933a2a683df412139b1204fee320096a889..4df992de7d0731508a6c42fccf51096928156e9e 100644 (file)
@@ -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 = &params->ssn;
+       u8 buf_size = params->buf_size;
 
        for (ii = 0; ii < RSI_MAX_VIFS; ii++) {
                if (vif == adapter->vifs[ii])
index 9733b31a780d380fd2bfd550efe155943b0fdb34..69c1c09687a30c5c2338cc84f12981eb4133d40d 100644 (file)
@@ -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;
 
index 440790b92b19e2927fd9b9d7446cbd3c8eef4f30..83f1a44fb9b481cb5f2a8dda9e9914b8113e91bb 100644 (file)
@@ -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);
index 09c7e098f4607bd6cb6d0b0f89654f63bcf6de74..085ef5c8726286b57125a6d05b2adea871acfbeb 100644 (file)
@@ -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;
 }
index f3d4f13379cb0dcd1846119d27941c8301167dac..9495fadc80934d0e5e650fd09db9eb2373c2afbb 100644 (file)
@@ -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),
index 50cce42089a5eb0358620a46d46d0990af47e6e7..47f355e92193f31ec5a7b59f7a67fc226e237e87 100644 (file)
@@ -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;
 
index f28fa3b5029d6f1a947fa8919783ccf65e265c84..0646c9b6f8d7854c81513d8f511488e6fdf3526d 100644 (file)
@@ -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,
index 954d57ec98f45cc358c0753dab590205322a8178..524aea495dffc4bfe162665b3f583aab6ba34e3d 100644 (file)
@@ -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,
index ec7f6af3fab26bebcac055892937332e0254c1fb..7b27c7e23af287c33f78281f9c8e9a0ac6a27a6d 100644 (file)
@@ -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 = &params->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--;
index b87192e0f9aa8ba93217aef26fb16b031cc1e469..109becdabc2446929edb220a26de746825249a24 100644 (file)
@@ -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 */
index 445f836155752e3225046cdd0268c388e1ff114f..fb4f3fea6c668657cd3be93c8951673fc2bb1be5 100644 (file)
@@ -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);
index c975c3b870938eb582d022785e9a0bdb0144e7fc..cfc3017fd64ae33a3ec7923655e51a12afd443b4 100644 (file)
@@ -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);
 
index 6ed80b05d674bc5a18da5e70899fecebfed4a621..200d3de8bc1e8a8303d3169813d957f1732206d8 100644 (file)
@@ -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);
index b4bfd706ac9422705a35fc879705f46d6787fc13..dc1bd1f1bdfe3b6990dd13570ab46a1085e56f31 100644 (file)
@@ -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;
 }
 
index 316f661723350f0872cabdba7571d868b2e4d212..4a137b0ae3dc11d09bfbf6941bc9d7c2e3b0558a 100644 (file)
@@ -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);
index 68261b7dcefe1e6e47be828dc87cca5c3f922ae8..205a509b0dfb289fac9791cdd0d44d259031a9a7 100644 (file)
@@ -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;
index 9db32bd24cd46d65c5b0050374d0fd6118ac9d32..2da211920c186215e740d1aaa47f781999d1fb71 100644 (file)
@@ -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);
index 79291869bce6c72d9eb4a72fa6d6f5614a104aa4..041a569878459490df0f95cd6b612fb1cb70515b 100644 (file)
@@ -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;
 }
 
index 90c5dffc9fa47afd1dd3e40067d46b96b516cfc3..6081178193661bc4f404b5af0373d7de1273286b 100644 (file)
@@ -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;
        }
 
index 2794c6ec5c3c5e43daf4783189ea9a87b15a8604..899c33b3c734b4594a00ec9e00eed9103442b6e7 100644 (file)
@@ -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);
index df2059984e147ee4e7417d8b4fb71c3fbe7e247a..af301414a9f3682d9d6ba627548e4b395865a300 100644 (file)
@@ -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);
 
index 807d8014568643a18fb061a8c661b0b0c3c5eeb1..96aa0ad3249751e21b4a9996d5670cdd52b60bfa 100644 (file)
@@ -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;
index 24280d9a05e9222dbdb7f5c21e1482c7fea774d7..de1c143b475fbca26bd163935c792f18333aa83a 100644 (file)
@@ -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);
 
index 6deb061472027f42e37c885da2579b39b9b9f742..e6bc1a6be4a4dfaae4cb33daf626061399e8688e 100644 (file)
@@ -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;
index dadd1e8dfe09ded9d28e541099d43f582707596c..0bb380a9fcf795cb854eee1413a17a1d8d46c637 100644 (file)
@@ -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.
         */
index ea337a718cc1ca38945d3c42e6d0f75d157083b6..b3de806085f049b1a418a122112aa6ea2fa7806e 100644 (file)
@@ -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;
 
index 7c2d87befb516adff119fed378f66f4cf7bb7610..67961231cbbd3b7ace45731f763a7e8fd53806f7 100644 (file)
@@ -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);
index 998a738e6359a710fba8bfcd0a8c3e048a02de05..5d70d46239bbf89a599b3eb659998d80490765cd 100644 (file)
@@ -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);
 
index 1624b09d974818194b66defad12d5af31bd5c956..2e947dc94e322015b06883186e7e1fd302496a31 100644 (file)
@@ -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;
index b3a21fcbbaf902c51e7b1c13dc54a8913b500589..dbd441c1c2ad039b8ba98bb46691086fe59a1780 100644 (file)
@@ -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 },
index 48ee04c94a7541ad6c5f9023be107246207c56fd..71fb9e59db7125c845a9a1c23c4e33430a142a3e 100644 (file)
 #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
index ecb826eefe0214861bf5e141b34ca74ecf804598..2fa280671c1ee45d3d46044acaa12548b05129ce 100644 (file)
@@ -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(&current->mm->mmap_sem)) {
-               current->mm->locked_vm += npage;
-               up_write(&current->mm->mmap_sem);
-               return;
-       }
+       down_write(&current->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(&current->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)
index e5733bb537c99ea792f3d85d9dfff0aa2607c30a..26bbaaefdff486a36185c797afe0019193a94f1a 100644 (file)
@@ -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
         */
index 819163d8313bb3748765b5c3313dfdfd32ac9472..b24275ef97f74d0d49f0f6f32ed4c32c9c3a6f8c 100644 (file)
@@ -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;
                }
        }
index 02b071bf3732ac29808183974636e2ac9ca56ce6..a0b3e7d1be484fd3f026258577e18c165f738f0e 100644 (file)
@@ -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;
index 479bc0a941f35f79056dedc45ab99825669f1e6e..07ade707fa60a43c9f64ad72512b1992c98c4ff1 100644 (file)
@@ -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
index 5e2f8b8ca08aac0441d8cbeae6b37eef4ba73fda..b60150e5b5ceaab72954b82b1519bf4792fa1589 100644 (file)
@@ -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;
index 35cf990f87d3245d01662cc550f4f3b43cc2dc58..a8f5b31636dc835a94a03f768101ec20e4c505a9 100644 (file)
@@ -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;
index 6cb2603f8a5c3685159eef3c549e6d558613d61d..f4afa3b1cc569274c9f112c1078df793bbbb09cc 100644 (file)
@@ -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);
index 817a937de73337770ceaef90acbdea115a5cac01..ccae64dad40c9740469021da944add0053b39f80 100644 (file)
@@ -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) &&
index 9b932b95d74e4faeb5653d1a3c4b11553d1e51e1..f0da9d24e9ca2ed4d23980dc8c0595d7e3dcbe21 100644 (file)
@@ -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;
index 760bc4d5a2cfe87aadd2e96a98292855cf2eb050..4e51f9a5a177940cd711694ec80a5232693a6995 100644 (file)
@@ -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;
@@ -2673,6 +2677,33 @@ enum ieee80211_ampdu_mlme_action {
        IEEE80211_AMPDU_TX_OPERATIONAL,
 };
 
+/**
+ * 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
@@ -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);
index 97069ecabe4937f1a0f5a14504efd2fd645fb9d9..5f9b62c129fcbb675a16336daa7e6d84cc1f4191 100644 (file)
@@ -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);
index 401227e3967c8188ef54a813c1f1769124a2c8ec..ecc7b3f452c70564b7363d54760fe1df564c44c8 100644 (file)
@@ -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;
        }
 
index b1eb8c09a66016c2cbcca79dcf3bb533bb85ec02..c842f40c11734bd1023c2b54aa160e996d66e232 100644 (file)
@@ -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)
index 367784be5df20f26fd3940c4608f1ea715bfddd6..a830356b94acffeb2ff9c6bfced612ccd9aa5176 100644 (file)
@@ -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, &params))
                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, &params);
        ht_dbg(sta->sdata, "Rx A-MPDU request on %pM tid %d result %d\n",
               sta->sta.addr, tid, ret);
        if (ret) {
index ff757181b0a85c820e1acc53a088e95c78b87bff..4932e9f243a2cb9e156e7e24ac1c098fc9a4b19c 100644 (file)
@@ -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, &params);
                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, &params);
 
        /* 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, &params);
        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, &params);
 
        /*
         * synchronize with TX path, while splicing the TX path
index ca1fe5576103767c3a98b52e037c0034b949887f..c258f1041d330885d08869e302a5ec255b470b4b 100644 (file)
@@ -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);
 
index 154ce4b13406d5a31bac8797f8069184ca9cd6f5..18b0d65baff000156c8015f76b9ce527a938e95a 100644 (file)
@@ -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)
index 67066d048e6fb00033a660e7bbaad11d5621b1ac..63ea6cbac5add6a9e5f58722f0b748b2a8cb0e26 100644 (file)
@@ -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;
index 56c6d6cfa5a1a211818ef2b472d0900207fc0b6f..913e959b03cf4cecb7720a1ccf2f2b9486292dec 100644 (file)
 #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
        )
 );
 
index 31a3035cd4eb33485dc01a0247e367606fc7ae50..923e59eb82c7f4df9602c3a351e3108c5af60eac 100644 (file)
@@ -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;