diff options
author | David S. Miller <davem@davemloft.net> | 2018-01-29 10:14:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-01-29 10:15:51 -0500 |
commit | 3e3ab9ccca5b50b11bd4d16c2048b667343354bd (patch) | |
tree | 7279f7401e7cc2b93fb7cb2bff894b5385429a68 | |
parent | 868c36dcc949c26bc74fa4661b670d9acc6489e4 (diff) | |
parent | ba804bb4b72e57374b5f567b783aa0298fba0ce6 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Signed-off-by: David S. Miller <davem@davemloft.net>
28 files changed, 346 insertions, 220 deletions
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 2598cf243b86..1371dff2b90d 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -769,7 +769,7 @@ static void kvm_s390_sync_request_broadcast(struct kvm *kvm, int req) | |||
769 | 769 | ||
770 | /* | 770 | /* |
771 | * Must be called with kvm->srcu held to avoid races on memslots, and with | 771 | * Must be called with kvm->srcu held to avoid races on memslots, and with |
772 | * kvm->lock to avoid races with ourselves and kvm_s390_vm_stop_migration. | 772 | * kvm->slots_lock to avoid races with ourselves and kvm_s390_vm_stop_migration. |
773 | */ | 773 | */ |
774 | static int kvm_s390_vm_start_migration(struct kvm *kvm) | 774 | static int kvm_s390_vm_start_migration(struct kvm *kvm) |
775 | { | 775 | { |
@@ -825,7 +825,7 @@ static int kvm_s390_vm_start_migration(struct kvm *kvm) | |||
825 | } | 825 | } |
826 | 826 | ||
827 | /* | 827 | /* |
828 | * Must be called with kvm->lock to avoid races with ourselves and | 828 | * Must be called with kvm->slots_lock to avoid races with ourselves and |
829 | * kvm_s390_vm_start_migration. | 829 | * kvm_s390_vm_start_migration. |
830 | */ | 830 | */ |
831 | static int kvm_s390_vm_stop_migration(struct kvm *kvm) | 831 | static int kvm_s390_vm_stop_migration(struct kvm *kvm) |
@@ -840,6 +840,8 @@ static int kvm_s390_vm_stop_migration(struct kvm *kvm) | |||
840 | 840 | ||
841 | if (kvm->arch.use_cmma) { | 841 | if (kvm->arch.use_cmma) { |
842 | kvm_s390_sync_request_broadcast(kvm, KVM_REQ_STOP_MIGRATION); | 842 | kvm_s390_sync_request_broadcast(kvm, KVM_REQ_STOP_MIGRATION); |
843 | /* We have to wait for the essa emulation to finish */ | ||
844 | synchronize_srcu(&kvm->srcu); | ||
843 | vfree(mgs->pgste_bitmap); | 845 | vfree(mgs->pgste_bitmap); |
844 | } | 846 | } |
845 | kfree(mgs); | 847 | kfree(mgs); |
@@ -849,14 +851,12 @@ static int kvm_s390_vm_stop_migration(struct kvm *kvm) | |||
849 | static int kvm_s390_vm_set_migration(struct kvm *kvm, | 851 | static int kvm_s390_vm_set_migration(struct kvm *kvm, |
850 | struct kvm_device_attr *attr) | 852 | struct kvm_device_attr *attr) |
851 | { | 853 | { |
852 | int idx, res = -ENXIO; | 854 | int res = -ENXIO; |
853 | 855 | ||
854 | mutex_lock(&kvm->lock); | 856 | mutex_lock(&kvm->slots_lock); |
855 | switch (attr->attr) { | 857 | switch (attr->attr) { |
856 | case KVM_S390_VM_MIGRATION_START: | 858 | case KVM_S390_VM_MIGRATION_START: |
857 | idx = srcu_read_lock(&kvm->srcu); | ||
858 | res = kvm_s390_vm_start_migration(kvm); | 859 | res = kvm_s390_vm_start_migration(kvm); |
859 | srcu_read_unlock(&kvm->srcu, idx); | ||
860 | break; | 860 | break; |
861 | case KVM_S390_VM_MIGRATION_STOP: | 861 | case KVM_S390_VM_MIGRATION_STOP: |
862 | res = kvm_s390_vm_stop_migration(kvm); | 862 | res = kvm_s390_vm_stop_migration(kvm); |
@@ -864,7 +864,7 @@ static int kvm_s390_vm_set_migration(struct kvm *kvm, | |||
864 | default: | 864 | default: |
865 | break; | 865 | break; |
866 | } | 866 | } |
867 | mutex_unlock(&kvm->lock); | 867 | mutex_unlock(&kvm->slots_lock); |
868 | 868 | ||
869 | return res; | 869 | return res; |
870 | } | 870 | } |
@@ -1754,7 +1754,9 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
1754 | r = -EFAULT; | 1754 | r = -EFAULT; |
1755 | if (copy_from_user(&args, argp, sizeof(args))) | 1755 | if (copy_from_user(&args, argp, sizeof(args))) |
1756 | break; | 1756 | break; |
1757 | mutex_lock(&kvm->slots_lock); | ||
1757 | r = kvm_s390_get_cmma_bits(kvm, &args); | 1758 | r = kvm_s390_get_cmma_bits(kvm, &args); |
1759 | mutex_unlock(&kvm->slots_lock); | ||
1758 | if (!r) { | 1760 | if (!r) { |
1759 | r = copy_to_user(argp, &args, sizeof(args)); | 1761 | r = copy_to_user(argp, &args, sizeof(args)); |
1760 | if (r) | 1762 | if (r) |
@@ -1768,7 +1770,9 @@ long kvm_arch_vm_ioctl(struct file *filp, | |||
1768 | r = -EFAULT; | 1770 | r = -EFAULT; |
1769 | if (copy_from_user(&args, argp, sizeof(args))) | 1771 | if (copy_from_user(&args, argp, sizeof(args))) |
1770 | break; | 1772 | break; |
1773 | mutex_lock(&kvm->slots_lock); | ||
1771 | r = kvm_s390_set_cmma_bits(kvm, &args); | 1774 | r = kvm_s390_set_cmma_bits(kvm, &args); |
1775 | mutex_unlock(&kvm->slots_lock); | ||
1772 | break; | 1776 | break; |
1773 | } | 1777 | } |
1774 | default: | 1778 | default: |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c index deb96de54b00..ee2431a7804e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c | |||
@@ -71,6 +71,10 @@ nvkm_pci_intr(int irq, void *arg) | |||
71 | struct nvkm_pci *pci = arg; | 71 | struct nvkm_pci *pci = arg; |
72 | struct nvkm_device *device = pci->subdev.device; | 72 | struct nvkm_device *device = pci->subdev.device; |
73 | bool handled = false; | 73 | bool handled = false; |
74 | |||
75 | if (pci->irq < 0) | ||
76 | return IRQ_HANDLED; | ||
77 | |||
74 | nvkm_mc_intr_unarm(device); | 78 | nvkm_mc_intr_unarm(device); |
75 | if (pci->msi) | 79 | if (pci->msi) |
76 | pci->func->msi_rearm(pci); | 80 | pci->func->msi_rearm(pci); |
@@ -84,11 +88,6 @@ nvkm_pci_fini(struct nvkm_subdev *subdev, bool suspend) | |||
84 | { | 88 | { |
85 | struct nvkm_pci *pci = nvkm_pci(subdev); | 89 | struct nvkm_pci *pci = nvkm_pci(subdev); |
86 | 90 | ||
87 | if (pci->irq >= 0) { | ||
88 | free_irq(pci->irq, pci); | ||
89 | pci->irq = -1; | ||
90 | } | ||
91 | |||
92 | if (pci->agp.bridge) | 91 | if (pci->agp.bridge) |
93 | nvkm_agp_fini(pci); | 92 | nvkm_agp_fini(pci); |
94 | 93 | ||
@@ -108,8 +107,20 @@ static int | |||
108 | nvkm_pci_oneinit(struct nvkm_subdev *subdev) | 107 | nvkm_pci_oneinit(struct nvkm_subdev *subdev) |
109 | { | 108 | { |
110 | struct nvkm_pci *pci = nvkm_pci(subdev); | 109 | struct nvkm_pci *pci = nvkm_pci(subdev); |
111 | if (pci_is_pcie(pci->pdev)) | 110 | struct pci_dev *pdev = pci->pdev; |
112 | return nvkm_pcie_oneinit(pci); | 111 | int ret; |
112 | |||
113 | if (pci_is_pcie(pci->pdev)) { | ||
114 | ret = nvkm_pcie_oneinit(pci); | ||
115 | if (ret) | ||
116 | return ret; | ||
117 | } | ||
118 | |||
119 | ret = request_irq(pdev->irq, nvkm_pci_intr, IRQF_SHARED, "nvkm", pci); | ||
120 | if (ret) | ||
121 | return ret; | ||
122 | |||
123 | pci->irq = pdev->irq; | ||
113 | return 0; | 124 | return 0; |
114 | } | 125 | } |
115 | 126 | ||
@@ -117,7 +128,6 @@ static int | |||
117 | nvkm_pci_init(struct nvkm_subdev *subdev) | 128 | nvkm_pci_init(struct nvkm_subdev *subdev) |
118 | { | 129 | { |
119 | struct nvkm_pci *pci = nvkm_pci(subdev); | 130 | struct nvkm_pci *pci = nvkm_pci(subdev); |
120 | struct pci_dev *pdev = pci->pdev; | ||
121 | int ret; | 131 | int ret; |
122 | 132 | ||
123 | if (pci->agp.bridge) { | 133 | if (pci->agp.bridge) { |
@@ -131,28 +141,34 @@ nvkm_pci_init(struct nvkm_subdev *subdev) | |||
131 | if (pci->func->init) | 141 | if (pci->func->init) |
132 | pci->func->init(pci); | 142 | pci->func->init(pci); |
133 | 143 | ||
134 | ret = request_irq(pdev->irq, nvkm_pci_intr, IRQF_SHARED, "nvkm", pci); | ||
135 | if (ret) | ||
136 | return ret; | ||
137 | |||
138 | pci->irq = pdev->irq; | ||
139 | |||
140 | /* Ensure MSI interrupts are armed, for the case where there are | 144 | /* Ensure MSI interrupts are armed, for the case where there are |
141 | * already interrupts pending (for whatever reason) at load time. | 145 | * already interrupts pending (for whatever reason) at load time. |
142 | */ | 146 | */ |
143 | if (pci->msi) | 147 | if (pci->msi) |
144 | pci->func->msi_rearm(pci); | 148 | pci->func->msi_rearm(pci); |
145 | 149 | ||
146 | return ret; | 150 | return 0; |
147 | } | 151 | } |
148 | 152 | ||
149 | static void * | 153 | static void * |
150 | nvkm_pci_dtor(struct nvkm_subdev *subdev) | 154 | nvkm_pci_dtor(struct nvkm_subdev *subdev) |
151 | { | 155 | { |
152 | struct nvkm_pci *pci = nvkm_pci(subdev); | 156 | struct nvkm_pci *pci = nvkm_pci(subdev); |
157 | |||
153 | nvkm_agp_dtor(pci); | 158 | nvkm_agp_dtor(pci); |
159 | |||
160 | if (pci->irq >= 0) { | ||
161 | /* freq_irq() will call the handler, we use pci->irq == -1 | ||
162 | * to signal that it's been torn down and should be a noop. | ||
163 | */ | ||
164 | int irq = pci->irq; | ||
165 | pci->irq = -1; | ||
166 | free_irq(irq, pci); | ||
167 | } | ||
168 | |||
154 | if (pci->msi) | 169 | if (pci->msi) |
155 | pci_disable_msi(pci->pdev); | 170 | pci_disable_msi(pci->pdev); |
171 | |||
156 | return nvkm_pci(subdev); | 172 | return nvkm_pci(subdev); |
157 | } | 173 | } |
158 | 174 | ||
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index 638540943c61..c94cce96544c 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c | |||
@@ -146,7 +146,7 @@ vc4_save_hang_state(struct drm_device *dev) | |||
146 | struct vc4_exec_info *exec[2]; | 146 | struct vc4_exec_info *exec[2]; |
147 | struct vc4_bo *bo; | 147 | struct vc4_bo *bo; |
148 | unsigned long irqflags; | 148 | unsigned long irqflags; |
149 | unsigned int i, j, unref_list_count, prev_idx; | 149 | unsigned int i, j, k, unref_list_count; |
150 | 150 | ||
151 | kernel_state = kcalloc(1, sizeof(*kernel_state), GFP_KERNEL); | 151 | kernel_state = kcalloc(1, sizeof(*kernel_state), GFP_KERNEL); |
152 | if (!kernel_state) | 152 | if (!kernel_state) |
@@ -182,7 +182,7 @@ vc4_save_hang_state(struct drm_device *dev) | |||
182 | return; | 182 | return; |
183 | } | 183 | } |
184 | 184 | ||
185 | prev_idx = 0; | 185 | k = 0; |
186 | for (i = 0; i < 2; i++) { | 186 | for (i = 0; i < 2; i++) { |
187 | if (!exec[i]) | 187 | if (!exec[i]) |
188 | continue; | 188 | continue; |
@@ -197,7 +197,7 @@ vc4_save_hang_state(struct drm_device *dev) | |||
197 | WARN_ON(!refcount_read(&bo->usecnt)); | 197 | WARN_ON(!refcount_read(&bo->usecnt)); |
198 | refcount_inc(&bo->usecnt); | 198 | refcount_inc(&bo->usecnt); |
199 | drm_gem_object_get(&exec[i]->bo[j]->base); | 199 | drm_gem_object_get(&exec[i]->bo[j]->base); |
200 | kernel_state->bo[j + prev_idx] = &exec[i]->bo[j]->base; | 200 | kernel_state->bo[k++] = &exec[i]->bo[j]->base; |
201 | } | 201 | } |
202 | 202 | ||
203 | list_for_each_entry(bo, &exec[i]->unref_list, unref_head) { | 203 | list_for_each_entry(bo, &exec[i]->unref_list, unref_head) { |
@@ -205,12 +205,12 @@ vc4_save_hang_state(struct drm_device *dev) | |||
205 | * because they are naturally unpurgeable. | 205 | * because they are naturally unpurgeable. |
206 | */ | 206 | */ |
207 | drm_gem_object_get(&bo->base.base); | 207 | drm_gem_object_get(&bo->base.base); |
208 | kernel_state->bo[j + prev_idx] = &bo->base.base; | 208 | kernel_state->bo[k++] = &bo->base.base; |
209 | j++; | ||
210 | } | 209 | } |
211 | prev_idx = j + 1; | ||
212 | } | 210 | } |
213 | 211 | ||
212 | WARN_ON_ONCE(k != state->bo_count); | ||
213 | |||
214 | if (exec[0]) | 214 | if (exec[0]) |
215 | state->start_bin = exec[0]->ct0ca; | 215 | state->start_bin = exec[0]->ct0ca; |
216 | if (exec[1]) | 216 | if (exec[1]) |
@@ -436,6 +436,19 @@ vc4_flush_caches(struct drm_device *dev) | |||
436 | VC4_SET_FIELD(0xf, V3D_SLCACTL_ICC)); | 436 | VC4_SET_FIELD(0xf, V3D_SLCACTL_ICC)); |
437 | } | 437 | } |
438 | 438 | ||
439 | static void | ||
440 | vc4_flush_texture_caches(struct drm_device *dev) | ||
441 | { | ||
442 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
443 | |||
444 | V3D_WRITE(V3D_L2CACTL, | ||
445 | V3D_L2CACTL_L2CCLR); | ||
446 | |||
447 | V3D_WRITE(V3D_SLCACTL, | ||
448 | VC4_SET_FIELD(0xf, V3D_SLCACTL_T1CC) | | ||
449 | VC4_SET_FIELD(0xf, V3D_SLCACTL_T0CC)); | ||
450 | } | ||
451 | |||
439 | /* Sets the registers for the next job to be actually be executed in | 452 | /* Sets the registers for the next job to be actually be executed in |
440 | * the hardware. | 453 | * the hardware. |
441 | * | 454 | * |
@@ -474,6 +487,14 @@ vc4_submit_next_render_job(struct drm_device *dev) | |||
474 | if (!exec) | 487 | if (!exec) |
475 | return; | 488 | return; |
476 | 489 | ||
490 | /* A previous RCL may have written to one of our textures, and | ||
491 | * our full cache flush at bin time may have occurred before | ||
492 | * that RCL completed. Flush the texture cache now, but not | ||
493 | * the instructions or uniforms (since we don't write those | ||
494 | * from an RCL). | ||
495 | */ | ||
496 | vc4_flush_texture_caches(dev); | ||
497 | |||
477 | submit_cl(dev, 1, exec->ct1ca, exec->ct1ea); | 498 | submit_cl(dev, 1, exec->ct1ca, exec->ct1ea); |
478 | } | 499 | } |
479 | 500 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 2c13123bfd69..71ea9e26666c 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
@@ -1456,8 +1456,7 @@ void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb, | |||
1456 | struct ipoib_dev_priv *priv = ipoib_priv(dev); | 1456 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
1457 | int e = skb_queue_empty(&priv->cm.skb_queue); | 1457 | int e = skb_queue_empty(&priv->cm.skb_queue); |
1458 | 1458 | ||
1459 | if (skb_dst(skb)) | 1459 | skb_dst_update_pmtu(skb, mtu); |
1460 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | ||
1461 | 1460 | ||
1462 | skb_queue_tail(&priv->cm.skb_queue, skb); | 1461 | skb_queue_tail(&priv->cm.skb_queue, skb); |
1463 | if (e) | 1462 | if (e) |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index d86e59515b9c..d88d3e0f59fb 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
@@ -229,6 +229,7 @@ static const struct xpad_device { | |||
229 | { 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, | 229 | { 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, |
230 | { 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, | 230 | { 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 }, |
231 | { 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, XTYPE_XBOXONE }, | 231 | { 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, XTYPE_XBOXONE }, |
232 | { 0x0e6f, 0x02ab, "PDP Controller for Xbox One", 0, XTYPE_XBOXONE }, | ||
232 | { 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 }, | 233 | { 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 }, |
233 | { 0x0e6f, 0x0346, "Rock Candy Gamepad for Xbox One 2016", 0, XTYPE_XBOXONE }, | 234 | { 0x0e6f, 0x0346, "Rock Candy Gamepad for Xbox One 2016", 0, XTYPE_XBOXONE }, |
234 | { 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 }, | 235 | { 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 }, |
@@ -476,6 +477,22 @@ static const u8 xboxone_hori_init[] = { | |||
476 | }; | 477 | }; |
477 | 478 | ||
478 | /* | 479 | /* |
480 | * This packet is required for some of the PDP pads to start | ||
481 | * sending input reports. One of those pads is (0x0e6f:0x02ab). | ||
482 | */ | ||
483 | static const u8 xboxone_pdp_init1[] = { | ||
484 | 0x0a, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14 | ||
485 | }; | ||
486 | |||
487 | /* | ||
488 | * This packet is required for some of the PDP pads to start | ||
489 | * sending input reports. One of those pads is (0x0e6f:0x02ab). | ||
490 | */ | ||
491 | static const u8 xboxone_pdp_init2[] = { | ||
492 | 0x06, 0x20, 0x00, 0x02, 0x01, 0x00 | ||
493 | }; | ||
494 | |||
495 | /* | ||
479 | * A specific rumble packet is required for some PowerA pads to start | 496 | * A specific rumble packet is required for some PowerA pads to start |
480 | * sending input reports. One of those pads is (0x24c6:0x543a). | 497 | * sending input reports. One of those pads is (0x24c6:0x543a). |
481 | */ | 498 | */ |
@@ -505,6 +522,8 @@ static const struct xboxone_init_packet xboxone_init_packets[] = { | |||
505 | XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init), | 522 | XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init), |
506 | XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init), | 523 | XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init), |
507 | XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init), | 524 | XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init), |
525 | XBOXONE_INIT_PKT(0x0e6f, 0x02ab, xboxone_pdp_init1), | ||
526 | XBOXONE_INIT_PKT(0x0e6f, 0x02ab, xboxone_pdp_init2), | ||
508 | XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init), | 527 | XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init), |
509 | XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init), | 528 | XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init), |
510 | XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init), | 529 | XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init), |
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 0871010f18d5..bbd29220dbe9 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c | |||
@@ -19,6 +19,13 @@ | |||
19 | #include "psmouse.h" | 19 | #include "psmouse.h" |
20 | #include "trackpoint.h" | 20 | #include "trackpoint.h" |
21 | 21 | ||
22 | static const char * const trackpoint_variants[] = { | ||
23 | [TP_VARIANT_IBM] = "IBM", | ||
24 | [TP_VARIANT_ALPS] = "ALPS", | ||
25 | [TP_VARIANT_ELAN] = "Elan", | ||
26 | [TP_VARIANT_NXP] = "NXP", | ||
27 | }; | ||
28 | |||
22 | /* | 29 | /* |
23 | * Power-on Reset: Resets all trackpoint parameters, including RAM values, | 30 | * Power-on Reset: Resets all trackpoint parameters, including RAM values, |
24 | * to defaults. | 31 | * to defaults. |
@@ -26,7 +33,7 @@ | |||
26 | */ | 33 | */ |
27 | static int trackpoint_power_on_reset(struct ps2dev *ps2dev) | 34 | static int trackpoint_power_on_reset(struct ps2dev *ps2dev) |
28 | { | 35 | { |
29 | unsigned char results[2]; | 36 | u8 results[2]; |
30 | int tries = 0; | 37 | int tries = 0; |
31 | 38 | ||
32 | /* Issue POR command, and repeat up to once if 0xFC00 received */ | 39 | /* Issue POR command, and repeat up to once if 0xFC00 received */ |
@@ -38,7 +45,7 @@ static int trackpoint_power_on_reset(struct ps2dev *ps2dev) | |||
38 | 45 | ||
39 | /* Check for success response -- 0xAA00 */ | 46 | /* Check for success response -- 0xAA00 */ |
40 | if (results[0] != 0xAA || results[1] != 0x00) | 47 | if (results[0] != 0xAA || results[1] != 0x00) |
41 | return -1; | 48 | return -ENODEV; |
42 | 49 | ||
43 | return 0; | 50 | return 0; |
44 | } | 51 | } |
@@ -46,8 +53,7 @@ static int trackpoint_power_on_reset(struct ps2dev *ps2dev) | |||
46 | /* | 53 | /* |
47 | * Device IO: read, write and toggle bit | 54 | * Device IO: read, write and toggle bit |
48 | */ | 55 | */ |
49 | static int trackpoint_read(struct ps2dev *ps2dev, | 56 | static int trackpoint_read(struct ps2dev *ps2dev, u8 loc, u8 *results) |
50 | unsigned char loc, unsigned char *results) | ||
51 | { | 57 | { |
52 | if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) || | 58 | if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) || |
53 | ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 1, loc))) { | 59 | ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 1, loc))) { |
@@ -57,8 +63,7 @@ static int trackpoint_read(struct ps2dev *ps2dev, | |||
57 | return 0; | 63 | return 0; |
58 | } | 64 | } |
59 | 65 | ||
60 | static int trackpoint_write(struct ps2dev *ps2dev, | 66 | static int trackpoint_write(struct ps2dev *ps2dev, u8 loc, u8 val) |
61 | unsigned char loc, unsigned char val) | ||
62 | { | 67 | { |
63 | if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) || | 68 | if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) || |
64 | ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_WRITE_MEM)) || | 69 | ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_WRITE_MEM)) || |
@@ -70,8 +75,7 @@ static int trackpoint_write(struct ps2dev *ps2dev, | |||
70 | return 0; | 75 | return 0; |
71 | } | 76 | } |
72 | 77 | ||
73 | static int trackpoint_toggle_bit(struct ps2dev *ps2dev, | 78 | static int trackpoint_toggle_bit(struct ps2dev *ps2dev, u8 loc, u8 mask) |
74 | unsigned char loc, unsigned char mask) | ||
75 | { | 79 | { |
76 | /* Bad things will happen if the loc param isn't in this range */ | 80 | /* Bad things will happen if the loc param isn't in this range */ |
77 | if (loc < 0x20 || loc >= 0x2F) | 81 | if (loc < 0x20 || loc >= 0x2F) |
@@ -87,11 +91,11 @@ static int trackpoint_toggle_bit(struct ps2dev *ps2dev, | |||
87 | return 0; | 91 | return 0; |
88 | } | 92 | } |
89 | 93 | ||
90 | static int trackpoint_update_bit(struct ps2dev *ps2dev, unsigned char loc, | 94 | static int trackpoint_update_bit(struct ps2dev *ps2dev, |
91 | unsigned char mask, unsigned char value) | 95 | u8 loc, u8 mask, u8 value) |
92 | { | 96 | { |
93 | int retval = 0; | 97 | int retval = 0; |
94 | unsigned char data; | 98 | u8 data; |
95 | 99 | ||
96 | trackpoint_read(ps2dev, loc, &data); | 100 | trackpoint_read(ps2dev, loc, &data); |
97 | if (((data & mask) == mask) != !!value) | 101 | if (((data & mask) == mask) != !!value) |
@@ -105,17 +109,18 @@ static int trackpoint_update_bit(struct ps2dev *ps2dev, unsigned char loc, | |||
105 | */ | 109 | */ |
106 | struct trackpoint_attr_data { | 110 | struct trackpoint_attr_data { |
107 | size_t field_offset; | 111 | size_t field_offset; |
108 | unsigned char command; | 112 | u8 command; |
109 | unsigned char mask; | 113 | u8 mask; |
110 | unsigned char inverted; | 114 | bool inverted; |
111 | unsigned char power_on_default; | 115 | u8 power_on_default; |
112 | }; | 116 | }; |
113 | 117 | ||
114 | static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse, void *data, char *buf) | 118 | static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse, |
119 | void *data, char *buf) | ||
115 | { | 120 | { |
116 | struct trackpoint_data *tp = psmouse->private; | 121 | struct trackpoint_data *tp = psmouse->private; |
117 | struct trackpoint_attr_data *attr = data; | 122 | struct trackpoint_attr_data *attr = data; |
118 | unsigned char value = *(unsigned char *)((char *)tp + attr->field_offset); | 123 | u8 value = *(u8 *)((void *)tp + attr->field_offset); |
119 | 124 | ||
120 | if (attr->inverted) | 125 | if (attr->inverted) |
121 | value = !value; | 126 | value = !value; |
@@ -128,8 +133,8 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data, | |||
128 | { | 133 | { |
129 | struct trackpoint_data *tp = psmouse->private; | 134 | struct trackpoint_data *tp = psmouse->private; |
130 | struct trackpoint_attr_data *attr = data; | 135 | struct trackpoint_attr_data *attr = data; |
131 | unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); | 136 | u8 *field = (void *)tp + attr->field_offset; |
132 | unsigned char value; | 137 | u8 value; |
133 | int err; | 138 | int err; |
134 | 139 | ||
135 | err = kstrtou8(buf, 10, &value); | 140 | err = kstrtou8(buf, 10, &value); |
@@ -157,17 +162,14 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data, | |||
157 | { | 162 | { |
158 | struct trackpoint_data *tp = psmouse->private; | 163 | struct trackpoint_data *tp = psmouse->private; |
159 | struct trackpoint_attr_data *attr = data; | 164 | struct trackpoint_attr_data *attr = data; |
160 | unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset); | 165 | bool *field = (void *)tp + attr->field_offset; |
161 | unsigned int value; | 166 | bool value; |
162 | int err; | 167 | int err; |
163 | 168 | ||
164 | err = kstrtouint(buf, 10, &value); | 169 | err = kstrtobool(buf, &value); |
165 | if (err) | 170 | if (err) |
166 | return err; | 171 | return err; |
167 | 172 | ||
168 | if (value > 1) | ||
169 | return -EINVAL; | ||
170 | |||
171 | if (attr->inverted) | 173 | if (attr->inverted) |
172 | value = !value; | 174 | value = !value; |
173 | 175 | ||
@@ -193,30 +195,6 @@ PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \ | |||
193 | &trackpoint_attr_##_name, \ | 195 | &trackpoint_attr_##_name, \ |
194 | trackpoint_show_int_attr, trackpoint_set_bit_attr) | 196 | trackpoint_show_int_attr, trackpoint_set_bit_attr) |
195 | 197 | ||
196 | #define TRACKPOINT_UPDATE_BIT(_psmouse, _tp, _name) \ | ||
197 | do { \ | ||
198 | struct trackpoint_attr_data *_attr = &trackpoint_attr_##_name; \ | ||
199 | \ | ||
200 | trackpoint_update_bit(&_psmouse->ps2dev, \ | ||
201 | _attr->command, _attr->mask, _tp->_name); \ | ||
202 | } while (0) | ||
203 | |||
204 | #define TRACKPOINT_UPDATE(_power_on, _psmouse, _tp, _name) \ | ||
205 | do { \ | ||
206 | if (!_power_on || \ | ||
207 | _tp->_name != trackpoint_attr_##_name.power_on_default) { \ | ||
208 | if (!trackpoint_attr_##_name.mask) \ | ||
209 | trackpoint_write(&_psmouse->ps2dev, \ | ||
210 | trackpoint_attr_##_name.command, \ | ||
211 | _tp->_name); \ | ||
212 | else \ | ||
213 | TRACKPOINT_UPDATE_BIT(_psmouse, _tp, _name); \ | ||
214 | } \ | ||
215 | } while (0) | ||
216 | |||
217 | #define TRACKPOINT_SET_POWER_ON_DEFAULT(_tp, _name) \ | ||
218 | (_tp->_name = trackpoint_attr_##_name.power_on_default) | ||
219 | |||
220 | TRACKPOINT_INT_ATTR(sensitivity, TP_SENS, TP_DEF_SENS); | 198 | TRACKPOINT_INT_ATTR(sensitivity, TP_SENS, TP_DEF_SENS); |
221 | TRACKPOINT_INT_ATTR(speed, TP_SPEED, TP_DEF_SPEED); | 199 | TRACKPOINT_INT_ATTR(speed, TP_SPEED, TP_DEF_SPEED); |
222 | TRACKPOINT_INT_ATTR(inertia, TP_INERTIA, TP_DEF_INERTIA); | 200 | TRACKPOINT_INT_ATTR(inertia, TP_INERTIA, TP_DEF_INERTIA); |
@@ -229,13 +207,33 @@ TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME, TP_DEF_Z_TIME); | |||
229 | TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV, TP_DEF_JENKS_CURV); | 207 | TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV, TP_DEF_JENKS_CURV); |
230 | TRACKPOINT_INT_ATTR(drift_time, TP_DRIFT_TIME, TP_DEF_DRIFT_TIME); | 208 | TRACKPOINT_INT_ATTR(drift_time, TP_DRIFT_TIME, TP_DEF_DRIFT_TIME); |
231 | 209 | ||
232 | TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, 0, | 210 | TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, false, |
233 | TP_DEF_PTSON); | 211 | TP_DEF_PTSON); |
234 | TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK, 0, | 212 | TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK, false, |
235 | TP_DEF_SKIPBACK); | 213 | TP_DEF_SKIPBACK); |
236 | TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV, 1, | 214 | TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV, true, |
237 | TP_DEF_EXT_DEV); | 215 | TP_DEF_EXT_DEV); |
238 | 216 | ||
217 | static bool trackpoint_is_attr_available(struct psmouse *psmouse, | ||
218 | struct attribute *attr) | ||
219 | { | ||
220 | struct trackpoint_data *tp = psmouse->private; | ||
221 | |||
222 | return tp->variant_id == TP_VARIANT_IBM || | ||
223 | attr == &psmouse_attr_sensitivity.dattr.attr || | ||
224 | attr == &psmouse_attr_press_to_select.dattr.attr; | ||
225 | } | ||
226 | |||
227 | static umode_t trackpoint_is_attr_visible(struct kobject *kobj, | ||
228 | struct attribute *attr, int n) | ||
229 | { | ||
230 | struct device *dev = container_of(kobj, struct device, kobj); | ||
231 | struct serio *serio = to_serio_port(dev); | ||
232 | struct psmouse *psmouse = serio_get_drvdata(serio); | ||
233 | |||
234 | return trackpoint_is_attr_available(psmouse, attr) ? attr->mode : 0; | ||
235 | } | ||
236 | |||
239 | static struct attribute *trackpoint_attrs[] = { | 237 | static struct attribute *trackpoint_attrs[] = { |
240 | &psmouse_attr_sensitivity.dattr.attr, | 238 | &psmouse_attr_sensitivity.dattr.attr, |
241 | &psmouse_attr_speed.dattr.attr, | 239 | &psmouse_attr_speed.dattr.attr, |
@@ -255,24 +253,56 @@ static struct attribute *trackpoint_attrs[] = { | |||
255 | }; | 253 | }; |
256 | 254 | ||
257 | static struct attribute_group trackpoint_attr_group = { | 255 | static struct attribute_group trackpoint_attr_group = { |
258 | .attrs = trackpoint_attrs, | 256 | .is_visible = trackpoint_is_attr_visible, |
257 | .attrs = trackpoint_attrs, | ||
259 | }; | 258 | }; |
260 | 259 | ||
261 | static int trackpoint_start_protocol(struct psmouse *psmouse, unsigned char *firmware_id) | 260 | #define TRACKPOINT_UPDATE(_power_on, _psmouse, _tp, _name) \ |
262 | { | 261 | do { \ |
263 | unsigned char param[2] = { 0 }; | 262 | struct trackpoint_attr_data *_attr = &trackpoint_attr_##_name; \ |
263 | \ | ||
264 | if ((!_power_on || _tp->_name != _attr->power_on_default) && \ | ||
265 | trackpoint_is_attr_available(_psmouse, \ | ||
266 | &psmouse_attr_##_name.dattr.attr)) { \ | ||
267 | if (!_attr->mask) \ | ||
268 | trackpoint_write(&_psmouse->ps2dev, \ | ||
269 | _attr->command, _tp->_name); \ | ||
270 | else \ | ||
271 | trackpoint_update_bit(&_psmouse->ps2dev, \ | ||
272 | _attr->command, _attr->mask, \ | ||
273 | _tp->_name); \ | ||
274 | } \ | ||
275 | } while (0) | ||
264 | 276 | ||
265 | if (ps2_command(&psmouse->ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID))) | 277 | #define TRACKPOINT_SET_POWER_ON_DEFAULT(_tp, _name) \ |
266 | return -1; | 278 | do { \ |
279 | _tp->_name = trackpoint_attr_##_name.power_on_default; \ | ||
280 | } while (0) | ||
267 | 281 | ||
268 | /* add new TP ID. */ | 282 | static int trackpoint_start_protocol(struct psmouse *psmouse, |
269 | if (!(param[0] & TP_MAGIC_IDENT)) | 283 | u8 *variant_id, u8 *firmware_id) |
270 | return -1; | 284 | { |
285 | u8 param[2] = { 0 }; | ||
286 | int error; | ||
271 | 287 | ||
272 | if (firmware_id) | 288 | error = ps2_command(&psmouse->ps2dev, |
273 | *firmware_id = param[1]; | 289 | param, MAKE_PS2_CMD(0, 2, TP_READ_ID)); |
290 | if (error) | ||
291 | return error; | ||
292 | |||
293 | switch (param[0]) { | ||
294 | case TP_VARIANT_IBM: | ||
295 | case TP_VARIANT_ALPS: | ||
296 | case TP_VARIANT_ELAN: | ||
297 | case TP_VARIANT_NXP: | ||
298 | if (variant_id) | ||
299 | *variant_id = param[0]; | ||
300 | if (firmware_id) | ||
301 | *firmware_id = param[1]; | ||
302 | return 0; | ||
303 | } | ||
274 | 304 | ||
275 | return 0; | 305 | return -ENODEV; |
276 | } | 306 | } |
277 | 307 | ||
278 | /* | 308 | /* |
@@ -285,7 +315,7 @@ static int trackpoint_sync(struct psmouse *psmouse, bool in_power_on_state) | |||
285 | { | 315 | { |
286 | struct trackpoint_data *tp = psmouse->private; | 316 | struct trackpoint_data *tp = psmouse->private; |
287 | 317 | ||
288 | if (!in_power_on_state) { | 318 | if (!in_power_on_state && tp->variant_id == TP_VARIANT_IBM) { |
289 | /* | 319 | /* |
290 | * Disable features that may make device unusable | 320 | * Disable features that may make device unusable |
291 | * with this driver. | 321 | * with this driver. |
@@ -347,7 +377,8 @@ static void trackpoint_defaults(struct trackpoint_data *tp) | |||
347 | 377 | ||
348 | static void trackpoint_disconnect(struct psmouse *psmouse) | 378 | static void trackpoint_disconnect(struct psmouse *psmouse) |
349 | { | 379 | { |
350 | sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, &trackpoint_attr_group); | 380 | device_remove_group(&psmouse->ps2dev.serio->dev, |
381 | &trackpoint_attr_group); | ||
351 | 382 | ||
352 | kfree(psmouse->private); | 383 | kfree(psmouse->private); |
353 | psmouse->private = NULL; | 384 | psmouse->private = NULL; |
@@ -355,14 +386,20 @@ static void trackpoint_disconnect(struct psmouse *psmouse) | |||
355 | 386 | ||
356 | static int trackpoint_reconnect(struct psmouse *psmouse) | 387 | static int trackpoint_reconnect(struct psmouse *psmouse) |
357 | { | 388 | { |
358 | int reset_fail; | 389 | struct trackpoint_data *tp = psmouse->private; |
390 | int error; | ||
391 | bool was_reset; | ||
359 | 392 | ||
360 | if (trackpoint_start_protocol(psmouse, NULL)) | 393 | error = trackpoint_start_protocol(psmouse, NULL, NULL); |
361 | return -1; | 394 | if (error) |
395 | return error; | ||
362 | 396 | ||
363 | reset_fail = trackpoint_power_on_reset(&psmouse->ps2dev); | 397 | was_reset = tp->variant_id == TP_VARIANT_IBM && |
364 | if (trackpoint_sync(psmouse, !reset_fail)) | 398 | trackpoint_power_on_reset(&psmouse->ps2dev) == 0; |
365 | return -1; | 399 | |
400 | error = trackpoint_sync(psmouse, was_reset); | ||
401 | if (error) | ||
402 | return error; | ||
366 | 403 | ||
367 | return 0; | 404 | return 0; |
368 | } | 405 | } |
@@ -370,46 +407,66 @@ static int trackpoint_reconnect(struct psmouse *psmouse) | |||
370 | int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | 407 | int trackpoint_detect(struct psmouse *psmouse, bool set_properties) |
371 | { | 408 | { |
372 | struct ps2dev *ps2dev = &psmouse->ps2dev; | 409 | struct ps2dev *ps2dev = &psmouse->ps2dev; |
373 | unsigned char firmware_id; | 410 | struct trackpoint_data *tp; |
374 | unsigned char button_info; | 411 | u8 variant_id; |
412 | u8 firmware_id; | ||
413 | u8 button_info; | ||
375 | int error; | 414 | int error; |
376 | 415 | ||
377 | if (trackpoint_start_protocol(psmouse, &firmware_id)) | 416 | error = trackpoint_start_protocol(psmouse, &variant_id, &firmware_id); |
378 | return -1; | 417 | if (error) |
418 | return error; | ||
379 | 419 | ||
380 | if (!set_properties) | 420 | if (!set_properties) |
381 | return 0; | 421 | return 0; |
382 | 422 | ||
383 | if (trackpoint_read(ps2dev, TP_EXT_BTN, &button_info)) { | 423 | tp = kzalloc(sizeof(*tp), GFP_KERNEL); |
384 | psmouse_warn(psmouse, "failed to get extended button data, assuming 3 buttons\n"); | 424 | if (!tp) |
385 | button_info = 0x33; | ||
386 | } | ||
387 | |||
388 | psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL); | ||
389 | if (!psmouse->private) | ||
390 | return -ENOMEM; | 425 | return -ENOMEM; |
391 | 426 | ||
392 | psmouse->vendor = "IBM"; | 427 | trackpoint_defaults(tp); |
428 | tp->variant_id = variant_id; | ||
429 | tp->firmware_id = firmware_id; | ||
430 | |||
431 | psmouse->private = tp; | ||
432 | |||
433 | psmouse->vendor = trackpoint_variants[variant_id]; | ||
393 | psmouse->name = "TrackPoint"; | 434 | psmouse->name = "TrackPoint"; |
394 | 435 | ||
395 | psmouse->reconnect = trackpoint_reconnect; | 436 | psmouse->reconnect = trackpoint_reconnect; |
396 | psmouse->disconnect = trackpoint_disconnect; | 437 | psmouse->disconnect = trackpoint_disconnect; |
397 | 438 | ||
439 | if (variant_id != TP_VARIANT_IBM) { | ||
440 | /* Newer variants do not support extended button query. */ | ||
441 | button_info = 0x33; | ||
442 | } else { | ||
443 | error = trackpoint_read(ps2dev, TP_EXT_BTN, &button_info); | ||
444 | if (error) { | ||
445 | psmouse_warn(psmouse, | ||
446 | "failed to get extended button data, assuming 3 buttons\n"); | ||
447 | button_info = 0x33; | ||
448 | } else if (!button_info) { | ||
449 | psmouse_warn(psmouse, | ||
450 | "got 0 in extended button data, assuming 3 buttons\n"); | ||
451 | button_info = 0x33; | ||
452 | } | ||
453 | } | ||
454 | |||
398 | if ((button_info & 0x0f) >= 3) | 455 | if ((button_info & 0x0f) >= 3) |
399 | __set_bit(BTN_MIDDLE, psmouse->dev->keybit); | 456 | input_set_capability(psmouse->dev, EV_KEY, BTN_MIDDLE); |
400 | 457 | ||
401 | __set_bit(INPUT_PROP_POINTER, psmouse->dev->propbit); | 458 | __set_bit(INPUT_PROP_POINTER, psmouse->dev->propbit); |
402 | __set_bit(INPUT_PROP_POINTING_STICK, psmouse->dev->propbit); | 459 | __set_bit(INPUT_PROP_POINTING_STICK, psmouse->dev->propbit); |
403 | 460 | ||
404 | trackpoint_defaults(psmouse->private); | 461 | if (variant_id != TP_VARIANT_IBM || |
405 | 462 | trackpoint_power_on_reset(ps2dev) != 0) { | |
406 | error = trackpoint_power_on_reset(ps2dev); | 463 | /* |
407 | 464 | * Write defaults to TP if we did not reset the trackpoint. | |
408 | /* Write defaults to TP only if reset fails. */ | 465 | */ |
409 | if (error) | ||
410 | trackpoint_sync(psmouse, false); | 466 | trackpoint_sync(psmouse, false); |
467 | } | ||
411 | 468 | ||
412 | error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group); | 469 | error = device_add_group(&ps2dev->serio->dev, &trackpoint_attr_group); |
413 | if (error) { | 470 | if (error) { |
414 | psmouse_err(psmouse, | 471 | psmouse_err(psmouse, |
415 | "failed to create sysfs attributes, error: %d\n", | 472 | "failed to create sysfs attributes, error: %d\n", |
@@ -420,8 +477,8 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) | |||
420 | } | 477 | } |
421 | 478 | ||
422 | psmouse_info(psmouse, | 479 | psmouse_info(psmouse, |
423 | "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n", | 480 | "%s TrackPoint firmware: 0x%02x, buttons: %d/%d\n", |
424 | firmware_id, | 481 | psmouse->vendor, firmware_id, |
425 | (button_info & 0xf0) >> 4, button_info & 0x0f); | 482 | (button_info & 0xf0) >> 4, button_info & 0x0f); |
426 | 483 | ||
427 | return 0; | 484 | return 0; |
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h index 88055755f82e..10a039148234 100644 --- a/drivers/input/mouse/trackpoint.h +++ b/drivers/input/mouse/trackpoint.h | |||
@@ -21,10 +21,16 @@ | |||
21 | #define TP_COMMAND 0xE2 /* Commands start with this */ | 21 | #define TP_COMMAND 0xE2 /* Commands start with this */ |
22 | 22 | ||
23 | #define TP_READ_ID 0xE1 /* Sent for device identification */ | 23 | #define TP_READ_ID 0xE1 /* Sent for device identification */ |
24 | #define TP_MAGIC_IDENT 0x03 /* Sent after a TP_READ_ID followed */ | ||
25 | /* by the firmware ID */ | ||
26 | /* Firmware ID includes 0x1, 0x2, 0x3 */ | ||
27 | 24 | ||
25 | /* | ||
26 | * Valid first byte responses to the "Read Secondary ID" (0xE1) command. | ||
27 | * 0x01 was the original IBM trackpoint, others implement very limited | ||
28 | * subset of trackpoint features. | ||
29 | */ | ||
30 | #define TP_VARIANT_IBM 0x01 | ||
31 | #define TP_VARIANT_ALPS 0x02 | ||
32 | #define TP_VARIANT_ELAN 0x03 | ||
33 | #define TP_VARIANT_NXP 0x04 | ||
28 | 34 | ||
29 | /* | 35 | /* |
30 | * Commands | 36 | * Commands |
@@ -136,18 +142,20 @@ | |||
136 | 142 | ||
137 | #define MAKE_PS2_CMD(params, results, cmd) ((params<<12) | (results<<8) | (cmd)) | 143 | #define MAKE_PS2_CMD(params, results, cmd) ((params<<12) | (results<<8) | (cmd)) |
138 | 144 | ||
139 | struct trackpoint_data | 145 | struct trackpoint_data { |
140 | { | 146 | u8 variant_id; |
141 | unsigned char sensitivity, speed, inertia, reach; | 147 | u8 firmware_id; |
142 | unsigned char draghys, mindrag; | 148 | |
143 | unsigned char thresh, upthresh; | 149 | u8 sensitivity, speed, inertia, reach; |
144 | unsigned char ztime, jenks; | 150 | u8 draghys, mindrag; |
145 | unsigned char drift_time; | 151 | u8 thresh, upthresh; |
152 | u8 ztime, jenks; | ||
153 | u8 drift_time; | ||
146 | 154 | ||
147 | /* toggles */ | 155 | /* toggles */ |
148 | unsigned char press_to_select; | 156 | bool press_to_select; |
149 | unsigned char skipback; | 157 | bool skipback; |
150 | unsigned char ext_dev; | 158 | bool ext_dev; |
151 | }; | 159 | }; |
152 | 160 | ||
153 | #ifdef CONFIG_MOUSE_PS2_TRACKPOINT | 161 | #ifdef CONFIG_MOUSE_PS2_TRACKPOINT |
diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c index ae966e333a2f..8a07ae147df6 100644 --- a/drivers/input/rmi4/rmi_f01.c +++ b/drivers/input/rmi4/rmi_f01.c | |||
@@ -570,14 +570,19 @@ static int rmi_f01_probe(struct rmi_function *fn) | |||
570 | 570 | ||
571 | dev_set_drvdata(&fn->dev, f01); | 571 | dev_set_drvdata(&fn->dev, f01); |
572 | 572 | ||
573 | error = devm_device_add_group(&fn->rmi_dev->dev, &rmi_f01_attr_group); | 573 | error = sysfs_create_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group); |
574 | if (error) | 574 | if (error) |
575 | dev_warn(&fn->dev, | 575 | dev_warn(&fn->dev, "Failed to create sysfs group: %d\n", error); |
576 | "Failed to create attribute group: %d\n", error); | ||
577 | 576 | ||
578 | return 0; | 577 | return 0; |
579 | } | 578 | } |
580 | 579 | ||
580 | static void rmi_f01_remove(struct rmi_function *fn) | ||
581 | { | ||
582 | /* Note that the bus device is used, not the F01 device */ | ||
583 | sysfs_remove_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group); | ||
584 | } | ||
585 | |||
581 | static int rmi_f01_config(struct rmi_function *fn) | 586 | static int rmi_f01_config(struct rmi_function *fn) |
582 | { | 587 | { |
583 | struct f01_data *f01 = dev_get_drvdata(&fn->dev); | 588 | struct f01_data *f01 = dev_get_drvdata(&fn->dev); |
@@ -717,6 +722,7 @@ struct rmi_function_handler rmi_f01_handler = { | |||
717 | }, | 722 | }, |
718 | .func = 0x01, | 723 | .func = 0x01, |
719 | .probe = rmi_f01_probe, | 724 | .probe = rmi_f01_probe, |
725 | .remove = rmi_f01_remove, | ||
720 | .config = rmi_f01_config, | 726 | .config = rmi_f01_config, |
721 | .attention = rmi_f01_attention, | 727 | .attention = rmi_f01_attention, |
722 | .suspend = rmi_f01_suspend, | 728 | .suspend = rmi_f01_suspend, |
diff --git a/drivers/input/touchscreen/s6sy761.c b/drivers/input/touchscreen/s6sy761.c index 26b1cb8a88ec..675efa93d444 100644 --- a/drivers/input/touchscreen/s6sy761.c +++ b/drivers/input/touchscreen/s6sy761.c | |||
@@ -1,13 +1,8 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | * Copyright (c) 2017 Samsung Electronics Co., Ltd. | 2 | // Samsung S6SY761 Touchscreen device driver |
3 | * Author: Andi Shyti <andi.shyti@samsung.com> | 3 | // |
4 | * | 4 | // Copyright (c) 2017 Samsung Electronics Co., Ltd. |
5 | * This program is free software; you can redistribute it and/or modify | 5 | // Copyright (c) 2017 Andi Shyti <andi.shyti@samsung.com> |
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * Samsung S6SY761 Touchscreen device driver | ||
10 | */ | ||
11 | 6 | ||
12 | #include <asm/unaligned.h> | 7 | #include <asm/unaligned.h> |
13 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c index c12d01899939..2a123e20a42e 100644 --- a/drivers/input/touchscreen/stmfts.c +++ b/drivers/input/touchscreen/stmfts.c | |||
@@ -1,13 +1,8 @@ | |||
1 | /* | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | * Copyright (c) 2017 Samsung Electronics Co., Ltd. | 2 | // STMicroelectronics FTS Touchscreen device driver |
3 | * Author: Andi Shyti <andi.shyti@samsung.com> | 3 | // |
4 | * | 4 | // Copyright (c) 2017 Samsung Electronics Co., Ltd. |
5 | * This program is free software; you can redistribute it and/or modify | 5 | // Copyright (c) 2017 Andi Shyti <andi.shyti@samsung.com> |
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * STMicroelectronics FTS Touchscreen device driver | ||
10 | */ | ||
11 | 6 | ||
12 | #include <linux/delay.h> | 7 | #include <linux/delay.h> |
13 | #include <linux/i2c.h> | 8 | #include <linux/i2c.h> |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 272c5962e4f7..8e91274174f1 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -2235,19 +2235,14 @@ static bool rtl8169_do_counters(struct net_device *dev, u32 counter_cmd) | |||
2235 | void __iomem *ioaddr = tp->mmio_addr; | 2235 | void __iomem *ioaddr = tp->mmio_addr; |
2236 | dma_addr_t paddr = tp->counters_phys_addr; | 2236 | dma_addr_t paddr = tp->counters_phys_addr; |
2237 | u32 cmd; | 2237 | u32 cmd; |
2238 | bool ret; | ||
2239 | 2238 | ||
2240 | RTL_W32(CounterAddrHigh, (u64)paddr >> 32); | 2239 | RTL_W32(CounterAddrHigh, (u64)paddr >> 32); |
2240 | RTL_R32(CounterAddrHigh); | ||
2241 | cmd = (u64)paddr & DMA_BIT_MASK(32); | 2241 | cmd = (u64)paddr & DMA_BIT_MASK(32); |
2242 | RTL_W32(CounterAddrLow, cmd); | 2242 | RTL_W32(CounterAddrLow, cmd); |
2243 | RTL_W32(CounterAddrLow, cmd | counter_cmd); | 2243 | RTL_W32(CounterAddrLow, cmd | counter_cmd); |
2244 | 2244 | ||
2245 | ret = rtl_udelay_loop_wait_low(tp, &rtl_counters_cond, 10, 1000); | 2245 | return rtl_udelay_loop_wait_low(tp, &rtl_counters_cond, 10, 1000); |
2246 | |||
2247 | RTL_W32(CounterAddrLow, 0); | ||
2248 | RTL_W32(CounterAddrHigh, 0); | ||
2249 | |||
2250 | return ret; | ||
2251 | } | 2246 | } |
2252 | 2247 | ||
2253 | static bool rtl8169_reset_counters(struct net_device *dev) | 2248 | static bool rtl8169_reset_counters(struct net_device *dev) |
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 195e0d0add8d..b919e89a9b93 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c | |||
@@ -829,7 +829,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, | |||
829 | int mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr) - | 829 | int mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr) - |
830 | GENEVE_BASE_HLEN - info->options_len - 14; | 830 | GENEVE_BASE_HLEN - info->options_len - 14; |
831 | 831 | ||
832 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | 832 | skb_dst_update_pmtu(skb, mtu); |
833 | } | 833 | } |
834 | 834 | ||
835 | sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); | 835 | sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); |
@@ -875,7 +875,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, | |||
875 | int mtu = dst_mtu(dst) - sizeof(struct ipv6hdr) - | 875 | int mtu = dst_mtu(dst) - sizeof(struct ipv6hdr) - |
876 | GENEVE_BASE_HLEN - info->options_len - 14; | 876 | GENEVE_BASE_HLEN - info->options_len - 14; |
877 | 877 | ||
878 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | 878 | skb_dst_update_pmtu(skb, mtu); |
879 | } | 879 | } |
880 | 880 | ||
881 | sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); | 881 | sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); |
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index feb1b2e15c2e..139c61c8244a 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c | |||
@@ -673,8 +673,9 @@ static struct sk_buff *vrf_ip_out(struct net_device *vrf_dev, | |||
673 | struct sock *sk, | 673 | struct sock *sk, |
674 | struct sk_buff *skb) | 674 | struct sk_buff *skb) |
675 | { | 675 | { |
676 | /* don't divert multicast */ | 676 | /* don't divert multicast or local broadcast */ |
677 | if (ipv4_is_multicast(ip_hdr(skb)->daddr)) | 677 | if (ipv4_is_multicast(ip_hdr(skb)->daddr) || |
678 | ipv4_is_lbcast(ip_hdr(skb)->daddr)) | ||
678 | return skb; | 679 | return skb; |
679 | 680 | ||
680 | if (qdisc_tx_is_default(vrf_dev)) | 681 | if (qdisc_tx_is_default(vrf_dev)) |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 82090ae7ced1..fab7a4db249e 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -2158,8 +2158,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
2158 | if (skb_dst(skb)) { | 2158 | if (skb_dst(skb)) { |
2159 | int mtu = dst_mtu(ndst) - VXLAN_HEADROOM; | 2159 | int mtu = dst_mtu(ndst) - VXLAN_HEADROOM; |
2160 | 2160 | ||
2161 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, | 2161 | skb_dst_update_pmtu(skb, mtu); |
2162 | skb, mtu); | ||
2163 | } | 2162 | } |
2164 | 2163 | ||
2165 | tos = ip_tunnel_ecn_encap(tos, old_iph, skb); | 2164 | tos = ip_tunnel_ecn_encap(tos, old_iph, skb); |
@@ -2200,8 +2199,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, | |||
2200 | if (skb_dst(skb)) { | 2199 | if (skb_dst(skb)) { |
2201 | int mtu = dst_mtu(ndst) - VXLAN6_HEADROOM; | 2200 | int mtu = dst_mtu(ndst) - VXLAN6_HEADROOM; |
2202 | 2201 | ||
2203 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, | 2202 | skb_dst_update_pmtu(skb, mtu); |
2204 | skb, mtu); | ||
2205 | } | 2203 | } |
2206 | 2204 | ||
2207 | tos = ip_tunnel_ecn_encap(tos, old_iph, skb); | 2205 | tos = ip_tunnel_ecn_encap(tos, old_iph, skb); |
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 056276101c63..a6226cd6063c 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -1633,28 +1633,18 @@ void btrfs_readdir_put_delayed_items(struct inode *inode, | |||
1633 | int btrfs_should_delete_dir_index(struct list_head *del_list, | 1633 | int btrfs_should_delete_dir_index(struct list_head *del_list, |
1634 | u64 index) | 1634 | u64 index) |
1635 | { | 1635 | { |
1636 | struct btrfs_delayed_item *curr, *next; | 1636 | struct btrfs_delayed_item *curr; |
1637 | int ret; | 1637 | int ret = 0; |
1638 | |||
1639 | if (list_empty(del_list)) | ||
1640 | return 0; | ||
1641 | 1638 | ||
1642 | list_for_each_entry_safe(curr, next, del_list, readdir_list) { | 1639 | list_for_each_entry(curr, del_list, readdir_list) { |
1643 | if (curr->key.offset > index) | 1640 | if (curr->key.offset > index) |
1644 | break; | 1641 | break; |
1645 | 1642 | if (curr->key.offset == index) { | |
1646 | list_del(&curr->readdir_list); | 1643 | ret = 1; |
1647 | ret = (curr->key.offset == index); | 1644 | break; |
1648 | 1645 | } | |
1649 | if (refcount_dec_and_test(&curr->refs)) | ||
1650 | kfree(curr); | ||
1651 | |||
1652 | if (ret) | ||
1653 | return 1; | ||
1654 | else | ||
1655 | continue; | ||
1656 | } | 1646 | } |
1657 | return 0; | 1647 | return ret; |
1658 | } | 1648 | } |
1659 | 1649 | ||
1660 | /* | 1650 | /* |
diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 1668fd645c45..0d228cd087e6 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c | |||
@@ -452,7 +452,7 @@ ssize_t orangefs_inode_read(struct inode *inode, | |||
452 | static ssize_t orangefs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) | 452 | static ssize_t orangefs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) |
453 | { | 453 | { |
454 | struct file *file = iocb->ki_filp; | 454 | struct file *file = iocb->ki_filp; |
455 | loff_t pos = *(&iocb->ki_pos); | 455 | loff_t pos = iocb->ki_pos; |
456 | ssize_t rc = 0; | 456 | ssize_t rc = 0; |
457 | 457 | ||
458 | BUG_ON(iocb->private); | 458 | BUG_ON(iocb->private); |
@@ -492,9 +492,6 @@ static ssize_t orangefs_file_write_iter(struct kiocb *iocb, struct iov_iter *ite | |||
492 | } | 492 | } |
493 | } | 493 | } |
494 | 494 | ||
495 | if (file->f_pos > i_size_read(file->f_mapping->host)) | ||
496 | orangefs_i_size_write(file->f_mapping->host, file->f_pos); | ||
497 | |||
498 | rc = generic_write_checks(iocb, iter); | 495 | rc = generic_write_checks(iocb, iter); |
499 | 496 | ||
500 | if (rc <= 0) { | 497 | if (rc <= 0) { |
@@ -508,7 +505,7 @@ static ssize_t orangefs_file_write_iter(struct kiocb *iocb, struct iov_iter *ite | |||
508 | * pos to the end of the file, so we will wait till now to set | 505 | * pos to the end of the file, so we will wait till now to set |
509 | * pos... | 506 | * pos... |
510 | */ | 507 | */ |
511 | pos = *(&iocb->ki_pos); | 508 | pos = iocb->ki_pos; |
512 | 509 | ||
513 | rc = do_readv_writev(ORANGEFS_IO_WRITE, | 510 | rc = do_readv_writev(ORANGEFS_IO_WRITE, |
514 | file, | 511 | file, |
diff --git a/fs/orangefs/orangefs-kernel.h b/fs/orangefs/orangefs-kernel.h index 97adf7d100b5..2595453fe737 100644 --- a/fs/orangefs/orangefs-kernel.h +++ b/fs/orangefs/orangefs-kernel.h | |||
@@ -533,17 +533,6 @@ do { \ | |||
533 | sys_attr.mask = ORANGEFS_ATTR_SYS_ALL_SETABLE; \ | 533 | sys_attr.mask = ORANGEFS_ATTR_SYS_ALL_SETABLE; \ |
534 | } while (0) | 534 | } while (0) |
535 | 535 | ||
536 | static inline void orangefs_i_size_write(struct inode *inode, loff_t i_size) | ||
537 | { | ||
538 | #if BITS_PER_LONG == 32 && defined(CONFIG_SMP) | ||
539 | inode_lock(inode); | ||
540 | #endif | ||
541 | i_size_write(inode, i_size); | ||
542 | #if BITS_PER_LONG == 32 && defined(CONFIG_SMP) | ||
543 | inode_unlock(inode); | ||
544 | #endif | ||
545 | } | ||
546 | |||
547 | static inline void orangefs_set_timeout(struct dentry *dentry) | 536 | static inline void orangefs_set_timeout(struct dentry *dentry) |
548 | { | 537 | { |
549 | unsigned long time = jiffies + orangefs_dcache_timeout_msecs*HZ/1000; | 538 | unsigned long time = jiffies + orangefs_dcache_timeout_msecs*HZ/1000; |
diff --git a/include/net/dst.h b/include/net/dst.h index 33d2a5433924..c63d2c37f6e9 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
@@ -504,4 +504,12 @@ static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst) | |||
504 | } | 504 | } |
505 | #endif | 505 | #endif |
506 | 506 | ||
507 | static inline void skb_dst_update_pmtu(struct sk_buff *skb, u32 mtu) | ||
508 | { | ||
509 | struct dst_entry *dst = skb_dst(skb); | ||
510 | |||
511 | if (dst && dst->ops->update_pmtu) | ||
512 | dst->ops->update_pmtu(dst, NULL, skb, mtu); | ||
513 | } | ||
514 | |||
507 | #endif /* _NET_DST_H */ | 515 | #endif /* _NET_DST_H */ |
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index f8a84a2c2341..f306b2aa15a4 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h | |||
@@ -223,6 +223,11 @@ int net_eq(const struct net *net1, const struct net *net2) | |||
223 | return net1 == net2; | 223 | return net1 == net2; |
224 | } | 224 | } |
225 | 225 | ||
226 | static inline int check_net(const struct net *net) | ||
227 | { | ||
228 | return refcount_read(&net->count) != 0; | ||
229 | } | ||
230 | |||
226 | void net_drop_ns(void *); | 231 | void net_drop_ns(void *); |
227 | 232 | ||
228 | #else | 233 | #else |
@@ -247,6 +252,11 @@ int net_eq(const struct net *net1, const struct net *net2) | |||
247 | return 1; | 252 | return 1; |
248 | } | 253 | } |
249 | 254 | ||
255 | static inline int check_net(const struct net *net) | ||
256 | { | ||
257 | return 1; | ||
258 | } | ||
259 | |||
250 | #define net_drop_ns NULL | 260 | #define net_drop_ns NULL |
251 | #endif | 261 | #endif |
252 | 262 | ||
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 1c75cd1255f6..92d016e87816 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c | |||
@@ -140,6 +140,9 @@ static void ccid2_hc_tx_rto_expire(struct timer_list *t) | |||
140 | 140 | ||
141 | ccid2_pr_debug("RTO_EXPIRE\n"); | 141 | ccid2_pr_debug("RTO_EXPIRE\n"); |
142 | 142 | ||
143 | if (sk->sk_state == DCCP_CLOSED) | ||
144 | goto out; | ||
145 | |||
143 | /* back-off timer */ | 146 | /* back-off timer */ |
144 | hc->tx_rto <<= 1; | 147 | hc->tx_rto <<= 1; |
145 | if (hc->tx_rto > DCCP_RTO_MAX) | 148 | if (hc->tx_rto > DCCP_RTO_MAX) |
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 141f5e865731..d786a8441bce 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
@@ -520,8 +520,7 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb, | |||
520 | else | 520 | else |
521 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; | 521 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; |
522 | 522 | ||
523 | if (skb_dst(skb)) | 523 | skb_dst_update_pmtu(skb, mtu); |
524 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | ||
525 | 524 | ||
526 | if (skb->protocol == htons(ETH_P_IP)) { | 525 | if (skb->protocol == htons(ETH_P_IP)) { |
527 | if (!skb_is_gso(skb) && | 526 | if (!skb_is_gso(skb) && |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 949f432a5f04..51b1669334fe 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -200,7 +200,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev, | |||
200 | 200 | ||
201 | mtu = dst_mtu(dst); | 201 | mtu = dst_mtu(dst); |
202 | if (skb->len > mtu) { | 202 | if (skb->len > mtu) { |
203 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | 203 | skb_dst_update_pmtu(skb, mtu); |
204 | if (skb->protocol == htons(ETH_P_IP)) { | 204 | if (skb->protocol == htons(ETH_P_IP)) { |
205 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, | 205 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, |
206 | htonl(mtu)); | 206 | htonl(mtu)); |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f013ddc191e0..c8ed3a04b504 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -2322,6 +2322,9 @@ adjudge_to_death: | |||
2322 | tcp_send_active_reset(sk, GFP_ATOMIC); | 2322 | tcp_send_active_reset(sk, GFP_ATOMIC); |
2323 | __NET_INC_STATS(sock_net(sk), | 2323 | __NET_INC_STATS(sock_net(sk), |
2324 | LINUX_MIB_TCPABORTONMEMORY); | 2324 | LINUX_MIB_TCPABORTONMEMORY); |
2325 | } else if (!check_net(sock_net(sk))) { | ||
2326 | /* Not possible to send reset; just close */ | ||
2327 | tcp_set_state(sk, TCP_CLOSE); | ||
2325 | } | 2328 | } |
2326 | } | 2329 | } |
2327 | 2330 | ||
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 257abdde23b0..71fc60f1b326 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -48,11 +48,19 @@ static void tcp_write_err(struct sock *sk) | |||
48 | * to prevent DoS attacks. It is called when a retransmission timeout | 48 | * to prevent DoS attacks. It is called when a retransmission timeout |
49 | * or zero probe timeout occurs on orphaned socket. | 49 | * or zero probe timeout occurs on orphaned socket. |
50 | * | 50 | * |
51 | * Also close if our net namespace is exiting; in that case there is no | ||
52 | * hope of ever communicating again since all netns interfaces are already | ||
53 | * down (or about to be down), and we need to release our dst references, | ||
54 | * which have been moved to the netns loopback interface, so the namespace | ||
55 | * can finish exiting. This condition is only possible if we are a kernel | ||
56 | * socket, as those do not hold references to the namespace. | ||
57 | * | ||
51 | * Criteria is still not confirmed experimentally and may change. | 58 | * Criteria is still not confirmed experimentally and may change. |
52 | * We kill the socket, if: | 59 | * We kill the socket, if: |
53 | * 1. If number of orphaned sockets exceeds an administratively configured | 60 | * 1. If number of orphaned sockets exceeds an administratively configured |
54 | * limit. | 61 | * limit. |
55 | * 2. If we have strong memory pressure. | 62 | * 2. If we have strong memory pressure. |
63 | * 3. If our net namespace is exiting. | ||
56 | */ | 64 | */ |
57 | static int tcp_out_of_resources(struct sock *sk, bool do_reset) | 65 | static int tcp_out_of_resources(struct sock *sk, bool do_reset) |
58 | { | 66 | { |
@@ -81,6 +89,13 @@ static int tcp_out_of_resources(struct sock *sk, bool do_reset) | |||
81 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); | 89 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); |
82 | return 1; | 90 | return 1; |
83 | } | 91 | } |
92 | |||
93 | if (!check_net(sock_net(sk))) { | ||
94 | /* Not possible to send reset; just close */ | ||
95 | tcp_done(sk); | ||
96 | return 1; | ||
97 | } | ||
98 | |||
84 | return 0; | 99 | return 0; |
85 | } | 100 | } |
86 | 101 | ||
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 8071f42cd8a0..4b15fe928278 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -642,8 +642,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
642 | if (rel_info > dst_mtu(skb_dst(skb2))) | 642 | if (rel_info > dst_mtu(skb_dst(skb2))) |
643 | goto out; | 643 | goto out; |
644 | 644 | ||
645 | skb_dst(skb2)->ops->update_pmtu(skb_dst(skb2), NULL, skb2, | 645 | skb_dst_update_pmtu(skb2, rel_info); |
646 | rel_info); | ||
647 | } | 646 | } |
648 | 647 | ||
649 | icmp_send(skb2, rel_type, rel_code, htonl(rel_info)); | 648 | icmp_send(skb2, rel_type, rel_code, htonl(rel_info)); |
@@ -1134,8 +1133,7 @@ route_lookup: | |||
1134 | mtu = 576; | 1133 | mtu = 576; |
1135 | } | 1134 | } |
1136 | 1135 | ||
1137 | if (skb_dst(skb) && !t->parms.collect_md) | 1136 | skb_dst_update_pmtu(skb, mtu); |
1138 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | ||
1139 | if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { | 1137 | if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { |
1140 | *pmtu = mtu; | 1138 | *pmtu = mtu; |
1141 | err = -EMSGSIZE; | 1139 | err = -EMSGSIZE; |
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index 18caa9539e6d..fa3ae1cb50d3 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -483,7 +483,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) | |||
483 | 483 | ||
484 | mtu = dst_mtu(dst); | 484 | mtu = dst_mtu(dst); |
485 | if (!skb->ignore_df && skb->len > mtu) { | 485 | if (!skb->ignore_df && skb->len > mtu) { |
486 | skb_dst(skb)->ops->update_pmtu(dst, NULL, skb, mtu); | 486 | skb_dst_update_pmtu(skb, mtu); |
487 | 487 | ||
488 | if (skb->protocol == htons(ETH_P_IPV6)) { | 488 | if (skb->protocol == htons(ETH_P_IPV6)) { |
489 | if (mtu < IPV6_MIN_MTU) | 489 | if (mtu < IPV6_MIN_MTU) |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index d7dc23c1b2ca..3873d3877135 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -934,8 +934,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
934 | df = 0; | 934 | df = 0; |
935 | } | 935 | } |
936 | 936 | ||
937 | if (tunnel->parms.iph.daddr && skb_dst(skb)) | 937 | if (tunnel->parms.iph.daddr) |
938 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | 938 | skb_dst_update_pmtu(skb, mtu); |
939 | 939 | ||
940 | if (skb->len > mtu && !skb_is_gso(skb)) { | 940 | if (skb->len > mtu && !skb_is_gso(skb)) { |
941 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 941 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 5d28abf87fbf..c9473d698525 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c | |||
@@ -951,7 +951,7 @@ static unsigned int vsock_poll(struct file *file, struct socket *sock, | |||
951 | * POLLOUT|POLLWRNORM when peer is closed and nothing to read, | 951 | * POLLOUT|POLLWRNORM when peer is closed and nothing to read, |
952 | * but local send is not shutdown. | 952 | * but local send is not shutdown. |
953 | */ | 953 | */ |
954 | if (sk->sk_state == TCP_CLOSE) { | 954 | if (sk->sk_state == TCP_CLOSE || sk->sk_state == TCP_CLOSING) { |
955 | if (!(sk->sk_shutdown & SEND_SHUTDOWN)) | 955 | if (!(sk->sk_shutdown & SEND_SHUTDOWN)) |
956 | mask |= POLLOUT | POLLWRNORM; | 956 | mask |= POLLOUT | POLLWRNORM; |
957 | 957 | ||