From e862f5583a92ac9680bdb18a0e5dffe2a2c3d464 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 11 Feb 2013 20:49:49 +0100 Subject: PCI/PM: Clean up PME state when removing a device commit 249bfb83cf8ba658955f0245ac3981d941f746ee upstream. Devices are added to pci_pme_list when drivers use pci_enable_wake() or pci_wake_from_d3(), but they aren't removed from the list unless the driver explicitly disables wakeup. Many drivers never disable wakeup, so their devices remain on the list even after they are removed, e.g., via hotplug. A subsequent PME poll will oops when it tries to touch the device. This patch disables PME# on a device before removing it, which removes the device from pci_pme_list. This is safe even if the device never had PME# enabled. This oops can be triggered by unplugging a Thunderbolt ethernet adapter on a Macbook Pro, as reported by Daniel below. [bhelgaas: changelog] Reference: http://lkml.kernel.org/r/CAMVG2svG21yiM1wkH4_2pen2n+cr2-Zv7TbH3Gj+8MwevZjDbw@mail.gmail.com Reported-and-tested-by: Daniel J Blueman Signed-off-by: Rafael J. Wysocki Signed-off-by: Bjorn Helgaas Signed-off-by: Greg Kroah-Hartman --- drivers/pci/remove.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 7f87bee..f53da9e 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -19,6 +19,8 @@ static void pci_free_resources(struct pci_dev *dev) static void pci_stop_dev(struct pci_dev *dev) { + pci_pme_active(dev, false); + if (dev->is_added) { pci_proc_detach_device(dev); pci_remove_sysfs_dev_files(dev); -- cgit v1.1 From f4dc0e6ec906da70d1edf6d00f49b792f47f2efd Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Wed, 8 Aug 2012 05:23:22 +0000 Subject: igb: Remove artificial restriction on RQDPC stat reading commit ae1c07a6b7ced6c0c94c99e3b53f4e7856fa8bff upstream. For some reason the reading of the RQDPC register was being artificially limited to 4K. Instead of limiting the value we should read the value and add the full amount. Otherwise this can lead to a misleading number of dropped packets when the actual value is in fact much higher. Signed-off-by: Alexander Duyck Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher Cc: Vinson Lee Signed-off-by: Greg Kroah-Hartman --- drivers/net/igb/igb_main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 97f46ac..a5d98a3 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -4521,11 +4521,13 @@ void igb_update_stats(struct igb_adapter *adapter, bytes = 0; packets = 0; for (i = 0; i < adapter->num_rx_queues; i++) { - u32 rqdpc_tmp = rd32(E1000_RQDPC(i)) & 0x0FFF; + u32 rqdpc = rd32(E1000_RQDPC(i)); struct igb_ring *ring = adapter->rx_ring[i]; - ring->rx_stats.drops += rqdpc_tmp; - net_stats->rx_fifo_errors += rqdpc_tmp; + if (rqdpc) { + ring->rx_stats.drops += rqdpc; + net_stats->rx_fifo_errors += rqdpc; + } do { start = u64_stats_fetch_begin_bh(&ring->rx_syncp); -- cgit v1.1 From 13efbfc6083d955929052394254d1ccba840edfc Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 29 Jan 2013 20:07:41 +0100 Subject: tty: set_termios/set_termiox should not return -EINTR commit 183d95cdd834381c594d3aa801c1f9f9c0c54fa9 upstream. See https://bugzilla.redhat.com/show_bug.cgi?id=904907 read command causes bash to abort with double free or corruption (out). A simple test-case from Roman: // Compile the reproducer and send sigchld ti that process. // EINTR occurs even if SA_RESTART flag is set. void handler(int sig) { } main() { struct sigaction act; act.sa_handler = handler; act.sa_flags = SA_RESTART; sigaction (SIGCHLD, &act, 0); struct termio ttp; ioctl(0, TCGETA, &ttp); while(1) { if (ioctl(0, TCSETAW, ttp) < 0) { if (errno == EINTR) { fprintf(stderr, "BUG!"); return(1); } } } } Change set_termios/set_termiox to return -ERESTARTSYS to fix this particular problem. I didn't dare to change other EINTR's in drivers/tty/, but they look equally wrong. Reported-by: Roman Rakus Reported-by: Lingzhu Xiang Signed-off-by: Oleg Nesterov Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index 53f2442..3047873 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c @@ -617,7 +617,7 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) if (opt & TERMIOS_WAIT) { tty_wait_until_sent(tty, 0); if (signal_pending(current)) - return -EINTR; + return -ERESTARTSYS; } tty_set_termios(tty, &tmp_termios); @@ -684,7 +684,7 @@ static int set_termiox(struct tty_struct *tty, void __user *arg, int opt) if (opt & TERMIOS_WAIT) { tty_wait_until_sent(tty, 0); if (signal_pending(current)) - return -EINTR; + return -ERESTARTSYS; } mutex_lock(&tty->termios_mutex); -- cgit v1.1 From 212d2748ffe43d4e2756be40ddfdd7044197936d Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 19 Feb 2013 09:05:46 +0000 Subject: xen/netback: check correct frag when looking for head frag When I backported 7d5145d8eb2b "xen/netback: don't leak pages on failure in xen_netbk_tx_check_gop" to 3.0 (where it became f0457844e605) I somehow picked up an extraneous hunk breaking this. Reported-by: Herton Ronaldo Krzesinski Signed-off-by: Ian Campbell Signed-off-by: Greg Kroah-Hartman --- drivers/net/xen-netback/netback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 9068d32..6ed44c3 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -990,7 +990,7 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk, xen_netbk_idx_release(netbk, pending_idx, XEN_NETIF_RSP_ERROR); /* Skip first skb fragment if it is on same page as header fragment. */ - start = ((unsigned long)shinfo->frags[i].page == pending_idx); + start = ((unsigned long)shinfo->frags[0].page == pending_idx); for (i = start; i < nr_frags; i++) { int j, newerr; -- cgit v1.1 From 0eec39b02834d2af586ec6ebe84117273995021c Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 29 Jan 2013 16:44:27 -0700 Subject: Driver core: treat unregistered bus_types as having no devices commit 4fa3e78be7e985ca814ce2aa0c09cbee404efcf7 upstream. A bus_type has a list of devices (klist_devices), but the list and the subsys_private structure that contains it are not initialized until the bus_type is registered with bus_register(). The panic/reboot path has fixups that look up devices in pci_bus_type. If we panic before registering pci_bus_type, the bus_type exists but the list does not, so mach_reboot_fixups() trips over a null pointer and panics again: mach_reboot_fixups pci_get_device .. bus_find_device(&pci_bus_type, ...) bus->p is NULL Joonsoo reported a problem when panicking before PCI was initialized. I think this patch should be sufficient to replace the patch he posted here: https://lkml.org/lkml/2012/12/28/75 ("[PATCH] x86, reboot: skip reboot_fixups in early boot phase") Reported-by: Joonsoo Kim Signed-off-by: Bjorn Helgaas Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 000e7b2..8b8e8c0 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -289,7 +289,7 @@ int bus_for_each_dev(struct bus_type *bus, struct device *start, struct device *dev; int error = 0; - if (!bus) + if (!bus || !bus->p) return -EINVAL; klist_iter_init_node(&bus->p->klist_devices, &i, @@ -323,7 +323,7 @@ struct device *bus_find_device(struct bus_type *bus, struct klist_iter i; struct device *dev; - if (!bus) + if (!bus || !bus->p) return NULL; klist_iter_init_node(&bus->p->klist_devices, &i, -- cgit v1.1 From 25adbf9cfa6ea467b681a11219d29c7ff41637c7 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Fri, 14 Dec 2012 17:02:16 +0100 Subject: KVM: s390: Handle hosts not supporting s390-virtio. commit 55c171a6d90dc0574021f9c836127cfd1a7d2e30 upstream. Running under a kvm host does not necessarily imply the presence of a page mapped above the main memory with the virtio information; however, the code includes a hard coded access to that page. Instead, check for the presence of the page and exit gracefully before we hit an addressing exception if it does not exist. Reviewed-by: Marcelo Tosatti Reviewed-by: Alexander Graf Signed-off-by: Cornelia Huck Signed-off-by: Gleb Natapov Signed-off-by: Greg Kroah-Hartman --- drivers/s390/kvm/kvm_virtio.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index aec60d5..481037d 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c @@ -413,6 +413,26 @@ static void kvm_extint_handler(unsigned int ext_int_code, } /* + * For s390-virtio, we expect a page above main storage containing + * the virtio configuration. Try to actually load from this area + * in order to figure out if the host provides this page. + */ +static int __init test_devices_support(unsigned long addr) +{ + int ret = -EIO; + + asm volatile( + "0: lura 0,%1\n" + "1: xgr %0,%0\n" + "2:\n" + EX_TABLE(0b,2b) + EX_TABLE(1b,2b) + : "+d" (ret) + : "a" (addr) + : "0", "cc"); + return ret; +} +/* * Init function for virtio * devices are in a single page above top of "normal" mem */ @@ -423,21 +443,23 @@ static int __init kvm_devices_init(void) if (!MACHINE_IS_KVM) return -ENODEV; + if (test_devices_support(real_memory_size) < 0) + return -ENODEV; + + rc = vmem_add_mapping(real_memory_size, PAGE_SIZE); + if (rc) + return rc; + + kvm_devices = (void *) real_memory_size; + kvm_root = root_device_register("kvm_s390"); if (IS_ERR(kvm_root)) { rc = PTR_ERR(kvm_root); printk(KERN_ERR "Could not register kvm_s390 root device"); + vmem_remove_mapping(real_memory_size, PAGE_SIZE); return rc; } - rc = vmem_add_mapping(real_memory_size, PAGE_SIZE); - if (rc) { - root_device_unregister(kvm_root); - return rc; - } - - kvm_devices = (void *) real_memory_size; - INIT_WORK(&hotplug_work, hotplug_devices); service_subclass_irq_register(); -- cgit v1.1 From 36c15fe81edd6963781d3472d27b199279f5d28a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 21 Feb 2013 16:44:04 -0800 Subject: drivers/video/backlight/adp88?0_bl.c: fix resume commit 5eb02c01bd1f3ef195989ab05e835e2b0711b5a9 upstream. Clearing the NSTBY bit in the control register also automatically clears the BLEN bit. So we need to make sure to set it again during resume, otherwise the backlight will stay off. Signed-off-by: Lars-Peter Clausen Acked-by: Michael Hennerich Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/video/backlight/adp8860_bl.c | 2 +- drivers/video/backlight/adp8870_bl.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index d2a96a4..ee0f001 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c @@ -793,7 +793,7 @@ static int adp8860_i2c_suspend(struct i2c_client *client, pm_message_t message) static int adp8860_i2c_resume(struct i2c_client *client) { - adp8860_set_bits(client, ADP8860_MDCR, NSTBY); + adp8860_set_bits(client, ADP8860_MDCR, NSTBY | BLEN); return 0; } diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c index 05a8832..bc0503a 100644 --- a/drivers/video/backlight/adp8870_bl.c +++ b/drivers/video/backlight/adp8870_bl.c @@ -968,7 +968,7 @@ static int adp8870_i2c_suspend(struct i2c_client *client, pm_message_t message) static int adp8870_i2c_resume(struct i2c_client *client) { - adp8870_set_bits(client, ADP8870_MDCR, NSTBY); + adp8870_set_bits(client, ADP8870_MDCR, NSTBY | BLEN); return 0; } -- cgit v1.1 From e487015297fca084180281fbc0ecdbf757ddbebe Mon Sep 17 00:00:00 2001 From: Tomasz Guszkowski Date: Tue, 5 Feb 2013 22:10:31 +0100 Subject: p54usb: corrected USB ID for T-Com Sinus 154 data II commit 008e33f733ca51acb2dd9d88ea878693b04d1d2a upstream. Corrected USB ID for T-Com Sinus 154 data II. ISL3887-based. The device was tested in managed mode with no security, WEP 128 bit and WPA-PSK (TKIP) with firmware 2.13.1.0.lm87.arm (md5sum: 7d676323ac60d6e1a3b6d61e8c528248). It works. Signed-off-by: Tomasz Guszkowski Acked-By: Christian Lamparter Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/p54/p54usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index f1fa763..99e7e7f 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -83,8 +83,8 @@ static struct usb_device_id p54u_table[] = { {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */ - {USB_DEVICE(0x083a, 0x4503)}, /* T-Com Sinus 154 data II */ {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ + {USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */ {USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */ {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */ {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ -- cgit v1.1 From ddab81f4d0998efd4d3e288a26379fb4957cb5f7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 14 Feb 2013 11:49:01 -0800 Subject: sunvdc: Fix off-by-one in generic_request(). [ Upstream commit f4d9605434c0fd4cc8639bf25cfc043418c52362 ] The 'operations' bitmap corresponds one-for-one with the operation codes, no adjustment is necessary. Reported-by: Mark Kettenis Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/block/sunvdc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 48e8fee..94f6ae2 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -461,7 +461,7 @@ static int generic_request(struct vdc_port *port, u8 op, void *buf, int len) int op_len, err; void *req_buf; - if (!(((u64)1 << ((u64)op - 1)) & port->operations)) + if (!(((u64)1 << (u64)op) & port->operations)) return -EOPNOTSUPP; switch (op) { -- cgit v1.1 From 4b5784741fdfdb5fa91edc6ea8fc5eeeed0b4a6a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 7 Feb 2013 10:10:04 +1000 Subject: drm/usb: bind driver to correct device commit 9f23de52b64f7fb801fd76f3dd8651a0dc89187b upstream. While looking at plymouth on udl I noticed that plymouth was trying to use its fb plugin not its drm one, it was trying to drmOpen a driver called usb not udl, noticed that we actually had out driver pointing at the wrong device. Signed-off-by: Dave Airlie Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c index 206d230..0c853f5 100644 --- a/drivers/gpu/drm/drm_usb.c +++ b/drivers/gpu/drm/drm_usb.c @@ -18,7 +18,7 @@ int drm_get_usb_dev(struct usb_interface *interface, usbdev = interface_to_usbdev(interface); dev->usbdev = usbdev; - dev->dev = &usbdev->dev; + dev->dev = &interface->dev; mutex_lock(&drm_global_mutex); -- cgit v1.1 From 8eac4364548b8f53476602969a2fba65d029d8b7 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 17 Nov 2011 16:42:19 -0500 Subject: NLS: improve UTF8 -> UTF16 string conversion routine commit 0720a06a7518c9d0c0125bd5d1f3b6264c55c3dd upstream. The utf8s_to_utf16s conversion routine needs to be improved. Unlike its utf16s_to_utf8s sibling, it doesn't accept arguments specifying the maximum length of the output buffer or the endianness of its 16-bit output. This patch (as1501) adds the two missing arguments, and adjusts the only two places in the kernel where the function is called. A follow-on patch will add a third caller that does utilize the new capabilities. The two conversion routines are still annoyingly inconsistent in the way they handle invalid byte combinations. But that's a subject for a different patch. Signed-off-by: Alan Stern CC: Clemens Ladisch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_kvp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/hv_kvp.c b/drivers/staging/hv/hv_kvp.c index 13b0ecf..9f8efd4 100644 --- a/drivers/staging/hv/hv_kvp.c +++ b/drivers/staging/hv/hv_kvp.c @@ -201,11 +201,13 @@ kvp_respond_to_host(char *key, char *value, int error) * The windows host expects the key/value pair to be encoded * in utf16. */ - keylen = utf8s_to_utf16s(key_name, strlen(key_name), - (wchar_t *)kvp_data->data.key); + keylen = utf8s_to_utf16s(key_name, strlen(key_name), UTF16_HOST_ENDIAN, + (wchar_t *) kvp_data->data.key, + HV_KVP_EXCHANGE_MAX_KEY_SIZE / 2); kvp_data->data.key_size = 2*(keylen + 1); /* utf16 encoding */ - valuelen = utf8s_to_utf16s(value, strlen(value), - (wchar_t *)kvp_data->data.value); + valuelen = utf8s_to_utf16s(value, strlen(value), UTF16_HOST_ENDIAN, + (wchar_t *) kvp_data->data.value, + HV_KVP_EXCHANGE_MAX_VALUE_SIZE / 2); kvp_data->data.value_size = 2*(valuelen + 1); /* utf16 encoding */ kvp_data->data.value_type = REG_SZ; /* all our values are strings */ -- cgit v1.1 From 2fb8324e4a70aef032d156ce26b979c7de59303f Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Fri, 8 Feb 2013 16:35:37 +0200 Subject: drm/i915: disable shared panel fitter for pipe commit 24a1f16de97c4cf0029d9acd04be06db32208726 upstream. If encoder is switched off by BIOS, but the panel fitter is left on, we never try to turn off the panel fitter and leave it still attached to the pipe - which can cause blurry output elsewhere. Based on work by Chris Wilson Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=58867 Signed-off-by: Mika Kuoppala Tested-by: Andreas Sturmlechner [danvet: Remove the redundant HAS_PCH_SPLIT check and add a tiny comment.] Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_display.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b4f4d12..11ecb0c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2898,6 +2898,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; int plane = intel_crtc->plane; + u32 pctl; if (!intel_crtc->active) return; @@ -2914,6 +2915,13 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) intel_disable_plane(dev_priv, plane, pipe); intel_disable_pipe(dev_priv, pipe); + + /* Disable pannel fitter if it is on this pipe. */ + pctl = I915_READ(PFIT_CONTROL); + if ((pctl & PFIT_ENABLE) && + ((pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT) == pipe) + I915_WRITE(PFIT_CONTROL, 0); + intel_disable_pll(dev_priv, pipe); intel_crtc->active = false; -- cgit v1.1 From 1646fff8a00d797cbaa0d711f29d3102cc7c022f Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 28 Jan 2013 16:14:31 +0000 Subject: staging: comedi: disallow COMEDI_DEVCONFIG on non-board minors commit 754ab5c0e55dd118273ca2c217c4d95e9fbc8259 upstream. Comedi has two sorts of minor devices: (a) normal board minor devices in the range 0 to COMEDI_NUM_BOARD_MINORS-1 inclusive; and (b) special subdevice minor devices in the range COMEDI_NUM_BOARD_MINORS upwards that are used to open the same underlying comedi device as the normal board minor devices, but with non-default read and write subdevices for asynchronous commands. The special subdevice minor devices get created when a board supporting asynchronous commands is attached to a normal board minor device, and destroyed when the board is detached from the normal board minor device. One way to attach or detach a board is by using the COMEDI_DEVCONFIG ioctl. This should only be used on normal board minors as the special subdevice minors are too ephemeral. In particular, the change introduced in commit 7d3135af399e92cf4c9bbc5f86b6c140aab3b88c ("staging: comedi: prevent auto-unconfig of manually configured devices") breaks horribly for special subdevice minor devices. Since there's no legitimate use for the COMEDI_DEVCONFIG ioctl on a special subdevice minor device node, disallow it and return -ENOTTY. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 39be673..4b9d8f0 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -136,6 +136,11 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, /* Device config is special, because it must work on * an unconfigured device. */ if (cmd == COMEDI_DEVCONFIG) { + if (minor >= COMEDI_NUM_BOARD_MINORS) { + /* Device config not appropriate on non-board minors. */ + rc = -ENOTTY; + goto done; + } rc = do_devconfig_ioctl(dev, (struct comedi_devconfig __user *)arg); if (rc == 0) -- cgit v1.1 From 02424a5539959f519256b3a1a9e046f4caed6e65 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Wed, 30 Jan 2013 20:07:29 +0000 Subject: staging: vt6656: Fix URB submitted while active warning. commit ae5943de8c8c4438cbac5cda599ff0b88c224468 upstream. This error happens because PIPEnsControlOut and PIPEnsControlIn unlock the spin lock for delay, letting in another thread. The patch moves the current MP_SET_FLAG to before filling of sUsbCtlRequest for pControlURB and clears it in event of failing. Any thread calling either function while fMP_CONTROL_READS or fMP_CONTROL_WRITES flags set will return STATUS_FAILURE. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/usbpipe.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index c612ab5..f759352 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -168,6 +168,11 @@ int PIPEnsControlOut( if (pDevice->Flags & fMP_CONTROL_WRITES) return STATUS_FAILURE; + if (pDevice->Flags & fMP_CONTROL_READS) + return STATUS_FAILURE; + + MP_SET_FLAG(pDevice, fMP_CONTROL_WRITES); + pDevice->sUsbCtlRequest.bRequestType = 0x40; pDevice->sUsbCtlRequest.bRequest = byRequest; pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue); @@ -182,12 +187,13 @@ int PIPEnsControlOut( ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC); if (ntStatus != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control send request submission failed: %d\n", ntStatus); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO + "control send request submission failed: %d\n", + ntStatus); + MP_CLEAR_FLAG(pDevice, fMP_CONTROL_WRITES); return STATUS_FAILURE; } - else { - MP_SET_FLAG(pDevice, fMP_CONTROL_WRITES); - } + spin_unlock_irq(&pDevice->lock); for (ii = 0; ii <= USB_CTL_WAIT; ii ++) { @@ -227,6 +233,11 @@ int PIPEnsControlIn( if (pDevice->Flags & fMP_CONTROL_READS) return STATUS_FAILURE; + if (pDevice->Flags & fMP_CONTROL_WRITES) + return STATUS_FAILURE; + + MP_SET_FLAG(pDevice, fMP_CONTROL_READS); + pDevice->sUsbCtlRequest.bRequestType = 0xC0; pDevice->sUsbCtlRequest.bRequest = byRequest; pDevice->sUsbCtlRequest.wValue = cpu_to_le16p(&wValue); @@ -240,10 +251,11 @@ int PIPEnsControlIn( ntStatus = usb_submit_urb(pDevice->pControlURB, GFP_ATOMIC); if (ntStatus != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"control request submission failed: %d\n", ntStatus); - }else { - MP_SET_FLAG(pDevice, fMP_CONTROL_READS); - } + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO + "control request submission failed: %d\n", ntStatus); + MP_CLEAR_FLAG(pDevice, fMP_CONTROL_READS); + return STATUS_FAILURE; + } spin_unlock_irq(&pDevice->lock); for (ii = 0; ii <= USB_CTL_WAIT; ii ++) { -- cgit v1.1 From 9c3f628b6004454a3867b4c0dad9c9738405dd75 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 16 Dec 2012 22:00:50 +0100 Subject: pcmcia/vrc4171: Add missing spinlock init commit 811af9723859884f2f771f3174f3ddedab7c53b5 upstream. It doesn't seem this spinlock was properly initialized. This bug was introduced by commit 7a410e8d4d97457c8c381e2de9cdc7bd3306badc. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/pcmcia/vrc4171_card.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index 86e4a1a..6bb02ab 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c @@ -246,6 +246,7 @@ static int pccard_init(struct pcmcia_socket *sock) socket = &vrc4171_sockets[slot]; socket->csc_irq = search_nonuse_irq(); socket->io_irq = search_nonuse_irq(); + spin_lock_init(&socket->lock); return 0; } -- cgit v1.1 From 90523879cdf0051a208a660a6ce475ed7ac51e99 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 24 Jan 2013 16:12:41 +1000 Subject: fbcon: don't lose the console font across generic->chip driver switch commit ae1287865f5361fa138d4d3b1b6277908b54eac9 upstream. If grub2 loads efifb/vesafb, then when systemd starts it can set the console font on that framebuffer device, however when we then load the native KMS driver, the first thing it does is tear down the generic framebuffer driver. The thing is the generic code is doing the right thing, it frees the font because otherwise it would leak memory. However we can assume that if you are removing the generic firmware driver (vesa/efi/offb), that a new driver *should* be loading soon after, so we effectively leak the font. However the old code left a dangling pointer in vc->vc_font.data and we can now reuse that dangling pointer to load the font into the new driver, now that we aren't freeing it. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=892340 Signed-off-by: Dave Airlie Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/video/console/fbcon.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index bf9a9b7..b27a91c 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -991,7 +991,7 @@ static const char *fbcon_startup(void) } /* Setup default font */ - if (!p->fontdata) { + if (!p->fontdata && !vc->vc_font.data) { if (!fontname[0] || !(font = find_font(fontname))) font = get_default_font(info->var.xres, info->var.yres, @@ -1001,6 +1001,8 @@ static const char *fbcon_startup(void) vc->vc_font.height = font->height; vc->vc_font.data = (void *)(p->fontdata = font->data); vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */ + } else { + p->fontdata = vc->vc_font.data; } cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); @@ -1160,9 +1162,9 @@ static void fbcon_init(struct vc_data *vc, int init) ops->p = &fb_display[fg_console]; } -static void fbcon_free_font(struct display *p) +static void fbcon_free_font(struct display *p, bool freefont) { - if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) + if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); p->fontdata = NULL; p->userfont = 0; @@ -1174,8 +1176,8 @@ static void fbcon_deinit(struct vc_data *vc) struct fb_info *info; struct fbcon_ops *ops; int idx; + bool free_font = true; - fbcon_free_font(p); idx = con2fb_map[vc->vc_num]; if (idx == -1) @@ -1186,6 +1188,8 @@ static void fbcon_deinit(struct vc_data *vc) if (!info) goto finished; + if (info->flags & FBINFO_MISC_FIRMWARE) + free_font = false; ops = info->fbcon_par; if (!ops) @@ -1197,6 +1201,8 @@ static void fbcon_deinit(struct vc_data *vc) ops->flags &= ~FBCON_FLAGS_INIT; finished: + fbcon_free_font(p, free_font); + if (!con_is_bound(&fb_con)) fbcon_exit(); -- cgit v1.1 From abd9120040d5f427b950561277f2846b0a80be44 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 25 Jan 2013 10:28:15 +1000 Subject: fb: rework locking to fix lock ordering on takeover commit 50e244cc793d511b86adea24972f3a7264cae114 upstream. Adjust the console layer to allow a take over call where the caller already holds the locks. Make the fb layer lock in order. This is partly a band aid, the fb layer is terminally confused about the locking rules it uses for its notifiers it seems. [akpm@linux-foundation.org: remove stray non-ascii char, tidy comment] [akpm@linux-foundation.org: export do_take_over_console()] [airlied: cleanup another non-ascii char] Signed-off-by: Alan Cox Cc: Florian Tobias Schandinat Cc: Stephen Rothwell Cc: Jiri Kosina Tested-by: Sedat Dilek Reviewed-by: Daniel Vetter Signed-off-by: Andrew Morton Signed-off-by: Dave Airlie Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 93 ++++++++++++++++++++++++++++++++----------- drivers/video/console/fbcon.c | 29 +++++++++++++- drivers/video/fbmem.c | 5 +-- drivers/video/fbsysfs.c | 3 ++ 4 files changed, 103 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index b3915b7..eb80f01 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3016,7 +3016,7 @@ int __init vty_init(const struct file_operations *console_fops) static struct class *vtconsole_class; -static int bind_con_driver(const struct consw *csw, int first, int last, +static int do_bind_con_driver(const struct consw *csw, int first, int last, int deflt) { struct module *owner = csw->owner; @@ -3027,7 +3027,7 @@ static int bind_con_driver(const struct consw *csw, int first, int last, if (!try_module_get(owner)) return -ENODEV; - console_lock(); + WARN_CONSOLE_UNLOCKED(); /* check if driver is registered */ for (i = 0; i < MAX_NR_CON_DRIVER; i++) { @@ -3112,11 +3112,22 @@ static int bind_con_driver(const struct consw *csw, int first, int last, retval = 0; err: - console_unlock(); module_put(owner); return retval; }; + +static int bind_con_driver(const struct consw *csw, int first, int last, + int deflt) +{ + int ret; + + console_lock(); + ret = do_bind_con_driver(csw, first, last, deflt); + console_unlock(); + return ret; +} + #ifdef CONFIG_VT_HW_CONSOLE_BINDING static int con_is_graphics(const struct consw *csw, int first, int last) { @@ -3228,9 +3239,9 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) if (!con_is_bound(csw)) con_driver->flag &= ~CON_DRIVER_FLAG_INIT; - console_unlock(); /* ignore return value, binding should not fail */ - bind_con_driver(defcsw, first, last, deflt); + do_bind_con_driver(defcsw, first, last, deflt); + console_unlock(); err: module_put(owner); return retval; @@ -3508,28 +3519,18 @@ int con_debug_leave(void) } EXPORT_SYMBOL_GPL(con_debug_leave); -/** - * register_con_driver - register console driver to console layer - * @csw: console driver - * @first: the first console to take over, minimum value is 0 - * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1 - * - * DESCRIPTION: This function registers a console driver which can later - * bind to a range of consoles specified by @first and @last. It will - * also initialize the console driver by calling con_startup(). - */ -int register_con_driver(const struct consw *csw, int first, int last) +static int do_register_con_driver(const struct consw *csw, int first, int last) { struct module *owner = csw->owner; struct con_driver *con_driver; const char *desc; int i, retval = 0; + WARN_CONSOLE_UNLOCKED(); + if (!try_module_get(owner)) return -ENODEV; - console_lock(); - for (i = 0; i < MAX_NR_CON_DRIVER; i++) { con_driver = ®istered_con_driver[i]; @@ -3582,10 +3583,29 @@ int register_con_driver(const struct consw *csw, int first, int last) } err: - console_unlock(); module_put(owner); return retval; } + +/** + * register_con_driver - register console driver to console layer + * @csw: console driver + * @first: the first console to take over, minimum value is 0 + * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1 + * + * DESCRIPTION: This function registers a console driver which can later + * bind to a range of consoles specified by @first and @last. It will + * also initialize the console driver by calling con_startup(). + */ +int register_con_driver(const struct consw *csw, int first, int last) +{ + int retval; + + console_lock(); + retval = do_register_con_driver(csw, first, last); + console_unlock(); + return retval; +} EXPORT_SYMBOL(register_con_driver); /** @@ -3639,17 +3659,44 @@ EXPORT_SYMBOL(unregister_con_driver); * when a driver wants to take over some existing consoles * and become default driver for newly opened ones. * - * take_over_console is basically a register followed by unbind + * take_over_console is basically a register followed by unbind + */ +int do_take_over_console(const struct consw *csw, int first, int last, int deflt) +{ + int err; + + err = do_register_con_driver(csw, first, last); + /* + * If we get an busy error we still want to bind the console driver + * and return success, as we may have unbound the console driver + * but not unregistered it. + */ + if (err == -EBUSY) + err = 0; + if (!err) + do_bind_con_driver(csw, first, last, deflt); + + return err; +} +EXPORT_SYMBOL_GPL(do_take_over_console); + +/* + * If we support more console drivers, this function is used + * when a driver wants to take over some existing consoles + * and become default driver for newly opened ones. + * + * take_over_console is basically a register followed by unbind */ int take_over_console(const struct consw *csw, int first, int last, int deflt) { int err; err = register_con_driver(csw, first, last); - /* if we get an busy error we still want to bind the console driver + /* + * If we get an busy error we still want to bind the console driver * and return success, as we may have unbound the console driver -  * but not unregistered it. - */ + * but not unregistered it. + */ if (err == -EBUSY) err = 0; if (!err) diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index b27a91c..18d02c6 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -530,6 +530,33 @@ static int search_for_mapped_con(void) return retval; } +static int do_fbcon_takeover(int show_logo) +{ + int err, i; + + if (!num_registered_fb) + return -ENODEV; + + if (!show_logo) + logo_shown = FBCON_LOGO_DONTSHOW; + + for (i = first_fb_vc; i <= last_fb_vc; i++) + con2fb_map[i] = info_idx; + + err = do_take_over_console(&fb_con, first_fb_vc, last_fb_vc, + fbcon_is_default); + + if (err) { + for (i = first_fb_vc; i <= last_fb_vc; i++) + con2fb_map[i] = -1; + info_idx = -1; + } else { + fbcon_has_console_bind = 1; + } + + return err; +} + static int fbcon_takeover(int show_logo) { int err, i; @@ -3122,7 +3149,7 @@ static int fbcon_fb_registered(struct fb_info *info) } if (info_idx != -1) - ret = fbcon_takeover(1); + ret = do_fbcon_takeover(1); } else { for (i = first_fb_vc; i <= last_fb_vc; i++) { if (con2fb_map_boot[i] == idx) diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 7a41220..a94edc3 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1628,7 +1628,9 @@ static int do_register_framebuffer(struct fb_info *fb_info) event.info = fb_info; if (!lock_fb_info(fb_info)) return -ENODEV; + console_lock(); fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); + console_unlock(); unlock_fb_info(fb_info); return 0; } @@ -1831,11 +1833,8 @@ int fb_new_modelist(struct fb_info *info) err = 1; if (!list_empty(&info->modelist)) { - if (!lock_fb_info(info)) - return -ENODEV; event.info = info; err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event); - unlock_fb_info(info); } return err; diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 67afa9c..303fb9f 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c @@ -175,6 +175,8 @@ static ssize_t store_modes(struct device *device, if (i * sizeof(struct fb_videomode) != count) return -EINVAL; + if (!lock_fb_info(fb_info)) + return -ENODEV; console_lock(); list_splice(&fb_info->modelist, &old_list); fb_videomode_to_modelist((const struct fb_videomode *)buf, i, @@ -186,6 +188,7 @@ static ssize_t store_modes(struct device *device, fb_destroy_modelist(&old_list); console_unlock(); + unlock_fb_info(fb_info); return 0; } -- cgit v1.1 From 49a656f8337670ffc66f28235f371767f5d25f42 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 25 Jan 2013 10:28:18 +1000 Subject: fb: Yet another band-aid for fixing lockdep mess commit e93a9a868792ad71cdd09d75e5a02d8067473c4e upstream. I've still got lockdep warnings even after Alan's patch, and it seems that yet more band aids are required to paper over similar paths for unbind_con_driver() and unregister_con_driver(). After this hack, lockdep warnings are finally gone. Signed-off-by: Takashi Iwai Cc: Alan Cox Cc: Florian Tobias Schandinat Cc: Jiri Kosina Tested-by: Sedat Dilek Signed-off-by: Andrew Morton Signed-off-by: Dave Airlie Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vt.c | 43 ++++++++++++++++++++++++++++--------------- drivers/video/console/fbcon.c | 4 ++-- drivers/video/fbmem.c | 4 ++++ 3 files changed, 34 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index eb80f01..e41288a 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3164,6 +3164,18 @@ static int con_is_graphics(const struct consw *csw, int first, int last) */ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) { + int retval; + + console_lock(); + retval = do_unbind_con_driver(csw, first, last, deflt); + console_unlock(); + return retval; +} +EXPORT_SYMBOL(unbind_con_driver); + +/* unlocked version of unbind_con_driver() */ +int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt) +{ struct module *owner = csw->owner; const struct consw *defcsw = NULL; struct con_driver *con_driver = NULL, *con_back = NULL; @@ -3172,7 +3184,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) if (!try_module_get(owner)) return -ENODEV; - console_lock(); + WARN_CONSOLE_UNLOCKED(); /* check if driver is registered and if it is unbindable */ for (i = 0; i < MAX_NR_CON_DRIVER; i++) { @@ -3185,10 +3197,8 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) } } - if (retval) { - console_unlock(); + if (retval) goto err; - } retval = -ENODEV; @@ -3204,15 +3214,11 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) } } - if (retval) { - console_unlock(); + if (retval) goto err; - } - if (!con_is_bound(csw)) { - console_unlock(); + if (!con_is_bound(csw)) goto err; - } first = max(first, con_driver->first); last = min(last, con_driver->last); @@ -3241,13 +3247,12 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) /* ignore return value, binding should not fail */ do_bind_con_driver(defcsw, first, last, deflt); - console_unlock(); err: module_put(owner); return retval; } -EXPORT_SYMBOL(unbind_con_driver); +EXPORT_SYMBOL_GPL(do_unbind_con_driver); static int vt_bind(struct con_driver *con) { @@ -3621,9 +3626,18 @@ EXPORT_SYMBOL(register_con_driver); */ int unregister_con_driver(const struct consw *csw) { - int i, retval = -ENODEV; + int retval; console_lock(); + retval = do_unregister_con_driver(csw); + console_unlock(); + return retval; +} +EXPORT_SYMBOL(unregister_con_driver); + +int do_unregister_con_driver(const struct consw *csw) +{ + int i, retval = -ENODEV; /* cannot unregister a bound driver */ if (con_is_bound(csw)) @@ -3649,10 +3663,9 @@ int unregister_con_driver(const struct consw *csw) } } err: - console_unlock(); return retval; } -EXPORT_SYMBOL(unregister_con_driver); +EXPORT_SYMBOL_GPL(do_unregister_con_driver); /* * If we support more console drivers, this function is used diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 18d02c6..9b8bcab 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -3011,7 +3011,7 @@ static int fbcon_unbind(void) { int ret; - ret = unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, + ret = do_unbind_con_driver(&fb_con, first_fb_vc, last_fb_vc, fbcon_is_default); if (!ret) @@ -3084,7 +3084,7 @@ static int fbcon_fb_unregistered(struct fb_info *info) primary_device = -1; if (!num_registered_fb) - unregister_con_driver(&fb_con); + do_unregister_con_driver(&fb_con); return 0; } diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index a94edc3..c133dde 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1646,8 +1646,10 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) if (!lock_fb_info(fb_info)) return -ENODEV; + console_lock(); event.info = fb_info; ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); + console_unlock(); unlock_fb_info(fb_info); if (ret) @@ -1662,7 +1664,9 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) num_registered_fb--; fb_cleanup_device(fb_info); event.info = fb_info; + console_lock(); fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); + console_unlock(); /* this may free fb info */ put_fb_info(fb_info); -- cgit v1.1 From 436d1b8ff7eb7ac9e2569ad780c33bd4287d0526 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Thu, 14 Feb 2013 03:18:57 +0000 Subject: xen-netback: correctly return errors from netbk_count_requests() [ Upstream commit 35876b5ffc154c357476b2c3bdab10feaf4bd8f0 ] netbk_count_requests() could detect an error, call netbk_fatal_tx_error() but return 0. The vif may then be used afterwards (e.g., in a call to netbk_tx_error(). Since netbk_fatal_tx_error() could set vif->refcnt to 1, the vif may be freed immediately after the call to netbk_fatal_tx_error() (e.g., if the vif is also removed). Netback thread Xenwatch thread ------------------------------------------- netbk_fatal_tx_err() netback_remove() xenvif_disconnect() ... free_netdev() netbk_tx_err() Oops! Signed-off-by: Wei Liu Signed-off-by: Jan Beulich Signed-off-by: David Vrabel Reported-by: Christopher S. Aker Acked-by: Ian Campbell Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/xen-netback/netback.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 6ed44c3..1260bf0 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -870,13 +870,13 @@ static int netbk_count_requests(struct xenvif *vif, if (frags >= work_to_do) { netdev_err(vif->dev, "Need more frags\n"); netbk_fatal_tx_err(vif); - return -frags; + return -ENODATA; } if (unlikely(frags >= MAX_SKB_FRAGS)) { netdev_err(vif->dev, "Too many frags\n"); netbk_fatal_tx_err(vif); - return -frags; + return -E2BIG; } memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags), @@ -884,7 +884,7 @@ static int netbk_count_requests(struct xenvif *vif, if (txp->size > first->size) { netdev_err(vif->dev, "Frag is bigger than frame.\n"); netbk_fatal_tx_err(vif); - return -frags; + return -EIO; } first->size -= txp->size; @@ -894,7 +894,7 @@ static int netbk_count_requests(struct xenvif *vif, netdev_err(vif->dev, "txp->offset: %x, size: %u\n", txp->offset, txp->size); netbk_fatal_tx_err(vif); - return -frags; + return -EINVAL; } } while ((txp++)->flags & XEN_NETTXF_more_data); return frags; -- cgit v1.1 From bd986521a6e35a301e45d2831501acc172fe2a8f Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Thu, 14 Feb 2013 03:18:58 +0000 Subject: xen-netback: cancel the credit timer when taking the vif down [ Upstream commit 3e55f8b306cf305832a4ac78aa82e1b40e818ece ] If the credit timer is left armed after calling xen_netbk_remove_xenvif(), then it may fire and attempt to schedule the vif which will then oops as vif->netbk == NULL. This may happen both in the fatal error path and during normal disconnection from the front end. The sequencing during shutdown is critical to ensure that: a) vif->netbk doesn't become unexpectedly NULL; and b) the net device/vif is not freed. 1. Mark as unschedulable (netif_carrier_off()). 2. Synchronously cancel the timer. 3. Remove the vif from the schedule list. 4. Remove it from it netback thread group. 5. Wait for vif->refcnt to become 0. Signed-off-by: David Vrabel Acked-by: Ian Campbell Reported-by: Christopher S. Aker Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/xen-netback/interface.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 5925e0b..8eaf0e2 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -132,6 +132,7 @@ static void xenvif_up(struct xenvif *vif) static void xenvif_down(struct xenvif *vif) { disable_irq(vif->irq); + del_timer_sync(&vif->credit_timeout); xen_netbk_deschedule_xenvif(vif); xen_netbk_remove_xenvif(vif); } @@ -362,8 +363,6 @@ void xenvif_disconnect(struct xenvif *vif) atomic_dec(&vif->refcnt); wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0); - del_timer_sync(&vif->credit_timeout); - if (vif->irq) unbind_from_irqhandler(vif->irq, vif); -- cgit v1.1 From 7a9a20ea77e7508c795dead9ab2f6c98a617762d Mon Sep 17 00:00:00 2001 From: Maciej Sosnowski Date: Wed, 23 May 2012 17:27:07 +0200 Subject: dca: check against empty dca_domains list before unregister provider commit c419fcfd071cf34ba00f9f65282583772d2655e7 upstream. When providers get blocked unregister_dca_providers() is called ending up with dca_providers and dca_domain lists emptied. Dca should be prevented from trying to unregister any provider if dca_domain list is found empty. Reported-by: Jiang Liu Tested-by: Gaohuai Han Signed-off-by: Maciej Sosnowski Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/dca/dca-core.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c index 4abd089..7065851 100644 --- a/drivers/dca/dca-core.c +++ b/drivers/dca/dca-core.c @@ -409,6 +409,11 @@ void unregister_dca_provider(struct dca_provider *dca, struct device *dev) spin_lock_irqsave(&dca_lock, flags); + if (list_empty(&dca_domains)) { + raw_spin_unlock_irqrestore(&dca_lock, flags); + return; + } + list_del(&dca->node); pci_rc = dca_pci_rc_from_dev(dev); -- cgit v1.1 From 2466f8620e8fb814f2d1c72584e1e4e95ca50ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 23 Jan 2013 10:44:36 +0100 Subject: USB: option: add and update Alcatel modems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit f8f0302bbcbd1b14655bef29f6996a2152be559d upstream. Adding three currently unsupported modems based on information from .inf driver files: Diag VID_1BBB&PID_0052&MI_00 AGPS VID_1BBB&PID_0052&MI_01 VOICE VID_1BBB&PID_0052&MI_02 AT VID_1BBB&PID_0052&MI_03 Modem VID_1BBB&PID_0052&MI_05 wwan VID_1BBB&PID_0052&MI_06 Diag VID_1BBB&PID_00B6&MI_00 AT VID_1BBB&PID_00B6&MI_01 Modem VID_1BBB&PID_00B6&MI_02 wwan VID_1BBB&PID_00B6&MI_03 Diag VID_1BBB&PID_00B7&MI_00 AGPS VID_1BBB&PID_00B7&MI_01 VOICE VID_1BBB&PID_00B7&MI_02 AT VID_1BBB&PID_00B7&MI_03 Modem VID_1BBB&PID_00B7&MI_04 wwan VID_1BBB&PID_00B7&MI_05 Updating the blacklist info for the X060S_X200 and X220_X500D, reserving interfaces for a wwan driver, based on wwan VID_1BBB&PID_0000&MI_04 wwan VID_1BBB&PID_0017&MI_06 Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 52cd814..19e1a80 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -479,6 +479,7 @@ static const struct option_blacklist_info four_g_w14_blacklist = { static const struct option_blacklist_info alcatel_x200_blacklist = { .sendsetup = BIT(0) | BIT(1), + .reserved = BIT(4), }; static const struct option_blacklist_info zte_0037_blacklist = { @@ -1215,7 +1216,14 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist }, - { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D), + .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, + { USB_DEVICE(ALCATEL_VENDOR_ID, 0x0052), + .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, + { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b6), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b7), + .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L100V), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, -- cgit v1.1 From 20fc803358fd0278dfbb5b82d947c3f9ea0164a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Tue, 12 Feb 2013 13:42:24 +0100 Subject: USB: option: add Yota / Megafon M100-1 4g modem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit cd565279e51bedee1b2988e84f9b3bef485adeb6 upstream. Interface layout: 00 CD-ROM 01 debug COM port 02 AP control port 03 modem 04 usb-ethernet Bus=01 Lev=02 Prnt=02 Port=01 Cnt=02 Dev#= 4 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0408 ProdID=ea42 Rev= 0.00 S: Manufacturer=Qualcomm, Incorporated S: Product=Qualcomm CDMA Technologies MSM S: SerialNumber=353568051xxxxxx C:* #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=84(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=86(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 19e1a80..7fdec0d 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -576,6 +576,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, + { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), -- cgit v1.1 From b3747d5aec3cc8a5a734bc384c3443d93a31b5e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 13 Feb 2013 23:41:34 +0100 Subject: USB: option: add Huawei "ACM" devices using protocol = vendor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 1f3f687722fd9b29a0c2a85b4844e3b2a3585c63 upstream. The USB device descriptor of one identity presented by a few Huawei morphing devices have serial functions with class codes 02/02/ff, indicating CDC ACM with a vendor specific protocol. This combination is often used for MSFT RNDIS functions, and the CDC ACM class driver will therefore ignore such functions. The CDC ACM class driver cannot support functions with only 2 endpoints. The underlying serial functions of these modems are also believed to be the same as for alternate device identities already supported by the option driver. Letting the same driver handle these functions independently of the current identity ensures consistent handling and user experience. There is no need to blacklist these devices in the rndis_host driver. Huawei serial functions will either have only 2 endpoints or a CDC ACM functional descriptor with bmCapabilities != 0, making them correctly ignored as "non RNDIS" by that driver. Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 7fdec0d..24a3ea6 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -578,8 +578,12 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), -- cgit v1.1 From e39d97f98e39ecb860d113ad75fa250bc52d247b Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Thu, 14 Feb 2013 17:08:09 +0200 Subject: USB: ehci-omap: Fix autoloading of module commit 04753523266629b1cd0518091da1658755787198 upstream. The module alias should be "ehci-omap" and not "omap-ehci" to match the platform device name. The omap-ehci module should now autoload correctly. Signed-off-by: Roger Quadros Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-omap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 55a57c2..028c572 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -321,7 +321,7 @@ static const struct hc_driver ehci_omap_hc_driver = { .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, }; -MODULE_ALIAS("platform:omap-ehci"); +MODULE_ALIAS("platform:ehci-omap"); MODULE_AUTHOR("Texas Instruments, Inc."); MODULE_AUTHOR("Felipe Balbi "); -- cgit v1.1 From ba18450b8528ed69d71b3cb8dbdecb08d9272c72 Mon Sep 17 00:00:00 2001 From: fangxiaozhi Date: Thu, 7 Feb 2013 15:32:07 +0800 Subject: USB: storage: properly handle the endian issues of idProduct commit cd060956c5e97931c3909e4a808508469c0bb9f6 upstream. 1. The idProduct is little endian, so make sure its value to be compatible with the current CPU. Make no break on big endian processors. Signed-off-by: fangxiaozhi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/initializers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 16b0bf0..7ab9046 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c @@ -147,7 +147,7 @@ static int usb_stor_huawei_dongles_pid(struct us_data *us) int idProduct; idesc = &us->pusb_intf->cur_altsetting->desc; - idProduct = us->pusb_dev->descriptor.idProduct; + idProduct = le16_to_cpu(us->pusb_dev->descriptor.idProduct); /* The first port is CDROM, * means the dongle in the single port mode, * and a switch command is required to be sent. */ @@ -169,7 +169,7 @@ int usb_stor_huawei_init(struct us_data *us) int result = 0; if (usb_stor_huawei_dongles_pid(us)) { - if (us->pusb_dev->descriptor.idProduct >= 0x1446) + if (le16_to_cpu(us->pusb_dev->descriptor.idProduct) >= 0x1446) result = usb_stor_huawei_scsi_init(us); else result = usb_stor_huawei_feature_init(us); -- cgit v1.1 From cfb2ddcace95399e4dcefebb62e16cd93c9d4ae7 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Thu, 14 Feb 2013 09:39:09 -0500 Subject: USB: usb-storage: unusual_devs update for Super TOP SATA bridge commit 18e03310b5caa6d11c1a8c61b982c37047693fba upstream. The current entry in unusual_cypress.h for the Super TOP SATA bridge devices seems to be causing corruption on newer revisions of this device. This has been reported in Arch Linux and Fedora. The original patch was tested on devices with bcdDevice of 1.60, whereas the newer devices report bcdDevice as 2.20. Limit the UNUSUAL_DEV entry to devices less than 2.20. This fixes https://bugzilla.redhat.com/show_bug.cgi?id=909591 The Arch Forum post on this is here: https://bbs.archlinux.org/viewtopic.php?id=152011 Reported-by: Carsten S. Tested-by: Carsten S. Signed-off-by: Josh Boyer Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_cypress.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h index 2c85530..65a6a75 100644 --- a/drivers/usb/storage/unusual_cypress.h +++ b/drivers/usb/storage/unusual_cypress.h @@ -31,7 +31,7 @@ UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, "Cypress ISD-300LP", USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), -UNUSUAL_DEV( 0x14cd, 0x6116, 0x0000, 0x9999, +UNUSUAL_DEV( 0x14cd, 0x6116, 0x0000, 0x0219, "Super Top", "USB 2.0 SATA BRIDGE", USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), -- cgit v1.1 From 954497ea2037e8c42fe1c7a0882030b62ac9116c Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Mon, 18 Feb 2013 18:31:37 -0800 Subject: target: Add missing mapped_lun bounds checking during make_mappedlun setup commit fbbf8555a986ed31e54f006b6cc637ea4ff1425b upstream. This patch adds missing bounds checking for the configfs provided mapped_lun value during target_fabric_make_mappedlun() setup ahead of se_lun_acl initialization. This addresses a potential OOPs when using a mapped_lun value that exceeds the hardcoded TRANSPORT_MAX_LUNS_PER_TPG-1 value within se_node_acl->device_list[]. Reported-by: Jan Engelhardt Cc: Jan Engelhardt Signed-off-by: Nicholas Bellinger Signed-off-by: Greg Kroah-Hartman --- drivers/target/target_core_fabric_configfs.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 07ab5a3..6246f28 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -355,6 +355,14 @@ static struct config_group *target_fabric_make_mappedlun( ret = -EINVAL; goto out; } + if (mapped_lun > (TRANSPORT_MAX_LUNS_PER_TPG-1)) { + pr_err("Mapped LUN: %lu exceeds TRANSPORT_MAX_LUNS_PER_TPG" + "-1: %u for Target Portal Group: %u\n", mapped_lun, + TRANSPORT_MAX_LUNS_PER_TPG-1, + se_tpg->se_tpg_tfo->tpg_get_tag(se_tpg)); + ret = -EINVAL; + goto out; + } lacl = core_dev_init_initiator_node_lun_acl(se_tpg, mapped_lun, config_item_name(acl_ci), &ret); -- cgit v1.1 From 975398374dac831d5d5c2825615c489aee24ea3a Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 20 Dec 2012 10:31:11 +0000 Subject: xen-blkback: do not leak mode property commit 9d092603cc306ee6edfe917bf9ab8beb5f32d7bc upstream. "be->mode" is obtained from xenbus_read(), which does a kmalloc() for the message body. The short string is never released, so do it along with freeing "be" itself, and make sure the string isn't kept when backend_changed() doesn't complete successfully (which made it desirable to slightly re-structure that function, so that the error cleanup can be done in one place). Reported-by: Olaf Hering Signed-off-by: Jan Beulich Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/block/xen-blkback/xenbus.c | 49 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 6cc0db1..97ded25 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -400,6 +400,7 @@ static int xen_blkbk_remove(struct xenbus_device *dev) be->blkif = NULL; } + kfree(be->mode); kfree(be); dev_set_drvdata(&dev->dev, NULL); return 0; @@ -482,6 +483,7 @@ static void backend_changed(struct xenbus_watch *watch, = container_of(watch, struct backend_info, backend_watch); struct xenbus_device *dev = be->dev; int cdrom = 0; + unsigned long handle; char *device_type; DPRINTK(""); @@ -501,10 +503,10 @@ static void backend_changed(struct xenbus_watch *watch, return; } - if ((be->major || be->minor) && - ((be->major != major) || (be->minor != minor))) { - pr_warn(DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n", - be->major, be->minor, major, minor); + if (be->major | be->minor) { + if (be->major != major || be->minor != minor) + pr_warn(DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n", + be->major, be->minor, major, minor); return; } @@ -522,36 +524,33 @@ static void backend_changed(struct xenbus_watch *watch, kfree(device_type); } - if (be->major == 0 && be->minor == 0) { - /* Front end dir is a number, which is used as the handle. */ - - char *p = strrchr(dev->otherend, '/') + 1; - long handle; - err = strict_strtoul(p, 0, &handle); - if (err) - return; + /* Front end dir is a number, which is used as the handle. */ + err = strict_strtoul(strrchr(dev->otherend, '/') + 1, 0, &handle); + if (err) + return; - be->major = major; - be->minor = minor; + be->major = major; + be->minor = minor; - err = xen_vbd_create(be->blkif, handle, major, minor, - (NULL == strchr(be->mode, 'w')), cdrom); - if (err) { - be->major = 0; - be->minor = 0; - xenbus_dev_fatal(dev, err, "creating vbd structure"); - return; - } + err = xen_vbd_create(be->blkif, handle, major, minor, + !strchr(be->mode, 'w'), cdrom); + if (err) + xenbus_dev_fatal(dev, err, "creating vbd structure"); + else { err = xenvbd_sysfs_addif(dev); if (err) { xen_vbd_free(&be->blkif->vbd); - be->major = 0; - be->minor = 0; xenbus_dev_fatal(dev, err, "creating sysfs entries"); - return; } + } + if (err) { + kfree(be->mode); + be->mode = NULL; + be->major = 0; + be->minor = 0; + } else { /* We're potentially connected now */ xen_update_blkif_status(be->blkif); } -- cgit v1.1 From cbf253c44b52b3c6b921a22f05243a1dc7a00122 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 27 Feb 2013 17:04:04 -0800 Subject: firewire: add minor number range check to fw_device_init() commit 3bec60d511179853138836ae6e1b61fe34d9235f upstream. fw_device_init() didn't check whether the allocated minor number isn't too large. Fail if it goes overflows MINORBITS. Signed-off-by: Tejun Heo Suggested-by: Stefan Richter Acked-by: Stefan Richter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/firewire/core-device.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 9f661e0..812cea3 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -995,6 +995,10 @@ static void fw_device_init(struct work_struct *work) ret = idr_pre_get(&fw_device_idr, GFP_KERNEL) ? idr_get_new(&fw_device_idr, device, &minor) : -ENOMEM; + if (minor >= 1 << MINORBITS) { + idr_remove(&fw_device_idr, minor); + minor = -ENOSPC; + } up_write(&fw_device_rwsem); if (ret < 0) -- cgit v1.1 From 5dec43e3d688390256df3343bb444e7ed0022f44 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 27 Nov 2012 13:35:09 -0300 Subject: media: rc: unlock on error in show_protocols() commit 30ebc5e44d057a1619ad63fe32c8c1670c37c4b8 upstream. We recently introduced a new return -ENODEV in this function but we need to unlock before returning. [mchehab@redhat.com: found two patches with the same fix. Merged SOB's/acks into one patch] Acked-by: Herton R. Krzesinski Signed-off-by: Dan Carpenter Signed-off-by: Douglas Bagnall Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Greg Kroah-Hartman --- drivers/media/rc/rc-main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 9cfb56d..62910ac 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -775,8 +775,10 @@ static ssize_t show_protocols(struct device *device, } else if (dev->raw) { enabled = dev->raw->enabled_protocols; allowed = ir_raw_get_allowed_protocols(); - } else + } else { + mutex_unlock(&dev->lock); return -ENODEV; + } IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n", (long long)allowed, -- cgit v1.1 From 603b86549a4d6928d1059b19df2dfc5d61070533 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 26 Nov 2012 05:57:27 +0000 Subject: vhost: fix length for cross region descriptor commit bd97120fc3d1a11f3124c7c9ba1d91f51829eb85 upstream. If a single descriptor crosses a region, the second chunk length should be decremented by size translated so far, instead it includes the full descriptor length. Signed-off-by: Michael S. Tsirkin Acked-by: Jason Wang Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/vhost/vhost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 61047fe..e3fac28 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -986,7 +986,7 @@ static int translate_desc(struct vhost_dev *dev, u64 addr, u32 len, } _iov = iov + ret; size = reg->memory_size - addr + reg->guest_phys_addr; - _iov->iov_len = min((u64)len, size); + _iov->iov_len = min((u64)len - s, size); _iov->iov_base = (void __user *)(unsigned long) (reg->userspace_addr + addr - reg->guest_phys_addr); s += size; -- cgit v1.1 From 55bce39db26a3b1d6b18fc0ae5d57948946f0c49 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 4 Mar 2013 06:09:07 +0800 Subject: dca: check against empty dca_domains list before unregister provider fix In 3.0.67, commit 7a9a20ea77e7508c795dead9ab2f6c98a617762d (dca: check against empty dca_domains list before unregister provider), upstream commit c419fcfd071cf34ba00f9f65282583772d2655e7, added a fail path to unregister_dca_provider. It added there also a call to raw_spin_unlock_irqrestore. But in 3.0, the lock is not raw, so this results in: drivers/dca/dca-core.c: In function 'unregister_dca_provider': drivers/dca/dca-core.c:413: warning: passing argument 1 of '_raw_spin_unlock_irqrestore' from incompatible pointer type Fix it by calling spin_unlock_irqrestore properly. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/dca/dca-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c index 7065851..605fd20 100644 --- a/drivers/dca/dca-core.c +++ b/drivers/dca/dca-core.c @@ -410,7 +410,7 @@ void unregister_dca_provider(struct dca_provider *dca, struct device *dev) spin_lock_irqsave(&dca_lock, flags); if (list_empty(&dca_domains)) { - raw_spin_unlock_irqrestore(&dca_lock, flags); + spin_unlock_irqrestore(&dca_lock, flags); return; } -- cgit v1.1 From 5e6af63de116db55be85da4374441f7963d11281 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 27 Feb 2013 12:52:45 +0000 Subject: staging: comedi: ni_labpc: correct differential channel sequence for AI commands Commit 4c4bc25d0fa6beaf054c0b4c3b324487f266c820 upstream. Tuomas reported problems getting meaningful output from a Lab-PC+ in differential mode for AI cmds, but AI insn reads gave correct readings. He tracked it down to two problems, one of which is addressed by this patch. It seems the setting of the channel bits for particular scanning modes was incorrect for differential mode. (Only half the number of channels are available in differential mode; comedi refers to them as channels 0, 1, 2 and 3, but the hardware documentation refers to them as channels 0, 2, 4 and 6.) In differential mode, the setting of the channel enable bits in the command1 register should depend on whether the scan enable bit is set. Effectively, we need to double the comedi channel number when the scan enable bit is not set in differential mode. The scan enable bit gets set when the AI scan mode is `MODE_MULT_CHAN_UP` or `MODE_MULT_CHAN_DOWN`, and gets cleared when the AI scan mode is `MODE_SINGLE_CHAN` or `MODE_SINGLE_CHAN_INTERVAL`. The existing test for whether the comedi channel number needs to be doubled in differential mode is incorrect in `labpc_ai_cmd()`. This patch corrects the test. Thanks to Tuomas for suggesting the fix. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index ab8f370..9b204b4 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -1241,7 +1241,9 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) else channel = CR_CHAN(cmd->chanlist[0]); /* munge channel bits for differential / scan disabled mode */ - if (labpc_ai_scan_mode(cmd) != MODE_SINGLE_CHAN && aref == AREF_DIFF) + if ((labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN || + labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN_INTERVAL) && + aref == AREF_DIFF) channel *= 2; devpriv->command1_bits |= ADC_CHAN_BITS(channel); devpriv->command1_bits |= thisboard->ai_range_code[range]; -- cgit v1.1 From 544da4403b05e874e134919db7124def003ef7cf Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 27 Feb 2013 12:52:46 +0000 Subject: staging: comedi: ni_labpc: set up command4 register *after* command3 Commit 22056e2b46246d97ff0f7c6e21a77b8daa07f02c upstream. Tuomas reported problems getting meaningful output from a Lab-PC+ in differential mode for AI cmds, but AI insn reads gave correct readings. He tracked it down to two problems, one of which is addressed by this patch. It seems that writing to the command3 register after writing to the command4 register in `labpc_ai_cmd()` messes up the differential reference bit setting in the command4 register. Set up the command4 register after the command3 register (as in `labpc_ai_rinsn()`) to avoid the problem. Thanks to Tuomas for suggesting the fix. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 9b204b4..897359d7 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -1259,21 +1259,6 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG); } - /* setup any external triggering/pacing (command4 register) */ - devpriv->command4_bits = 0; - if (cmd->convert_src != TRIG_EXT) - devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT; - /* XXX should discard first scan when using interval scanning - * since manual says it is not synced with scan clock */ - if (labpc_use_continuous_mode(cmd) == 0) { - devpriv->command4_bits |= INTERVAL_SCAN_EN_BIT; - if (cmd->scan_begin_src == TRIG_EXT) - devpriv->command4_bits |= EXT_SCAN_EN_BIT; - } - /* single-ended/differential */ - if (aref == AREF_DIFF) - devpriv->command4_bits |= ADC_DIFF_BIT; - devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG); devpriv->write_byte(cmd->chanlist_len, dev->iobase + INTERVAL_COUNT_REG); @@ -1351,6 +1336,22 @@ static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) devpriv->command3_bits &= ~ADC_FNE_INTR_EN_BIT; devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG); + /* setup any external triggering/pacing (command4 register) */ + devpriv->command4_bits = 0; + if (cmd->convert_src != TRIG_EXT) + devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT; + /* XXX should discard first scan when using interval scanning + * since manual says it is not synced with scan clock */ + if (labpc_use_continuous_mode(cmd) == 0) { + devpriv->command4_bits |= INTERVAL_SCAN_EN_BIT; + if (cmd->scan_begin_src == TRIG_EXT) + devpriv->command4_bits |= EXT_SCAN_EN_BIT; + } + /* single-ended/differential */ + if (aref == AREF_DIFF) + devpriv->command4_bits |= ADC_DIFF_BIT; + devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG); + /* startup acquisition */ /* command2 reg */ -- cgit v1.1 From 6c80ee53f3737993f693bf2a3b4b3e4bbde9b51f Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 27 Feb 2013 10:56:19 +0000 Subject: staging: comedi: check s->async for poll(), read() and write() commit cc400e185c07c15a42d2635995f422de5b94b696 upstream. Some low-level comedi drivers (incorrectly) point `dev->read_subdev` or `dev->write_subdev` to a subdevice that does not support asynchronous commands. Comedi's poll(), read() and write() file operation handlers assume these subdevices do support asynchronous commands. In particular, they assume `s->async` is valid (where `s` points to the read or write subdevice), which it won't be if it has been set incorrectly. This can lead to a NULL pointer dereference. Check `s->async` is non-NULL in `comedi_poll()`, `comedi_read()` and `comedi_write()` to avoid the bug. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 4b9d8f0..ee33cba 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1577,7 +1577,7 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait) mask = 0; read_subdev = comedi_get_read_subdevice(dev_file_info); - if (read_subdev) { + if (read_subdev && read_subdev->async) { poll_wait(file, &read_subdev->async->wait_head, wait); if (!read_subdev->busy || comedi_buf_read_n_available(read_subdev->async) > 0 @@ -1587,7 +1587,7 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait) } } write_subdev = comedi_get_write_subdevice(dev_file_info); - if (write_subdev) { + if (write_subdev && write_subdev->async) { poll_wait(file, &write_subdev->async->wait_head, wait); comedi_buf_write_alloc(write_subdev->async, write_subdev->async->prealloc_bufsz); @@ -1629,7 +1629,7 @@ static ssize_t comedi_write(struct file *file, const char __user *buf, } s = comedi_get_write_subdevice(dev_file_info); - if (s == NULL) { + if (s == NULL || s->async == NULL) { retval = -EIO; goto done; } @@ -1740,7 +1740,7 @@ static ssize_t comedi_read(struct file *file, char __user *buf, size_t nbytes, } s = comedi_get_read_subdevice(dev_file_info); - if (s == NULL) { + if (s == NULL || s->async == NULL) { retval = -EIO; goto done; } -- cgit v1.1 From c9ad62366468c20381217476c1ebc5cc13ffcbbc Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 11 Feb 2013 22:03:18 +0300 Subject: SCSI: dc395x: uninitialized variable in device_alloc() commit 208afec4f3be8c51ad6eebe6611dd6d2ad2fa298 upstream. This bug was introduced back in bitkeeper days in 2003. We use "dcb->dev_mode" before it has been initialized. Signed-off-by: Dan Carpenter Acked-by: Oliver Neukum Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/dc395x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index f5b718d..aed7756 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -3747,13 +3747,13 @@ static struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb, dcb->max_command = 1; dcb->target_id = target; dcb->target_lun = lun; + dcb->dev_mode = eeprom->target[target].cfg0; #ifndef DC395x_NO_DISCONNECT dcb->identify_msg = IDENTIFY(dcb->dev_mode & NTC_DO_DISCONNECT, lun); #else dcb->identify_msg = IDENTIFY(0, lun); #endif - dcb->dev_mode = eeprom->target[target].cfg0; dcb->inquiry7 = 0; dcb->sync_mode = 0; dcb->min_nego_period = clock_period[period_index]; -- cgit v1.1 From 21a3473f1b9aaf7a458b43acb5237794e8cecadb Mon Sep 17 00:00:00 2001 From: Asias He Date: Wed, 27 Feb 2013 13:29:29 +0800 Subject: target/pscsi: Fix page increment commit 472b72f2db7831d7dbe22ffdff4adee3bd49b05d upstream. The page++ is wrong. It makes bio_add_pc_page() pointing to a wrong page address if the 'while (len > 0 && data_len > 0) { ... }' loop is executed more than one once. Signed-off-by: Asias He Signed-off-by: Nicholas Bellinger Signed-off-by: Greg Kroah-Hartman --- drivers/target/target_core_pscsi.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 331d423..af0c500 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -1210,7 +1210,6 @@ static int __pscsi_map_task_SG( bio = NULL; } - page++; len -= bytes; data_len -= bytes; off = 0; -- cgit v1.1 From 728975e1e15673f9e45ee5d0f1581d8787f3c3b7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 5 Mar 2013 10:07:08 +1030 Subject: hw_random: make buffer usable in scatterlist. commit f7f154f1246ccc5a0a7e9ce50932627d60a0c878 upstream. virtio_rng feeds the randomness buffer handed by the core directly into the scatterlist, since commit bb347d98079a547e80bd4722dee1de61e4dca0e8. However, if CONFIG_HW_RANDOM=m, the static buffer isn't a linear address (at least on most archs). We could fix this in virtio_rng, but it's actually far easier to just do it in the core as virtio_rng would have to allocate a buffer every time (it doesn't know how much the core will want to read). Reported-by: Aurelien Jarno Tested-by: Aurelien Jarno Signed-off-by: Rusty Russell Signed-off-by: Greg Kroah-Hartman --- drivers/char/hw_random/core.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 2016aad..564f6c4 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -52,8 +53,12 @@ static struct hwrng *current_rng; static LIST_HEAD(rng_list); static DEFINE_MUTEX(rng_mutex); static int data_avail; -static u8 rng_buffer[SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES] - __cacheline_aligned; +static u8 *rng_buffer; + +static size_t rng_buffer_size(void) +{ + return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES; +} static inline int hwrng_init(struct hwrng *rng) { @@ -116,7 +121,7 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf, if (!data_avail) { bytes_read = rng_get_data(current_rng, rng_buffer, - sizeof(rng_buffer), + rng_buffer_size(), !(filp->f_flags & O_NONBLOCK)); if (bytes_read < 0) { err = bytes_read; @@ -307,6 +312,14 @@ int hwrng_register(struct hwrng *rng) mutex_lock(&rng_mutex); + /* kmalloc makes this safe for virt_to_page() in virtio_rng.c */ + err = -ENOMEM; + if (!rng_buffer) { + rng_buffer = kmalloc(rng_buffer_size(), GFP_KERNEL); + if (!rng_buffer) + goto out_unlock; + } + /* Must not register two RNGs with the same name. */ err = -EEXIST; list_for_each_entry(tmp, &rng_list, list) { -- cgit v1.1 From b77a7b64bd40be69cf9e4476640349f9ad98fb88 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 22 Feb 2013 21:09:17 +0100 Subject: ath9k: fix RSSI dummy marker value commit a3d63cadbad97671d740a9698acc2c95d1ca6e79 upstream. RSSI is being stored internally as s8 in several places. The indication of an unset RSSI value, ATH_RSSI_DUMMY_MARKER, was supposed to have been set to 127, but ended up being set to 0x127 because of a code cleanup mistake. This could lead to invalid signal strength values in a few places. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 77ec288..247f7f8 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -35,7 +35,7 @@ #define WME_AC_BK 3 #define WME_NUM_AC 4 -#define ATH_RSSI_DUMMY_MARKER 0x127 +#define ATH_RSSI_DUMMY_MARKER 127 #define ATH_RSSI_LPF_LEN 10 #define RSSI_LPF_THRESHOLD -20 #define ATH_RSSI_EP_MULTIPLIER (1<<7) -- cgit v1.1 From d726c470444d85b2cb8cf2dd87f038bb04292b00 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 21 Feb 2013 15:36:38 +1100 Subject: md: raid0: fix error return from create_stripe_zones. commit 58ebb34c49fcfcaa029e4b1c1453d92583900f9a upstream. Create_stripe_zones returns an error slightly differently to raid0_run and to raid0_takeover_*. The error returned used by the second was wrong and an error would result in mddev->private being set to NULL and sooner or later a crash. So never return NULL, return ERR_PTR(err), not NULL from create_stripe_zones. This bug has been present since 2.6.35 so the fix is suitable for any kernel since then. Signed-off-by: NeilBrown Signed-off-by: Greg Kroah-Hartman --- drivers/md/raid0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index e86bf36..0e5084b 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -283,7 +283,7 @@ abort: kfree(conf->strip_zone); kfree(conf->devlist); kfree(conf); - *private_conf = NULL; + *private_conf = ERR_PTR(err); return err; } -- cgit v1.1 From 4f7a207fa110fe9af0d8b68f243337599fb78702 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 2 Mar 2013 15:33:30 +0800 Subject: hwmon: (sht15) Check return value of regulator_enable() commit 3e78080f81481aa8340374d5a37ae033c1cf4272 upstream. Not having power is a pretty serious error so check that we are able to enable the supply and error out if we can't. Signed-off-by: Mark Brown Signed-off-by: Guenter Roeck --- drivers/hwmon/sht15.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 9594cdb..bbfa1e3 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -926,7 +926,13 @@ static int __devinit sht15_probe(struct platform_device *pdev) if (voltage) data->supply_uV = voltage; - regulator_enable(data->reg); + ret = regulator_enable(data->reg); + if (ret != 0) { + dev_err(&pdev->dev, + "failed to enable regulator: %d\n", ret); + return ret; + } + /* * Setup a notifier block to update this if another device * causes the voltage to change -- cgit v1.1 From 98fbe03043cfc683297aa1d9787ec0e01a997cc1 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 27 Feb 2013 12:01:58 -0500 Subject: drm/radeon: add primary dac adj quirk for R200 board commit e8fc41377f5037ff7a661ea06adc05f1daec1548 upstream. vbios values are wrong leading to colors that are too bright. Use the default values instead. Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/radeon_combios.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 2157e77..98fb3d7 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -958,6 +958,15 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct found = 1; } + /* quirks */ + /* Radeon 9100 (R200) */ + if ((dev->pdev->device == 0x514D) && + (dev->pdev->subsystem_vendor == 0x174B) && + (dev->pdev->subsystem_device == 0x7149)) { + /* vbios value is bad, use the default */ + found = 0; + } + if (!found) /* fallback to defaults */ radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac); -- cgit v1.1 From ce38f02134fc8d9a43cf459a35581e046898c22b Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Tue, 5 Mar 2013 09:42:59 +0000 Subject: e1000e: fix pci-device enable-counter balance commit 4e0855dff094b0d56d6b5b271e0ce7851cc1e063 upstream. This patch removes redundant and unbalanced pci_disable_device() from __e1000_shutdown(). pci_clear_master() is enough, device can go into suspended state with elevated enable_cnt. Bug was introduced in commit 23606cf5d1192c2b17912cb2ef6e62f9b11de133 ("e1000e / PCI / PM: Add basic runtime PM support (rev. 4)") in v2.6.35 Signed-off-by: Konstantin Khlebnikov Cc: Bruce Allan Acked-by: Rafael J. Wysocki Tested-by: Borislav Petkov Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher Signed-off-by: Greg Kroah-Hartman --- drivers/net/e1000e/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 5430a9a..4ef2552 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -5330,7 +5330,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake, */ e1000e_release_hw_control(adapter); - pci_disable_device(pdev); + pci_clear_master(pdev); return 0; } -- cgit v1.1 From eb868f2c44b556ddea6a88e0a1a70945364e0ee1 Mon Sep 17 00:00:00 2001 From: "Tu, Xiaobing" Date: Tue, 23 Oct 2012 01:03:00 +0200 Subject: Fix memory leak in cpufreq stats. commit e37736777254ce1abc85493a5cacbefe5983b896 upstream. When system enters sleep, non-boot CPUs will be disabled. Cpufreq stats sysfs is created when the CPU is up, but it is not freed when the CPU is going down. This will cause memory leak. Signed-off-by: xiaobing tu Signed-off-by: guifang tang Signed-off-by: Rafael J. Wysocki Cc: Colin Cross Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/cpufreq_stats.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index faf7c52..df41080 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -329,6 +329,7 @@ static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb, cpufreq_update_policy(cpu); break; case CPU_DOWN_PREPARE: + case CPU_DOWN_PREPARE_FROZEN: cpufreq_stats_free_sysfs(cpu); break; case CPU_DEAD: -- cgit v1.1 From 3241d80d48900fc43535980865f1ef726af68713 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 8 Mar 2013 12:43:32 -0800 Subject: dmi_scan: fix missing check for _DMI_ signature in smbios_present() commit a40e7cf8f06b4e322ba902e4e9f6a6b0c2daa907 upstream. Commit 9f9c9cbb6057 ("drivers/firmware/dmi_scan.c: fetch dmi version from SMBIOS if it exists") hoisted the check for "_DMI_" into dmi_scan_machine(), which means that we don't bother to check for "_DMI_" at offset 16 in an SMBIOS entry. smbios_present() may also call dmi_present() for an address where we found "_SM_", if it failed further validation. Check for "_DMI_" in smbios_present() before calling dmi_present(). [akpm@linux-foundation.org: fix build] Signed-off-by: Ben Hutchings Reported-by: Tim McGrath Tested-by: Tim Mcgrath Cc: Zhenzhong Duan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/dmi_scan.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 66b6315..03ab4e8 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -442,7 +442,6 @@ static int __init dmi_present(const char __iomem *p) static int __init smbios_present(const char __iomem *p) { u8 buf[32]; - int offset = 0; memcpy_fromio(buf, p, 32); if ((buf[5] < 32) && dmi_checksum(buf, buf[5])) { @@ -461,9 +460,9 @@ static int __init smbios_present(const char __iomem *p) dmi_ver = 0x0206; break; } - offset = 16; + return memcmp(p + 16, "_DMI_", 5) || dmi_present(p + 16); } - return dmi_present(buf + offset); + return 1; } void __init dmi_scan_machine(void) -- cgit v1.1 From 74bb0c4e0d2644b9b070d92e675e6c2d04e5875b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 19 Feb 2013 09:47:09 -0600 Subject: qcaux: add Franklin U600 commit 2d90e63603ac235aecd7d20e234616e0682c8b1f upstream. 4 ports; AT/PPP is standard CDC-ACM. The other three (added by this patch) are QCDM/DIAG, possibly GPS, and unknown. Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/qcaux.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/qcaux.c b/drivers/usb/serial/qcaux.c index 87271e3..153d719 100644 --- a/drivers/usb/serial/qcaux.c +++ b/drivers/usb/serial/qcaux.c @@ -69,6 +69,7 @@ static struct usb_device_id id_table[] = { { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfd, 0xff) }, /* NMEA */ { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfe, 0xff) }, /* WMC */ { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xff, 0xff) }, /* DIAG */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1fac, 0x0151, 0xff, 0xff, 0xff) }, { }, }; MODULE_DEVICE_TABLE(usb, id_table); -- cgit v1.1 From 22220e7c212f7f64d76077c0601139cf0c56255c Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Fri, 8 Mar 2013 11:30:18 +1100 Subject: virtio: rng: disallow multiple device registrations, fixes crashes commit e84e7a56a3aa2963db506299e29a5f3f09377f9b upstream. The code currently only supports one virtio-rng device at a time. Invoking guests with multiple devices causes the guest to blow up. Check if we've already registered and initialised the driver. Also cleanup in case of registration errors or hot-unplug so that a new device can be used. Reported-by: Peter Krempa Reported-by: Signed-off-by: Amit Shah Signed-off-by: Rusty Russell Signed-off-by: Greg Kroah-Hartman --- drivers/char/hw_random/virtio-rng.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 75f1cbd..ca7570d 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -88,14 +88,22 @@ static int virtrng_probe(struct virtio_device *vdev) { int err; + if (vq) { + /* We only support one device for now */ + return -EBUSY; + } /* We expect a single virtqueue. */ vq = virtio_find_single_vq(vdev, random_recv_done, "input"); - if (IS_ERR(vq)) - return PTR_ERR(vq); + if (IS_ERR(vq)) { + err = PTR_ERR(vq); + vq = NULL; + return err; + } err = hwrng_register(&virtio_hwrng); if (err) { vdev->config->del_vqs(vdev); + vq = NULL; return err; } @@ -107,6 +115,7 @@ static void __devexit virtrng_remove(struct virtio_device *vdev) vdev->config->reset(vdev); hwrng_unregister(&virtio_hwrng); vdev->config->del_vqs(vdev); + vq = NULL; } static struct virtio_device_id id_table[] = { -- cgit v1.1 From 77dd40c77a5eb5db824efa37ba78e9146bc6d7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 27 Feb 2013 15:52:56 +0100 Subject: USB: option: add Huawei E5331 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit daec90e7382cbd0e73eb6861109b3da91e5ab1f3 upstream. Another device using CDC ACM with vendor specific protocol to mark serial functions. Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 24a3ea6..e59e585 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -579,6 +579,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c1f, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, -- cgit v1.1 From c0863b3aeabd52847c62bbf806cccb3041808ad8 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 12 Mar 2013 14:52:42 +0100 Subject: USB: cdc-wdm: fix buffer overflow commit c0f5ecee4e741667b2493c742b60b6218d40b3aa upstream. The buffer for responses must not overflow. If this would happen, set a flag, drop the data and return an error after user space has read all remaining data. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 8a72e05..c84b455 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -54,6 +54,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_POLL_RUNNING 6 #define WDM_RESPONDING 7 #define WDM_SUSPENDING 8 +#define WDM_OVERFLOW 10 #define WDM_MAX 16 @@ -118,6 +119,7 @@ static void wdm_in_callback(struct urb *urb) { struct wdm_device *desc = urb->context; int status = urb->status; + int length = urb->actual_length; spin_lock(&desc->iuspin); clear_bit(WDM_RESPONDING, &desc->flags); @@ -148,9 +150,17 @@ static void wdm_in_callback(struct urb *urb) } desc->rerr = status; - desc->reslength = urb->actual_length; - memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); - desc->length += desc->reslength; + if (length + desc->length > desc->wMaxCommand) { + /* The buffer would overflow */ + set_bit(WDM_OVERFLOW, &desc->flags); + } else { + /* we may already be in overflow */ + if (!test_bit(WDM_OVERFLOW, &desc->flags)) { + memmove(desc->ubuf + desc->length, desc->inbuf, length); + desc->length += length; + desc->reslength = length; + } + } skip_error: wake_up(&desc->wait); @@ -417,6 +427,11 @@ retry: rv = -ENODEV; goto err; } + if (test_bit(WDM_OVERFLOW, &desc->flags)) { + clear_bit(WDM_OVERFLOW, &desc->flags); + rv = -ENOBUFS; + goto err; + } i++; if (file->f_flags & O_NONBLOCK) { if (!test_bit(WDM_READ, &desc->flags)) { @@ -456,6 +471,7 @@ retry: spin_unlock_irq(&desc->iuspin); goto retry; } + if (!desc->reslength) { /* zero length read */ dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__); clear_bit(WDM_READ, &desc->flags); @@ -901,6 +917,7 @@ static int wdm_post_reset(struct usb_interface *intf) struct wdm_device *desc = usb_get_intfdata(intf); int rv; + clear_bit(WDM_OVERFLOW, &desc->flags); rv = recover_from_urb_loss(desc); mutex_unlock(&desc->wlock); mutex_unlock(&desc->rlock); -- cgit v1.1 From 0b709ddda5b44574d14607931537eca459dbcb21 Mon Sep 17 00:00:00 2001 From: "Matwey V. Kornilov" Date: Sat, 9 Mar 2013 13:57:32 +0400 Subject: usb: cp210x new Vendor/Device IDs commit be3101c23394af59694c8a2aae6d07f5da62fea5 upstream. This patch adds support for the Lake Shore Cryotronics devices to the CP210x driver. These lines are ported from cp210x driver distributed by Lake Shore web site: http://www.lakeshore.com/Documents/Lake%20Shore%20cp210x-3.0.0.tar.gz and licensed under the terms of GPLv2. Moreover, I've tested this changes with Lake Shore 335 in my labs. Signed-off-by: Matwey V. Kornilov Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 381d00d..96cd80c 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -156,6 +156,25 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */ { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */ + { USB_DEVICE(0x1FB9, 0x0100) }, /* Lake Shore Model 121 Current Source */ + { USB_DEVICE(0x1FB9, 0x0200) }, /* Lake Shore Model 218A Temperature Monitor */ + { USB_DEVICE(0x1FB9, 0x0201) }, /* Lake Shore Model 219 Temperature Monitor */ + { USB_DEVICE(0x1FB9, 0x0202) }, /* Lake Shore Model 233 Temperature Transmitter */ + { USB_DEVICE(0x1FB9, 0x0203) }, /* Lake Shore Model 235 Temperature Transmitter */ + { USB_DEVICE(0x1FB9, 0x0300) }, /* Lake Shore Model 335 Temperature Controller */ + { USB_DEVICE(0x1FB9, 0x0301) }, /* Lake Shore Model 336 Temperature Controller */ + { USB_DEVICE(0x1FB9, 0x0302) }, /* Lake Shore Model 350 Temperature Controller */ + { USB_DEVICE(0x1FB9, 0x0303) }, /* Lake Shore Model 371 AC Bridge */ + { USB_DEVICE(0x1FB9, 0x0400) }, /* Lake Shore Model 411 Handheld Gaussmeter */ + { USB_DEVICE(0x1FB9, 0x0401) }, /* Lake Shore Model 425 Gaussmeter */ + { USB_DEVICE(0x1FB9, 0x0402) }, /* Lake Shore Model 455A Gaussmeter */ + { USB_DEVICE(0x1FB9, 0x0403) }, /* Lake Shore Model 475A Gaussmeter */ + { USB_DEVICE(0x1FB9, 0x0404) }, /* Lake Shore Model 465 Three Axis Gaussmeter */ + { USB_DEVICE(0x1FB9, 0x0600) }, /* Lake Shore Model 625A Superconducting MPS */ + { USB_DEVICE(0x1FB9, 0x0601) }, /* Lake Shore Model 642A Magnet Power Supply */ + { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */ + { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */ + { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */ { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ -- cgit v1.1 From d2ea887d1d3b43aa0d4800a5e2dedbe5f5b456c3 Mon Sep 17 00:00:00 2001 From: Christian Schmiedl Date: Wed, 6 Mar 2013 17:08:50 +0100 Subject: USB: added support for Cinterion's products AH6 and PLS8 commit 1941138e1c024ecb5bd797d414928d3eb94d8662 upstream. add support for Cinterion's products AH6 and PLS8 by adding Product IDs and USB_DEVICE tuples. Signed-off-by: Christian Schmiedl Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index e59e585..4418538 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -341,6 +341,8 @@ static void option_instat_callback(struct urb *urb); #define CINTERION_PRODUCT_EU3_E 0x0051 #define CINTERION_PRODUCT_EU3_P 0x0052 #define CINTERION_PRODUCT_PH8 0x0053 +#define CINTERION_PRODUCT_AH6 0x0055 +#define CINTERION_PRODUCT_PLS8 0x0060 /* Olivetti products */ #define OLIVETTI_VENDOR_ID 0x0b3c @@ -1261,6 +1263,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AH6) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLS8) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, -- cgit v1.1 From 47003abe681e978405932244d5a23acf90c78387 Mon Sep 17 00:00:00 2001 From: Steve Conklin Date: Thu, 7 Mar 2013 17:19:33 -0600 Subject: usb: serial: Add Rigblaster Advantage to device table commit a57e82a18779ab8a5e5a1f5841cef937cf578913 upstream. The Rigblaster Advantage is an amateur radio interface sold by West Mountain Radio. It contains a cp210x serial interface but the device ID is not in the driver. Signed-off-by: Steve Conklin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 96cd80c..913a178 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -91,6 +91,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */ { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ + { USB_DEVICE(0x2405, 0x0003) }, /* West Mountain Radio RIGblaster Advantage */ { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ { USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */ -- cgit v1.1 From 581964efbe9480abd67e53a35bab14a9d8232116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Mon, 4 Mar 2013 14:19:21 +0100 Subject: USB: storage: fix Huawei mode switching regression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit ab4b71644a26d1ab92b987b2fd30e17c25e89f85 upstream. This reverts commit 200e0d99 ("USB: storage: optimize to match the Huawei USB storage devices and support new switch command" and the followup bugfix commit cd060956 ("USB: storage: properly handle the endian issues of idProduct"). The commit effectively added a large number of Huawei devices to the deprecated usb-storage mode switching logic. Many of these devices have been in use and supported by the userspace usb_modeswitch utility for years. Forcing the switching inside the kernel causes a number of regressions as a result of ignoring existing onfigurations, and also completely takes away the ability to configure mode switching per device/system/user. Known regressions caused by this: - Some of the devices support multiple modes, using different switching commands. There are existing configurations taking advantage of this. - There is a real use case for disabling mode switching and instead mounting the exposed storage device. This becomes impossible with switching logic inside the usb-storage driver. - At least on device fail as a result of the usb-storage switching command, becoming completely unswitchable. This is possibly a firmware bug, but still a regression because the device work as expected using usb_modeswitch defaults. In-kernel mode switching was deprecated years ago with the development of the more user friendly userspace alternatives. The existing list of devices in usb-storage was only kept to prevent breaking already working systems. The long term plan is to remove the list, not to add to it. Ref: http://permalink.gmane.org/gmane.linux.usb.general/28543 Signed-off-by: Bjørn Mork Cc: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/initializers.c | 76 +-------- drivers/usb/storage/initializers.h | 4 +- drivers/usb/storage/unusual_devs.h | 329 ++++++++++++++++++++++++++++++++++++- 3 files changed, 331 insertions(+), 78 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 7ab9046..105d900 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c @@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us) return 0; } -/* This places the HUAWEI usb dongles in multi-port mode */ -static int usb_stor_huawei_feature_init(struct us_data *us) +/* This places the HUAWEI E220 devices in multi-port mode */ +int usb_stor_huawei_e220_init(struct us_data *us) { int result; @@ -104,75 +104,3 @@ static int usb_stor_huawei_feature_init(struct us_data *us) US_DEBUGP("Huawei mode set result is %d\n", result); return 0; } - -/* - * It will send a scsi switch command called rewind' to huawei dongle. - * When the dongle receives this command at the first time, - * it will reboot immediately. After rebooted, it will ignore this command. - * So it is unnecessary to read its response. - */ -static int usb_stor_huawei_scsi_init(struct us_data *us) -{ - int result = 0; - int act_len = 0; - struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf; - char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcbw->Tag = 0; - bcbw->DataTransferLength = 0; - bcbw->Flags = bcbw->Lun = 0; - bcbw->Length = sizeof(rewind_cmd); - memset(bcbw->CDB, 0, sizeof(bcbw->CDB)); - memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd)); - - result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw, - US_BULK_CB_WRAP_LEN, &act_len); - US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result); - return result; -} - -/* - * It tries to find the supported Huawei USB dongles. - * In Huawei, they assign the following product IDs - * for all of their mobile broadband dongles, - * including the new dongles in the future. - * So if the product ID is not included in this list, - * it means it is not Huawei's mobile broadband dongles. - */ -static int usb_stor_huawei_dongles_pid(struct us_data *us) -{ - struct usb_interface_descriptor *idesc; - int idProduct; - - idesc = &us->pusb_intf->cur_altsetting->desc; - idProduct = le16_to_cpu(us->pusb_dev->descriptor.idProduct); - /* The first port is CDROM, - * means the dongle in the single port mode, - * and a switch command is required to be sent. */ - if (idesc && idesc->bInterfaceNumber == 0) { - if ((idProduct == 0x1001) - || (idProduct == 0x1003) - || (idProduct == 0x1004) - || (idProduct >= 0x1401 && idProduct <= 0x1500) - || (idProduct >= 0x1505 && idProduct <= 0x1600) - || (idProduct >= 0x1c02 && idProduct <= 0x2202)) { - return 1; - } - } - return 0; -} - -int usb_stor_huawei_init(struct us_data *us) -{ - int result = 0; - - if (usb_stor_huawei_dongles_pid(us)) { - if (le16_to_cpu(us->pusb_dev->descriptor.idProduct) >= 0x1446) - result = usb_stor_huawei_scsi_init(us); - else - result = usb_stor_huawei_feature_init(us); - } - return result; -} diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h index 5376d4f..529327f 100644 --- a/drivers/usb/storage/initializers.h +++ b/drivers/usb/storage/initializers.h @@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us); * flash reader */ int usb_stor_ucr61s2b_init(struct us_data *us); -/* This places the HUAWEI usb dongles in multi-port mode */ -int usb_stor_huawei_init(struct us_data *us); +/* This places the HUAWEI E220 devices in multi-port mode */ +int usb_stor_huawei_e220_init(struct us_data *us); diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 12640ef..fa8a1b2 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1515,10 +1515,335 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100, /* Reported by fangxiaozhi * This brings the HUAWEI data card devices into multi-port mode */ -UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50, +UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000, "HUAWEI MOBILE", "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init, + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1402, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1404, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1407, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1420, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1421, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1422, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1423, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1424, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1425, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1426, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1427, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1428, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1429, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1430, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1431, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1432, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1433, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1434, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1435, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1436, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1437, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1438, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1439, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, 0), /* Reported by Vilius Bilinkevicius Date: Fri, 1 Mar 2013 10:51:15 -0500 Subject: USB: EHCI: don't check DMA values in QH overlays commit feca7746d5d9e84b105a613b7f3b6ad00d327372 upstream. This patch (as1661) fixes a rather obscure bug in ehci-hcd. In a couple of places, the driver compares the DMA address stored in a QH's overlay region with the address of a particular qTD, in order to see whether that qTD is the one currently being processed by the hardware. (If it is then the status in the QH's overlay region is more up-to-date than the status in the qTD, and if it isn't then the overlay's value needs to be adjusted when the QH is added back to the active schedule.) However, DMA address in the overlay region isn't always valid. It sometimes will contain a stale value, which may happen by coincidence to be equal to a qTD's DMA address. Instead of checking the DMA address, we should check whether the overlay region is active and valid. The patch tests the ACTIVE bit in the overlay, and clears this bit when the overlay becomes invalid (which happens when the currently-executing URB is unlinked). This is the second part of a fix for the regression reported at: https://bugs.launchpad.net/bugs/1088733 Signed-off-by: Alan Stern Reported-by: Joseph Salisbury Reported-and-tested-by: Stephen Thirlwall Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-q.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 923153c..a54c380 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -137,7 +137,7 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) * qtd is updated in qh_completions(). Update the QH * overlay here. */ - if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) { + if (qh->hw->hw_token & ACTIVE_BIT(ehci)) { qh->hw->hw_qtd_next = qtd->hw_next; qtd = NULL; } @@ -450,11 +450,19 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) else if (last_status == -EINPROGRESS && !urb->unlinked) continue; - /* qh unlinked; token in overlay may be most current */ - if (state == QH_STATE_IDLE - && cpu_to_hc32(ehci, qtd->qtd_dma) - == hw->hw_current) { + /* + * If this was the active qtd when the qh was unlinked + * and the overlay's token is active, then the overlay + * hasn't been written back to the qtd yet so use its + * token instead of the qtd's. After the qtd is + * processed and removed, the overlay won't be valid + * any more. + */ + if (state == QH_STATE_IDLE && + qh->qtd_list.next == &qtd->qtd_list && + (hw->hw_token & ACTIVE_BIT(ehci))) { token = hc32_to_cpu(ehci, hw->hw_token); + hw->hw_token &= ~ACTIVE_BIT(ehci); /* An unlink may leave an incomplete * async transaction in the TT buffer. -- cgit v1.1 From e41eeb8a041667163b0d9efd6d30c01440179c9a Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Mon, 18 Feb 2013 19:54:18 +0000 Subject: staging: vt6656: Fix oops on resume from suspend. commit 6987a6dabfc40222ef767f67b57212fe3a0225fb upstream. Remove usb_put_dev from vt6656_suspend and usb_get_dev from vt6566_resume. These are not normally in suspend/resume functions. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/main_usb.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index ce459d5..5fb56a6 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -725,8 +725,6 @@ static int vt6656_suspend(struct usb_interface *intf, pm_message_t message) if (device->flags & DEVICE_FLAGS_OPENED) device_close(device->dev); - usb_put_dev(interface_to_usbdev(intf)); - return 0; } @@ -737,8 +735,6 @@ static int vt6656_resume(struct usb_interface *intf) if (!device || !device->dev) return -ENODEV; - usb_get_dev(interface_to_usbdev(intf)); - if (!(device->flags & DEVICE_FLAGS_OPENED)) device_open(device->dev); -- cgit v1.1 From e88da4a932b6f524afdf26dadb8a63f0afcfcd14 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Sat, 9 Mar 2013 23:16:44 +0100 Subject: tty: serial: fix typo "ARCH_S5P6450" commit 827aa0d36d486f359808c8fb931cf7a71011a09d upstream. This could have been either ARCH_S5P64X0 or CPU_S5P6450. Looking at commit 2555e663b367b8d555e76023f4de3f6338c28d6c ("ARM: S5P64X0: Add UART serial support for S5P6450") - which added this typo - makes clear this should be CPU_S5P6450. Signed-off-by: Paul Bolle Acked-by: Kukjin Kim Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 9789293..3f71771 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -458,7 +458,7 @@ config SERIAL_SAMSUNG_UARTS int depends on ARM && PLAT_SAMSUNG default 2 if ARCH_S3C2400 - default 6 if ARCH_S5P6450 + default 6 if CPU_S5P6450 default 4 if SERIAL_SAMSUNG_UARTS_4 default 3 help -- cgit v1.1 From 1fc6d3ad342542afb92cca52bc5d8569f29576e0 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 15 Jan 2013 23:26:22 +0100 Subject: TTY: do not reset master's packet mode commit b81273a132177edd806476b953f6afeb17b786d5 upstream. Now that login from util-linux is forced to drop all references to a TTY which it wants to hangup (to reach reference count 1) we are seeing issues with telnet. When login closes its last reference to the slave PTY, it also resets packet mode on the *master* side. And we have a race here. What telnet does is fork+exec of `login'. Then there are two scenarios: * `login' closes the slave TTY and resets thus master's packet mode, but even now telnet properly sets the mode, or * `telnetd' sets packet mode on the master, `login' closes the slave TTY and resets master's packet mode. The former case is OK. However the latter happens in much more cases, by the order of magnitude to be precise. So when one tries to login to such a messed telnet setup, they see the following: inux login: ogin incorrect Note the missing first letters -- telnet thinks it is still in the packet mode, so when it receives "linux login" from `login', it considers "l" as the type of the packet and strips it. SuS does not mention how the implementation should behave. Both BSDs I checked (Free and Net) do not reset the flag upon the last close. By this I am resurrecting an old bug, see References. We are hitting it regularly now, i.e. with updated util-linux, ergo login. Here, I am changing a behavior introduced back in 2.1 times. It would better have a long time testing before goes upstream. Signed-off-by: Jiri Slaby Cc: Mauro Carvalho Chehab Cc: Bryan Mason References: https://lkml.org/lkml/2009/11/11/223 References: https://bugzilla.redhat.com/show_bug.cgi?id=504703 References: https://bugzilla.novell.com/show_bug.cgi?id=797042 Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index e18604b..d19b879 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -49,7 +49,6 @@ static void pty_close(struct tty_struct *tty, struct file *filp) tty->packet = 0; if (!tty->link) return; - tty->link->packet = 0; set_bit(TTY_OTHER_CLOSED, &tty->link->flags); wake_up_interruptible(&tty->link->read_wait); wake_up_interruptible(&tty->link->write_wait); -- cgit v1.1 From f18f43cb20c3236df02472f84f5183e01c457507 Mon Sep 17 00:00:00 2001 From: Sebastian Riemer Date: Thu, 21 Feb 2013 13:28:09 +1100 Subject: md: protect against crash upon fsync on ro array commit bbfa57c0f2243a7c31fd248d22e9861a2802cad5 upstream. If an fsync occurs on a read-only array, we need to send a completion for the IO and may not increment the active IO count. Otherwise, we hit a bug trace and can't stop the MD array anymore. By advice of Christoph Hellwig we return success upon a flush request but we return -EROFS for other writes. We detect flush requests by checking if the bio has zero sectors. Signed-off-by: Sebastian Riemer Cc: Christoph Hellwig Cc: Ben Hutchings Cc: NeilBrown Reported-by: Ben Hutchings Acked-by: Paul Menzel Signed-off-by: Greg Kroah-Hartman --- drivers/md/md.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 98262e5..4ef75e9 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -299,6 +299,10 @@ static int md_make_request(struct request_queue *q, struct bio *bio) bio_io_error(bio); return 0; } + if (mddev->ro == 1 && unlikely(rw == WRITE)) { + bio_endio(bio, bio_sectors(bio) == 0 ? 0 : -EROFS); + return 0; + } smp_rmb(); /* Ensure implications of 'active' are visible */ rcu_read_lock(); if (mddev->suspended) { -- cgit v1.1 From b25a5de428a92dfef306a28f6bf6b2beac2b0074 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 14 Mar 2013 16:27:18 +0800 Subject: hwmon: (lineage-pem) Add missing terminating entry for pem_[input|fan]_attributes commit df069079c153d22adf6c28dcc0b1cf62bba75167 upstream. Signed-off-by: Axel Lin Acked-by: Jean Delvare Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/lineage-pem.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/lineage-pem.c b/drivers/hwmon/lineage-pem.c index 58eded2..c9910f7 100644 --- a/drivers/hwmon/lineage-pem.c +++ b/drivers/hwmon/lineage-pem.c @@ -421,6 +421,7 @@ static struct attribute *pem_input_attributes[] = { &sensor_dev_attr_in2_input.dev_attr.attr, &sensor_dev_attr_curr1_input.dev_attr.attr, &sensor_dev_attr_power1_input.dev_attr.attr, + NULL }; static const struct attribute_group pem_input_group = { @@ -431,6 +432,7 @@ static struct attribute *pem_fan_attributes[] = { &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan2_input.dev_attr.attr, &sensor_dev_attr_fan3_input.dev_attr.attr, + NULL }; static const struct attribute_group pem_fan_group = { -- cgit v1.1 From 47c89922d3af8dc01ad77e34a61e5ceae2d7a11c Mon Sep 17 00:00:00 2001 From: Marcin Jurkowski Date: Sat, 2 Mar 2013 14:50:15 +0100 Subject: w1: fix oops when w1_search is called from netlink connector commit 9d1817cab2f030f6af360e961cc69bb1da8ad765 upstream. On Sat, Mar 02, 2013 at 10:45:10AM +0100, Sven Geggus wrote: > This is the bad commit I found doing git bisect: > 04f482faf50535229a5a5c8d629cf963899f857c is the first bad commit > commit 04f482faf50535229a5a5c8d629cf963899f857c > Author: Patrick McHardy > Date: Mon Mar 28 08:39:36 2011 +0000 Good job. I was too lazy to bisect for bad commit;) Reading the code I found problematic kthread_should_stop call from netlink connector which causes the oops. After applying a patch, I've been testing owfs+w1 setup for nearly two days and it seems to work very reliable (no hangs, no memleaks etc). More detailed description and possible fix is given below: Function w1_search can be called from either kthread or netlink callback. While the former works fine, the latter causes oops due to kthread_should_stop invocation. This patch adds a check if w1_search is serving netlink command, skipping kthread_should_stop invocation if so. Signed-off-by: Marcin Jurkowski Acked-by: Evgeniy Polyakov Cc: Josh Boyer Tested-by: Sven Geggus Signed-off-by: Greg Kroah-Hartman --- drivers/w1/w1.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 10606c8..cbff966 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -918,7 +918,8 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb tmp64 = (triplet_ret >> 2); rn |= (tmp64 << i); - if (kthread_should_stop()) { + /* ensure we're called from kthread and not by netlink callback */ + if (!dev->priv && kthread_should_stop()) { dev_dbg(&dev->dev, "Abort w1_search\n"); return; } -- cgit v1.1 From f77ce97ae2bc14cd3a340b3ce91008350fc3fa3f Mon Sep 17 00:00:00 2001 From: Dmitry Rogozhkin Date: Wed, 3 Oct 2012 17:15:26 +0300 Subject: drm/i915: EBUSY status handling added to i915_gem_fault(). commit e79e0fe380847493266fba557217e2773c61bd1b upstream. Subsequent threads returning EBUSY from vm_insert_pfn() was not handled correctly. As a result concurrent access from new threads to mmapped data caused SIGBUS. Note that this fixes i-g-t/tests/gem_threaded_tiled_access. Tested-by: Mika Kuoppala Signed-off-by: Dmitry Rogozhkin Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/i915_gem.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5548593..46e04a1 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1256,6 +1256,11 @@ out: case 0: case -ERESTARTSYS: case -EINTR: + case -EBUSY: + /* + * EBUSY is ok: this just means that another thread + * already did the job. + */ return VM_FAULT_NOPAGE; case -ENOMEM: return VM_FAULT_OOM; -- cgit v1.1 From e97d818d630b09895d0f5efd879df08777273f11 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 16 Mar 2013 06:32:16 -0700 Subject: hwmon: (sht15) Fix memory leak if regulator_enable() fails Commit 3e78080f8148 ('hwmon: (sht15) Check return value of regulator_enable()') depends on the use of devm_kmalloc() for automatic resource cleanup in the failure cases, which was introduced in 3.7. In older stable branches, explicit cleanup is needed. Signed-off-by: Ben Hutchings Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/sht15.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index bbfa1e3..8aa6e12 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -930,7 +930,7 @@ static int __devinit sht15_probe(struct platform_device *pdev) if (ret != 0) { dev_err(&pdev->dev, "failed to enable regulator: %d\n", ret); - return ret; + goto err_free_data; } /* -- cgit v1.1 From 965fa30c0675af7086dffa940839bcc894ca376d Mon Sep 17 00:00:00 2001 From: Guo Chao Date: Thu, 21 Feb 2013 15:16:45 -0800 Subject: loopdev: fix a deadlock commit 5370019dc2d2c2ff90e95d181468071362934f3a upstream. bd_mutex and lo_ctl_mutex can be held in different order. Path #1: blkdev_open blkdev_get __blkdev_get (hold bd_mutex) lo_open (hold lo_ctl_mutex) Path #2: blkdev_ioctl lo_ioctl (hold lo_ctl_mutex) lo_set_capacity (hold bd_mutex) Lockdep does not report it, because path #2 actually holds a subclass of lo_ctl_mutex. This subclass seems creep into the code by mistake. The patch author actually just mentioned it in the changelog, see commit f028f3b2 ("loop: fix circular locking in loop_clr_fd()"), also see: http://marc.info/?l=linux-kernel&m=123806169129727&w=2 Path #2 hold bd_mutex to call bd_set_size(), I've protected it with i_mutex in a previous patch, so drop bd_mutex at this site. Signed-off-by: Guo Chao Cc: Alexander Viro Cc: Guo Chao Cc: M. Hindess Cc: Nikanth Karthikesan Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe Acked-by: Jeff Mahoney Signed-off-by: Greg Kroah-Hartman --- drivers/block/loop.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 2ebacf0..258cd0a 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1274,11 +1274,9 @@ static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev) /* the width of sector_t may be narrow for bit-shift */ sz = sec; sz <<= 9; - mutex_lock(&bdev->bd_mutex); bd_set_size(bdev, sz); /* let user-space know about the new size */ kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE); - mutex_unlock(&bdev->bd_mutex); out: return err; -- cgit v1.1 From 20ef510141e92e872e5dfd84dd6c77b8f94effee Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 6 Mar 2013 11:02:37 +0000 Subject: tun: add a missing nf_reset() in tun_net_xmit() [ Upstream commit f8af75f3517a24838a36eb5797a1a3e60bf9e276 ] Dave reported following crash : general protection fault: 0000 [#1] SMP CPU 2 Pid: 25407, comm: qemu-kvm Not tainted 3.7.9-205.fc18.x86_64 #1 Hewlett-Packard HP Z400 Workstation/0B4Ch RIP: 0010:[] [] destroy_conntrack+0x35/0x120 [nf_conntrack] RSP: 0018:ffff880276913d78 EFLAGS: 00010206 RAX: 50626b6b7876376c RBX: ffff88026e530d68 RCX: ffff88028d158e00 RDX: ffff88026d0d5470 RSI: 0000000000000011 RDI: 0000000000000002 RBP: ffff880276913d88 R08: 0000000000000000 R09: ffff880295002900 R10: 0000000000000000 R11: 0000000000000003 R12: ffffffff81ca3b40 R13: ffffffff8151a8e0 R14: ffff880270875000 R15: 0000000000000002 FS: 00007ff3bce38a00(0000) GS:ffff88029fc40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 00007fd1430bd000 CR3: 000000027042b000 CR4: 00000000000027e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process qemu-kvm (pid: 25407, threadinfo ffff880276912000, task ffff88028c369720) Stack: ffff880156f59100 ffff880156f59100 ffff880276913d98 ffffffff815534f7 ffff880276913db8 ffffffff8151a74b ffff880270875000 ffff880156f59100 ffff880276913dd8 ffffffff8151a5a6 ffff880276913dd8 ffff88026d0d5470 Call Trace: [] nf_conntrack_destroy+0x17/0x20 [] skb_release_head_state+0x7b/0x100 [] __kfree_skb+0x16/0xa0 [] kfree_skb+0x36/0xa0 [] skb_queue_purge+0x20/0x40 [] __tun_detach+0x117/0x140 [tun] [] tun_chr_close+0x3c/0xd0 [tun] [] __fput+0xec/0x240 [] ____fput+0xe/0x10 [] task_work_run+0xa7/0xe0 [] do_notify_resume+0x71/0xb0 [] int_signal+0x12/0x17 Code: 00 00 04 48 89 e5 41 54 53 48 89 fb 4c 8b a7 e8 00 00 00 0f 85 de 00 00 00 0f b6 73 3e 0f b7 7b 2a e8 10 40 00 00 48 85 c0 74 0e <48> 8b 40 28 48 85 c0 74 05 48 89 df ff d0 48 c7 c7 08 6a 3a a0 RIP [] destroy_conntrack+0x35/0x120 [nf_conntrack] RSP This is because tun_net_xmit() needs to call nf_reset() before queuing skb into receive_queue Reported-by: Dave Jones Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/tun.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index a631bf7..28c5c6a 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -417,6 +417,8 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) * for indefinite time. */ skb_orphan(skb); + nf_reset(skb); + /* Enqueue packet */ skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb); -- cgit v1.1 From 28de3b32ee0a6785e17dd8db5e37c5ccc19a3b79 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 20 Mar 2013 14:16:12 -0700 Subject: Revert "USB: EHCI: don't check DMA values in QH overlays" This reverts commit 0319f9909ce68a7516dfc8d53400e07168d281a8, which is commit feca7746d5d9e84b105a613b7f3b6ad00d327372 upstream. It shouldn't have gone into this stable release. Cc: Alan Stern Cc: Joseph Salisbury Cc: Stephen Thirlwall Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-q.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index a54c380..923153c 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -137,7 +137,7 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) * qtd is updated in qh_completions(). Update the QH * overlay here. */ - if (qh->hw->hw_token & ACTIVE_BIT(ehci)) { + if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) { qh->hw->hw_qtd_next = qtd->hw_next; qtd = NULL; } @@ -450,19 +450,11 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) else if (last_status == -EINPROGRESS && !urb->unlinked) continue; - /* - * If this was the active qtd when the qh was unlinked - * and the overlay's token is active, then the overlay - * hasn't been written back to the qtd yet so use its - * token instead of the qtd's. After the qtd is - * processed and removed, the overlay won't be valid - * any more. - */ - if (state == QH_STATE_IDLE && - qh->qtd_list.next == &qtd->qtd_list && - (hw->hw_token & ACTIVE_BIT(ehci))) { + /* qh unlinked; token in overlay may be most current */ + if (state == QH_STATE_IDLE + && cpu_to_hc32(ehci, qtd->qtd_dma) + == hw->hw_current) { token = hc32_to_cpu(ehci, hw->hw_token); - hw->hw_token &= ~ACTIVE_BIT(ehci); /* An unlink may leave an incomplete * async transaction in the TT buffer. -- cgit v1.1 From bf40057118cc5392a0fe4bd77b1f65dd49bcc8d2 Mon Sep 17 00:00:00 2001 From: Tkhai Kirill Date: Sat, 23 Feb 2013 23:01:15 +0000 Subject: sunsu: Fix panic in case of nonexistent port at "console=ttySY" cmdline option [ Upstream commit cb29529ea0030e60ef1bbbf8399a43d397a51526 ] If a machine has X (X < 4) sunsu ports and cmdline option "console=ttySY" is passed, where X < Y <= 4, than the following panic happens: Unable to handle kernel NULL pointer dereference TPC: RPC: I7: Call Trace: [0000000000453a38] register_console+0x378/0x3e0 [0000000000576fa0] uart_add_one_port+0x2e0/0x340 [000000000057af40] su_probe+0x160/0x2e0 [00000000005b8a4c] platform_drv_probe+0xc/0x20 [00000000005b6c2c] driver_probe_device+0x12c/0x220 [00000000005b6da8] __driver_attach+0x88/0xa0 [00000000005b4df4] bus_for_each_dev+0x54/0xa0 [00000000005b5a54] bus_add_driver+0x154/0x260 [00000000005b7190] driver_register+0x50/0x180 [00000000006d250c] sunsu_init+0x18c/0x1e0 [00000000006c2668] do_one_initcall+0xe8/0x160 [00000000006c282c] kernel_init_freeable+0x12c/0x1e0 [0000000000603764] kernel_init+0x4/0x100 [0000000000405f64] ret_from_syscall+0x1c/0x2c [0000000000000000] (null) 1)Fix the panic; 2)Increment registered port number every successful probe. Signed-off-by: Kirill Tkhai CC: David Miller Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sunsu.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 92aa545..bf583fa 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -968,6 +968,7 @@ static struct uart_ops sunsu_pops = { #define UART_NR 4 static struct uart_sunsu_port sunsu_ports[UART_NR]; +static int nr_inst; /* Number of already registered ports */ #ifdef CONFIG_SERIO @@ -1337,13 +1338,8 @@ static int __init sunsu_console_setup(struct console *co, char *options) printk("Console: ttyS%d (SU)\n", (sunsu_reg.minor - 64) + co->index); - /* - * Check whether an invalid uart number has been specified, and - * if so, search for the first available port that does have - * console support. - */ - if (co->index >= UART_NR) - co->index = 0; + if (co->index > nr_inst) + return -ENODEV; port = &sunsu_ports[co->index].port; /* @@ -1408,7 +1404,6 @@ static enum su_type __devinit su_get_type(struct device_node *dp) static int __devinit su_probe(struct platform_device *op) { - static int inst; struct device_node *dp = op->dev.of_node; struct uart_sunsu_port *up; struct resource *rp; @@ -1418,16 +1413,16 @@ static int __devinit su_probe(struct platform_device *op) type = su_get_type(dp); if (type == SU_PORT_PORT) { - if (inst >= UART_NR) + if (nr_inst >= UART_NR) return -EINVAL; - up = &sunsu_ports[inst]; + up = &sunsu_ports[nr_inst]; } else { up = kzalloc(sizeof(*up), GFP_KERNEL); if (!up) return -ENOMEM; } - up->port.line = inst; + up->port.line = nr_inst; spin_lock_init(&up->port.lock); @@ -1461,6 +1456,8 @@ static int __devinit su_probe(struct platform_device *op) } dev_set_drvdata(&op->dev, up); + nr_inst++; + return 0; } @@ -1488,7 +1485,7 @@ static int __devinit su_probe(struct platform_device *op) dev_set_drvdata(&op->dev, up); - inst++; + nr_inst++; return 0; -- cgit v1.1 From 0f4bab2da773a765a4025189bb6fb2ffacccf91a Mon Sep 17 00:00:00 2001 From: Veaceslav Falico Date: Mon, 11 Mar 2013 00:21:48 +0000 Subject: netconsole: don't call __netpoll_cleanup() while atomic [ Upstream commit 3f315bef23075ea8a98a6fe4221a83b83456d970 ] __netpoll_cleanup() is called in netconsole_netdev_event() while holding a spinlock. Release/acquire the spinlock before/after it and restart the loop. Also, disable the netconsole completely, because we won't have chance after the restart of the loop, and might end up in a situation where nt->enabled == 1 and nt->np.dev == NULL. Signed-off-by: Veaceslav Falico Acked-by: Neil Horman Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/netconsole.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 4309296..8824dd4 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -630,6 +630,7 @@ static int netconsole_netdev_event(struct notifier_block *this, goto done; spin_lock_irqsave(&target_list_lock, flags); +restart: list_for_each_entry(nt, &target_list, list) { netconsole_target_get(nt); if (nt->np.dev == dev) { @@ -642,20 +643,17 @@ static int netconsole_netdev_event(struct notifier_block *this, case NETDEV_UNREGISTER: /* * rtnl_lock already held + * we might sleep in __netpoll_cleanup() */ - if (nt->np.dev) { - spin_unlock_irqrestore( - &target_list_lock, - flags); - __netpoll_cleanup(&nt->np); - spin_lock_irqsave(&target_list_lock, - flags); - dev_put(nt->np.dev); - nt->np.dev = NULL; - } + spin_unlock_irqrestore(&target_list_lock, flags); + __netpoll_cleanup(&nt->np); + spin_lock_irqsave(&target_list_lock, flags); + dev_put(nt->np.dev); + nt->np.dev = NULL; nt->enabled = 0; stopped = true; - break; + netconsole_target_put(nt); + goto restart; } } netconsole_target_put(nt); -- cgit v1.1 From de279fd887d1237ec1cd330e1a3c02807eb9ba56 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 24 Jun 2011 20:26:44 +0100 Subject: sfc: Fix loop condition for efx_filter_search() when !for_insert [ Upstream commit 4017dbdc14af1903dc9fcba4d08b89c02325069d ] efx_filter_remove_filter() fails to remove inserted filters in some cases. For example: 1. Two filters A and B have specifications that result in an initial hash collision. 2. A is inserted first, followed by B. 3. An attempt to remove B first succeeds, but if A is removed first a subsequent attempt to remove B fails. When searching for an existing filter (!for_insert), efx_filter_search() must always continue to the maximum search depth for the given type rather than stopping at the first unused entry. Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/net/sfc/filter.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c index 95a980f..08addc9 100644 --- a/drivers/net/sfc/filter.c +++ b/drivers/net/sfc/filter.c @@ -335,28 +335,35 @@ static int efx_filter_search(struct efx_filter_table *table, bool for_insert, int *depth_required) { unsigned hash, incr, filter_idx, depth, depth_max; - struct efx_filter_spec *cmp; hash = efx_filter_hash(key); incr = efx_filter_increment(key); - depth_max = (spec->priority <= EFX_FILTER_PRI_HINT ? - FILTER_CTL_SRCH_HINT_MAX : FILTER_CTL_SRCH_MAX); - - for (depth = 1, filter_idx = hash & (table->size - 1); - depth <= depth_max && test_bit(filter_idx, table->used_bitmap); - ++depth) { - cmp = &table->spec[filter_idx]; - if (efx_filter_equal(spec, cmp)) - goto found; + + filter_idx = hash & (table->size - 1); + depth = 1; + depth_max = (for_insert ? + (spec->priority <= EFX_FILTER_PRI_HINT ? + FILTER_CTL_SRCH_HINT_MAX : FILTER_CTL_SRCH_MAX) : + table->search_depth[spec->type]); + + for (;;) { + /* Return success if entry is used and matches this spec + * or entry is unused and we are trying to insert. + */ + if (test_bit(filter_idx, table->used_bitmap) ? + efx_filter_equal(spec, &table->spec[filter_idx]) : + for_insert) { + *depth_required = depth; + return filter_idx; + } + + /* Return failure if we reached the maximum search depth */ + if (depth == depth_max) + return for_insert ? -EBUSY : -ENOENT; + filter_idx = (filter_idx + incr) & (table->size - 1); + ++depth; } - if (!for_insert) - return -ENOENT; - if (depth > depth_max) - return -EBUSY; -found: - *depth_required = depth; - return filter_idx; } /* Construct/deconstruct external filter IDs */ -- cgit v1.1 From dc3780422853539f985271c59e686e4e53ac0eb2 Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Wed, 22 Jun 2011 12:11:33 +0100 Subject: sfc: Fix Siena mac statistics on big endian platforms [ Upstream commit a659b2a94d87add999229ecd9f2f56817d5d737b ] [bwh: Use __force in the one place it's needed] Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/net/sfc/siena.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index ceac1c9..407f50b 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -372,14 +372,13 @@ static void siena_remove_nic(struct efx_nic *efx) efx->nic_data = NULL; } -#define STATS_GENERATION_INVALID ((u64)(-1)) +#define STATS_GENERATION_INVALID ((__force __le64)(-1)) static int siena_try_update_nic_stats(struct efx_nic *efx) { - u64 *dma_stats; + __le64 *dma_stats; struct efx_mac_stats *mac_stats; - u64 generation_start; - u64 generation_end; + __le64 generation_start, generation_end; mac_stats = &efx->mac_stats; dma_stats = (u64 *)efx->stats_buffer.addr; @@ -390,7 +389,7 @@ static int siena_try_update_nic_stats(struct efx_nic *efx) rmb(); #define MAC_STAT(M, D) \ - mac_stats->M = dma_stats[MC_CMD_MAC_ ## D] + mac_stats->M = le64_to_cpu(dma_stats[MC_CMD_MAC_ ## D]) MAC_STAT(tx_bytes, TX_BYTES); MAC_STAT(tx_bad_bytes, TX_BAD_BYTES); @@ -460,7 +459,8 @@ static int siena_try_update_nic_stats(struct efx_nic *efx) MAC_STAT(rx_internal_error, RX_INTERNAL_ERROR_PKTS); mac_stats->rx_good_lt64 = 0; - efx->n_rx_nodesc_drop_cnt = dma_stats[MC_CMD_MAC_RX_NODESC_DROPS]; + efx->n_rx_nodesc_drop_cnt = + le64_to_cpu(dma_stats[MC_CMD_MAC_RX_NODESC_DROPS]); #undef MAC_STAT @@ -489,7 +489,7 @@ static void siena_update_nic_stats(struct efx_nic *efx) static void siena_start_nic_stats(struct efx_nic *efx) { - u64 *dma_stats = (u64 *)efx->stats_buffer.addr; + __le64 *dma_stats = efx->stats_buffer.addr; dma_stats[MC_CMD_MAC_GENERATION_END] = STATS_GENERATION_INVALID; -- cgit v1.1 From c7c9da144089da9241afd57398144ba4860e91bd Mon Sep 17 00:00:00 2001 From: Stuart Hodgson Date: Fri, 30 Mar 2012 13:04:51 +0100 Subject: sfc: Do not attempt to flush queues if DMA is disabled [ Upstream commit 3dca9d2dc285faf1910d405b65df845cab061356 ] efx_nic_fatal_interrupt() disables DMA before scheduling a reset. After this, we need not and *cannot* flush queues. Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/net/sfc/efx.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index be3cade..f2bdc50 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -651,25 +651,30 @@ static void efx_fini_channels(struct efx_nic *efx) struct efx_channel *channel; struct efx_tx_queue *tx_queue; struct efx_rx_queue *rx_queue; + struct pci_dev *dev = efx->pci_dev; int rc; EFX_ASSERT_RESET_SERIALISED(efx); BUG_ON(efx->port_enabled); - rc = efx_nic_flush_queues(efx); - if (rc && EFX_WORKAROUND_7803(efx)) { - /* Schedule a reset to recover from the flush failure. The - * descriptor caches reference memory we're about to free, - * but falcon_reconfigure_mac_wrapper() won't reconnect - * the MACs because of the pending reset. */ - netif_err(efx, drv, efx->net_dev, - "Resetting to recover from flush failure\n"); - efx_schedule_reset(efx, RESET_TYPE_ALL); - } else if (rc) { - netif_err(efx, drv, efx->net_dev, "failed to flush queues\n"); - } else { - netif_dbg(efx, drv, efx->net_dev, - "successfully flushed all queues\n"); + /* Only perform flush if dma is enabled */ + if (dev->is_busmaster) { + rc = efx_nic_flush_queues(efx); + + if (rc && EFX_WORKAROUND_7803(efx)) { + /* Schedule a reset to recover from the flush failure. The + * descriptor caches reference memory we're about to free, + * but falcon_reconfigure_mac_wrapper() won't reconnect + * the MACs because of the pending reset. */ + netif_err(efx, drv, efx->net_dev, + "Resetting to recover from flush failure\n"); + efx_schedule_reset(efx, RESET_TYPE_ALL); + } else if (rc) { + netif_err(efx, drv, efx->net_dev, "failed to flush queues\n"); + } else { + netif_dbg(efx, drv, efx->net_dev, + "successfully flushed all queues\n"); + } } efx_for_each_channel(channel, efx) { -- cgit v1.1 From 886033e132d6d83d6e7738e3edcd1598a7b66cf0 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 7 Sep 2012 00:58:10 +0100 Subject: sfc: Convert firmware subtypes to native byte order in efx_mcdi_get_board_cfg() [ Upstream commit bfeed902946a31692e7a24ed355b6d13ac37d014 ] On big-endian systems the MTD partition names currently have mangled subtype numbers and are not recognised by the firmware update tool (sfupdate). Signed-off-by: Ben Hutchings [bwh: Backported to 3.0: use old macros for length of firmware subtype array] Signed-off-by: Greg Kroah-Hartman --- drivers/net/sfc/mcdi.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index 81a4253..85e070e 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c @@ -666,9 +666,8 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, u16 *fw_subtype_list) { uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LEN]; - size_t outlen; + size_t outlen, offset, i; int port_num = efx_port_num(efx); - int offset; int rc; BUILD_BUG_ON(MC_CMD_GET_BOARD_CFG_IN_LEN != 0); @@ -688,10 +687,16 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, : MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST; if (mac_address) memcpy(mac_address, outbuf + offset, ETH_ALEN); - if (fw_subtype_list) - memcpy(fw_subtype_list, - outbuf + MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST, - MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN); + if (fw_subtype_list) { + offset = MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST; + for (i = 0; + i < MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN / 2; + i++) { + fw_subtype_list[i] = + le16_to_cpup((__le16 *)(outbuf + offset)); + offset += 2; + } + } return 0; -- cgit v1.1 From 442933f2b6a4c0e1d4a3b216c55c720a01c032be Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 23 May 2011 12:18:45 +0100 Subject: sfc: Fix two causes of flush failure [ Upstream commits a606f4325dca6950996abbae452d33f2af095f39, d5e8cc6c946e0857826dcfbb3585068858445bfe, 525d9e824018cd7cc8d8d44832ddcd363abfe6e1 ] The TX DMA engine issues upstream read requests when there is room in the TX FIFO for the completion. However, the fetches for the rest of the packet might be delayed by any back pressure. Since a flush must wait for an EOP, the entire flush may be delayed by back pressure. Mitigate this by disabling flow control before the flushes are started. Since PF and VF flushes run in parallel introduce fc_disable, a reference count of the number of flushes outstanding. The same principle could be applied to Falcon, but that would bring with it its own testing. We sometimes hit a "failed to flush" timeout on some TX queues, but the flushes have completed and the flush completion events seem to go missing. In this case, we can check the TX_DESC_PTR_TBL register and drain the queues if the flushes had finished. Signed-off-by: Ben Hutchings [bwh: Backported to 3.0: - Call efx_nic_type::finish_flush() on both success and failure paths - Check the TX_DESC_PTR_TBL registers in the polling loop - Declare efx_mcdi_set_mac() extern] Signed-off-by: Greg Kroah-Hartman --- drivers/net/sfc/falcon.c | 2 ++ drivers/net/sfc/mcdi.h | 1 + drivers/net/sfc/mcdi_mac.c | 4 +++- drivers/net/sfc/net_driver.h | 6 ++++++ drivers/net/sfc/nic.c | 21 ++++++++++++++++++--- drivers/net/sfc/nic.h | 2 ++ drivers/net/sfc/siena.c | 15 ++++++++++++++- 7 files changed, 46 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 60176e8..19b996b 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1714,6 +1714,7 @@ const struct efx_nic_type falcon_a1_nic_type = { .remove_port = falcon_remove_port, .handle_global_event = falcon_handle_global_event, .prepare_flush = falcon_prepare_flush, + .finish_flush = efx_port_dummy_op_void, .update_stats = falcon_update_nic_stats, .start_stats = falcon_start_nic_stats, .stop_stats = falcon_stop_nic_stats, @@ -1755,6 +1756,7 @@ const struct efx_nic_type falcon_b0_nic_type = { .remove_port = falcon_remove_port, .handle_global_event = falcon_handle_global_event, .prepare_flush = falcon_prepare_flush, + .finish_flush = efx_port_dummy_op_void, .update_stats = falcon_update_nic_stats, .start_stats = falcon_start_nic_stats, .stop_stats = falcon_stop_nic_stats, diff --git a/drivers/net/sfc/mcdi.h b/drivers/net/sfc/mcdi.h index aced2a7..b61eea0 100644 --- a/drivers/net/sfc/mcdi.h +++ b/drivers/net/sfc/mcdi.h @@ -126,5 +126,6 @@ extern int efx_mcdi_wol_filter_set_magic(struct efx_nic *efx, extern int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out); extern int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id); extern int efx_mcdi_wol_filter_reset(struct efx_nic *efx); +extern int efx_mcdi_set_mac(struct efx_nic *efx); #endif /* EFX_MCDI_H */ diff --git a/drivers/net/sfc/mcdi_mac.c b/drivers/net/sfc/mcdi_mac.c index 50c2077..da269d7 100644 --- a/drivers/net/sfc/mcdi_mac.c +++ b/drivers/net/sfc/mcdi_mac.c @@ -13,7 +13,7 @@ #include "mcdi.h" #include "mcdi_pcol.h" -static int efx_mcdi_set_mac(struct efx_nic *efx) +int efx_mcdi_set_mac(struct efx_nic *efx) { u32 reject, fcntl; u8 cmdbytes[MC_CMD_SET_MAC_IN_LEN]; @@ -45,6 +45,8 @@ static int efx_mcdi_set_mac(struct efx_nic *efx) } if (efx->wanted_fc & EFX_FC_AUTO) fcntl = MC_CMD_FCNTL_AUTO; + if (efx->fc_disable) + fcntl = MC_CMD_FCNTL_OFF; MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl); diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index e8d5f03..47aff8e 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -690,6 +690,9 @@ struct efx_filter_state; * @promiscuous: Promiscuous flag. Protected by netif_tx_lock. * @multicast_hash: Multicast hash table * @wanted_fc: Wanted flow control flags + * @fc_disable: When non-zero flow control is disabled. Typically used to + * ensure that network back pressure doesn't delay dma queue flushes. + * Serialised by the rtnl lock. * @mac_work: Work item for changing MAC promiscuity and multicast hash * @loopback_mode: Loopback status * @loopback_modes: Supported loopback mode bitmask @@ -783,6 +786,7 @@ struct efx_nic { bool promiscuous; union efx_multicast_hash multicast_hash; u8 wanted_fc; + unsigned fc_disable; atomic_t rx_reset; enum efx_loopback_mode loopback_mode; @@ -834,6 +838,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * @remove_port: Free resources allocated by probe_port() * @handle_global_event: Handle a "global" event (may be %NULL) * @prepare_flush: Prepare the hardware for flushing the DMA queues + * @finish_flush: Clean up after flushing the DMA queues * @update_stats: Update statistics not provided by event handling * @start_stats: Start the regular fetching of statistics * @stop_stats: Stop the regular fetching of statistics @@ -879,6 +884,7 @@ struct efx_nic_type { void (*remove_port)(struct efx_nic *efx); bool (*handle_global_event)(struct efx_channel *channel, efx_qword_t *); void (*prepare_flush)(struct efx_nic *efx); + void (*finish_flush)(struct efx_nic *efx); void (*update_stats)(struct efx_nic *efx); void (*start_stats)(struct efx_nic *efx); void (*stop_stats)(struct efx_nic *efx); diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 5ac9fa2..854df4e 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -1260,13 +1260,27 @@ int efx_nic_flush_queues(struct efx_nic *efx) } efx_for_each_possible_channel_tx_queue(tx_queue, channel) { if (tx_queue->initialised && - tx_queue->flushed != FLUSH_DONE) - ++tx_pending; + tx_queue->flushed != FLUSH_DONE) { + efx_oword_t txd_ptr_tbl; + + efx_reado_table(efx, &txd_ptr_tbl, + FR_BZ_TX_DESC_PTR_TBL, + tx_queue->queue); + if (EFX_OWORD_FIELD(txd_ptr_tbl, + FRF_AZ_TX_DESCQ_FLUSH) || + EFX_OWORD_FIELD(txd_ptr_tbl, + FRF_AZ_TX_DESCQ_EN)) + ++tx_pending; + else + tx_queue->flushed = FLUSH_DONE; + } } } - if (rx_pending == 0 && tx_pending == 0) + if (rx_pending == 0 && tx_pending == 0) { + efx->type->finish_flush(efx); return 0; + } msleep(EFX_FLUSH_INTERVAL); efx_poll_flush_events(efx); @@ -1292,6 +1306,7 @@ int efx_nic_flush_queues(struct efx_nic *efx) } } + efx->type->finish_flush(efx); return -ETIMEDOUT; } diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h index d2405ce..8a2c4f5 100644 --- a/drivers/net/sfc/nic.h +++ b/drivers/net/sfc/nic.h @@ -211,6 +211,8 @@ extern void falcon_irq_ack_a1(struct efx_nic *efx); /* Global Resources */ extern int efx_nic_flush_queues(struct efx_nic *efx); +extern void siena_prepare_flush(struct efx_nic *efx); +extern void siena_finish_flush(struct efx_nic *efx); extern void falcon_start_nic_stats(struct efx_nic *efx); extern void falcon_stop_nic_stats(struct efx_nic *efx); extern void falcon_setup_xaui(struct efx_nic *efx); diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 407f50b..062494a 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -135,6 +135,18 @@ static void siena_remove_port(struct efx_nic *efx) efx_nic_free_buffer(efx, &efx->stats_buffer); } +void siena_prepare_flush(struct efx_nic *efx) +{ + if (efx->fc_disable++ == 0) + efx_mcdi_set_mac(efx); +} + +void siena_finish_flush(struct efx_nic *efx) +{ + if (--efx->fc_disable == 0) + efx_mcdi_set_mac(efx); +} + static const struct efx_nic_register_test siena_register_tests[] = { { FR_AZ_ADR_REGION, EFX_OWORD32(0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF) }, @@ -590,7 +602,8 @@ const struct efx_nic_type siena_a0_nic_type = { .reset = siena_reset_hw, .probe_port = siena_probe_port, .remove_port = siena_remove_port, - .prepare_flush = efx_port_dummy_op_void, + .prepare_flush = siena_prepare_flush, + .finish_flush = siena_finish_flush, .update_stats = siena_update_nic_stats, .start_stats = siena_start_nic_stats, .stop_stats = siena_stop_nic_stats, -- cgit v1.1 From 376ed848f420a921325e9dc144c9cc7fa3829a38 Mon Sep 17 00:00:00 2001 From: Daniel Pieczko Date: Wed, 17 Oct 2012 13:21:23 +0100 Subject: sfc: lock TX queues when calling netif_device_detach() [ Upstream commit c2f3b8e3a44b6fe9e36704e30157ebe1a88c08b1 ] The assertion of netif_device_present() at the top of efx_hard_start_xmit() may fail if we don't do this. Signed-off-by: Ben Hutchings [bwh: Backported to 3.0: adjust context] Signed-off-by: Greg Kroah-Hartman --- drivers/net/sfc/efx.c | 4 ++-- drivers/net/sfc/efx.h | 13 +++++++++++++ drivers/net/sfc/selftest.c | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index f2bdc50..7157a33 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -2106,7 +2106,7 @@ int efx_reset(struct efx_nic *efx, enum reset_type method) netif_info(efx, drv, efx->net_dev, "resetting (%s)\n", RESET_TYPE(method)); - netif_device_detach(efx->net_dev); + efx_device_detach_sync(efx); efx_reset_down(efx, method); rc = efx->type->reset(efx, method); @@ -2565,7 +2565,7 @@ static int efx_pm_freeze(struct device *dev) efx->state = STATE_FINI; - netif_device_detach(efx->net_dev); + efx_device_detach_sync(efx); efx_stop_all(efx); efx_fini_channels(efx); diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index a5d1c60..dabde2c 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -150,4 +150,17 @@ extern void efx_link_status_changed(struct efx_nic *efx); extern void efx_link_set_advertising(struct efx_nic *efx, u32); extern void efx_link_set_wanted_fc(struct efx_nic *efx, u8); +static inline void efx_device_detach_sync(struct efx_nic *efx) +{ + struct net_device *dev = efx->net_dev; + + /* Lock/freeze all TX queues so that we can be sure the + * TX scheduler is stopped when we're done and before + * netif_device_present() becomes false. + */ + netif_tx_lock(dev); + netif_device_detach(dev); + netif_tx_unlock(dev); +} + #endif /* EFX_EFX_H */ diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index 822f6c2..4907885 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c @@ -698,7 +698,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests, /* Detach the device so the kernel doesn't transmit during the * loopback test and the watchdog timeout doesn't fire. */ - netif_device_detach(efx->net_dev); + efx_device_detach_sync(efx); mutex_lock(&efx->mac_lock); if (efx->loopback_modes) { -- cgit v1.1 From 16cec22e5099020edb0ba8b6ae8f1b011e2ec4d5 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 1 Dec 2012 02:21:17 +0000 Subject: sfc: Fix timekeeping in efx_mcdi_poll() [ Upstream commit ebf98e797b4e26ad52ace1511a0b503ee60a6cd4 ] efx_mcdi_poll() uses get_seconds() to read the current time and to implement a polling timeout. The use of this function was chosen partly because it could easily be replaced in a co-sim environment with a macro that read the simulated time. Unfortunately the real get_seconds() returns the system time (real time) which is subject to adjustment by e.g. ntpd. If the system time is adjusted forward during a polled MCDI operation, the effective timeout can be shorter than the intended 10 seconds, resulting in a spurious failure. It is also possible for a backward adjustment to delay detection of a areal failure. Use jiffies instead, and change MCDI_RPC_TIMEOUT to be denominated in jiffies. Also correct rounding of the timeout: check time > finish (or rather time_after(time, finish)) and not time >= finish. Signed-off-by: Ben Hutchings [bwh: Backported to 3.0: adjust context] Signed-off-by: Greg Kroah-Hartman --- drivers/net/sfc/mcdi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index 85e070e..c1000ce 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c @@ -30,7 +30,7 @@ #define REBOOT_FLAG_PORT0 0x3f8 #define REBOOT_FLAG_PORT1 0x3fc -#define MCDI_RPC_TIMEOUT 10 /*seconds */ +#define MCDI_RPC_TIMEOUT (10 * HZ) #define MCDI_PDU(efx) \ (efx_port_num(efx) ? CMD_PDU_PORT1 : CMD_PDU_PORT0) @@ -120,7 +120,7 @@ static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen) static int efx_mcdi_poll(struct efx_nic *efx) { struct efx_mcdi_iface *mcdi = efx_mcdi(efx); - unsigned int time, finish; + unsigned long time, finish; unsigned int respseq, respcmd, error; unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); unsigned int rc, spins; @@ -136,7 +136,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) * and poll once a jiffy (approximately) */ spins = TICK_USEC; - finish = get_seconds() + MCDI_RPC_TIMEOUT; + finish = jiffies + MCDI_RPC_TIMEOUT; while (1) { if (spins != 0) { @@ -146,7 +146,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) schedule_timeout_uninterruptible(1); } - time = get_seconds(); + time = jiffies; rmb(); efx_readd(efx, ®, pdu); @@ -158,7 +158,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) EFX_DWORD_FIELD(reg, MCDI_HEADER_RESPONSE)) break; - if (time >= finish) + if (time_after(time, finish)) return -ETIMEDOUT; } @@ -250,7 +250,7 @@ static int efx_mcdi_await_completion(struct efx_nic *efx) if (wait_event_timeout( mcdi->wq, atomic_read(&mcdi->state) == MCDI_STATE_COMPLETED, - msecs_to_jiffies(MCDI_RPC_TIMEOUT * 1000)) == 0) + MCDI_RPC_TIMEOUT) == 0) return -ETIMEDOUT; /* Check if efx_mcdi_set_mode() switched us back to polled completions. -- cgit v1.1 From bbd3cfb8cbb326f32f1daec0ea6ffbf855a7ecc8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 20 Dec 2012 18:48:20 +0000 Subject: sfc: Properly sync RX DMA buffer when it is not the last in the page [ Upstream commit 3a68f19d7afb80f548d016effbc6ed52643a8085 ] We may currently allocate two RX DMA buffers to a page, and only unmap the page when the second is completed. We do not sync the first RX buffer to be completed; this can result in packet loss or corruption if the last RX buffer completed in a NAPI poll is the first in a page and is not DMA-coherent. (In the middle of a NAPI poll, we will handle the following RX completion and unmap the page *before* looking at the content of the first buffer.) Signed-off-by: Ben Hutchings [bwh: Backported to 3.0: adjust context] Signed-off-by: Greg Kroah-Hartman --- drivers/net/sfc/rx.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 4004fc2..ce6f53f 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -245,7 +245,8 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) } static void efx_unmap_rx_buffer(struct efx_nic *efx, - struct efx_rx_buffer *rx_buf) + struct efx_rx_buffer *rx_buf, + unsigned int used_len) { if (rx_buf->is_page && rx_buf->u.page) { struct efx_rx_page_state *state; @@ -256,6 +257,10 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx, state->dma_addr, efx_rx_buf_size(efx), PCI_DMA_FROMDEVICE); + } else if (used_len) { + dma_sync_single_for_cpu(&efx->pci_dev->dev, + rx_buf->dma_addr, used_len, + DMA_FROM_DEVICE); } } else if (!rx_buf->is_page && rx_buf->u.skb) { pci_unmap_single(efx->pci_dev, rx_buf->dma_addr, @@ -278,7 +283,7 @@ static void efx_free_rx_buffer(struct efx_nic *efx, static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue, struct efx_rx_buffer *rx_buf) { - efx_unmap_rx_buffer(rx_queue->efx, rx_buf); + efx_unmap_rx_buffer(rx_queue->efx, rx_buf, 0); efx_free_rx_buffer(rx_queue->efx, rx_buf); } @@ -549,10 +554,10 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, goto out; } - /* Release card resources - assumes all RX buffers consumed in-order - * per RX queue + /* Release and/or sync DMA mapping - assumes all RX buffers + * consumed in-order per RX queue */ - efx_unmap_rx_buffer(efx, rx_buf); + efx_unmap_rx_buffer(efx, rx_buf, len); /* Prefetch nice and early so data will (hopefully) be in cache by * the time we look at it. -- cgit v1.1 From 67d8c1035e0c960a3d41abe532ea868bb3985f22 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 10 Jan 2013 23:51:54 +0000 Subject: sfc: Fix efx_rx_buf_offset() in the presence of swiotlb [ Upstream commits 06e63c57acbb1df7c35ebe846ae416a8b88dfafa, b590ace09d51cd39744e0f7662c5e4a0d1b5d952 and c73e787a8db9117d59b5180baf83203a42ecadca ] We assume that the mapping between DMA and virtual addresses is done on whole pages, so we can find the page offset of an RX buffer using the lower bits of the DMA address. However, swiotlb maps in units of 2K, breaking this assumption. Add an explicit page_offset field to struct efx_rx_buffer. Signed-off-by: Ben Hutchings [bwh: Backported to 3.0: adjust context] Signed-off-by: Greg Kroah-Hartman --- drivers/net/sfc/net_driver.h | 4 +++- drivers/net/sfc/rx.c | 10 +++++----- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 47aff8e..2f932c5 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -214,6 +214,7 @@ struct efx_tx_queue { * If both this and page are %NULL, the buffer slot is currently free. * @page: The associated page buffer, if any. * If both this and skb are %NULL, the buffer slot is currently free. + * @page_offset: Offset within page. Valid iff @flags & %EFX_RX_BUF_PAGE. * @len: Buffer length, in bytes. * @is_page: Indicates if @page is valid. If false, @skb is valid. */ @@ -223,7 +224,8 @@ struct efx_rx_buffer { struct sk_buff *skb; struct page *page; } u; - unsigned int len; + u16 page_offset; + u16 len; bool is_page; }; diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index ce6f53f..d429f0a 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -94,11 +94,7 @@ static unsigned int rx_refill_limit = 95; static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx, struct efx_rx_buffer *buf) { - /* Offset is always within one page, so we don't need to consider - * the page order. - */ - return (((__force unsigned long) buf->dma_addr & (PAGE_SIZE - 1)) + - efx->type->rx_buffer_hash_size); + return buf->page_offset + efx->type->rx_buffer_hash_size; } static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) { @@ -193,6 +189,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) struct efx_rx_buffer *rx_buf; struct page *page; void *page_addr; + unsigned int page_offset; struct efx_rx_page_state *state; dma_addr_t dma_addr; unsigned index, count; @@ -219,12 +216,14 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) page_addr += sizeof(struct efx_rx_page_state); dma_addr += sizeof(struct efx_rx_page_state); + page_offset = sizeof(struct efx_rx_page_state); split: index = rx_queue->added_count & rx_queue->ptr_mask; rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; rx_buf->u.page = page; + rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN; rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN; rx_buf->is_page = true; ++rx_queue->added_count; @@ -236,6 +235,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) get_page(page); dma_addr += (PAGE_SIZE >> 1); page_addr += (PAGE_SIZE >> 1); + page_offset += (PAGE_SIZE >> 1); ++count; goto split; } -- cgit v1.1 From c62fe657e9c08b273aac0c3a0556ccdce9ede49a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 28 Jan 2013 19:01:06 +0000 Subject: sfc: Detach net device when stopping queues for reconfiguration [ Upstream commit 29c69a4882641285a854d6d03ca5adbba68c0034 ] We must only ever stop TX queues when they are full or the net device is not 'ready' so far as the net core, and specifically the watchdog, is concerned. Otherwise, the watchdog may fire *immediately* if no packets have been added to the queue in the last 5 seconds. The device is ready if all the following are true: (a) It has a qdisc (b) It is marked present (c) It is running (d) The link is reported up (a) and (c) are normally true, and must not be changed by a driver. (d) is under our control, but fake link changes may disturb userland. This leaves (b). We already mark the device absent during reset and self-test, but we need to do the same during MTU changes and ring reallocation. We don't need to do this when the device is brought down because then (c) is already false. Signed-off-by: Ben Hutchings [bwh: Backported to 3.0: adjust context] Signed-off-by: Greg Kroah-Hartman --- drivers/net/sfc/efx.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 7157a33..07e526d 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -720,6 +720,7 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries) unsigned i; int rc; + efx_device_detach_sync(efx); efx_stop_all(efx); efx_fini_channels(efx); @@ -763,6 +764,7 @@ out: efx_init_channels(efx); efx_start_all(efx); + netif_device_attach(efx->net_dev); return rc; rollback: @@ -1530,8 +1532,12 @@ static void efx_stop_all(struct efx_nic *efx) /* Flush efx_mac_work(), refill_workqueue, monitor_work */ efx_flush_all(efx); - /* Stop the kernel transmit interface late, so the watchdog - * timer isn't ticking over the flush */ + /* Stop the kernel transmit interface. This is only valid if + * the device is stopped or detached; otherwise the watchdog + * may fire immediately. + */ + WARN_ON(netif_running(efx->net_dev) && + netif_device_present(efx->net_dev)); if (efx_dev_registered(efx)) { netif_tx_stop_all_queues(efx->net_dev); netif_tx_lock_bh(efx->net_dev); @@ -1801,10 +1807,11 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu) if (new_mtu > EFX_MAX_MTU) return -EINVAL; - efx_stop_all(efx); - netif_dbg(efx, drv, efx->net_dev, "changing MTU to %d\n", new_mtu); + efx_device_detach_sync(efx); + efx_stop_all(efx); + efx_fini_channels(efx); mutex_lock(&efx->mac_lock); @@ -1817,6 +1824,7 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu) efx_init_channels(efx); efx_start_all(efx); + netif_device_attach(efx->net_dev); return rc; } -- cgit v1.1 From ad0c4a9fa31036fefb30385edfbd1feb8971de97 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 5 Mar 2013 01:03:47 +0000 Subject: sfc: Disable soft interrupt handling during efx_device_detach_sync() [ Upstream commit 35205b211c8d17a8a0b5e8926cb7c73e9a7ef1ad ] efx_device_detach_sync() locks all TX queues before marking the device detached and thus disabling further TX scheduling. But it can still be interrupted by TX completions which then result in TX scheduling in soft interrupt context. This will deadlock when it tries to acquire a TX queue lock that efx_device_detach_sync() already acquired. To avoid deadlock, we must use netif_tx_{,un}lock_bh(). Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/net/sfc/efx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index dabde2c..76e891e 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -158,9 +158,9 @@ static inline void efx_device_detach_sync(struct efx_nic *efx) * TX scheduler is stopped when we're done and before * netif_device_present() becomes false. */ - netif_tx_lock(dev); + netif_tx_lock_bh(dev); netif_device_detach(dev); - netif_tx_unlock(dev); + netif_tx_unlock_bh(dev); } #endif /* EFX_EFX_H */ -- cgit v1.1 From 9bb104c28a389c39812b15b39672aa87b91bcd79 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 27 Feb 2013 16:50:38 +0000 Subject: sfc: Only use TX push if a single descriptor is to be written [ Upstream commit fae8563b25f73dc584a07bcda7a82750ff4f7672 ] Using TX push when notifying the NIC of multiple new descriptors in the ring will very occasionally cause the TX DMA engine to re-use an old descriptor. This can result in a duplicated or partly duplicated packet (new headers with old data), or an IOMMU page fault. This does not happen when the pushed descriptor is the only one written. TX push also provides little latency benefit when a packet requires more than one descriptor. Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/net/sfc/nic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 854df4e..4949004 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -370,7 +370,8 @@ efx_may_push_tx_desc(struct efx_tx_queue *tx_queue, unsigned int write_count) return false; tx_queue->empty_read_count = 0; - return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0; + return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0 + && tx_queue->write_count - write_count == 1; } /* For each entry inserted into the software descriptor ring, create a -- cgit v1.1 From 7ace9c4c6c590531e0cf4a61925ec2dd5947f81c Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 11 Mar 2013 12:25:19 -0700 Subject: drm/i915: restrict kernel address leak in debugfs commit 2563a4524febe8f4a98e717e02436d1aaf672aa2 upstream. Masks kernel address info-leak in object dumps with the %pK suffix, so they cannot be used to target kernel memory corruption attacks if the kptr_restrict sysctl is set. Signed-off-by: Kees Cook Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index e36efdc..19bab81 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -119,7 +119,7 @@ static const char *cache_level_str(int type) static void describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) { - seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s%s", + seq_printf(m, "%pK: %s%s %8zd %04x %04x %d %d%s%s%s", &obj->base, get_pin_flag(obj), get_tiling_flag(obj), -- cgit v1.1 From 23e90aa103cabff3b5d48faad3e8deefa43e38b6 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Thu, 7 Mar 2013 20:00:16 -0800 Subject: mwifiex: fix potential out-of-boundary access to ibss rate table commit 5f0fabf84d7b52f979dcbafa3d3c530c60d9a92c upstream. smatch found this error: CHECK drivers/net/wireless/mwifiex/join.c drivers/net/wireless/mwifiex/join.c:1121 mwifiex_cmd_802_11_ad_hoc_join() error: testing array offset 'i' after use. Signed-off-by: Bing Zhao Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/mwifiex/join.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 5eab3dc..890841a 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -1102,10 +1102,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, adhoc_join->bss_descriptor.bssid, adhoc_join->bss_descriptor.ssid); - for (i = 0; bss_desc->supported_rates[i] && - i < MWIFIEX_SUPPORTED_RATES; - i++) - ; + for (i = 0; i < MWIFIEX_SUPPORTED_RATES && + bss_desc->supported_rates[i]; i++) + ; rates_size = i; /* Copy Data Rates from the Rates recorded in scan response */ -- cgit v1.1 From 28513ead437be0ab26124c430411c1358b69e71d Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 11 Mar 2013 17:31:45 -0700 Subject: drm/i915: bounds check execbuffer relocation count commit 3118a4f652c7b12c752f3222af0447008f9b2368 upstream. It is possible to wrap the counter used to allocate the buffer for relocation copies. This could lead to heap writing overflows. CVE-2013-0913 v3: collapse test, improve comment v2: move check into validate_exec_list Signed-off-by: Kees Cook Reported-by: Pinkie Pie Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 490ab6b..1ca53ff 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -888,15 +888,20 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, int count) { int i; + int relocs_total = 0; + int relocs_max = INT_MAX / sizeof(struct drm_i915_gem_relocation_entry); for (i = 0; i < count; i++) { char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr; int length; /* limited by fault_in_pages_readable() */ - /* First check for malicious input causing overflow */ - if (exec[i].relocation_count > - INT_MAX / sizeof(struct drm_i915_gem_relocation_entry)) + /* First check for malicious input causing overflow in + * the worst case where we need to allocate the entire + * relocation tree as a single array. + */ + if (exec[i].relocation_count > relocs_max - relocs_total) return -EINVAL; + relocs_total += exec[i].relocation_count; length = exec[i].relocation_count * sizeof(struct drm_i915_gem_relocation_entry); -- cgit v1.1 From b599876605b32b7b692b095df613af8d27240a1f Mon Sep 17 00:00:00 2001 From: Torsten Duwe Date: Sat, 23 Mar 2013 15:38:22 +0100 Subject: KMS: fix EDID detailed timing vsync parsing commit 16dad1d743d31a104a849c8944e6b9eb479f6cd7 upstream. EDID spreads some values across multiple bytes; bit-fiddling is needed to retrieve these. The current code to parse "detailed timings" has a cut&paste error that results in a vsync offset of at most 15 lines instead of 63. See http://en.wikipedia.org/wiki/EDID and in the "EDID Detailed Timing Descriptor" see bytes 10+11 show why that needs to be a left shift. Signed-off-by: Torsten Duwe Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_edid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index a303b61..b4d7898 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -841,7 +841,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo; unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo; unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo; - unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; + unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 2 | pt->vsync_offset_pulse_width_lo >> 4; unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf); /* ignore tiny modes */ -- cgit v1.1 From b5b9400569dec274ff74b3182e1f86c1e5b50ce4 Mon Sep 17 00:00:00 2001 From: Dmitry Artamonow Date: Sat, 9 Mar 2013 20:30:58 +0400 Subject: usb-storage: add unusual_devs entry for Samsung YP-Z3 mp3 player commit 29f86e66428ee083aec106cca1748dc63d98ce23 upstream. Device stucks on filesystem writes, unless following quirk is passed: echo 04e8:5136:m > /sys/module/usb_storage/parameters/quirks Add corresponding entry to unusual_devs.h Signed-off-by: Dmitry Artamonow Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index fa8a1b2..7b8d564 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -488,6 +488,13 @@ UNUSUAL_DEV( 0x04e8, 0x5122, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_MAX_SECTORS_64 | US_FL_BULK_IGNORE_TAG), +/* Added by Dmitry Artamonow */ +UNUSUAL_DEV( 0x04e8, 0x5136, 0x0000, 0x9999, + "Samsung", + "YP-Z3", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64), + /* Entry and supporting patch by Theodore Kilgore . * Device uses standards-violating 32-byte Bulk Command Block Wrappers and * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011. -- cgit v1.1 From 52bc8dc1e1023ad0a91b3c80d048688d4167b7e5 Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Tue, 26 Feb 2013 15:46:27 +0000 Subject: IPoIB: Fix send lockup due to missed TX completion commit 1ee9e2aa7b31427303466776f455d43e5e3c9275 upstream. Commit f0dc117abdfa ("IPoIB: Fix TX queue lockup with mixed UD/CM traffic") attempts to solve an issue where unprocessed UD send completions can deadlock the netdev. The patch doesn't fully resolve the issue because if more than half the tx_outstanding's were UD and all of the destinations are RC reachable, arming the CQ doesn't solve the issue. This patch uses the IB_CQ_REPORT_MISSED_EVENTS on the ib_req_notify_cq(). If the rc is above 0, the UD send cq completion callback is called directly to re-arm the send completion timer. This issue is seen in very large parallel filesystem deployments and the patch has been shown to correct the issue. Reviewed-by: Dean Luick Signed-off-by: Mike Marciniszyn Signed-off-by: Roland Dreier Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/ulp/ipoib/ipoib_cm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 39913a0..073acdf 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -753,9 +753,13 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_ if (++priv->tx_outstanding == ipoib_sendq_size) { ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n", tx->qp->qp_num); - if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP)) - ipoib_warn(priv, "request notify on send CQ failed\n"); netif_stop_queue(dev); + rc = ib_req_notify_cq(priv->send_cq, + IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS); + if (rc < 0) + ipoib_warn(priv, "request notify on send CQ failed\n"); + else if (rc) + ipoib_send_comp_handler(priv->send_cq, dev); } } } -- cgit v1.1 From 1f9e70fa1d260bb1ed217bd636cad0c1d0a29f24 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 25 Feb 2013 10:56:01 -0800 Subject: USB: xhci - fix bit definitions for IMAN register commit f8264340e694604863255cc0276491d17c402390 upstream. According to XHCI specification (5.5.2.1) the IP is bit 0 and IE is bit 1 of IMAN register. Previously their definitions were reversed. Even though there are no ill effects being observed from the swapped definitions (because IMAN_IP is RW1C and in legacy PCI case we come in with it already set to 1 so it was clearing itself even though we were setting IMAN_IE instead of IMAN_IP), we should still correct the values. This patch should be backported to kernels as old as 2.6.36, that contain the commit 4e833c0b87a30798e67f06120cecebef6ee9644c "xhci: don't re-enable IE constantly". Signed-off-by: Dmitry Torokhov Signed-off-by: Sarah Sharp Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 1d72895..8b94412 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -206,8 +206,8 @@ struct xhci_op_regs { /* bits 12:31 are reserved (and should be preserved on writes). */ /* IMAN - Interrupt Management Register */ -#define IMAN_IP (1 << 1) -#define IMAN_IE (1 << 0) +#define IMAN_IE (1 << 1) +#define IMAN_IP (1 << 0) /* USBSTS - USB status - status bitmasks */ /* HC not running - set to 1 when run/stop bit is cleared. */ -- cgit v1.1 From 28a4b1b70dd44e8e4ab9df6e84e776911902313e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 19 Mar 2013 09:21:09 +0100 Subject: USB: serial: fix interface refcounting commit d7971051e4df825e0bc11b995e87bfe86355b8e5 upstream. Make sure the interface is not released before our serial device. Note that drivers are still not allowed to access the interface in any way that may interfere with another driver that may have gotten bound to the same interface after disconnect returns. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 637dfa4..f678532 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -168,6 +168,7 @@ static void destroy_serial(struct kref *kref) } } + usb_put_intf(serial->interface); usb_put_dev(serial->dev); kfree(serial); } @@ -624,7 +625,7 @@ static struct usb_serial *create_serial(struct usb_device *dev, } serial->dev = usb_get_dev(dev); serial->type = driver; - serial->interface = interface; + serial->interface = usb_get_intf(interface); kref_init(&serial->kref); mutex_init(&serial->disc_mutex); serial->minor = SERIAL_TTY_NO_MINOR; -- cgit v1.1 From 2f4e0bbf44d7469d6de03155cdf25e3928a93707 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 19 Mar 2013 09:21:07 +0100 Subject: USB: garmin_gps: fix memory leak on disconnect commit 618aa1068df29c37a58045fe940f9106664153fd upstream. Remove bogus disconnect test introduced by 95bef012e ("USB: more serial drivers writing after disconnect") which prevented queued data from being freed on disconnect. The possible IO it was supposed to prevent is long gone. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/garmin_gps.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index b0a7a9e..51b22c3 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -973,10 +973,7 @@ static void garmin_close(struct usb_serial_port *port) if (!serial) return; - mutex_lock(&port->serial->disc_mutex); - - if (!port->serial->disconnected) - garmin_clear(garmin_data_p); + garmin_clear(garmin_data_p); /* shutdown our urbs */ usb_kill_urb(port->read_urb); @@ -985,8 +982,6 @@ static void garmin_close(struct usb_serial_port *port) /* keep reset state so we know that we must start a new session */ if (garmin_data_p->state != STATE_RESET) garmin_data_p->state = STATE_DISCONNECTED; - - mutex_unlock(&port->serial->disc_mutex); } -- cgit v1.1 From d79c29b44524bd1ea8c4ab71a13f33fced3bb17a Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 19 Mar 2013 09:21:08 +0100 Subject: USB: io_ti: fix get_icount for two port adapters commit 5492bf3d5655b4954164f69c02955a7fca267611 upstream. Add missing get_icount field to two-port driver. The two-port driver was not updated when switching to the new icount interface in commit 0bca1b913aff ("tty: Convert the USB drivers to the new icount interface"). Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/io_ti.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 8a90d58..bdb44fc 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2793,6 +2793,7 @@ static struct usb_serial_driver edgeport_2port_device = { .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, .tiocmset = edge_tiocmset, + .get_icount = edge_get_icount, .write = edge_write, .write_room = edge_write_room, .chars_in_buffer = edge_chars_in_buffer, -- cgit v1.1 From 7396043fa475256bb61f1c9f901cfd3ed550a3cd Mon Sep 17 00:00:00 2001 From: Lekensteyn Date: Tue, 26 Jun 2012 00:36:24 +0200 Subject: i915: initialize CADL in opregion commit d627b62ff8d4d36761adbcd90ff143d79c94ab22 upstream. This is rather a hack to fix brightness hotkeys on a Clevo laptop. CADL is not used anywhere in the driver code at the moment, but it could be used in BIOS as is the case with the Clevo laptop. The Clevo B7130 requires the CADL field to contain at least the ID of the LCD device. If this field is empty, the ACPI methods that are called on pressing brightness / display switching hotkeys will not trigger a notification. As a result, it appears as no hotkey has been pressed. Reference: https://bugs.freedesktop.org/show_bug.cgi?id=45452 Tested-by: Peter Wu Signed-off-by: Peter Wu Acked-by: Jesse Barnes Signed-off-by: Daniel Vetter Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_opregion.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index d2c7104..e7a97b5 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -413,6 +413,25 @@ blind_set: goto end; } +static void intel_setup_cadls(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_opregion *opregion = &dev_priv->opregion; + int i = 0; + u32 disp_id; + + /* Initialize the CADL field by duplicating the DIDL values. + * Technically, this is not always correct as display outputs may exist, + * but not active. This initialization is necessary for some Clevo + * laptops that check this field before processing the brightness and + * display switching hotkeys. Just like DIDL, CADL is NULL-terminated if + * there are less than eight devices. */ + do { + disp_id = ioread32(&opregion->acpi->didl[i]); + iowrite32(disp_id, &opregion->acpi->cadl[i]); + } while (++i < 8 && disp_id != 0); +} + void intel_opregion_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -422,8 +441,10 @@ void intel_opregion_init(struct drm_device *dev) return; if (opregion->acpi) { - if (drm_core_check_feature(dev, DRIVER_MODESET)) + if (drm_core_check_feature(dev, DRIVER_MODESET)) { intel_didl_outputs(dev); + intel_setup_cadls(dev); + } /* Notify BIOS we are ready to handle ACPI video ext notifs. * Right now, all the events are handled by the ACPI video module. -- cgit v1.1 From 9fbbadf339d8d97a2aa16c25346278ef64cbcfc1 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 26 Feb 2013 16:09:55 +0100 Subject: rt2x00: error in configurations with mesh support disabled commit 6ef9e2f6d12ce9e2120916804d2ddd46b954a70b upstream. If CONFIG_MAC80211_MESH is not set, cfg80211 will now allow advertising interface combinations with NL80211_IFTYPE_MESH_POINT present. Add appropriate ifdefs to avoid running into errors. [Backported for 3.8-stable. Removed code of simultaneous AP and mesh mode added in 4a5fc6d 3.9-rc1.] Signed-off-by: Felix Fietkau Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville Signed-off-by: Lingzhu Xiang Reviewed-by: CAI Qian Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/rt2x00/rt2x00dev.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 5bd2c55..031aa2b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1113,7 +1113,9 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) rt2x00dev->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) | +#ifdef CONFIG_MAC80211_MESH BIT(NL80211_IFTYPE_MESH_POINT) | +#endif BIT(NL80211_IFTYPE_WDS); /* -- cgit v1.1 From f2c1a6c85f3cf6be6cf0ddf38fc8a0a5b05498fb Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 29 Nov 2012 09:12:37 +0100 Subject: asus-laptop: Do not call HWRS on init commit cb7da022450cdaaebd33078b6b32fb7dd2aaf6db upstream. Since commit 8871e99f89b7 ('asus-laptop: HRWS/HWRS typo'), module initialisation is very slow on the Asus UL30A. The HWRS method takes about 12 seconds to run, and subsequent initialisation also seems to be delayed. Since we don't really need the result, don't bother calling it on init. Those who are curious can still get the result through the 'infos' device attribute. Update the comment about HWRS in show_infos(). Reported-by: ryan References: http://bugs.debian.org/692436 Signed-off-by: Ben Hutchings Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/asus-laptop.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 26f7f01..f0bf9c2 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -643,8 +643,10 @@ static ssize_t show_infos(struct device *dev, /* * The HWRS method return informations about the hardware. * 0x80 bit is for WLAN, 0x100 for Bluetooth. + * 0x40 for WWAN, 0x10 for WIMAX. * The significance of others is yet to be found. - * If we don't find the method, we assume the device are present. + * We don't currently use this for device detection, and it + * takes several seconds to run on some systems. */ rv = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &temp); if (!ACPI_FAILURE(rv)) @@ -1271,7 +1273,7 @@ static int asus_laptop_get_info(struct asus_laptop *asus) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *model = NULL; - unsigned long long bsts_result, hwrs_result; + unsigned long long bsts_result; char *string = NULL; acpi_status status; @@ -1333,17 +1335,6 @@ static int asus_laptop_get_info(struct asus_laptop *asus) if (*string) pr_notice(" %s model detected\n", string); - /* - * The HWRS method return informations about the hardware. - * 0x80 bit is for WLAN, 0x100 for Bluetooth, - * 0x40 for WWAN, 0x10 for WIMAX. - * The significance of others is yet to be found. - */ - status = - acpi_evaluate_integer(asus->handle, "HWRS", NULL, &hwrs_result); - if (!ACPI_FAILURE(status)) - pr_notice(" HWRS returned %x", (int)hwrs_result); - if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) asus->have_rsts = true; -- cgit v1.1 From 54f0a27d68535e728a0d7780cc809d97895ce3f9 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 15 Mar 2013 11:00:39 +0800 Subject: Bluetooth: Add support for Dell[QCA 0cf3:0036] commit d66629c1325399cf080ba8b2fb086c10e5439cdd upstream. Add support for the AR9462 chip T: Bus=03 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0cf3 ProdID=0036 Rev= 0.02 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA A: FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=01 I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms Signed-off-by: Ming Lei Cc: Gustavo Padovan Signed-off-by: Gustavo Padovan Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 85e1ad6..1628d85 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -71,6 +71,7 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x03F0, 0x311D) }, /* Atheros AR3012 with sflash firmware*/ + { USB_DEVICE(0x0CF3, 0x0036) }, { USB_DEVICE(0x0CF3, 0x3004) }, { USB_DEVICE(0x0CF3, 0x311D) }, { USB_DEVICE(0x13d3, 0x3375) }, @@ -93,6 +94,7 @@ MODULE_DEVICE_TABLE(usb, ath3k_table); static struct usb_device_id ath3k_blist_tbl[] = { /* Atheros AR3012 with sflash firmware*/ + { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 4b764f8..867c049 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -136,6 +136,7 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, /* Atheros 3012 with sflash firmware */ + { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, -- cgit v1.1 From 9a0f79c84c9966f19cb44e1c37344faf30ed5e22 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Mon, 18 Mar 2013 23:45:11 +0800 Subject: Bluetooth: Add support for Dell[QCA 0cf3:817a] commit ebaf5795ef57a70a042ea259448a465024e2821d upstream. Add support for the AR9462 chip T: Bus=03 Lev=01 Prnt=01 Port=08 Cnt=01 Dev#= 5 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0cf3 ProdID=817a Rev= 0.02 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms Signed-off-by: Ming Lei Cc: Gustavo Padovan Signed-off-by: Gustavo Padovan Signed-off-by: Greg Kroah-Hartman --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 1628d85..e866ed9 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -74,6 +74,7 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x0CF3, 0x0036) }, { USB_DEVICE(0x0CF3, 0x3004) }, { USB_DEVICE(0x0CF3, 0x311D) }, + { USB_DEVICE(0x0CF3, 0x817a) }, { USB_DEVICE(0x13d3, 0x3375) }, { USB_DEVICE(0x04CA, 0x3005) }, @@ -97,6 +98,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 867c049..a77e0d1 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -139,6 +139,7 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, -- cgit v1.1 From 3d8c163a2ecea7dd6c2c9efd68b6348ef0248733 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Fri, 22 Mar 2013 15:16:29 +0000 Subject: staging: comedi: s626: fix continuous acquisition commit e4317ce877a31dbb9d96375391c1c4ad2210d637 upstream. For the s626 driver, there is a bug in the handling of asynchronous commands on the AI subdevice when the stop source is `TRIG_NONE`. The command should run continuously until cancelled, but the interrupt handler stops the command running after the first scan. The command set-up function `s626_ai_cmd()` contains this code: switch (cmd->stop_src) { case TRIG_COUNT: /* data arrives as one packet */ devpriv->ai_sample_count = cmd->stop_arg; devpriv->ai_continous = 0; break; case TRIG_NONE: /* continous acquisition */ devpriv->ai_continous = 1; devpriv->ai_sample_count = 0; break; } The interrupt handler `s626_irq_handler()` contains this code: if (!(devpriv->ai_continous)) devpriv->ai_sample_count--; if (devpriv->ai_sample_count <= 0) { devpriv->ai_cmd_running = 0; /* ... */ } So `devpriv->ai_sample_count` is only decremented for the `TRIG_COUNT` case, but `devpriv->ai_cmd_running` is set to 0 (and the command stopped) regardless. Fix this in `s626_ai_cmd()` by setting `devpriv->ai_sample_count = 1` for the `TRIG_NONE` case. The interrupt handler will not decrement it so it will remain greater than 0 and the check for stopping the acquisition will fail. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s626.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index c72128f..42cad5c 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -1882,7 +1882,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) case TRIG_NONE: /* continous acquisition */ devpriv->ai_continous = 1; - devpriv->ai_sample_count = 0; + devpriv->ai_sample_count = 1; break; } -- cgit v1.1 From 1c9c0901afba44cf1353505b72e146e7f87a54b6 Mon Sep 17 00:00:00 2001 From: "Iestyn C. Elfick" Date: Wed, 20 Mar 2013 14:02:31 -0500 Subject: b43: A fix for DMA transmission sequence errors commit b251412db99ccd4495ce372fec7daee27bf06923 upstream. Intermittently, b43 will report "Out of order TX status report on DMA ring". When this happens, the driver must be reset before communication can resume. The cause of the problem is believed to be an error in the closed-source firmware; however, all versions of the firmware are affected. This change uses the observation that the expected status is always 2 less than the observed value, and supplies a fake status report to skip one header/data pair. Not all devices suffer from this problem, but it can occur several times per second under heavy load. As each occurence kills the unmodified driver, this patch makes if possible for the affected devices to function. The patch logs only the first instance of the reset operation to prevent spamming the logs. Tested-by: Chris Vine Signed-off-by: Larry Finger Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/b43/dma.c | 65 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 47d44bc..5deeb14 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -1390,8 +1390,12 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, struct b43_dmaring *ring; struct b43_dmadesc_generic *desc; struct b43_dmadesc_meta *meta; + static const struct b43_txstatus fake; /* filled with 0 */ + const struct b43_txstatus *txstat; int slot, firstused; bool frame_succeed; + int skip; + static u8 err_out1, err_out2; ring = parse_cookie(dev, status->cookie, &slot); if (unlikely(!ring)) @@ -1404,13 +1408,36 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, firstused = ring->current_slot - ring->used_slots + 1; if (firstused < 0) firstused = ring->nr_slots + firstused; + + skip = 0; if (unlikely(slot != firstused)) { /* This possibly is a firmware bug and will result in - * malfunction, memory leaks and/or stall of DMA functionality. */ - b43dbg(dev->wl, "Out of order TX status report on DMA ring %d. " - "Expected %d, but got %d\n", - ring->index, firstused, slot); - return; + * malfunction, memory leaks and/or stall of DMA functionality. + */ + if (slot == next_slot(ring, next_slot(ring, firstused))) { + /* If a single header/data pair was missed, skip over + * the first two slots in an attempt to recover. + */ + slot = firstused; + skip = 2; + if (!err_out1) { + /* Report the error once. */ + b43dbg(dev->wl, + "Skip on DMA ring %d slot %d.\n", + ring->index, slot); + err_out1 = 1; + } + } else { + /* More than a single header/data pair were missed. + * Report this error once. + */ + if (!err_out2) + b43dbg(dev->wl, + "Out of order TX status report on DMA ring %d. Expected %d, but got %d\n", + ring->index, firstused, slot); + err_out2 = 1; + return; + } } ops = ring->ops; @@ -1424,11 +1451,13 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, slot, firstused, ring->index); break; } + if (meta->skb) { struct b43_private_tx_info *priv_info = - b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb)); + b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb)); - unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1); + unmap_descbuffer(ring, meta->dmaaddr, + meta->skb->len, 1); kfree(priv_info->bouncebuffer); priv_info->bouncebuffer = NULL; } else { @@ -1440,8 +1469,9 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, struct ieee80211_tx_info *info; if (unlikely(!meta->skb)) { - /* This is a scatter-gather fragment of a frame, so - * the skb pointer must not be NULL. */ + /* This is a scatter-gather fragment of a frame, + * so the skb pointer must not be NULL. + */ b43dbg(dev->wl, "TX status unexpected NULL skb " "at slot %d (first=%d) on ring %d\n", slot, firstused, ring->index); @@ -1452,9 +1482,18 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, /* * Call back to inform the ieee80211 subsystem about - * the status of the transmission. + * the status of the transmission. When skipping over + * a missed TX status report, use a status structure + * filled with zeros to indicate that the frame was not + * sent (frame_count 0) and not acknowledged */ - frame_succeed = b43_fill_txstatus_report(dev, info, status); + if (unlikely(skip)) + txstat = &fake; + else + txstat = status; + + frame_succeed = b43_fill_txstatus_report(dev, info, + txstat); #ifdef CONFIG_B43_DEBUG if (frame_succeed) ring->nr_succeed_tx_packets++; @@ -1482,12 +1521,14 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, /* Everything unmapped and free'd. So it's not used anymore. */ ring->used_slots--; - if (meta->is_last_fragment) { + if (meta->is_last_fragment && !skip) { /* This is the last scatter-gather * fragment of the frame. We are done. */ break; } slot = next_slot(ring, slot); + if (skip > 0) + --skip; } if (ring->stopped) { B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME); -- cgit v1.1 From 460c49749ae56b5f49454ad0ce0066f80a14c385 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 11 Mar 2013 09:39:55 +0000 Subject: xen-blkback: fix dispatch_rw_block_io() error path commit 0e5e098ac22dae38f957e951b70d3cf73beff0f7 upstream. Commit 7708992 ("xen/blkback: Seperate the bio allocation and the bio submission") consolidated the pendcnt updates to just a single write, neglecting the fact that the error path relied on it getting set to 1 up front (such that the decrement in __end_block_io_op() would actually drop the count to zero, triggering the necessary cleanup actions). Also remove a misleading and a stale (after said commit) comment. Signed-off-by: Jan Beulich Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/block/xen-blkback/blkback.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 54139d0..92bdc40 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -650,13 +650,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, bio->bi_end_io = end_block_io_op; } - /* - * We set it one so that the last submit_bio does not have to call - * atomic_inc. - */ atomic_set(&pending_req->pendcnt, nbio); - - /* Get a reference count for the disk queue and start sending I/O */ blk_start_plug(&plug); for (i = 0; i < nbio; i++) @@ -684,6 +678,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, fail_put_bio: for (i = 0; i < nbio; i++) bio_put(biolist[i]); + atomic_set(&pending_req->pendcnt, 1); __end_block_io_op(pending_req, -EINVAL); msleep(1); /* back off a bit */ return -EIO; -- cgit v1.1 From 19c85a53434ec90c1c6d6b0717e1eb37c5f2f84d Mon Sep 17 00:00:00 2001 From: Konstantin Holoborodko Date: Fri, 29 Mar 2013 00:06:13 +0900 Subject: usb: ftdi_sio: Add support for Mitsubishi FX-USB-AW/-BD commit 482b0b5d82bd916cc0c55a2abf65bdc69023b843 upstream. It enhances the driver for FTDI-based USB serial adapters to recognize Mitsubishi Electric Corp. USB/RS422 Converters as FT232BM chips and support them. https://search.meau.com/?q=FX-USB-AW Signed-off-by: Konstantin Holoborodko Tested-by: Konstantin Holoborodko Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio_ids.h | 7 +++++++ 2 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 149198f..132f114 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -646,6 +646,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) }, { USB_DEVICE(ACTON_VID, ACTON_SPECTRAPRO_PID) }, { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, + { USB_DEVICE(MITSUBISHI_VID, MITSUBISHI_FXUSB_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 97e0a6b..809c03a 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -584,6 +584,13 @@ #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ /* + * Mitsubishi Electric Corp. (http://www.meau.com) + * Submitted by Konstantin Holoborodko + */ +#define MITSUBISHI_VID 0x06D3 +#define MITSUBISHI_FXUSB_PID 0x0284 /* USB/RS422 converters: FX-USB-AW/-BD */ + +/* * Definitions for B&B Electronics products. */ #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ -- cgit v1.1 From 8cc034e4c1b7901787bbf72908bc584c055b5e09 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 26 Mar 2013 20:30:17 -0400 Subject: vt: synchronize_rcu() under spinlock is not nice... commit e8cd81693bbbb15db57d3c9aa7dd90eda4842874 upstream. vcs_poll_data_free() calls unregister_vt_notifier(), which calls atomic_notifier_chain_unregister(), which calls synchronize_rcu(). Do it *after* we'd dropped ->f_lock. Signed-off-by: Al Viro Signed-off-by: Greg Kroah-Hartman --- drivers/tty/vt/vc_screen.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index 66825c9..ab23201 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -92,7 +92,7 @@ vcs_poll_data_free(struct vcs_poll_data *poll) static struct vcs_poll_data * vcs_poll_data_get(struct file *file) { - struct vcs_poll_data *poll = file->private_data; + struct vcs_poll_data *poll = file->private_data, *kill = NULL; if (poll) return poll; @@ -121,10 +121,12 @@ vcs_poll_data_get(struct file *file) file->private_data = poll; } else { /* someone else raced ahead of us */ - vcs_poll_data_free(poll); + kill = poll; poll = file->private_data; } spin_unlock(&file->f_lock); + if (kill) + vcs_poll_data_free(kill); return poll; } -- cgit v1.1 From b9f1f48ce20a1b923429c216669d03b5a900a8cf Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Fri, 15 Mar 2013 18:47:07 -0700 Subject: mwifiex: cancel cmd timer and free curr_cmd in shutdown process commit 084c7189acb3f969c855536166042e27f5dd703f upstream. curr_cmd points to the command that is in processing or waiting for its command response from firmware. If the function shutdown happens to occur at this time we should cancel the cmd timer and put the command back to free queue. Tested-by: Marco Cesarano Signed-off-by: Bing Zhao Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/mwifiex/init.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 3f1559e..45dfc2b 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -561,6 +561,14 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) return ret; } + /* cancel current command */ + if (adapter->curr_cmd) { + dev_warn(adapter->dev, "curr_cmd is still in processing\n"); + del_timer(&adapter->cmd_timer); + mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); + adapter->curr_cmd = NULL; + } + /* shut down mwifiex */ dev_dbg(adapter->dev, "info: shutdown mwifiex...\n"); -- cgit v1.1 From 98b3faa6da804a4cbb5aa205fac0933585d49444 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Thu, 21 Mar 2013 12:06:48 +0530 Subject: usb: xhci: Fix TRB transfer length macro used for Event TRB. commit 1c11a172cb30492f5f6a82c6e118fdcd9946c34f upstream. Use proper macro while extracting TRB transfer length from Transfer event TRBs. Adding a macro EVENT_TRB_LEN (bits 0:23) for the same, and use it instead of TRB_LEN (bits 0:16) in case of event TRBs. This patch should be backported to kernels as old as 2.6.31, that contain the commit b10de142119a676552df3f0d2e3a9d647036c26a "USB: xhci: Bulk transfer support". This patch will have issues applying to older kernels. Signed-off-by: Vivek gautam Signed-off-by: Sarah Sharp Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 24 ++++++++++++------------ drivers/usb/host/xhci.h | 4 ++++ 2 files changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index cb436fe1..151ca5e 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1960,8 +1960,8 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, if (event_trb != ep_ring->dequeue && event_trb != td->last_trb) td->urb->actual_length = - td->urb->transfer_buffer_length - - TRB_LEN(le32_to_cpu(event->transfer_len)); + td->urb->transfer_buffer_length - + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); else td->urb->actual_length = 0; @@ -1993,7 +1993,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, /* Maybe the event was for the data stage? */ td->urb->actual_length = td->urb->transfer_buffer_length - - TRB_LEN(le32_to_cpu(event->transfer_len)); + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); xhci_dbg(xhci, "Waiting for status " "stage event\n"); return 0; @@ -2029,7 +2029,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, /* handle completion code */ switch (trb_comp_code) { case COMP_SUCCESS: - if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) { + if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) { frame->status = 0; break; } @@ -2076,7 +2076,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])); } len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - - TRB_LEN(le32_to_cpu(event->transfer_len)); + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); if (trb_comp_code != COMP_STOP_INVAL) { frame->actual_length = len; @@ -2134,7 +2134,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, case COMP_SUCCESS: /* Double check that the HW transferred everything. */ if (event_trb != td->last_trb || - TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { xhci_warn(xhci, "WARN Successful completion " "on short TX\n"); if (td->urb->transfer_flags & URB_SHORT_NOT_OK) @@ -2162,18 +2162,18 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, "%d bytes untransferred\n", td->urb->ep->desc.bEndpointAddress, td->urb->transfer_buffer_length, - TRB_LEN(le32_to_cpu(event->transfer_len))); + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len))); /* Fast path - was this the last TRB in the TD for this URB? */ if (event_trb == td->last_trb) { - if (TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { + if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { td->urb->actual_length = td->urb->transfer_buffer_length - - TRB_LEN(le32_to_cpu(event->transfer_len)); + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); if (td->urb->transfer_buffer_length < td->urb->actual_length) { xhci_warn(xhci, "HC gave bad length " "of %d bytes left\n", - TRB_LEN(le32_to_cpu(event->transfer_len))); + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len))); td->urb->actual_length = 0; if (td->urb->transfer_flags & URB_SHORT_NOT_OK) *status = -EREMOTEIO; @@ -2217,7 +2217,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, if (trb_comp_code != COMP_STOP_INVAL) td->urb->actual_length += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - - TRB_LEN(le32_to_cpu(event->transfer_len)); + EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); } return finish_td(xhci, td, event_trb, event, ep, status, false); @@ -2283,7 +2283,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, * transfer type */ case COMP_SUCCESS: - if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) + if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) break; if (xhci->quirks & XHCI_TRUST_TX_LENGTH) trb_comp_code = COMP_SHORT_TX; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 8b94412..94724b0 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -831,6 +831,10 @@ struct xhci_transfer_event { __le32 flags; }; +/* Transfer event TRB length bit mask */ +/* bits 0:23 */ +#define EVENT_TRB_LEN(p) ((p) & 0xffffff) + /** Transfer Event bit fields **/ #define TRB_TO_EP_ID(p) (((p) >> 16) & 0x1f) -- cgit v1.1 From d1cc80b94858666cc48467e8e166ccf389551b5d Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Tue, 19 Mar 2013 12:36:56 +0100 Subject: macvtap: zerocopy: validate vectors before building skb commit b92946e2919134ebe2a4083e4302236295ea2a73 upstream. There're several reasons that the vectors need to be validated: - Return error when caller provides vectors whose num is greater than UIO_MAXIOV. - Linearize part of skb when userspace provides vectors grater than MAX_SKB_FRAGS. - Return error when userspace provides vectors whose total length may exceed - MAX_SKB_FRAGS * PAGE_SIZE. Signed-off-by: Jason Wang Signed-off-by: Michael S. Tsirkin Signed-off-by: Benjamin Poirier [patch reduced to the 3rd reason only for 3.0] Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/net/macvtap.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 6696e56..023b57e 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -552,6 +552,10 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, if (unlikely(len < ETH_HLEN)) goto err; + err = -EMSGSIZE; + if (unlikely(count > UIO_MAXIOV)) + goto err; + skb = macvtap_alloc_skb(&q->sk, NET_IP_ALIGN, len, vnet_hdr.hdr_len, noblock, &err); if (!skb) -- cgit v1.1 From 582b4c3dc62284aec367a3f4f74ce8101303e9c4 Mon Sep 17 00:00:00 2001 From: Anatol Pomozov Date: Mon, 1 Apr 2013 09:47:56 -0700 Subject: loop: prevent bdev freeing while device in use commit c1681bf8a7b1b98edee8b862a42c19c4e53205fd upstream. struct block_device lifecycle is defined by its inode (see fs/block_dev.c) - block_device allocated first time we access /dev/loopXX and deallocated on bdev_destroy_inode. When we create the device "losetup /dev/loopXX afile" we want that block_device stay alive until we destroy the loop device with "losetup -d". But because we do not hold /dev/loopXX inode its counter goes 0, and inode/bdev can be destroyed at any moment. Usually it happens at memory pressure or when user drops inode cache (like in the test below). When later in loop_clr_fd() we want to use bdev we have use-after-free error with following stack: BUG: unable to handle kernel NULL pointer dereference at 0000000000000280 bd_set_size+0x10/0xa0 loop_clr_fd+0x1f8/0x420 [loop] lo_ioctl+0x200/0x7e0 [loop] lo_compat_ioctl+0x47/0xe0 [loop] compat_blkdev_ioctl+0x341/0x1290 do_filp_open+0x42/0xa0 compat_sys_ioctl+0xc1/0xf20 do_sys_open+0x16e/0x1d0 sysenter_dispatch+0x7/0x1a To prevent use-after-free we need to grab the device in loop_set_fd() and put it later in loop_clr_fd(). The issue is reprodusible on current Linus head and v3.3. Here is the test: dd if=/dev/zero of=loop.file bs=1M count=1 while [ true ]; do losetup /dev/loop0 loop.file echo 2 > /proc/sys/vm/drop_caches losetup -d /dev/loop0 done [ Doing bdgrab/bput in loop_set_fd/loop_clr_fd is safe, because every time we call loop_set_fd() we check that loop_device->lo_state is Lo_unbound and set it to Lo_bound If somebody will try to set_fd again it will get EBUSY. And if we try to loop_clr_fd() on unbound loop device we'll get ENXIO. loop_set_fd/loop_clr_fd (and any other loop ioctl) is called under loop_device->lo_ctl_mutex. ] Signed-off-by: Anatol Pomozov Cc: Al Viro Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/block/loop.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 258cd0a..38f8da9 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -928,6 +928,11 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, wake_up_process(lo->lo_thread); if (max_part > 0) ioctl_by_bdev(bdev, BLKRRPART, 0); + + /* Grab the block_device to prevent its destruction after we + * put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev). + */ + bdgrab(bdev); return 0; out_clr: @@ -1024,8 +1029,10 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); memset(lo->lo_file_name, 0, LO_NAME_SIZE); - if (bdev) + if (bdev) { + bdput(bdev); invalidate_bdev(bdev); + } set_capacity(lo->lo_disk, 0); loop_sysfs_exit(lo); if (bdev) { -- cgit v1.1 From 08b2dce495f36f35e2759446a0ed94c66a05a0c5 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 29 Aug 2011 09:45:28 -0700 Subject: drm/i915: don't set unpin_work if vblank_get fails commit 7317c75e66fce0c9f82fbe6f72f7e5256b315422 upstream. This fixes a race where we may try to finish a page flip and decrement the refcount even if our vblank_get failed and we ended up with a spurious flip pending interrupt. Fixes https://bugs.freedesktop.org/show_bug.cgi?id=34211. Signed-off-by: Jesse Barnes Signed-off-by: Keith Packard Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_display.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 11ecb0c..e6ea002 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6524,11 +6524,16 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work->old_fb_obj = intel_fb->obj; INIT_WORK(&work->work, intel_unpin_work_fn); + ret = drm_vblank_get(dev, intel_crtc->pipe); + if (ret) + goto free_work; + /* We borrow the event spin lock for protecting unpin_work */ spin_lock_irqsave(&dev->event_lock, flags); if (intel_crtc->unpin_work) { spin_unlock_irqrestore(&dev->event_lock, flags); kfree(work); + drm_vblank_put(dev, intel_crtc->pipe); DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); return -EBUSY; @@ -6547,10 +6552,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, crtc->fb = fb; - ret = drm_vblank_get(dev, intel_crtc->pipe); - if (ret) - goto cleanup_objs; - work->pending_flip_obj = obj; work->enable_stall_check = true; @@ -6572,7 +6573,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, cleanup_pending: atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); -cleanup_objs: drm_gem_object_unreference(&work->old_fb_obj->base); drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); @@ -6581,6 +6581,8 @@ cleanup_objs: intel_crtc->unpin_work = NULL; spin_unlock_irqrestore(&dev->event_lock, flags); + drm_vblank_put(dev, intel_crtc->pipe); +free_work: kfree(work); return ret; -- cgit v1.1 From 22b2f9aaf4d832e4eef1b8a437e64db5f2f147d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 22 Feb 2013 16:53:38 +0200 Subject: drm/i915: Don't clobber crtc->fb when queue_flip fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 4a35f83b2b7c6aae3fc0d1c4554fdc99dc33ad07 upstream. Restore crtc->fb to the old framebuffer if queue_flip fails. While at it, kill the pointless intel_fb temp variable. v2: Update crtc->fb before queue_flip and restore it back after a failure. [Backported for 3.0-stable. Adjusted context. Please cherry-pick commit 7317c75e66fce0c9f82fbe6f72f7e5256b315422 upstream before this patch as it provides necessary context and fixes a panic.] Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Reported-and-Tested-by: Mika Kuoppala Signed-off-by: Daniel Vetter Signed-off-by: Lingzhu Xiang Reviewed-by: CAI Qian Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_display.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e6ea002..2e0c24d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6507,8 +6507,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_framebuffer *intel_fb; - struct drm_i915_gem_object *obj; + struct drm_framebuffer *old_fb = crtc->fb; + struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_unpin_work *work; unsigned long flags; @@ -6520,8 +6520,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work->event = event; work->dev = crtc->dev; - intel_fb = to_intel_framebuffer(crtc->fb); - work->old_fb_obj = intel_fb->obj; + work->old_fb_obj = to_intel_framebuffer(old_fb)->obj; INIT_WORK(&work->work, intel_unpin_work_fn); ret = drm_vblank_get(dev, intel_crtc->pipe); @@ -6541,9 +6540,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, intel_crtc->unpin_work = work; spin_unlock_irqrestore(&dev->event_lock, flags); - intel_fb = to_intel_framebuffer(fb); - obj = intel_fb->obj; - mutex_lock(&dev->struct_mutex); /* Reference the objects for the scheduled work. */ @@ -6573,6 +6569,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, cleanup_pending: atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); + crtc->fb = old_fb; drm_gem_object_unreference(&work->old_fb_obj->base); drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); -- cgit v1.1 From c2ff0153d27b39d87c1ff5f575c4ca7b52f33381 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Fri, 1 Mar 2013 14:49:12 +0000 Subject: efivars: explicitly calculate length of VariableName commit ec50bd32f1672d38ddce10fb1841cbfda89cfe9a upstream. It's not wise to assume VariableNameSize represents the length of VariableName, as not all firmware updates VariableNameSize in the same way (some don't update it at all if EFI_SUCCESS is returned). There are even implementations out there that update VariableNameSize with values that are both larger than the string returned in VariableName and smaller than the buffer passed to GetNextVariableName(), which resulted in the following bug report from Michael Schroeder, > On HP z220 system (firmware version 1.54), some EFI variables are > incorrectly named : > > ls -d /sys/firmware/efi/vars/*8be4d* | grep -v -- -8be returns > /sys/firmware/efi/vars/dbxDefault-pport8be4df61-93ca-11d2-aa0d-00e098032b8c > /sys/firmware/efi/vars/KEKDefault-pport8be4df61-93ca-11d2-aa0d-00e098032b8c > /sys/firmware/efi/vars/SecureBoot-pport8be4df61-93ca-11d2-aa0d-00e098032b8c > /sys/firmware/efi/vars/SetupMode-Information8be4df61-93ca-11d2-aa0d-00e098032b8c The issue here is that because we blindly use VariableNameSize without verifying its value, we can potentially read garbage values from the buffer containing VariableName if VariableNameSize is larger than the length of VariableName. Since VariableName is a string, we can calculate its size by searching for the terminating NULL character. [Backported for 3.8-stable. Removed workqueue code added in a93bc0c 3.9-rc1.] Reported-by: Frederic Crozat Cc: Matthew Garrett Cc: Josh Boyer Cc: Michael Schroeder Cc: Lee, Chun-Yi Cc: Lingzhu Xiang Cc: Seiji Aguchi Signed-off-by: Matt Fleming Signed-off-by: Lingzhu Xiang Reviewed-by: CAI Qian Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/efivars.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'drivers') diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 6871ed3..f3d83d8 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -731,6 +731,31 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, } /* + * Returns the size of variable_name, in bytes, including the + * terminating NULL character, or variable_name_size if no NULL + * character is found among the first variable_name_size bytes. + */ +static unsigned long var_name_strnsize(efi_char16_t *variable_name, + unsigned long variable_name_size) +{ + unsigned long len; + efi_char16_t c; + + /* + * The variable name is, by definition, a NULL-terminated + * string, so make absolutely sure that variable_name_size is + * the value we expect it to be. If not, return the real size. + */ + for (len = 2; len <= variable_name_size; len += sizeof(c)) { + c = variable_name[(len / sizeof(c)) - 1]; + if (!c) + break; + } + + return min(len, variable_name_size); +} + +/* * Let's not leave out systab information that snuck into * the efivars driver */ @@ -957,6 +982,8 @@ int register_efivars(struct efivars *efivars, &vendor_guid); switch (status) { case EFI_SUCCESS: + variable_name_size = var_name_strnsize(variable_name, + variable_name_size); efivar_create_sysfs_entry(efivars, variable_name_size, variable_name, -- cgit v1.1 From 7fb54baf47818c2a76999ff907e2cecf25b98218 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 7 Mar 2013 11:59:14 +0000 Subject: efivars: Handle duplicate names from get_next_variable() commit e971318bbed610e28bb3fde9d548e6aaf0a6b02e upstream. Some firmware exhibits a bug where the same VariableName and VendorGuid values are returned on multiple invocations of GetNextVariableName(). See, https://bugzilla.kernel.org/show_bug.cgi?id=47631 As a consequence of such a bug, Andre reports hitting the following WARN_ON() in the sysfs code after updating the BIOS on his, "Gigabyte Technology Co., Ltd. To be filled by O.E.M./Z77X-UD3H, BIOS F19e 11/21/2012)" machine, [ 0.581554] EFI Variables Facility v0.08 2004-May-17 [ 0.584914] ------------[ cut here ]------------ [ 0.585639] WARNING: at /home/andre/linux/fs/sysfs/dir.c:536 sysfs_add_one+0xd4/0x100() [ 0.586381] Hardware name: To be filled by O.E.M. [ 0.587123] sysfs: cannot create duplicate filename '/firmware/efi/vars/SbAslBufferPtrVar-01f33c25-764d-43ea-aeea-6b5a41f3f3e8' [ 0.588694] Modules linked in: [ 0.589484] Pid: 1, comm: swapper/0 Not tainted 3.8.0+ #7 [ 0.590280] Call Trace: [ 0.591066] [] ? sysfs_add_one+0xd4/0x100 [ 0.591861] [] warn_slowpath_common+0x7f/0xc0 [ 0.592650] [] warn_slowpath_fmt+0x4c/0x50 [ 0.593429] [] ? strlcat+0x65/0x80 [ 0.594203] [] sysfs_add_one+0xd4/0x100 [ 0.594979] [] create_dir+0x78/0xd0 [ 0.595753] [] sysfs_create_dir+0x86/0xe0 [ 0.596532] [] kobject_add_internal+0x9c/0x220 [ 0.597310] [] kobject_init_and_add+0x67/0x90 [ 0.598083] [] ? efivar_create_sysfs_entry+0x61/0x1c0 [ 0.598859] [] efivar_create_sysfs_entry+0x11b/0x1c0 [ 0.599631] [] register_efivars+0xde/0x420 [ 0.600395] [] ? edd_init+0x2f5/0x2f5 [ 0.601150] [] efivars_init+0xb8/0x104 [ 0.601903] [] do_one_initcall+0x12a/0x180 [ 0.602659] [] kernel_init_freeable+0x13e/0x1c6 [ 0.603418] [] ? loglevel+0x31/0x31 [ 0.604183] [] ? rest_init+0x80/0x80 [ 0.604936] [] kernel_init+0xe/0xf0 [ 0.605681] [] ret_from_fork+0x7c/0xb0 [ 0.606414] [] ? rest_init+0x80/0x80 [ 0.607143] ---[ end trace 1609741ab737eb29 ]--- There's not much we can do to work around and keep traversing the variable list once we hit this firmware bug. Our only solution is to terminate the loop because, as Lingzhu reports, some machines get stuck when they encounter duplicate names, > I had an IBM System x3100 M4 and x3850 X5 on which kernel would > get stuck in infinite loop creating duplicate sysfs files because, > for some reason, there are several duplicate boot entries in nvram > getting GetNextVariableName into a circle of iteration (with > period > 2). Also disable the workqueue, as efivar_update_sysfs_entries() uses GetNextVariableName() to figure out which variables have been created since the last iteration. That algorithm isn't going to work if GetNextVariableName() returns duplicates. Note that we don't disable EFI variable creation completely on the affected machines, it's just that any pstore dump-* files won't appear in sysfs until the next boot. [Backported for 3.0-stable. Removed code related to pstore workqueue but pulled in helper function variable_is_present from a93bc0c; Moved the definition of __efivars to the top for being referenced in variable_is_present.] Reported-by: Andre Heider Reported-by: Lingzhu Xiang Tested-by: Lingzhu Xiang Cc: Seiji Aguchi Signed-off-by: Matt Fleming Signed-off-by: Lingzhu Xiang Reviewed-by: CAI Qian Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/efivars.c | 65 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index f3d83d8..c5cce9c 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -119,6 +119,8 @@ struct efivar_attribute { ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count); }; +static struct efivars __efivars; +static struct efivar_operations ops; #define EFIVAR_ATTR(_name, _mode, _show, _store) \ struct efivar_attribute efivar_attr_##_name = { \ @@ -730,6 +732,28 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, return count; } +static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor) +{ + struct efivar_entry *entry, *n; + struct efivars *efivars = &__efivars; + unsigned long strsize1, strsize2; + bool found = false; + + strsize1 = utf16_strsize(variable_name, 1024); + list_for_each_entry_safe(entry, n, &efivars->list, list) { + strsize2 = utf16_strsize(entry->var.VariableName, 1024); + if (strsize1 == strsize2 && + !memcmp(variable_name, &(entry->var.VariableName), + strsize2) && + !efi_guidcmp(entry->var.VendorGuid, + *vendor)) { + found = true; + break; + } + } + return found; +} + /* * Returns the size of variable_name, in bytes, including the * terminating NULL character, or variable_name_size if no NULL @@ -942,6 +966,28 @@ void unregister_efivars(struct efivars *efivars) } EXPORT_SYMBOL_GPL(unregister_efivars); +/* + * Print a warning when duplicate EFI variables are encountered and + * disable the sysfs workqueue since the firmware is buggy. + */ +static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid, + unsigned long len16) +{ + size_t i, len8 = len16 / sizeof(efi_char16_t); + char *s8; + + s8 = kzalloc(len8, GFP_KERNEL); + if (!s8) + return; + + for (i = 0; i < len8; i++) + s8[i] = s16[i]; + + printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n", + s8, vendor_guid); + kfree(s8); +} + int register_efivars(struct efivars *efivars, const struct efivar_operations *ops, struct kobject *parent_kobj) @@ -984,6 +1030,22 @@ int register_efivars(struct efivars *efivars, case EFI_SUCCESS: variable_name_size = var_name_strnsize(variable_name, variable_name_size); + + /* + * Some firmware implementations return the + * same variable name on multiple calls to + * get_next_variable(). Terminate the loop + * immediately as there is no guarantee that + * we'll ever see a different variable name, + * and may end up looping here forever. + */ + if (variable_is_present(variable_name, &vendor_guid)) { + dup_variable_bug(variable_name, &vendor_guid, + variable_name_size); + status = EFI_NOT_FOUND; + break; + } + efivar_create_sysfs_entry(efivars, variable_name_size, variable_name, @@ -1010,9 +1072,6 @@ out: } EXPORT_SYMBOL_GPL(register_efivars); -static struct efivars __efivars; -static struct efivar_operations ops; - /* * For now we register the efi subsystem with the firmware subsystem * and the vars subsystem with the efi subsystem. In the future, it -- cgit v1.1 From 0b1a48cbcca9aa5aeed944c88c3d2b7c745d6f37 Mon Sep 17 00:00:00 2001 From: Mirko Lindner Date: Tue, 26 Mar 2013 06:38:35 +0000 Subject: sky2: Receive Overflows not counted [ Upstream commit 9cfe8b156c21cf340b3a10ecb3022fbbc1c39185 ] The sky2 driver doesn't count the Receive Overflows because the MAC interrupt for this event is not set in the MAC's interrupt mask. The MAC's interrupt mask is set only for Transmit FIFO Underruns. Fix: The correct setting should be (GM_IS_TX_FF_UR | GM_IS_RX_FF_OR) Otherwise the Receive Overflow event will not generate any interrupt. The Receive Overflow interrupt is handled correctly Signed-off-by: Mirko Lindner Acked-by: Stephen Hemminger Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/sky2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index a79a166..8cc863e 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -2064,7 +2064,7 @@ enum { GM_IS_RX_FF_OR = 1<<1, /* Receive FIFO Overrun */ GM_IS_RX_COMPL = 1<<0, /* Frame Reception Complete */ -#define GMAC_DEF_MSK GM_IS_TX_FF_UR +#define GMAC_DEF_MSK (GM_IS_TX_FF_UR | GM_IS_RX_FF_OR) }; /* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ -- cgit v1.1 From 40e954e2b1e8f84eb1e0eb7af49bf4b9baa8a0ac Mon Sep 17 00:00:00 2001 From: Mirko Lindner Date: Tue, 26 Mar 2013 06:38:42 +0000 Subject: sky2: Threshold for Pause Packet is set wrong [ Upstream commit 74f9f42c1c1650e74fb464f76644c9041f996851 ] The sky2 driver sets the Rx Upper Threshold for Pause Packet generation to a wrong value which leads to only 2kB of RAM remaining space. This can lead to Rx overflow errors even with activated flow-control. Fix: We should increase the value to 8192/8 Signed-off-by: Mirko Lindner Acked-by: Stephen Hemminger Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/sky2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 5f93956..7f7aae2 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -992,7 +992,7 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space) sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp); sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2); - tp = space - 2048/8; + tp = space - 8192/8; sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp); sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4); } else { -- cgit v1.1 From 5a37b9a3f61eced85a8398250f2fc89dbfdf1a10 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 27 Mar 2013 18:28:41 +0000 Subject: aoe: reserve enough headroom on skbs [ Upstream commit 91c5746425aed8f7188a351f1224a26aa232e4b3 ] Some network drivers use a non default hard_header_len Transmitted skb should take into account dev->hard_header_len, or risk crashes or expensive reallocations. In the case of aoe, lets reserve MAX_HEADER bytes. David reported a crash in defxx driver, solved by this patch. Reported-by: David Oostdyk Tested-by: David Oostdyk Signed-off-by: Eric Dumazet Cc: Ed Cashin Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/block/aoe/aoecmd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 887f68f..db30542 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -30,8 +30,9 @@ new_skb(ulong len) { struct sk_buff *skb; - skb = alloc_skb(len, GFP_ATOMIC); + skb = alloc_skb(len + MAX_HEADER, GFP_ATOMIC); if (skb) { + skb_reserve(skb, MAX_HEADER); skb_reset_mac_header(skb); skb_reset_network_header(skb); skb->protocol = __constant_htons(ETH_P_AOE); -- cgit v1.1 From 85d17d2226b60776d55260f8bf5c5db972136e72 Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Wed, 27 Mar 2013 04:42:00 +0000 Subject: drivers: net: ethernet: davinci_emac: use netif_wake_queue() while restarting tx queue To restart tx queue use netif_wake_queue() intead of netif_start_queue() so that net schedule will restart transmission immediately which will increase network performance while doing huge data transfers. Reported-by: Dan Franke Suggested-by: Sriramakrishnan A G Signed-off-by: Mugunthan V N Acked-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/davinci_emac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index e5efe3a..e5d0eed 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c @@ -1049,7 +1049,7 @@ static void emac_tx_handler(void *token, int len, int status) struct net_device *ndev = skb->dev; if (unlikely(netif_queue_stopped(ndev))) - netif_start_queue(ndev); + netif_wake_queue(ndev); ndev->stats.tx_packets++; ndev->stats.tx_bytes += len; dev_kfree_skb_any(skb); -- cgit v1.1 From be409987531f89307e1cb281ff104209a085a5d7 Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Thu, 28 Mar 2013 18:10:50 +0000 Subject: atl1e: drop pci-msi support because of packet corruption MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 188ab1b105c96656f6bcfb49d0d8bb1b1936b632 ] Usage of pci-msi results in corrupted dma packet transfers to the host. Reported-by: rebelyouth Cc: Huang, Xiong Tested-by: Christian Sünkenberg Signed-off-by: Hannes Frederic Sowa Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/atl1e/atl1e.h | 1 - drivers/net/atl1e/atl1e_main.c | 22 ++-------------------- 2 files changed, 2 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h index 490d3b3..4093097 100644 --- a/drivers/net/atl1e/atl1e.h +++ b/drivers/net/atl1e/atl1e.h @@ -439,7 +439,6 @@ struct atl1e_adapter { struct atl1e_hw hw; struct atl1e_hw_stats hw_stats; - bool have_msi; u32 wol; u16 link_speed; u16 link_duplex; diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 86a9122..b0132bb 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -1848,37 +1848,19 @@ static void atl1e_free_irq(struct atl1e_adapter *adapter) struct net_device *netdev = adapter->netdev; free_irq(adapter->pdev->irq, netdev); - - if (adapter->have_msi) - pci_disable_msi(adapter->pdev); } static int atl1e_request_irq(struct atl1e_adapter *adapter) { struct pci_dev *pdev = adapter->pdev; struct net_device *netdev = adapter->netdev; - int flags = 0; int err = 0; - adapter->have_msi = true; - err = pci_enable_msi(adapter->pdev); - if (err) { - netdev_dbg(adapter->netdev, - "Unable to allocate MSI interrupt Error: %d\n", err); - adapter->have_msi = false; - } else - netdev->irq = pdev->irq; - - - if (!adapter->have_msi) - flags |= IRQF_SHARED; - err = request_irq(adapter->pdev->irq, atl1e_intr, flags, - netdev->name, netdev); + err = request_irq(pdev->irq, atl1e_intr, IRQF_SHARED, + netdev->name, netdev); if (err) { netdev_dbg(adapter->netdev, "Unable to allocate interrupt Error: %d\n", err); - if (adapter->have_msi) - pci_disable_msi(adapter->pdev); return err; } netdev_dbg(adapter->netdev, "atl1e_request_irq OK\n"); -- cgit v1.1 From 3d2479580b8832251ab98dff289a88647e2d73bf Mon Sep 17 00:00:00 2001 From: "Max.Nekludov@us.elster.com" Date: Fri, 29 Mar 2013 05:27:36 +0000 Subject: ks8851: Fix interpretation of rxlen field. [ Upstream commit 14bc435ea54cb888409efb54fc6b76c13ef530e9 ] According to the Datasheet (page 52): 15-12 Reserved 11-0 RXBC Receive Byte Count This field indicates the present received frame byte size. The code has a bug: rxh = ks8851_rdreg32(ks, KS_RXFHSR); rxstat = rxh & 0xffff; rxlen = rxh >> 16; // BUG!!! 0xFFF mask should be applied Signed-off-by: Max Nekludov Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ks8851.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c index bcd9ba6..99593f0 100644 --- a/drivers/net/ks8851.c +++ b/drivers/net/ks8851.c @@ -489,7 +489,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) for (; rxfc != 0; rxfc--) { rxh = ks8851_rdreg32(ks, KS_RXFHSR); rxstat = rxh & 0xffff; - rxlen = rxh >> 16; + rxlen = (rxh >> 16) & 0xfff; netif_dbg(ks, rx_status, ks->netdev, "rx: stat 0x%04x, len 0x%04x\n", rxstat, rxlen); -- cgit v1.1 From 3beceaf660dffbe11f5a5606ea379666eb9eaad0 Mon Sep 17 00:00:00 2001 From: Veaceslav Falico Date: Mon, 25 Mar 2013 22:26:21 +0000 Subject: pch_gbe: fix ip_summed checksum reporting on rx [ Upstream commit 76a0e68129d7d24eb995a6871ab47081bbfa0acc ] skb->ip_summed should be CHECKSUM_UNNECESSARY when the driver reports that checksums were correct and CHECKSUM_NONE in any other case. They're currently placed vice versa, which breaks the forwarding scenario. Fix it by placing them as described above. Signed-off-by: Veaceslav Falico Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/pch_gbe/pch_gbe_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c index 236d00e..0055daf 100644 --- a/drivers/net/pch_gbe/pch_gbe_main.c +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -1509,9 +1509,9 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, skb_put(skb, length); skb->protocol = eth_type_trans(skb, netdev); if (tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK) - skb->ip_summed = CHECKSUM_NONE; - else skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; napi_gro_receive(&adapter->napi, skb); (*work_done)++; -- cgit v1.1 From 5229aee5b9a28ac7b1c12ae988e1c8a49b217123 Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Thu, 28 Mar 2013 02:34:41 +0000 Subject: smsc75xx: fix jumbo frame support [ Upstream commit 4c51e53689569398d656e631c17308d9b8e84650 ] This patch enables RX of jumbo frames for LAN7500. Previously the driver would transmit jumbo frames succesfully but would drop received jumbo frames (incrementing the interface errors count). With this patch applied the device can succesfully receive jumbo frames up to MTU 9000 (9014 bytes on the wire including ethernet header). Signed-off-by: Steve Glendinning Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/smsc75xx.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index de0de3e..2f4775f 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -719,8 +719,12 @@ static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size) static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu) { struct usbnet *dev = netdev_priv(netdev); + int ret; + + if (new_mtu > MAX_SINGLE_PACKET_SIZE) + return -EINVAL; - int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu); + ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu + ETH_HLEN); check_warn_return(ret, "Failed to set mac rx frame length"); return usbnet_change_mtu(netdev, new_mtu); @@ -964,7 +968,7 @@ static int smsc75xx_reset(struct usbnet *dev) netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x", buf); - ret = smsc75xx_set_rx_max_frame_length(dev, 1514); + ret = smsc75xx_set_rx_max_frame_length(dev, dev->net->mtu + ETH_HLEN); check_warn_return(ret, "Failed to set max rx frame length"); ret = smsc75xx_read_reg(dev, MAC_RX, &buf); @@ -1108,8 +1112,8 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT)) dev->net->stats.rx_frame_errors++; } else { - /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ - if (unlikely(size > (ETH_FRAME_LEN + 12))) { + /* MAX_SINGLE_PACKET_SIZE + 4(CRC) + 2(COE) + 4(Vlan) */ + if (unlikely(size > (MAX_SINGLE_PACKET_SIZE + ETH_HLEN + 12))) { netif_dbg(dev, rx_err, dev->net, "size err rx_cmd_a=0x%08x", rx_cmd_a); return 0; -- cgit v1.1 From f6cab49c7b11abf9595b1bf9b6ff73931c832e2e Mon Sep 17 00:00:00 2001 From: Veaceslav Falico Date: Tue, 2 Apr 2013 05:15:16 +0000 Subject: bonding: get netdev_rx_handler_unregister out of locks [ Upstream commit fcd99434fb5c137274d2e15dd2a6a7455f0f29ff ] Now that netdev_rx_handler_unregister contains synchronize_net(), we need to call it outside of bond->lock, cause it might sleep. Also, remove the already unneded synchronize_net(). Signed-off-by: Veaceslav Falico Acked-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6f8b268..dd433a7 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -2017,12 +2017,11 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) return -EINVAL; } + write_unlock_bh(&bond->lock); /* unregister rx_handler early so bond_handle_frame wouldn't be called * for this slave anymore. */ netdev_rx_handler_unregister(slave_dev); - write_unlock_bh(&bond->lock); - synchronize_net(); write_lock_bh(&bond->lock); if (!bond->params.fail_over_mac) { -- cgit v1.1 From c55f9197cfc3d968c64ed4e7762214c04090426e Mon Sep 17 00:00:00 2001 From: Shan Hai Date: Mon, 18 Mar 2013 10:30:44 +0800 Subject: libata: Set max sector to 65535 for Slimtype DVD A DS8A8SH drive commit a32450e127fc6e5ca6d958ceb3cfea4d30a00846 upstream. The Slimtype DVD A DS8A8SH drive locks up when max sector is smaller than 65535, and the blow backtrace is observed on locking up: INFO: task flush-8:32:1130 blocked for more than 120 seconds. "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. flush-8:32 D ffffffff8180cf60 0 1130 2 0x00000000 ffff880273aef618 0000000000000046 0000000000000005 ffff880273aee000 ffff880273aee000 ffff880273aeffd8 ffff880273aee010 ffff880273aee000 ffff880273aeffd8 ffff880273aee000 ffff88026e842ea0 ffff880274a10000 Call Trace: [] schedule+0x5d/0x70 [] io_schedule+0x8c/0xd0 [] get_request+0x731/0x7d0 [] ? cfq_allow_merge+0x50/0x90 [] ? wake_up_bit+0x40/0x40 [] ? bio_attempt_back_merge+0x33/0x110 [] blk_queue_bio+0x23a/0x3f0 [] generic_make_request+0xc6/0x120 [] submit_bio+0x138/0x160 [] ? bio_alloc_bioset+0x96/0x120 [] submit_bh+0x1f1/0x220 [] __block_write_full_page+0x228/0x340 [] ? attach_nobh_buffers+0xc0/0xc0 [] ? I_BDEV+0x10/0x10 [] ? I_BDEV+0x10/0x10 [] block_write_full_page_endio+0xe6/0x100 [] block_write_full_page+0x15/0x20 [] blkdev_writepage+0x18/0x20 [] __writepage+0x17/0x40 [] write_cache_pages+0x34a/0x4a0 [] ? set_page_dirty+0x70/0x70 [] generic_writepages+0x51/0x80 [] do_writepages+0x20/0x50 [] __writeback_single_inode+0xa6/0x2b0 [] writeback_sb_inodes+0x311/0x4d0 [] __writeback_inodes_wb+0x86/0xd0 [] wb_writeback+0x1a3/0x330 [] ? _raw_spin_lock_irqsave+0x3f/0x50 [] ? get_nr_inodes+0x52/0x70 [] wb_do_writeback+0x1dc/0x260 [] ? schedule_timeout+0x204/0x240 [] bdi_writeback_thread+0x102/0x2b0 [] ? wb_do_writeback+0x260/0x260 [] kthread+0xc0/0xd0 [] ? kthread_worker_fn+0x1b0/0x1b0 [] ret_from_fork+0x7c/0xb0 [] ? kthread_worker_fn+0x1b0/0x1b0 The above trace was triggered by "dd if=/dev/zero of=/dev/sr0 bs=2048 count=32768" It was previously working by accident, since another bug introduced by 4dce8ba94c7 (libata: Use 'bool' return value for ata_id_XXX) caused all drives to use maxsect=65535. Signed-off-by: Shan Hai Signed-off-by: Jeff Garzik Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 5a72e36..172619e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2412,6 +2412,9 @@ int ata_dev_configure(struct ata_device *dev) dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128, dev->max_sectors); + if (dev->horkage & ATA_HORKAGE_MAX_SEC_LBA48) + dev->max_sectors = ATA_MAX_SECTORS_LBA48; + if (ap->ops->dev_config) ap->ops->dev_config(dev); @@ -4077,6 +4080,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { /* Weird ATAPI devices */ { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 }, { "QUANTUM DAT DAT72-000", NULL, ATA_HORKAGE_ATAPI_MOD16_DMA }, + { "Slimtype DVD A DS8A8SH", NULL, ATA_HORKAGE_MAX_SEC_LBA48 }, /* Devices we expect to fail diagnostics */ -- cgit v1.1 From c3ca0ec19faf219a76242f15eab08cc51ad13831 Mon Sep 17 00:00:00 2001 From: Richard Guy Briggs Date: Tue, 12 Feb 2013 19:39:44 +0000 Subject: thermal: return an error on failure to register thermal class commit da28d966f6aa942ae836d09729f76a1647932309 upstream. The return code from the registration of the thermal class is used to unallocate resources, but this failure isn't passed back to the caller of thermal_init. Return this failure back to the caller. This bug was introduced in changeset 4cb18728 which overwrote the return code when the variable was re-used to catch the return code of the registration of the genetlink thermal socket family. Signed-off-by: Richard Guy Briggs Signed-off-by: Zhang Rui Cc: Jonghwan Choi Signed-off-by: Greg Kroah-Hartman --- drivers/thermal/thermal_sys.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 0b1c82a..ba6b71b 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -1319,6 +1319,7 @@ static int __init thermal_init(void) idr_destroy(&thermal_cdev_idr); mutex_destroy(&thermal_idr_lock); mutex_destroy(&thermal_list_lock); + return result; } result = genetlink_init(); return result; -- cgit v1.1 From 0ea64c49dc38aa94552c3fa1d81b0901bbfbccd1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 10 Apr 2013 15:21:39 -0700 Subject: Revert "mwifiex: cancel cmd timer and free curr_cmd in shutdown process revert commit b9f1f48ce20a1b923429c216669d03b5a900a8cf which is commit 084c7189acb3f969c855536166042e27f5dd703f upstream. It shouldn't have been applied to the 3.0-stable tree. Reported-by: Ben Hutchings Cc: Marco Cesarano Reported-by: Bing Zhao Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/mwifiex/init.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 45dfc2b..3f1559e 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -561,14 +561,6 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) return ret; } - /* cancel current command */ - if (adapter->curr_cmd) { - dev_warn(adapter->dev, "curr_cmd is still in processing\n"); - del_timer(&adapter->cmd_timer); - mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); - adapter->curr_cmd = NULL; - } - /* shut down mwifiex */ dev_dbg(adapter->dev, "info: shutdown mwifiex...\n"); -- cgit v1.1 From 5c077afc739a302afb26fe3cea445c4974ab1457 Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Mon, 18 Feb 2013 12:56:28 -0700 Subject: rt2x00: rt2x00pci_regbusy_read() - only print register access failure once commit 83589b30f1e1dc9898986293c9336b8ce1705dec upstream. BugLink: http://bugs.launchpad.net/bugs/1128840 It appears that when this register read fails it never recovers, so I think there is no need to repeat the same error message ad infinitum. Signed-off-by: Tim Gardner Cc: Ivo van Doorn Cc: Gertjan van Wingerde Cc: Helmut Schaa Cc: "John W. Linville" Cc: linux-wireless@vger.kernel.org Cc: users@rt2x00.serialmonkey.com Cc: netdev@vger.kernel.org Cc: stable@vger.kernel.org Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/rt2x00/rt2x00pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 17148bb..10fe07d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -52,8 +52,8 @@ int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, udelay(REGISTER_BUSY_DELAY); } - ERROR(rt2x00dev, "Indirect register access failed: " - "offset=0x%.08x, value=0x%.08x\n", offset, *reg); + printk_once(KERN_ERR "%s() Indirect register access failed: " + "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg); *reg = ~0; return 0; -- cgit v1.1 From 3d91fc30b72e90319f1bb35905e284b58b976d6f Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Wed, 10 Apr 2013 15:00:27 -0700 Subject: target: Fix incorrect fallthrough of ALUA Standby/Offline/Transition CDBs commit 30f359a6f9da65a66de8cadf959f0f4a0d498bba upstream. This patch fixes a bug where a handful of informational / control CDBs that should be allowed during ALUA access state Standby/Offline/Transition where incorrectly returning CHECK_CONDITION + ASCQ_04H_ALUA_TG_PT_*. This includes INQUIRY + REPORT_LUNS, which would end up preventing LUN registration when LUN scanning occured during these ALUA access states. Signed-off-by: Nicholas Bellinger Cc: Hannes Reinecke Signed-off-by: Greg Kroah-Hartman --- drivers/target/target_core_alua.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index c967405..527bda4 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c @@ -351,6 +351,7 @@ static inline int core_alua_state_standby( case REPORT_LUNS: case RECEIVE_DIAGNOSTIC: case SEND_DIAGNOSTIC: + return 0; case MAINTENANCE_IN: switch (cdb[1]) { case MI_REPORT_TARGET_PGS: @@ -393,6 +394,7 @@ static inline int core_alua_state_unavailable( switch (cdb[0]) { case INQUIRY: case REPORT_LUNS: + return 0; case MAINTENANCE_IN: switch (cdb[1]) { case MI_REPORT_TARGET_PGS: @@ -433,6 +435,7 @@ static inline int core_alua_state_transition( switch (cdb[0]) { case INQUIRY: case REPORT_LUNS: + return 0; case MAINTENANCE_IN: switch (cdb[1]) { case MI_REPORT_TARGET_PGS: -- cgit v1.1 From fcea984b4ded553023858d55afcf5e782462af1c Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 8 Sep 2012 12:57:30 -0700 Subject: mtdchar: fix offset overflow detection commit 9c603e53d380459fb62fec7cd085acb0b74ac18f upstream. Sasha Levin has been running trinity in a KVM tools guest, and was able to trigger the BUG_ON() at arch/x86/mm/pat.c:279 (verifying the range of the memory type). The call trace showed that it was mtdchar_mmap() that created an invalid remap_pfn_range(). The problem is that mtdchar_mmap() does various really odd and subtle things with the vma page offset etc, and uses the wrong types (and the wrong overflow) detection for it. For example, the page offset may well be 32-bit on a 32-bit architecture, but after shifting it up by PAGE_SHIFT, we need to use a potentially 64-bit resource_size_t to correctly hold the full value. Also, we need to check that the vma length plus offset doesn't overflow before we check that it is smaller than the length of the mtdmap region. This fixes things up and tries to make the code a bit easier to read. Reported-and-tested-by: Sasha Levin Acked-by: Suresh Siddha Acked-by: Artem Bityutskiy Cc: David Woodhouse Cc: linux-mtd@lists.infradead.org Signed-off-by: Linus Torvalds Cc: Ben Hutchings Cc: Brad Spengler Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/mtdchar.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 9f8658e..2434e9d 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -1064,6 +1064,33 @@ static unsigned long mtd_get_unmapped_area(struct file *file, } #endif +static inline unsigned long get_vm_size(struct vm_area_struct *vma) +{ + return vma->vm_end - vma->vm_start; +} + +static inline resource_size_t get_vm_offset(struct vm_area_struct *vma) +{ + return (resource_size_t) vma->vm_pgoff << PAGE_SHIFT; +} + +/* + * Set a new vm offset. + * + * Verify that the incoming offset really works as a page offset, + * and that the offset and size fit in a resource_size_t. + */ +static inline int set_vm_offset(struct vm_area_struct *vma, resource_size_t off) +{ + pgoff_t pgoff = off >> PAGE_SHIFT; + if (off != (resource_size_t) pgoff << PAGE_SHIFT) + return -EINVAL; + if (off + get_vm_size(vma) - 1 < off) + return -EINVAL; + vma->vm_pgoff = pgoff; + return 0; +} + /* * set up a mapping for shared memory segments */ @@ -1073,20 +1100,29 @@ static int mtd_mmap(struct file *file, struct vm_area_struct *vma) struct mtd_file_info *mfi = file->private_data; struct mtd_info *mtd = mfi->mtd; struct map_info *map = mtd->priv; - unsigned long start; - unsigned long off; - u32 len; + resource_size_t start, off; + unsigned long len, vma_len; if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) { - off = vma->vm_pgoff << PAGE_SHIFT; + off = get_vm_offset(vma); start = map->phys; len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size); start &= PAGE_MASK; - if ((vma->vm_end - vma->vm_start + off) > len) + vma_len = get_vm_size(vma); + + /* Overflow in off+len? */ + if (vma_len + off < off) + return -EINVAL; + /* Does it fit in the mapping? */ + if (vma_len + off > len) return -EINVAL; off += start; - vma->vm_pgoff = off >> PAGE_SHIFT; + /* Did that overflow? */ + if (off < start) + return -EINVAL; + if (set_vm_offset(vma, off) < 0) + return -EINVAL; vma->vm_flags |= VM_IO | VM_RESERVED; #ifdef pgprot_noncached -- cgit v1.1 From f0776cdd7c35a4b4ca7b80e6afc4ecd0d26831d7 Mon Sep 17 00:00:00 2001 From: Hayes Wang Date: Sat, 13 Apr 2013 12:26:55 +0200 Subject: r8169: fix auto speed down issue commit e2409d83434d77874b461b78af6a19cd6e6a1280 upstream. It would cause no link after suspending or shutdowning when the nic changes the speed to 10M and connects to a link partner which forces the speed to 100M. Check the link partner ability to determine which speed to set. The link speed down code path is not factored in this kernel version. Signed-off-by: Hayes Wang Acked-by: Francois Romieu Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/r8169.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 80b230e..8350f8d 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -3105,11 +3105,34 @@ static void r810x_phy_power_up(struct rtl8169_private *tp) rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE); } +static void rtl_speed_down(struct rtl8169_private *tp) +{ + u32 adv; + int lpa; + + rtl_writephy(tp, 0x1f, 0x0000); + lpa = rtl_readphy(tp, MII_LPA); + + if (lpa & (LPA_10HALF | LPA_10FULL)) + adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full; + else if (lpa & (LPA_100HALF | LPA_100FULL)) + adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; + else + adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | + (tp->mii.supports_gmii ? + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full : 0); + + rtl8169_set_speed(tp->dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL, + adv); +} + static void r810x_pll_power_down(struct rtl8169_private *tp) { if (__rtl8169_get_wol(tp) & WAKE_ANY) { - rtl_writephy(tp, 0x1f, 0x0000); - rtl_writephy(tp, MII_BMCR, 0x0000); + rtl_speed_down(tp); return; } @@ -3201,8 +3224,7 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) rtl_ephy_write(ioaddr, 0x19, 0xff64); if (__rtl8169_get_wol(tp) & WAKE_ANY) { - rtl_writephy(tp, 0x1f, 0x0000); - rtl_writephy(tp, MII_BMCR, 0x0000); + rtl_speed_down(tp); if (tp->mac_version == RTL_GIGA_MAC_VER_32 || tp->mac_version == RTL_GIGA_MAC_VER_33) -- cgit v1.1 From c6c8807630f086872b446cc66752a1835df5e9d7 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 9 Oct 2012 15:08:10 +0100 Subject: mtd: Disable mtdchar mmap on MMU systems commit f5cf8f07423b2677cebebcebc863af77223a4972 upstream. This code was broken because it assumed that all MTD devices were map-based. Disable it for now, until it can be fixed properly for the next merge window. Signed-off-by: David Woodhouse Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/mtdchar.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 2434e9d..9892dcc 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -1103,7 +1103,11 @@ static int mtd_mmap(struct file *file, struct vm_area_struct *vma) resource_size_t start, off; unsigned long len, vma_len; - if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) { + /* This is broken because it assumes the MTD device is map-based + and that mtd->priv is a valid struct map_info. It should be + replaced with something that uses the mtd_get_unmapped_area() + operation properly. */ + if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) { off = get_vm_offset(vma); start = map->phys; len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size); -- cgit v1.1 From 55fe10a686c3a8bce7bddc149e4ebb12f5a18c25 Mon Sep 17 00:00:00 2001 From: Christoph Fritz Date: Thu, 11 Apr 2013 21:32:57 +0200 Subject: can: sja1000: fix handling on dt properties on little endian systems commit 0443de5fbf224abf41f688d8487b0c307dc5a4b4 upstream. To get correct endianes on little endian cpus (like arm) while reading device tree properties, this patch replaces of_get_property() with of_property_read_u32(). While there use of_property_read_bool() for the handling of the boolean "nxp,no-comparator-bypass" property. Signed-off-by: Christoph Fritz Signed-off-by: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/sja1000/sja1000_of_platform.c | 31 +++++++++++++-------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c index 9793df6..877836f 100644 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/drivers/net/can/sja1000/sja1000_of_platform.c @@ -93,8 +93,8 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev) struct net_device *dev; struct sja1000_priv *priv; struct resource res; - const u32 *prop; - int err, irq, res_size, prop_size; + u32 prop; + int err, irq, res_size; void __iomem *base; err = of_address_to_resource(np, 0, &res); @@ -135,27 +135,27 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev) priv->read_reg = sja1000_ofp_read_reg; priv->write_reg = sja1000_ofp_write_reg; - prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size); - if (prop && (prop_size == sizeof(u32))) - priv->can.clock.freq = *prop / 2; + err = of_property_read_u32(np, "nxp,external-clock-frequency", &prop); + if (!err) + priv->can.clock.freq = prop / 2; else priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */ - prop = of_get_property(np, "nxp,tx-output-mode", &prop_size); - if (prop && (prop_size == sizeof(u32))) - priv->ocr |= *prop & OCR_MODE_MASK; + err = of_property_read_u32(np, "nxp,tx-output-mode", &prop); + if (!err) + priv->ocr |= prop & OCR_MODE_MASK; else priv->ocr |= OCR_MODE_NORMAL; /* default */ - prop = of_get_property(np, "nxp,tx-output-config", &prop_size); - if (prop && (prop_size == sizeof(u32))) - priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK; + err = of_property_read_u32(np, "nxp,tx-output-config", &prop); + if (!err) + priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK; else priv->ocr |= OCR_TX0_PULLDOWN; /* default */ - prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size); - if (prop && (prop_size == sizeof(u32)) && *prop) { - u32 divider = priv->can.clock.freq * 2 / *prop; + err = of_property_read_u32(np, "nxp,clock-out-frequency", &prop); + if (!err && prop) { + u32 divider = priv->can.clock.freq * 2 / prop; if (divider > 1) priv->cdr |= divider / 2 - 1; @@ -165,8 +165,7 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev) priv->cdr |= CDR_CLK_OFF; /* default */ } - prop = of_get_property(np, "nxp,no-comparator-bypass", NULL); - if (!prop) + if (!of_property_read_bool(np, "nxp,no-comparator-bypass")) priv->cdr |= CDR_CBP; /* default */ priv->irq_flags = IRQF_SHARED; -- cgit v1.1 From 0a9cb8d371991dceed054aec71541653e330180f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 7 Apr 2013 21:10:48 +0200 Subject: ath9k_htc: accept 1.x firmware newer than 1.3 commit 319e7bd96aca64a478f3aad40711c928405b8b77 upstream. Since the firmware has been open sourced, the minor version has been bumped to 1.4 and the API/ABI will stay compatible across further 1.x releases. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 61e6d39..4099712 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -823,7 +823,7 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv) * required version. */ if (priv->fw_version_major != MAJOR_VERSION_REQ || - priv->fw_version_minor != MINOR_VERSION_REQ) { + priv->fw_version_minor < MINOR_VERSION_REQ) { dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n", MAJOR_VERSION_REQ, MINOR_VERSION_REQ); return -EINVAL; -- cgit v1.1 From 22fd0f0bb5e791b7cd5b5e0c7d4c2172c722844d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 25 Jan 2013 11:38:56 +1000 Subject: fbcon: fix locking harder commit 054430e773c9a1e26f38e30156eff02dedfffc17 upstream. Okay so Alan's patch handled the case where there was no registered fbcon, however the other path entered in set_con2fb_map pit. In there we called fbcon_takeover, but we also took the console lock in a couple of places. So push the console lock out to the callers of set_con2fb_map, this means fbmem and switcheroo needed to take the lock around the fb notifier entry points that lead to this. This should fix the efifb regression seen by Maarten. Tested-by: Maarten Lankhorst Tested-by: Lu Hua Signed-off-by: Dave Airlie Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/vga/vga_switcheroo.c | 3 +++ drivers/video/console/fbcon.c | 11 ++++++++--- drivers/video/fbmem.c | 2 ++ 3 files changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 58434e8..37fe246 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -26,6 +26,7 @@ #include #include +#include #include struct vga_switcheroo_client { @@ -256,8 +257,10 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) if (new_client->fb_info) { struct fb_event event; + console_lock(); event.info = new_client->fb_info; fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event); + console_unlock(); } ret = vgasr_priv.handler->switchto(new_client->id); diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 9b8bcab..7a36dff 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -843,6 +843,8 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info, * * Maps a virtual console @unit to a frame buffer device * @newidx. + * + * This should be called with the console lock held. */ static int set_con2fb_map(int unit, int newidx, int user) { @@ -860,7 +862,7 @@ static int set_con2fb_map(int unit, int newidx, int user) if (!search_for_mapped_con() || !con_is_bound(&fb_con)) { info_idx = newidx; - return fbcon_takeover(0); + return do_fbcon_takeover(0); } if (oldidx != -1) @@ -868,7 +870,6 @@ static int set_con2fb_map(int unit, int newidx, int user) found = search_fb_in_map(newidx); - console_lock(); con2fb_map[unit] = newidx; if (!err && !found) err = con2fb_acquire_newinfo(vc, info, unit, oldidx); @@ -895,7 +896,6 @@ static int set_con2fb_map(int unit, int newidx, int user) if (!search_fb_in_map(info_idx)) info_idx = newidx; - console_unlock(); return err; } @@ -3026,6 +3026,7 @@ static inline int fbcon_unbind(void) } #endif /* CONFIG_VT_HW_CONSOLE_BINDING */ +/* called with console_lock held */ static int fbcon_fb_unbind(int idx) { int i, new_idx = -1, ret = 0; @@ -3052,6 +3053,7 @@ static int fbcon_fb_unbind(int idx) return ret; } +/* called with console_lock held */ static int fbcon_fb_unregistered(struct fb_info *info) { int i, idx; @@ -3089,6 +3091,7 @@ static int fbcon_fb_unregistered(struct fb_info *info) return 0; } +/* called with console_lock held */ static void fbcon_remap_all(int idx) { int i; @@ -3133,6 +3136,7 @@ static inline void fbcon_select_primary(struct fb_info *info) } #endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */ +/* called with console_lock held */ static int fbcon_fb_registered(struct fb_info *info) { int ret = 0, i, idx; @@ -3285,6 +3289,7 @@ static int fbcon_event_notify(struct notifier_block *self, ret = fbcon_fb_unregistered(info); break; case FB_EVENT_SET_CONSOLE_MAP: + /* called with console lock held */ con2fb = event->data; ret = set_con2fb_map(con2fb->console - 1, con2fb->framebuffer, 1); diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index c133dde..babbb07 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1154,8 +1154,10 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, event.data = &con2fb; if (!lock_fb_info(info)) return -ENODEV; + console_lock(); event.info = info; ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event); + console_unlock(); unlock_fb_info(info); break; case FBIOBLANK: -- cgit v1.1 From 03a850de03bfed25270d20918ee02d9f0dbb1f21 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 19 Apr 2013 09:57:35 -0700 Subject: vm: convert fb_mmap to vm_iomap_memory() helper commit fc9bbca8f650e5f738af8806317c0a041a48ae4a upstream. This is my example conversion of a few existing mmap users. The fb_mmap() case is a good example because it is a bit more complicated than some: fb_mmap() mmaps one of two different memory areas depending on the page offset of the mmap (but happily there is never any mixing of the two, so the helper function still works). Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/video/fbmem.c | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index babbb07..0a22808 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1350,15 +1350,12 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) { struct fb_info *info = file_fb_info(file); struct fb_ops *fb; - unsigned long off; + unsigned long mmio_pgoff; unsigned long start; u32 len; if (!info) return -ENODEV; - if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) - return -EINVAL; - off = vma->vm_pgoff << PAGE_SHIFT; fb = info->fbops; if (!fb) return -ENODEV; @@ -1370,33 +1367,24 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) return res; } - /* frame buffer memory */ + /* + * Ugh. This can be either the frame buffer mapping, or + * if pgoff points past it, the mmio mapping. + */ start = info->fix.smem_start; - len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len); - if (off >= len) { - /* memory mapped io */ - off -= len; - if (info->var.accel_flags) { - mutex_unlock(&info->mm_lock); - return -EINVAL; - } + len = info->fix.smem_len; + mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT; + if (vma->vm_pgoff >= mmio_pgoff) { + vma->vm_pgoff -= mmio_pgoff; start = info->fix.mmio_start; - len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); + len = info->fix.mmio_len; } mutex_unlock(&info->mm_lock); - start &= PAGE_MASK; - if ((vma->vm_end - vma->vm_start + off) > len) - return -EINVAL; - off += start; - vma->vm_pgoff = off >> PAGE_SHIFT; - /* This is an IO map - tell maydump to skip this VMA */ - vma->vm_flags |= VM_IO | VM_RESERVED; + vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); - fb_pgprotect(file, vma, off); - if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, vma->vm_page_prot)) - return -EAGAIN; - return 0; + fb_pgprotect(file, vma, start); + + return vm_iomap_memory(vma, start, len); } static int -- cgit v1.1 From 102fe50d961cf56eb764959783485193884ab1e6 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 19 Apr 2013 09:46:39 -0700 Subject: vm: convert HPET mmap to vm_iomap_memory() helper commit 2323036dfec8ce3ce6e1c86a49a31b039f3300d1 upstream. This is my example conversion of a few existing mmap users. The HPET case is simple, widely available, and easy to test (Clemens Ladisch sent a trivial test-program for it). Test-program-by: Clemens Ladisch Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/char/hpet.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 34d6a1c..853f8e8 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -374,26 +374,14 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma) struct hpet_dev *devp; unsigned long addr; - if (((vma->vm_end - vma->vm_start) != PAGE_SIZE) || vma->vm_pgoff) - return -EINVAL; - devp = file->private_data; addr = devp->hd_hpets->hp_hpet_phys; if (addr & (PAGE_SIZE - 1)) return -ENOSYS; - vma->vm_flags |= VM_IO; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, - PAGE_SIZE, vma->vm_page_prot)) { - printk(KERN_ERR "%s: io_remap_pfn_range failed\n", - __func__); - return -EAGAIN; - } - - return 0; + return vm_iomap_memory(vma, addr, PAGE_SIZE); #else return -ENOSYS; #endif -- cgit v1.1 From 856398d852436111d5cdbf30374f576671903998 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 19 Apr 2013 09:53:07 -0700 Subject: vm: convert mtdchar mmap to vm_iomap_memory() helper commit 8558e4a26b00225efeb085725bc319f91201b239 upstream. This is my example conversion of a few existing mmap users. The mtdchar case is actually disabled right now (and stays disabled), but I did it because it showed up on my "git grep", and I was familiar with the code due to fixing an overflow problem in the code in commit 9c603e53d380 ("mtdchar: fix offset overflow detection"). Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/mtd/mtdchar.c | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 9892dcc..72b788e 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -1100,45 +1100,17 @@ static int mtd_mmap(struct file *file, struct vm_area_struct *vma) struct mtd_file_info *mfi = file->private_data; struct mtd_info *mtd = mfi->mtd; struct map_info *map = mtd->priv; - resource_size_t start, off; - unsigned long len, vma_len; /* This is broken because it assumes the MTD device is map-based and that mtd->priv is a valid struct map_info. It should be replaced with something that uses the mtd_get_unmapped_area() operation properly. */ if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) { - off = get_vm_offset(vma); - start = map->phys; - len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size); - start &= PAGE_MASK; - vma_len = get_vm_size(vma); - - /* Overflow in off+len? */ - if (vma_len + off < off) - return -EINVAL; - /* Does it fit in the mapping? */ - if (vma_len + off > len) - return -EINVAL; - - off += start; - /* Did that overflow? */ - if (off < start) - return -EINVAL; - if (set_vm_offset(vma, off) < 0) - return -EINVAL; - vma->vm_flags |= VM_IO | VM_RESERVED; - #ifdef pgprot_noncached - if (file->f_flags & O_DSYNC || off >= __pa(high_memory)) + if (file->f_flags & O_DSYNC || map->phys >= __pa(high_memory)) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); #endif - if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, - vma->vm_page_prot)) - return -EAGAIN; - - return 0; + return vm_iomap_memory(vma, map->phys, map->size); } return -ENOSYS; #else -- cgit v1.1 From 6dd4ef3051173062350a4c53a2c4212d3f052e0c Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 15 Feb 2013 15:25:05 +0100 Subject: TTY: do not update atime/mtime on read/write commit b0de59b5733d18b0d1974a060860a8b5c1b36a2e upstream. On http://vladz.devzero.fr/013_ptmx-timing.php, we can see how to find out length of a password using timestamps of /dev/ptmx. It is documented in "Timing Analysis of Keystrokes and Timing Attacks on SSH". To avoid that problem, do not update time when reading from/writing to a TTY. I am afraid of regressions as this is a behavior we have since 0.97 and apps may expect the time to be current, e.g. for monitoring whether there was a change on the TTY. Now, there is no change. So this would better have a lot of testing before it goes upstream. References: CVE-2013-0160 Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b44aef0..3855ec1 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -975,8 +975,7 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, else i = -EIO; tty_ldisc_deref(ld); - if (i > 0) - inode->i_atime = current_fs_time(inode->i_sb); + return i; } @@ -1077,11 +1076,8 @@ static inline ssize_t do_tty_write( break; cond_resched(); } - if (written) { - struct inode *inode = file->f_path.dentry->d_inode; - inode->i_mtime = current_fs_time(inode->i_sb); + if (written) ret = written; - } out: tty_write_unlock(tty); return ret; -- cgit v1.1 From 061bd83c6fd1c22fbcf0357d4b7e306ba5ea8591 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 26 Apr 2013 13:48:53 +0200 Subject: TTY: fix atime/mtime regression commit 37b7f3c76595e23257f61bd80b223de8658617ee upstream. In commit b0de59b5733d ("TTY: do not update atime/mtime on read/write") we removed timestamps from tty inodes to fix a security issue and waited if something breaks. Well, 'w', the utility to find out logged users and their inactivity time broke. It shows that users are inactive since the time they logged in. To revert to the old behaviour while still preventing attackers to guess the password length, we update the timestamps in one-minute intervals by this patch. Signed-off-by: Jiri Slaby Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 3855ec1..612432e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -939,6 +939,14 @@ void start_tty(struct tty_struct *tty) EXPORT_SYMBOL(start_tty); +static void tty_update_time(struct timespec *time) +{ + unsigned long sec = get_seconds(); + sec -= sec % 60; + if ((long)(sec - time->tv_sec) > 0) + time->tv_sec = sec; +} + /** * tty_read - read method for tty device files * @file: pointer to tty file @@ -976,6 +984,9 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, i = -EIO; tty_ldisc_deref(ld); + if (i > 0) + tty_update_time(&inode->i_atime); + return i; } @@ -1076,8 +1087,11 @@ static inline ssize_t do_tty_write( break; cond_resched(); } - if (written) + if (written) { + struct inode *inode = file->f_path.dentry->d_inode; + tty_update_time(&inode->i_mtime); ret = written; + } out: tty_write_unlock(tty); return ret; -- cgit v1.1 From abd70dfd7e1df706a70fb9fa7d7777cf4428fe2c Mon Sep 17 00:00:00 2001 From: Hannes Frederic Sowa Date: Tue, 2 Apr 2013 14:36:46 +0000 Subject: atl1e: limit gso segment size to prevent generation of wrong ip length fields [ Upstream commit 31d1670e73f4911fe401273a8f576edc9c2b5fea ] The limit of 0x3c00 is taken from the windows driver. Suggested-by: Huang, Xiong Cc: Huang, Xiong Cc: Eric Dumazet Signed-off-by: Hannes Frederic Sowa Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/atl1e/atl1e.h | 2 +- drivers/net/atl1e/atl1e_main.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/atl1e/atl1e.h b/drivers/net/atl1e/atl1e.h index 4093097..2cec0df 100644 --- a/drivers/net/atl1e/atl1e.h +++ b/drivers/net/atl1e/atl1e.h @@ -186,7 +186,7 @@ struct atl1e_tpd_desc { /* how about 0x2000 */ #define MAX_TX_BUF_LEN 0x2000 #define MAX_TX_BUF_SHIFT 13 -/*#define MAX_TX_BUF_LEN 0x3000 */ +#define MAX_TSO_SEG_SIZE 0x3c00 /* rrs word 1 bit 0:31 */ #define RRS_RX_CSUM_MASK 0xFFFF diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index b0132bb..8fe1cd3 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -2333,6 +2333,7 @@ static int __devinit atl1e_probe(struct pci_dev *pdev, INIT_WORK(&adapter->reset_task, atl1e_reset_task); INIT_WORK(&adapter->link_chg_task, atl1e_link_chg_task); + netif_set_gso_max_size(netdev, MAX_TSO_SEG_SIZE); err = register_netdev(netdev); if (err) { netdev_err(netdev, "register netdevice failed\n"); -- cgit v1.1 From 3c53e8d24e96e85acf028dc4ccb1e60a5486f47d Mon Sep 17 00:00:00 2001 From: "nikolay@redhat.com" Date: Thu, 11 Apr 2013 09:18:56 +0000 Subject: bonding: IFF_BONDING is not stripped on enslave failure [ Upstream commit b6a5a7b9a528a8b4c8bec940b607c5dd9102b8cc ] While enslaving a new device and after IFF_BONDING flag is set, in case of failure it is not stripped from the device's priv_flags while cleaning up, which could lead to other problems. Cleaning at err_close because the flag is set after dev_open(). v2: no change Signed-off-by: Nikolay Aleksandrov Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index dd433a7..f271e44 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1949,6 +1949,7 @@ err_detach: write_unlock_bh(&bond->lock); err_close: + slave_dev->priv_flags &= ~IFF_BONDING; dev_close(slave_dev); err_unset_master: -- cgit v1.1 From 5e0c24d1ff9f94c0c1721b4b00b927aa6ecfe8fc Mon Sep 17 00:00:00 2001 From: Filippo Turato Date: Sat, 20 Apr 2013 15:04:08 +0200 Subject: USB: serial: option: Added support Olivetti Olicard 145 commit d19bf5cedfd7d53854a3bd699c98b467b139833b upstream. This adds PID for Olivetti Olicard 145 in option.c Signed-off-by: Filippo Turato Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 4418538..93b56af 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -347,6 +347,7 @@ static void option_instat_callback(struct urb *urb); /* Olivetti products */ #define OLIVETTI_VENDOR_ID 0x0b3c #define OLIVETTI_PRODUCT_OLICARD100 0xc000 +#define OLIVETTI_PRODUCT_OLICARD145 0xc003 /* Celot products */ #define CELOT_VENDOR_ID 0x211f @@ -1273,6 +1274,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) }, { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ -- cgit v1.1 From f4fd63017f8d28fa7719aebf1abca98f31685b2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Tue, 9 Apr 2013 11:26:02 +0200 Subject: USB: option: add a D-Link DWM-156 variant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit a2a2d6c7f93e160b52a4ad0164db1f43f743ae0f upstream. Adding support for a Mediatek based device labelled as D-Link Model: DWM-156, H/W Ver: A7 Also adding two other device IDs found in the Debian(!) packages included on the embedded device driver CD. This is a composite MBIM + serial ports + card reader device: T: Bus=04 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 14 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2001 ProdID=7d01 Rev= 3.00 S: Manufacturer=D-Link,Inc S: Product=D-Link DWM-156 C:* #Ifs= 7 Cfg#= 1 Atr=a0 MxPwr=500mA A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00 I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=88(I) Atr=03(Int.) MxPS= 64 Ivl=125us I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=02 Prot=01 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 64 Ivl=500us E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 6 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 93b56af..8513f51 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1352,6 +1352,12 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x02, 0x01) }, /* D-Link DWM-156 (variant) */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x00, 0x00) }, /* D-Link DWM-156 (variant) */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x02, 0x01) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); -- cgit v1.1 From 6f3894d0531ec8aa8c111919af5f5d5c997d5106 Mon Sep 17 00:00:00 2001 From: Ben Jencks Date: Tue, 2 Apr 2013 00:35:08 -0400 Subject: usb/misc/appledisplay: Add 24" LED Cinema display commit e7d3b6e22c871ba36d052ca99bc8ceca4d546a60 upstream. Add the Apple 24" LED Cinema display to the supported devices. Signed-off-by: Ben Jencks Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/appledisplay.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 68ab460..0a70c98 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -63,6 +63,7 @@ static const struct usb_device_id appledisplay_table[] = { { APPLEDISPLAY_DEVICE(0x9219) }, { APPLEDISPLAY_DEVICE(0x921c) }, { APPLEDISPLAY_DEVICE(0x921d) }, + { APPLEDISPLAY_DEVICE(0x9236) }, /* Terminating entry */ { } -- cgit v1.1 From 525df18348e4c2a144b957f3ab6eb02386700f1b Mon Sep 17 00:00:00 2001 From: Stefani Seibold Date: Sun, 7 Apr 2013 12:08:55 +0200 Subject: USB: add ftdi_sio USB ID for GDM Boost V1.x commit 58f8b6c4fa5a13cb2ddb400e26e9e65766d71e38 upstream. This patch add a missing usb device id for the GDMBoost V1.x device The patch is against 3.9-rc5 Signed-off-by: Stefani Seibold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio_ids.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 132f114..669c4b8 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -195,6 +195,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_THROTTLE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GATEWAY_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_BOOST_PID) }, { USB_DEVICE(NEWPORT_VID, NEWPORT_AGILIS_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 809c03a..3012b17 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -74,6 +74,7 @@ #define FTDI_OPENDCC_THROTTLE_PID 0xBFDA #define FTDI_OPENDCC_GATEWAY_PID 0xBFDB #define FTDI_OPENDCC_GBM_PID 0xBFDC +#define FTDI_OPENDCC_GBM_BOOST_PID 0xBFDD /* NZR SEM 16+ USB (http://www.nzr.de) */ #define FTDI_NZR_SEM_USB_PID 0xC1E0 /* NZR SEM-LOG16+ */ -- cgit v1.1 From 131541cdce961e10b4a6f10246c19075ed845729 Mon Sep 17 00:00:00 2001 From: Adrian Thomasset Date: Tue, 23 Apr 2013 12:46:29 +0100 Subject: USB: ftdi_sio: correct ST Micro Connect Lite PIDs commit 9f06d15f8db6946e41f73196a122b84a37938878 upstream. The current ST Micro Connect Lite uses the FT4232H hi-speed quad USB UART FTDI chip. It is also possible to drive STM reference targets populated with an on-board JTAG debugger based on the FT2232H chip with the same STMicroelectronics tools. For this reason, the ST Micro Connect Lite PIDs should be ST_STMCLT_2232_PID: 0x3746 ST_STMCLT_4232_PID: 0x3747 Signed-off-by: Adrian Thomasset Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 4 +++- drivers/usb/serial/ftdi_sio_ids.h | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 669c4b8..0860007 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -877,7 +877,9 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) }, { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, - { USB_DEVICE(ST_VID, ST_STMCLT1030_PID), + { USB_DEVICE(ST_VID, ST_STMCLT_2232_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(ST_VID, ST_STMCLT_4232_PID), .driver_info = (kernel_ulong_t)&ftdi_stmclite_quirk }, { USB_DEVICE(FTDI_VID, FTDI_RF_R106) }, { USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID), diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 3012b17..2f86008 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -1151,7 +1151,8 @@ * STMicroelectonics */ #define ST_VID 0x0483 -#define ST_STMCLT1030_PID 0x3747 /* ST Micro Connect Lite STMCLT1030 */ +#define ST_STMCLT_2232_PID 0x3746 +#define ST_STMCLT_4232_PID 0x3747 /* * Papouch products (http://www.papouch.com/) -- cgit v1.1 From 60306774f3716df189a69d226d2a59fcf57b4aa9 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 16 Apr 2013 11:08:33 +0200 Subject: usbfs: Always allow ctrl requests with USB_RECIP_ENDPOINT on the ctrl ep commit 1361bf4b9f9ef45e628a5b89e0fd9bedfdcb7104 upstream. When usbfs receives a ctrl-request from userspace it calls check_ctrlrecip, which for a request with USB_RECIP_ENDPOINT tries to map this to an interface to see if this interface is claimed, except for ctrl-requests with a type of USB_TYPE_VENDOR. When trying to use this device: http://www.akaipro.com/eiepro redirected to a Windows vm running on qemu on top of Linux. The windows driver makes a ctrl-req with USB_TYPE_CLASS and USB_RECIP_ENDPOINT with index 0, and the mapping of the endpoint (0) to the interface fails since ep 0 is the ctrl endpoint and thus never is part of an interface. This patch fixes this ctrl-req failing by skipping the checkintf call for USB_RECIP_ENDPOINT ctrl-reqs on the ctrl endpoint. Reported-by: Dave Stikkolorum Tested-by: Dave Stikkolorum Signed-off-by: Hans de Goede Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 4d1f996..2bb9410 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -642,6 +642,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, index &= 0xff; switch (requesttype & USB_RECIP_MASK) { case USB_RECIP_ENDPOINT: + if ((index & ~USB_DIR_IN) == 0) + return 0; ret = findintfep(ps->dev, index); if (ret >= 0) ret = checkintf(ps, ret); -- cgit v1.1 From 42753c725c8233d5efbd682e34d0f3215a7c7aaa Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Sat, 20 Apr 2013 14:24:04 +0200 Subject: usb-storage: CY7C68300A chips do not support Cypress ATACB commit 671b4b2ba9266cbcfe7210a704e9ea487dcaa988 upstream. Many cards based on CY7C68300A/B/C use the USB ID 04b4:6830 but only the B and C variants (EZ-USB AT2LP) support the ATA Command Block functionality, according to the data sheets. The A variant (EZ-USB AT2) locks up if ATACB is attempted, until a typical 30 seconds timeout runs out and a USB reset is performed. https://bugs.launchpad.net/bugs/428469 It seems that one way to spot a CY7C68300A (at least where the card manufacturer left Cypress' EEPROM default vaules, against Cypress' recommendations) is to look at the USB string descriptor indices. A http://media.digikey.com/pdf/Data%20Sheets/Cypress%20PDFs/CY7C68300A.pdf B http://www.farnell.com/datasheets/43456.pdf C http://www.cypress.com/?rID=14189 Note that a CY7C68300B/C chip appears as CY7C68300A if it is running in Backward Compatibility Mode, and if ATACB would be supported in this case there is anyway no way to tell which chip it really is. For 5 years my external USB drive has been locking up for half a minute when plugged in and ata_id is run by udev, or anytime hdparm or similar is run on it. Finally looking at the /correct/ datasheet I think I found the reason. I am aware the quirk in this patch is a bit hacky, but the hardware manufacturers haven't made it easy for us. Signed-off-by: Tormod Volden Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/cypress_atacb.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c index c844718..7341ce2 100644 --- a/drivers/usb/storage/cypress_atacb.c +++ b/drivers/usb/storage/cypress_atacb.c @@ -248,14 +248,26 @@ static int cypress_probe(struct usb_interface *intf, { struct us_data *us; int result; + struct usb_device *device; result = usb_stor_probe1(&us, intf, id, (id - cypress_usb_ids) + cypress_unusual_dev_list); if (result) return result; - us->protocol_name = "Transparent SCSI with Cypress ATACB"; - us->proto_handler = cypress_atacb_passthrough; + /* Among CY7C68300 chips, the A revision does not support Cypress ATACB + * Filter out this revision from EEPROM default descriptor values + */ + device = interface_to_usbdev(intf); + if (device->descriptor.iManufacturer != 0x38 || + device->descriptor.iProduct != 0x4e || + device->descriptor.iSerialNumber != 0x64) { + us->protocol_name = "Transparent SCSI with Cypress ATACB"; + us->proto_handler = cypress_atacb_passthrough; + } else { + us->protocol_name = "Transparent SCSI"; + us->proto_handler = usb_stor_transparent_scsi_command; + } result = usb_stor_probe2(us); return result; -- cgit v1.1 From d44632e6253a87c8fdad2329b266cfc9c1d5c83c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 25 Apr 2013 10:03:15 +0200 Subject: s390/memory hotplug: prevent offline of active memory increments commit 94c163663fc1dcfc067a5fb3cc1446b9469975ce upstream. In case a machine supports memory hotplug all active memory increments present at IPL time have been initialized with a "usecount" of 1. This is wrong if the memory increment size is larger than the memory section size of the memory hotplug code. If that is the case the usecount must be initialized with the number of memory sections that fit into one memory increment. Otherwise it is possible to put a memory increment into standby state even if there are still active sections. Afterwards addressing exceptions might happen which cause the kernel to panic. However even worse, if a memory increment was put into standby state and afterwards into active state again, it's contents would have been zeroed, leading to memory corruption. This was only an issue for machines that support standby memory and have at least 256GB memory. This is broken since commit fdb1bb15 "[S390] sclp/memory hotplug: fix initial usecount of increments". Signed-off-by: Heiko Carstens Reviewed-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky Signed-off-by: Greg Kroah-Hartman --- drivers/s390/char/sclp_cmd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index be55fb2..a0ce2a9 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -507,6 +507,8 @@ static void __init sclp_add_standby_memory(void) add_memory_merged(0); } +#define MEM_SCT_SIZE (1UL << SECTION_SIZE_BITS) + static void __init insert_increment(u16 rn, int standby, int assigned) { struct memory_increment *incr, *new_incr; @@ -519,7 +521,7 @@ static void __init insert_increment(u16 rn, int standby, int assigned) new_incr->rn = rn; new_incr->standby = standby; if (!standby) - new_incr->usecount = 1; + new_incr->usecount = rzm > MEM_SCT_SIZE ? rzm/MEM_SCT_SIZE : 1; last_rn = 0; prev = &sclp_mem_list; list_for_each_entry(incr, &sclp_mem_list, list) { -- cgit v1.1 From 70f4184b8eeb04a2b8ad2778a76ffac3a0d4e4d2 Mon Sep 17 00:00:00 2001 From: Federico Vaga Date: Mon, 15 Apr 2013 16:01:07 +0200 Subject: serial_core.c: add put_device() after device_find_child() commit 5a65dcc04cda41f4122aacc37a5a348454645399 upstream. The serial core uses device_find_child() but does not drop the reference to the retrieved child after using it. This patch add the missing put_device(). What I have done to test this issue. I used a machine with an AMBA PL011 serial driver. I tested the patch on next-20120408 because the last branch [next-20120415] does not boot on this board. For test purpose, I added some pr_info() messages to print the refcount after device_find_child() (lines: 1937,2009), and after put_device() (lines: 1947, 2021). Boot the machine *without* put_device(). Then: echo reboot > /sys/power/disk echo disk > /sys/power/state [ 87.058575] uart_suspend_port:1937 refcount 4 [ 87.058582] uart_suspend_port:1947 refcount 4 [ 87.098083] uart_resume_port:2009refcount 5 [ 87.098088] uart_resume_port:2021 refcount 5 echo disk > /sys/power/state [ 103.055574] uart_suspend_port:1937 refcount 6 [ 103.055580] uart_suspend_port:1947 refcount 6 [ 103.095322] uart_resume_port:2009 refcount 7 [ 103.095327] uart_resume_port:2021 refcount 7 echo disk > /sys/power/state [ 252.459580] uart_suspend_port:1937 refcount 8 [ 252.459586] uart_suspend_port:1947 refcount 8 [ 252.499611] uart_resume_port:2009 refcount 9 [ 252.499616] uart_resume_port:2021 refcount 9 The refcount continuously increased. Boot the machine *with* this patch. Then: echo reboot > /sys/power/disk echo disk > /sys/power/state [ 159.333559] uart_suspend_port:1937 refcount 4 [ 159.333566] uart_suspend_port:1947 refcount 3 [ 159.372751] uart_resume_port:2009 refcount 4 [ 159.372755] uart_resume_port:2021 refcount 3 echo disk > /sys/power/state [ 185.713614] uart_suspend_port:1937 refcount 4 [ 185.713621] uart_suspend_port:1947 refcount 3 [ 185.752935] uart_resume_port:2009 refcount 4 [ 185.752940] uart_resume_port:2021 refcount 3 echo disk > /sys/power/state [ 207.458584] uart_suspend_port:1937 refcount 4 [ 207.458591] uart_suspend_port:1947 refcount 3 [ 207.498598] uart_resume_port:2009 refcount 4 [ 207.498605] uart_resume_port:2021 refcount 3 The refcount correctly handled. Signed-off-by: Federico Vaga Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index de5e33f..28630b6 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1917,6 +1917,8 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) mutex_unlock(&port->mutex); return 0; } + put_device(tty_dev); + if (console_suspend_enabled || !uart_console(uport)) uport->suspended = 1; @@ -1982,9 +1984,11 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) disable_irq_wake(uport->irq); uport->irq_wake = 0; } + put_device(tty_dev); mutex_unlock(&port->mutex); return 0; } + put_device(tty_dev); uport->suspended = 0; /* -- cgit v1.1 From 5022cf90d4bb8bed51c8176ce57ac7ccf87ed3d4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 1 May 2013 07:32:21 -0700 Subject: tty: fix up atime/mtime mess, take three commit b0b885657b6c8ef63a46bc9299b2a7715d19acde upstream. We first tried to avoid updating atime/mtime entirely (commit b0de59b5733d: "TTY: do not update atime/mtime on read/write"), and then limited it to only update it occasionally (commit 37b7f3c76595: "TTY: fix atime/mtime regression"), but it turns out that this was both insufficient and overkill. It was insufficient because we let people attach to the shared ptmx node to see activity without even reading atime/mtime, and it was overkill because the "only once a minute" means that you can't really tell an idle person from an active one with 'w'. So this tries to fix the problem properly. It marks the shared ptmx node as un-notifiable, and it lowers the "only once a minute" to a few seconds instead - still long enough that you can't time individual keystrokes, but short enough that you can tell whether somebody is active or not. Reported-by: Simon Kirby Acked-by: Jiri Slaby Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 3 +++ drivers/tty/tty_io.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index d19b879..4735928 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -669,6 +669,9 @@ static int ptmx_open(struct inode *inode, struct file *filp) nonseekable_open(inode, filp); + /* We refuse fsnotify events on ptmx, since it's a shared resource */ + filp->f_mode |= FMODE_NONOTIFY; + retval = tty_alloc_file(filp); if (retval) return retval; diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 612432e..cf32a5c 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -939,10 +939,10 @@ void start_tty(struct tty_struct *tty) EXPORT_SYMBOL(start_tty); +/* We limit tty time update visibility to every 8 seconds or so. */ static void tty_update_time(struct timespec *time) { - unsigned long sec = get_seconds(); - sec -= sec % 60; + unsigned long sec = get_seconds() & ~7; if ((long)(sec - time->tv_sec) > 0) time->tv_sec = sec; } -- cgit v1.1 From 02f1fef6377f64ae0ea5b542a39eddf1424b505d Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Mon, 22 Apr 2013 14:19:26 +0300 Subject: fbcon: when font is freed, clear also vc_font.data commit e6637d5427d2af9f3f33b95447bfc5347e5ccd85 upstream. commit ae1287865f5361fa138d4d3b1b6277908b54eac9 Author: Dave Airlie Date: Thu Jan 24 16:12:41 2013 +1000 fbcon: don't lose the console font across generic->chip driver switch uses a pointer in vc->vc_font.data to load font into the new driver. However if the font is actually freed, we need to clear the data so that we don't reload font from dangling pointer. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=892340 Signed-off-by: Mika Kuoppala Signed-off-by: Dave Airlie Signed-off-by: Greg Kroah-Hartman --- drivers/video/console/fbcon.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 7a36dff..6b4fb5c 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -1229,6 +1229,8 @@ static void fbcon_deinit(struct vc_data *vc) finished: fbcon_free_font(p, free_font); + if (free_font) + vc->vc_font.data = NULL; if (!con_is_bound(&fb_con)) fbcon_exit(); -- cgit v1.1 From 9702319c6eb4ebedc334ea5825ccce3b210c4a32 Mon Sep 17 00:00:00 2001 From: "Steven A. Falco" Date: Mon, 22 Apr 2013 09:34:39 +0000 Subject: i2c: xiic: must always write 16-bit words to TX_FIFO commit c39e8e4354ce4daf23336de5daa28a3b01f00aa6 upstream. The TX_FIFO register is 10 bits wide. The lower 8 bits are the data to be written, while the upper two bits are flags to indicate stop/start. The driver apparently attempted to optimize write access, by only writing a byte in those cases where the stop/start bits are zero. However, we have seen cases where the lower byte is duplicated onto the upper byte by the hardware, which causes inadvertent stop/starts. This patch changes the write access to the transmit FIFO to always be 16 bits wide. Signed off by: Steven A. Falco Signed-off-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-xiic.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index 4bb68f3..64e7065 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c @@ -311,10 +311,8 @@ static void xiic_fill_tx_fifo(struct xiic_i2c *i2c) /* last message in transfer -> STOP */ data |= XIIC_TX_DYN_STOP_MASK; dev_dbg(i2c->adap.dev.parent, "%s TX STOP\n", __func__); - - xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data); - } else - xiic_setreg8(i2c, XIIC_DTR_REG_OFFSET, data); + } + xiic_setreg16(i2c, XIIC_DTR_REG_OFFSET, data); } } -- cgit v1.1 From 3c567a40a1538c96c7cfaa86d944301203e2810d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 28 Mar 2013 04:28:58 +0000 Subject: PCI / ACPI: Don't query OSC support with all possible controls commit 545d6e189a41c94c11f55045a771118eccc9d9eb upstream. Found problem on system that firmware that could handle pci aer. Firmware get error reporting after pci injecting error, before os boots. But after os boots, firmware can not get report anymore, even pci=noaer is passed. Root cause: BIOS _OSC has problem with query bit checking. It turns out that BIOS vendor is copying example code from ACPI Spec. In ACPI Spec 5.0, page 290: If (Not(And(CDW1,1))) // Query flag clear? { // Disable GPEs for features granted native control. If (And(CTRL,0x01)) // Hot plug control granted? { Store(0,HPCE) // clear the hot plug SCI enable bit Store(1,HPCS) // clear the hot plug SCI status bit } ... } When Query flag is set, And(CDW1,1) will be 1, Not(1) will return 0xfffffffe. So it will get into code path that should be for control set only. BIOS acpi code should be changed to "If (LEqual(And(CDW1,1), 0)))" Current kernel code is using _OSC query to notify firmware about support from OS and then use _OSC to set control bits. During query support, current code is using all possible controls. So will execute code that should be only for control set stage. That will have problem when pci=noaer or aer firmware_first is used. As firmware have that control set for os aer already in query support stage, but later will not os aer handling. We should avoid passing all possible controls, just use osc_control_set instead. That should workaround BIOS bugs with affected systems on the field as more bios vendors are copying sample code from ACPI spec. Signed-off-by: Yinghai Lu Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/pci_root.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index dfafecb..ea89d85 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -247,8 +247,8 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, *control &= OSC_PCI_CONTROL_MASKS; capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set; } else { - /* Run _OSC query for all possible controls. */ - capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS; + /* Run _OSC query only with existing controls. */ + capbuf[OSC_CONTROL_TYPE] = root->osc_control_set; } status = acpi_pci_run_osc(root->device->handle, capbuf, &result); -- cgit v1.1 From 10eb78f693be5d924d8ae19264efc8da2d6cb8a3 Mon Sep 17 00:00:00 2001 From: Derek Basehore Date: Mon, 29 Apr 2013 16:20:23 -0700 Subject: drivers/rtc/rtc-cmos.c: don't disable hpet emulation on suspend commit e005715efaf674660ae59af83b13822567e3a758 upstream. There's a bug where rtc alarms are ignored after the rtc cmos suspends but before the system finishes suspend. Since hpet emulation is disabled and it still handles the interrupts, a wake event is never registered which is done from the rtc layer. This patch reverts commit d1b2efa83fbf ("rtc: disable hpet emulation on suspend") which disabled hpet emulation. To fix the problem mentioned in that commit, hpet_rtc_timer_init() is called directly on resume. Signed-off-by: Derek Basehore Cc: Maxim Levitsky Cc: "H. Peter Anvin" Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "Rafael J. Wysocki" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-cmos.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 911e75c..cd61178 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -805,9 +805,8 @@ static int cmos_suspend(struct device *dev) mask = RTC_IRQMASK; tmp &= ~mask; CMOS_WRITE(tmp, RTC_CONTROL); + hpet_mask_rtc_irq_bit(mask); - /* shut down hpet emulation - we don't need it for alarm */ - hpet_mask_rtc_irq_bit(RTC_PIE|RTC_AIE|RTC_UIE); cmos_checkintr(cmos, tmp); } spin_unlock_irq(&rtc_lock); @@ -872,6 +871,7 @@ static int cmos_resume(struct device *dev) rtc_update_irq(cmos->rtc, 1, mask); tmp &= ~RTC_AIE; hpet_mask_rtc_irq_bit(RTC_AIE); + hpet_rtc_timer_init(); } while (mask & RTC_AIE); spin_unlock_irq(&rtc_lock); } -- cgit v1.1 From 92e5cc743134cec1532b43fa2b97340effd956a8 Mon Sep 17 00:00:00 2001 From: Philip Rakity Date: Thu, 4 Apr 2013 20:18:11 +0100 Subject: mmc: core: Fix bit width test failing on old eMMC cards commit 836dc2fe89c968c10cada87e0dfae6626f8f9da3 upstream. PARTITION_SUPPORT needs to be set before doing the compare on version number so the bit width test does not get invalid data. Before this patch, a Sandisk iNAND eMMC card would detect 1-bit width although the hardware supports 4-bit. Only affects old emmc devices - pre 4.4 devices. Reported-by: Elad Yi Signed-off-by: Philip Rakity Signed-off-by: Chris Ball Signed-off-by: Greg Kroah-Hartman --- drivers/mmc/core/mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index f601180..0216df2 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -353,13 +353,13 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; card->ext_csd.raw_trim_mult = ext_csd[EXT_CSD_TRIM_MULT]; + card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT]; if (card->ext_csd.rev >= 4) { /* * Enhanced area feature support -- check whether the eMMC * card has the Enhanced area enabled. If so, export enhanced * area offset and size to user by adding sysfs interface. */ - card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT]; if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { u8 hc_erase_grp_sz = -- cgit v1.1 From eadb89490b7b35a5fbb169dfc59e7a3d07b4c492 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Feb 2013 11:51:22 +0100 Subject: mfd: adp5520: Restore mode bits on resume commit c6cc25fda58da8685ecef3f179adc7b99c8253b2 upstream. The adp5520 unfortunately also clears the BL_EN bit when the nSTNDBY bit is cleared. So we need to make sure to restore it during resume if it was set before suspend. Signed-off-by: Lars-Peter Clausen Acked-by: Michael Hennerich Signed-off-by: Samuel Ortiz Signed-off-by: Greg Kroah-Hartman --- drivers/mfd/adp5520.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c index f1d8848..2943fbf 100644 --- a/drivers/mfd/adp5520.c +++ b/drivers/mfd/adp5520.c @@ -36,6 +36,7 @@ struct adp5520_chip { struct blocking_notifier_head notifier_list; int irq; unsigned long id; + uint8_t mode; }; static int __adp5520_read(struct i2c_client *client, @@ -326,7 +327,10 @@ static int adp5520_suspend(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct adp5520_chip *chip = dev_get_drvdata(&client->dev); - adp5520_clr_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); + adp5520_read(chip->dev, ADP5520_MODE_STATUS, &chip->mode); + /* All other bits are W1C */ + chip->mode &= ADP5520_BL_EN | ADP5520_DIM_EN | ADP5520_nSTNBY; + adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0); return 0; } @@ -335,7 +339,7 @@ static int adp5520_resume(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct adp5520_chip *chip = dev_get_drvdata(&client->dev); - adp5520_set_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); + adp5520_write(chip->dev, ADP5520_MODE_STATUS, chip->mode); return 0; } #endif -- cgit v1.1 From 97a0b301f6520690724602497c699890144ccff6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 6 May 2013 11:30:43 -0700 Subject: Revert :can: sja1000: fix handling on dt properties on little endian systems" This reverts commit 55fe10a686c3a8bce7bddc149e4ebb12f5a18c25 which is commit 0443de5fbf224abf41f688d8487b0c307dc5a4b4 upstream. This causes a build breakage on 3.0, so we shouldn't apply it to that tree. Reported-by: Jiri Slaby Cc: Christoph Fritz Cc: Marc Kleine-Budde Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/sja1000/sja1000_of_platform.c | 31 ++++++++++++++------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c index 877836f..9793df6 100644 --- a/drivers/net/can/sja1000/sja1000_of_platform.c +++ b/drivers/net/can/sja1000/sja1000_of_platform.c @@ -93,8 +93,8 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev) struct net_device *dev; struct sja1000_priv *priv; struct resource res; - u32 prop; - int err, irq, res_size; + const u32 *prop; + int err, irq, res_size, prop_size; void __iomem *base; err = of_address_to_resource(np, 0, &res); @@ -135,27 +135,27 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev) priv->read_reg = sja1000_ofp_read_reg; priv->write_reg = sja1000_ofp_write_reg; - err = of_property_read_u32(np, "nxp,external-clock-frequency", &prop); - if (!err) - priv->can.clock.freq = prop / 2; + prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size); + if (prop && (prop_size == sizeof(u32))) + priv->can.clock.freq = *prop / 2; else priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */ - err = of_property_read_u32(np, "nxp,tx-output-mode", &prop); - if (!err) - priv->ocr |= prop & OCR_MODE_MASK; + prop = of_get_property(np, "nxp,tx-output-mode", &prop_size); + if (prop && (prop_size == sizeof(u32))) + priv->ocr |= *prop & OCR_MODE_MASK; else priv->ocr |= OCR_MODE_NORMAL; /* default */ - err = of_property_read_u32(np, "nxp,tx-output-config", &prop); - if (!err) - priv->ocr |= (prop << OCR_TX_SHIFT) & OCR_TX_MASK; + prop = of_get_property(np, "nxp,tx-output-config", &prop_size); + if (prop && (prop_size == sizeof(u32))) + priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK; else priv->ocr |= OCR_TX0_PULLDOWN; /* default */ - err = of_property_read_u32(np, "nxp,clock-out-frequency", &prop); - if (!err && prop) { - u32 divider = priv->can.clock.freq * 2 / prop; + prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size); + if (prop && (prop_size == sizeof(u32)) && *prop) { + u32 divider = priv->can.clock.freq * 2 / *prop; if (divider > 1) priv->cdr |= divider / 2 - 1; @@ -165,7 +165,8 @@ static int __devinit sja1000_ofp_probe(struct platform_device *ofdev) priv->cdr |= CDR_CLK_OFF; /* default */ } - if (!of_property_read_bool(np, "nxp,no-comparator-bypass")) + prop = of_get_property(np, "nxp,no-comparator-bypass", NULL); + if (!prop) priv->cdr |= CDR_CBP; /* default */ priv->irq_flags = IRQF_SHARED; -- cgit v1.1 From df859ddd0675a729e4108da5bd9c3ac9618441f2 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Wed, 3 Apr 2013 14:34:11 +0200 Subject: drm/i915: Add no-lvds quirk for Fujitsu Esprimo Q900 commit 9e9dd0e889c76c786e8f2e164c825c3c06dea30c upstream. The "Mobile Sandy Bridge CPUs" in the Fujitsu Esprimo Q900 mini desktop PCs are probably misleading the LVDS detection code in intel_lvds_supported. Nothing is connected to the LVDS ports in these systems. Signed-off-by: Christian Lamparter Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_lvds.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index eebf002..09881ac 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -767,6 +767,14 @@ static const struct dmi_system_id intel_no_lvds[] = { DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"), }, }, + { + .callback = intel_no_lvds_dmi_callback, + .ident = "Fujitsu Esprimo Q900", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Q900"), + }, + }, { } /* terminating entry */ }; -- cgit v1.1 From c2fde23d77ebcf4577fdd703af8b1600f3c87f69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20M=C3=BCller?= Date: Fri, 19 Apr 2013 10:41:50 +0200 Subject: drm/i915: Fall back to bit banging mode for DVO transmitter detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e4bfff54ed3f5de88f5358504c78c2cb037813aa upstream. As discussed in this thread http://lists.freedesktop.org/archives/dri-devel/2013-April/037411.html GMBUS based DVO transmitter detection seems to be unreliable which could result in an unusable DVO port. The attached patch fixes this by falling back to bit banging mode for the time DVO transmitter detection is in progress. Signed-off-by: David Müller Tested-by: David Müller Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_dvo.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 6eda1b5..8ac91b8 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -371,6 +371,7 @@ void intel_dvo_init(struct drm_device *dev) const struct intel_dvo_device *dvo = &intel_dvo_devices[i]; struct i2c_adapter *i2c; int gpio; + bool dvoinit; /* Allow the I2C driver info to specify the GPIO to be used in * special cases, but otherwise default to what's defined @@ -390,7 +391,17 @@ void intel_dvo_init(struct drm_device *dev) i2c = &dev_priv->gmbus[gpio].adapter; intel_dvo->dev = *dvo; - if (!dvo->dev_ops->init(&intel_dvo->dev, i2c)) + + /* GMBUS NAK handling seems to be unstable, hence let the + * transmitter detection run in bit banging mode for now. + */ + intel_gmbus_force_bit(i2c, true); + + dvoinit = dvo->dev_ops->init(&intel_dvo->dev, i2c); + + intel_gmbus_force_bit(i2c, false); + + if (!dvoinit) continue; intel_encoder->type = INTEL_OUTPUT_DVO; -- cgit v1.1 From b1459cd57d01eb554821bf263463ef18bc1f59ef Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 18 Mar 2013 17:12:50 -0400 Subject: drm/radeon: don't use get_engine_clock() on APUs commit bf05d9985111f85ed6922c134567b96eb789283b upstream. It doesn't work reliably. Just report back the currently selected engine clock. Partially fixes: https://bugs.freedesktop.org/show_bug.cgi?id=62493 Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/radeon_pm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 4f88863..8270a85 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -845,7 +845,11 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data) struct radeon_device *rdev = dev->dev_private; seq_printf(m, "default engine clock: %u0 kHz\n", rdev->pm.default_sclk); - seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); + /* radeon_get_engine_clock is not reliable on APUs so just print the current clock */ + if ((rdev->family >= CHIP_PALM) && (rdev->flags & RADEON_IS_IGP)) + seq_printf(m, "current engine clock: %u0 kHz\n", rdev->pm.current_sclk); + else + seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); seq_printf(m, "default memory clock: %u0 kHz\n", rdev->pm.default_mclk); if (rdev->asic->get_memory_clock) seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev)); -- cgit v1.1 From 370112b115a3867b2ebf0ac6a2f44f11425fe818 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 11 Apr 2013 12:45:34 -0400 Subject: drm/radeon/evergreen+: don't enable HPD interrupts on eDP/LVDS commit 2e97be73e5f74a317232740ae82eb8f95326a660 upstream. Avoids potential interrupt storms when the display is disabled. May fix: https://bugzilla.kernel.org/show_bug.cgi?id=56041 Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/evergreen.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index a75d290..d3264b9 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -330,6 +330,16 @@ void evergreen_hpd_init(struct radeon_device *rdev) list_for_each_entry(connector, &dev->mode_config.connector_list, head) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); + + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || + connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { + /* don't try to enable hpd on eDP or LVDS avoid breaking the + * aux dp channel on imac and help (but not completely fix) + * https://bugzilla.redhat.com/show_bug.cgi?id=726143 + * also avoid interrupt storms during dpms. + */ + continue; + } switch (radeon_connector->hpd.hpd) { case RADEON_HPD_1: WREG32(DC_HPD1_CONTROL, tmp); -- cgit v1.1 From b085d867934932a43188297161a5fbbe07565b4c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 24 Apr 2013 14:39:31 -0400 Subject: drm/radeon: fix endian bugs in atom_allocate_fb_scratch() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit beb71fc61c2cad64e347f164991b8ef476529e64 upstream. Reviwed-by: Michel Dänzer Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/atom.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 88661ea..6b84d279 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -1384,10 +1384,10 @@ int atom_allocate_fb_scratch(struct atom_context *ctx) firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); DRM_DEBUG("atom firmware requested %08x %dkb\n", - firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware, - firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb); + le32_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware), + le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb)); - usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024; + usage_bytes = le16_to_cpu(firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb) * 1024; } ctx->scratch_size_bytes = 0; if (usage_bytes == 0) -- cgit v1.1 From 82bab2b3b6d6029b06a4e85156ccf99bf95cc2f2 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 25 Apr 2013 09:29:17 -0400 Subject: drm/radeon: fix possible segfault when parsing pm tables commit f8e6bfc2ce162855fa4f9822a45659f4b542c960 upstream. If we have a empty power table, bail early and allocate the default power state. Should fix: https://bugs.freedesktop.org/show_bug.cgi?id=63865 Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/radeon_atombios.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index cee3184..b1aade0 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -2031,6 +2031,8 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) num_modes = power_info->info.ucNumOfPowerModeEntries; if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; + if (num_modes == 0) + return state_index; rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * num_modes, GFP_KERNEL); if (!rdev->pm.power_state) return state_index; @@ -2401,6 +2403,8 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); + if (power_info->pplib.ucNumStates == 0) + return state_index; rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * power_info->pplib.ucNumStates, GFP_KERNEL); if (!rdev->pm.power_state) @@ -2485,6 +2489,8 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) non_clock_info_array = (struct NonClockInfoArray *) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); + if (state_array->ucNumEntries == 0) + return state_index; rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state) * state_array->ucNumEntries, GFP_KERNEL); if (!rdev->pm.power_state) @@ -2561,7 +2567,9 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) default: break; } - } else { + } + + if (state_index == 0) { rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); if (rdev->pm.power_state) { /* add the default mode */ -- cgit v1.1 From 94adafe60f4a1ed621da67dde6cc457fd5255e18 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 8 May 2013 04:01:15 +0000 Subject: ACPICA: Fix possible buffer overflow during a field unit read operation commit 61388f9e5d93053cf399a356414f31f9b4814c6d upstream. Can only happen under these conditions: 1) The DSDT version is 1, meaning integers are 32-bits. 2) The field is between 33 and 64 bits long. It applies cleanly back to ACPICA 20100806+ (Linux v2.6.37+). Signed-off-by: Bob Moore Signed-off-by: Lv Zheng Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/acpica/exfldio.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index f915a7f..b334f54 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -702,7 +702,19 @@ acpi_ex_extract_from_field(union acpi_operand_object *obj_desc, if ((obj_desc->common_field.start_field_bit_offset == 0) && (obj_desc->common_field.bit_length == access_bit_width)) { - status = acpi_ex_field_datum_io(obj_desc, 0, buffer, ACPI_READ); + if (buffer_length >= sizeof(u64)) { + status = + acpi_ex_field_datum_io(obj_desc, 0, buffer, + ACPI_READ); + } else { + /* Use raw_datum (u64) to handle buffers < 64 bits */ + + status = + acpi_ex_field_datum_io(obj_desc, 0, &raw_datum, + ACPI_READ); + ACPI_MEMCPY(buffer, &raw_datum, buffer_length); + } + return_ACPI_STATUS(status); } -- cgit v1.1 From 37cc8ba179a6e326d9074b23e8bccdf4cadd6b58 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 10 May 2013 14:37:15 +0100 Subject: dm snapshot: fix error return code in snapshot_ctr commit 09e8b813897a0f85bb401435d009228644c81214 upstream. Return -ENOMEM instead of success if unable to allocate pending exception mempool in snapshot_ctr. Signed-off-by: Wei Yongjun Signed-off-by: Alasdair G Kergon Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-snap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 9ecff5f..f3e632a 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -1121,6 +1121,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) s->pending_pool = mempool_create_slab_pool(MIN_IOS, pending_cache); if (!s->pending_pool) { ti->error = "Could not allocate mempool for pending exceptions"; + r = -ENOMEM; goto bad_pending_pool; } -- cgit v1.1 From 8ee29c2d66ae8aab9b28af5e83ec23dd99d8e500 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 24 Apr 2013 14:02:53 -0700 Subject: SCSI: sd: fix array cache flushing bug causing performance problems commit 39c60a0948cc06139e2fbfe084f83cb7e7deae3b upstream. Some arrays synchronize their full non volatile cache when the sd driver sends a SYNCHRONIZE CACHE command. Unfortunately, they can have Terrabytes of this and we send a SYNCHRONIZE CACHE for every barrier if an array reports it has a writeback cache. This leads to massive slowdowns on journalled filesystems. The fix is to allow userspace to turn off the writeback cache setting as a temporary measure (i.e. without doing the MODE SELECT to write it back to the device), so even though the device reported it has a writeback cache, the user, knowing that the cache is non volatile and all they care about is filesystem correctness, can turn that bit off in the kernel and avoid the performance ruinous (and safety irrelevant) SYNCHRONIZE CACHE commands. The way you do this is add a 'temporary' prefix when performing the usual cache setting operations, so echo temporary write through > /sys/class/scsi_disk//cache_type Reported-by: Ric Wheeler Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sd.c | 20 ++++++++++++++++++++ drivers/scsi/sd.h | 1 + 2 files changed, 21 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 515ec6d..7db7eb7 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -138,6 +138,7 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, char *buffer_data; struct scsi_mode_data data; struct scsi_sense_hdr sshdr; + const char *temp = "temporary "; int len; if (sdp->type != TYPE_DISK) @@ -146,6 +147,13 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, * it's not worth the risk */ return -EINVAL; + if (strncmp(buf, temp, sizeof(temp) - 1) == 0) { + buf += sizeof(temp) - 1; + sdkp->cache_override = 1; + } else { + sdkp->cache_override = 0; + } + for (i = 0; i < ARRAY_SIZE(sd_cache_types); i++) { len = strlen(sd_cache_types[i]); if (strncmp(sd_cache_types[i], buf, len) == 0 && @@ -158,6 +166,13 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, return -EINVAL; rcd = ct & 0x01 ? 1 : 0; wce = ct & 0x02 ? 1 : 0; + + if (sdkp->cache_override) { + sdkp->WCE = wce; + sdkp->RCD = rcd; + return count; + } + if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT, SD_MAX_RETRIES, &data, NULL)) return -EINVAL; @@ -2036,6 +2051,10 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) int old_rcd = sdkp->RCD; int old_dpofua = sdkp->DPOFUA; + + if (sdkp->cache_override) + return; + first_len = 4; if (sdp->skip_ms_page_8) { if (sdp->type == TYPE_RBC) @@ -2517,6 +2536,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie) sdkp->capacity = 0; sdkp->media_present = 1; sdkp->write_prot = 0; + sdkp->cache_override = 0; sdkp->WCE = 0; sdkp->RCD = 0; sdkp->ATO = 0; diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 6ad798b..812f1ba 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -70,6 +70,7 @@ struct scsi_disk { u8 protection_type;/* Data Integrity Field */ u8 provisioning_mode; unsigned ATO : 1; /* state of disk ATO bit */ + unsigned cache_override : 1; /* temp override of WCE,RCD */ unsigned WCE : 1; /* state of disk WCE bit */ unsigned RCD : 1; /* state of disk RCD bit, unused */ unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ -- cgit v1.1 From 61ed7336516e074d426f2f7c1e041846d7fa5c12 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 27 Apr 2013 11:47:01 +0200 Subject: ath9k: fix key allocation error handling for powersave keys commit 4ef69d0394cba8caa9f75d3f2e53429bfb8b3045 upstream. If no keycache slots are available, ath_key_config can return -ENOSPC. If the key index is not checked for errors, it can lead to logspam that looks like this: "ath: wiphy0: keyreset: keycache entry 228 out of range" This can cause follow-up errors if the invalid keycache index gets used for tx. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 633f962..806748a 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1791,6 +1791,7 @@ static int ath9k_sta_add(struct ieee80211_hw *hw, struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_node *an = (struct ath_node *) sta->drv_priv; struct ieee80211_key_conf ps_key = { }; + int key; ath_node_attach(sc, sta); @@ -1798,7 +1799,9 @@ static int ath9k_sta_add(struct ieee80211_hw *hw, vif->type != NL80211_IFTYPE_AP_VLAN) return 0; - an->ps_key = ath_key_config(common, vif, sta, &ps_key); + key = ath_key_config(common, vif, sta, &ps_key); + if (key > 0) + an->ps_key = key; return 0; } @@ -1815,6 +1818,7 @@ static void ath9k_del_ps_key(struct ath_softc *sc, return; ath_key_delete(common, &ps_key); + an->ps_key = 0; } static int ath9k_sta_remove(struct ieee80211_hw *hw, -- cgit v1.1 From a7cacebc8eed5136de20315d0dd8de300e5d18b3 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Mon, 6 May 2013 19:46:53 -0700 Subject: mwifiex: clear is_suspended flag when interrupt is received early commit 48795424acff7215d5eac0b52793a2c1eb3a6283 upstream. When the XO-4 with 8787 wireless is woken up due to wake-on-WLAN mwifiex is often flooded with "not allowed while suspended" messages and the interface is unusable. [ 202.171609] int: sdio_ireg = 0x1 [ 202.180700] info: mwifiex_process_hs_config: auto cancelling host sleep since there is interrupt from the firmware [ 202.201880] event: wakeup device... [ 202.211452] event: hs_deactivated [ 202.514638] info: --- Rx: Data packet --- [ 202.514753] data: 4294957544 BSS(0-0): Data <= kernel [ 202.514825] PREP_CMD: device in suspended state [ 202.514839] data: dequeuing the packet ec7248c0 ec4869c0 [ 202.514886] mwifiex_write_data_sync: not allowed while suspended [ 202.514886] host_to_card, write iomem (1) failed: -1 [ 202.514917] mwifiex_write_data_sync: not allowed while suspended [ 202.514936] host_to_card, write iomem (2) failed: -1 [ 202.514949] mwifiex_write_data_sync: not allowed while suspended [ 202.514965] host_to_card, write iomem (3) failed: -1 [ 202.514976] mwifiex_write_data_async failed: 0xFFFFFFFF This can be readily reproduced when putting the XO-4 in a loop where it goes to sleep due to inactivity, but then wakes up due to an incoming ping. The error is hit within an hour or two. This issue happens when an interrupt comes in early while host sleep is still activated. Driver handles this case by auto cancelling host sleep. However is_suspended flag is still set which prevents any cmd or data from being sent to firmware. Fix it by clearing is_suspended flag in this path. Reported-by: Daniel Drake Tested-by: Daniel Drake Signed-off-by: Bing Zhao Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/mwifiex/cmdevt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index cd89fed..677e60b 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -1081,6 +1081,7 @@ mwifiex_process_hs_config(struct mwifiex_adapter *adapter) adapter->if_ops.wakeup(adapter); adapter->hs_activated = false; adapter->is_hs_configured = false; + adapter->is_suspended = false; mwifiex_hs_activated_event(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY), false); } -- cgit v1.1 From 483e107f172d8a120579ffe077f834304aa95599 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Wed, 8 May 2013 15:37:19 -0400 Subject: mwifiex: fix setting of multicast filter commit ccd384b10420ac81ba3fb9b0a7d18272c7173552 upstream. A small bug in this code was causing the ALLMULTI filter to be set when in fact we were just wanting to program a selective multicast list to the hardware. Fix that bug and remove a redundant if condition in the code that follows. This fixes wakeup behaviour when multicast WOL is enabled. Previously, all multicast packets would wake up the system. Now, only those that the host intended to receive trigger wakeups. Signed-off-by: Daniel Drake Acked-by: Bing Zhao Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/mwifiex/sta_ioctl.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index d05907d..a677e7b 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -100,7 +100,7 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, } else { /* Multicast */ priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE; - if (mcast_list->mode == MWIFIEX_MULTICAST_MODE) { + if (mcast_list->mode == MWIFIEX_ALL_MULTI_MODE) { dev_dbg(priv->adapter->dev, "info: Enabling All Multicast!\n"); priv->curr_pkt_filter |= @@ -112,20 +112,11 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, dev_dbg(priv->adapter->dev, "info: Set multicast list=%d\n", mcast_list->num_multicast_addr); - /* Set multicast addresses to firmware */ - if (old_pkt_filter == priv->curr_pkt_filter) { - /* Send request to firmware */ - ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_MAC_MULTICAST_ADR, - HostCmd_ACT_GEN_SET, 0, - mcast_list); - } else { - /* Send request to firmware */ - ret = mwifiex_send_cmd_async(priv, - HostCmd_CMD_MAC_MULTICAST_ADR, - HostCmd_ACT_GEN_SET, 0, - mcast_list); - } + /* Send multicast addresses to firmware */ + ret = mwifiex_send_cmd_async(priv, + HostCmd_CMD_MAC_MULTICAST_ADR, + HostCmd_ACT_GEN_SET, 0, + mcast_list); } } } -- cgit v1.1 From 875cfc6271a37f35f6334c26184b16eb70625929 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 20 Apr 2013 12:08:11 +0200 Subject: drm/mm: fix dump table BUG commit 3a359f0b21ab218c1bf7a6a1b638b6fd143d0b99 upstream. In commit 9e8944ab564f2e3dde90a518cd32048c58918608 Author: Chris Wilson Date: Thu Nov 15 11:32:17 2012 +0000 drm: Introduce an iterator over holes in the drm_mm range manager helpers and iterators for hole handling have been introduced with some debug BUG_ONs sprinkled over. Unfortunately this broke the mm dumper which unconditionally tried to compute the size of the very first hole. While at it unify the code a bit with the hole dumping in the loop. v2: Extract a hole dump helper. Reported-by: Christopher Harvey Cc: Christopher Harvey Cc: Dave Airlie Cc: Chris Wilson Acked-by: Dave Airlie Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_mm.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 959186c..01894e4 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -679,33 +679,35 @@ void drm_mm_debug_table(struct drm_mm *mm, const char *prefix) EXPORT_SYMBOL(drm_mm_debug_table); #if defined(CONFIG_DEBUG_FS) -int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) +static unsigned long drm_mm_dump_hole(struct seq_file *m, struct drm_mm_node *entry) { - struct drm_mm_node *entry; - unsigned long total_used = 0, total_free = 0, total = 0; unsigned long hole_start, hole_end, hole_size; - hole_start = drm_mm_hole_node_start(&mm->head_node); - hole_end = drm_mm_hole_node_end(&mm->head_node); - hole_size = hole_end - hole_start; - if (hole_size) + if (entry->hole_follows) { + hole_start = drm_mm_hole_node_start(entry); + hole_end = drm_mm_hole_node_end(entry); + hole_size = hole_end - hole_start; seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", hole_start, hole_end, hole_size); - total_free += hole_size; + return hole_size; + } + + return 0; +} + +int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) +{ + struct drm_mm_node *entry; + unsigned long total_used = 0, total_free = 0, total = 0; + + total_free += drm_mm_dump_hole(m, &mm->head_node); drm_mm_for_each_node(entry, mm) { seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: used\n", entry->start, entry->start + entry->size, entry->size); total_used += entry->size; - if (entry->hole_follows) { - hole_start = drm_mm_hole_node_start(entry); - hole_end = drm_mm_hole_node_end(entry); - hole_size = hole_end - hole_start; - seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", - hole_start, hole_end, hole_size); - total_free += hole_size; - } + total_free += drm_mm_dump_hole(m, entry); } total = total_free + total_used; -- cgit v1.1 From be8fd5041900f0d8233ca61119477b28ca7df6e0 Mon Sep 17 00:00:00 2001 From: Matthew Whitehead Date: Mon, 29 Apr 2013 17:46:53 -0400 Subject: 3c509.c: call SET_NETDEV_DEV for all device types (ISA/ISAPnP/EISA) [ Upstream commit 3b54912f9cd167641b91d4a697bd742f70e534fe ] The venerable 3c509 driver only sets its device parent in one case, the ISAPnP one. It does this with the SET_NETDEV_DEV function. It should register with the device hierarchy in two additional cases: standard (non-PnP) ISA and EISA. - Currently they appear here: /sys/devices/virtual/net/eth0 (standard ISA) /sys/devices/virtual/net/eth1 (EISA) - Rather, they should instead be here: /sys/devices/isa/3c509.0/net/eth0 (standard ISA) /sys/devices/pci0000:00/0000:00:07.0/00:04/net/eth1 (EISA) Tested on ISA and EISA boards. Signed-off-by: Matthew Whitehead Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/3c509.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c index 44b28b2..15410f7 100644 --- a/drivers/net/3c509.c +++ b/drivers/net/3c509.c @@ -309,6 +309,7 @@ static int __devinit el3_isa_match(struct device *pdev, if (!dev) return -ENOMEM; + SET_NETDEV_DEV(dev, pdev); netdev_boot_setup_check(dev); if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-isa")) { @@ -704,6 +705,7 @@ static int __init el3_eisa_probe (struct device *device) return -ENOMEM; } + SET_NETDEV_DEV(dev, device); netdev_boot_setup_check(dev); el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_EISA); -- cgit v1.1 From 20a7e697adea9e58ce7ad390ba487b995ebcbb1b Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 2 May 2013 11:10:22 +0000 Subject: 3c59x: fix freeing nonexistent resource on driver unload [ Upstream commit c81400be716aa4c76f6ebf339ba94358dbbf6da6 ] When unloading the driver that drives an EISA board, a message similar to the following one is displayed: Trying to free nonexistent resource <0000000000013000-000000000001301f> Then an user is unable to reload the driver because the resource it requested in the previous load hasn't been freed. This happens most probably due to a typo in vortex_eisa_remove() which calls release_region() with 'dev->base_addr' instead of 'edev->base_addr'... Reported-by: Matthew Whitehead Tested-by: Matthew Whitehead Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/3c59x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 41afc40..cbdf8e5 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -951,7 +951,7 @@ static int __devexit vortex_eisa_remove(struct device *device) unregister_netdev(dev); iowrite16(TotalReset|0x14, ioaddr + EL3_CMD); - release_region(dev->base_addr, VORTEX_TOTAL_SIZE); + release_region(edev->base_addr, VORTEX_TOTAL_SIZE); free_netdev(dev); return 0; -- cgit v1.1 From cddd4b732be4dd206b99e25ac652db222d0ec2ba Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Thu, 9 May 2013 11:14:07 +0000 Subject: 3c59x: fix PCI resource management [ Upstream commit 4b264a1676e70dc656ba53a8cac690f2d4b65f4e ] The driver wrongly claimed I/O ports at an address returned by pci_iomap() -- even if it was passed an MMIO address. Fix this by claiming/releasing all PCI resources in the PCI driver's probe()/remove() methods instead and get rid of 'must_free_region' flag weirdness (why would Cardbus claim anything for us?). Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/3c59x.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index cbdf8e5..c83be40 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -632,7 +632,6 @@ struct vortex_private { pm_state_valid:1, /* pci_dev->saved_config_space has sane contents */ open:1, medialock:1, - must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ large_frames:1, /* accept large frames */ handling_irq:1; /* private in_irq indicator */ /* {get|set}_wol operations are already serialized by rtnl. @@ -1012,6 +1011,12 @@ static int __devinit vortex_init_one(struct pci_dev *pdev, if (rc < 0) goto out; + rc = pci_request_regions(pdev, DRV_NAME); + if (rc < 0) { + pci_disable_device(pdev); + goto out; + } + unit = vortex_cards_found; if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) { @@ -1027,6 +1032,7 @@ static int __devinit vortex_init_one(struct pci_dev *pdev, if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */ ioaddr = pci_iomap(pdev, 0, 0); if (!ioaddr) { + pci_release_regions(pdev); pci_disable_device(pdev); rc = -ENOMEM; goto out; @@ -1036,6 +1042,7 @@ static int __devinit vortex_init_one(struct pci_dev *pdev, ent->driver_data, unit); if (rc < 0) { pci_iounmap(pdev, ioaddr); + pci_release_regions(pdev); pci_disable_device(pdev); goto out; } @@ -1180,11 +1187,6 @@ static int __devinit vortex_probe1(struct device *gendev, /* PCI-only startup logic */ if (pdev) { - /* EISA resources already marked, so only PCI needs to do this here */ - /* Ignore return value, because Cardbus drivers already allocate for us */ - if (request_region(dev->base_addr, vci->io_size, print_name) != NULL) - vp->must_free_region = 1; - /* enable bus-mastering if necessary */ if (vci->flags & PCI_USES_MASTER) pci_set_master(pdev); @@ -1222,7 +1224,7 @@ static int __devinit vortex_probe1(struct device *gendev, &vp->rx_ring_dma); retval = -ENOMEM; if (!vp->rx_ring) - goto free_region; + goto free_device; vp->tx_ring = (struct boom_tx_desc *)(vp->rx_ring + RX_RING_SIZE); vp->tx_ring_dma = vp->rx_ring_dma + sizeof(struct boom_rx_desc) * RX_RING_SIZE; @@ -1487,9 +1489,7 @@ free_ring: + sizeof(struct boom_tx_desc) * TX_RING_SIZE, vp->rx_ring, vp->rx_ring_dma); -free_region: - if (vp->must_free_region) - release_region(dev->base_addr, vci->io_size); +free_device: free_netdev(dev); pr_err(PFX "vortex_probe1 fails. Returns %d\n", retval); out: @@ -3253,8 +3253,9 @@ static void __devexit vortex_remove_one(struct pci_dev *pdev) + sizeof(struct boom_tx_desc) * TX_RING_SIZE, vp->rx_ring, vp->rx_ring_dma); - if (vp->must_free_region) - release_region(dev->base_addr, vp->io_size); + + pci_release_regions(pdev); + free_netdev(dev); } -- cgit v1.1 From d5bf240fa193989d605a715bda7cb3283b1abc89 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 9 May 2013 04:23:40 +0000 Subject: macvlan: fix passthru mode race between dev removal and rx path [ Upstream commit 233c7df0821c4190e2d3f4be0f2ca0ab40a5ed8c, note that I had to add list_first_or_null_rcu to rculist.h in order to accomodate this fix. ] Currently, if macvlan in passthru mode is created and data are rxed and you remove this device, following panic happens: NULL pointer dereference at 0000000000000198 IP: [] macvlan_handle_frame+0x153/0x1f7 [macvlan] I'm using following script to trigger this: I run this script while "ping -f" is running on another machine to send packets to e1 rx. Reason of the panic is that list_first_entry() is blindly called in macvlan_handle_frame() even if the list was empty. vlan is set to incorrect pointer which leads to the crash. I'm fixing this by protecting port->vlans list by rcu and by preventing from getting incorrect pointer in case the list is empty. Introduced by: commit eb06acdc85585f2 "macvlan: Introduce 'passthru' mode to takeover the underlying device" Signed-off-by: Jiri Pirko Acked-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/macvlan.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 735f726..4c0bdac 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -193,7 +193,8 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) } if (port->passthru) - vlan = list_first_entry(&port->vlans, struct macvlan_dev, list); + vlan = list_first_or_null_rcu(&port->vlans, + struct macvlan_dev, list); else vlan = macvlan_hash_lookup(port, eth->h_dest); if (vlan == NULL) @@ -687,7 +688,7 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, if (err < 0) goto destroy_port; - list_add_tail(&vlan->list, &port->vlans); + list_add_tail_rcu(&vlan->list, &port->vlans); netif_stacked_transfer_operstate(lowerdev, dev); return 0; @@ -713,7 +714,7 @@ void macvlan_dellink(struct net_device *dev, struct list_head *head) { struct macvlan_dev *vlan = netdev_priv(dev); - list_del(&vlan->list); + list_del_rcu(&vlan->list); unregister_netdevice_queue(dev, head); } EXPORT_SYMBOL_GPL(macvlan_dellink); -- cgit v1.1 From b89396eaa22b921245b4d30f7e26e406e89aa51c Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Tue, 12 Feb 2013 11:25:33 +0900 Subject: pch_dma: Use GFP_ATOMIC because called from interrupt context commit 5c1ef59168c485318e40ba485c1eba57d81d0faa upstream. pdc_desc_get() is called from pd_prep_slave_sg, and the function is called from interrupt context(e.g. Uart driver "pch_uart.c"). In fact, I saw kernel error message. So, GFP_ATOMIC must be used not GFP_NOIO. Signed-off-by: Tomoya MORINAGA Signed-off-by: Vinod Koul Signed-off-by: Greg Kroah-Hartman --- drivers/dma/pch_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index 1ed89d0..e6f128a 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c @@ -489,7 +489,7 @@ static struct pch_dma_desc *pdc_desc_get(struct pch_dma_chan *pd_chan) dev_dbg(chan2dev(&pd_chan->chan), "scanned %d descriptors\n", i); if (!ret) { - ret = pdc_alloc_desc(&pd_chan->chan, GFP_NOIO); + ret = pdc_alloc_desc(&pd_chan->chan, GFP_ATOMIC); if (ret) { spin_lock(&pd_chan->lock); pd_chan->descs_allocated++; -- cgit v1.1 From e81164cfec2f578998670c8f00e5d0c33c06f20f Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 10 May 2013 00:50:20 +0200 Subject: r8169: fix vlan tag read ordering. commit ce11ff5e5963e441feb591e76278528f876c332d upstream. Control of receive descriptor must not be returned to ethernet chipset before vlan tag processing is done. VLAN tag receive word is now reset both in normal and error path. Signed-off-by: Francois Romieu Spotted-by: Timo Teras Cc: Hayes Wang Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/r8169.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 8350f8d..bf67991 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1494,8 +1494,6 @@ static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb) if (opts2 & RxVlanTag) __vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff)); - - desc->opts2 = 0; } static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd) @@ -5188,7 +5186,6 @@ static int rtl8169_rx_interrupt(struct net_device *dev, rtl8169_schedule_work(dev, rtl8169_reset_task); dev->stats.rx_fifo_errors++; } - rtl8169_mark_to_asic(desc, rx_buf_sz); } else { struct sk_buff *skb; dma_addr_t addr = le64_to_cpu(desc->addr); @@ -5202,16 +5199,14 @@ static int rtl8169_rx_interrupt(struct net_device *dev, if (unlikely(rtl8169_fragmented_frame(status))) { dev->stats.rx_dropped++; dev->stats.rx_length_errors++; - rtl8169_mark_to_asic(desc, rx_buf_sz); - continue; + goto release_descriptor; } skb = rtl8169_try_rx_copy(tp->Rx_databuff[entry], tp, pkt_size, addr); - rtl8169_mark_to_asic(desc, rx_buf_sz); if (!skb) { dev->stats.rx_dropped++; - continue; + goto release_descriptor; } rtl8169_rx_csum(skb, status); @@ -5225,6 +5220,10 @@ static int rtl8169_rx_interrupt(struct net_device *dev, dev->stats.rx_bytes += pkt_size; dev->stats.rx_packets++; } +release_descriptor: + desc->opts2 = 0; + wmb(); + rtl8169_mark_to_asic(desc, rx_buf_sz); } count = cur_rx - tp->cur_rx; -- cgit v1.1 From d8b1123f949c5463421ec0a66bbca21e0a5feba0 Mon Sep 17 00:00:00 2001 From: Philipp Reisner Date: Wed, 27 Mar 2013 14:08:47 +0100 Subject: drbd: fix for deadlock when using automatic split-brain-recovery commit 7c689e63a847316c1b2500f86891b0a574ce7e69 upstream. With an automatic after split-brain recovery policy of "after-sb-1pri call-pri-lost-after-sb", when trying to drbd_set_role() to R_SECONDARY, we run into a deadlock. This was first recognized and supposedly fixed by 2009-06-10 "Fixed a deadlock when using automatic split brain recovery when both nodes are" replacing drbd_set_role() with drbd_change_state() in that code-path, but the first hunk of that patch forgets to remove the drbd_set_role(). We apparently only ever tested the "two primaries" case. Signed-off-by: Philipp Reisner Signed-off-by: Lars Ellenberg Signed-off-by: Jens Axboe Signed-off-by: Jonghwan Choi Signed-off-by: Greg Kroah-Hartman --- drivers/block/drbd/drbd_receiver.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 43beaca..13cbdd3 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -2225,7 +2225,6 @@ static int drbd_asb_recover_1p(struct drbd_conf *mdev) __must_hold(local) if (hg == -1 && mdev->state.role == R_PRIMARY) { enum drbd_state_rv rv2; - drbd_set_role(mdev, R_SECONDARY, 0); /* drbd_change_state() does not sleep while in SS_IN_TRANSIENT_STATE, * we might be here in C_WF_REPORT_PARAMS which is transient. * we do not need to wait for the after state change work either. */ -- cgit v1.1 From 5cb2df345fb2b2e119f492d6c36e8d3bad70d8b3 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 29 Apr 2013 16:21:07 -0700 Subject: drivers/rtc/rtc-pcf2123.c: fix error return code in pcf2123_probe() commit 35623715818dfa720cccf99cd280dcbb4b78da23 upstream. Fix to return -ENODEV in the chip not found error handling case instead of 0, as done elsewhere in this function. Signed-off-by: Wei Yongjun Cc: Jingoo Han Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Jonghwan Choi Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-pcf2123.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index 71bab0e..646f6fe 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -263,6 +263,7 @@ static int __devinit pcf2123_probe(struct spi_device *spi) if (!(rxbuf[0] & 0x20)) { dev_err(&spi->dev, "chip not found\n"); + ret = -ENODEV; goto kfree_exit; } -- cgit v1.1 From 9e5124c57d380d616aef157c0f9e05ef0c80d1ca Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Mon, 6 May 2013 03:23:40 +0000 Subject: ACPI / EC: Restart transaction even when the IBF flag set commit 28fe5c825f8e15744d04c7c1b8df197950923ecd upstream. The EC driver works abnormally with IBF flag always set. IBF means "The host has written a byte of data to the command or data port, but the embedded controller has not yet read it". If IBF is set in the EC status and not cleared, this will cause all subsequent EC requests to fail with a timeout error. Change the EC driver so that it doesn't refuse to restart a transaction if IBF is set in the status. Also increase the number of transaction restarts to 5, as it turns out that 2 is not sufficient in some cases. This bug happens on several different machines (Asus V1S, Dell Latitude E6530, Samsung R719, Acer Aspire 5930G, Sony Vaio SR19VN and others). [rjw: Changelog] References: https://bugzilla.kernel.org/show_bug.cgi?id=14733 References: https://bugzilla.kernel.org/show_bug.cgi?id=15560 References: https://bugzilla.kernel.org/show_bug.cgi?id=15946 References: https://bugzilla.kernel.org/show_bug.cgi?id=42945 References: https://bugzilla.kernel.org/show_bug.cgi?id=48221 Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/ec.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d2519b2..51de186 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -217,7 +217,7 @@ static int ec_check_sci_sync(struct acpi_ec *ec, u8 state) static int ec_poll(struct acpi_ec *ec) { unsigned long flags; - int repeat = 2; /* number of command restarts */ + int repeat = 5; /* number of command restarts */ while (repeat--) { unsigned long delay = jiffies + msecs_to_jiffies(ec_delay); @@ -235,8 +235,6 @@ static int ec_poll(struct acpi_ec *ec) } advance_transaction(ec, acpi_ec_read_status(ec)); } while (time_before(jiffies, delay)); - if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) - break; pr_debug(PREFIX "controller reset, restart transaction\n"); spin_lock_irqsave(&ec->curr_lock, flags); start_transaction(ec); -- cgit v1.1 From c9e43f309c0a5ecb9467ea826c238fc0febb1e30 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Thu, 16 May 2013 14:04:25 -0500 Subject: drivers/char/ipmi: memcpy, need additional 2 bytes to avoid memory overflow commit a5f2b3d6a738e7d4180012fe7b541172f8c8dcea upstream. When calling memcpy, read_data and write_data need additional 2 bytes. write_data: for checking: "if (size > IPMI_MAX_MSG_LENGTH)" for operating: "memcpy(bt->write_data + 3, data + 1, size - 1)" read_data: for checking: "if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH)" for operating: "memcpy(data + 2, bt->read_data + 4, msg_len - 2)" Signed-off-by: Chen Gang Signed-off-by: Corey Minyard Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/char/ipmi/ipmi_bt_sm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c index 3ed20e8..92ce302 100644 --- a/drivers/char/ipmi/ipmi_bt_sm.c +++ b/drivers/char/ipmi/ipmi_bt_sm.c @@ -95,9 +95,9 @@ struct si_sm_data { enum bt_states state; unsigned char seq; /* BT sequence number */ struct si_sm_io *io; - unsigned char write_data[IPMI_MAX_MSG_LENGTH]; + unsigned char write_data[IPMI_MAX_MSG_LENGTH + 2]; /* +2 for memcpy */ int write_count; - unsigned char read_data[IPMI_MAX_MSG_LENGTH]; + unsigned char read_data[IPMI_MAX_MSG_LENGTH + 2]; /* +2 for memcpy */ int read_count; int truncated; long timeout; /* microseconds countdown */ -- cgit v1.1 From 486684458640fe1e74937b2e0eef41444515caf0 Mon Sep 17 00:00:00 2001 From: Benjamin LaHaise Date: Thu, 16 May 2013 14:04:27 -0500 Subject: ipmi: ipmi_devintf: compat_ioctl method fails to take ipmi_mutex commit 6368087e851e697679af059b4247aca33a69cef3 upstream. When a 32 bit version of ipmitool is used on a 64 bit kernel, the ipmi_devintf code fails to correctly acquire ipmi_mutex. This results in incomplete data being retrieved in some cases, or other possible failures. Add a wrapper around compat_ipmi_ioctl() to take ipmi_mutex to fix this. Signed-off-by: Benjamin LaHaise Signed-off-by: Corey Minyard Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/char/ipmi/ipmi_devintf.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 2aa3977..8dde1f5 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -838,13 +838,25 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd, return ipmi_ioctl(filep, cmd, arg); } } + +static long unlocked_compat_ipmi_ioctl(struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int ret; + + mutex_lock(&ipmi_mutex); + ret = compat_ipmi_ioctl(filep, cmd, arg); + mutex_unlock(&ipmi_mutex); + + return ret; +} #endif static const struct file_operations ipmi_fops = { .owner = THIS_MODULE, .unlocked_ioctl = ipmi_unlocked_ioctl, #ifdef CONFIG_COMPAT - .compat_ioctl = compat_ipmi_ioctl, + .compat_ioctl = unlocked_compat_ipmi_ioctl, #endif .open = ipmi_open, .release = ipmi_release, -- cgit v1.1 From ac087d8e21d7722266d913d766b5c8b87772cbb4 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sun, 12 May 2013 22:00:51 -0700 Subject: drm/radeon: check incoming cliprects pointer commit fefaedcfb82d2e57c2320acf60604ab03b750cc0 upstream. The "boxes" parameter points into userspace memory. It should be verified like any other operation against user memory. Signed-off-by: Kees Cook Signed-off-by: Dave Airlie Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/r300_cmdbuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c index c5c2742..a12f373 100644 --- a/drivers/gpu/drm/radeon/r300_cmdbuf.c +++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c @@ -74,7 +74,7 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv, OUT_RING(CP_PACKET0(R300_RE_CLIPRECT_TL_0, nr * 2 - 1)); for (i = 0; i < nr; ++i) { - if (DRM_COPY_FROM_USER_UNCHECKED + if (DRM_COPY_FROM_USER (&box, &cmdbuf->boxes[n + i], sizeof(box))) { DRM_ERROR("copy cliprect faulted\n"); return -EFAULT; -- cgit v1.1 From 38180ec039a7589112633b85b2cfab72a76ec9c0 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 13 May 2013 14:01:43 +0800 Subject: hwmon: fix error return code in abituguru_probe() commit ecacb0b17c08fae89f65468727f0e4b8e91da4e1 upstream. Fix to return a negative error code from the error handling case instead of 0, as done elsewhere in this function. Signed-off-by: Wei Yongjun Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/abituguru.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index 65a35cf..61ab615 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c @@ -1280,14 +1280,18 @@ static int __devinit abituguru_probe(struct platform_device *pdev) pr_info("found Abit uGuru\n"); /* Register sysfs hooks */ - for (i = 0; i < sysfs_attr_i; i++) - if (device_create_file(&pdev->dev, - &data->sysfs_attr[i].dev_attr)) + for (i = 0; i < sysfs_attr_i; i++) { + res = device_create_file(&pdev->dev, + &data->sysfs_attr[i].dev_attr); + if (res) goto abituguru_probe_error; - for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) - if (device_create_file(&pdev->dev, - &abituguru_sysfs_attr[i].dev_attr)) + } + for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++) { + res = device_create_file(&pdev->dev, + &abituguru_sysfs_attr[i].dev_attr); + if (res) goto abituguru_probe_error; + } data->hwmon_dev = hwmon_device_register(&pdev->dev); if (!IS_ERR(data->hwmon_dev)) -- cgit v1.1 From e51c0ea1c933d98e3f0ea5bf0a8a3149475cf0a1 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 9 Aug 2012 12:33:52 -0300 Subject: media: mantis: fix silly crash case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e1d45ae10aea8e8a403e5d96bf5902ee670007ff upstream. If we set mantis->fe to NULL on an error its not a good idea to then try passing NULL to the unregister paths and oopsing really. Resolves-bug: https://bugzilla.kernel.org/show_bug.cgi?id=16473 Signed-off-by: Alan Cox Signed-off-by: Mauro Carvalho Chehab Cc: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/media/dvb/mantis/mantis_dvb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/mantis/mantis_dvb.c b/drivers/media/dvb/mantis/mantis_dvb.c index e5180e4..5d15c6b 100644 --- a/drivers/media/dvb/mantis/mantis_dvb.c +++ b/drivers/media/dvb/mantis/mantis_dvb.c @@ -248,8 +248,10 @@ int __devinit mantis_dvb_init(struct mantis_pci *mantis) err5: tasklet_kill(&mantis->tasklet); dvb_net_release(&mantis->dvbnet); - dvb_unregister_frontend(mantis->fe); - dvb_frontend_detach(mantis->fe); + if (mantis->fe) { + dvb_unregister_frontend(mantis->fe); + dvb_frontend_detach(mantis->fe); + } err4: mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); -- cgit v1.1 From bbb17fe79731a9d580ab2338fe001b900fc29311 Mon Sep 17 00:00:00 2001 From: Hema Prathaban Date: Sat, 11 May 2013 22:39:47 +0530 Subject: staging: vt6656: use free_netdev instead of kfree commit 0a438d5b381e2bdfd5e02d653bf46fcc878356e3 upstream. use free_netdev() instead of kfree(pDevice->apdev) Signed-off-by: Hema Prathaban Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/hostap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/hostap.c b/drivers/staging/vt6656/hostap.c index 51b5adf..df8ea25 100644 --- a/drivers/staging/vt6656/hostap.c +++ b/drivers/staging/vt6656/hostap.c @@ -153,7 +153,7 @@ static int hostap_disable_hostapd(PSDevice pDevice, int rtnl_locked) DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n", pDevice->dev->name, pDevice->apdev->name); } - kfree(pDevice->apdev); + free_netdev(pDevice->apdev); pDevice->apdev = NULL; pDevice->bEnable8021x = FALSE; pDevice->bEnableHostWEP = FALSE; -- cgit v1.1 From 4c540276d44f2fc29c82338bc15b9d3a335d82f8 Mon Sep 17 00:00:00 2001 From: Teppo Kotilainen Date: Fri, 3 May 2013 10:28:12 +0300 Subject: usb: option: Add Telewell TW-LTE 4G commit 73c042df6e1bc50544842a04b777b36bbe3630e6 upstream. Information from driver description files: diag: VID_19D2&PID_0412&MI_00 nmea: VID_19D2&PID_0412&MI_01 at: VID_19D2&PID_0412&MI_02 modem: VID_19D2&PID_0412&MI_03 net: VID_19D2&PID_0412&MI_04 Signed-off-by: Teppo Kotilainen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 8513f51..240f727 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -966,6 +966,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0330, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0395, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0412, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G */ + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), -- cgit v1.1 From ef98b82a7c1671d08802574131c2c9b73e6b96fe Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 6 May 2013 16:16:44 -0500 Subject: USB: option: add device IDs for Dell 5804 (Novatel E371) WWAN card commit 49c6e370dd6400b84897c4100095089b5c13a061 upstream. A rebranded Novatel E371 for AT&T's LTE bands. Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 240f727..70895ed 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -196,6 +196,7 @@ static void option_instat_callback(struct urb *urb); #define DELL_PRODUCT_5800_MINICARD_VZW 0x8195 /* Novatel E362 */ #define DELL_PRODUCT_5800_V2_MINICARD_VZW 0x8196 /* Novatel E362 */ +#define DELL_PRODUCT_5804_MINICARD_ATT 0x819b /* Novatel E371 */ #define KYOCERA_VENDOR_ID 0x0c88 #define KYOCERA_PRODUCT_KPC650 0x17da @@ -771,6 +772,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5804_MINICARD_ATT, 0xff, 0xff, 0xff) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, -- cgit v1.1 From e50d48c8f67b2b96797bc5d66eb3c717d24744ff Mon Sep 17 00:00:00 2001 From: "Gomella, Andrew (NIH/NHLBI) [F]" Date: Fri, 17 May 2013 17:39:46 +0000 Subject: USB: ftdi_sio: Add support for Newport CONEX motor drivers commit 7138143972b7c293267c783fc99a194f0ceff7f2 upstream. Here are two more devices that use FTDI USB-to-serial chips with new product ID's. The devices are the Newport Conex-AGP and Conex-CC motor controllers. (http://www.newport.com/CONEX-AGP-Integrated-Piezo-Motor-Rotation-Stages-/987623/1033/info.aspx) (http://www.newport.com/CONEX-CC-DC-Servo-Controller-Actuators/934114/1033/info.aspx) usb-devices command yields: P: Vendor=104d ProdID=3002 Rev=06.00 S: Manufacturer=Newport S: Product=CONEX-CC as well as P: Vendor=104d ProdID=3006 Rev=06.00 S: Manufacturer=Newport S: Product=CONEX-AGP Signed-off-by: Andrew Gomella Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 ++ drivers/usb/serial/ftdi_sio_ids.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 0860007..7639cba 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -197,6 +197,8 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_GBM_BOOST_PID) }, { USB_DEVICE(NEWPORT_VID, NEWPORT_AGILIS_PID) }, + { USB_DEVICE(NEWPORT_VID, NEWPORT_CONEX_CC_PID) }, + { USB_DEVICE(NEWPORT_VID, NEWPORT_CONEX_AGP_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 2f86008..5d25e26 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -772,6 +772,8 @@ */ #define NEWPORT_VID 0x104D #define NEWPORT_AGILIS_PID 0x3000 +#define NEWPORT_CONEX_CC_PID 0x3002 +#define NEWPORT_CONEX_AGP_PID 0x3006 /* Interbiometrics USB I/O Board */ /* Developed for Interbiometrics by Rudolf Gugler */ -- cgit v1.1 From 2d722d28a3614fcd7959adc6e7debf9959b4bb8c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sun, 19 May 2013 21:52:20 +0300 Subject: USB: cxacru: potential underflow in cxacru_cm_get_array() commit 2a0ebf80aa95cc758d4725f74a7016e992606a39 upstream. The value of "offd" comes off the instance->rcv_buf[] and we used it as the offset into an array. The problem is that we check the upper bound but not for negative values. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/cxacru.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index a845f8b..9497171 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -686,7 +686,8 @@ static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_requ { int ret, len; __le32 *buf; - int offb, offd; + int offb; + unsigned int offd; const int stride = CMD_PACKET_SIZE / (4 * 2) - 1; int buflen = ((size - 1) / stride + 1 + size * 2) * 4; -- cgit v1.1 From 3bf001a01656e1fa0dc34e3c0043801575fdb6bb Mon Sep 17 00:00:00 2001 From: Wang YanQing Date: Thu, 9 May 2013 14:16:47 +0800 Subject: TTY: Fix tty miss restart after we turn off flow-control commit dab73b4eb9ef924a2b90dab84e539076d82b256f upstream. I meet emacs hang in start if I do the operation below: 1: echo 3 > /proc/sys/vm/drop_caches 2: emacs BigFile 3: Press CTRL-S follow 2 immediately Then emacs hang on, CTRL-Q can't resume, the terminal hang on, you can do nothing with this terminal except close it. The reason is before emacs takeover control the tty, we use CTRL-S to XOFF it. Then when emacs takeover the control, it may don't use the flow-control, so emacs hang. This patch fix it. This patch will fix a kind of strange tty relation hang problem, I believe I meet it with vim in ssh, and also see below bug report: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=465823 Signed-off-by: Wang YanQing Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index d7164bf..687cfe3 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1531,6 +1531,14 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) tty->real_raw = 0; } n_tty_set_room(tty); + /* + * Fix tty hang when I_IXON(tty) is cleared, but the tty + * been stopped by STOP_CHAR(tty) before it. + */ + if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped) { + start_tty(tty); + } + /* The termios change make the tty ready for I/O */ wake_up_interruptible(&tty->write_wait); wake_up_interruptible(&tty->read_wait); -- cgit v1.1 From bf968788053dca71a4cb6f798ac19d9f4312648c Mon Sep 17 00:00:00 2001 From: Schemmel Hans-Christoph Date: Mon, 6 May 2013 11:05:12 +0200 Subject: USB: Blacklisted Cinterion's PLxx WWAN Interface commit 8ff10bdb14a52e3f25d4ce09e0582a8684c1a6db upstream. /drivers/usb/serial/option.c: Blacklisted Cinterion's PLxx WWAN Interface (USB Interface 4), because it will be handled by QMI WWAN driver. Product IDs renamed. Signed-off-by: Hans-Christoph Schemmel Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 70895ed..59c4997 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -342,8 +342,8 @@ static void option_instat_callback(struct urb *urb); #define CINTERION_PRODUCT_EU3_E 0x0051 #define CINTERION_PRODUCT_EU3_P 0x0052 #define CINTERION_PRODUCT_PH8 0x0053 -#define CINTERION_PRODUCT_AH6 0x0055 -#define CINTERION_PRODUCT_PLS8 0x0060 +#define CINTERION_PRODUCT_AHXX 0x0055 +#define CINTERION_PRODUCT_PLXX 0x0060 /* Olivetti products */ #define OLIVETTI_VENDOR_ID 0x0b3c @@ -1268,8 +1268,9 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AH6) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLS8) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, -- cgit v1.1 From ea4950c9faa2a5d1019d74ff559374a56fdad8a2 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 30 Apr 2013 10:18:04 +0200 Subject: USB: reset resume quirk needed by a hub commit bac6b03275184c912ad0818c9a0a736847804dca upstream. Werner Fink has reported problems with this hub. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 8b2a9d8..f88ad63 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -110,6 +110,9 @@ static const struct usb_device_id usb_quirk_list[] = { /* Edirol SD-20 */ { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Alcor Micro Corp. Hub */ + { USB_DEVICE(0x058f, 0x9254), .driver_info = USB_QUIRK_RESET_RESUME }, + /* appletouch */ { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME }, -- cgit v1.1 From c2ecac559adaf4a9413a01d3601006320e345d96 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 14 May 2013 13:55:29 -0400 Subject: USB: UHCI: fix for suspend of virtual HP controller commit 997ff893603c6455da4c5e26ba1d0f81adfecdfc upstream. HP's virtual UHCI host controller takes a long time to suspend (several hundred microseconds), even when no devices are attached. This provokes a warning message from uhci-hcd in the auto-stop case. To prevent this from happening, this patch adds a test to avoid performing an auto-stop when the wait_for_hp quirk flag is set. The controller will still suspend through the normal runtime PM mechanism. And since that pathway includes a 1-ms delay, the slowness of the virtual hardware won't matter. Signed-off-by: Alan Stern Reported-and-tested-by: ZhenHua Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-hub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 045cde4..850723f 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c @@ -221,7 +221,8 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf) /* auto-stop if nothing connected for 1 second */ if (any_ports_active(uhci)) uhci->rh_state = UHCI_RH_RUNNING; - else if (time_after_eq(jiffies, uhci->auto_stop_time)) + else if (time_after_eq(jiffies, uhci->auto_stop_time) && + !uhci->wait_for_hp) suspend_rh(uhci, UHCI_RH_AUTO_STOPPED); break; -- cgit v1.1 From 77809457d14ff89ac8e67f3cdf45a43b2b620f82 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Fri, 24 May 2013 15:55:28 -0700 Subject: drivers/block/brd.c: fix brd_lookup_page() race commit dfd20b2b174d3a9b258ea3b7a35ead33576587b1 upstream. The index on the page must be set before it is inserted in the radix tree. Otherwise there is a small race which can occur during lookup where the page can be found with the incorrect index. This will trigger the BUG_ON() in brd_lookup_page(). Signed-off-by: Brian Behlendorf Reported-by: Chris Wedgwood Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/block/brd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/brd.c b/drivers/block/brd.c index dba1c32..f5dfb8498 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -117,13 +117,13 @@ static struct page *brd_insert_page(struct brd_device *brd, sector_t sector) spin_lock(&brd->brd_lock); idx = sector >> PAGE_SECTORS_SHIFT; + page->index = idx; if (radix_tree_insert(&brd->brd_pages, idx, page)) { __free_page(page); page = radix_tree_lookup(&brd->brd_pages, idx); BUG_ON(!page); BUG_ON(page->index != idx); - } else - page->index = idx; + } spin_unlock(&brd->brd_lock); radix_tree_preload_end(); -- cgit v1.1 From 2b23550e4d01f4c0c1560c899db43e1a63f7ccd0 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 22 May 2013 11:22:51 -0400 Subject: drm/radeon: fix card_posted check for newer asics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 09fb8bd1a63b0f9f15e655c4fe8d047e5d2bf67a upstream. Newer asics have variable numbers of crtcs. Use that rather than the asic family to determine which crtcs to check. This avoids checking non-existent crtcs or missing crtcs on certain asics. Reviewed-by: Michel Dänzer Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/radeon_device.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index e87893c..a275cf6 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -352,18 +352,17 @@ bool radeon_card_posted(struct radeon_device *rdev) uint32_t reg; /* first check CRTCs */ - if (ASIC_IS_DCE41(rdev)) { + if (ASIC_IS_DCE4(rdev)) { reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); - if (reg & EVERGREEN_CRTC_MASTER_EN) - return true; - } else if (ASIC_IS_DCE4(rdev)) { - reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); + if (rdev->num_crtc >= 4) { + reg |= RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); + } + if (rdev->num_crtc >= 6) { + reg |= RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); + } if (reg & EVERGREEN_CRTC_MASTER_EN) return true; } else if (ASIC_IS_AVIVO(rdev)) { -- cgit v1.1 From 2af3ee134e1c73c6ab72e958495cee9c238845b0 Mon Sep 17 00:00:00 2001 From: Wolfgang Frisch Date: Thu, 17 Jan 2013 01:07:02 +0100 Subject: USB: io_ti: Fix NULL dereference in chase_port() commit 1ee0a224bc9aad1de496c795f96bc6ba2c394811 upstream. The tty is NULL when the port is hanging up. chase_port() needs to check for this. This patch is intended for stable series. The behavior was observed and tested in Linux 3.2 and 3.7.1. Johan Hovold submitted a more elaborate patch for the mainline kernel. [ 56.277883] usb 1-1: edge_bulk_in_callback - nonzero read bulk status received: -84 [ 56.278811] usb 1-1: USB disconnect, device number 3 [ 56.278856] usb 1-1: edge_bulk_in_callback - stopping read! [ 56.279562] BUG: unable to handle kernel NULL pointer dereference at 00000000000001c8 [ 56.280536] IP: [] _raw_spin_lock_irqsave+0x19/0x35 [ 56.281212] PGD 1dc1b067 PUD 1e0f7067 PMD 0 [ 56.282085] Oops: 0002 [#1] SMP [ 56.282744] Modules linked in: [ 56.283512] CPU 1 [ 56.283512] Pid: 25, comm: khubd Not tainted 3.7.1 #1 innotek GmbH VirtualBox/VirtualBox [ 56.283512] RIP: 0010:[] [] _raw_spin_lock_irqsave+0x19/0x35 [ 56.283512] RSP: 0018:ffff88001fa99ab0 EFLAGS: 00010046 [ 56.283512] RAX: 0000000000000046 RBX: 00000000000001c8 RCX: 0000000000640064 [ 56.283512] RDX: 0000000000010000 RSI: ffff88001fa99b20 RDI: 00000000000001c8 [ 56.283512] RBP: ffff88001fa99b20 R08: 0000000000000000 R09: 0000000000000000 [ 56.283512] R10: 0000000000000000 R11: ffffffff812fcb4c R12: ffff88001ddf53c0 [ 56.283512] R13: 0000000000000000 R14: 00000000000001c8 R15: ffff88001e19b9f4 [ 56.283512] FS: 0000000000000000(0000) GS:ffff88001fd00000(0000) knlGS:0000000000000000 [ 56.283512] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 56.283512] CR2: 00000000000001c8 CR3: 000000001dc51000 CR4: 00000000000006e0 [ 56.283512] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 56.283512] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 56.283512] Process khubd (pid: 25, threadinfo ffff88001fa98000, task ffff88001fa94f80) [ 56.283512] Stack: [ 56.283512] 0000000000000046 00000000000001c8 ffffffff810578ec ffffffff812fcb4c [ 56.283512] ffff88001e19b980 0000000000002710 ffffffff812ffe81 0000000000000001 [ 56.283512] ffff88001fa94f80 0000000000000202 ffffffff00000001 0000000000000296 [ 56.283512] Call Trace: [ 56.283512] [] ? add_wait_queue+0x12/0x3c [ 56.283512] [] ? usb_serial_port_work+0x28/0x28 [ 56.283512] [] ? chase_port+0x84/0x2d6 [ 56.283512] [] ? try_to_wake_up+0x199/0x199 [ 56.283512] [] ? tty_ldisc_hangup+0x222/0x298 [ 56.283512] [] ? edge_close+0x64/0x129 [ 56.283512] [] ? __wake_up+0x35/0x46 [ 56.283512] [] ? should_resched+0x5/0x23 [ 56.283512] [] ? tty_port_shutdown+0x39/0x44 [ 56.283512] [] ? usb_serial_port_work+0x28/0x28 [ 56.283512] [] ? __tty_hangup+0x307/0x351 [ 56.283512] [] ? usb_hcd_flush_endpoint+0xde/0xed [ 56.283512] [] ? _raw_spin_lock_irqsave+0x14/0x35 [ 56.283512] [] ? usb_serial_disconnect+0x57/0xc2 [ 56.283512] [] ? usb_unbind_interface+0x5c/0x131 [ 56.283512] [] ? __device_release_driver+0x7f/0xd5 [ 56.283512] [] ? device_release_driver+0x1a/0x25 [ 56.283512] [] ? bus_remove_device+0xd2/0xe7 [ 56.283512] [] ? device_del+0x119/0x167 [ 56.283512] [] ? usb_disable_device+0x6a/0x180 [ 56.283512] [] ? usb_disconnect+0x81/0xe6 [ 56.283512] [] ? hub_thread+0x577/0xe82 [ 56.283512] [] ? __schedule+0x490/0x4be [ 56.283512] [] ? abort_exclusive_wait+0x79/0x79 [ 56.283512] [] ? usb_remote_wakeup+0x2f/0x2f [ 56.283512] [] ? usb_remote_wakeup+0x2f/0x2f [ 56.283512] [] ? kthread+0x81/0x89 [ 56.283512] [] ? __kthread_parkme+0x5c/0x5c [ 56.283512] [] ? ret_from_fork+0x7c/0xb0 [ 56.283512] [] ? __kthread_parkme+0x5c/0x5c [ 56.283512] Code: 8b 7c 24 08 e8 17 0b c3 ff 48 8b 04 24 48 83 c4 10 c3 53 48 89 fb 41 50 e8 e0 0a c3 ff 48 89 04 24 e8 e7 0a c3 ff ba 00 00 01 00 0f c1 13 48 8b 04 24 89 d1 c1 ea 10 66 39 d1 74 07 f3 90 66 [ 56.283512] RIP [] _raw_spin_lock_irqsave+0x19/0x35 [ 56.283512] RSP [ 56.283512] CR2: 00000000000001c8 [ 56.283512] ---[ end trace 49714df27e1679ce ]--- Signed-off-by: Wolfgang Frisch Cc: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/io_ti.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index bdb44fc..1f145bf 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -558,6 +558,9 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout, wait_queue_t wait; unsigned long flags; + if (!tty) + return; + if (!timeout) timeout = (HZ * EDGE_CLOSING_WAIT)/100; -- cgit v1.1 From cd6b18b0605a8a6355d6b838296926b12d548df3 Mon Sep 17 00:00:00 2001 From: Vincent Pelletier Date: Sat, 18 May 2013 18:44:04 +0200 Subject: libata: make ata_exec_internal_sg honor DMADIR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit e771451c0a831d96a7c14b0ca8a8ec671d98567b upstream. libata honors DMADIR for regular commands, but not for internal commands used (among other) during device initialisation. This makes SATA-host-to-PATA-device bridges based on Silicon Image SiL3611 (such as "Abit Serillel 2") end up disabled when used with an ATAPI device after a few tries. Log output of the bridge being hot-plugged with an ATAPI drive: [ 9631.212901] ata1: exception Emask 0x10 SAct 0x0 SErr 0x40c0000 action 0xe frozen [ 9631.212913] ata1: irq_stat 0x00000040, connection status changed [ 9631.212923] ata1: SError: { CommWake 10B8B DevExch } [ 9631.212939] ata1: hard resetting link [ 9632.104962] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) [ 9632.106393] ata1.00: ATAPI: PIONEER DVD-RW DVR-115, 1.06, max UDMA/33 [ 9632.106407] ata1.00: applying bridge limits [ 9632.108151] ata1.00: configured for UDMA/33 [ 9637.105303] ata1.00: qc timeout (cmd 0xa0) [ 9637.105324] ata1.00: failed to clear UNIT ATTENTION (err_mask=0x5) [ 9637.105335] ata1: hard resetting link [ 9638.044599] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) [ 9638.047878] ata1.00: configured for UDMA/33 [ 9643.044933] ata1.00: qc timeout (cmd 0xa0) [ 9643.044953] ata1.00: failed to clear UNIT ATTENTION (err_mask=0x5) [ 9643.044963] ata1: limiting SATA link speed to 1.5 Gbps [ 9643.044971] ata1.00: limiting speed to UDMA/33:PIO3 [ 9643.044979] ata1: hard resetting link [ 9643.984225] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 310) [ 9643.987471] ata1.00: configured for UDMA/33 [ 9648.984591] ata1.00: qc timeout (cmd 0xa0) [ 9648.984612] ata1.00: failed to clear UNIT ATTENTION (err_mask=0x5) [ 9648.984619] ata1.00: disabled [ 9649.000593] ata1: hard resetting link [ 9649.939902] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 310) [ 9649.955864] ata1: EH complete With this patch, the drive enumerates correctly when libata is loaded with atapi_dmadir=1: [ 9891.810863] ata1: exception Emask 0x10 SAct 0x0 SErr 0x40c0000 action 0xe frozen [ 9891.810874] ata1: irq_stat 0x00000040, connection status changed [ 9891.810884] ata1: SError: { CommWake 10B8B DevExch } [ 9891.810900] ata1: hard resetting link [ 9892.762105] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) [ 9892.763544] ata1.00: ATAPI: PIONEER DVD-RW DVR-115, 1.06, max UDMA/33, DMADIR [ 9892.763558] ata1.00: applying bridge limits [ 9892.765393] ata1.00: configured for UDMA/33 [ 9892.786063] ata1: EH complete [ 9892.792062] scsi 0:0:0:0: CD-ROM PIONEER DVD-RW DVR-115 1.06 PQ: 0 ANSI: 5 [ 9892.798455] sr2: scsi3-mmc drive: 12x/12x writer dvd-ram cd/rw xa/form2 cdda tray [ 9892.798837] sr 0:0:0:0: Attached scsi CD-ROM sr2 [ 9892.799109] sr 0:0:0:0: Attached scsi generic sg6 type 5 Based on a patch by Csaba Halász on linux-ide: http://marc.info/?l=linux-ide&m=136121147832295&w=2 tj: minor formatting changes. Signed-off-by: Vincent Pelletier Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-core.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 172619e..aa5f055 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1599,6 +1599,12 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, qc->tf = *tf; if (cdb) memcpy(qc->cdb, cdb, ATAPI_CDB_LEN); + + /* some SATA bridges need us to indicate data xfer direction */ + if (tf->protocol == ATAPI_PROT_DMA && (dev->flags & ATA_DFLAG_DMADIR) && + dma_dir == DMA_FROM_DEVICE) + qc->tf.feature |= ATAPI_DMADIR; + qc->flags |= ATA_QCFLAG_RESULT_TF; qc->dma_dir = dma_dir; if (dma_dir != DMA_NONE) { -- cgit v1.1 From 3a6b9138a066588649cf0387bf34d7068f0b19a6 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 28 Mar 2013 10:03:36 -0400 Subject: xen/events: Handle VIRQ_TIMER before any other hardirq in event loop. commit bee980d9e9642e96351fa3ca9077b853ecf62f57 upstream. This avoids any other hardirq handler seeing a very stale jiffies value immediately after wakeup from a long idle period. The one observable symptom of this was a USB keyboard, with software keyboard repeat, which would always repeat a key immediately that it was pressed. This is due to the key press waking the guest, the key handler immediately runs, sees an old jiffies value, and then that jiffies value significantly updated, before the key is unpressed. Reviewed-by: David Vrabel Signed-off-by: Keir Fraser Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/xen/events.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index a5493f8..a2f1f71 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -1153,7 +1153,7 @@ static void __xen_evtchn_do_upcall(void) { int start_word_idx, start_bit_idx; int word_idx, bit_idx; - int i; + int i, irq; int cpu = get_cpu(); struct shared_info *s = HYPERVISOR_shared_info; struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); @@ -1161,6 +1161,8 @@ static void __xen_evtchn_do_upcall(void) do { unsigned long pending_words; + unsigned long pending_bits; + struct irq_desc *desc; vcpu_info->evtchn_upcall_pending = 0; @@ -1171,6 +1173,17 @@ static void __xen_evtchn_do_upcall(void) /* Clear master flag /before/ clearing selector flag. */ wmb(); #endif + if ((irq = per_cpu(virq_to_irq, cpu)[VIRQ_TIMER]) != -1) { + int evtchn = evtchn_from_irq(irq); + word_idx = evtchn / BITS_PER_LONG; + pending_bits = evtchn % BITS_PER_LONG; + if (active_evtchns(cpu, s, word_idx) & (1ULL << pending_bits)) { + desc = irq_to_desc(irq); + if (desc) + generic_handle_irq_desc(irq, desc); + } + } + pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0); start_word_idx = __this_cpu_read(current_word_idx); @@ -1179,7 +1192,6 @@ static void __xen_evtchn_do_upcall(void) word_idx = start_word_idx; for (i = 0; pending_words != 0; i++) { - unsigned long pending_bits; unsigned long words; words = MASK_LSBS(pending_words, word_idx); @@ -1208,8 +1220,7 @@ static void __xen_evtchn_do_upcall(void) do { unsigned long bits; - int port, irq; - struct irq_desc *desc; + int port; bits = MASK_LSBS(pending_bits, bit_idx); -- cgit v1.1 From 48bcd39b354548d556911373d6c7f3ecfca9d043 Mon Sep 17 00:00:00 2001 From: Manoj Iyer Date: Mon, 6 Aug 2012 18:15:37 -0500 Subject: thinkpad-acpi: recognize latest V-Series using DMI_BIOS_VENDOR commit a4f46bb9fa84642e356898ee44b670989622f8bb upstream. In the latest V-series bios DMI_PRODUCT_VERSION does not contain the string Lenovo or Thinkpad, but is set to the model number, this causes the thinkpad_acpi module to fail to load. Recognize laptop as Lenovo using DMI_BIOS_VENDOR instead, which is set to Lenovo. Test on V490u ============= == After the patch == [ 1350.295757] thinkpad_acpi: ThinkPad ACPI Extras v0.24 [ 1350.295760] thinkpad_acpi: http://ibm-acpi.sf.net/ [ 1350.295761] thinkpad_acpi: ThinkPad BIOS H7ET21WW (1.00 ), EC unknown [ 1350.295763] thinkpad_acpi: Lenovo LENOVO, model LV5DXXX [ 1350.296086] thinkpad_acpi: detected a 8-level brightness capable ThinkPad [ 1350.296694] thinkpad_acpi: radio switch found; radios are enabled [ 1350.296703] thinkpad_acpi: possible tablet mode switch found; ThinkPad in laptop mode [ 1350.306466] thinkpad_acpi: rfkill switch tpacpi_bluetooth_sw: radio is unblocked [ 1350.307082] Registered led device: tpacpi::thinklight [ 1350.307215] Registered led device: tpacpi::power [ 1350.307255] Registered led device: tpacpi::standby [ 1350.307294] Registered led device: tpacpi::thinkvantage [ 1350.308160] thinkpad_acpi: Standard ACPI backlight interface available, not loading native one [ 1350.308333] thinkpad_acpi: Console audio control enabled, mode: monitor (read only) [ 1350.312287] input: ThinkPad Extra Buttons as /devices/platform/thinkpad_acpi/input/input14 == Before the patch == sudo modprobe thinkpad_acpi FATAL: Error inserting thinkpad_acpi (/lib/modules/3.2.0-27-generic/kernel/drivers/platform/x86/thinkpad_acpi.ko): No such device Test on B485 ============= This patch was also test in a B485 where the thinkpad_acpi module does not have any issues loading. But, I tested it to make sure this patch does not break on already functioning models of Lenovo products. [13486.746359] thinkpad_acpi: ThinkPad ACPI Extras v0.24 [13486.746364] thinkpad_acpi: http://ibm-acpi.sf.net/ [13486.746368] thinkpad_acpi: ThinkPad BIOS HJET15WW(1.01), EC unknown [13486.746373] thinkpad_acpi: Lenovo Lenovo LB485, model 814TR01 [13486.747300] thinkpad_acpi: detected a 8-level brightness capable ThinkPad [13486.752435] thinkpad_acpi: rfkill switch tpacpi_bluetooth_sw: radio is unblocked [13486.752883] Registered led device: tpacpi::thinklight [13486.752915] thinkpad_acpi: Standard ACPI backlight interface available, not loading native one [13486.753216] thinkpad_acpi: Console audio control enabled, mode: monitor (read only) [13486.757147] input: ThinkPad Extra Buttons as /devices/platform/thinkpad_acpi/input/input15 Signed-off-by: Manoj Iyer Signed-off-by: Matthew Garrett Cc: Shuduo Sang Signed-off-by: Greg Kroah-Hartman --- drivers/platform/x86/thinkpad_acpi.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 26c5b11..aaba423 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -8656,6 +8656,13 @@ static int __must_check __init get_thinkpad_model_data( tp->model_str = kstrdup(s, GFP_KERNEL); if (!tp->model_str) return -ENOMEM; + } else { + s = dmi_get_system_info(DMI_BIOS_VENDOR); + if (s && !(strnicmp(s, "Lenovo", 6))) { + tp->model_str = kstrdup(s, GFP_KERNEL); + if (!tp->model_str) + return -ENOMEM; + } } s = dmi_get_system_info(DMI_PRODUCT_NAME); -- cgit v1.1 From 3af312d74eeea767598d0b4f9e909e098599f4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Thu, 6 Jun 2013 12:57:24 +0200 Subject: USB: option: blacklist network interface on Huawei E1820 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit b8a24e6281d37243c06b9497dcbfaa98c1e2ad35 upstream. The mode used by Windows for the Huawei E1820 will use the same ff/ff/ff class codes for both serial and network functions. Reported-by: Graham Inggs Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 59c4997..8ea37bc 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -593,6 +593,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x14ac, 0xff, 0xff, 0xff), /* Huawei E1820 */ + .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) }, -- cgit v1.1 From c4e994727232f6106df6b21f96d3bfd4c04b3ed1 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 27 May 2013 14:44:42 +0200 Subject: USB: iuu_phoenix: fix bulk-message timeout commit 6c13ff68a7ce01da7a51b44241a7aad8eaaedde7 upstream. The bulk-message timeout is specified in milliseconds and should not depend on HZ. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/iuu_phoenix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 6aca631..cf2668e 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -327,7 +327,7 @@ static int bulk_immediate(struct usb_serial_port *port, u8 *buf, u8 count) usb_bulk_msg(serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), buf, - count, &actual, HZ * 1); + count, &actual, 1000); if (status != IUU_OPERATION_OK) dbg("%s - error = %2x", __func__, status); @@ -350,7 +350,7 @@ static int read_immediate(struct usb_serial_port *port, u8 *buf, u8 count) usb_bulk_msg(serial->dev, usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), buf, - count, &actual, HZ * 1); + count, &actual, 1000); if (status != IUU_OPERATION_OK) dbg("%s - error = %2x", __func__, status); -- cgit v1.1 From eedbcc70f665c043b7094b17092f6fc99c084c7f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 4 Jun 2013 18:50:29 +0200 Subject: USB: keyspan: fix bogus array index commit a07088098a650267b2eda689538133a324b9523f upstream. The outcont_endpoints array was indexed using the port minor number (which can be greater than the array size) rather than the device port number. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/keyspan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index a442352..4f415e2 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -1833,7 +1833,7 @@ static int keyspan_usa26_send_setup(struct usb_serial *serial, d_details = s_priv->device_details; device_port = port->number - port->serial->minor; - outcont_urb = d_details->outcont_endpoints[port->number]; + outcont_urb = d_details->outcont_endpoints[device_port]; this_urb = p_priv->outcont_urb; dbg("%s - endpoint %d", __func__, usb_pipeendpoint(this_urb->pipe)); -- cgit v1.1 From b40e7b1ead426706d4ca3193b484cec5df215106 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 27 May 2013 14:44:41 +0200 Subject: USB: ark3116: fix control-message timeout commit 634371911730a462626071065b64cd6e1fe213e0 upstream. The control-message timeout is specified in milliseconds and should not depend on HZ. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ark3116.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 18e875b..5cc633e 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -49,7 +49,7 @@ static int debug; #define DRIVER_NAME "ark3116" /* usb timeout of 1 second */ -#define ARK_TIMEOUT (1*HZ) +#define ARK_TIMEOUT 1000 static const struct usb_device_id id_table[] = { { USB_DEVICE(0x6547, 0x0232) }, -- cgit v1.1 From 1450a25582a8fab2c19d87182c98505173ec6bfa Mon Sep 17 00:00:00 2001 From: Robert Butora Date: Fri, 31 May 2013 18:09:51 +0300 Subject: USB: Serial: cypress_M8: Enable FRWD Dongle hidcom device commit 6529591e3eef65f0f528a81ac169f6e294b947a7 upstream. The patch adds a new HIDCOM device and does not affect other devices driven by the cypress_M8 module. Changes are: - add VendorID ProductID to device tables - skip unstable speed check because FRWD uses 115200bps - skip reset at probe which is an issue workaround for this particular device. Signed-off-by: Robert Butora Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cypress_m8.c | 18 +++++++++++++++++- drivers/usb/serial/cypress_m8.h | 4 ++++ 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index d9906eb..a75cce9 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -96,6 +96,7 @@ static const struct usb_device_id id_table_earthmate[] = { static const struct usb_device_id id_table_cyphidcomrs232[] = { { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, + { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) }, { } /* Terminating entry */ }; @@ -109,6 +110,7 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, { USB_DEVICE(VENDOR_ID_POWERCOM, PRODUCT_ID_UPS) }, + { USB_DEVICE(VENDOR_ID_FRWD, PRODUCT_ID_CYPHIDCOM_FRWD) }, { USB_DEVICE(VENDOR_ID_DAZZLE, PRODUCT_ID_CA42) }, { } /* Terminating entry */ }; @@ -268,6 +270,12 @@ static struct usb_serial_driver cypress_ca42v2_device = { * Cypress serial helper functions *****************************************************************************/ +/* FRWD Dongle hidcom needs to skip reset and speed checks */ +static inline bool is_frwd(struct usb_device *dev) +{ + return ((le16_to_cpu(dev->descriptor.idVendor) == VENDOR_ID_FRWD) && + (le16_to_cpu(dev->descriptor.idProduct) == PRODUCT_ID_CYPHIDCOM_FRWD)); +} static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate) { @@ -277,6 +285,10 @@ static int analyze_baud_rate(struct usb_serial_port *port, speed_t new_rate) if (unstable_bauds) return new_rate; + /* FRWD Dongle uses 115200 bps */ + if (is_frwd(port->serial->dev)) + return new_rate; + /* * The general purpose firmware for the Cypress M8 allows for * a maximum speed of 57600bps (I have no idea whether DeLorme @@ -490,7 +502,11 @@ static int generic_startup(struct usb_serial *serial) } init_waitqueue_head(&priv->delta_msr_wait); - usb_reset_configuration(serial->dev); + /* Skip reset for FRWD device. It is a workaound: + device hangs if it receives SET_CONFIGURE in Configured + state. */ + if (!is_frwd(serial->dev)) + usb_reset_configuration(serial->dev); priv->cmd_ctrl = 0; priv->line_control = 0; diff --git a/drivers/usb/serial/cypress_m8.h b/drivers/usb/serial/cypress_m8.h index 67cf608..b461311 100644 --- a/drivers/usb/serial/cypress_m8.h +++ b/drivers/usb/serial/cypress_m8.h @@ -24,6 +24,10 @@ #define VENDOR_ID_CYPRESS 0x04b4 #define PRODUCT_ID_CYPHIDCOM 0x5500 +/* FRWD Dongle - a GPS sports watch */ +#define VENDOR_ID_FRWD 0x6737 +#define PRODUCT_ID_CYPHIDCOM_FRWD 0x0001 + /* Powercom UPS, chip CY7C63723 */ #define VENDOR_ID_POWERCOM 0x0d9f #define PRODUCT_ID_UPS 0x0002 -- cgit v1.1 From 0317720b2f8c9d7c1b085a039b9a25cfad09a417 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 6 Jun 2013 13:32:47 +0200 Subject: USB: whiteheat: fix broken port configuration commit 9eecf22d2b375b9064a20421c6c307b760b03d46 upstream. When configuring the port (e.g. set_termios) the port minor number rather than the port number was used in the request (and they only coincide for minor number 0). Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/whiteheat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 59d646d..0ec60cd 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -1209,7 +1209,7 @@ static void firm_setup_port(struct tty_struct *tty) struct whiteheat_port_settings port_settings; unsigned int cflag = tty->termios->c_cflag; - port_settings.port = port->number + 1; + port_settings.port = port->number - port->serial->minor + 1; /* get the byte size */ switch (cflag & CSIZE) { -- cgit v1.1 From e1742ba57d747024a4f0c01c88a212b7e4d5e898 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 27 May 2013 14:44:37 +0200 Subject: USB: serial: fix Treo/Kyocera interrrupt-in urb context commit 5f8e2c07d75967ee49a5da1d21ddf5f50d48cda0 upstream. The first and second interrupt-in urbs are swapped for some Treo/Kyocera devices, but the urb context was never updated with the new port. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/visor.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 1c11959..189a894 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -600,6 +600,7 @@ static int treo_attach(struct usb_serial *serial) dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\ dest->bulk_in_buffer = src->bulk_in_buffer; \ dest->interrupt_in_urb = src->interrupt_in_urb; \ + dest->interrupt_in_urb->context = dest; \ dest->interrupt_in_endpointAddress = \ src->interrupt_in_endpointAddress;\ dest->interrupt_in_buffer = src->interrupt_in_buffer; \ -- cgit v1.1 From 9afcad40de6d98484d3d12305830656b882f76f1 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 28 May 2013 14:03:10 -0400 Subject: USB: revert periodic scheduling bugfix commit fdc03438f53a00294ed9939eb3a1f6db6f3d8963 upstream. This patch reverts commit 3e619d04159be54b3daa0b7036b0ce9e067f4b5d (USB: EHCI: fix bug in scheduling periodic split transfers). The commit was valid -- it fixed a real bug -- but the periodic scheduler in ehci-hcd is in such bad shape (especially the part that handles split transactions) that fixing one bug is very likely to cause another to surface. That's what happened in this case; the result was choppy and noisy playback on certain 24-bit audio devices. The only real fix will be to rewrite this entire section of code. My next project... This fixes https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1136110. Thanks to Tim Richardson for extra testing and feedback, and to Joseph Salisbury and Tyson Tan for tracking down the original source of the problem. Signed-off-by: Alan Stern CC: Joseph Salisbury CC: Tim Richardson Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 53192f2..8949b23 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -236,7 +236,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask) } static const unsigned char -max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 }; +max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 }; /* carryover low/fullspeed bandwidth that crosses uframe boundries */ static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8]) -- cgit v1.1 From e9ab9a9031d6224f01577a8fdfe8d380882b8b25 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 27 May 2013 14:44:39 +0200 Subject: USB: mos7720: fix DMA to stack commit 72ea18a558ed7a63a50bb121ba60d73b5b38ae30 upstream. The read_mos_reg function is called with stack-allocated buffers, which must not be used for control messages. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7720.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 40abedb..f235390 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -234,11 +234,22 @@ static int read_mos_reg(struct usb_serial *serial, unsigned int serial_portnum, __u8 requesttype = (__u8)0xc0; __u16 index = get_reg_index(reg); __u16 value = get_reg_value(reg, serial_portnum); - int status = usb_control_msg(usbdev, pipe, request, requesttype, value, - index, data, 1, MOS_WDR_TIMEOUT); - if (status < 0) + u8 *buf; + int status; + + buf = kmalloc(1, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + status = usb_control_msg(usbdev, pipe, request, requesttype, value, + index, buf, 1, MOS_WDR_TIMEOUT); + if (status == 1) + *data = *buf; + else if (status < 0) dev_err(&usbdev->dev, "mos7720: usb_control_msg() failed: %d", status); + kfree(buf); + return status; } -- cgit v1.1 From 061a4524510c25c2e594aaa86f6100bf82b20c5f Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 27 May 2013 14:44:43 +0200 Subject: USB: mos7720: fix message timeouts commit 849513a7809175420d353625b6f651d961e99d49 upstream. The control and bulk-message timeouts are specified in milliseconds and should not depend on HZ. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7720.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index f235390..6f33f29 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -44,7 +44,7 @@ #define DRIVER_DESC "Moschip USB Serial Driver" /* default urb timeout */ -#define MOS_WDR_TIMEOUT (HZ * 5) +#define MOS_WDR_TIMEOUT 5000 #define MOS_MAX_PORT 0x02 #define MOS_WRITE 0x0E @@ -2124,7 +2124,7 @@ static int mos7720_startup(struct usb_serial *serial) /* setting configuration feature to one */ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), - (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); + (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5000); /* start the interrupt urb */ ret_val = usb_submit_urb(serial->port[0]->interrupt_in_urb, GFP_KERNEL); @@ -2169,7 +2169,7 @@ static void mos7720_release(struct usb_serial *serial) /* wait for synchronous usb calls to return */ if (mos_parport->msg_pending) wait_for_completion_timeout(&mos_parport->syncmsg_compl, - MOS_WDR_TIMEOUT); + msecs_to_jiffies(MOS_WDR_TIMEOUT)); parport_remove_port(mos_parport->pp); usb_set_serial_data(serial, NULL); -- cgit v1.1 From 078da62e2285732cda0863cca0da10f5b69bf552 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 4 Jun 2013 18:50:31 +0200 Subject: USB: mos7720: fix hardware flow control commit a26f009a070e840fadacb91013b2391ba7ab6cc2 upstream. The register access to enable hardware flow control depends on the device port number and not the port minor number. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7720.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 6f33f29..703d1fa 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -1711,7 +1711,7 @@ static void change_port_settings(struct tty_struct *tty, mos7720_port->shadowMCR |= (UART_MCR_XONANY); /* To set hardware flow control to the specified * * serial port, in SP1/2_CONTROL_REG */ - if (port->number) + if (port_number) write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x01); else write_mos_reg(serial, dummy, SP_CONTROL_REG, 0x02); -- cgit v1.1 From d117eaaa99ceedbf4c73a6dabf2f92d330c3b71b Mon Sep 17 00:00:00 2001 From: Alex Hung Date: Tue, 28 May 2013 02:05:09 +0000 Subject: ACPI / video: ignore BIOS initial backlight value for HP m4 commit fedbe9bc6fd3e14b1ffbb3dac407777ac4a3650c upstream. On HP m4 lapops, BIOS reports minimum backlight on boot and causes backlight to dim completely. This ignores the initial backlight values and set to max brightness. References: https://bugs.launchpad.net/bugs/1184501 Signed-off-by: Alex Hung Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/video.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 76f0b94..30026613 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -448,6 +448,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13 - 2000 Notebook PC"), }, }, + { + .callback = video_ignore_initial_backlight, + .ident = "HP Pavilion m4", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion m4 Notebook PC"), + }, + }, {} }; -- cgit v1.1 From 87646a0da17e5368db84a14c506e9df588051acf Mon Sep 17 00:00:00 2001 From: Ash Willis Date: Wed, 29 May 2013 01:27:59 +0000 Subject: ACPI / video: ignore BIOS initial backlight value for HP Pavilion g6 commit 780a6ec640a3fed671fc2c40e4dd30c03eca3ac3 upstream. This patch addresses kernel bug 56661. BIOS reports an incorrect backlight value, causing the driver to switch off the backlight completely during startup. This patch ignores the incorrect value from BIOS. References: https://bugzilla.kernel.org/show_bug.cgi?id=56661 Signed-off-by: Ash Willis Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/video.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 30026613..6f42a5d 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -450,6 +450,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { }, { .callback = video_ignore_initial_backlight, + .ident = "HP Pavilion g6 Notebook PC", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion g6 Notebook PC"), + }, + }, + { + .callback = video_ignore_initial_backlight, .ident = "HP Pavilion m4", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), -- cgit v1.1 From bf204ada5b969c9f33b903795b5b0e530d389350 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 5 Jun 2013 14:09:30 -0700 Subject: hwmon: (adm1021) Strengthen chip detection for ADM1021, LM84 and MAX1617 commit 591bfcfc334a003ba31c0deff03b22e73349939b upstream. On a system with both MAX1617 and JC42 sensors, JC42 sensors can be misdetected as LM84. Strengthen detection sufficiently enough to avoid this misdetection. Also improve detection for ADM1021. Modeled after chip detection code in sensors-detect command. Signed-off-by: Guenter Roeck Tested-by: Jean Delvare Acked-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/adm1021.c | 58 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c index 1ad0a88..8178927 100644 --- a/drivers/hwmon/adm1021.c +++ b/drivers/hwmon/adm1021.c @@ -311,26 +311,68 @@ static int adm1021_detect(struct i2c_client *client, man_id = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID); dev_id = i2c_smbus_read_byte_data(client, ADM1021_REG_DEV_ID); + if (man_id < 0 || dev_id < 0) + return -ENODEV; + if (man_id == 0x4d && dev_id == 0x01) type_name = "max1617a"; else if (man_id == 0x41) { if ((dev_id & 0xF0) == 0x30) type_name = "adm1023"; - else + else if ((dev_id & 0xF0) == 0x00) type_name = "adm1021"; + else + return -ENODEV; } else if (man_id == 0x49) type_name = "thmc10"; else if (man_id == 0x23) type_name = "gl523sm"; else if (man_id == 0x54) type_name = "mc1066"; - /* LM84 Mfr ID in a different place, and it has more unused bits */ - else if (conv_rate == 0x00 - && (config & 0x7F) == 0x00 - && (status & 0xAB) == 0x00) - type_name = "lm84"; - else - type_name = "max1617"; + else { + int lte, rte, lhi, rhi, llo, rlo; + + /* extra checks for LM84 and MAX1617 to avoid misdetections */ + + llo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(0)); + rlo = i2c_smbus_read_byte_data(client, ADM1021_REG_THYST_R(1)); + + /* fail if any of the additional register reads failed */ + if (llo < 0 || rlo < 0) + return -ENODEV; + + lte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(0)); + rte = i2c_smbus_read_byte_data(client, ADM1021_REG_TEMP(1)); + lhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(0)); + rhi = i2c_smbus_read_byte_data(client, ADM1021_REG_TOS_R(1)); + + /* + * Fail for negative temperatures and negative high limits. + * This check also catches read errors on the tested registers. + */ + if ((s8)lte < 0 || (s8)rte < 0 || (s8)lhi < 0 || (s8)rhi < 0) + return -ENODEV; + + /* fail if all registers hold the same value */ + if (lte == rte && lte == lhi && lte == rhi && lte == llo + && lte == rlo) + return -ENODEV; + + /* + * LM84 Mfr ID is in a different place, + * and it has more unused bits. + */ + if (conv_rate == 0x00 + && (config & 0x7F) == 0x00 + && (status & 0xAB) == 0x00) { + type_name = "lm84"; + } else { + /* fail if low limits are larger than high limits */ + if ((s8)llo > lhi || (s8)rlo > rhi) + return -ENODEV; + type_name = "max1617"; + } + } pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n", type_name, i2c_adapter_id(adapter), client->addr); -- cgit v1.1 From ad712863393b6d3b772529c1726b3aa3375e3fc1 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Tue, 21 May 2013 06:23:43 +0000 Subject: drm: fix a use-after-free when GPU acceleration disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit b7ea85a4fed37835eec78a7be3039c8dc22b8178 upstream. When GPU acceleration is disabled, drm_vblank_cleanup() will free the vblank-related data, such as vblank_refcount, vblank_inmodeset, etc. But we found that drm_vblank_post_modeset() may be called after the cleanup, which use vblank_refcount and vblank_inmodeset. And this will cause a kernel panic. Fix this by return immediately if dev->num_crtcs is zero. This is the same thing that drm_vblank_pre_modeset() does. Call trace of a drm_vblank_post_modeset() after drm_vblank_cleanup(): [ 62.628906] [] drm_vblank_post_modeset+0x34/0xb4 [ 62.628906] [] atombios_crtc_dpms+0xb4/0x174 [ 62.628906] [] atombios_crtc_commit+0x18/0x38 [ 62.628906] [] drm_crtc_helper_set_mode+0x304/0x3cc [ 62.628906] [] drm_crtc_helper_set_config+0x6d8/0x988 [ 62.628906] [] drm_fb_helper_set_par+0x94/0x104 [ 62.628906] [] fbcon_init+0x424/0x57c [ 62.628906] [] visual_init+0xb8/0x118 [ 62.628906] [] take_over_console+0x238/0x384 [ 62.628906] [] fbcon_takeover+0x7c/0xdc [ 62.628906] [] notifier_call_chain+0x44/0x94 [ 62.628906] [] __blocking_notifier_call_chain+0x48/0x68 [ 62.628906] [] register_framebuffer+0x228/0x260 [ 62.628906] [] drm_fb_helper_single_fb_probe+0x260/0x314 [ 62.628906] [] drm_fb_helper_initial_config+0x200/0x234 [ 62.628906] [] radeon_fbdev_init+0xd4/0xf4 [ 62.628906] [] radeon_modeset_init+0x9bc/0xa18 [ 62.628906] [] radeon_driver_load_kms+0xdc/0x12c [ 62.628906] [] drm_get_pci_dev+0x148/0x238 [ 62.628906] [] local_pci_probe+0x5c/0xd0 [ 62.628906] [] work_for_cpu_fn+0x1c/0x30 [ 62.628906] [] process_one_work+0x274/0x3bc [ 62.628906] [] process_scheduled_works+0x24/0x44 [ 62.628906] [] worker_thread+0x31c/0x3f4 [ 62.628906] [] kthread+0x88/0x90 [ 62.628906] [] kernel_thread_helper+0x10/0x18 Signed-off-by: Huacai Chen Signed-off-by: Binbin Zhou Reviewed-by: Michel Dänzer Acked-by: Paul Menzel Signed-off-by: Dave Airlie Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_irq.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 2022a5c..3dc3c9e 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -976,7 +976,7 @@ EXPORT_SYMBOL(drm_vblank_off); */ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) { - /* vblank is not initialized (IRQ not installed ?) */ + /* vblank is not initialized (IRQ not installed ?), or has been freed */ if (!dev->num_crtcs) return; /* @@ -998,6 +998,10 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc) { unsigned long irqflags; + /* vblank is not initialized (IRQ not installed ?), or has been freed */ + if (!dev->num_crtcs) + return; + if (dev->vblank_inmodeset[crtc]) { spin_lock_irqsave(&dev->vbl_lock, irqflags); dev->vblank_disable_allowed = 1; -- cgit v1.1 From c4c2a7db886d6a7bb562fe5eebbb74ba043745b2 Mon Sep 17 00:00:00 2001 From: Egbert Eich Date: Tue, 4 Jun 2013 17:13:21 +0200 Subject: drm/i915/sdvo: Use &intel_sdvo->ddc instead of intel_sdvo->i2c for DDC. commit 53d3b4d7778daf15900867336c85d3f8dd70600c upstream. In intel_sdvo_get_lvds_modes() the wrong i2c adapter record is used for DDC. Thus the code will always have to rely on a LVDS panel mode supplied by VBT. In most cases this succeeds, so this didn't get detected for quite a while. This regression seems to have been introduced in commit f899fc64cda8569d0529452aafc0da31c042df2e Author: Chris Wilson Date: Tue Jul 20 15:44:45 2010 -0700 drm/i915: use GMBUS to manage i2c links Signed-off-by: Egbert Eich Reviewed-by: Chris Wilson [danvet: Add note about which commit likely introduced this issue.] Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_sdvo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d1141e8..05aae1c 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1609,7 +1609,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) * Assume that the preferred modes are * arranged in priority order. */ - intel_ddc_get_modes(connector, intel_sdvo->i2c); + intel_ddc_get_modes(connector, &intel_sdvo->ddc); if (list_empty(&connector->probed_modes) == false) goto end; -- cgit v1.1 From 9c9d7bf530c4d01e695fd9e8ba69006177d36a14 Mon Sep 17 00:00:00 2001 From: Andrew Worsley Date: Tue, 22 Nov 2011 20:00:19 +1100 Subject: USB: serial: ftdi_sio: Handle the old_termios == 0 case e.g. uart_resume_port() commit c515598e0f5769916c31c00392cc2bfe6af74e55 upstream. Handle null old_termios in ftdi_set_termios() calls from uart_resume_port(). Signed-off-by: Andrew Worsley Signed-off-by: Greg Kroah-Hartman Cc: Lotfi Manseur Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 7639cba..457122a 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2141,6 +2141,9 @@ static void ftdi_set_termios(struct tty_struct *tty, cflag = termios->c_cflag; + if (old_termios == 0) + goto no_skip; + if (old_termios->c_cflag == termios->c_cflag && old_termios->c_ispeed == termios->c_ispeed && old_termios->c_ospeed == termios->c_ospeed) @@ -2154,6 +2157,7 @@ static void ftdi_set_termios(struct tty_struct *tty, (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB))) goto no_data_parity_stop_changes; +no_skip: /* Set number of data bits, parity, stop bits */ urb_value = 0; -- cgit v1.1 From 24d54932440284584060455a81156f7ca4edff0e Mon Sep 17 00:00:00 2001 From: Ying Xue Date: Mon, 6 Aug 2012 17:46:37 +0800 Subject: USB: ftdi_sio: Quiet sparse noise about using plain integer was NULL pointer commit a816e3113b63753c330ca4751ea1d208e93e3015 upstream. Pointers should not be compared to plain integers. Quiets the sparse warning: warning: Using plain integer as NULL pointer Signed-off-by: Ying Xue Cc: Lotfi Manseur Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 457122a..45e55e2 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2141,7 +2141,7 @@ static void ftdi_set_termios(struct tty_struct *tty, cflag = termios->c_cflag; - if (old_termios == 0) + if (!old_termios) goto no_skip; if (old_termios->c_cflag == termios->c_cflag -- cgit v1.1 From 720083f1dc15ac6b6fb85b323d0eae1a151e20ce Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 10 May 2013 14:48:21 -0700 Subject: b43: stop format string leaking into error msgs commit e0e29b683d6784ef59bbc914eac85a04b650e63c upstream. The module parameter "fwpostfix" is userspace controllable, unfiltered, and is used to define the firmware filename. b43_do_request_fw() populates ctx->errors[] on error, containing the firmware filename. b43err() parses its arguments as a format string. For systems with b43 hardware, this could lead to a uid-0 to ring-0 escalation. CVE-2013-2852 Signed-off-by: Kees Cook Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/b43/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 7c2e09a..4db716b 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2309,7 +2309,7 @@ static int b43_request_firmware(struct b43_wldev *dev) for (i = 0; i < B43_NR_FWTYPES; i++) { errmsg = ctx->errors[i]; if (strlen(errmsg)) - b43err(dev->wl, errmsg); + b43err(dev->wl, "%s", errmsg); } b43_print_fw_helptext(dev->wl, 1); err = -ENOENT; -- cgit v1.1 From 319d630e7f0778c8999f6ef503998a4d99cee5f1 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Sat, 1 Jun 2013 07:08:09 +0530 Subject: ath9k: Disable PowerSave by default commit 531671cb17af07281e6f28c1425f754346e65c41 upstream. Almost all the DMA issues which have plagued ath9k (in station mode) for years are related to PS. Disabling PS usually "fixes" the user's connection stablility. Reports of DMA problems are still trickling in and are sitting in the kernel bugzilla. Until the PS code in ath9k is given a thorough review, disbale it by default. The slight increase in chip power consumption is a small price to pay for improved link stability. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/init.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 5a9fd21..d6059a2 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -704,8 +704,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); - if (AR_SREV_5416(sc->sc_ah)) - hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; -- cgit v1.1 From bac5719cdfb081dd68b0eeef7d9796c15fc29811 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 10 Jun 2013 09:47:58 +0200 Subject: drm/i915: prefer VBT modes for SVDO-LVDS over EDID commit c3456fb3e4712d0448592af3c5d644c9472cd3c1 upstream. In commit 53d3b4d7778daf15900867336c85d3f8dd70600c Author: Egbert Eich Date: Tue Jun 4 17:13:21 2013 +0200 drm/i915/sdvo: Use &intel_sdvo->ddc instead of intel_sdvo->i2c for DDC Egbert Eich fixed a long-standing bug where we simply used a non-working i2c controller to read the EDID for SDVO-LVDS panels. Unfortunately some machines seem to not be able to cope with the mode provided in the EDID. Specifically they seem to not be able to cope with a 4x pixel mutliplier instead of a 2x one, which seems to have been worked around by slightly changing the panels native mode in the VBT so that the dotclock is just barely above 50MHz. Since it took forever to notice the breakage it's fairly safe to assume that at least for SDVO-LVDS panels the VBT contains fairly sane data. So just switch around the order and use VBT modes first. v2: Also add EDID modes just in case, and spell Egbert correctly. v3: Elaborate a bit more about what's going on on Chris' machine. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=65524 Reported-and-tested-by: Chris Wilson Cc: Egbert Eich Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_sdvo.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 05aae1c..06b51ff 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1610,10 +1610,13 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) * arranged in priority order. */ intel_ddc_get_modes(connector, &intel_sdvo->ddc); - if (list_empty(&connector->probed_modes) == false) - goto end; - /* Fetch modes from VBT */ + /* + * Fetch modes from VBT. For SDVO prefer the VBT mode since some + * SDVO->LVDS transcoders can't cope with the EDID mode. Since + * drm_mode_probed_add adds the mode at the head of the list we add it + * last. + */ if (dev_priv->sdvo_lvds_vbt_mode != NULL) { newmode = drm_mode_duplicate(connector->dev, dev_priv->sdvo_lvds_vbt_mode); @@ -1625,7 +1628,6 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) } } -end: list_for_each_entry(newmode, &connector->probed_modes, head) { if (newmode->type & DRM_MODE_TYPE_PREFERRED) { intel_sdvo->sdvo_lvds_fixed_mode = -- cgit v1.1 From cc56da01f9325fd72ebf4d759b8333020bdc5f6c Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Thu, 16 May 2013 22:25:34 +0000 Subject: gianfar: add missing iounmap() on error in gianfar_ptp_probe() [ Upstream commit e5f5e380e0f3bb11f04ca5bc66a551e58e0ad26e ] Add the missing iounmap() before return from gianfar_ptp_probe() in the error handling case. Signed-off-by: Wei Yongjun Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/gianfar_ptp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/gianfar_ptp.c b/drivers/net/gianfar_ptp.c index c413479..68cfa08 100644 --- a/drivers/net/gianfar_ptp.c +++ b/drivers/net/gianfar_ptp.c @@ -521,6 +521,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) return 0; no_clock: + iounmap(etsects->regs); no_ioremap: release_resource(etsects->rsrc); no_resource: -- cgit v1.1 From c77a0bc75e37339dcbd4caf20d5ce2a4e7070740 Mon Sep 17 00:00:00 2001 From: Anders Hammarquist Date: Wed, 19 Jun 2013 01:45:48 +0200 Subject: USB: serial: ti_usb_3410_5052: new device id for Abbot strip port cable commit 35a2fbc941accd0e9f1bfadd669311786118d874 upstream. Add product id for Abbott strip port cable for Precision meter which uses the TI 3410 chip. Signed-off-by: Anders Hammarquist Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ti_usb_3410_5052.c | 3 ++- drivers/usb/serial/ti_usb_3410_5052.h | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 2856474..a8c4f44 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -179,7 +179,8 @@ static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = { { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, - { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) }, + { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STEREO_PLUG_ID) }, + { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) }, { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, }; diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h index b353e7e..4a2423e 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.h +++ b/drivers/usb/serial/ti_usb_3410_5052.h @@ -52,7 +52,9 @@ /* Abbott Diabetics vendor and product ids */ #define ABBOTT_VENDOR_ID 0x1a61 -#define ABBOTT_PRODUCT_ID 0x3410 +#define ABBOTT_STEREO_PLUG_ID 0x3410 +#define ABBOTT_PRODUCT_ID ABBOTT_STEREO_PLUG_ID +#define ABBOTT_STRIP_PORT_ID 0x3420 /* Commands */ #define TI_GET_VERSION 0x01 -- cgit v1.1 From 72ad35befc4715ebb0d715b90f27572ef11a15e2 Mon Sep 17 00:00:00 2001 From: Zefan Li Date: Wed, 26 Jun 2013 15:29:54 +0800 Subject: dlci: acquire rtnl_lock before calling __dev_get_by_name() commit 11eb2645cbf38a08ae491bf6c602eea900ec0bb5 upstream. Otherwise the net device returned can be freed at anytime. Signed-off-by: Li Zefan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/wan/dlci.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index 21b104d..df65aca 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c @@ -378,20 +378,24 @@ static int dlci_del(struct dlci_add *dlci) struct net_device *master, *slave; int err; + rtnl_lock(); + /* validate slave device */ master = __dev_get_by_name(&init_net, dlci->devname); - if (!master) - return -ENODEV; + if (!master) { + err = -ENODEV; + goto out; + } if (netif_running(master)) { - return -EBUSY; + err = -EBUSY; + goto out; } dlp = netdev_priv(master); slave = dlp->slave; flp = netdev_priv(slave); - rtnl_lock(); err = (*flp->deassoc)(slave, master); if (!err) { list_del(&dlp->list); @@ -400,8 +404,8 @@ static int dlci_del(struct dlci_add *dlci) dev_put(slave); } +out: rtnl_unlock(); - return err; } -- cgit v1.1 From 806f529730af538c2edbb805589c48cc19ad169b Mon Sep 17 00:00:00 2001 From: Zefan Li Date: Wed, 26 Jun 2013 15:31:58 +0800 Subject: dlci: validate the net device in dlci_del() commit 578a1310f2592ba90c5674bca21c1dbd1adf3f0a upstream. We triggered an oops while running trinity with 3.4 kernel: BUG: unable to handle kernel paging request at 0000000100000d07 IP: [] dlci_ioctl+0xd8/0x2d4 [dlci] PGD 640c0d067 PUD 0 Oops: 0000 [#1] PREEMPT SMP CPU 3 ... Pid: 7302, comm: trinity-child3 Not tainted 3.4.24.09+ 40 Huawei Technologies Co., Ltd. Tecal RH2285 /BC11BTSA RIP: 0010:[] [] dlci_ioctl+0xd8/0x2d4 [dlci] ... Call Trace: [] sock_ioctl+0x153/0x280 [] do_vfs_ioctl+0xa4/0x5e0 [] ? fget_light+0x3ea/0x490 [] sys_ioctl+0x4f/0x80 [] system_call_fastpath+0x16/0x1b ... It's because the net device is not a dlci device. Reported-by: Li Jinyue Signed-off-by: Li Zefan Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/wan/dlci.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index df65aca..af44b93 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c @@ -377,6 +377,7 @@ static int dlci_del(struct dlci_add *dlci) struct frad_local *flp; struct net_device *master, *slave; int err; + bool found = false; rtnl_lock(); @@ -387,6 +388,17 @@ static int dlci_del(struct dlci_add *dlci) goto out; } + list_for_each_entry(dlp, &dlci_devs, list) { + if (dlp->master == master) { + found = true; + break; + } + } + if (!found) { + err = -ENODEV; + goto out; + } + if (netif_running(master)) { err = -EBUSY; goto out; -- cgit v1.1 From db61e4ec623437237d05b5ab8ce97d9377682de2 Mon Sep 17 00:00:00 2001 From: Liang Li Date: Sat, 19 Jan 2013 17:52:10 +0800 Subject: pch_uart: fix a deadlock when pch_uart as console commit 384e301e3519599b000c1a2ecd938b533fc15d85 upstream. When we use pch_uart as system console like 'console=ttyPCH0,115200', then 'send break' to it. We'll encounter the deadlock on a cpu/core, with interrupts disabled on the core. When we happen to have all irqs affinity to cpu0 then the deadlock on cpu0 actually deadlock whole system. In pch_uart_interrupt, we have spin_lock_irqsave(&priv->lock, flags) then call pch_uart_err_ir when break is received. Then the call to dev_err would actually call to pch_console_write then we'll run into another spin_lock(&priv->lock), with interrupts disabled. So in the call sequence lead by pch_uart_interrupt, we should be carefully to call functions that will 'print message to console' only in case the uart port is not being used as serial console. Signed-off-by: Liang Li Cc: Yijing Wang Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 73038ba..78c26ca 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -935,22 +935,37 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) static void pch_uart_err_ir(struct eg20t_port *priv, unsigned int lsr) { u8 fcr = ioread8(priv->membase + UART_FCR); + struct uart_port *port = &priv->port; + struct tty_struct *tty = tty_port_tty_get(&port->state->port); + char *error_msg[5] = {}; + int i = 0; /* Reset FIFO */ fcr |= UART_FCR_CLEAR_RCVR; iowrite8(fcr, priv->membase + UART_FCR); if (lsr & PCH_UART_LSR_ERR) - dev_err(&priv->pdev->dev, "Error data in FIFO\n"); + error_msg[i++] = "Error data in FIFO\n"; - if (lsr & UART_LSR_FE) - dev_err(&priv->pdev->dev, "Framing Error\n"); + if (lsr & UART_LSR_FE) { + port->icount.frame++; + error_msg[i++] = " Framing Error\n"; + } - if (lsr & UART_LSR_PE) - dev_err(&priv->pdev->dev, "Parity Error\n"); + if (lsr & UART_LSR_PE) { + port->icount.parity++; + error_msg[i++] = " Parity Error\n"; + } - if (lsr & UART_LSR_OE) - dev_err(&priv->pdev->dev, "Overrun Error\n"); + if (lsr & UART_LSR_OE) { + port->icount.overrun++; + error_msg[i++] = " Overrun Error\n"; + } + + if (tty == NULL) { + for (i = 0; error_msg[i] != NULL; i++) + dev_err(&priv->pdev->dev, error_msg[i]); + } } static irqreturn_t pch_uart_interrupt(int irq, void *dev_id) -- cgit v1.1 From a6ca6dff63f92efa17810ac0a4d33e3b63670482 Mon Sep 17 00:00:00 2001 From: Jonathan Salwan Date: Wed, 3 Jul 2013 15:01:13 -0700 Subject: drivers/cdrom/cdrom.c: use kzalloc() for failing hardware commit 542db01579fbb7ea7d1f7bb9ddcef1559df660b2 upstream. In drivers/cdrom/cdrom.c mmc_ioctl_cdrom_read_data() allocates a memory area with kmalloc in line 2885. 2885 cgc->buffer = kmalloc(blocksize, GFP_KERNEL); 2886 if (cgc->buffer == NULL) 2887 return -ENOMEM; In line 2908 we can find the copy_to_user function: 2908 if (!ret && copy_to_user(arg, cgc->buffer, blocksize)) The cgc->buffer is never cleaned and initialized before this function. If ret = 0 with the previous basic block, it's possible to display some memory bytes in kernel space from userspace. When we read a block from the disk it normally fills the ->buffer but if the drive is malfunctioning there is a chance that it would only be partially filled. The result is an leak information to userspace. Signed-off-by: Dan Carpenter Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Cc: Jonathan Salwan Cc: Luis Henriques Signed-off-by: Greg Kroah-Hartman --- drivers/cdrom/cdrom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index cc6471a..fd484a9 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -2879,7 +2879,7 @@ static noinline int mmc_ioctl_cdrom_read_data(struct cdrom_device_info *cdi, if (lba < 0) return -EINVAL; - cgc->buffer = kmalloc(blocksize, GFP_KERNEL); + cgc->buffer = kzalloc(blocksize, GFP_KERNEL); if (cgc->buffer == NULL) return -ENOMEM; -- cgit v1.1 From cb065a908d47441cfc660d1cc0a50fceefa0cda0 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 3 Jul 2013 15:01:14 -0700 Subject: block: do not pass disk names as format strings commit ffc8b30866879ed9ba62bd0a86fecdbd51cd3d19 upstream. Disk names may contain arbitrary strings, so they must not be interpreted as format strings. It seems that only md allows arbitrary strings to be used for disk names, but this could allow for a local memory corruption from uid 0 into ring 0. CVE-2013-2851 Signed-off-by: Kees Cook Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/block/nbd.c | 3 ++- drivers/scsi/osd/osd_uld.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index f533f33..12a7368 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -658,7 +658,8 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo, mutex_unlock(&lo->tx_lock); - thread = kthread_create(nbd_thread, lo, lo->disk->disk_name); + thread = kthread_create(nbd_thread, lo, "%s", + lo->disk->disk_name); if (IS_ERR(thread)) { mutex_lock(&lo->tx_lock); return PTR_ERR(thread); diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c index d4ed9eb..caac1b2 100644 --- a/drivers/scsi/osd/osd_uld.c +++ b/drivers/scsi/osd/osd_uld.c @@ -465,7 +465,7 @@ static int osd_probe(struct device *dev) oud->class_dev.class = &osd_uld_class; oud->class_dev.parent = dev; oud->class_dev.release = __remove; - error = dev_set_name(&oud->class_dev, disk->disk_name); + error = dev_set_name(&oud->class_dev, "%s", disk->disk_name); if (error) { OSD_ERR("dev_set_name failed => %d\n", error); goto err_put_cdev; -- cgit v1.1 From 3bb0ab9e10eecc932df94807cacb90ca30010cb7 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 27 May 2013 19:07:19 +0100 Subject: SCSI: sd: Fix parsing of 'temporary ' cache mode prefix commit 2ee3e26c673e75c05ef8b914f54fadee3d7b9c88 upstream. Commit 39c60a0948cc '[SCSI] sd: fix array cache flushing bug causing performance problems' added temp as a pointer to "temporary " and used sizeof(temp) - 1 as its length. But sizeof(temp) is the size of the pointer, not the size of the string constant. Change temp to a static array so that sizeof() does what was intended. Signed-off-by: Ben Hutchings Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 7db7eb7..43c7a90 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -138,7 +138,7 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, char *buffer_data; struct scsi_mode_data data; struct scsi_sense_hdr sshdr; - const char *temp = "temporary "; + static const char temp[] = "temporary "; int len; if (sdp->type != TYPE_DISK) -- cgit v1.1 From 4a5152cd2778b10414d2184b6d31c71a1e068e97 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 20 Jun 2013 16:07:40 -0500 Subject: USB: option,qcserial: move Novatel Gobi1K IDs to qcserial commit a254810a86aaaac4ac6ba44fa934558b042a17a7 upstream. These devices are all Gobi1K devices (according to the Windows INF files) and should be handled by qcserial instead of option. Their network port is handled by qmi_wwan. Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 4 ---- drivers/usb/serial/qcserial.c | 8 +++++++- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 8ea37bc..b8365a7 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -159,8 +159,6 @@ static void option_instat_callback(struct urb *urb); #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000 #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001 #define NOVATELWIRELESS_PRODUCT_E362 0x9010 -#define NOVATELWIRELESS_PRODUCT_G1 0xA001 -#define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 #define NOVATELWIRELESS_PRODUCT_G2 0xA010 #define NOVATELWIRELESS_PRODUCT_MC551 0xB001 @@ -744,8 +742,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC547) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1_M) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 03d5f93..a7cd6fd 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -36,7 +36,13 @@ static const struct usb_device_id id_table[] = { {DEVICE_G1K(0x04da, 0x250c)}, /* Panasonic Gobi QDL device */ {DEVICE_G1K(0x413c, 0x8172)}, /* Dell Gobi Modem device */ {DEVICE_G1K(0x413c, 0x8171)}, /* Dell Gobi QDL device */ - {DEVICE_G1K(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ + {DEVICE_G1K(0x1410, 0xa001)}, /* Novatel/Verizon USB-1000 */ + {DEVICE_G1K(0x1410, 0xa002)}, /* Novatel Gobi Modem device */ + {DEVICE_G1K(0x1410, 0xa003)}, /* Novatel Gobi Modem device */ + {DEVICE_G1K(0x1410, 0xa004)}, /* Novatel Gobi Modem device */ + {DEVICE_G1K(0x1410, 0xa005)}, /* Novatel Gobi Modem device */ + {DEVICE_G1K(0x1410, 0xa006)}, /* Novatel Gobi Modem device */ + {DEVICE_G1K(0x1410, 0xa007)}, /* Novatel Gobi Modem device */ {DEVICE_G1K(0x1410, 0xa008)}, /* Novatel Gobi QDL device */ {DEVICE_G1K(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ {DEVICE_G1K(0x0b05, 0x1774)}, /* Asus Gobi QDL device */ -- cgit v1.1 From fad6ba80759e3efa6e0a7a1463cf3e506f53b85f Mon Sep 17 00:00:00 2001 From: UCHINO Satoshi Date: Thu, 23 May 2013 11:10:11 +0900 Subject: usb: gadget: f_mass_storage: add missing memory barrier for thread_wakeup_needed commit d68c277b501889b3a50c179d1c3d704db7947b83 upstream. Without this memory barrier, the file-storage thread may fail to escape from the following while loop, because it may observe new common->thread_wakeup_needed and old bh->state which are updated by the callback functions. /* Wait for the CBW to arrive */ while (bh->state != BUF_STATE_FULL) { rc = sleep_thread(common); if (rc) return rc; } Signed-off-by: UCHINO Satoshi Acked-by: Michal Nazarewicz Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/f_mass_storage.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 3bbdc9a..8826763 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -513,6 +513,7 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) /* Caller must hold fsg->lock */ static void wakeup_thread(struct fsg_common *common) { + smp_wmb(); /* ensure the write of bh->state is complete */ /* Tell the main thread that something has happened */ common->thread_wakeup_needed = 1; if (common->thread_task) @@ -730,6 +731,7 @@ static int sleep_thread(struct fsg_common *common) } __set_current_state(TASK_RUNNING); common->thread_wakeup_needed = 0; + smp_rmb(); /* ensure the latest bh->state is visible */ return rc; } -- cgit v1.1 From 281eb7655ac766335f8fe47da6695e538dc063df Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Mon, 17 Jun 2013 09:56:33 -0700 Subject: xhci: check for failed dma pool allocation commit 025f880cb2e4d7218d0422d4b07bea1a68959c38 upstream. Fail and free the container context in case dma_pool_alloc() can't allocate the raw context data part of it This patch should be backported to kernels as old as 2.6.31, that contain the commit d115b04818e57bdbc7ccde4d0660b15e33013dc8 "USB: xhci: Support for 64-byte contexts". Signed-off-by: Mathias Nyman Signed-off-by: Sarah Sharp Cc: John Youn Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mem.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index af65322..45ff7ba 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -273,6 +273,10 @@ static struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci ctx->size += CTX_SIZE(xhci->hcc_params); ctx->bytes = dma_pool_alloc(xhci->device_pool, flags, &ctx->dma); + if (!ctx->bytes) { + kfree(ctx); + return NULL; + } memset(ctx->bytes, 0, ctx->size); return ctx; } -- cgit v1.1 From cf1febd5483958b2826de88f321df3f5856ed547 Mon Sep 17 00:00:00 2001 From: Joachim Eastwood Date: Thu, 6 Jun 2013 10:24:14 +0200 Subject: pcmcia: at91_cf: fix gpio_get_value in at91_cf_get_status commit e39506b466edcda2a7e9d0174d7987ae654137b7 upstream. Commit 80af9e6d (pcmcia at91_cf: fix raw gpio number usage) forgot to change the parameter in gpio_get_value after adding gpio validation. Signed-off-by: Joachim Eastwood Signed-off-by: Nicolas Ferre Acked-by: Jean-Christophe PLAGNIOL-VILLARD Signed-off-by: Greg Kroah-Hartman --- drivers/pcmcia/at91_cf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index fb33fa4..cb0ff91 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c @@ -99,9 +99,9 @@ static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp) int vcc = cf->board->vcc_pin; *sp = SS_DETECT | SS_3VCARD; - if (!rdy || gpio_get_value(rdy)) + if (!rdy || gpio_get_value(cf->board->irq_pin)) *sp |= SS_READY; - if (!vcc || gpio_get_value(vcc)) + if (!vcc || gpio_get_value(cf->board->vcc_pin)) *sp |= SS_POWERON; } else *sp = 0; -- cgit v1.1 From 1cb58457fa8a025e39363ef8496279a30c75f280 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 3 Jul 2013 15:06:45 -0700 Subject: drivers/rtc/rtc-rv3029c2.c: fix disabling AIE irq commit 29ecd78c0fd6ee05f2c6b07b23823a6ae43c13ff upstream. In the disable AIE irq code path, current code passes "1" to enable parameter of rv3029c2_rtc_i2c_alarm_set_irq(). Thus it does not disable AIE irq. Signed-off-by: Axel Lin Acked-by: Heiko Schocher Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/rtc/rtc-rv3029c2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-rv3029c2.c b/drivers/rtc/rtc-rv3029c2.c index ea09ff2..5317d94 100644 --- a/drivers/rtc/rtc-rv3029c2.c +++ b/drivers/rtc/rtc-rv3029c2.c @@ -310,7 +310,7 @@ static int rv3029c2_rtc_i2c_set_alarm(struct i2c_client *client, dev_dbg(&client->dev, "alarm IRQ armed\n"); } else { /* disable AIE irq */ - ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 1); + ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 0); if (ret) return ret; -- cgit v1.1 From 16bfeaafd474e38a6b19b2f76ef4d665f9b1b0f9 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Wed, 5 Jun 2013 02:27:51 +0000 Subject: ACPI / EC: Add HP Folio 13 to ec_dmi_table in order to skip DSDT scan commit eff9a4b62b14cf0d9913e3caf1f26f8b7a6105c9 upstream. HP Folio 13's BIOS defines CMOS RTC Operation Region and the EC's _REG method will access that region. To allow the CMOS RTC region handler to be installed before the EC _REG method is first invoked, add ec_skip_dsdt_scan() as HP Folio 13's callback to ec_dmi_table. References: https://bugzilla.kernel.org/show_bug.cgi?id=54621 Reported-and-tested-by: Stefan Nagy Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/ec.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 51de186..9cb436a 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -964,6 +964,10 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { ec_enlarge_storm_threshold, "CLEVO hardware", { DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."), DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL}, + { + ec_skip_dsdt_scan, "HP Folio 13", { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL}, {}, }; -- cgit v1.1 From 5e9516f6d5f1f24e8b4f0327caf3d197400d3c1e Mon Sep 17 00:00:00 2001 From: Shane Huang Date: Mon, 3 Jun 2013 18:24:10 +0800 Subject: ahci: Add AMD CZ SATA device ID commit fafe5c3d82a470d73de53e6b08eb4e28d974d895 upstream. To add AMD CZ SATA controller device ID of IDE mode. [bhelgaas: drop pci_ids.h update] Signed-off-by: Shane Huang Signed-off-by: Bjorn Helgaas Reviewed-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/ahci.c | 1 + drivers/pci/quirks.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 75a8d0f..f3d09f3 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -284,6 +284,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { /* AMD */ { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */ + { PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */ /* AMD is using RAID class only for ahci controllers */ { PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci }, diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index a9b1249..f097df2 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1122,6 +1122,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE, quirk_amd_ide_mode); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SATA_IDE, quirk_amd_ide_mode); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x7900, quirk_amd_ide_mode); +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, 0x7900, quirk_amd_ide_mode); /* * Serverworks CSB5 IDE does not fully support native mode -- cgit v1.1 From b53a038e4d4e68ebbee7eddbd9c8793d75c5fe3f Mon Sep 17 00:00:00 2001 From: Shane Huang Date: Sat, 8 Jun 2013 16:00:16 +0800 Subject: ahci: remove pmp link online check in FBS EH commit 912b9ac683b112615d5605686f1dc086402ce9f7 upstream. ata_link_online() check in ahci_error_intr() is unnecessary, it should be removed otherwise may lead to lockup with FBS enabled PMP. http://marc.info/?l=linux-ide&m=137050421603272&w=2 Reported-by: Yu Liu Signed-off-by: Shane Huang Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libahci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 41223c7..b64e4a7 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1495,8 +1495,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) u32 fbs = readl(port_mmio + PORT_FBS); int pmp = fbs >> PORT_FBS_DWE_OFFSET; - if ((fbs & PORT_FBS_SDE) && (pmp < ap->nr_pmp_links) && - ata_link_online(&ap->pmp_link[pmp])) { + if ((fbs & PORT_FBS_SDE) && (pmp < ap->nr_pmp_links)) { link = &ap->pmp_link[pmp]; fbs_need_dec = true; } -- cgit v1.1 From 6fe0ab4d8e8b794e1d59ace3969ca8da259b25e3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Wed, 3 Jul 2013 15:00:43 -0700 Subject: drivers/dma/pl330.c: fix locking in pl330_free_chan_resources() commit da331ba8e9c5de72a27e50f71105395bba6eebe0 upstream. tasklet_kill() may sleep so call it before taking pch->lock. Fixes following lockup: BUG: scheduling while atomic: cat/2383/0x00000002 Modules linked in: unwind_backtrace+0x0/0xfc __schedule_bug+0x4c/0x58 __schedule+0x690/0x6e0 sys_sched_yield+0x70/0x78 tasklet_kill+0x34/0x8c pl330_free_chan_resources+0x24/0x88 dma_chan_put+0x4c/0x50 [...] BUG: spinlock lockup suspected on CPU#0, swapper/0/0 lock: 0xe52aa04c, .magic: dead4ead, .owner: cat/2383, .owner_cpu: 1 unwind_backtrace+0x0/0xfc do_raw_spin_lock+0x194/0x204 _raw_spin_lock_irqsave+0x20/0x28 pl330_tasklet+0x2c/0x5a8 tasklet_action+0xfc/0x114 __do_softirq+0xe4/0x19c irq_exit+0x98/0x9c handle_IPI+0x124/0x16c gic_handle_irq+0x64/0x68 __irq_svc+0x40/0x70 cpuidle_wrap_enter+0x4c/0xa0 cpuidle_enter_state+0x18/0x68 cpuidle_idle_call+0xac/0xe0 cpu_idle+0xac/0xf0 Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Kyungmin Park Acked-by: Jassi Brar Cc: Vinod Koul Cc: Tomasz Figa Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/dma/pl330.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 6abe1ec..4802aac 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -281,10 +281,10 @@ static void pl330_free_chan_resources(struct dma_chan *chan) struct dma_pl330_chan *pch = to_pchan(chan); unsigned long flags; - spin_lock_irqsave(&pch->lock, flags); - tasklet_kill(&pch->task); + spin_lock_irqsave(&pch->lock, flags); + pl330_release_channel(pch->pl330_chid); pch->pl330_chid = NULL; -- cgit v1.1 From 1d912e701574a3327199d20d280f010b479a41af Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Sat, 22 Jun 2013 13:13:25 +0200 Subject: rt2x00: read 5GHz TX power values from the correct offset commit 0a6f3a8ebaf13407523c2c7d575b4ca2debd23ba upstream. The current code uses the same index value both for the channel information array and for the TX power table. The index starts from 14, however the index of the TX power table must start from zero. Fix it, in order to get the correct TX power value for a given channel. The changes in rt61pci.c and rt73usb.c are compile tested only. Signed-off-by: Gabor Juhos Acked-by: Stanislaw Gruszka Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/rt2x00/rt2800lib.c | 4 ++-- drivers/net/wireless/rt2x00/rt61pci.c | 3 ++- drivers/net/wireless/rt2x00/rt73usb.c | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index d44ce30..9457987 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -4075,8 +4075,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); for (i = 14; i < spec->num_channels; i++) { - info[i].default_power1 = default_power1[i]; - info[i].default_power2 = default_power2[i]; + info[i].default_power1 = default_power1[i - 14]; + info[i].default_power2 = default_power2[i - 14]; } } diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 17de24e..dd31588 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -2830,7 +2830,8 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); for (i = 14; i < spec->num_channels; i++) { info[i].max_power = MAX_TXPOWER; - info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + info[i].default_power1 = + TXPOWER_FROM_DEV(tx_power[i - 14]); } } diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 1a06231..3b68155 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -2167,7 +2167,8 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); for (i = 14; i < spec->num_channels; i++) { info[i].max_power = MAX_TXPOWER; - info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + info[i].default_power1 = + TXPOWER_FROM_DEV(tx_power[i - 14]); } } -- cgit v1.1 From ddaf85745502f71e6a873c5cb6c975a3b0993bbc Mon Sep 17 00:00:00 2001 From: Daniel Hansel Date: Fri, 26 Apr 2013 17:32:14 +0200 Subject: SCSI: zfcp: fix adapter (re)open recovery while link to SAN is down commit f76ccaac4f82c463a037aa4a1e4ccb85c7011814 upstream. FCP device remains in status ERP_FAILED when device is switched online or adapter recovery is triggered while link to SAN is down. When Exchange Configuration Data command returns the FSF status FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE it aborts the exchange process. The only retries are done during the common error recovery procedure (i.e. max. 3 retries with 8sec sleep between) and remains in status ERP_FAILED with QDIO down. This commit reverts the commit 0df138476c8306478d6e726f044868b4bccf411c (zfcp: Fix adapter activation on link down). When FSF status FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE is received the adapter recovery will be finished without any retries. QDIO will be up now and status changes such as LINK UP will be received now. Signed-off-by: Daniel Hansel Signed-off-by: Steffen Maier Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/s390/scsi/zfcp_fsf.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 6e73bfe..8976d02 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -534,6 +534,10 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req) fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; adapter->hydra_version = 0; + /* avoids adapter shutdown to be able to recognize + * events such as LINK UP */ + atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, + &adapter->status); zfcp_fsf_link_down_info_eval(req, &qtcb->header.fsf_status_qual.link_down_info); break; -- cgit v1.1 From 9fdc84e56b76450d0d252893aa0ca87f69ba65df Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Sat, 2 Feb 2013 00:58:20 +0530 Subject: SCSI: mpt2sas: fix firmware failure with wrong task attribute commit 48ba2efc382f94fae16ca8ca011e5961a81ad1ea upstream. When SCSI command is received with task attribute not set, set it to SIMPLE. Previously it is set to untagged. This causes the firmware to fail the commands. Signed-off-by: Sreekanth Reddy Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/mpt2sas/mpt2sas_scsih.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index aa51195..d6e8353 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -3740,11 +3740,7 @@ _scsih_qcmd_lck(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) else mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; } else -/* MPI Revision I (UNIT = 0xA) - removed MPI2_SCSIIO_CONTROL_UNTAGGED */ -/* mpi_control |= MPI2_SCSIIO_CONTROL_UNTAGGED; - */ - mpi_control |= (0x500); - + mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; } else mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; /* Make sure Device is not raid volume. -- cgit v1.1 From 83e460923c7640fe6af1a1b386513dcc26fe7251 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Mon, 1 Jul 2013 16:49:22 -0500 Subject: sunvnet: vnet_port_remove must call unregister_netdev [ Upstream commit aabb9875d02559ab9b928cd6f259a5cc4c21a589 ] The missing call to unregister_netdev() leaves the interface active after the driver is unloaded by rmmod. Signed-off-by: Dave Kleikamp Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/sunvnet.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c index bf3c762..cc77f70 100644 --- a/drivers/net/sunvnet.c +++ b/drivers/net/sunvnet.c @@ -1248,6 +1248,8 @@ static int vnet_port_remove(struct vio_dev *vdev) dev_set_drvdata(&vdev->dev, NULL); kfree(port); + + unregister_netdev(vp->dev); } return 0; } -- cgit v1.1 From 14dfbe18c960e9367a6a25f6d7933e293fae1d20 Mon Sep 17 00:00:00 2001 From: dingtianhong Date: Wed, 10 Jul 2013 12:04:02 +0800 Subject: ifb: fix rcu_sched self-detected stalls [ Upstream commit 440d57bc5ff55ec1efb3efc9cbe9420b4bbdfefa ] According to the commit 16b0dc29c1af9df341428f4c49ada4f626258082 (dummy: fix rcu_sched self-detected stalls) Eric Dumazet fix the problem in dummy, but the ifb will occur the same problem like the dummy modules. Trying to "modprobe ifb numifbs=30000" triggers : INFO: rcu_sched self-detected stall on CPU After this splat, RTNL is locked and reboot is needed. We must call cond_resched() to avoid this, even holding RTNL. Signed-off-by: Ding Tianhong Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ifb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 2b98461..280f4a8 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -252,8 +253,10 @@ static int __init ifb_init_module(void) rtnl_lock(); err = __rtnl_link_register(&ifb_link_ops); - for (i = 0; i < numifbs && !err; i++) + for (i = 0; i < numifbs && !err; i++) { err = ifb_init_one(i); + cond_resched(); + } if (err) __rtnl_link_unregister(&ifb_link_ops); rtnl_unlock(); -- cgit v1.1 From 7474f8cdc7a60fe7c5d2579f99ec04232f76a208 Mon Sep 17 00:00:00 2001 From: dingtianhong Date: Thu, 11 Jul 2013 19:04:02 +0800 Subject: dummy: fix oops when loading the dummy failed [ Upstream commit 2c8a01894a12665d8059fad8f0a293c98a264121 ] We rename the dummy in modprobe.conf like this: install dummy0 /sbin/modprobe -o dummy0 --ignore-install dummy install dummy1 /sbin/modprobe -o dummy1 --ignore-install dummy We got oops when we run the command: modprobe dummy0 modprobe dummy1 ------------[ cut here ]------------ [ 3302.187584] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 [ 3302.195411] IP: [] __rtnl_link_unregister+0x9a/0xd0 [ 3302.201844] PGD 85c94a067 PUD 8517bd067 PMD 0 [ 3302.206305] Oops: 0002 [#1] SMP [ 3302.299737] task: ffff88105ccea300 ti: ffff880eba4a0000 task.ti: ffff880eba4a0000 [ 3302.307186] RIP: 0010:[] [] __rtnl_link_unregister+0x9a/0xd0 [ 3302.316044] RSP: 0018:ffff880eba4a1dd8 EFLAGS: 00010246 [ 3302.321332] RAX: 0000000000000000 RBX: ffffffff81a9d738 RCX: 0000000000000002 [ 3302.328436] RDX: 0000000000000000 RSI: ffffffffa04d602c RDI: ffff880eba4a1dd8 [ 3302.335541] RBP: ffff880eba4a1e18 R08: dead000000200200 R09: dead000000100100 [ 3302.342644] R10: 0000000000000080 R11: 0000000000000003 R12: ffffffff81a9d788 [ 3302.349748] R13: ffffffffa04d7020 R14: ffffffff81a9d670 R15: ffff880eba4a1dd8 [ 3302.364910] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 3302.370630] CR2: 0000000000000008 CR3: 000000085e15e000 CR4: 00000000000427e0 [ 3302.377734] DR0: 0000000000000003 DR1: 00000000000000b0 DR2: 0000000000000001 [ 3302.384838] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 3302.391940] Stack: [ 3302.393944] ffff880eba4a1dd8 ffff880eba4a1dd8 ffff880eba4a1e18 ffffffffa04d70c0 [ 3302.401350] 00000000ffffffef ffffffffa01a8000 0000000000000000 ffffffff816111c8 [ 3302.408758] ffff880eba4a1e48 ffffffffa01a80be ffff880eba4a1e48 ffffffffa04d70c0 [ 3302.416164] Call Trace: [ 3302.418605] [] ? 0xffffffffa01a7fff [ 3302.423727] [] dummy_init_module+0xbe/0x1000 [dummy0] [ 3302.430405] [] ? 0xffffffffa01a7fff [ 3302.435535] [] do_one_initcall+0x152/0x1b0 [ 3302.441263] [] do_init_module+0x7b/0x200 [ 3302.446824] [] load_module+0x4e2/0x530 [ 3302.452215] [] ? ddebug_dyndbg_boot_param_cb+0x60/0x60 [ 3302.458979] [] SyS_init_module+0xd1/0x130 [ 3302.464627] [] system_call_fastpath+0x16/0x1b [ 3302.490090] RIP [] __rtnl_link_unregister+0x9a/0xd0 [ 3302.496607] RSP [ 3302.500084] CR2: 0000000000000008 [ 3302.503466] ---[ end trace 8342d49cd49f78ed ]--- The reason is that when loading dummy, if __rtnl_link_register() return failed, the init_module should return and avoid take the wrong path. Signed-off-by: Tan Xiaojun Signed-off-by: Ding Tianhong Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/dummy.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 098ff31..d74c431 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -186,6 +186,8 @@ static int __init dummy_init_module(void) rtnl_lock(); err = __rtnl_link_register(&dummy_link_ops); + if (err < 0) + goto out; for (i = 0; i < numdummies && !err; i++) { err = dummy_init_one(); @@ -193,6 +195,8 @@ static int __init dummy_init_module(void) } if (err < 0) __rtnl_link_unregister(&dummy_link_ops); + +out: rtnl_unlock(); return err; -- cgit v1.1 From 8956c3efefa2a61df16a47ba4f159e3d49717858 Mon Sep 17 00:00:00 2001 From: dingtianhong Date: Thu, 11 Jul 2013 19:04:06 +0800 Subject: ifb: fix oops when loading the ifb failed [ Upstream commit f2966cd5691058b8674a20766525bedeaea9cbcf ] If __rtnl_link_register() return faild when loading the ifb, it will take the wrong path and get oops, so fix it just like dummy. Signed-off-by: Ding Tianhong Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ifb.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 280f4a8..902ba2f 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -252,6 +252,8 @@ static int __init ifb_init_module(void) rtnl_lock(); err = __rtnl_link_register(&ifb_link_ops); + if (err < 0) + goto out; for (i = 0; i < numifbs && !err; i++) { err = ifb_init_one(i); @@ -259,6 +261,8 @@ static int __init ifb_init_module(void) } if (err) __rtnl_link_unregister(&ifb_link_ops); + +out: rtnl_unlock(); return err; -- cgit v1.1 From d45ff5f89c087a667290048c24deaeb27fa43ba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 21 Nov 2012 09:54:48 +0100 Subject: SCSI: megaraid_sas: fix memory leak if SGL has zero length entries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 7a6a731bd00ca90d0e250867c3b9c05b5ff0fa49 upstream. commit 98cb7e44 ([SCSI] megaraid_sas: Sanity check user supplied length before passing it to dma_alloc_coherent()) introduced a memory leak. Memory allocated for entries following zero length SGL entries will not be freed. Reference: http://bugs.debian.org/688198 Signed-off-by: Bjørn Mork Acked-by: Adam Radford Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/megaraid/megaraid_sas_base.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 931cb11..5eac650 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4746,10 +4746,12 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, sense, sense_handle); } - for (i = 0; i < ioc->sge_count && kbuff_arr[i]; i++) { - dma_free_coherent(&instance->pdev->dev, - kern_sge32[i].length, - kbuff_arr[i], kern_sge32[i].phys_addr); + for (i = 0; i < ioc->sge_count; i++) { + if (kbuff_arr[i]) + dma_free_coherent(&instance->pdev->dev, + kern_sge32[i].length, + kbuff_arr[i], + kern_sge32[i].phys_addr); } megasas_return_cmd(instance, cmd); -- cgit v1.1 From ad4beaccb0882af065befc18665f461d9711a2d4 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 3 Sep 2012 20:50:30 +0200 Subject: SCSI: Fix incorrect memset in bnx2fc_parse_fcp_rsp commit 16da05b1158d1bcb31656e636a8736a663b1cf1f upstream. gcc 4.8 warns because the memset only clears sizeof(char *) bytes, not the whole buffer. Use the correct buffer size and clear the whole sense buffer. /backup/lsrc/git/linux-lto-2.6/drivers/scsi/bnx2fc/bnx2fc_io.c: In function 'bnx2fc_parse_fcp_rsp': /backup/lsrc/git/linux-lto-2.6/drivers/scsi/bnx2fc/bnx2fc_io.c:1810:41: warning: argument to 'sizeof' in 'memset' call is the same expression as the destination; did you mean to provide an explicit length? [-Wsizeof-pointer-memaccess] memset(sc_cmd->sense_buffer, 0, sizeof(sc_cmd->sense_buffer)); ^ Signed-off-by: Andi Kleen Acked-by: Bhanu Prakash Gollapudi Signed-off-by: James Bottomley Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/bnx2fc/bnx2fc_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 454c72c..ca4be24 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -1618,7 +1618,7 @@ static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req, fcp_sns_len = SCSI_SENSE_BUFFERSIZE; } - memset(sc_cmd->sense_buffer, 0, sizeof(sc_cmd->sense_buffer)); + memset(sc_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); if (fcp_sns_len) memcpy(sc_cmd->sense_buffer, rq_data, fcp_sns_len); -- cgit v1.1 From 086d6ce19be48369ede4cf32a4983f70618caea5 Mon Sep 17 00:00:00 2001 From: Enrico Mioso Date: Sat, 29 Jun 2013 15:33:35 +0200 Subject: usb: serial: option: blacklist ONDA MT689DC QMI interface commit 3d1a69e726406ab662ab88fa30a3a05ed404334d upstream. Prevent the option driver from binding itself to the QMI/WWAN interface, making it unusable by the proper driver. Signed-off-by: enrico Mioso Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index b8365a7..d6a1710 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -832,7 +832,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0018, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0020, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0021, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, -- cgit v1.1 From db3b3fb7e0beb4f1c0aecbf4b701b550b1378e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Fri, 28 Jun 2013 17:15:25 +0200 Subject: usb: option: add TP-LINK MA260 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 94190301ffa059c2d127b3a67ec5d161d5c62681 upstream. Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index d6a1710..14b39dc 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1355,6 +1355,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) }, { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */ + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) }, { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x02, 0x01) }, /* D-Link DWM-156 (variant) */ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d01, 0xff, 0x00, 0x00) }, /* D-Link DWM-156 (variant) */ -- cgit v1.1 From f560b0a91504905b45a86d6aab741596f8918de9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 10 Jul 2013 12:25:02 -0500 Subject: usb: serial: option: add Olivetti Olicard 200 commit 4cf76df06ecc852633ed927d91e01c83c33bc331 upstream. Speaks AT on interfaces 5 (command & PPP) and 3 (secondary), other interface protocols are unknown. Signed-off-by: Dan Williams Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 14b39dc..b79d071 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -347,6 +347,7 @@ static void option_instat_callback(struct urb *urb); #define OLIVETTI_VENDOR_ID 0x0b3c #define OLIVETTI_PRODUCT_OLICARD100 0xc000 #define OLIVETTI_PRODUCT_OLICARD145 0xc003 +#define OLIVETTI_PRODUCT_OLICARD200 0xc005 /* Celot products */ #define CELOT_VENDOR_ID 0x211f @@ -1279,6 +1280,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200) }, { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ -- cgit v1.1 From 95087796786486aed495ef1bcbd90293457a95f4 Mon Sep 17 00:00:00 2001 From: Enrico Mioso Date: Sat, 13 Jul 2013 18:54:14 +0200 Subject: usb: serial: option.c: remove ONDA MT825UP product ID fromdriver commit 878c69aae986ae97084458c0183a8c0a059865b1 upstream. Some (very few) early devices like mine, where not exposting a proper CDC descriptor. This was fixed with an immediate firmware update from the vendor, and pre-installed on newer devices. So actual devices can be driven by cdc_acm.c + cdc_ether.c. Signed-off-by: Enrico Mioso Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index b79d071..d6c42ae 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -353,12 +353,6 @@ static void option_instat_callback(struct urb *urb); #define CELOT_VENDOR_ID 0x211f #define CELOT_PRODUCT_CT680M 0x6801 -/* ONDA Communication vendor id */ -#define ONDA_VENDOR_ID 0x1ee8 - -/* ONDA MT825UP HSDPA 14.2 modem */ -#define ONDA_MT825UP 0x000b - /* Samsung products */ #define SAMSUNG_VENDOR_ID 0x04e8 #define SAMSUNG_PRODUCT_GT_B3730 0x6889 @@ -1282,7 +1276,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200) }, { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ - { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) }, { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM610) }, -- cgit v1.1 From c3a11656cc97d64855423ba438828c85a8e54ee5 Mon Sep 17 00:00:00 2001 From: Daniil Bolsun Date: Fri, 19 Jul 2013 10:21:23 +0300 Subject: USB: option: append Petatel NP10T device to GSM modems list commit c38e83b6cc2adf80e3f091fd92cfbeacc9748347 upstream. This patch was tested on 3.10.1 kernel. Same models of Petatel NP10T modems have different device IDs. Unfortunately they have no additional revision information on a board which may treat them as different devices. Currently I've seen only two NP10T devices with various IDs. Possibly Petatel NP10T list will be appended upon devices with new IDs will appear. Signed-off-by: Daniil Bolsun Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index d6c42ae..c1ff773 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -445,7 +445,8 @@ static void option_instat_callback(struct urb *urb); /* Hyundai Petatel Inc. products */ #define PETATEL_VENDOR_ID 0x1ff4 -#define PETATEL_PRODUCT_NP10T 0x600e +#define PETATEL_PRODUCT_NP10T_600A 0x600a +#define PETATEL_PRODUCT_NP10T_600E 0x600e /* TP-LINK Incorporated products */ #define TPLINK_VENDOR_ID 0x2357 @@ -1347,7 +1348,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x02, 0x01) }, { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM2, 0xff, 0x00, 0x00) }, { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, - { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) }, + { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600A) }, + { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) }, { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */ -- cgit v1.1 From ce2a4856d35f96196200e28a6ee34a836a4b3b2f Mon Sep 17 00:00:00 2001 From: "Alexandr \\\\\\\"Sky\\\\\\\" Ivanov" Date: Tue, 23 Jul 2013 17:46:40 +0400 Subject: USB: option: add D-Link DWM-152/C1 and DWM-156/C1 commit ca24763588844b14f019ffc45c7df6d9e8f932c5 upstream. Adding support for D-Link DWM-152/C1 and DWM-156/C1 devices. DWM-152/C1: T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 6 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=07d1 ProdID=3e01 Rev= 0.00 S: Product=USB Configuration S: SerialNumber=1234567890ABCDEF C:* #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 4 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms DWM-156/C1: T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 8 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=07d1 ProdID=3e02 Rev= 0.00 S: Product=DataCard Device S: SerialNumber=1234567890ABCDEF C:* #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 4 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Alexandr Ivanov Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index c1ff773..b0d468a 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1361,6 +1361,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) }, { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); -- cgit v1.1 From 6280fb6d01c8e3fd3b2e4467e5e5cecce2e3b41d Mon Sep 17 00:00:00 2001 From: Enrico Mioso Date: Thu, 25 Jul 2013 02:01:39 +0200 Subject: usb: serial: option: Add ONYX 3G device support commit 63b5df963f52ccbab6fabedf05b7ac6b465789a4 upstream. This patch adds support for the ONYX 3G device (version 1) from ALFA NETWORK. Signed-off-by: Enrico Mioso Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index b0d468a..c2103f4 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -793,6 +793,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, -- cgit v1.1 From a18112769fdfa24345bc8d0cec6cb6b590d87325 Mon Sep 17 00:00:00 2001 From: Luiz Angelo Daros de Luca Date: Mon, 1 Jul 2013 23:56:25 -0300 Subject: usb: serial: cp210x: Add USB ID for Netgear Switches embedded serial adapter commit 90625070c4253377025878c4e82feed8b35c7116 upstream. This adds NetGear Managed Switch M4100 series, M5300 series, M7100 series USB ID (0846:0110) to the cp210x driver. Without this, the serial adapter is not recognized in Linux. Description was obtained from an Netgear Eng. Signed-off-by: Luiz Angelo Daros de Luca Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 913a178..f581927 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -60,6 +60,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ { USB_DEVICE(0x0489, 0xE003) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */ { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */ + { USB_DEVICE(0x0846, 0x1100) }, /* NetGear Managed Switch M4100 series, M5300 series, M7100 series */ { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ { USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher Acceptor */ -- cgit v1.1 From 838adcbfb9d711a56c0137cc10307fe3dce30771 Mon Sep 17 00:00:00 2001 From: Sami Rahman Date: Mon, 8 Jul 2013 14:28:55 -0400 Subject: USB: cp210x: add MMB and PI ZigBee USB Device Support commit 7681156982026ebf7eafd7301eb0374d7648d068 upstream. Added support for MMB Networks and Planet Innovation Ingeni ZigBee USB devices using customized Silicon Labs' CP210x.c USB to UART bridge drivers with PIDs: 88A4, 88A5. Signed-off-by: Sami Rahman Tested-by: Sami Rahman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index f581927..5f96d46 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -125,6 +125,8 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x85F8) }, /* Virtenio Preon32 */ { USB_DEVICE(0x10C4, 0x8664) }, /* AC-Services CAN-IF */ { USB_DEVICE(0x10C4, 0x8665) }, /* AC-Services OBD-IF */ + { USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */ + { USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ -- cgit v1.1 From 101e49a9ce6fadd876ae68bddf6f155bbd02a776 Mon Sep 17 00:00:00 2001 From: Barry Grussling Date: Fri, 19 Jul 2013 14:46:12 -0700 Subject: usb: cp210x support SEL C662 Vendor/Device commit b579fa52f6be0b4157ca9cc5e94d44a2c89a7e95 upstream. This patch adds support for the Schweitzer Engineering Laboratories C662 USB cable based off the CP210x driver. Signed-off-by: Barry Grussling Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 5f96d46..c408ff7 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -157,6 +157,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */ { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ + { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */ { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */ -- cgit v1.1 From 9cfe5af116d3c10595733f11681399f5d80980f6 Mon Sep 17 00:00:00 2001 From: Steffen Maier Date: Fri, 26 Apr 2013 17:34:54 +0200 Subject: zfcp: status read buffers on first adapter open with link down commit 9edf7d75ee5f21663a0183d21f702682d0ef132f upstream. Commit 64deb6efdc5504ce97b5c1c6f281fffbc150bd93 "[SCSI] zfcp: Use status_read_buf_num provided by FCP channel" started using a value returned by the channel but only evaluated the value if the fabric link is up. Commit 8d88cf3f3b9af4713642caeb221b6d6a42019001 "[SCSI] zfcp: Update status read mempool" introduced mempool resizings based on the above value. On setting an FCP device online for the very first time since boot, a new zeroed adapter object is allocated. If the link is down, the number of status read requests remains zero. Since just the config data exchange is incomplete, we proceed with adapter open recovery. However, we unconditionally call mempool_resize with adapter->stat_read_buf_num == 0 in this case. This causes a kernel message "kernel BUG at mm/mempool.c:131!" in process "zfcperp" with last function mempool_resize in Krnl PSW and zfcp_erp_thread in the Call Trace. Don't evaluate channel values which are invalid on link down. The number of status read requests is always valid, evaluated, and set to a positive minimum greater than zero. The adapter open recovery can proceed and the channel has status read buffers to inform us on a future link up event. While we are not aware of any other code path that could result in mempool resize attempts of size zero, we still also initialize the number of status read buffers to be posted to a static minimum number on adapter object allocation. Signed-off-by: Steffen Maier [sm: Backported to 3.0: - Copyright notice changed slightly - Don't use zfcp_fsf_convert_portspeed()] Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/s390/scsi/zfcp_aux.c | 5 ++++- drivers/s390/scsi/zfcp_fsf.c | 21 +++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 61da2cd..fc669c0 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -3,7 +3,7 @@ * * Module interface and handling of zfcp data structures. * - * Copyright IBM Corporation 2002, 2010 + * Copyright IBM Corp. 2002, 2013 */ /* @@ -23,6 +23,7 @@ * Christof Schmitt * Martin Petermann * Sven Schuetz + * Steffen Maier */ #define KMSG_COMPONENT "zfcp" @@ -414,6 +415,8 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) adapter->dma_parms.max_segment_size = ZFCP_QDIO_SBALE_LEN; adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; + adapter->stat_read_buf_num = FSF_STATUS_READS_RECOM; + if (!zfcp_scsi_adapter_register(adapter)) return adapter; diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 8976d02..ceb7f7c 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -3,7 +3,7 @@ * * Implementation of FSF commands. * - * Copyright IBM Corporation 2002, 2010 + * Copyright IBM Corp. 2002, 2013 */ #define KMSG_COMPONENT "zfcp" @@ -455,11 +455,8 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) fc_host_port_name(shost) = nsp->fl_wwpn; fc_host_node_name(shost) = nsp->fl_wwnn; - fc_host_port_id(shost) = ntoh24(bottom->s_id); - fc_host_speed(shost) = bottom->fc_link_speed; fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; - adapter->hydra_version = bottom->adapter_type; adapter->timer_ticks = bottom->timer_interval & ZFCP_FSF_TIMER_INT_MASK; adapter->stat_read_buf_num = max(bottom->status_read_buf_num, (u16)FSF_STATUS_READS_RECOM); @@ -467,6 +464,18 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) if (fc_host_permanent_port_name(shost) == -1) fc_host_permanent_port_name(shost) = fc_host_port_name(shost); + zfcp_scsi_set_prot(adapter); + + /* no error return above here, otherwise must fix call chains */ + /* do not evaluate invalid fields */ + if (req->qtcb->header.fsf_status == FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE) + return 0; + + fc_host_port_id(shost) = ntoh24(bottom->s_id); + fc_host_speed(shost) = bottom->fc_link_speed; + + adapter->hydra_version = bottom->adapter_type; + switch (bottom->fc_topology) { case FSF_TOPO_P2P: adapter->peer_d_id = ntoh24(bottom->peer_d_id); @@ -488,8 +497,6 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req) return -EIO; } - zfcp_scsi_set_prot(adapter); - return 0; } @@ -540,6 +547,8 @@ static void zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *req) &adapter->status); zfcp_fsf_link_down_info_eval(req, &qtcb->header.fsf_status_qual.link_down_info); + if (zfcp_fsf_exchange_config_evaluate(req)) + return; break; default: zfcp_erp_adapter_shutdown(adapter, 0, "fsecdh3"); -- cgit v1.1 From 738ae485e65ea6304466ef22c7eb6981c5174d60 Mon Sep 17 00:00:00 2001 From: Ren Bigcren Date: Tue, 2 Jul 2013 13:34:30 +0200 Subject: USB: storage: Add MicroVault Flash Drive to unusual_devs commit e7a6121f4929c17215f0cdca3726f4bf3e4e9529 upstream. The device report an error capacity when read_capacity_16(). Using read_capacity_10() can get the correct capacity. Signed-off-by: Ren Bigcren Cc: Matthew Dharm Signed-off-by: Oskar Andero Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 7b8d564..8a3b531 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -657,6 +657,13 @@ UNUSUAL_DEV( 0x054c, 0x016a, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), +/* Submitted by Ren Bigcren */ +UNUSUAL_DEV( 0x054c, 0x02a5, 0x0100, 0x0100, + "Sony Corp.", + "MicroVault Flash Drive", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_READ_CAPACITY_16 ), + /* floppy reports multiple luns */ UNUSUAL_DEV( 0x055d, 0x2020, 0x0000, 0x0210, "SAMSUNG", -- cgit v1.1 From eeba2290fa3d43e5d424964ef54836227c9c21c5 Mon Sep 17 00:00:00 2001 From: "Ewan D. Milne" Date: Fri, 2 Nov 2012 09:38:34 -0400 Subject: SCSI: sd: fix crash when UA received on DIF enabled device commit 085b513f97d8d799d28491239be4b451bcd8c2c5 upstream. sd_prep_fn will allocate a larger CDB for the command via mempool_alloc for devices using DIF type 2 protection. This CDB was being freed in sd_done, which results in a kernel crash if the command is retried due to a UNIT ATTENTION. This change moves the code to free the larger CDB into sd_unprep_fn instead, which is invoked after the request is complete. It is no longer necessary to call scsi_print_command separately for this case as the ->cmnd will no longer be NULL in the normal code path. Also removed conditional test for DIF type 2 when freeing the larger CDB because the protection_type could have been changed via sysfs while the command was executing. Signed-off-by: Ewan D. Milne Acked-by: Martin K. Petersen Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sd.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 43c7a90..3d15a37 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -641,10 +641,17 @@ static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq) static void sd_unprep_fn(struct request_queue *q, struct request *rq) { + struct scsi_cmnd *SCpnt = rq->special; + if (rq->cmd_flags & REQ_DISCARD) { free_page((unsigned long)rq->buffer); rq->buffer = NULL; } + if (SCpnt->cmnd != rq->cmd) { + mempool_free(SCpnt->cmnd, sd_cdb_pool); + SCpnt->cmnd = NULL; + SCpnt->cmd_len = 0; + } } /** @@ -1451,21 +1458,6 @@ static int sd_done(struct scsi_cmnd *SCpnt) if (rq_data_dir(SCpnt->request) == READ && scsi_prot_sg_count(SCpnt)) sd_dif_complete(SCpnt, good_bytes); - if (scsi_host_dif_capable(sdkp->device->host, sdkp->protection_type) - == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd) { - - /* We have to print a failed command here as the - * extended CDB gets freed before scsi_io_completion() - * is called. - */ - if (result) - scsi_print_command(SCpnt); - - mempool_free(SCpnt->cmnd, sd_cdb_pool); - SCpnt->cmnd = NULL; - SCpnt->cmd_len = 0; - } - return good_bytes; } -- cgit v1.1 From 95a9769291fda8caa8a98c0eabff769509a6e1ba Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Fri, 12 Jul 2013 14:47:51 -0400 Subject: SCSI: qla2xxx: Properly set the tagging for commands. commit c3ccb1d7cf4c4549151876dd37c0944a682fd9e1 upstream. This fixes a regression where Xyratex controllers and disks were lost by the driver: https://bugzilla.kernel.org/show_bug.cgi?id=59601 Reported-by: Jack Hill Signed-off-by: Saurav Kashyap Signed-off-by: Giridhar Malavali Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/qla2xxx/qla_iocb.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 7bac3cd..d2fb950 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -422,6 +422,8 @@ qla2x00_start_scsi(srb_t *sp) __constant_cpu_to_le16(CF_SIMPLE_TAG); break; } + } else { + cmd_pkt->control_flags = __constant_cpu_to_le16(CF_SIMPLE_TAG); } /* Load SCSI command packet. */ @@ -1099,11 +1101,11 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, fcp_cmnd->task_attribute = TSK_ORDERED; break; default: - fcp_cmnd->task_attribute = 0; + fcp_cmnd->task_attribute = TSK_SIMPLE; break; } } else { - fcp_cmnd->task_attribute = 0; + fcp_cmnd->task_attribute = TSK_SIMPLE; } cmd_pkt->fcp_rsp_dseg_len = 0; /* Let response come in status iocb */ @@ -1305,7 +1307,12 @@ qla24xx_start_scsi(srb_t *sp) case ORDERED_QUEUE_TAG: cmd_pkt->task = TSK_ORDERED; break; + default: + cmd_pkt->task = TSK_SIMPLE; + break; } + } else { + cmd_pkt->task = TSK_SIMPLE; } /* Load SCSI command packet. */ -- cgit v1.1 From 67a6ad3b0ca2311d4209338eec23c14331da5d36 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Sun, 21 Jul 2013 15:36:19 +0200 Subject: xhci: fix null pointer dereference on ring_doorbell_for_active_rings commit d66eaf9f89502971fddcb0de550b01fa6f409d83 upstream. in some cases where device is attched to xhci port and do not responding, for example ath9k_htc with stalled firmware, kernel will crash on ring_doorbell_for_active_rings. This patch check if pointer exist before it is used. This patch should be backported to kernels as old as 2.6.35, that contain the commit e9df17eb1408cfafa3d1844bfc7f22c7237b31b8 "USB: xhci: Correct assumptions about number of rings per endpoint" Signed-off-by: Oleksij Rempel Signed-off-by: Sarah Sharp Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 151ca5e..f40567e 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -465,7 +465,7 @@ static void ring_doorbell_for_active_rings(struct xhci_hcd *xhci, /* A ring has pending URBs if its TD list is not empty */ if (!(ep->ep_state & EP_HAS_STREAMS)) { - if (!(list_empty(&ep->ring->td_list))) + if (ep->ring && !(list_empty(&ep->ring->td_list))) xhci_ring_ep_doorbell(xhci, slot_id, ep_index, 0); return; } -- cgit v1.1 From 11e8ea9e069e6012a634017ad534c25030b1104a Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 24 Jul 2013 10:27:13 -0700 Subject: xhci: Avoid NULL pointer deref when host dies. commit 203a86613fb3bf2767335659513fa98563a3eb71 upstream. When the host controller fails to respond to an Enable Slot command, and the host fails to respond to the register write to abort the command ring, the xHCI driver will assume the host is dead, and call usb_hc_died(). The USB device's slot_id is still set to zero, and the pointer stored at xhci->devs[0] will always be NULL. The call to xhci_check_args in xhci_free_dev should have caught the NULL virt_dev pointer. However, xhci_free_dev is designed to free the xhci_virt_device structures, even if the host is dead, so that we don't leak kernel memory. xhci_free_dev checks the return value from the generic xhci_check_args function. If the return value is -ENODEV, it carries on trying to free the virtual device. The issue is that xhci_check_args looks at the host controller state before it looks at the xhci_virt_device pointer. It will return -ENIVAL because the host is dead, and xhci_free_dev will ignore the return value, and happily dereference the NULL xhci_virt_device pointer. The fix is to make sure that xhci_check_args checks the xhci_virt_device pointer before it checks the host state. See https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1203453 for further details. This patch doesn't solve the underlying issue, but will ensure we don't see any more NULL pointer dereferences because of the issue. This patch should be backported to kernels as old as 3.1, that contain the commit 7bd89b4017f46a9b92853940fd9771319acb578a "xhci: Don't submit commands or URBs to halted hosts." Signed-off-by: Sarah Sharp Reported-by: Vincent Thiele Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 4864b25..7f07eb8 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -956,9 +956,6 @@ static int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, } xhci = hcd_to_xhci(hcd); - if (xhci->xhc_state & XHCI_STATE_HALTED) - return -ENODEV; - if (check_virt_dev) { if (!udev->slot_id || !xhci->devs || !xhci->devs[udev->slot_id]) { @@ -975,6 +972,9 @@ static int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, } } + if (xhci->xhc_state & XHCI_STATE_HALTED) + return -ENODEV; + return 1; } -- cgit v1.1 From bd8f7d2c00c7ac86c9aa50fc73427009993cec03 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 28 Jun 2013 12:24:26 +0200 Subject: USB: ti_usb_3410_5052: fix dynamic-id matching commit 1fad56424f5ad3ce4973505a357212b2e2282b3f upstream. The driver failed to take the dynamic ids into account when determining the device type and therefore all devices were detected as 2-port devices when using the dynamic-id interface. Match on the usb-serial-driver field instead of doing redundant id-table searches. Reported-by: Anders Hammarquist Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ti_usb_3410_5052.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index a8c4f44..4757880 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -409,7 +409,7 @@ static int ti_startup(struct usb_serial *serial) usb_set_serial_data(serial, tdev); /* determine device type */ - if (usb_match_id(serial->interface, ti_id_table_3410)) + if (serial->type == &ti_1port_device) tdev->td_is_3410 = 1; dbg("%s - device type is %s", __func__, tdev->td_is_3410 ? "3410" : "5052"); -- cgit v1.1 From 54b404671f9535d0bd6bf388686cc5f8ee245c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3hann=20B=2E=20Gu=C3=B0mundsson?= Date: Thu, 4 Jul 2013 21:47:52 +0000 Subject: USB: misc: Add Manhattan Hi-Speed USB DVI Converter to sisusbvga MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 58fc90db8261b571c026bb8bf23aad48a7233118 upstream. Signed-off-by: Jóhann B. Guðmundsson Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/sisusbvga/sisusb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index dd573ab..7af163d 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c @@ -3247,6 +3247,7 @@ static const struct usb_device_id sisusb_table[] = { { USB_DEVICE(0x0711, 0x0903) }, { USB_DEVICE(0x0711, 0x0918) }, { USB_DEVICE(0x0711, 0x0920) }, + { USB_DEVICE(0x0711, 0x0950) }, { USB_DEVICE(0x182d, 0x021c) }, { USB_DEVICE(0x182d, 0x0269) }, { } -- cgit v1.1 From 94c3bbaf01202674a406d075429513e321a5b236 Mon Sep 17 00:00:00 2001 From: William Gulland Date: Thu, 27 Jun 2013 16:10:20 -0700 Subject: usb: Clear both buffers when clearing a control transfer TT buffer. commit 2c7b871b9102c497ba8f972aa5d38532f05b654d upstream. Control transfers have both IN and OUT (or SETUP) packets, so when clearing TT buffers for a control transfer it's necessary to send two HUB_CLEAR_TT_BUFFER requests to the hub. Signed-off-by: William Gulland Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index be9cac6..cb98968 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -463,6 +463,15 @@ resubmit: static inline int hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt) { + /* Need to clear both directions for control ep */ + if (((devinfo >> 11) & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_CONTROL) { + int status = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), + HUB_CLEAR_TT_BUFFER, USB_RT_PORT, + devinfo ^ 0x8000, tt, NULL, 0, 1000); + if (status) + return status; + } return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0), HUB_CLEAR_TT_BUFFER, USB_RT_PORT, devinfo, tt, NULL, 0, 1000); -- cgit v1.1 From dbe048b2eebb75f9b5c17b0d948fe5a8ec396cc5 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 8 Jul 2013 13:36:19 +0100 Subject: staging: comedi: COMEDI_CANCEL ioctl should wake up read/write commit 69acbaac303e8cb948801a9ddd0ac24e86cc4a1b upstream. Comedi devices can do blocking read() or write() (or poll()) if an asynchronous command has been set up, blocking for data (for read()) or buffer space (for write()). Various events associated with the asynchronous command will wake up the blocked reader or writer (or poller). It is also possible to force the asynchronous command to terminate by issuing a `COMEDI_CANCEL` ioctl. That shuts down the asynchronous command, but does not currently wake up the blocked reader or writer (or poller). If the blocked task could be woken up, it would see that the command is no longer active and return. The caller of the `COMEDI_CANCEL` ioctl could attempt to wake up the blocked task by sending a signal, but that's a nasty workaround. Change `do_cancel_ioctl()` to wake up the wait queue after it returns from `do_cancel()`. `do_cancel()` can propagate an error return value from the low-level comedi driver's cancel routine, but it always shuts the command down regardless, so `do_cancel_ioctl()` can wake up he wait queue regardless of the return value from `do_cancel()`. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_fops.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index ee33cba..40b40ed 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1370,6 +1370,7 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file) { struct comedi_subdevice *s; + int ret; if (arg >= dev->n_subdevices) return -EINVAL; @@ -1386,7 +1387,11 @@ static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, if (s->busy != file) return -EBUSY; - return do_cancel(dev, s); + ret = do_cancel(dev, s); + if (comedi_get_subdevice_runflags(s) & SRF_USER) + wake_up_interruptible(&s->async->wait_head); + + return ret; } /* -- cgit v1.1 From d8ab3c8b69ba3922b06e077c39ffc4dbcbeabe64 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 22 Jul 2013 16:53:36 -0400 Subject: libata: make it clear that sata_inic162x is experimental commit bb9696192826a7d9279caf872e95b41bc26c7eff upstream. sata_inic162x never reached a state where it's reliable enough for production use and data corruption is a relatively common occurrence. Make the driver generate warning about the issues and mark the Kconfig option as experimental. If the situation doesn't improve, we'd be better off making it depend on CONFIG_BROKEN. Let's wait for several cycles and see if the kernel message draws any attention. Signed-off-by: Tejun Heo Reported-by: Martin Braure de Calignon Reported-by: Ben Hutchings Reported-by: risc4all@yahoo.com Signed-off-by: Greg Kroah-Hartman --- drivers/ata/Kconfig | 2 +- drivers/ata/sata_inic162x.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 75afa75..34575fb 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -93,7 +93,7 @@ config SATA_FSL If unsure, say N. config SATA_INIC162X - tristate "Initio 162x SATA support" + tristate "Initio 162x SATA support (Very Experimental)" depends on PCI help This option enables support for Initio 162x Serial ATA. diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index 83a4447..15391ee 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c @@ -6,6 +6,18 @@ * * This file is released under GPL v2. * + * **** WARNING **** + * + * This driver never worked properly and unfortunately data corruption is + * relatively common. There isn't anyone working on the driver and there's + * no support from the vendor. Do not use this driver in any production + * environment. + * + * http://thread.gmane.org/gmane.linux.debian.devel.bugs.rc/378525/focus=54491 + * https://bugzilla.kernel.org/show_bug.cgi?id=60565 + * + * ***************** + * * This controller is eccentric and easily locks up if something isn't * right. Documentation is available at initio's website but it only * documents registers (not programming model). @@ -810,6 +822,8 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); + dev_alert(&pdev->dev, "inic162x support is broken with common data corruption issues and will be disabled by default, contact linux-ide@vger.kernel.org if in production use\n"); + /* alloc host */ host = ata_host_alloc_pinfo(&pdev->dev, ppi, NR_PORTS); hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); -- cgit v1.1 From 8673e4e2f9b08fd036cf9a088a9fe16d681b6ab7 Mon Sep 17 00:00:00 2001 From: Toshi Kani Date: Wed, 10 Jul 2013 10:47:13 -0600 Subject: ACPI / memhotplug: Fix a stale pointer in error path commit d19f503e22316a84c39bc19445e0e4fdd49b3532 upstream. device->driver_data needs to be cleared when releasing its data, mem_device, in an error path of acpi_memory_device_add(). The function evaluates the _CRS of memory device objects, and fails when it gets an unexpected resource or cannot allocate memory. A kernel crash or data corruption may occur when the kernel accesses the stale pointer. Signed-off-by: Toshi Kani Reviewed-by: Yasuaki Ishimatsu Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/acpi_memhotplug.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index d985713..f81597f 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -421,6 +421,7 @@ static int acpi_memory_device_add(struct acpi_device *device) /* Get the range from the _CRS */ result = acpi_memory_get_device_resources(mem_device); if (result) { + device->driver_data = NULL; kfree(mem_device); return result; } -- cgit v1.1 From 720c2af54ebce30c402581384e2287e66b4dee8c Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Sun, 21 Jul 2013 16:44:09 -0400 Subject: drm/radeon: fix combios tables on older cards commit cef1d00cd56f600121ad121875655ad410a001b8 upstream. Noticed that my old Radeon 7500 hung after printing drm: GPU not posted. posting now... when it wasn't selected as the primary card the BIOS. Some digging revealed that it was hanging in combios_parse_mmio_table() while parsing the ASIC INIT 3 table. Looking at the BIOS ROM for the card, it becomes obvious that there is no ASIC INIT 3 table in the BIOS. The code is just processing random garbage. No surprise it hangs! Why do I say that there is no ASIC INIT 3 table is the BIOS? This table is found through the MISC INFO table. The MISC INFO table can be found at offset 0x5e in the COMBIOS header. But the header is smaller than that. The COMBIOS header starts at offset 0x126. The standard PCI Data Structure (the bit that starts with 'PCIR') lives at offset 0x180. That means that the COMBIOS header can not be larger than 0x5a bytes and therefore cannot contain a MISC INFO table. I looked at a dozen or so BIOS images, some my own, some downloaded from: It is fairly obvious that the size of the COMBIOS header can be found at offset 0x6 of the header. Not sure if it is a 16-bit number or just an 8-bit number, but that doesn't really matter since the tables seems to be always smaller than 256 bytes. So I think combios_get_table_offset() should check if the requested table is present. This can be done by checking the offset against the size of the header. See the diff below. The diff is against the WIP OpenBSD codebase that roughly corresponds to Linux 3.8.13 at this point. But I don't think this bit of the code changed much since then. For what it is worth: Signed-off-by: Mark Kettenis Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/radeon_combios.c | 145 +++++++++----------------------- 1 file changed, 41 insertions(+), 104 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 98fb3d7..51096ad 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -147,7 +147,7 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, enum radeon_combios_table_offset table) { struct radeon_device *rdev = dev->dev_private; - int rev; + int rev, size; uint16_t offset = 0, check_offset; if (!rdev->bios) @@ -156,174 +156,106 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, switch (table) { /* absolute offset tables */ case COMBIOS_ASIC_INIT_1_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0xc); - if (check_offset) - offset = check_offset; + check_offset = 0xc; break; case COMBIOS_BIOS_SUPPORT_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x14); - if (check_offset) - offset = check_offset; + check_offset = 0x14; break; case COMBIOS_DAC_PROGRAMMING_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x2a); - if (check_offset) - offset = check_offset; + check_offset = 0x2a; break; case COMBIOS_MAX_COLOR_DEPTH_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x2c); - if (check_offset) - offset = check_offset; + check_offset = 0x2c; break; case COMBIOS_CRTC_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x2e); - if (check_offset) - offset = check_offset; + check_offset = 0x2e; break; case COMBIOS_PLL_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x30); - if (check_offset) - offset = check_offset; + check_offset = 0x30; break; case COMBIOS_TV_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x32); - if (check_offset) - offset = check_offset; + check_offset = 0x32; break; case COMBIOS_DFP_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x34); - if (check_offset) - offset = check_offset; + check_offset = 0x34; break; case COMBIOS_HW_CONFIG_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x36); - if (check_offset) - offset = check_offset; + check_offset = 0x36; break; case COMBIOS_MULTIMEDIA_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x38); - if (check_offset) - offset = check_offset; + check_offset = 0x38; break; case COMBIOS_TV_STD_PATCH_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x3e); - if (check_offset) - offset = check_offset; + check_offset = 0x3e; break; case COMBIOS_LCD_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x40); - if (check_offset) - offset = check_offset; + check_offset = 0x40; break; case COMBIOS_MOBILE_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x42); - if (check_offset) - offset = check_offset; + check_offset = 0x42; break; case COMBIOS_PLL_INIT_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x46); - if (check_offset) - offset = check_offset; + check_offset = 0x46; break; case COMBIOS_MEM_CONFIG_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x48); - if (check_offset) - offset = check_offset; + check_offset = 0x48; break; case COMBIOS_SAVE_MASK_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x4a); - if (check_offset) - offset = check_offset; + check_offset = 0x4a; break; case COMBIOS_HARDCODED_EDID_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x4c); - if (check_offset) - offset = check_offset; + check_offset = 0x4c; break; case COMBIOS_ASIC_INIT_2_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x4e); - if (check_offset) - offset = check_offset; + check_offset = 0x4e; break; case COMBIOS_CONNECTOR_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x50); - if (check_offset) - offset = check_offset; + check_offset = 0x50; break; case COMBIOS_DYN_CLK_1_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x52); - if (check_offset) - offset = check_offset; + check_offset = 0x52; break; case COMBIOS_RESERVED_MEM_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x54); - if (check_offset) - offset = check_offset; + check_offset = 0x54; break; case COMBIOS_EXT_TMDS_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x58); - if (check_offset) - offset = check_offset; + check_offset = 0x58; break; case COMBIOS_MEM_CLK_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x5a); - if (check_offset) - offset = check_offset; + check_offset = 0x5a; break; case COMBIOS_EXT_DAC_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x5c); - if (check_offset) - offset = check_offset; + check_offset = 0x5c; break; case COMBIOS_MISC_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x5e); - if (check_offset) - offset = check_offset; + check_offset = 0x5e; break; case COMBIOS_CRT_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x60); - if (check_offset) - offset = check_offset; + check_offset = 0x60; break; case COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x62); - if (check_offset) - offset = check_offset; + check_offset = 0x62; break; case COMBIOS_COMPONENT_VIDEO_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x64); - if (check_offset) - offset = check_offset; + check_offset = 0x64; break; case COMBIOS_FAN_SPEED_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x66); - if (check_offset) - offset = check_offset; + check_offset = 0x66; break; case COMBIOS_OVERDRIVE_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x68); - if (check_offset) - offset = check_offset; + check_offset = 0x68; break; case COMBIOS_OEM_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x6a); - if (check_offset) - offset = check_offset; + check_offset = 0x6a; break; case COMBIOS_DYN_CLK_2_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x6c); - if (check_offset) - offset = check_offset; + check_offset = 0x6c; break; case COMBIOS_POWER_CONNECTOR_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x6e); - if (check_offset) - offset = check_offset; + check_offset = 0x6e; break; case COMBIOS_I2C_INFO_TABLE: - check_offset = RBIOS16(rdev->bios_header_start + 0x70); - if (check_offset) - offset = check_offset; + check_offset = 0x70; break; /* relative offset tables */ case COMBIOS_ASIC_INIT_3_TABLE: /* offset from misc info */ @@ -439,11 +371,16 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, } break; default: + check_offset = 0; break; } - return offset; + size = RBIOS8(rdev->bios_header_start + 0x6); + /* check absolute offset tables */ + if (table < COMBIOS_ASIC_INIT_3_TABLE && check_offset && check_offset < size) + offset = RBIOS16(rdev->bios_header_start + check_offset); + return offset; } bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) -- cgit v1.1 From e0d2313f66fea2e8a5286d5ccebb057810ad4e9b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 19 Jul 2013 17:44:43 -0400 Subject: drm/radeon: improve dac adjust heuristics for legacy pdac commit 03ed8cf9b28d886c64c7e705c7bb1a365fd8fb95 upstream. Hopefully avoid more quirks in the future due to bogus vbios dac data. Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/radeon_combios.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 51096ad..f616e40 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -890,8 +890,10 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct dac = RBIOS8(dac_info + 0x3) & 0xf; p_dac->ps2_pdac_adj = (bg << 8) | (dac); } - /* if the values are all zeros, use the table */ - if (p_dac->ps2_pdac_adj) + /* if the values are zeros, use the table */ + if ((dac == 0) || (bg == 0)) + found = 0; + else found = 1; } -- cgit v1.1 From 6ec322493ae29932c23a20ad015921fe133b9ff8 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 30 Jul 2013 00:22:53 -0400 Subject: drm/radeon/atom: initialize more atom interpretor elements to 0 commit 42a21826dc54583cdb79cc8477732e911ac9c376 upstream. The ProcessAuxChannel table on some rv635 boards assumes the divmul members are initialized to 0 otherwise we get an invalid fb offset since it has a bad mask set when setting the fb base. While here initialize all the atom interpretor elements to 0. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=60639 Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/atom.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 6b84d279..a1df7d7 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -1220,12 +1220,17 @@ int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) int r; mutex_lock(&ctx->mutex); + /* reset data block */ + ctx->data_block = 0; /* reset reg block */ ctx->reg_block = 0; /* reset fb window */ ctx->fb_base = 0; /* reset io mode */ ctx->io_mode = ATOM_IO_MM; + /* reset divmul */ + ctx->divmul[0] = 0; + ctx->divmul[1] = 0; r = atom_execute_table_locked(ctx, index, params); mutex_unlock(&ctx->mutex); return r; -- cgit v1.1 From 2fcaa774ab8375516255249648af76ce16663b6a Mon Sep 17 00:00:00 2001 From: "Rick Farina (Zero_Chaos)" Date: Mon, 29 Jul 2013 15:17:59 -0400 Subject: USB: serial: ftdi_sio: add more RT Systems ftdi devices commit fed1f1ed90bce42ea010e2904cbc04e7b8304940 upstream. RT Systems makes many usb serial cables based on the ftdi_sio driver for programming various amateur radios. This patch is a full listing of their current product offerings and should allow these cables to all be recognized. Signed-off-by: Rick Farina (Zero_Chaos) Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 31 ++++++++++++++++++++++++++++--- drivers/usb/serial/ftdi_sio_ids.h | 34 +++++++++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 45e55e2..04d5427 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -743,9 +743,34 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID), .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk }, { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, - { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_SERIAL_VX7_PID) }, - { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_CT29B_PID) }, - { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_RTS01_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S03_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_59_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57A_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_57B_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29A_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29B_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29F_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_62B_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S01_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_63_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_29C_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_81B_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_82B_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K5D_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K4Y_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_K5G_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_S05_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_60_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_61_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_62_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_63B_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_64_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_65_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_92_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_92D_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_W5R_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_A5R_PID) }, + { USB_DEVICE(RTSYSTEMS_VID, RTSYSTEMS_USB_PW1_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) }, { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 5d25e26..61685ed 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -815,11 +815,35 @@ /* * RT Systems programming cables for various ham radios */ -#define RTSYSTEMS_VID 0x2100 /* Vendor ID */ -#define RTSYSTEMS_SERIAL_VX7_PID 0x9e52 /* Serial converter for VX-7 Radios using FT232RL */ -#define RTSYSTEMS_CT29B_PID 0x9e54 /* CT29B Radio Cable */ -#define RTSYSTEMS_RTS01_PID 0x9e57 /* USB-RTS01 Radio Cable */ - +#define RTSYSTEMS_VID 0x2100 /* Vendor ID */ +#define RTSYSTEMS_USB_S03_PID 0x9001 /* RTS-03 USB to Serial Adapter */ +#define RTSYSTEMS_USB_59_PID 0x9e50 /* USB-59 USB to 8 pin plug */ +#define RTSYSTEMS_USB_57A_PID 0x9e51 /* USB-57A USB to 4pin 3.5mm plug */ +#define RTSYSTEMS_USB_57B_PID 0x9e52 /* USB-57B USB to extended 4pin 3.5mm plug */ +#define RTSYSTEMS_USB_29A_PID 0x9e53 /* USB-29A USB to 3.5mm stereo plug */ +#define RTSYSTEMS_USB_29B_PID 0x9e54 /* USB-29B USB to 6 pin mini din */ +#define RTSYSTEMS_USB_29F_PID 0x9e55 /* USB-29F USB to 6 pin modular plug */ +#define RTSYSTEMS_USB_62B_PID 0x9e56 /* USB-62B USB to 8 pin mini din plug*/ +#define RTSYSTEMS_USB_S01_PID 0x9e57 /* USB-RTS01 USB to 3.5 mm stereo plug*/ +#define RTSYSTEMS_USB_63_PID 0x9e58 /* USB-63 USB to 9 pin female*/ +#define RTSYSTEMS_USB_29C_PID 0x9e59 /* USB-29C USB to 4 pin modular plug*/ +#define RTSYSTEMS_USB_81B_PID 0x9e5A /* USB-81 USB to 8 pin mini din plug*/ +#define RTSYSTEMS_USB_82B_PID 0x9e5B /* USB-82 USB to 2.5 mm stereo plug*/ +#define RTSYSTEMS_USB_K5D_PID 0x9e5C /* USB-K5D USB to 8 pin modular plug*/ +#define RTSYSTEMS_USB_K4Y_PID 0x9e5D /* USB-K4Y USB to 2.5/3.5 mm plugs*/ +#define RTSYSTEMS_USB_K5G_PID 0x9e5E /* USB-K5G USB to 8 pin modular plug*/ +#define RTSYSTEMS_USB_S05_PID 0x9e5F /* USB-RTS05 USB to 2.5 mm stereo plug*/ +#define RTSYSTEMS_USB_60_PID 0x9e60 /* USB-60 USB to 6 pin din*/ +#define RTSYSTEMS_USB_61_PID 0x9e61 /* USB-61 USB to 6 pin mini din*/ +#define RTSYSTEMS_USB_62_PID 0x9e62 /* USB-62 USB to 8 pin mini din*/ +#define RTSYSTEMS_USB_63B_PID 0x9e63 /* USB-63 USB to 9 pin female*/ +#define RTSYSTEMS_USB_64_PID 0x9e64 /* USB-64 USB to 9 pin male*/ +#define RTSYSTEMS_USB_65_PID 0x9e65 /* USB-65 USB to 9 pin female null modem*/ +#define RTSYSTEMS_USB_92_PID 0x9e66 /* USB-92 USB to 12 pin plug*/ +#define RTSYSTEMS_USB_92D_PID 0x9e67 /* USB-92D USB to 12 pin plug data*/ +#define RTSYSTEMS_USB_W5R_PID 0x9e68 /* USB-W5R USB to 8 pin modular plug*/ +#define RTSYSTEMS_USB_A5R_PID 0x9e69 /* USB-A5R USB to 8 pin modular plug*/ +#define RTSYSTEMS_USB_PW1_PID 0x9e6A /* USB-PW1 USB to 8 pin modular plug*/ /* * Physik Instrumente -- cgit v1.1 From 0b7b1cfac3b60be07d6b2ae8fe4db495de5883a6 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Fri, 19 Jul 2013 15:51:58 +0100 Subject: xen/evtchn: avoid a deadlock when unbinding an event channel commit 179fbd5a45f0d4034cc6fd37b8d367a3b79663c4 upstream. Unbinding an event channel (either with the ioctl or when the evtchn device is closed) may deadlock because disable_irq() is called with port_user_lock held which is also locked by the interrupt handler. Think of the IOCTL_EVTCHN_UNBIND is being serviced, the routine has just taken the lock, and an interrupt happens. The evtchn_interrupt is invoked, tries to take the lock and spins forever. A quick glance at the code shows that the spinlock is a local IRQ variant. Unfortunately that does not help as "disable_irq() waits for the interrupt handler on all CPUs to stop running. If the irq occurs on another VCPU, it tries to take port_user_lock and can't because the unbind ioctl is holding it." (from David). Hence we cannot depend on the said spinlock to protect us. We could make it a system wide IRQ disable spinlock but there is a better way. We can piggyback on the fact that the existence of the spinlock is to make get_port_user() checks be up-to-date. And we can alter those checks to not depend on the spin lock (as it's protected by u->bind_mutex in the ioctl) and can remove the unnecessary locking (this is IOCTL_EVTCHN_UNBIND) path. In the interrupt handler we cannot use the mutex, but we do not need it. "The unbind disables the irq before making the port user stale, so when you clear it you are guaranteed that the interrupt handler that might use that port cannot be running." (from David). Hence this patch removes the spinlock usage on the teardown path and piggybacks on disable_irq happening before we muck with the get_port_user() data. This ensures that the interrupt handler will never run on stale data. Signed-off-by: David Vrabel Signed-off-by: Konrad Rzeszutek Wilk [v1: Expanded the commit description a bit] Signed-off-by: Jonghwan Choi Signed-off-by: Greg Kroah-Hartman --- drivers/xen/evtchn.c | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index dbc13e9..ce3a0f5 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -367,18 +367,12 @@ static long evtchn_ioctl(struct file *file, if (unbind.port >= NR_EVENT_CHANNELS) break; - spin_lock_irq(&port_user_lock); - rc = -ENOTCONN; - if (get_port_user(unbind.port) != u) { - spin_unlock_irq(&port_user_lock); + if (get_port_user(unbind.port) != u) break; - } disable_irq(irq_from_evtchn(unbind.port)); - spin_unlock_irq(&port_user_lock); - evtchn_unbind_from_user(u, unbind.port); rc = 0; @@ -478,26 +472,15 @@ static int evtchn_release(struct inode *inode, struct file *filp) int i; struct per_user_data *u = filp->private_data; - spin_lock_irq(&port_user_lock); - - free_page((unsigned long)u->ring); - for (i = 0; i < NR_EVENT_CHANNELS; i++) { if (get_port_user(i) != u) continue; disable_irq(irq_from_evtchn(i)); - } - - spin_unlock_irq(&port_user_lock); - - for (i = 0; i < NR_EVENT_CHANNELS; i++) { - if (get_port_user(i) != u) - continue; - evtchn_unbind_from_user(get_port_user(i), i); } + free_page((unsigned long)u->ring); kfree(u->name); kfree(u); -- cgit v1.1 From 8ff3d73133cb5a8a3514cc184152c553637e74a8 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 4 Aug 2013 15:43:40 +0800 Subject: virtio: support unlocked queue poll commit cc229884d3f77ec3b1240e467e0236c3e0647c0c upstream. This adds a way to check ring empty state after enable_cb outside any locks. Will be used by virtio_net. Note: there's room for more optimization: caller is likely to have a memory barrier already, which means we might be able to get rid of a barrier here. Deferring this optimization until we do some benchmarking. Signed-off-by: Michael S. Tsirkin Signed-off-by: David S. Miller [wg: Backported to 3.2] Signed-off-by: Wolfram Gloger Signed-off-by: Greg Kroah-Hartman --- drivers/virtio/virtio_ring.c | 59 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 92bd773..a0aecab 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -359,9 +359,22 @@ void virtqueue_disable_cb(struct virtqueue *_vq) } EXPORT_SYMBOL_GPL(virtqueue_disable_cb); -bool virtqueue_enable_cb(struct virtqueue *_vq) +/** + * virtqueue_enable_cb_prepare - restart callbacks after disable_cb + * @vq: the struct virtqueue we're talking about. + * + * This re-enables callbacks; it returns current queue state + * in an opaque unsigned value. This value should be later tested by + * virtqueue_poll, to detect a possible race between the driver checking for + * more work, and enabling callbacks. + * + * Caller must ensure we don't call this with other virtqueue + * operations at the same time (except where noted). + */ +unsigned virtqueue_enable_cb_prepare(struct virtqueue *_vq) { struct vring_virtqueue *vq = to_vvq(_vq); + u16 last_used_idx; START_USE(vq); @@ -371,15 +384,45 @@ bool virtqueue_enable_cb(struct virtqueue *_vq) * either clear the flags bit or point the event index at the next * entry. Always do both to keep code simple. */ vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; - vring_used_event(&vq->vring) = vq->last_used_idx; + vring_used_event(&vq->vring) = last_used_idx = vq->last_used_idx; + END_USE(vq); + return last_used_idx; +} +EXPORT_SYMBOL_GPL(virtqueue_enable_cb_prepare); + +/** + * virtqueue_poll - query pending used buffers + * @vq: the struct virtqueue we're talking about. + * @last_used_idx: virtqueue state (from call to virtqueue_enable_cb_prepare). + * + * Returns "true" if there are pending used buffers in the queue. + * + * This does not need to be serialized. + */ +bool virtqueue_poll(struct virtqueue *_vq, unsigned last_used_idx) +{ + struct vring_virtqueue *vq = to_vvq(_vq); + virtio_mb(); - if (unlikely(more_used(vq))) { - END_USE(vq); - return false; - } + return (u16)last_used_idx != vq->vring.used->idx; +} +EXPORT_SYMBOL_GPL(virtqueue_poll); - END_USE(vq); - return true; +/** + * virtqueue_enable_cb - restart callbacks after disable_cb. + * @vq: the struct virtqueue we're talking about. + * + * This re-enables callbacks; it returns "false" if there are pending + * buffers in the queue, to detect a possible race between the driver + * checking for more work, and enabling callbacks. + * + * Caller must ensure we don't call this with other virtqueue + * operations at the same time (except where noted). + */ +bool virtqueue_enable_cb(struct virtqueue *_vq) +{ + unsigned last_used_idx = virtqueue_enable_cb_prepare(_vq); + return !virtqueue_poll(_vq, last_used_idx); } EXPORT_SYMBOL_GPL(virtqueue_enable_cb); -- cgit v1.1 From 27fe2c366213592a862d8f5160c606eded3947c7 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 4 Aug 2013 15:43:40 +0800 Subject: virtio_net: fix race in RX VQ processing commit cbdadbbf0c790f79350a8f36029208944c5487d0 upstream virtio net called virtqueue_enable_cq on RX path after napi_complete, so with NAPI_STATE_SCHED clear - outside the implicit napi lock. This violates the requirement to synchronize virtqueue_enable_cq wrt virtqueue_add_buf. In particular, used event can move backwards, causing us to lose interrupts. In a debug build, this can trigger panic within START_USE. Jason Wang reports that he can trigger the races artificially, by adding udelay() in virtqueue_enable_cb() after virtio_mb(). However, we must call napi_complete to clear NAPI_STATE_SCHED before polling the virtqueue for used buffers, otherwise napi_schedule_prep in a callback will fail, causing us to lose RX events. To fix, call virtqueue_enable_cb_prepare with NAPI_STATE_SCHED set (under napi lock), later call virtqueue_poll with NAPI_STATE_SCHED clear (outside the lock). Reported-by: Jason Wang Tested-by: Jason Wang Acked-by: Jason Wang Signed-off-by: Michael S. Tsirkin Signed-off-by: David S. Miller [wg: Backported to 3.2] Signed-off-by: Wolfram Gloger Signed-off-by: Greg Kroah-Hartman --- drivers/net/virtio_net.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index f685324..316a565 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -480,7 +480,7 @@ static int virtnet_poll(struct napi_struct *napi, int budget) { struct virtnet_info *vi = container_of(napi, struct virtnet_info, napi); void *buf; - unsigned int len, received = 0; + unsigned int r, len, received = 0; again: while (received < budget && @@ -497,8 +497,9 @@ again: /* Out of packets? */ if (received < budget) { + r = virtqueue_enable_cb_prepare(vi->rvq); napi_complete(napi); - if (unlikely(!virtqueue_enable_cb(vi->rvq)) && + if (unlikely(virtqueue_poll(vi->rvq, r)) && napi_schedule_prep(napi)) { virtqueue_disable_cb(vi->rvq); __napi_schedule(napi); -- cgit v1.1 From 71ee5d037bc9d215e06248642ea28b559b9440fa Mon Sep 17 00:00:00 2001 From: Ren Bigcren Date: Tue, 2 Jul 2013 13:34:30 +0200 Subject: USB: storage: Add MicroVault Flash Drive to unusual_devs commit e7a6121f4929c17215f0cdca3726f4bf3e4e9529 upstream. The device report an error capacity when read_capacity_16(). Using read_capacity_10() can get the correct capacity. Signed-off-by: Ren Bigcren Cc: Matthew Dharm Signed-off-by: Oskar Andero Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 8a3b531..e073e2f 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -664,6 +664,13 @@ UNUSUAL_DEV( 0x054c, 0x02a5, 0x0100, 0x0100, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_READ_CAPACITY_16 ), +/* Submitted by Ren Bigcren */ +UNUSUAL_DEV( 0x054c, 0x02a5, 0x0100, 0x0100, + "Sony Corp.", + "MicroVault Flash Drive", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_READ_CAPACITY_16 ), + /* floppy reports multiple luns */ UNUSUAL_DEV( 0x055d, 0x2020, 0x0000, 0x0210, "SAMSUNG", -- cgit v1.1 From 8c7e5916a54affa0565428f8926008f0d175ae88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 4 Jul 2013 11:28:51 +0200 Subject: serial/mxs-auart: fix race condition in interrupt handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit d970d7fe65adff5efe75b4a73c4ffc9be57089f7 upstream. The handler needs to ack the pending events before actually handling them. Otherwise a new event might come in after it it considered non-pending or handled and is acked then without being handled. So this event is only noticed when the next interrupt happens. Without this patch an i.MX28 based machine running an rt-patched kernel regularly hangs during boot. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mxs-auart.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 5b3d063..e6b8b09 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -374,11 +374,18 @@ static void mxs_auart_settermios(struct uart_port *u, static irqreturn_t mxs_auart_irq_handle(int irq, void *context) { - u32 istatus, istat; + u32 istat; struct mxs_auart_port *s = context; u32 stat = readl(s->port.membase + AUART_STAT); - istatus = istat = readl(s->port.membase + AUART_INTR); + istat = readl(s->port.membase + AUART_INTR); + + /* ack irq */ + writel(istat & (AUART_INTR_RTIS + | AUART_INTR_TXIS + | AUART_INTR_RXIS + | AUART_INTR_CTSMIS), + s->port.membase + AUART_INTR_CLR); if (istat & AUART_INTR_CTSMIS) { uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS); @@ -397,12 +404,6 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context) istat &= ~AUART_INTR_TXIS; } - writel(istatus & (AUART_INTR_RTIS - | AUART_INTR_TXIS - | AUART_INTR_RXIS - | AUART_INTR_CTSMIS), - s->port.membase + AUART_INTR_CLR); - return IRQ_HANDLED; } -- cgit v1.1 From 3d709d102bd11c86eddcbf6c50407df19a4fbc34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Fri, 28 Jun 2013 11:49:41 +0200 Subject: serial/mxs-auart: increase time to wait for transmitter to become idle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 079a036f4283e2b0e5c26080b8c5112bc0cc1831 upstream. Without this patch the driver waits ~1 ms for the UART to become idle. At 115200n8 this time is (theoretically) enough to transfer 11.5 characters (= 115200 bits/s / (10 Bits/char) * 1ms). As the mxs-auart has a fifo size of 16 characters the clock is gated too early. The problem is worse for lower baud rates. This only happens to really shut down the transmitter in the middle of a transfer if /dev/ttyAPPx isn't opened in userspace (e.g. by a getty) but was at least once (because the bootloader doesn't disable the transmitter). So increase the timeout to 20 ms which should be enough for 9600n8, too. Moreover skip gating the clock if the timeout is elapsed. Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mxs-auart.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index e6b8b09..ab7d11e 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c @@ -543,7 +543,7 @@ auart_console_write(struct console *co, const char *str, unsigned int count) struct mxs_auart_port *s; struct uart_port *port; unsigned int old_ctrl0, old_ctrl2; - unsigned int to = 1000; + unsigned int to = 20000; if (co->index > MXS_AUART_PORTS || co->index < 0) return; @@ -564,18 +564,23 @@ auart_console_write(struct console *co, const char *str, unsigned int count) uart_console_write(port, str, count, mxs_auart_console_putchar); - /* - * Finally, wait for transmitter to become empty - * and restore the TCR - */ + /* Finally, wait for transmitter to become empty ... */ while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) { + udelay(1); if (!to--) break; - udelay(1); } - writel(old_ctrl0, port->membase + AUART_CTRL0); - writel(old_ctrl2, port->membase + AUART_CTRL2); + /* + * ... and restore the TCR if we waited long enough for the transmitter + * to be idle. This might keep the transmitter enabled although it is + * unused, but that is better than to disable it while it is still + * transmitting. + */ + if (!(readl(port->membase + AUART_STAT) & AUART_STAT_BUSY)) { + writel(old_ctrl0, port->membase + AUART_CTRL0); + writel(old_ctrl2, port->membase + AUART_CTRL2); + } clk_disable(s->clk); } -- cgit v1.1 From 20d717bb0ff8cf37eedc9edb538c6f7ddc2b44cc Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 19 Jul 2013 20:16:17 +0200 Subject: ath9k_htc: do some initial hardware configuration commit dc2a87f519a4d8cb376ab54f22b6b98a943b51ce upstream. Currently we configure harwdare and clock, only after interface start. In this case, if we reload module or reboot PC without configuring adapter, firmware will freeze. There is no software way to reset adpter. This patch add initial configuration and set it in disabled state, to avoid this freeze. Behaviour of this patch should be similar to: ifconfig wlan0 up; ifconfig wlan0 down. Bug: https://github.com/qca/open-ath9k-htc-firmware/issues/1 Tested-by: Bo Shi Signed-off-by: Oleksij Rempel Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 4099712..403d33f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -873,6 +873,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, if (error != 0) goto err_rx; + ath9k_hw_disable(priv->ah); #ifdef CONFIG_MAC80211_LEDS /* must be initialized before ieee80211_register_hw */ priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw, -- cgit v1.1 From 0088acabd29e8060552237f4f256b476678c68c2 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Sun, 28 Jul 2013 13:17:22 +0200 Subject: rt2x00: fix stop queue commit e2288b66fe7ff0288382b2af671b4da558b44472 upstream. Since we clear QUEUE_STARTED in rt2x00queue_stop_queue(), following call to rt2x00queue_pause_queue() reduce to noop, i.e we do not stop queue in mac80211. To fix that introduce rt2x00queue_pause_queue_nocheck() function, which will stop queue in mac80211 directly. Note that rt2x00_start_queue() explicitly set QUEUE_PAUSED bit. Note also that reordering operations i.e. first call to rt2x00queue_pause_queue() and then clear QUEUE_STARTED bit, will race with rt2x00queue_unpause_queue(), so calling ieee80211_stop_queue() directly is the only available solution to fix the problem without major rework. Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/rt2x00/rt2x00queue.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 76f26ad..2d7c59f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -848,13 +848,8 @@ void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index) spin_unlock_irqrestore(&queue->index_lock, irqflags); } -void rt2x00queue_pause_queue(struct data_queue *queue) +void rt2x00queue_pause_queue_nocheck(struct data_queue *queue) { - if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) || - !test_bit(QUEUE_STARTED, &queue->flags) || - test_and_set_bit(QUEUE_PAUSED, &queue->flags)) - return; - switch (queue->qid) { case QID_AC_VO: case QID_AC_VI: @@ -870,6 +865,15 @@ void rt2x00queue_pause_queue(struct data_queue *queue) break; } } +void rt2x00queue_pause_queue(struct data_queue *queue) +{ + if (!test_bit(DEVICE_STATE_PRESENT, &queue->rt2x00dev->flags) || + !test_bit(QUEUE_STARTED, &queue->flags) || + test_and_set_bit(QUEUE_PAUSED, &queue->flags)) + return; + + rt2x00queue_pause_queue_nocheck(queue); +} EXPORT_SYMBOL_GPL(rt2x00queue_pause_queue); void rt2x00queue_unpause_queue(struct data_queue *queue) @@ -931,7 +935,7 @@ void rt2x00queue_stop_queue(struct data_queue *queue) return; } - rt2x00queue_pause_queue(queue); + rt2x00queue_pause_queue_nocheck(queue); queue->rt2x00dev->ops->lib->stop_queue(queue); -- cgit v1.1 From 605e81c987e95f423ee97173a2002363404a1402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mo=C5=84?= Date: Tue, 23 Jul 2013 07:42:49 +0200 Subject: mwifiex: Add missing endian conversion. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 83e612f632c3897be29ef02e0472f6d63e258378 upstream. Both type and pkt_len variables are in host endian and these should be in Little Endian in the payload. Signed-off-by: Tomasz Moń Acked-by: Bing Zhao Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/mwifiex/sdio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 3b1217f..61e152d 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -1387,8 +1387,8 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, /* Allocate buffer and copy payload */ blk_size = MWIFIEX_SDIO_BLOCK_SIZE; buf_block_len = (pkt_len + blk_size - 1) / blk_size; - *(u16 *) &payload[0] = (u16) pkt_len; - *(u16 *) &payload[2] = type; + *(__le16 *)&payload[0] = cpu_to_le16((u16)pkt_len); + *(__le16 *)&payload[2] = cpu_to_le16(type); /* * This is SDIO specific header -- cgit v1.1 From 09ff7f1fc186c7c45211c8e70761863366e6c7b6 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Tue, 30 Jul 2013 14:00:42 +0200 Subject: ACPI / battery: Fix parsing _BIX return value commit 016d5baad04269e8559332df05f89bd95b52d6ad upstream. The _BIX method returns extended battery info as a package. According the ACPI spec (ACPI 5, Section 10.2.2.2), the first member of that package should be "Revision". However, the current ACPI battery driver treats the first member as "Power Unit" which should be the second member. This causes the result of _BIX return data parsing to be incorrect. Fix this by adding a new member called 'revision' to struct acpi_battery and adding the offsetof() information on it to extended_info_offsets[] as the first row. [rjw: Changelog] Reported-and-tested-by: Jan Hoffmann References: http://bugzilla.kernel.org/show_bug.cgi?id=60519 Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/battery.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 4a15d57..908f40a 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -118,6 +118,7 @@ struct acpi_battery { struct acpi_device *device; struct notifier_block pm_nb; unsigned long update_time; + int revision; int rate_now; int capacity_now; int voltage_now; @@ -350,6 +351,7 @@ static struct acpi_offsets info_offsets[] = { }; static struct acpi_offsets extended_info_offsets[] = { + {offsetof(struct acpi_battery, revision), 0}, {offsetof(struct acpi_battery, power_unit), 0}, {offsetof(struct acpi_battery, design_capacity), 0}, {offsetof(struct acpi_battery, full_charge_capacity), 0}, -- cgit v1.1 From b04aff391ca61fb2ac4e60be602aa2850c577cdd Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 19 Jul 2013 08:48:05 +0300 Subject: arcnet: cleanup sizeof parameter [ Upstream commit 087d273caf4f7d3f2159256f255f1f432bc84a5b ] This patch doesn't change the compiled code because ARC_HDR_SIZE is 4 and sizeof(int) is 4, but the intent was to use the header size and not the sizeof the header size. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/arcnet/arcnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index a746ba2..a956053 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -1007,7 +1007,7 @@ static void arcnet_rx(struct net_device *dev, int bufnum) soft = &pkt.soft.rfc1201; - lp->hw.copy_from_card(dev, bufnum, 0, &pkt, sizeof(ARC_HDR_SIZE)); + lp->hw.copy_from_card(dev, bufnum, 0, &pkt, ARC_HDR_SIZE); if (pkt.hard.offset[0]) { ofs = pkt.hard.offset[0]; length = 256 - ofs; -- cgit v1.1 From 590c955eaaa18c5f1b341093baa60e0d582ba426 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 23 Jul 2013 17:15:54 -0700 Subject: usbnet: do not pretend to support SG/TSO [ Upstream commit 20f0170377264e8449b6987041f0bcc4d746d3ed ] usbnet doesn't support yet SG, so drivers should not advertise SG or TSO capabilities, as they allow TCP stack to build large TSO packets that need to be linearized and might use order-5 pages. This adds an extra copy overhead and possible allocation failures. Current code ignore skb_linearize() return code so crashes are even possible. Best is to not pretend SG/TSO is supported, and add this again when/if usbnet really supports SG for devices who could get a performance gain. Based on a prior patch from Freddy Xin Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/smsc75xx.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 2f4775f..be27891 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -43,7 +43,6 @@ #define EEPROM_MAC_OFFSET (0x01) #define DEFAULT_TX_CSUM_ENABLE (true) #define DEFAULT_RX_CSUM_ENABLE (true) -#define DEFAULT_TSO_ENABLE (true) #define SMSC75XX_INTERNAL_PHY_ID (1) #define SMSC75XX_TX_OVERHEAD (8) #define MAX_RX_FIFO_SIZE (20 * 1024) @@ -1034,17 +1033,14 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write); - if (DEFAULT_TX_CSUM_ENABLE) { + if (DEFAULT_TX_CSUM_ENABLE) dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; - if (DEFAULT_TSO_ENABLE) - dev->net->features |= NETIF_F_SG | - NETIF_F_TSO | NETIF_F_TSO6; - } + if (DEFAULT_RX_CSUM_ENABLE) dev->net->features |= NETIF_F_RXCSUM; dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_RXCSUM; + NETIF_F_RXCSUM; /* Init all registers */ ret = smsc75xx_reset(dev); @@ -1169,8 +1165,6 @@ static struct sk_buff *smsc75xx_tx_fixup(struct usbnet *dev, { u32 tx_cmd_a, tx_cmd_b; - skb_linearize(skb); - if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) { struct sk_buff *skb2 = skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags); -- cgit v1.1 From 2e18e5161c634aa5d7e685f348aca98d295accb8 Mon Sep 17 00:00:00 2001 From: Curt Brune Date: Thu, 8 Aug 2013 12:11:03 -0700 Subject: hwmon: (adt7470) Fix incorrect return code check commit 93d783bcca69bfacc8dc739d8a050498402587b5 upstream. In adt7470_write_word_data(), which writes two bytes using i2c_smbus_write_byte_data(), the return codes are incorrectly AND-ed together when they should be OR-ed together. The return code of i2c_smbus_write_byte_data() is zero for success. The upshot is only the first byte was ever written to the hardware. The 2nd byte was never written out. I noticed that trying to set the fan speed limits was not working correctly on my system. Setting the fan speed limits is the only code that uses adt7470_write_word_data(). After making the change the limit settings work and the alarms work also. Signed-off-by: Curt Brune Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/adt7470.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/adt7470.c b/drivers/hwmon/adt7470.c index c6d1ce0..a9726c1 100644 --- a/drivers/hwmon/adt7470.c +++ b/drivers/hwmon/adt7470.c @@ -215,7 +215,7 @@ static inline int adt7470_write_word_data(struct i2c_client *client, u8 reg, u16 value) { return i2c_smbus_write_byte_data(client, reg, value & 0xFF) - && i2c_smbus_write_byte_data(client, reg + 1, value >> 8); + || i2c_smbus_write_byte_data(client, reg + 1, value >> 8); } static void adt7470_init_client(struct i2c_client *client) -- cgit v1.1 From e3a5a432070dcebaffee8f9af193f99471280ea9 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 29 Jul 2013 14:16:13 +0930 Subject: virtio: console: fix race with port unplug and open/close commit 057b82be3ca3d066478e43b162fc082930a746c9 upstream. There's a window between find_port_by_devt() returning a port and us taking a kref on the port, where the port could get unplugged. Fix it by taking the reference in find_port_by_devt() itself. Problem reported and analyzed by Mateusz Guzik. Reported-by: Mateusz Guzik Signed-off-by: Amit Shah Signed-off-by: Rusty Russell Signed-off-by: Greg Kroah-Hartman --- drivers/char/virtio_console.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index a95256a..a21d6d2 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -241,9 +241,12 @@ static struct port *find_port_by_devt_in_portdev(struct ports_device *portdev, unsigned long flags; spin_lock_irqsave(&portdev->ports_lock, flags); - list_for_each_entry(port, &portdev->ports, list) - if (port->cdev->dev == dev) + list_for_each_entry(port, &portdev->ports, list) { + if (port->cdev->dev == dev) { + kref_get(&port->kref); goto out; + } + } port = NULL; out: spin_unlock_irqrestore(&portdev->ports_lock, flags); @@ -781,14 +784,10 @@ static int port_fops_open(struct inode *inode, struct file *filp) struct port *port; int ret; + /* We get the port with a kref here */ port = find_port_by_devt(cdev->dev); filp->private_data = port; - /* Prevent against a port getting hot-unplugged at the same time */ - spin_lock_irq(&port->portdev->ports_lock); - kref_get(&port->kref); - spin_unlock_irq(&port->portdev->ports_lock); - /* * Don't allow opening of console port devices -- that's done * via /dev/hvc -- cgit v1.1 From 6c17607b4149b82da3cabffca74c2cdfb8479bb1 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 29 Jul 2013 14:17:13 +0930 Subject: virtio: console: fix race in port_fops_open() and port unplug commit 671bdea2b9f210566610603ecbb6584c8a201c8c upstream. Between open() being called and processed, the port can be unplugged. Check if this happened, and bail out. A simple test script to reproduce this is: while true; do for i in $(seq 1 100); do echo $i > /dev/vport0p3; done; done; This opens and closes the port a lot of times; unplugging the port while this is happening triggers the bug. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell Signed-off-by: Greg Kroah-Hartman --- drivers/char/virtio_console.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index a21d6d2..08570ef 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -786,6 +786,10 @@ static int port_fops_open(struct inode *inode, struct file *filp) /* We get the port with a kref here */ port = find_port_by_devt(cdev->dev); + if (!port) { + /* Port was unplugged before we could proceed */ + return -ENXIO; + } filp->private_data = port; /* -- cgit v1.1 From 64aafc3d30fac8bc65bb28b1bbd97528cb5ef725 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 29 Jul 2013 14:20:29 +0930 Subject: virtio: console: clean up port data immediately at time of unplug commit ea3768b4386a8d1790f4cc9a35de4f55b92d6442 upstream. We used to keep the port's char device structs and the /sys entries around till the last reference to the port was dropped. This is actually unnecessary, and resulted in buggy behaviour: 1. Open port in guest 2. Hot-unplug port 3. Hot-plug a port with the same 'name' property as the unplugged one This resulted in hot-plug being unsuccessful, as a port with the same name already exists (even though it was unplugged). This behaviour resulted in a warning message like this one: -------------------8<--------------------------------------- WARNING: at fs/sysfs/dir.c:512 sysfs_add_one+0xc9/0x130() (Not tainted) Hardware name: KVM sysfs: cannot create duplicate filename '/devices/pci0000:00/0000:00:04.0/virtio0/virtio-ports/vport0p1' Call Trace: [] ? warn_slowpath_common+0x87/0xc0 [] ? warn_slowpath_fmt+0x46/0x50 [] ? sysfs_add_one+0xc9/0x130 [] ? create_dir+0x68/0xb0 [] ? sysfs_create_dir+0x39/0x50 [] ? kobject_add_internal+0xb9/0x260 [] ? kobject_add_varg+0x38/0x60 [] ? kobject_add+0x44/0x70 [] ? get_device_parent+0xf4/0x1d0 [] ? device_add+0xc9/0x650 -------------------8<--------------------------------------- Instead of relying on guest applications to release all references to the ports, we should go ahead and unregister the port from all the core layers. Any open/read calls on the port will then just return errors, and an unplug/plug operation on the host will succeed as expected. This also caused buggy behaviour in case of the device removal (not just a port): when the device was removed (which means all ports on that device are removed automatically as well), the ports with active users would clean up only when the last references were dropped -- and it would be too late then to be referencing char device pointers, resulting in oopses: -------------------8<--------------------------------------- PID: 6162 TASK: ffff8801147ad500 CPU: 0 COMMAND: "cat" #0 [ffff88011b9d5a90] machine_kexec at ffffffff8103232b #1 [ffff88011b9d5af0] crash_kexec at ffffffff810b9322 #2 [ffff88011b9d5bc0] oops_end at ffffffff814f4a50 #3 [ffff88011b9d5bf0] die at ffffffff8100f26b #4 [ffff88011b9d5c20] do_general_protection at ffffffff814f45e2 #5 [ffff88011b9d5c50] general_protection at ffffffff814f3db5 [exception RIP: strlen+2] RIP: ffffffff81272ae2 RSP: ffff88011b9d5d00 RFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff880118901c18 RCX: 0000000000000000 RDX: ffff88011799982c RSI: 00000000000000d0 RDI: 3a303030302f3030 RBP: ffff88011b9d5d38 R8: 0000000000000006 R9: ffffffffa0134500 R10: 0000000000001000 R11: 0000000000001000 R12: ffff880117a1cc10 R13: 00000000000000d0 R14: 0000000000000017 R15: ffffffff81aff700 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 #6 [ffff88011b9d5d00] kobject_get_path at ffffffff8126dc5d #7 [ffff88011b9d5d40] kobject_uevent_env at ffffffff8126e551 #8 [ffff88011b9d5dd0] kobject_uevent at ffffffff8126e9eb #9 [ffff88011b9d5de0] device_del at ffffffff813440c7 -------------------8<--------------------------------------- So clean up when we have all the context, and all that's left to do when the references to the port have dropped is to free up the port struct itself. Reported-by: chayang Reported-by: YOGANANTH SUBRAMANIAN Reported-by: FuXiangChun Reported-by: Qunfang Zhang Reported-by: Sibiao Luo Signed-off-by: Amit Shah Signed-off-by: Rusty Russell Signed-off-by: Greg Kroah-Hartman --- drivers/char/virtio_console.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 08570ef..7a25a7e 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1246,14 +1246,6 @@ static void remove_port(struct kref *kref) port = container_of(kref, struct port, kref); - sysfs_remove_group(&port->dev->kobj, &port_attribute_group); - device_destroy(pdrvdata.class, port->dev->devt); - cdev_del(port->cdev); - - kfree(port->name); - - debugfs_remove(port->debugfs_file); - kfree(port); } @@ -1302,6 +1294,14 @@ static void unplug_port(struct port *port) */ port->portdev = NULL; + sysfs_remove_group(&port->dev->kobj, &port_attribute_group); + device_destroy(pdrvdata.class, port->dev->devt); + cdev_del(port->cdev); + + kfree(port->name); + + debugfs_remove(port->debugfs_file); + /* * Locks around here are not necessary - a port can't be * opened after we removed the port struct from ports_list -- cgit v1.1 From 7ba6337874c92f15212065b120fa70de573c56ed Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 29 Jul 2013 14:21:32 +0930 Subject: virtio: console: fix raising SIGIO after port unplug commit 92d3453815fbe74d539c86b60dab39ecdf01bb99 upstream. SIGIO should be sent when a port gets unplugged. It should only be sent to prcesses that have the port opened, and have asked for SIGIO to be delivered. We were clearing out guest_connected before calling send_sigio_to_port(), resulting in a sigio not getting sent to processes. Fix by setting guest_connected to false after invoking the sigio function. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell Signed-off-by: Greg Kroah-Hartman --- drivers/char/virtio_console.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 7a25a7e..0d50d92 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1263,12 +1263,14 @@ static void unplug_port(struct port *port) spin_unlock_irq(&port->portdev->ports_lock); if (port->guest_connected) { + /* Let the app know the port is going down. */ + send_sigio_to_port(port); + + /* Do this after sigio is actually sent */ port->guest_connected = false; port->host_connected = false; - wake_up_interruptible(&port->waitqueue); - /* Let the app know the port is going down. */ - send_sigio_to_port(port); + wake_up_interruptible(&port->waitqueue); } if (is_console_port(port)) { -- cgit v1.1 From 1336e0d81c7ea5128f87993907aaff3db71bf973 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Mon, 29 Jul 2013 14:23:21 +0930 Subject: virtio: console: return -ENODEV on all read operations after unplug commit 96f97a83910cdb9d89d127c5ee523f8fc040a804 upstream. If a port gets unplugged while a user is blocked on read(), -ENODEV is returned. However, subsequent read()s returned 0, indicating there's no host-side connection (but not indicating the device went away). This also happened when a port was unplugged and the user didn't have any blocking operation pending. If the user didn't monitor the SIGIO signal, they won't have a chance to find out if the port went away. Fix by returning -ENODEV on all read()s after the port gets unplugged. write() already behaves this way. Signed-off-by: Amit Shah Signed-off-by: Rusty Russell Signed-off-by: Greg Kroah-Hartman --- drivers/char/virtio_console.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 0d50d92..f2fb2f2 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -625,6 +625,10 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf, port = filp->private_data; + /* Port is hot-unplugged. */ + if (!port->guest_connected) + return -ENODEV; + if (!port_has_data(port)) { /* * If nothing's connected on the host just return 0 in @@ -641,7 +645,7 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf, if (ret < 0) return ret; } - /* Port got hot-unplugged. */ + /* Port got hot-unplugged while we were waiting above. */ if (!port->guest_connected) return -ENODEV; /* -- cgit v1.1 From 5fc83a91c5d973a204efc619006699da9676e37f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 14 Mar 2013 15:21:36 +0100 Subject: SCSI: nsp32: use mdelay instead of large udelay constants commit b497ceb964a80ebada3b9b3cea4261409039e25a upstream. ARM cannot handle udelay for more than 2 miliseconds, so we should use mdelay instead for those. Signed-off-by: Arnd Bergmann Acked-by: GOTO Masanori Cc: YOKOTA Hiroshi Cc: "James E.J. Bottomley" Cc: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/nsp32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index f6a50c9..bfb05b8 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -2927,7 +2927,7 @@ static void nsp32_do_bus_reset(nsp32_hw_data *data) * reset SCSI bus */ nsp32_write1(base, SCSI_BUS_CONTROL, BUSCTL_RST); - udelay(RESET_HOLD_TIME); + mdelay(RESET_HOLD_TIME / 1000); nsp32_write1(base, SCSI_BUS_CONTROL, 0); for(i = 0; i < 5; i++) { intrdat = nsp32_read2(base, IRQ_STATUS); /* dummy read */ -- cgit v1.1 From fc1cabf00e9fd2fbfaf4d4df246f53138ccf3a0d Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 14 Aug 2013 11:01:46 +0200 Subject: usb: add two quirky touchscreen commit 304ab4ab079a8ed03ce39f1d274964a532db036b upstream. These devices tend to become unresponsive after S3 Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index f88ad63..8659cd9 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -100,6 +100,12 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x04d8, 0x000c), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, + /* CarrolTouch 4000U */ + { USB_DEVICE(0x04e7, 0x0009), .driver_info = USB_QUIRK_RESET_RESUME }, + + /* CarrolTouch 4500U */ + { USB_DEVICE(0x04e7, 0x0030), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Samsung Android phone modem - ID conflict with SPH-I500 */ { USB_DEVICE(0x04e8, 0x6601), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, -- cgit v1.1 From d808cb7d6aacff9e39d6d1a4e4ad54ad0a47e901 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 13 Aug 2013 13:27:34 +0200 Subject: USB: mos7720: fix broken control requests commit ef6c8c1d733e244f0499035be0dabe1f4ed98c6f upstream. The parallel-port code of the drivers used a stack allocated control-request buffer for asynchronous (and possibly deferred) control requests. This not only violates the no-DMA-from-stack requirement but could also lead to corrupt control requests being submitted. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7720.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 703d1fa..267dff9 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -97,6 +97,7 @@ struct urbtracker { struct list_head urblist_entry; struct kref ref_count; struct urb *urb; + struct usb_ctrlrequest *setup; }; enum mos7715_pp_modes { @@ -279,6 +280,7 @@ static void destroy_urbtracker(struct kref *kref) struct mos7715_parport *mos_parport = urbtrack->mos_parport; dbg("%s called", __func__); usb_free_urb(urbtrack->urb); + kfree(urbtrack->setup); kfree(urbtrack); kref_put(&mos_parport->ref_count, destroy_mos_parport); } @@ -363,7 +365,6 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, struct urbtracker *urbtrack; int ret_val; unsigned long flags; - struct usb_ctrlrequest setup; struct usb_serial *serial = mos_parport->serial; struct usb_device *usbdev = serial->dev; dbg("%s called", __func__); @@ -382,14 +383,20 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, kfree(urbtrack); return -ENOMEM; } - setup.bRequestType = (__u8)0x40; - setup.bRequest = (__u8)0x0e; - setup.wValue = get_reg_value(reg, dummy); - setup.wIndex = get_reg_index(reg); - setup.wLength = 0; + urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL); + if (!urbtrack->setup) { + usb_free_urb(urbtrack->urb); + kfree(urbtrack); + return -ENOMEM; + } + urbtrack->setup->bRequestType = (__u8)0x40; + urbtrack->setup->bRequest = (__u8)0x0e; + urbtrack->setup->wValue = get_reg_value(reg, dummy); + urbtrack->setup->wIndex = get_reg_index(reg); + urbtrack->setup->wLength = 0; usb_fill_control_urb(urbtrack->urb, usbdev, usb_sndctrlpipe(usbdev, 0), - (unsigned char *)&setup, + (unsigned char *)urbtrack->setup, NULL, 0, async_complete, urbtrack); kref_init(&urbtrack->ref_count); INIT_LIST_HEAD(&urbtrack->urblist_entry); -- cgit v1.1 From 50e27a160f6146de036e81420dc13ec9f4824564 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Tue, 6 Aug 2013 14:28:42 +0300 Subject: zd1201: do not use stack as URB transfer_buffer commit 1206ff4ff9d2ef7468a355328bc58ac6ebf5be44 upstream. Patch fixes zd1201 not to use stack as URB transfer_buffer. URB buffers need to be DMA-able, which stack is not. Patch is only compile tested. Signed-off-by: Jussi Kivilinna Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/zd1201.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index 415eec4..af792a4 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c @@ -98,10 +98,12 @@ static int zd1201_fw_upload(struct usb_device *dev, int apfw) goto exit; err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x4, - USB_DIR_IN | 0x40, 0,0, &ret, sizeof(ret), ZD1201_FW_TIMEOUT); + USB_DIR_IN | 0x40, 0, 0, buf, sizeof(ret), ZD1201_FW_TIMEOUT); if (err < 0) goto exit; + memcpy(&ret, buf, sizeof(ret)); + if (ret & 0x80) { err = -EIO; goto exit; -- cgit v1.1 From 1b9ba06c5f4e84b8dfa402bee0daff42db045977 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Thu, 15 Aug 2013 13:21:06 +0100 Subject: xen/events: initialize local per-cpu mask for all possible events commit 84ca7a8e45dafb49cd5ca90a343ba033e2885c17 upstream. The sizeof() argument in init_evtchn_cpu_bindings() is incorrect resulting in only the first 64 (or 32 in 32-bit guests) ports having their bindings being initialized to VCPU 0. In most cases this does not cause a problem as request_irq() will set the irq affinity which will set the correct local per-cpu mask. However, if the request_irq() is called on a VCPU other than 0, there is a window between the unmasking of the event and the affinity being set were an event may be lost because it is not locally unmasked on any VCPU. If request_irq() is called on VCPU 0 then local irqs are disabled during the window and the race does not occur. Fix this by initializing all NR_EVENT_CHANNEL bits in the local per-cpu masks. Signed-off-by: David Vrabel Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: Greg Kroah-Hartman --- drivers/xen/events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/events.c b/drivers/xen/events.c index a2f1f71..7ba4d0e 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -317,7 +317,7 @@ static void init_evtchn_cpu_bindings(void) for_each_possible_cpu(i) memset(per_cpu(cpu_evtchn_mask, i), - (i == 0) ? ~0 : 0, sizeof(*per_cpu(cpu_evtchn_mask, i))); + (i == 0) ? ~0 : 0, NR_EVENT_CHANNELS/8); } static inline void clear_evtchn(int port) -- cgit v1.1 From 14c3de73b19d1c758ae92ec4674482742ad54fb3 Mon Sep 17 00:00:00 2001 From: Wladislav Wiebe Date: Mon, 12 Aug 2013 13:06:53 +0200 Subject: of: fdt: fix memory initialization for expanded DT commit 9e40127526e857fa3f29d51e83277204fbdfc6ba upstream. Already existing property flags are filled wrong for properties created from initial FDT. This could cause problems if this DYNAMIC device-tree functions are used later, i.e. properties are attached/detached/replaced. Simply dumping flags from the running system show, that some initial static (not allocated via kzmalloc()) nodes are marked as dynamic. I putted some debug extensions to property_proc_show(..) : .. + if (OF_IS_DYNAMIC(pp)) + pr_err("DEBUG: xxx : OF_IS_DYNAMIC\n"); + if (OF_IS_DETACHED(pp)) + pr_err("DEBUG: xxx : OF_IS_DETACHED\n"); when you operate on the nodes (e.g.: ~$ cat /proc/device-tree/*some_node*) you will see that those flags are filled wrong, basically in most cases it will dump a DYNAMIC or DETACHED status, which is in not true. (BTW. this OF_IS_DETACHED is a own define for debug purposes which which just make a test_bit(OF_DETACHED, &x->_flags) If nodes are dynamic kernel is allowed to kfree() them. But it will crash attempting to do so on the nodes from FDT -- they are not allocated via kzmalloc(). Signed-off-by: Wladislav Wiebe Acked-by: Alexander Sverdlin Signed-off-by: Rob Herring Signed-off-by: Greg Kroah-Hartman --- drivers/of/fdt.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 65200af..d3645f6 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -389,6 +389,8 @@ static void __unflatten_device_tree(struct boot_param_header *blob, mem = (unsigned long) dt_alloc(size + 4, __alignof__(struct device_node)); + memset((void *)mem, 0, size); + ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); pr_debug(" unflattening %lx...\n", mem); -- cgit v1.1 From 8d43271717d467f6795cfc5a81fd2cd886833330 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 9 Aug 2013 12:52:31 +0300 Subject: Hostap: copying wrong data prism2_ioctl_giwaplist() commit 909bd5926d474e275599094acad986af79671ac9 upstream. We want the data stored in "addr" and "qual", but the extra ampersands mean we are copying stack data instead. Signed-off-by: Dan Carpenter Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/hostap/hostap_ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index 12de464..10ce1bc 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c @@ -521,9 +521,9 @@ static int prism2_ioctl_giwaplist(struct net_device *dev, data->length = prism2_ap_get_sta_qual(local, addr, qual, IW_MAX_AP, 1); - memcpy(extra, &addr, sizeof(struct sockaddr) * data->length); + memcpy(extra, addr, sizeof(struct sockaddr) * data->length); data->flags = 1; /* has quality information */ - memcpy(extra + sizeof(struct sockaddr) * data->length, &qual, + memcpy(extra + sizeof(struct sockaddr) * data->length, qual, sizeof(struct iw_quality) * data->length); kfree(addr); -- cgit v1.1 From 016d826cfcb22b27915149aabadf461641b7907c Mon Sep 17 00:00:00 2001 From: Terry Suereth Date: Sat, 17 Aug 2013 15:53:12 -0400 Subject: libata: apply behavioral quirks to sil3826 PMP commit 8ffff94d20b7eb446e848e0046107d51b17a20a8 upstream. Fixing support for the Silicon Image 3826 port multiplier, by applying to it the same quirks applied to the Silicon Image 3726. Specifically fixes the repeated timeout/reset process which previously afflicted the 3726, as described from line 290. Slightly based on notes from: https://bugzilla.redhat.com/show_bug.cgi?id=890237 Signed-off-by: Terry Suereth Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/ata/libata-pmp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index f06b7ea..cf9dc09 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -288,24 +288,24 @@ static int sata_pmp_configure(struct ata_device *dev, int print_info) /* Disable sending Early R_OK. * With "cached read" HDD testing and multiple ports busy on a SATA - * host controller, 3726 PMP will very rarely drop a deferred + * host controller, 3x26 PMP will very rarely drop a deferred * R_OK that was intended for the host. Symptom will be all * 5 drives under test will timeout, get reset, and recover. */ - if (vendor == 0x1095 && devid == 0x3726) { + if (vendor == 0x1095 && (devid == 0x3726 || devid == 0x3826)) { u32 reg; err_mask = sata_pmp_read(&ap->link, PMP_GSCR_SII_POL, ®); if (err_mask) { rc = -EIO; - reason = "failed to read Sil3726 Private Register"; + reason = "failed to read Sil3x26 Private Register"; goto fail; } reg &= ~0x1; err_mask = sata_pmp_write(&ap->link, PMP_GSCR_SII_POL, reg); if (err_mask) { rc = -EIO; - reason = "failed to write Sil3726 Private Register"; + reason = "failed to write Sil3x26 Private Register"; goto fail; } } @@ -383,8 +383,8 @@ static void sata_pmp_quirks(struct ata_port *ap) u16 devid = sata_pmp_gscr_devid(gscr); struct ata_link *link; - if (vendor == 0x1095 && devid == 0x3726) { - /* sil3726 quirks */ + if (vendor == 0x1095 && (devid == 0x3726 || devid == 0x3826)) { + /* sil3x26 quirks */ ata_for_each_link(link, ap, EDGE) { /* link reports offline after LPM */ link->flags |= ATA_LFLAG_NO_LPM; -- cgit v1.1 From 374172589a9c99e63c373b1c74588553237a74d3 Mon Sep 17 00:00:00 2001 From: Martin Peschke Date: Thu, 22 Aug 2013 17:45:36 +0200 Subject: SCSI: zfcp: fix lock imbalance by reworking request queue locking commit d79ff142624e1be080ad8d09101f7004d79c36e1 upstream. This patch adds wait_event_interruptible_lock_irq_timeout(), which is a straight-forward descendant of wait_event_interruptible_timeout() and wait_event_interruptible_lock_irq(). The zfcp driver used to call wait_event_interruptible_timeout() in combination with some intricate and error-prone locking. Using wait_event_interruptible_lock_irq_timeout() as a replacement nicely cleans up that locking. This rework removes a situation that resulted in a locking imbalance in zfcp_qdio_sbal_get(): BUG: workqueue leaked lock or atomic: events/1/0xffffff00/10 last function: zfcp_fc_wka_port_offline+0x0/0xa0 [zfcp] It was introduced by commit c2af7545aaff3495d9bf9a7608c52f0af86fb194 "[SCSI] zfcp: Do not wait for SBALs on stopped queue", which had a new code path related to ZFCP_STATUS_ADAPTER_QDIOUP that took an early exit without a required lock being held. The problem occured when a special, non-SCSI I/O request was being submitted in process context, when the adapter's queues had been torn down. In this case the bug surfaced when the Fibre Channel port connection for a well-known address was closed during a concurrent adapter shut-down procedure, which is a rare constellation. This patch also fixes these warnings from the sparse tool (make C=1): drivers/s390/scsi/zfcp_qdio.c:224:12: warning: context imbalance in 'zfcp_qdio_sbal_check' - wrong count at exit drivers/s390/scsi/zfcp_qdio.c:244:5: warning: context imbalance in 'zfcp_qdio_sbal_get' - unexpected unlock Last but not least, we get rid of that crappy lock-unlock-lock sequence at the beginning of the critical section. It is okay to call zfcp_erp_adapter_reopen() with req_q_lock held. Reported-by: Mikulas Patocka Reported-by: Heiko Carstens Signed-off-by: Martin Peschke Signed-off-by: Steffen Maier Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/s390/scsi/zfcp_qdio.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index d9c40ea..f3922a8 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -199,11 +199,9 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req, static int zfcp_qdio_sbal_check(struct zfcp_qdio *qdio) { - spin_lock_irq(&qdio->req_q_lock); if (atomic_read(&qdio->req_q_free) || !(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) return 1; - spin_unlock_irq(&qdio->req_q_lock); return 0; } @@ -221,9 +219,8 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio) { long ret; - spin_unlock_irq(&qdio->req_q_lock); - ret = wait_event_interruptible_timeout(qdio->req_q_wq, - zfcp_qdio_sbal_check(qdio), 5 * HZ); + ret = wait_event_interruptible_lock_irq_timeout(qdio->req_q_wq, + zfcp_qdio_sbal_check(qdio), qdio->req_q_lock, 5 * HZ); if (!(atomic_read(&qdio->adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) return -EIO; @@ -237,7 +234,6 @@ int zfcp_qdio_sbal_get(struct zfcp_qdio *qdio) zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdsbg_1"); } - spin_lock_irq(&qdio->req_q_lock); return -EIO; } -- cgit v1.1 From 43bbe371b28bdcb7367e846d53bf6632a2ab2287 Mon Sep 17 00:00:00 2001 From: Martin Peschke Date: Thu, 22 Aug 2013 17:45:37 +0200 Subject: SCSI: zfcp: fix schedule-inside-lock in scsi_device list loops commit 924dd584b198a58aa7cb3efefd8a03326550ce8f upstream. BUG: sleeping function called from invalid context at kernel/workqueue.c:2752 in_atomic(): 1, irqs_disabled(): 1, pid: 360, name: zfcperp0.0.1700 CPU: 1 Not tainted 3.9.3+ #69 Process zfcperp0.0.1700 (pid: 360, task: 0000000075b7e080, ksp: 000000007476bc30) Call Trace: ([<00000000001165de>] show_trace+0x106/0x154) [<00000000001166a0>] show_stack+0x74/0xf4 [<00000000006ff646>] dump_stack+0xc6/0xd4 [<000000000017f3a0>] __might_sleep+0x128/0x148 [<000000000015ece8>] flush_work+0x54/0x1f8 [<00000000001630de>] __cancel_work_timer+0xc6/0x128 [<00000000005067ac>] scsi_device_dev_release_usercontext+0x164/0x23c [<0000000000161816>] execute_in_process_context+0x96/0xa8 [<00000000004d33d8>] device_release+0x60/0xc0 [<000000000048af48>] kobject_release+0xa8/0x1c4 [<00000000004f4bf2>] __scsi_iterate_devices+0xfa/0x130 [<000003ff801b307a>] zfcp_erp_strategy+0x4da/0x1014 [zfcp] [<000003ff801b3caa>] zfcp_erp_thread+0xf6/0x2b0 [zfcp] [<000000000016b75a>] kthread+0xf2/0xfc [<000000000070c9de>] kernel_thread_starter+0x6/0xc [<000000000070c9d8>] kernel_thread_starter+0x0/0xc Apparently, the ref_count for some scsi_device drops down to zero, triggering device removal through execute_in_process_context(), while the lldd error recovery thread iterates through a scsi device list. Unfortunately, execute_in_process_context() decides to immediately execute that device removal function, instead of scheduling asynchronous execution, since it detects process context and thinks it is safe to do so. But almost all calls to shost_for_each_device() in our lldd are inside spin_lock_irq, even in thread context. Obviously, schedule() inside spin_lock_irq sections is a bad idea. Change the lldd to use the proper iterator function, __shost_for_each_device(), in combination with required locking. Occurences that need to be changed include all calls in zfcp_erp.c, since those might be executed in zfcp error recovery thread context with a lock held. Other occurences of shost_for_each_device() in zfcp_fsf.c do not need to be changed (no process context, no surrounding locking). The problem was introduced in Linux 2.6.37 by commit b62a8d9b45b971a67a0f8413338c230e3117dff5 "[SCSI] zfcp: Use SCSI device data zfcp_scsi_dev instead of zfcp_unit". Reported-by: Christian Borntraeger Signed-off-by: Martin Peschke Signed-off-by: Steffen Maier Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/s390/scsi/zfcp_erp.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index e1b4f80..5c87270 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -102,10 +102,13 @@ static void zfcp_erp_action_dismiss_port(struct zfcp_port *port) if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_INUSE) zfcp_erp_action_dismiss(&port->erp_action); - else - shost_for_each_device(sdev, port->adapter->scsi_host) + else { + spin_lock(port->adapter->scsi_host->host_lock); + __shost_for_each_device(sdev, port->adapter->scsi_host) if (sdev_to_zfcp(sdev)->port == port) zfcp_erp_action_dismiss_lun(sdev); + spin_unlock(port->adapter->scsi_host->host_lock); + } } static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) @@ -592,9 +595,11 @@ static void _zfcp_erp_lun_reopen_all(struct zfcp_port *port, int clear, { struct scsi_device *sdev; - shost_for_each_device(sdev, port->adapter->scsi_host) + spin_lock(port->adapter->scsi_host->host_lock); + __shost_for_each_device(sdev, port->adapter->scsi_host) if (sdev_to_zfcp(sdev)->port == port) _zfcp_erp_lun_reopen(sdev, clear, id, 0); + spin_unlock(port->adapter->scsi_host->host_lock); } static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) @@ -1435,8 +1440,10 @@ void zfcp_erp_set_adapter_status(struct zfcp_adapter *adapter, u32 mask) atomic_set_mask(common_mask, &port->status); read_unlock_irqrestore(&adapter->port_list_lock, flags); - shost_for_each_device(sdev, adapter->scsi_host) + spin_lock_irqsave(adapter->scsi_host->host_lock, flags); + __shost_for_each_device(sdev, adapter->scsi_host) atomic_set_mask(common_mask, &sdev_to_zfcp(sdev)->status); + spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags); } /** @@ -1470,11 +1477,13 @@ void zfcp_erp_clear_adapter_status(struct zfcp_adapter *adapter, u32 mask) } read_unlock_irqrestore(&adapter->port_list_lock, flags); - shost_for_each_device(sdev, adapter->scsi_host) { + spin_lock_irqsave(adapter->scsi_host->host_lock, flags); + __shost_for_each_device(sdev, adapter->scsi_host) { atomic_clear_mask(common_mask, &sdev_to_zfcp(sdev)->status); if (clear_counter) atomic_set(&sdev_to_zfcp(sdev)->erp_counter, 0); } + spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags); } /** @@ -1488,16 +1497,19 @@ void zfcp_erp_set_port_status(struct zfcp_port *port, u32 mask) { struct scsi_device *sdev; u32 common_mask = mask & ZFCP_COMMON_FLAGS; + unsigned long flags; atomic_set_mask(mask, &port->status); if (!common_mask) return; - shost_for_each_device(sdev, port->adapter->scsi_host) + spin_lock_irqsave(port->adapter->scsi_host->host_lock, flags); + __shost_for_each_device(sdev, port->adapter->scsi_host) if (sdev_to_zfcp(sdev)->port == port) atomic_set_mask(common_mask, &sdev_to_zfcp(sdev)->status); + spin_unlock_irqrestore(port->adapter->scsi_host->host_lock, flags); } /** @@ -1512,6 +1524,7 @@ void zfcp_erp_clear_port_status(struct zfcp_port *port, u32 mask) struct scsi_device *sdev; u32 common_mask = mask & ZFCP_COMMON_FLAGS; u32 clear_counter = mask & ZFCP_STATUS_COMMON_ERP_FAILED; + unsigned long flags; atomic_clear_mask(mask, &port->status); @@ -1521,13 +1534,15 @@ void zfcp_erp_clear_port_status(struct zfcp_port *port, u32 mask) if (clear_counter) atomic_set(&port->erp_counter, 0); - shost_for_each_device(sdev, port->adapter->scsi_host) + spin_lock_irqsave(port->adapter->scsi_host->host_lock, flags); + __shost_for_each_device(sdev, port->adapter->scsi_host) if (sdev_to_zfcp(sdev)->port == port) { atomic_clear_mask(common_mask, &sdev_to_zfcp(sdev)->status); if (clear_counter) atomic_set(&sdev_to_zfcp(sdev)->erp_counter, 0); } + spin_unlock_irqrestore(port->adapter->scsi_host->host_lock, flags); } /** -- cgit v1.1 From 8e4c396fd61d6f00f1def1be3eec40cacffd3862 Mon Sep 17 00:00:00 2001 From: Russ Anderson Date: Wed, 28 Aug 2013 16:35:18 -0700 Subject: drivers/base/memory.c: fix show_mem_removable() to handle missing sections commit 21ea9f5ace3a7317cc3ba1fbc749758021a83136 upstream. "cat /sys/devices/system/memory/memory*/removable" crashed the system. The problem is that show_mem_removable() is passing a bad pfn to is_mem_section_removable(), which causes if (!node_online(page_to_nid(page))) to blow up. Why is it passing in a bad pfn? The reason is that show_mem_removable() will loop sections_per_block times. sections_per_block is 16, but mem->section_count is 8, indicating holes in this memory block. Checking that the memory section is present before checking to see if the memory section is removable fixes the problem. harp5-sys:~ # cat /sys/devices/system/memory/memory*/removable 0 1 1 1 1 1 1 1 1 1 1 1 1 1 BUG: unable to handle kernel paging request at ffffea00c3200000 IP: [] is_pageblock_removable_nolock+0x1/0x90 PGD 83ffd4067 PUD 37bdfce067 PMD 0 Oops: 0000 [#1] SMP Modules linked in: autofs4 binfmt_misc rdma_ucm rdma_cm iw_cm ib_addr ib_srp scsi_transport_srp scsi_tgt ib_ipoib ib_cm ib_uverbs ib_umad iw_cxgb3 cxgb3 mdio mlx4_en mlx4_ib ib_sa mlx4_core ib_mthca ib_mad ib_core fuse nls_iso8859_1 nls_cp437 vfat fat joydev loop hid_generic usbhid hid hwperf(O) numatools(O) dm_mod iTCO_wdt ipv6 iTCO_vendor_support igb i2c_i801 ioatdma i2c_algo_bit ehci_pci pcspkr lpc_ich i2c_core ehci_hcd ptp sg mfd_core dca rtc_cmos pps_core mperf button xhci_hcd sd_mod crc_t10dif usbcore usb_common scsi_dh_emc scsi_dh_hp_sw scsi_dh_alua scsi_dh_rdac scsi_dh gru(O) xvma(O) xfs crc32c libcrc32c thermal sata_nv processor piix mptsas mptscsih scsi_transport_sas mptbase megaraid_sas fan thermal_sys hwmon ext3 jbd ata_piix ahci libahci libata scsi_mod CPU: 4 PID: 5991 Comm: cat Tainted: G O 3.11.0-rc5-rja-uv+ #10 Hardware name: SGI UV2000/ROMLEY, BIOS SGI UV 2000/3000 series BIOS 01/15/2013 task: ffff88081f034580 ti: ffff880820022000 task.ti: ffff880820022000 RIP: 0010:[] [] is_pageblock_removable_nolock+0x1/0x90 RSP: 0018:ffff880820023df8 EFLAGS: 00010287 RAX: 0000000000040000 RBX: ffffea00c3200000 RCX: 0000000000000004 RDX: ffffea00c30b0000 RSI: 00000000001c0000 RDI: ffffea00c3200000 RBP: ffff880820023e38 R08: 0000000000000000 R09: 0000000000000001 R10: 0000000000000000 R11: 0000000000000001 R12: ffffea00c33c0000 R13: 0000160000000000 R14: 6db6db6db6db6db7 R15: 0000000000000001 FS: 00007ffff7fb2700(0000) GS:ffff88083fc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffea00c3200000 CR3: 000000081b954000 CR4: 00000000000407e0 Call Trace: show_mem_removable+0x41/0x70 dev_attr_show+0x2a/0x60 sysfs_read_file+0xf7/0x1c0 vfs_read+0xc8/0x130 SyS_read+0x5d/0xa0 system_call_fastpath+0x16/0x1b Signed-off-by: Russ Anderson Cc: "Rafael J. Wysocki" Cc: Yinghai Lu Reviewed-by: Yasuaki Ishimatsu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/base/memory.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 5fb6aae..02653fc 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -172,6 +172,8 @@ static ssize_t show_mem_removable(struct sys_device *dev, container_of(dev, struct memory_block, sysdev); for (i = 0; i < sections_per_block; i++) { + if (!present_section_nr(mem->start_section_nr + i)) + continue; pfn = section_nr_to_pfn(mem->start_section_nr + i); ret &= is_mem_section_removable(pfn, PAGES_PER_SECTION); } -- cgit v1.1 From ed12ee72b75085866d3af2ded3a5177ef51c550a Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Fri, 16 Aug 2013 21:39:40 +0200 Subject: ath9k_htc: Restore skb headroom when returning skb to mac80211 commit d2e9fc141e2aa21f4b35ee27072d84e9aa6e2ba0 upstream. ath9k_htc adds padding between the 802.11 header and the payload during TX by moving the header. When handing the frame back to mac80211 for TX status handling the header is not moved back into its original position. This can result in a too small skb headroom when entering ath9k_htc again (due to a soft retransmission for example) causing an skb_under_panic oops. Fix this by moving the 802.11 header back into its original position before returning the frame to mac80211 as other drivers like rt2x00 or ath5k do. Reported-by: Marc Kleine-Budde Signed-off-by: Helmut Schaa Tested-by: Marc Kleine-Budde Signed-off-by: Marc Kleine-Budde Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 2d81c70..3f2c88f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -448,6 +448,7 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, struct ieee80211_conf *cur_conf = &priv->hw->conf; bool txok; int slot; + int hdrlen, padsize; slot = strip_drv_header(priv, skb); if (slot < 0) { @@ -504,6 +505,15 @@ send_mac80211: ath9k_htc_tx_clear_slot(priv, slot); + /* Remove padding before handing frame back to mac80211 */ + hdrlen = ieee80211_get_hdrlen_from_skb(skb); + + padsize = hdrlen & 3; + if (padsize && skb->len > hdrlen + padsize) { + memmove(skb->data + padsize, skb->data, hdrlen); + skb_pull(skb, padsize); + } + /* Send status to mac80211 */ ieee80211_tx_status(priv->hw, skb); } -- cgit v1.1 From 833c9b848d8fab75497a7bb9741d58faeb2810cf Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Mon, 26 Aug 2013 10:19:18 +0800 Subject: ACPI / EC: Add ASUSTEK L4R to quirk list in order to validate ECDT commit 524f42fab787a9510be826ce3d736b56d454ac6d upstream. The ECDT of ASUSTEK L4R doesn't provide correct command and data I/O ports. The DSDT provides the correct information instead. For this reason, add this machine to quirk list for ECDT validation and use the EC information from the DSDT. [rjw: Changelog] References: https://bugzilla.kernel.org/show_bug.cgi?id=60765 Reported-and-tested-by: Daniele Esposti Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/ec.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 9cb436a..af66776 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -968,6 +968,10 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { ec_skip_dsdt_scan, "HP Folio 13", { DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL}, + { + ec_validate_ecdt, "ASUS hardware", { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTek Computer Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "L4R"),}, NULL}, {}, }; -- cgit v1.1 From e9d581e05541c10c4eed1ea5718e084a80e10b8a Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Wed, 24 Jul 2013 16:15:08 -0700 Subject: target: Fix trailing ASCII space usage in INQUIRY vendor+model commit ee60bddba5a5f23e39598195d944aa0eb2d455e5 upstream. This patch fixes spc_emulate_inquiry_std() to add trailing ASCII spaces for INQUIRY vendor + model fields following SPC-4 text: "ASCII data fields described as being left-aligned shall have any unused bytes at the end of the field (i.e., highest offset) and the unused bytes shall be filled with ASCII space characters (20h)." This addresses a problem with Falconstor NSS multipathing. Reported-by: Tomas Molota Signed-off-by: Nicholas Bellinger Signed-off-by: Greg Kroah-Hartman --- drivers/target/target_core_cdb.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index 0558401..f8c49ab 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c @@ -117,11 +117,12 @@ target_emulate_inquiry_std(struct se_cmd *cmd) return 0; } - snprintf((unsigned char *)&buf[8], 8, "LIO-ORG"); - snprintf((unsigned char *)&buf[16], 16, "%s", - &DEV_T10_WWN(dev)->model[0]); - snprintf((unsigned char *)&buf[32], 4, "%s", - &DEV_T10_WWN(dev)->revision[0]); + memcpy(&buf[8], "LIO-ORG ", 8); + memset(&buf[16], 0x20, 16); + memcpy(&buf[16], dev->se_sub_dev->t10_wwn.model, + min_t(size_t, strlen(dev->se_sub_dev->t10_wwn.model), 16)); + memcpy(&buf[32], dev->se_sub_dev->t10_wwn.revision, + min_t(size_t, strlen(dev->se_sub_dev->t10_wwn.revision), 4)); buf[4] = 31; /* Set additional length to 31 */ return 0; } -- cgit v1.1 From 7d2754c66e451ac82fd5e93bdb715e59c4bfdb02 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 15 Aug 2013 15:52:57 +0300 Subject: tun: signedness bug in tun_get_user() [ Upstream commit 15718ea0d844e4816dbd95d57a8a0e3e264ba90e ] The recent fix d9bf5f1309 "tun: compare with 0 instead of total_len" is not totally correct. Because "len" and "sizeof()" are size_t type, that means they are never less than zero. Signed-off-by: Dan Carpenter Acked-by: Michael S. Tsirkin Acked-by: Neil Horman Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/tun.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 28c5c6a..476b2ed 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -614,8 +614,9 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, int offset = 0; if (!(tun->flags & TUN_NO_PI)) { - if ((len -= sizeof(pi)) > count) + if (len < sizeof(pi)) return -EINVAL; + len -= sizeof(pi); if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi))) return -EFAULT; @@ -623,8 +624,9 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, } if (tun->flags & TUN_VNET_HDR) { - if ((len -= tun->vnet_hdr_sz) > count) + if (len < tun->vnet_hdr_sz) return -EINVAL; + len -= tun->vnet_hdr_sz; if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) return -EFAULT; -- cgit v1.1 From 288e9d859cc10e121a33dd603bd7174c98bd7ac8 Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Fri, 3 Feb 2012 15:34:16 +0800 Subject: PARISC: include in drivers/parisc/iommu-helpers.h commit 650275dbfb2f4c12bc91420ad5a99f955eabec98 upstream. drivers/parisc/iommu-helpers.h:62: error: implicit declaration of function 'prefetchw' make[3]: *** [drivers/parisc/sba_iommu.o] Error 1 drivers/parisc/iommu-helpers.h needs to #include where prefetchw is declared. Signed-off-by: WANG Cong Signed-off-by: James Bottomley Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/parisc/iommu-helpers.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/parisc/iommu-helpers.h b/drivers/parisc/iommu-helpers.h index a9c46cc..8c33491 100644 --- a/drivers/parisc/iommu-helpers.h +++ b/drivers/parisc/iommu-helpers.h @@ -1,3 +1,5 @@ +#include + /** * iommu_fill_pdir - Insert coalesced scatter/gather chunks into the I/O Pdir. * @ioc: The I/O Controller. -- cgit v1.1 From dbc93fb6085c4182233621a981e7ec0a3539cbf9 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Wed, 18 Apr 2012 17:17:19 -0400 Subject: pci: frv architecture needs generic setup-bus infrastructure commit cd0a2bfb77a3edeecd652081e0b1a163d3b0696b upstream. Otherwise we get this link failure for frv's defconfig: LD .tmp_vmlinux1 drivers/built-in.o: In function `pci_assign_resource': (.text+0xbf0c): undefined reference to `pci_cardbus_resource_alignment' drivers/built-in.o: In function `pci_setup': pci.c:(.init.text+0x174): undefined reference to `pci_realloc_get_opt' pci.c:(.init.text+0x1a0): undefined reference to `pci_realloc_get_opt' make[1]: *** [.tmp_vmlinux1] Error 1 Cc: David Howells Acked-by: Bjorn Helgaas Signed-off-by: Paul Gortmaker Cc: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- drivers/pci/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 094308e..9eff33b 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_UNICORE32) += setup-bus.o setup-irq.o obj-$(CONFIG_PARISC) += setup-bus.o obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o obj-$(CONFIG_PPC) += setup-bus.o +obj-$(CONFIG_FRV) += setup-bus.o obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o obj-$(CONFIG_X86_VISWS) += setup-irq.o obj-$(CONFIG_MN10300) += setup-bus.o -- cgit v1.1 From 173798ef2abbec8faf2a4397a24bd357fecfe008 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 6 Sep 2013 11:49:51 -0400 Subject: SCSI: sd: Fix potential out-of-bounds access commit 984f1733fcee3fbc78d47e26c5096921c5d9946a upstream. This patch fixes an out-of-bounds error in sd_read_cache_type(), found by Google's AddressSanitizer tool. When the loop ends, we know that "offset" lies beyond the end of the data in the buffer, so no Caching mode page was found. In theory it may be present, but the buffer size is limited to 512 bytes. Signed-off-by: Alan Stern Reported-by: Dmitry Vyukov Signed-off-by: James Bottomley Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/sd.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 3d15a37..cc3943a 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2135,14 +2135,9 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) } } - if (modepage == 0x3F) { - sd_printk(KERN_ERR, sdkp, "No Caching mode page " - "present\n"); - goto defaults; - } else if ((buffer[offset] & 0x3f) != modepage) { - sd_printk(KERN_ERR, sdkp, "Got wrong page\n"); - goto defaults; - } + sd_printk(KERN_ERR, sdkp, "No Caching mode page found\n"); + goto defaults; + Page_found: if (modepage == 8) { sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0); -- cgit v1.1 From def5a30f1a9766eb269234971f45736d67326925 Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Wed, 31 Jul 2013 17:00:42 +0200 Subject: xen-gnt: prevent adding duplicate gnt callbacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 5f338d9001094a56cf87bd8a280b4e7ff953bb59 upstream. With the current implementation, the callback in the tail of the list can be added twice, because the check done in gnttab_request_free_callback is bogus, callback->next can be NULL if it is the last callback in the list. If we add the same callback twice we end up with an infinite loop, were callback == callback->next. Replace this check with a proper one that iterates over the list to see if the callback has already been added. Signed-off-by: Roger Pau Monné Cc: Konrad Rzeszutek Wilk Cc: David Vrabel Signed-off-by: Konrad Rzeszutek Wilk Acked-by: Matt Wilson Reviewed-by: David Vrabel Signed-off-by: Greg Kroah-Hartman --- drivers/xen/grant-table.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index fd725cd..949af52 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -355,9 +355,18 @@ void gnttab_request_free_callback(struct gnttab_free_callback *callback, void (*fn)(void *), void *arg, u16 count) { unsigned long flags; + struct gnttab_free_callback *cb; + spin_lock_irqsave(&gnttab_list_lock, flags); - if (callback->next) - goto out; + + /* Check if the callback is already on the list */ + cb = gnttab_free_callback_list; + while (cb) { + if (cb == callback) + goto out; + cb = cb->next; + } + callback->fn = fn; callback->arg = arg; callback->count = count; -- cgit v1.1 From 3fa24717e9b3e4d50f5dd912270613d5887f361c Mon Sep 17 00:00:00 2001 From: Shawn Nematbakhsh Date: Mon, 19 Aug 2013 10:36:13 -0700 Subject: usb: xhci: Disable runtime PM suspend for quirky controllers commit c8476fb855434c733099079063990e5bfa7ecad6 upstream. If a USB controller with XHCI_RESET_ON_RESUME goes to runtime suspend, a reset will be performed upon runtime resume. Any previously suspended devices attached to the controller will be re-enumerated at this time. This will cause problems, for example, if an open system call on the device triggered the resume (the open call will fail). Note that this change is only relevant when persist_enabled is not set for USB devices. This patch should be backported to kernels as old as 3.0, that contain the commit c877b3b2ad5cb9d4fe523c5496185cc328ff3ae9 "xhci: Add reset on resume quirk for asrock p67 host". Signed-off-by: Shawn Nematbakhsh Signed-off-by: Sarah Sharp Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 7f07eb8..c95252d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -2713,10 +2713,21 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_virt_device *virt_dev; + struct device *dev = hcd->self.controller; unsigned long flags; u32 state; int i, ret; +#ifndef CONFIG_USB_DEFAULT_PERSIST + /* + * We called pm_runtime_get_noresume when the device was attached. + * Decrement the counter here to allow controller to runtime suspend + * if no devices remain. + */ + if (xhci->quirks & XHCI_RESET_ON_RESUME) + pm_runtime_put_noidle(dev); +#endif + ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__); /* If the host is halted due to driver unload, we still need to free the * device. @@ -2783,6 +2794,7 @@ static int xhci_reserve_host_control_ep_resources(struct xhci_hcd *xhci) int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct device *dev = hcd->self.controller; unsigned long flags; int timeleft; int ret; @@ -2835,6 +2847,16 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) goto disable_slot; } udev->slot_id = xhci->slot_id; + +#ifndef CONFIG_USB_DEFAULT_PERSIST + /* + * If resetting upon resume, we can't put the controller into runtime + * suspend if there is a device attached. + */ + if (xhci->quirks & XHCI_RESET_ON_RESUME) + pm_runtime_get_noresume(dev); +#endif + /* Is this a LS or FS device under a HS hub? */ /* Hub or peripherial? */ return 1; -- cgit v1.1 From 71d5f63763f01e5577c465d6752b7060ba105fa6 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 20 Aug 2013 11:57:35 +0300 Subject: staging: comedi: dt282x: dt282x_ai_insn_read() always fails commit 2c4283ca7cdcc6605859c836fc536fcd83a4525f upstream. In dt282x_ai_insn_read() we call this macro like: wait_for(!mux_busy(), comedi_error(dev, "timeout\n"); return -ETIME;); Because the if statement doesn't have curly braces it means we always return -ETIME and the function never succeeds. Signed-off-by: Dan Carpenter Acked-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt282x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c index 8cea9dc..00a285c 100644 --- a/drivers/staging/comedi/drivers/dt282x.c +++ b/drivers/staging/comedi/drivers/dt282x.c @@ -406,8 +406,9 @@ struct dt282x_private { } \ udelay(5); \ } \ - if (_i) \ + if (_i) { \ b \ + } \ } while (0) static int dt282x_attach(struct comedi_device *dev, -- cgit v1.1 From d723c89020d4f5f54b42997ae5e90f13bc620d8b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 16 Aug 2013 10:16:59 +0300 Subject: USB: mos7720: use GFP_ATOMIC under spinlock commit d0bd9a41186e076ea543c397ad8a67a6cf604b55 upstream. The write_parport_reg_nonblock() function shouldn't sleep because it's called with spinlocks held. Signed-off-by: Dan Carpenter Acked-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7720.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 267dff9..90f7ad5 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -383,7 +383,7 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, kfree(urbtrack); return -ENOMEM; } - urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_KERNEL); + urbtrack->setup = kmalloc(sizeof(*urbtrack->setup), GFP_ATOMIC); if (!urbtrack->setup) { usb_free_urb(urbtrack->urb); kfree(urbtrack); -- cgit v1.1 From 5f8ce0764bb3d54090856cca1c8562c0435003ca Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 19 Aug 2013 13:05:45 +0200 Subject: USB: mos7720: fix big-endian control requests commit 3b716caf190ccc6f2a09387210e0e6a26c1d81a4 upstream. Fix endianess bugs in parallel-port code which caused corrupt control-requests to be issued on big-endian machines. Reported-by: kbuild test robot Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7720.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 90f7ad5..7ee78bd 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -391,8 +391,8 @@ static int write_parport_reg_nonblock(struct mos7715_parport *mos_parport, } urbtrack->setup->bRequestType = (__u8)0x40; urbtrack->setup->bRequest = (__u8)0x0e; - urbtrack->setup->wValue = get_reg_value(reg, dummy); - urbtrack->setup->wIndex = get_reg_index(reg); + urbtrack->setup->wValue = cpu_to_le16(get_reg_value(reg, dummy)); + urbtrack->setup->wIndex = cpu_to_le16(get_reg_index(reg)); urbtrack->setup->wLength = 0; usb_fill_control_urb(urbtrack->urb, usbdev, usb_sndctrlpipe(usbdev, 0), -- cgit v1.1 From fe3efa501f32fc05483a095334573799a954d1ab Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 6 Aug 2013 14:22:59 +0200 Subject: USB: cdc-wdm: fix race between interrupt handler and tasklet commit 6dd433e6cf2475ce8abec1b467720858c24450eb upstream. Both could want to submit the same URB. Some checks of the flag intended to prevent that were missing. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index c84b455..0b85e2c 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -171,6 +171,7 @@ skip_error: static void wdm_int_callback(struct urb *urb) { int rv = 0; + int responding; int status = urb->status; struct wdm_device *desc; struct usb_ctrlrequest *req; @@ -244,8 +245,8 @@ static void wdm_int_callback(struct urb *urb) desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; spin_lock(&desc->iuspin); clear_bit(WDM_READ, &desc->flags); - set_bit(WDM_RESPONDING, &desc->flags); - if (!test_bit(WDM_DISCONNECTING, &desc->flags) + responding = test_and_set_bit(WDM_RESPONDING, &desc->flags); + if (!responding && !test_bit(WDM_DISCONNECTING, &desc->flags) && !test_bit(WDM_SUSPENDING, &desc->flags)) { rv = usb_submit_urb(desc->response, GFP_ATOMIC); dev_dbg(&desc->intf->dev, "%s: usb_submit_urb %d", @@ -635,16 +636,20 @@ static void wdm_rxwork(struct work_struct *work) { struct wdm_device *desc = container_of(work, struct wdm_device, rxwork); unsigned long flags; - int rv; + int rv = 0; + int responding; spin_lock_irqsave(&desc->iuspin, flags); if (test_bit(WDM_DISCONNECTING, &desc->flags)) { spin_unlock_irqrestore(&desc->iuspin, flags); } else { + responding = test_and_set_bit(WDM_RESPONDING, &desc->flags); spin_unlock_irqrestore(&desc->iuspin, flags); - rv = usb_submit_urb(desc->response, GFP_KERNEL); + if (!responding) + rv = usb_submit_urb(desc->response, GFP_KERNEL); if (rv < 0 && rv != -EPERM) { spin_lock_irqsave(&desc->iuspin, flags); + clear_bit(WDM_RESPONDING, &desc->flags); if (!test_bit(WDM_DISCONNECTING, &desc->flags)) schedule_work(&desc->rxwork); spin_unlock_irqrestore(&desc->iuspin, flags); -- cgit v1.1 From ff819a0c7f12179d197aa06841087964dd2be7d3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 3 Aug 2013 16:37:48 +0200 Subject: usb: config->desc.bLength may not exceed amount of data returned by the device commit b4f17a488ae2e09bfcf95c0e0b4219c246f1116a upstream. While reading the config parsing code I noticed this check is missing, without this check config->desc.wTotalLength can end up with a value larger then the dev->rawdescriptors length for the config, and when userspace then tries to get the rawdescriptors bad things may happen. Signed-off-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/config.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 26678ca..c29f521 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -424,7 +424,8 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE); if (config->desc.bDescriptorType != USB_DT_CONFIG || - config->desc.bLength < USB_DT_CONFIG_SIZE) { + config->desc.bLength < USB_DT_CONFIG_SIZE || + config->desc.bLength > size) { dev_err(ddev, "invalid descriptor for config index %d: " "type = 0x%X, length = %d\n", cfgidx, config->desc.bDescriptorType, config->desc.bLength); -- cgit v1.1 From be84480edb2b552c2fb9ca940c6bb07464306108 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 6 Aug 2013 14:18:10 +0200 Subject: ath9k: always clear ps filter bit on new assoc commit 026d5b07c03458f9c0ccd19c3850564a5409c325 upstream. Otherwise in some cases, EAPOL frames might be filtered during the initial handshake, causing delays and assoc failures. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/xmit.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 6f6f100..e1f1971 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -2433,6 +2433,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) for (acno = 0, ac = &an->ac[acno]; acno < WME_NUM_AC; acno++, ac++) { ac->sched = false; + ac->clear_ps_filter = true; ac->txq = sc->tx.txq_map[acno]; INIT_LIST_HEAD(&ac->tid_q); } -- cgit v1.1 From 8600be1d3927e177b80c7ee9263ef3b28a0ba115 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 13 Aug 2013 12:33:28 +0200 Subject: ath9k: avoid accessing MRC registers on single-chain devices commit a1c781bb20ac1e03280e420abd47a99eb8bbdd3b upstream. They are not implemented, and accessing them might trigger errors Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/ath/ath9k/ar9003_phy.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 892c48b..b8a26d2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -1005,6 +1005,10 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, * is_on == 0 means MRC CCK is OFF (more noise imm) */ bool is_on = param ? 1 : 0; + + if (ah->caps.rx_chainmask == 1) + break; + REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, AR_PHY_MRC_CCK_ENABLE, is_on); REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, -- cgit v1.1 From c993386d8c99c60ffb1161076040f3ffb46c0794 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 28 Aug 2013 22:30:49 +0200 Subject: HID: pantherlord: validate output report details commit 412f30105ec6735224535791eed5cdc02888ecb4 upstream. A HID device could send a malicious output report that would cause the pantherlord HID driver to write beyond the output report allocation during initialization, causing a heap overflow: [ 310.939483] usb 1-1: New USB device found, idVendor=0e8f, idProduct=0003 ... [ 315.980774] BUG kmalloc-192 (Tainted: G W ): Redzone overwritten CVE-2013-2892 Signed-off-by: Kees Cook Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-pl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c index 06e5300..fa74232 100644 --- a/drivers/hid/hid-pl.c +++ b/drivers/hid/hid-pl.c @@ -128,8 +128,14 @@ static int plff_init(struct hid_device *hid) strong = &report->field[0]->value[2]; weak = &report->field[0]->value[3]; debug("detected single-field device"); - } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 && - report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) { + } else if (report->field[0]->maxusage == 1 && + report->field[0]->usage[0].hid == + (HID_UP_LED | 0x43) && + report->maxfield >= 4 && + report->field[0]->report_count >= 1 && + report->field[1]->report_count >= 1 && + report->field[2]->report_count >= 1 && + report->field[3]->report_count >= 1) { report->field[0]->value[0] = 0x00; report->field[1]->value[0] = 0x00; strong = &report->field[2]->value[0]; -- cgit v1.1 From 645c9dcabb2c234e6d4a546125830d04988a1f90 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 28 Aug 2013 22:29:55 +0200 Subject: HID: validate HID report id size commit 43622021d2e2b82ea03d883926605bdd0525e1d1 upstream. The "Report ID" field of a HID report is used to build indexes of reports. The kernel's index of these is limited to 256 entries, so any malicious device that sets a Report ID greater than 255 will trigger memory corruption on the host: [ 1347.156239] BUG: unable to handle kernel paging request at ffff88094958a878 [ 1347.156261] IP: [] hid_register_report+0x2a/0x8b CVE-2013-2888 Signed-off-by: Kees Cook Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-core.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 53576e7..bc0bb21 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -58,6 +58,8 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type, struct hid_report_enum *report_enum = device->report_enum + type; struct hid_report *report; + if (id >= HID_MAX_IDS) + return NULL; if (report_enum->report_id_hash[id]) return report_enum->report_id_hash[id]; @@ -379,9 +381,11 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) case HID_GLOBAL_ITEM_TAG_REPORT_ID: parser->global.report_id = item_udata(item); - if (parser->global.report_id == 0) { - dbg_hid("report_id 0 is invalid\n"); - return -1; + if (parser->global.report_id == 0 || + parser->global.report_id >= HID_MAX_IDS) { + hid_err(parser->device, "report_id %u is invalid\n", + parser->global.report_id); + return -1; } return 0; @@ -551,7 +555,7 @@ static void hid_device_release(struct device *dev) for (i = 0; i < HID_REPORT_TYPES; i++) { struct hid_report_enum *report_enum = device->report_enum + i; - for (j = 0; j < 256; j++) { + for (j = 0; j < HID_MAX_IDS; j++) { struct hid_report *report = report_enum->report_id_hash[j]; if (report) hid_free_report(report); -- cgit v1.1 From 0d564bb5984ae5b94233bc0bdb0e38073fc1b038 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 28 Aug 2013 22:31:28 +0200 Subject: HID: ntrig: validate feature report details commit 875b4e3763dbc941f15143dd1a18d10bb0be303b upstream. A HID device could send a malicious feature report that would cause the ntrig HID driver to trigger a NULL dereference during initialization: [57383.031190] usb 3-1: New USB device found, idVendor=1b96, idProduct=0001 ... [57383.315193] BUG: unable to handle kernel NULL pointer dereference at 0000000000000030 [57383.315308] IP: [] ntrig_probe+0x25e/0x420 [hid_ntrig] CVE-2013-2896 Signed-off-by: Kees Cook Signed-off-by: Rafi Rubin Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-ntrig.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 9fae2eb..48cba85 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -115,7 +115,8 @@ static inline int ntrig_get_mode(struct hid_device *hdev) struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT]. report_id_hash[0x0d]; - if (!report) + if (!report || report->maxfield < 1 || + report->field[0]->report_count < 1) return -EINVAL; usbhid_submit_report(hdev, report, USB_DIR_IN); -- cgit v1.1 From fc4a8fd8746dcd6ff011bc61c06fe9cf5ed2015a Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 28 Aug 2013 22:32:01 +0200 Subject: HID: check for NULL field when setting values commit be67b68d52fa28b9b721c47bb42068f0c1214855 upstream. Defensively check that the field to be worked on is not NULL. Signed-off-by: Kees Cook Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index bc0bb21..a9c2b68 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -993,7 +993,12 @@ EXPORT_SYMBOL_GPL(hid_output_report); int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) { - unsigned size = field->report_size; + unsigned size; + + if (!field) + return -1; + + size = field->report_size; hid_dump_input(field->report->device, field->usage + offset, value); -- cgit v1.1 From 43423691a01dcee991ba1cf4111bb82b2aa0e677 Mon Sep 17 00:00:00 2001 From: Fabio Porcedda Date: Mon, 16 Sep 2013 11:47:50 +0200 Subject: net: usb: cdc_ether: Use wwan interface for Telit modules commit 0092820407901a0b2c4e343e85f96bb7abfcded1 upstream. Signed-off-by: Fabio Porcedda Acked-by: Oliver Neukum Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/cdc_ether.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 544c309..e48a677 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -615,6 +615,11 @@ static const struct usb_device_id products [] = { .bInterfaceProtocol = USB_CDC_PROTO_NONE, .driver_info = (unsigned long)&wwan_info, }, { + /* Telit modules */ + USB_VENDOR_AND_INTERFACE_INFO(0x1bc7, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = (kernel_ulong_t) &wwan_info, +}, { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), .driver_info = (unsigned long) &cdc_info, -- cgit v1.1 From d46f78f18ccd208c5325357bfe108f5e02044b6b Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 26 Aug 2013 15:18:53 +0200 Subject: rt2800: fix wrong TX power compensation commit 6e956da2027c767859128b9bfef085cf2a8e233b upstream. We should not do temperature compensation on devices without EXTERNAL_TX_ALC bit set (called DynamicTxAgcControl on vendor driver). Such devices can have totally bogus TSSI parameters on the EEPROM, but still threaded by us as valid and result doing wrong TX power calculations. This fix inability to connect to AP on slightly longer distance on some Ralink chips/devices. Reported-and-tested-by: Fabien ADAM Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/rt2x00/rt2800lib.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 9457987..62b92c4 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1861,6 +1861,13 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) int i; /* + * First check if temperature compensation is supported. + */ + rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); + if (!rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_TX_ALC)) + return 0; + + /* * Read TSSI boundaries for temperature compensation from * the EEPROM. * -- cgit v1.1 From 7247e66f07168b28410549634ea5d29a84602f81 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 11 Sep 2013 21:56:50 +0200 Subject: HID: provide a helper for validating hid reports commit 331415ff16a12147d57d5c953f3a961b7ede348b upstream. Many drivers need to validate the characteristics of their HID report during initialization to avoid misusing the reports. This adds a common helper to perform validation of the report exisitng, the field existing, and the expected number of values within the field. Signed-off-by: Kees Cook Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-core.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index a9c2b68..8fa2cd7 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -815,6 +815,64 @@ static int search(__s32 *array, __s32 value, unsigned n) return -1; } +static const char * const hid_report_names[] = { + "HID_INPUT_REPORT", + "HID_OUTPUT_REPORT", + "HID_FEATURE_REPORT", +}; +/** + * hid_validate_values - validate existing device report's value indexes + * + * @device: hid device + * @type: which report type to examine + * @id: which report ID to examine (0 for first) + * @field_index: which report field to examine + * @report_counts: expected number of values + * + * Validate the number of values in a given field of a given report, after + * parsing. + */ +struct hid_report *hid_validate_values(struct hid_device *hid, + unsigned int type, unsigned int id, + unsigned int field_index, + unsigned int report_counts) +{ + struct hid_report *report; + + if (type > HID_FEATURE_REPORT) { + hid_err(hid, "invalid HID report type %u\n", type); + return NULL; + } + + if (id >= HID_MAX_IDS) { + hid_err(hid, "invalid HID report id %u\n", id); + return NULL; + } + + /* + * Explicitly not using hid_get_report() here since it depends on + * ->numbered being checked, which may not always be the case when + * drivers go to access report values. + */ + report = hid->report_enum[type].report_id_hash[id]; + if (!report) { + hid_err(hid, "missing %s %u\n", hid_report_names[type], id); + return NULL; + } + if (report->maxfield <= field_index) { + hid_err(hid, "not enough fields in %s %u\n", + hid_report_names[type], id); + return NULL; + } + if (report->field[field_index]->report_count < report_counts) { + hid_err(hid, "not enough values in %s %u field %u\n", + hid_report_names[type], id, field_index); + return NULL; + } + return report; +} +EXPORT_SYMBOL_GPL(hid_validate_values); + /** * hid_match_report - check if driver's raw_event should be called * -- cgit v1.1 From 69e5a58ed3cdfa6a4a708f6f00ec0ee79e2fe6cd Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 11 Sep 2013 21:56:51 +0200 Subject: HID: zeroplus: validate output report details commit 78214e81a1bf43740ce89bb5efda78eac2f8ef83 upstream. The zeroplus HID driver was not checking the size of allocated values in fields it used. A HID device could send a malicious output report that would cause the driver to write beyond the output report allocation during initialization, causing a heap overflow: [ 1442.728680] usb 1-1: New USB device found, idVendor=0c12, idProduct=0005 ... [ 1466.243173] BUG kmalloc-192 (Tainted: G W ): Redzone overwritten CVE-2013-2889 Signed-off-by: Kees Cook Reviewed-by: Benjamin Tissoires Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-zpff.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c index f31fab0..5c8f628 100644 --- a/drivers/hid/hid-zpff.c +++ b/drivers/hid/hid-zpff.c @@ -69,21 +69,13 @@ static int zpff_init(struct hid_device *hid) struct hid_report *report; struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); - struct list_head *report_list = - &hid->report_enum[HID_OUTPUT_REPORT].report_list; struct input_dev *dev = hidinput->input; - int error; + int i, error; - if (list_empty(report_list)) { - hid_err(hid, "no output report found\n"); - return -ENODEV; - } - - report = list_entry(report_list->next, struct hid_report, list); - - if (report->maxfield < 4) { - hid_err(hid, "not enough fields in report\n"); - return -ENODEV; + for (i = 0; i < 4; i++) { + report = hid_validate_values(hid, HID_OUTPUT_REPORT, 0, i, 1); + if (!report) + return -ENODEV; } zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL); -- cgit v1.1 From 3df0155c467f982d4c06078b74d042d7a5c2a743 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 20 Aug 2013 14:59:01 -0400 Subject: drm/radeon: fix LCD record parsing commit 95663948ba22a4be8b99acd67fbf83e86ddffba4 upstream. If the LCD table contains an EDID record, properly account for the edid size when walking through the records. This should fix error messages about unknown LCD records. Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/radeon_atombios.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index b1aade0..4b2a7f0 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1658,7 +1658,9 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct kfree(edid); } } - record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD); + record += fake_edid_record->ucFakeEDIDLength ? + fake_edid_record->ucFakeEDIDLength + 2 : + sizeof(ATOM_FAKE_EDID_PATCH_RECORD); break; case LCD_PANEL_RESOLUTION_RECORD_TYPE: panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; -- cgit v1.1 From ea0f1f563576a598112cd64308ddb461379d85a9 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 19 Aug 2013 11:06:50 -0400 Subject: drm/radeon: update line buffer allocation for dce4.1/5 commit 0b31e02363b0db4e7931561bc6c141436e729d9f upstream. We need to allocate line buffer to each display when setting up the watermarks. Failure to do so can lead to a blank screen. This fixes blank screen problems on dce4.1/5 asics. Based on an initial fix from: Jay Cornwall Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/evergreen.c | 25 +++++++++++++++++++++---- drivers/gpu/drm/radeon/evergreend.h | 4 ++++ 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index d3264b9..eecd3dc 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -419,7 +419,8 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, struct drm_display_mode *mode, struct drm_display_mode *other_mode) { - u32 tmp; + u32 tmp, buffer_alloc, i; + u32 pipe_offset = radeon_crtc->crtc_id * 0x20; /* * Line Buffer Setup * There are 3 line buffers, each one shared by 2 display controllers. @@ -442,18 +443,34 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, * non-linked crtcs for maximum line buffer allocation. */ if (radeon_crtc->base.enabled && mode) { - if (other_mode) + if (other_mode) { tmp = 0; /* 1/2 */ - else + buffer_alloc = 1; + } else { tmp = 2; /* whole */ - } else + buffer_alloc = 2; + } + } else { tmp = 0; + buffer_alloc = 0; + } /* second controller of the pair uses second half of the lb */ if (radeon_crtc->crtc_id % 2) tmp += 4; WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp); + if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { + WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset, + DMIF_BUFFERS_ALLOCATED(buffer_alloc)); + for (i = 0; i < rdev->usec_timeout; i++) { + if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) & + DMIF_BUFFERS_ALLOCATED_COMPLETED) + break; + udelay(1); + } + } + if (radeon_crtc->base.enabled && mode) { switch (tmp) { case 0: diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 6078ae4..ab670c3 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -450,6 +450,10 @@ # define LATENCY_LOW_WATERMARK(x) ((x) << 0) # define LATENCY_HIGH_WATERMARK(x) ((x) << 16) +#define PIPE0_DMIF_BUFFER_CONTROL 0x0ca0 +# define DMIF_BUFFERS_ALLOCATED(x) ((x) << 0) +# define DMIF_BUFFERS_ALLOCATED_COMPLETED (1 << 4) + #define IH_RB_CNTL 0x3e00 # define IH_RB_ENABLE (1 << 0) # define IH_IB_SIZE(x) ((x) << 1) /* log2 */ -- cgit v1.1 From d8dcb2c6f47bab3dfd8059e58a3641b37ca70c30 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 26 Aug 2013 17:52:12 -0400 Subject: drm/radeon: fix resume on some rs4xx boards (v2) commit acf88deb8ddbb73acd1c3fa32fde51af9153227f upstream. Setting MC_MISC_CNTL.GART_INDEX_REG_EN causes hangs on some boards on resume. The systems seem to work fine without touching this bit so leave it as is. v2: read-modify-write the GART_INDEX_REG_EN bit. I suspect the problem is that we are losing the other settings in the register. fixes: https://bugs.freedesktop.org/show_bug.cgi?id=52952 Reported-by: Ondrej Zary Tested-by: Daniel Tobias Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/rs400.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index aa6a66e..317eac1 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -174,10 +174,13 @@ int rs400_gart_enable(struct radeon_device *rdev) /* FIXME: according to doc we should set HIDE_MMCFG_BAR=0, * AGPMODE30=0 & AGP30ENHANCED=0 in NB_CNTL */ if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740)) { - WREG32_MC(RS480_MC_MISC_CNTL, - (RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN)); + tmp = RREG32_MC(RS480_MC_MISC_CNTL); + tmp |= RS480_GART_INDEX_REG_EN | RS690_BLOCK_GFX_D3_EN; + WREG32_MC(RS480_MC_MISC_CNTL, tmp); } else { - WREG32_MC(RS480_MC_MISC_CNTL, RS480_GART_INDEX_REG_EN); + tmp = RREG32_MC(RS480_MC_MISC_CNTL); + tmp |= RS480_GART_INDEX_REG_EN; + WREG32_MC(RS480_MC_MISC_CNTL, tmp); } /* Enable gart */ WREG32_MC(RS480_AGP_ADDRESS_SPACE_SIZE, (RS480_GART_EN | size_reg)); -- cgit v1.1 From 2864d3c11eced6708234b92186149f70748a85c4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 27 Aug 2013 12:36:01 -0400 Subject: drm/radeon: fix handling of variable sized arrays for router objects commit fb93df1c2d8b3b1fb16d6ee9e32554e0c038815d upstream. The table has the following format: typedef struct _ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT //usSrcDstTableOffset pointing to this structure { UCHAR ucNumberOfSrc; USHORT usSrcObjectID[1]; UCHAR ucNumberOfDst; USHORT usDstObjectID[1]; }ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT; usSrcObjectID[] and usDstObjectID[] are variably sized, so we can't access them directly. Use pointers and update the offset appropriately when accessing the Dst members. Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/radeon_atombios.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 4b2a7f0..f9d49e3 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -751,13 +751,16 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) (ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT *) (ctx->bios + data_offset + le16_to_cpu(router_obj->asObjects[k].usSrcDstTableOffset)); + u8 *num_dst_objs = (u8 *) + ((u8 *)router_src_dst_table + 1 + + (router_src_dst_table->ucNumberOfSrc * 2)); + u16 *dst_objs = (u16 *)(num_dst_objs + 1); int enum_id; router.router_id = router_obj_id; - for (enum_id = 0; enum_id < router_src_dst_table->ucNumberOfDst; - enum_id++) { + for (enum_id = 0; enum_id < (*num_dst_objs); enum_id++) { if (le16_to_cpu(path->usConnObjectId) == - le16_to_cpu(router_src_dst_table->usDstObjectID[enum_id])) + le16_to_cpu(dst_objs[enum_id])) break; } -- cgit v1.1 From 3a454fd0a92af12ab465b88a25a7089e65eb8420 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Wed, 25 Jan 2012 22:16:16 -0500 Subject: SCSI: iscsi: don't hang in endless loop if no targets present commit 46a7c17d26967922092f3a8291815ffb20f6cabe upstream. iscsi_if_send_reply() may return -ESRCH if there were no targets to send data to. Currently we're ignoring this value and looping in attempt to do it over and over, which will usually lead in a hung task like this one: [ 4920.817298] INFO: task trinity:9074 blocked for more than 120 seconds. [ 4920.818527] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. [ 4920.819982] trinity D 0000000000000000 5504 9074 2756 0x00000004 [ 4920.825374] ffff880003961a98 0000000000000086 ffff8800001aa000 ffff8800001aa000 [ 4920.826791] 00000000001d4340 ffff880003961fd8 ffff880003960000 00000000001d4340 [ 4920.828241] 00000000001d4340 00000000001d4340 ffff880003961fd8 00000000001d4340 [ 4920.833231] [ 4920.833519] Call Trace: [ 4920.834010] [] schedule+0x3a/0x50 [ 4920.834953] [] __mutex_lock_common+0x209/0x5b0 [ 4920.836226] [] ? iscsi_if_rx+0x2d/0x990 [ 4920.837281] [] ? sched_clock+0x13/0x20 [ 4920.838305] [] ? iscsi_if_rx+0x2d/0x990 [ 4920.839336] [] mutex_lock_nested+0x40/0x50 [ 4920.840423] [] iscsi_if_rx+0x2d/0x990 [ 4920.841434] [] ? sub_preempt_count+0x9d/0xd0 [ 4920.842548] [] ? _raw_read_unlock+0x30/0x60 [ 4920.843666] [] netlink_unicast+0x1ae/0x1f0 [ 4920.844751] [] netlink_sendmsg+0x227/0x350 [ 4920.845850] [] ? sock_update_netprioidx+0xdd/0x1b0 [ 4920.847060] [] ? sock_update_netprioidx+0x52/0x1b0 [ 4920.848276] [] sock_aio_write+0x166/0x180 [ 4920.849348] [] ? get_parent_ip+0x11/0x50 [ 4920.850428] [] do_sync_write+0xda/0x120 [ 4920.851465] [] ? sub_preempt_count+0x9d/0xd0 [ 4920.852579] [] ? get_parent_ip+0x11/0x50 [ 4920.853608] [] ? security_file_permission+0x27/0xb0 [ 4920.854821] [] vfs_write+0x16c/0x180 [ 4920.855781] [] sys_write+0x4f/0xa0 [ 4920.856798] [] system_call_fastpath+0x16/0x1b [ 4920.877487] 1 lock held by trinity/9074: [ 4920.878239] #0: (rx_queue_mutex){+.+...}, at: [] iscsi_if_rx+0x2d/0x990 [ 4920.880005] Kernel panic - not syncing: hung_task: blocked tasks Signed-off-by: Sasha Levin Acked-by: Mike Christie Signed-off-by: James Bottomley Cc: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/scsi_transport_iscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 3fd16d7..acc53e2 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -1747,7 +1747,7 @@ iscsi_if_rx(struct sk_buff *skb) break; err = iscsi_if_send_reply(group, nlh->nlmsg_seq, nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); - } while (err < 0 && err != -ECONNREFUSED); + } while (err < 0 && err != -ECONNREFUSED && err != -ESRCH); skb_pull(skb, rlen); } mutex_unlock(&rx_queue_mutex); -- cgit v1.1 From f77b78d931314d3e066266c23b44f90807ee5774 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 6 Sep 2013 22:39:20 +0100 Subject: sfc: Fix efx_rx_buf_offset() for recycled pages This bug fix is only for stable branches older than 3.10. The bug was fixed upstream by commit 2768935a4660 ('sfc: reuse pages to avoid DMA mapping/unmapping costs'), but that change is totally unsuitable for stable. Commit b590ace09d51 ('sfc: Fix efx_rx_buf_offset() in the presence of swiotlb') added an explicit page_offset member to struct efx_rx_buffer, which must be set consistently with the u.page and dma_addr fields. However, it failed to add the necessary assignment in efx_resurrect_rx_buffer(). It also did not correct the calculation of efx_rx_buffer::dma_addr in efx_resurrect_rx_buffer(), which assumes that DMA-mapping a page will result in a page-aligned DMA address (exactly what swiotlb violates). Add the assignment of efx_rx_buffer::page_offset and change the calculation of dma_addr to make use of it. Signed-off-by: Ben Hutchings Cc: David Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/sfc/rx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index d429f0a..26e4cca 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -311,8 +311,9 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, index = rx_queue->added_count & rx_queue->ptr_mask; new_buf = efx_rx_buffer(rx_queue, index); - new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1); new_buf->u.page = rx_buf->u.page; + new_buf->page_offset = rx_buf->page_offset ^ (PAGE_SIZE >> 1); + new_buf->dma_addr = state->dma_addr + new_buf->page_offset; new_buf->len = rx_buf->len; new_buf->is_page = true; ++rx_queue->added_count; -- cgit v1.1 From 79e1fc8a531ebe5da1078d765fadf6662edad612 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 22 Sep 2013 19:48:54 +0100 Subject: staging: vt6656: [BUG] main_usb.c oops on device_close move flag earlier. commit e3eb270fab7734427dd8171a93e4946fe28674bc upstream. The vt6656 is prone to resetting on the usb bus. It seems there is a race condition and wpa supplicant is trying to open the device via iw_handlers before its actually closed at a stage that the buffers are being removed. The device is longer considered open when the buffers are being removed. So move ~DEVICE_FLAGS_OPENED flag to before freeing the device buffers. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/main_usb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index 5fb56a6..0b8f93b 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -1228,6 +1228,8 @@ device_release_WPADEV(pDevice); memset(pMgmt->abyCurrBSSID, 0, 6); pMgmt->eCurrState = WMAC_STATE_IDLE; + pDevice->flags &= ~DEVICE_FLAGS_OPENED; + device_free_tx_bufs(pDevice); device_free_rx_bufs(pDevice); device_free_int_bufs(pDevice); @@ -1239,7 +1241,6 @@ device_release_WPADEV(pDevice); usb_free_urb(pDevice->pInterruptURB); BSSvClearNodeDBTable(pDevice, 0); - pDevice->flags &=(~DEVICE_FLAGS_OPENED); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close2 \n"); -- cgit v1.1 From a86384dbc0bf86e10301eb8eaafb9d49c90e3183 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Thu, 5 Sep 2013 11:01:20 +0300 Subject: xhci: Fix oops happening after address device timeout commit 284d20552461466b04d6bfeafeb1c47a8891b591 upstream. When a command times out, the command ring is first aborted, and then stopped. If the command ring is empty when it is stopped the stop event will point to next command which is not yet set. xHCI tries to handle this next event often causing an oops. Don't handle command completion events on stopped cmd ring if ring is empty. This patch should be backported to kernels as old as 3.7, that contain the commit b92cc66c047ff7cf587b318fe377061a353c120f "xHCI: add aborting command ring function" Signed-off-by: Mathias Nyman Reported-by: Giovanni Signed-off-by: Sarah Sharp Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index f40567e..244a5e24 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1377,6 +1377,12 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, inc_deq(xhci, xhci->cmd_ring, false); return; } + /* There is no command to handle if we get a stop event when the + * command ring is empty, event->cmd_trb points to the next + * unset command + */ + if (xhci->cmd_ring->dequeue == xhci->cmd_ring->enqueue) + return; } switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]) -- cgit v1.1 From 314bb48ec028ae62cec4a1371cdd84b672d5a759 Mon Sep 17 00:00:00 2001 From: Florian Wolter Date: Wed, 14 Aug 2013 10:33:16 +0200 Subject: xhci: Fix race between ep halt and URB cancellation commit 526867c3ca0caa2e3e846cb993b0f961c33c2abb upstream. The halted state of a endpoint cannot be cleared over CLEAR_HALT from a user process, because the stopped_td variable was overwritten in the handle_stopped_endpoint() function. So the xhci_endpoint_reset() function will refuse the reset and communication with device can not run over this endpoint. https://bugzilla.kernel.org/show_bug.cgi?id=60699 Signed-off-by: Florian Wolter Signed-off-by: Sarah Sharp Cc: Jonghwan Choi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 244a5e24..40e39df 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -882,8 +882,12 @@ remove_finished_td: /* Otherwise ring the doorbell(s) to restart queued transfers */ ring_doorbell_for_active_rings(xhci, slot_id, ep_index); } - ep->stopped_td = NULL; - ep->stopped_trb = NULL; + + /* Clear stopped_td and stopped_trb if endpoint is not halted */ + if (!(ep->ep_state & EP_HALTED)) { + ep->stopped_td = NULL; + ep->stopped_trb = NULL; + } /* * Drop the lock and complete the URBs in the cancelled TD list. -- cgit v1.1 From 0c61d8a1d51e6f701ee17af5fa33bdeefaa02b75 Mon Sep 17 00:00:00 2001 From: Kurt Garloff Date: Tue, 24 Sep 2013 14:13:48 +0200 Subject: usb/core/devio.c: Don't reject control message to endpoint with wrong direction bit commit 831abf76643555a99b80a3b54adfa7e4fa0a3259 upstream. Trying to read data from the Pegasus Technologies NoteTaker (0e20:0101) [1] with the Windows App (EasyNote) works natively but fails when Windows is running under KVM (and the USB device handed to KVM). The reason is a USB control message usb 4-2.2: control urb: bRequestType=22 bRequest=09 wValue=0200 wIndex=0001 wLength=0008 This goes to endpoint address 0x01 (wIndex); however, endpoint address 0x01 does not exist. There is an endpoint 0x81 though (same number, but other direction); the app may have meant that endpoint instead. The kernel thus rejects the IO and thus we see the failure. Apparently, Linux is more strict here than Windows ... we can't change the Win app easily, so that's a problem. It seems that the Win app/driver is buggy here and the driver does not behave fully according to the USB HID class spec that it claims to belong to. The device seems to happily deal with that though (and seems to not really care about this value much). So the question is whether the Linux kernel should filter here. Rejecting has the risk that somewhat non-compliant userspace apps/ drivers (most likely in a virtual machine) are prevented from working. Not rejecting has the risk of confusing an overly sensitive device with such a transfer. Given the fact that Windows does not filter it makes this risk rather small though. The patch makes the kernel more tolerant: If the endpoint address in wIndex does not exist, but an endpoint with toggled direction bit does, it will let the transfer through. (It does NOT change the message.) With attached patch, the app in Windows in KVM works. usb 4-2.2: check_ctrlrecip: process 13073 (qemu-kvm) requesting ep 01 but needs 81 I suspect this will mostly affect apps in virtual environments; as on Linux the apps would have been adapted to the stricter handling of the kernel. I have done that for mine[2]. [1] http://www.pegatech.com/ [2] https://sourceforge.net/projects/notetakerpen/ Signed-off-by: Kurt Garloff Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 2bb9410..b08fcd2 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -645,6 +645,22 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, if ((index & ~USB_DIR_IN) == 0) return 0; ret = findintfep(ps->dev, index); + if (ret < 0) { + /* + * Some not fully compliant Win apps seem to get + * index wrong and have the endpoint number here + * rather than the endpoint address (with the + * correct direction). Win does let this through, + * so we'll not reject it here but leave it to + * the device to not break KVM. But we warn. + */ + ret = findintfep(ps->dev, index ^ 0x80); + if (ret >= 0) + dev_info(&ps->dev->dev, + "%s: process %i (%s) requesting ep %02x but needs %02x\n", + __func__, task_pid_nr(current), + current->comm, index, index ^ 0x80); + } if (ret >= 0) ret = checkintf(ps, ret); break; -- cgit v1.1 From 434b9ee66a512e9b91b9e1687b8183cd48a353fb Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 18 Sep 2013 19:14:22 -0400 Subject: dm snapshot: workaround for a false positive lockdep warning commit 5ea330a75bd86b2b2a01d7b85c516983238306fb upstream. The kernel reports a lockdep warning if a snapshot is invalidated because it runs out of space. The lockdep warning was triggered by commit 0976dfc1d0cd80a4e9dfaf87bd87 ("workqueue: Catch more locking problems with flush_work()") in v3.5. The warning is false positive. The real cause for the warning is that the lockdep engine treats different instances of md->lock as a single lock. This patch is a workaround - we use flush_workqueue instead of flush_work. This code path is not performance sensitive (it is called only on initialization or invalidation), thus it doesn't matter that we flush the whole workqueue. The real fix for the problem would be to teach the lockdep engine to treat different instances of md->lock as separate locks. Signed-off-by: Mikulas Patocka Acked-by: Alasdair G Kergon Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-snap-persistent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index e4ecadf..2847a0b 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c @@ -251,7 +251,7 @@ static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw, */ INIT_WORK_ONSTACK(&req.work, do_metadata); queue_work(ps->metadata_wq, &req.work); - flush_work(&req.work); + flush_workqueue(ps->metadata_wq); return req.result; } -- cgit v1.1 From 1f6014d357c7884e176c9d78c321ded23bdbd985 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 18 Sep 2013 19:40:42 -0400 Subject: dm-snapshot: fix performance degradation due to small hash size commit 60e356f381954d79088d0455e357db48cfdd6857 upstream. LVM2, since version 2.02.96, creates origin with zero size, then loads the snapshot driver and then loads the origin. Consequently, the snapshot driver sees the origin size zero and sets the hash size to the lower bound 64. Such small hash table causes performance degradation. This patch changes it so that the hash size is determined by the size of snapshot volume, not minimum of origin and snapshot size. It doesn't make sense to set the snapshot size significantly larger than the origin size, so we do not need to take origin size into account when calculating the hash size. Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-snap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index f3e632a..95e6db1 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -724,17 +724,16 @@ static int calc_max_buckets(void) */ static int init_hash_tables(struct dm_snapshot *s) { - sector_t hash_size, cow_dev_size, origin_dev_size, max_buckets; + sector_t hash_size, cow_dev_size, max_buckets; /* * Calculate based on the size of the original volume or * the COW volume... */ cow_dev_size = get_dev_size(s->cow->bdev); - origin_dev_size = get_dev_size(s->origin->bdev); max_buckets = calc_max_buckets(); - hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift; + hash_size = cow_dev_size >> s->store->chunk_shift; hash_size = min(hash_size, max_buckets); if (hash_size < 64) -- cgit v1.1 From d0d0e6c36f6d9fdf0df50c4d1877156b7bcff565 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 20 Sep 2013 16:42:15 +0300 Subject: drm/i915/dp: increase i2c-over-aux retry interval on AUX DEFER commit 8d16f258217f2f583af1fd57c5144aa4bbe73e48 upstream. There is no clear cut rules or specs for the retry interval, as there are many factors that affect overall response time. Increase the interval, and even more so on branch devices which may have limited i2c bit rates. Signed-off-by: Jani Nikula Reference: https://bugs.freedesktop.org/show_bug.cgi?id=60263 Tested-by: Nicolas Suzor Reviewed-by: Todd Previte Signed-off-by: Daniel Vetter Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/i915/intel_dp.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index bf9fea9..57b3728 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -531,7 +531,18 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, DRM_DEBUG_KMS("aux_ch native nack\n"); return -EREMOTEIO; case AUX_NATIVE_REPLY_DEFER: - udelay(100); + /* + * For now, just give more slack to branch devices. We + * could check the DPCD for I2C bit rate capabilities, + * and if available, adjust the interval. We could also + * be more careful with DP-to-Legacy adapters where a + * long legacy cable may force very low I2C bit rates. + */ + if (intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & + DP_DWN_STRM_PORT_PRESENT) + usleep_range(500, 600); + else + usleep_range(300, 400); continue; default: DRM_ERROR("aux_ch invalid native reply 0x%02x\n", -- cgit v1.1 From 94c7268325e30ecb4767b9c080e8cec9c92d6689 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 26 Sep 2013 08:33:16 +0200 Subject: hwmon: (applesmc) Check key count before proceeding commit 5f4513864304672e6ea9eac60583eeac32e679f2 upstream. After reports from Chris and Josh Boyer of a rare crash in applesmc, Guenter pointed at the initialization problem fixed below. The patch has not been verified to fix the crash, but should be applied regardless. Reported-by: Suggested-by: Guenter Roeck Signed-off-by: Henrik Rydberg Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/applesmc.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index d99aa84..6218d08 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -485,16 +485,25 @@ static int applesmc_init_smcreg_try(void) { struct applesmc_registers *s = &smcreg; bool left_light_sensor, right_light_sensor; + unsigned int count; u8 tmp[1]; int ret; if (s->init_complete) return 0; - ret = read_register_count(&s->key_count); + ret = read_register_count(&count); if (ret) return ret; + if (s->cache && s->key_count != count) { + pr_warn("key count changed from %d to %d\n", + s->key_count, count); + kfree(s->cache); + s->cache = NULL; + } + s->key_count = count; + if (!s->cache) s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL); if (!s->cache) -- cgit v1.1 From 96ec909de79e2cc422126fdeb427fe8d0ffb4b95 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 26 Jan 2012 06:08:41 -0500 Subject: hwmon: (applesmc) Silence uninitialized warnings commit 0fc86eca1b338d06ec500b34ef7def79c32b602b upstream. Some error paths do not set a result, leading to the (false) assumption that the value may be used uninitialized. Set results for those paths as well. Signed-off-by: Henrik Rydberg Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/applesmc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 6218d08..30cac58 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -344,8 +344,10 @@ static int applesmc_get_lower_bound(unsigned int *lo, const char *key) while (begin != end) { int middle = begin + (end - begin) / 2; entry = applesmc_get_entry_by_index(middle); - if (IS_ERR(entry)) + if (IS_ERR(entry)) { + *lo = 0; return PTR_ERR(entry); + } if (strcmp(entry->key, key) < 0) begin = middle + 1; else @@ -364,8 +366,10 @@ static int applesmc_get_upper_bound(unsigned int *hi, const char *key) while (begin != end) { int middle = begin + (end - begin) / 2; entry = applesmc_get_entry_by_index(middle); - if (IS_ERR(entry)) + if (IS_ERR(entry)) { + *hi = smcreg.key_count; return PTR_ERR(entry); + } if (strcmp(key, entry->key) < 0) end = middle; else -- cgit v1.1 From 00dd675556f5c6a17bcba5f7e47c2552daeed84c Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Sat, 15 Jun 2013 10:27:19 -0600 Subject: intel-iommu: Fix leaks in pagetable freeing commit 3269ee0bd6686baf86630300d528500ac5b516d7 upstream. At best the current code only seems to free the leaf pagetables and the root. If you're unlucky enough to have a large gap (like any QEMU guest with more than 3G of memory), only the first chunk of leaf pagetables are freed (plus the root). This is a massive memory leak. This patch re-writes the pagetable freeing function to use a recursive algorithm and manages to not only free all the pagetables, but does it without any apparent performance loss versus the current broken version. Signed-off-by: Alex Williamson Cc: stable@vger.kernel.org Reviewed-by: Marcelo Tosatti Signed-off-by: Joerg Roedel Signed-off-by: Borislav Petkov Signed-off-by: Greg Kroah-Hartman --- drivers/pci/intel-iommu.c | 72 +++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index ae762ec..68baf17 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -853,56 +853,54 @@ static int dma_pte_clear_range(struct dmar_domain *domain, return order; } +static void dma_pte_free_level(struct dmar_domain *domain, int level, + struct dma_pte *pte, unsigned long pfn, + unsigned long start_pfn, unsigned long last_pfn) +{ + pfn = max(start_pfn, pfn); + pte = &pte[pfn_level_offset(pfn, level)]; + + do { + unsigned long level_pfn; + struct dma_pte *level_pte; + + if (!dma_pte_present(pte) || dma_pte_superpage(pte)) + goto next; + + level_pfn = pfn & level_mask(level - 1); + level_pte = phys_to_virt(dma_pte_addr(pte)); + + if (level > 2) + dma_pte_free_level(domain, level - 1, level_pte, + level_pfn, start_pfn, last_pfn); + + /* If range covers entire pagetable, free it */ + if (!(start_pfn > level_pfn || + last_pfn < level_pfn + level_size(level))) { + dma_clear_pte(pte); + domain_flush_cache(domain, pte, sizeof(*pte)); + free_pgtable_page(level_pte); + } +next: + pfn += level_size(level); + } while (!first_pte_in_page(++pte) && pfn <= last_pfn); +} + /* free page table pages. last level pte should already be cleared */ static void dma_pte_free_pagetable(struct dmar_domain *domain, unsigned long start_pfn, unsigned long last_pfn) { int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT; - struct dma_pte *first_pte, *pte; - int total = agaw_to_level(domain->agaw); - int level; - unsigned long tmp; - int large_page = 2; BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width); BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); BUG_ON(start_pfn > last_pfn); /* We don't need lock here; nobody else touches the iova range */ - level = 2; - while (level <= total) { - tmp = align_to_level(start_pfn, level); - - /* If we can't even clear one PTE at this level, we're done */ - if (tmp + level_size(level) - 1 > last_pfn) - return; - - do { - large_page = level; - first_pte = pte = dma_pfn_level_pte(domain, tmp, level, &large_page); - if (large_page > level) - level = large_page + 1; - if (!pte) { - tmp = align_to_level(tmp + 1, level + 1); - continue; - } - do { - if (dma_pte_present(pte)) { - free_pgtable_page(phys_to_virt(dma_pte_addr(pte))); - dma_clear_pte(pte); - } - pte++; - tmp += level_size(level); - } while (!first_pte_in_page(pte) && - tmp + level_size(level) - 1 <= last_pfn); + dma_pte_free_level(domain, agaw_to_level(domain->agaw), + domain->pgd, 0, start_pfn, last_pfn); - domain_flush_cache(domain, first_pte, - (void *)pte - (void *)first_pte); - - } while (tmp && tmp + level_size(level) - 1 <= last_pfn); - level++; - } /* free pgd */ if (start_pfn == 0 && last_pfn == DOMAIN_MAX_PFN(domain->gaw)) { free_pgtable_page(domain->pgd); -- cgit v1.1 From dcad3ae646c253f445658d695f3e1f3ba0f2ac69 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 24 Sep 2013 15:27:44 -0700 Subject: cpqarray: fix info leak in ida_locked_ioctl() commit 627aad1c01da6f881e7f98d71fd928ca0c316b1a upstream. The pciinfo struct has a two byte hole after ->dev_fn so stack information could be leaked to the user. This was assigned CVE-2013-2147. Signed-off-by: Dan Carpenter Acked-by: Mike Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/block/cpqarray.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index b2fceb5..e1ac6d2 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -1195,6 +1195,7 @@ out_passthru: ida_pci_info_struct pciinfo; if (!arg) return -EINVAL; + memset(&pciinfo, 0, sizeof(pciinfo)); pciinfo.bus = host->pci_dev->bus->number; pciinfo.dev_fn = host->pci_dev->devfn; pciinfo.board_id = host->board_id; -- cgit v1.1 From 67ea0764ff204966d8f45b35dd26e939e2377b5a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 24 Sep 2013 15:27:45 -0700 Subject: cciss: fix info leak in cciss_ioctl32_passthru() commit 58f09e00ae095e46ef9edfcf3a5fd9ccdfad065e upstream. The arg64 struct has a hole after ->buf_size which isn't cleared. Or if any of the calls to copy_from_user() fail then that would cause an information leak as well. This was assigned CVE-2013-2147. Signed-off-by: Dan Carpenter Acked-by: Mike Miller Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- drivers/block/cciss.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 1dab802..9ee7fe7 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1179,6 +1179,7 @@ static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, int err; u32 cp; + memset(&arg64, 0, sizeof(arg64)); err = 0; err |= copy_from_user(&arg64.LUN_info, &arg32->LUN_info, -- cgit v1.1 From 2a6a2791b1e6ebd7ad29f137a309471f92d71c55 Mon Sep 17 00:00:00 2001 From: Ansis Atteka Date: Wed, 18 Sep 2013 15:29:53 -0700 Subject: ip: generate unique IP identificator if local fragmentation is allowed [ Upstream commit 703133de331a7a7df47f31fb9de51dc6f68a9de8 ] If local fragmentation is allowed, then ip_select_ident() and ip_select_ident_more() need to generate unique IDs to ensure correct defragmentation on the peer. For example, if IPsec (tunnel mode) has to encrypt large skbs that have local_df bit set, then all IP fragments that belonged to different ESP datagrams would have used the same identificator. If one of these IP fragments would get lost or reordered, then peer could possibly stitch together wrong IP fragments that did not belong to the same datagram. This would lead to a packet loss or data corruption. Signed-off-by: Ansis Atteka Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/pptp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c index 4b3a68b..e6a8ebf 100644 --- a/drivers/net/pptp.c +++ b/drivers/net/pptp.c @@ -282,7 +282,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) nf_reset(skb); skb->ip_summed = CHECKSUM_NONE; - ip_select_ident(iph, &rt->dst, NULL); + ip_select_ident(skb, &rt->dst, NULL); ip_send_check(iph); ip_local_out(skb); -- cgit v1.1 From 6838208d0662ff90eab0df3e36c481644083e888 Mon Sep 17 00:00:00 2001 From: Roger Luethi Date: Sat, 21 Sep 2013 14:24:11 +0200 Subject: via-rhine: fix VLAN priority field (PCP, IEEE 802.1p) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ Upstream commit 207070f5221e2a901d56a49df9cde47d9b716cd7 ] Outgoing packets sent by via-rhine have their VLAN PCP field off by one (when hardware acceleration is enabled). The TX descriptor expects only VID and PCP (without a CFI/DEI bit). Peter Boström noticed and reported the bug. Signed-off-by: Roger Luethi Cc: Peter Boström Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/via-rhine.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 7f23ab9..e64e440 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -32,7 +32,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define DRV_NAME "via-rhine" -#define DRV_VERSION "1.5.0" +#define DRV_VERSION "1.5.1" #define DRV_RELDATE "2010-10-09" @@ -1518,7 +1518,12 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb, cpu_to_le32(TXDESC | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN)); if (unlikely(vlan_tx_tag_present(skb))) { - rp->tx_ring[entry].tx_status = cpu_to_le32((vlan_tx_tag_get(skb)) << 16); + u16 vid_pcp = vlan_tx_tag_get(skb); + + /* drop CFI/DEI bit, register needs VID and PCP */ + vid_pcp = (vid_pcp & VLAN_VID_MASK) | + ((vid_pcp & VLAN_PRIO_MASK) >> 1); + rp->tx_ring[entry].tx_status = cpu_to_le32((vid_pcp) << 16); /* request tagging */ rp->tx_ring[entry].desc_length |= cpu_to_le32(0x020000); } -- cgit v1.1 From edd423cc3e80c43ca95c8a8ad292dc1f29d8a936 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Mon, 30 Sep 2013 23:28:20 +0200 Subject: dm9601: fix IFF_ALLMULTI handling [ Upstream commit bf0ea6380724beb64f27a722dfc4b0edabff816e ] Pass-all-multicast is controlled by bit 3 in RX control, not bit 2 (pass undersized frames). Reported-by: Joseph Chang Signed-off-by: Peter Korsgaard Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/usb/dm9601.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index 1d93133..64a0ad1 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c @@ -384,7 +384,7 @@ static void dm9601_set_multicast(struct net_device *net) rx_ctl |= 0x02; } else if (net->flags & IFF_ALLMULTI || netdev_mc_count(net) > DM_MAX_MCAST) { - rx_ctl |= 0x04; + rx_ctl |= 0x08; } else if (!netdev_mc_empty(net)) { struct netdev_hw_addr *ha; -- cgit v1.1 From dbe48e5b8c4f5f3096102d98cc53441178e67aa2 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Fri, 27 Sep 2013 12:22:15 -0400 Subject: bonding: Fix broken promiscuity reference counting issue [ Upstream commit 5a0068deb611109c5ba77358be533f763f395ee4 ] Recently grabbed this report: https://bugzilla.redhat.com/show_bug.cgi?id=1005567 Of an issue in which the bonding driver, with an attached vlan encountered the following errors when bond0 was taken down and back up: dummy1: promiscuity touches roof, set promiscuity failed. promiscuity feature of device might be broken. The error occurs because, during __bond_release_one, if we release our last slave, we take on a random mac address and issue a NETDEV_CHANGEADDR notification. With an attached vlan, the vlan may see that the vlan and bond mac address were in sync, but no longer are. This triggers a call to dev_uc_add and dev_set_rx_mode, which enables IFF_PROMISC on the bond device. Then, when we complete __bond_release_one, we use the current state of the bond flags to determine if we should decrement the promiscuity of the releasing slave. But since the bond changed promiscuity state during the release operation, we incorrectly decrement the slave promisc count when it wasn't in promiscuous mode to begin with, causing the above error Fix is pretty simple, just cache the bonding flags at the start of the function and use those when determining the need to set promiscuity. This is also needed for the ALLMULTI flag Reported-by: Mark Wu CC: Jay Vosburgh CC: Andy Gospodarek CC: Mark Wu CC: "David S. Miller" Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/bonding/bond_main.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index f271e44..f1b566f 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1994,6 +1994,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) struct bonding *bond = netdev_priv(bond_dev); struct slave *slave, *oldcurrent; struct sockaddr addr; + int old_flags = bond_dev->flags; u32 old_features = bond_dev->features; /* slave is not a slave or master is not master of this slave */ @@ -2124,12 +2125,18 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) * already taken care of above when we detached the slave */ if (!USES_PRIMARY(bond->params.mode)) { - /* unset promiscuity level from slave */ - if (bond_dev->flags & IFF_PROMISC) + /* unset promiscuity level from slave + * NOTE: The NETDEV_CHANGEADDR call above may change the value + * of the IFF_PROMISC flag in the bond_dev, but we need the + * value of that flag before that change, as that was the value + * when this slave was attached, so we cache at the start of the + * function and use it here. Same goes for ALLMULTI below + */ + if (old_flags & IFF_PROMISC) dev_set_promiscuity(slave_dev, -1); /* unset allmulti level from slave */ - if (bond_dev->flags & IFF_ALLMULTI) + if (old_flags & IFF_ALLMULTI) dev_set_allmulti(slave_dev, -1); /* flush master's mc_list from slave */ -- cgit v1.1 From 67a8bceeb8f58b365104b0b35285205bff488727 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Tue, 1 Oct 2013 08:17:10 +0200 Subject: ll_temac: Reset dma descriptors indexes on ndo_open [ Upstream commit 7167cf0e8cd10287b7912b9ffcccd9616f382922 ] The dma descriptors indexes are only initialized on the probe function. If a packet is on the buffer when temac_stop is called, the dma descriptors indexes can be left on a incorrect state where no other package can be sent. So an interface could be left in an usable state after ifdow/ifup. This patch makes sure that the descriptors indexes are in a proper status when the device is open. Signed-off-by: Ricardo Ribalda Delgado Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/ll_temac_main.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index b7948cc..7ebb4c1 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -302,6 +302,12 @@ static int temac_dma_bd_init(struct net_device *ndev) lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); + /* Init descriptor indexes */ + lp->tx_bd_ci = 0; + lp->tx_bd_next = 0; + lp->tx_bd_tail = 0; + lp->rx_bd_ci = 0; + return 0; out: -- cgit v1.1 From ffc8f511cbea2ff61941c26a243c70136994094d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 1 Aug 2013 18:08:34 -0700 Subject: esp_scsi: Fix tag state corruption when autosensing. [ Upstream commit 21af8107f27878813d0364733c0b08813c2c192a ] Meelis Roos reports a crash in esp_free_lun_tag() in the presense of a disk which has died. The issue is that when we issue an autosense command, we do so by hijacking the original command that caused the check-condition. When we do so we clear out the ent->tag[] array when we issue it via find_and_prep_issuable_command(). This is so that the autosense command is forced to be issued non-tagged. That is problematic, because it is the value of ent->tag[] which determines whether we issued the original scsi command as tagged vs. non-tagged (see esp_alloc_lun_tag()). And that, in turn, is what trips up the sanity checks in esp_free_lun_tag(). That function needs the original ->tag[] values in order to free up the tag slot properly. Fix this by remembering the original command's tag values, and having esp_alloc_lun_tag() and esp_free_lun_tag() use them. Reported-by: Meelis Roos Tested-by: Meelis Roos Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/scsi/esp_scsi.c | 14 ++++++++------ drivers/scsi/esp_scsi.h | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index 394ed9e..4aa30d8 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -530,7 +530,7 @@ static int esp_need_to_nego_sync(struct esp_target_data *tp) static int esp_alloc_lun_tag(struct esp_cmd_entry *ent, struct esp_lun_data *lp) { - if (!ent->tag[0]) { + if (!ent->orig_tag[0]) { /* Non-tagged, slot already taken? */ if (lp->non_tagged_cmd) return -EBUSY; @@ -564,9 +564,9 @@ static int esp_alloc_lun_tag(struct esp_cmd_entry *ent, return -EBUSY; } - BUG_ON(lp->tagged_cmds[ent->tag[1]]); + BUG_ON(lp->tagged_cmds[ent->orig_tag[1]]); - lp->tagged_cmds[ent->tag[1]] = ent; + lp->tagged_cmds[ent->orig_tag[1]] = ent; lp->num_tagged++; return 0; @@ -575,9 +575,9 @@ static int esp_alloc_lun_tag(struct esp_cmd_entry *ent, static void esp_free_lun_tag(struct esp_cmd_entry *ent, struct esp_lun_data *lp) { - if (ent->tag[0]) { - BUG_ON(lp->tagged_cmds[ent->tag[1]] != ent); - lp->tagged_cmds[ent->tag[1]] = NULL; + if (ent->orig_tag[0]) { + BUG_ON(lp->tagged_cmds[ent->orig_tag[1]] != ent); + lp->tagged_cmds[ent->orig_tag[1]] = NULL; lp->num_tagged--; } else { BUG_ON(lp->non_tagged_cmd != ent); @@ -667,6 +667,8 @@ static struct esp_cmd_entry *find_and_prep_issuable_command(struct esp *esp) ent->tag[0] = 0; ent->tag[1] = 0; } + ent->orig_tag[0] = ent->tag[0]; + ent->orig_tag[1] = ent->tag[1]; if (esp_alloc_lun_tag(ent, lp) < 0) continue; diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h index 28e22ac..cd68805 100644 --- a/drivers/scsi/esp_scsi.h +++ b/drivers/scsi/esp_scsi.h @@ -271,6 +271,7 @@ struct esp_cmd_entry { #define ESP_CMD_FLAG_AUTOSENSE 0x04 /* Doing automatic REQUEST_SENSE */ u8 tag[2]; + u8 orig_tag[2]; u8 status; u8 message; -- cgit v1.1 From 6a89ff9ebd1f81f6449b4c3c7a5e8861a0a6edf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Mal=C3=BD?= Date: Sat, 28 Sep 2013 19:50:27 +0200 Subject: USB: serial: option: Ignore card reader interface on Huawei E1750 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit eb2addd4044b4b2ce77693bde5bc810536dd96ee upstream. Hi, my Huawei 3G modem has an embedded Smart Card reader which causes trouble when the modem is being detected (a bunch of " (ttyUSBx): open blocked by driver for more than 7 seconds!" in messages.log). This trivial patch corrects the problem for me. The modem identifies itself as "12d1:1406 Huawei Technologies Co., Ltd. E1750" in lsusb although the description on the body says "Model E173u-1" Signed-off-by: Michal Malý Cc: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index c2103f4..536c4ad 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -81,6 +81,7 @@ static void option_instat_callback(struct urb *urb); #define HUAWEI_VENDOR_ID 0x12D1 #define HUAWEI_PRODUCT_E173 0x140C +#define HUAWEI_PRODUCT_E1750 0x1406 #define HUAWEI_PRODUCT_K4505 0x1464 #define HUAWEI_PRODUCT_K3765 0x1465 #define HUAWEI_PRODUCT_K4605 0x14C6 @@ -581,6 +582,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t) &net_intf2_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), -- cgit v1.1 From d3f0cca5d5a167a7e154a7e4065f7e858539df4c Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 18 Sep 2013 21:21:35 -0500 Subject: rtlwifi: Align private space in rtl_priv struct commit 60ce314d1750fef843e9db70050e09e49f838b69 upstream. The private array at the end of the rtl_priv struct is not aligned. On ARM architecture, this causes an alignment trap and is fixed by aligning that array with __align(sizeof(void *)). That should properly align that space according to the requirements of all architectures. Reported-by: Jason Andrews Tested-by: Jason Andrews Signed-off-by: Larry Finger Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/rtlwifi/wifi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 693395e..2e3daea 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1587,7 +1587,7 @@ struct rtl_priv { that it points to the data allocated beyond this structure like: rtl_pci_priv or rtl_usb_priv */ - u8 priv[0]; + u8 priv[0] __aligned(sizeof(void *)); }; #define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv)) -- cgit v1.1 From 8e0e2535ad3cdcd6e17d11ac52b5fb6487679e6c Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 24 Sep 2013 21:56:46 +0200 Subject: p54usb: add USB ID for Corega WLUSB2GTST USB adapter commit 1e43692cdb7cc445d6347d8a5207d9cef0c71434 upstream. Added USB ID for Corega WLUSB2GTST USB adapter. Reported-by: Joerg Kalisch Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/net/wireless/p54/p54usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 99e7e7f..0de0837 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -82,6 +82,7 @@ static struct usb_device_id p54u_table[] = { {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */ {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ + {USB_DEVICE(0x07aa, 0x0020)}, /* Corega WLUSB2GTST USB */ {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */ {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ {USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */ -- cgit v1.1 From c724d4f0439a7af388de3929d80a933137168db5 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 10 Oct 2013 10:53:46 +0100 Subject: staging: comedi: ni_65xx: (bug fix) confine insn_bits to one subdevice commit 677a31565692d596ef42ea589b53ba289abf4713 upstream. The `insn_bits` handler `ni_65xx_dio_insn_bits()` has a `for` loop that currently writes (optionally) and reads back up to 5 "ports" consisting of 8 channels each. It reads up to 32 1-bit channels but can only read and write a whole port at once - it needs to handle up to 5 ports as the first channel it reads might not be aligned on a port boundary. It breaks out of the loop early if the next port it handles is beyond the final port on the card. It also breaks out early on the 5th port in the loop if the first channel was aligned. Unfortunately, it doesn't check that the current port it is dealing with belongs to the comedi subdevice the `insn_bits` handler is acting on. That's a bug. Redo the `for` loop to terminate after the final port belonging to the subdevice, changing the loop variable in the process to simplify things a bit. The `for` loop could now try and handle more than 5 ports if the subdevice has more than 40 channels, but the test `if (bitshift >= 32)` ensures it will break out early after 4 or 5 ports (depending on whether the first channel is aligned on a port boundary). (`bitshift` will be between -7 and 7 inclusive on the first iteration, increasing by 8 for each subsequent operation.) Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_65xx.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 403fc09..8b564ad 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -411,29 +411,25 @@ static int ni_65xx_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - unsigned base_bitfield_channel; - const unsigned max_ports_per_bitfield = 5; + int base_bitfield_channel; unsigned read_bits = 0; - unsigned j; + int last_port_offset = ni_65xx_port_by_channel(s->n_chan - 1); + int port_offset; + if (insn->n != 2) return -EINVAL; base_bitfield_channel = CR_CHAN(insn->chanspec); - for (j = 0; j < max_ports_per_bitfield; ++j) { - const unsigned port_offset = - ni_65xx_port_by_channel(base_bitfield_channel) + j; - const unsigned port = - sprivate(s)->base_port + port_offset; - unsigned base_port_channel; + for (port_offset = ni_65xx_port_by_channel(base_bitfield_channel); + port_offset <= last_port_offset; port_offset++) { + unsigned port = sprivate(s)->base_port + port_offset; + int base_port_channel = port_offset * ni_65xx_channels_per_port; unsigned port_mask, port_data, port_read_bits; - int bitshift; - if (port >= ni_65xx_total_num_ports(board(dev))) + int bitshift = base_port_channel - base_bitfield_channel; + + if (bitshift >= 32) break; - base_port_channel = port_offset * ni_65xx_channels_per_port; port_mask = data[0]; port_data = data[1]; - bitshift = base_port_channel - base_bitfield_channel; - if (bitshift >= 32 || bitshift <= -32) - break; if (bitshift > 0) { port_mask >>= bitshift; port_data >>= bitshift; -- cgit v1.1 From b8a3fdb8cfff87da926b868c3263a8a51c02af47 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Fri, 13 Sep 2013 13:13:23 +0800 Subject: ACPI / IPMI: Fix atomic context requirement of ipmi_msg_handler() commit 06a8566bcf5cf7db9843a82cde7a33c7bf3947d9 upstream. This patch fixes the issues indicated by the test results that ipmi_msg_handler() is invoked in atomic context. BUG: scheduling while atomic: kipmi0/18933/0x10000100 Modules linked in: ipmi_si acpi_ipmi ... CPU: 3 PID: 18933 Comm: kipmi0 Tainted: G AW 3.10.0-rc7+ #2 Hardware name: QCI QSSC-S4R/QSSC-S4R, BIOS QSSC-S4R.QCI.01.00.0027.070120100606 07/01/2010 ffff8838245eea00 ffff88103fc63c98 ffffffff814c4a1e ffff88103fc63ca8 ffffffff814bfbab ffff88103fc63d28 ffffffff814c73e0 ffff88103933cbd4 0000000000000096 ffff88103fc63ce8 ffff88102f618000 ffff881035c01fd8 Call Trace: [] dump_stack+0x19/0x1b [] __schedule_bug+0x46/0x54 [] __schedule+0x83/0x59c [] __cond_resched+0x22/0x2d [] _cond_resched+0x14/0x1d [] mutex_lock+0x11/0x32 [] ? __default_send_IPI_dest_field.constprop.0+0x53/0x58 [] ipmi_msg_handler+0x23/0x166 [ipmi_si] [] deliver_response+0x55/0x5a [] handle_new_recv_msgs+0xb67/0xc65 [] ? read_tsc+0x9/0x19 [] ? _raw_spin_lock_irq+0xa/0xc [] ipmi_thread+0x5c/0x146 [ipmi_si] ... Also Tony Camuso says: We were getting occasional "Scheduling while atomic" call traces during boot on some systems. Problem was first seen on a Cisco C210 but we were able to reproduce it on a Cisco c220m3. Setting CONFIG_LOCKDEP and LOCKDEP_SUPPORT to 'y' exposed a lockdep around tx_msg_lock in acpi_ipmi.c struct acpi_ipmi_device. ================================= [ INFO: inconsistent lock state ] 2.6.32-415.el6.x86_64-debug-splck #1 --------------------------------- inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage. ksoftirqd/3/17 [HC0[0]:SC1[1]:HE1:SE0] takes: (&ipmi_device->tx_msg_lock){+.?...}, at: [] ipmi_msg_handler+0x71/0x126 {SOFTIRQ-ON-W} state was registered at: [] __lock_acquire+0x63c/0x1570 [] lock_acquire+0xa4/0x120 [] __mutex_lock_common+0x4c/0x400 [] mutex_lock_nested+0x4a/0x60 [] acpi_ipmi_space_handler+0x11b/0x234 [] acpi_ev_address_space_dispatch+0x170/0x1be The fix implemented by this change has been tested by Tony: Tested the patch in a boot loop with lockdep debug enabled and never saw the problem in over 400 reboots. Reported-and-tested-by: Tony Camuso Signed-off-by: Lv Zheng Reviewed-by: Huang Ying Signed-off-by: Rafael J. Wysocki Cc: Jonghwan Choi Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/acpi_ipmi.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c index f40acef..a6977e1 100644 --- a/drivers/acpi/acpi_ipmi.c +++ b/drivers/acpi/acpi_ipmi.c @@ -39,6 +39,7 @@ #include #include #include +#include MODULE_AUTHOR("Zhao Yakui"); MODULE_DESCRIPTION("ACPI IPMI Opregion driver"); @@ -57,7 +58,7 @@ struct acpi_ipmi_device { struct list_head head; /* the IPMI request message list */ struct list_head tx_msg_list; - struct mutex tx_msg_lock; + spinlock_t tx_msg_lock; acpi_handle handle; struct pnp_dev *pnp_dev; ipmi_user_t user_interface; @@ -147,6 +148,7 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, struct kernel_ipmi_msg *msg; struct acpi_ipmi_buffer *buffer; struct acpi_ipmi_device *device; + unsigned long flags; msg = &tx_msg->tx_message; /* @@ -177,10 +179,10 @@ static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, /* Get the msgid */ device = tx_msg->device; - mutex_lock(&device->tx_msg_lock); + spin_lock_irqsave(&device->tx_msg_lock, flags); device->curr_msgid++; tx_msg->tx_msgid = device->curr_msgid; - mutex_unlock(&device->tx_msg_lock); + spin_unlock_irqrestore(&device->tx_msg_lock, flags); } static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, @@ -242,6 +244,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) int msg_found = 0; struct acpi_ipmi_msg *tx_msg; struct pnp_dev *pnp_dev = ipmi_device->pnp_dev; + unsigned long flags; if (msg->user != ipmi_device->user_interface) { dev_warn(&pnp_dev->dev, "Unexpected response is returned. " @@ -250,7 +253,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) ipmi_free_recv_msg(msg); return; } - mutex_lock(&ipmi_device->tx_msg_lock); + spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) { if (msg->msgid == tx_msg->tx_msgid) { msg_found = 1; @@ -258,7 +261,7 @@ static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) } } - mutex_unlock(&ipmi_device->tx_msg_lock); + spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); if (!msg_found) { dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is " "returned.\n", msg->msgid); @@ -378,6 +381,7 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, struct acpi_ipmi_device *ipmi_device = handler_context; int err, rem_time; acpi_status status; + unsigned long flags; /* * IPMI opregion message. * IPMI message is firstly written to the BMC and system software @@ -395,9 +399,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, return AE_NO_MEMORY; acpi_format_ipmi_msg(tx_msg, address, value); - mutex_lock(&ipmi_device->tx_msg_lock); + spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); - mutex_unlock(&ipmi_device->tx_msg_lock); + spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); err = ipmi_request_settime(ipmi_device->user_interface, &tx_msg->addr, tx_msg->tx_msgid, @@ -413,9 +417,9 @@ acpi_ipmi_space_handler(u32 function, acpi_physical_address address, status = AE_OK; end_label: - mutex_lock(&ipmi_device->tx_msg_lock); + spin_lock_irqsave(&ipmi_device->tx_msg_lock, flags); list_del(&tx_msg->head); - mutex_unlock(&ipmi_device->tx_msg_lock); + spin_unlock_irqrestore(&ipmi_device->tx_msg_lock, flags); kfree(tx_msg); return status; } @@ -457,7 +461,7 @@ static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device) INIT_LIST_HEAD(&ipmi_device->head); - mutex_init(&ipmi_device->tx_msg_lock); + spin_lock_init(&ipmi_device->tx_msg_lock); INIT_LIST_HEAD(&ipmi_device->tx_msg_list); ipmi_install_space_handler(ipmi_device); -- cgit v1.1 From 7b3c1a8576716d825c73ac1739b2b3f0d7226dcf Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 27 Mar 2013 06:40:50 +0000 Subject: tg3: fix length overflow in VPD firmware parsing commit 715230a44310a8cf66fbfb5a46f9a62a9b2de424 upstream. Commit 184b89044fb6e2a74611dafa69b1dce0d98612c6 ("tg3: Use VPD fw version when present") introduced VPD parsing that contained a potential length overflow. Limit the hardware's reported firmware string length (max 255 bytes) to stay inside the driver's firmware string length (32 bytes). On overflow, truncate the formatted firmware string instead of potentially overwriting portions of the tg3 struct. http://cansecwest.com/slides/2013/PrivateCore%20CSW%202013.pdf -js: This fixes CVE-2013-1929. Signed-off-by: Kees Cook Reported-by: Oded Horovitz Reported-by: Brad Spengler Cc: stable@vger.kernel.org Cc: Matt Carlson Signed-off-by: David S. Miller Acked-by: Jeff Mahoney Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/net/tg3.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index eaa24fa8..1736875 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -13067,8 +13067,11 @@ static void __devinit tg3_read_vpd(struct tg3 *tp) if (j + len > block_end) goto partno; - memcpy(tp->fw_ver, &vpd_data[j], len); - strncat(tp->fw_ver, " bc ", TG3_NVM_VPD_LEN - len - 1); + if (len >= sizeof(tp->fw_ver)) + len = sizeof(tp->fw_ver) - 1; + memset(tp->fw_ver, 0, sizeof(tp->fw_ver)); + snprintf(tp->fw_ver, sizeof(tp->fw_ver), "%.*s bc ", len, + &vpd_data[j]); } partno: -- cgit v1.1 From fd819bdaa91422cf6b568bb76c40d0e5d8fbddaf Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Thu, 31 May 2012 16:40:06 +0200 Subject: Tools: hv: verify origin of netlink connector message commit bcc2c9c3fff859e0eb019fe6fec26f9b8eba795c upstream. The SuSE security team suggested to use recvfrom instead of recv to be certain that the connector message is originated from kernel. CVE-2012-2669 Signed-off-by: Olaf Hering Signed-off-by: Marcus Meissner Signed-off-by: Sebastian Krahmer Signed-off-by: K. Y. Srinivasan Signed-off-by: Greg Kroah-Hartman Signed-off-by: Jiri Slaby --- drivers/staging/hv/tools/hv_kvp_daemon.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/hv/tools/hv_kvp_daemon.c b/drivers/staging/hv/tools/hv_kvp_daemon.c index 33f0f1c..1468a01 100644 --- a/drivers/staging/hv/tools/hv_kvp_daemon.c +++ b/drivers/staging/hv/tools/hv_kvp_daemon.c @@ -378,14 +378,18 @@ int main(void) pfd.fd = fd; while (1) { + struct sockaddr *addr_p = (struct sockaddr *) &addr; + socklen_t addr_l = sizeof(addr); pfd.events = POLLIN; pfd.revents = 0; poll(&pfd, 1, -1); - len = recv(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0); + len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0, + addr_p, &addr_l); - if (len < 0) { - syslog(LOG_ERR, "recv failed; error:%d", len); + if (len < 0 || addr.nl_pid) { + syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s", + addr.nl_pid, errno, strerror(errno)); close(fd); return -1; } -- cgit v1.1 From fa759b5d100c8b0d2ec2b83fcac990f2c3ac13b7 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 10 Sep 2013 10:52:35 -0400 Subject: random: run random_int_secret_init() run after all late_initcalls commit 47d06e532e95b71c0db3839ebdef3fe8812fca2c upstream. The some platforms (e.g., ARM) initializes their clocks as late_initcalls for some unknown reason. So make sure random_int_secret_init() is run after all of the late_initcalls are run. Signed-off-by: "Theodore Ts'o" Signed-off-by: Greg Kroah-Hartman --- drivers/char/random.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index fceac95..e7e479c 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1435,12 +1435,11 @@ ctl_table random_table[] = { static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; -static int __init random_int_secret_init(void) +int random_int_secret_init(void) { get_random_bytes(random_int_secret, sizeof(random_int_secret)); return 0; } -late_initcall(random_int_secret_init); /* * Get a random word for internal kernel use only. Similar to urandom but -- cgit v1.1 From 826380d59f09185201d4327121f4919d2914a2cc Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 23 Aug 2013 11:40:59 +0300 Subject: watchdog: ts72xx_wdt: locking bug in ioctl commit 8612ed0d97abcf1c016d34755b7cf2060de71963 upstream. Calling the WDIOC_GETSTATUS & WDIOC_GETBOOTSTATUS and twice will cause a interruptible deadlock. Signed-off-by: Dan Carpenter Reviewed-by: Guenter Roeck Signed-off-by: Wim Van Sebroeck Cc: Jonghwan Choi Signed-off-by: Greg Kroah-Hartman --- drivers/watchdog/ts72xx_wdt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/ts72xx_wdt.c b/drivers/watchdog/ts72xx_wdt.c index 5a90a4a..87c0924 100644 --- a/drivers/watchdog/ts72xx_wdt.c +++ b/drivers/watchdog/ts72xx_wdt.c @@ -310,7 +310,8 @@ static long ts72xx_wdt_ioctl(struct file *file, unsigned int cmd, case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - return put_user(0, p); + error = put_user(0, p); + break; case WDIOC_KEEPALIVE: ts72xx_wdt_kick(wdt); -- cgit v1.1 From f11d481f8f81dec26d3370bcf8f4c1f2d53ccefc Mon Sep 17 00:00:00 2001 From: wojciech kapuscinski Date: Tue, 1 Oct 2013 19:54:33 -0400 Subject: drm/radeon: fix hw contexts for SUMO2 asics commit 50b8f5aec04ebec7dbdf2adb17220b9148c99e63 upstream. They have 4 rather than 8. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=63599 Signed-off-by: wojciech kapuscinski Signed-off-by: Alex Deucher Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/radeon/evergreen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index eecd3dc..87ff586 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1749,7 +1749,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) rdev->config.evergreen.sx_max_export_size = 256; rdev->config.evergreen.sx_max_export_pos_size = 64; rdev->config.evergreen.sx_max_export_smx_size = 192; - rdev->config.evergreen.max_hw_contexts = 8; + rdev->config.evergreen.max_hw_contexts = 4; rdev->config.evergreen.sq_num_cf_insts = 2; rdev->config.evergreen.sc_prim_fifo_size = 0x40; -- cgit v1.1