From 5aceca9d3cbdacbd017712513387d930f9f944d9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 23 May 2011 17:12:22 -0700 Subject: PCI: Fix warning in drivers/pci/probe.c on sparc64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IO_SPACE_LIMIT is currently used in two ways: 1) As a way to mask I/O port values read out of PCI base address registers. This value should be 64-bit. 2) As a value which is the upper limit for all I/O "ports" in the system. On sparc64 we store the full 64-bit physical I/O address in the resources. For this reason we define IO_SPACE_LIMIT at a 64-bit "all 1's". This is the right value to use for ioport_resource.end and for the check made in drivers/pcmcia/rsrc_nonstatic.c:adjust_io(). But in driver/pci/probe.c:__pci_read_base() we mask this against a "u32" variable and thus get the following warning: drivers/pci/probe.c: In function ¡__pci_read_base¢: drivers/pci/probe.c:207: warning: large integer implicitly truncated to unsigned type Fix this by using an explicit "u32" cast. I considered changing sparc64 to define a 32-bit "all 1's" like most other systems do, but this wouldn't work because the checks in PCMCIA's rsrc_nonstatic.c would no longer be right since they are testing against fully formed 64-bit resources. As described above, on sparc64 such resources will hold full 64-bit physical I/O addresses, not bus-centric 32-bit ones. Signed-off-by: David S. Miller Signed-off-by: Jesse Barnes --- drivers/pci/probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 48849ff..bafb3c3 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -168,7 +168,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN; if (type == pci_bar_io) { l &= PCI_BASE_ADDRESS_IO_MASK; - mask = PCI_BASE_ADDRESS_IO_MASK & IO_SPACE_LIMIT; + mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT; } else { l &= PCI_BASE_ADDRESS_MEM_MASK; mask = (u32)PCI_BASE_ADDRESS_MEM_MASK; -- cgit v1.1 From 3f37d6229ca309f96b163b943ff982f4697630cd Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 25 May 2011 19:21:25 -0700 Subject: PCI: fix new kernel-doc warning Fix pci.c kernel-doc warnings: Warning(drivers/pci/pci.c:3292): No description found for parameter 'flags' Warning(drivers/pci/pci.c:3292): Excess function parameter 'change_bridge_flags' description in 'pci_set_vga_state' Signed-off-by: Randy Dunlap Signed-off-by: Jesse Barnes --- drivers/pci/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 56098b3..e43a7bb 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3284,7 +3284,7 @@ static int pci_set_vga_state_arch(struct pci_dev *dev, bool decode, * @dev: the PCI device * @decode: true = enable decoding, false = disable decoding * @command_bits: PCI_COMMAND_IO and/or PCI_COMMAND_MEMORY - * @change_bridge_flags: traverse ancestors and change bridges + * @flags: traverse ancestors and change bridges * CHANGE_BRIDGE_ONLY / CHANGE_BRIDGE */ int pci_set_vga_state(struct pci_dev *dev, bool decode, -- cgit v1.1 From eb7073db1076777496495483854993165e14790f Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 2 Jun 2011 11:31:29 +0900 Subject: 8250_pci: add -ENODEV code for Intel EG20T PCH Intel EG20T PCH has UART device which is compatible with 8250. Currently, with general configuration, the PCH UART driver is not loaded but 8250 standard driver is loaded. Therefore, in case of using PCH UART driver, need to disable 8250 pci function. However, this procedure is not best solution. This patch, in 8250_pci, if the device is the PCH or the family IOH, '-ENODEV' is returned. As a result, disabling 8250-pci processing becomes unnecessary. Signed-off-by: Tomoya MORINAGA Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250_pci.c | 59 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c index 4b4968a..d7dc513 100644 --- a/drivers/tty/serial/8250_pci.c +++ b/drivers/tty/serial/8250_pci.c @@ -994,6 +994,15 @@ static int skip_tx_en_setup(struct serial_private *priv, return pci_default_setup(priv, board, port, idx); } +static int pci_eg20t_init(struct pci_dev *dev) +{ +#if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE) + return -ENODEV; +#else + return 0; +#endif +} + /* This should be in linux/pci_ids.h */ #define PCI_VENDOR_ID_SBSMODULARIO 0x124B #define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B @@ -1446,6 +1455,56 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .init = pci_oxsemi_tornado_init, .setup = pci_default_setup, }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x8811, + .init = pci_eg20t_init, + }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x8812, + .init = pci_eg20t_init, + }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x8813, + .init = pci_eg20t_init, + }, + { + .vendor = PCI_VENDOR_ID_INTEL, + .device = 0x8814, + .init = pci_eg20t_init, + }, + { + .vendor = 0x10DB, + .device = 0x8027, + .init = pci_eg20t_init, + }, + { + .vendor = 0x10DB, + .device = 0x8028, + .init = pci_eg20t_init, + }, + { + .vendor = 0x10DB, + .device = 0x8029, + .init = pci_eg20t_init, + }, + { + .vendor = 0x10DB, + .device = 0x800C, + .init = pci_eg20t_init, + }, + { + .vendor = 0x10DB, + .device = 0x800D, + .init = pci_eg20t_init, + }, + { + .vendor = 0x10DB, + .device = 0x800D, + .init = pci_eg20t_init, + }, /* * Cronyx Omega PCI (PLX-chip based) */ -- cgit v1.1 From af99d6f0037d970084b03d9690f50e34d6f70dae Mon Sep 17 00:00:00 2001 From: Lennart Sorensen Date: Wed, 1 Jun 2011 14:38:41 -0400 Subject: serial: ioremap warning fix for jsm driver. I saw a warning about ioremap from the jsm driver on a system which looked like this: resource map sanity check conflict: 0xe0200800 0xe02017ff 0xe0200800 0xe0200fff 0000:01:08.0 Turns out the warning is valid. The jsm driver has been asking to ioremap 0x1000 forever, but in fact only 8 port chips have 0x1000 bytes of memory. 4 port chips have 0x800 and 2 port chips have 0x400 according to the data sheet. It makes more sense to map the size of the region rather than a hard coded value. If you happen to have the region legitimately mapped to a base address that is not 4K aligned, ioremap complains otherwise. Signed-off-by: Len Sorensen Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/jsm/jsm_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index 18f5484..96da178 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c @@ -125,7 +125,7 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device brd->bd_uart_offset = 0x200; brd->bd_dividend = 921600; - brd->re_map_membase = ioremap(brd->membase, 0x1000); + brd->re_map_membase = ioremap(brd->membase, pci_resource_len(pdev, 0)); if (!brd->re_map_membase) { dev_err(&pdev->dev, "card has no PCI Memory resources, " -- cgit v1.1 From 470f22975448a65a1084a6f0721fa5df15323f02 Mon Sep 17 00:00:00 2001 From: Boojin Kim Date: Fri, 27 May 2011 19:04:03 -0700 Subject: ARM: SAMSUNG: serial: Fix on handling of one clock source for UART This patch fixes the way of comparison for handling of two or more clock sources for UART. For example, if just only one clock source is defined even though there are two clock sources for UART, the serial driver does not set proper clock up. Of course, it is problem. So this patch changes the condition of comparison to avoid useless setup clock and adds a flag 'NO_NEED_CHECK_CLKSRC' which means selection of source clock is not required. In addition, since the Exynos4210 has only one clock source for UART this patch adds the flag into its common_init_uarts(). Signed-off-by: Boojin Kim Signed-off-by: Kukjin Kim Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/s5pv210.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c index fb2619f9..dd194dc 100644 --- a/drivers/tty/serial/s5pv210.c +++ b/drivers/tty/serial/s5pv210.c @@ -30,7 +30,7 @@ static int s5pv210_serial_setsource(struct uart_port *port, struct s3c2410_uartcfg *cfg = port->dev->platform_data; unsigned long ucon = rd_regl(port, S3C2410_UCON); - if ((cfg->clocks_size) == 1) + if (cfg->flags & NO_NEED_CHECK_CLKSRC) return 0; if (strcmp(clk->name, "pclk") == 0) @@ -55,7 +55,7 @@ static int s5pv210_serial_getsource(struct uart_port *port, clk->divisor = 1; - if ((cfg->clocks_size) == 1) + if (cfg->flags & NO_NEED_CHECK_CLKSRC) return 0; switch (ucon & S5PV210_UCON_CLKMASK) { -- cgit v1.1 From 1798ca13bfae8cc7c0ef82c034c3c4951ecaeb88 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 24 May 2011 12:35:48 +0100 Subject: 8250_pci: Fix missing const from merges Signed-off-by: Alan Cox Signed-off-by: Antony Pavlov Signed-off-by: Borislav Petkov Signed-off-by: Vasily Averin Signed-off-by: Guenter Roeck Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c index d7dc513..f41b425 100644 --- a/drivers/tty/serial/8250_pci.c +++ b/drivers/tty/serial/8250_pci.c @@ -973,7 +973,7 @@ ce4100_serial_setup(struct serial_private *priv, static int pci_omegapci_setup(struct serial_private *priv, - struct pciserial_board *board, + const struct pciserial_board *board, struct uart_port *port, int idx) { return setup_port(priv, port, 2, idx * 8, 0); -- cgit v1.1 From cb01ece3ea5dec16ac7bab30069c7736b59f7dea Mon Sep 17 00:00:00 2001 From: "leitao@linux.vnet.ibm.com" Date: Thu, 26 May 2011 11:18:39 -0300 Subject: 8250: Fix capabilities when changing the port type When changing the port type, the capabilities flags should be changed also, otherwise the capabilities will not correspond to the port type, which make set_sleep() crash on rmmod. This patch just assign the correct capabilites when the port changes. Signed-off-by: Breno Leitao CC: Michael Reed Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index b40f7b9..b4129f5 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -3318,6 +3318,7 @@ void serial8250_unregister_port(int line) uart->port.flags &= ~UPF_BOOT_AUTOCONF; uart->port.type = PORT_UNKNOWN; uart->port.dev = &serial8250_isa_devs->dev; + uart->capabilities = uart_config[uart->port.type].flags; uart_add_one_port(&serial8250_reg, &uart->port); } else { uart->port.dev = NULL; -- cgit v1.1 From 5daf538a0313509ecdeb5b7a61257f39881f9361 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 22 May 2011 17:38:02 -0700 Subject: firmware: fix GOOGLE_SMI kconfig dependency warning Is it meaningful/useful to enable EFI_VARS but not EFI? That's what GOOGLE_SMI does. Make it enable EFI also. Fixes this kconfig dependency warning: warning: (GOOGLE_SMI) selects EFI_VARS which has unmet direct dependencies (EFI) Signed-off-by: Randy Dunlap Acked-by: Mike Waychison Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/google/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/firmware/google/Kconfig b/drivers/firmware/google/Kconfig index 87096b6..2f21b0b 100644 --- a/drivers/firmware/google/Kconfig +++ b/drivers/firmware/google/Kconfig @@ -13,6 +13,7 @@ menu "Google Firmware Drivers" config GOOGLE_SMI tristate "SMI interface for Google platforms" depends on ACPI && DMI + select EFI select EFI_VARS help Say Y here if you want to enable SMI callbacks for Google -- cgit v1.1 From 7316a9f2a94c14e66e9421a777dffc509a2fe0e3 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 23 May 2011 16:45:32 -0400 Subject: st_kim: Handle case of no device found for ID 0 Running ktest.pl, I hit this bug: [ 19.780654] BUG: unable to handle kernel NULL pointer dereference at 0000000c [ 19.780660] IP: [] dev_get_drvdata+0xc/0x46 [ 19.780669] *pdpt = 0000000031daf001 *pde = 0000000000000000 [ 19.780673] Oops: 0000 [#1] SMP [ 19.780680] Dumping ftrace buffer:^M [ 19.780685] (ftrace buffer empty) [ 19.780687] Modules linked in: ide_pci_generic firewire_ohci firewire_core evbug crc_itu_t e1000 ide_core i2c_i801 iTCO_wdt [ 19.780697] [ 19.780700] Pid: 346, comm: v4l_id Not tainted 2.6.39-test-02740-gcaebc16-dirty #4 /DG965MQ [ 19.780706] EIP: 0060:[] EFLAGS: 00010202 CPU: 0 [ 19.780709] EIP is at dev_get_drvdata+0xc/0x46 [ 19.780712] EAX: 00000008 EBX: f1e37da4 ECX: 00000000 EDX: 00000000 [ 19.780715] ESI: f1c3f200 EDI: c33ec95c EBP: f1e37d80 ESP: f1e37d80 [ 19.780718] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 [ 19.780721] Process v4l_id (pid: 346, ti=f1e36000 task=f2bc2a60 task.ti=f1e36000) [ 19.780723] Stack: [ 19.780725] f1e37d8c c117d395 c33ec93c f1e37db4 c117a0f9 00000002 00000000 c1725e54 [ 19.780732] 00000001 00000007 f2918c90 f1c3f200 c33ec95c f1e37dd4 c1789d3d 22222222 [ 19.780740] 22222222 22222222 f2918c90 f1c3f200 f29194f4 f1e37de8 c178d5c4 c1725e54 [ 19.780747] Call Trace: [ 19.780752] [] st_kim_ref+0x28/0x41 [ 19.780756] [] st_register+0x29/0x562 [ 19.780761] [] ? v4l2_open+0x111/0x1e3 [ 19.780766] [] fmc_prepare+0x97/0x424 [ 19.780770] [] fm_v4l2_fops_open+0x70/0x106 [ 19.780773] [] ? v4l2_open+0x111/0x1e3 [ 19.780777] [] v4l2_open+0x158/0x1e3 [ 19.780782] [] chrdev_open+0x22c/0x276 [ 19.780787] [] __dentry_open+0x35c/0x581 [ 19.780792] [] nameidata_to_filp+0x7c/0x96 [ 19.780795] [] ? cdev_put+0x57/0x57 [ 19.780800] [] do_last+0x743/0x9d4 [ 19.780804] [] ? path_init+0x1ee/0x596 [ 19.780808] [] path_openat+0x10c/0x597 [ 19.780813] [] ? trace_hardirqs_off+0x27/0x37 [ 19.780817] [] ? local_clock+0x78/0xc7 [ 19.780821] [] do_filp_open+0x39/0xc2 [ 19.780827] [] ? _raw_spin_unlock+0x4c/0x5d^M [ 19.780831] [] ? alloc_fd+0x19e/0x1b7 [ 19.780836] [] do_sys_open+0xb7/0x1bd [ 19.780840] [] ? sys_munmap+0x78/0x8d [ 19.780844] [] sys_open+0x36/0x58 [ 19.780849] [] sysenter_do_call+0x12/0x38 [ 19.780852] Code: d8 2f 20 c3 01 83 15 dc 2f 20 c3 00 f0 ff 00 83 05 e0 2f 20 c3 01 83 15 e4 2f 20 c3 00 5d c3 55 89 e5 3e 8d 74 26 00 85 c0 74 28 <8b> 40 04 83 05 e8 2f 20 c3 01 83 15 ec 2f 20 c3 00 85 c0 74 13 ^M [ 19.780889] EIP: [] dev_get_drvdata+0xc/0x46 SS:ESP 0068:f1e37d80 [ 19.780894] CR2: 000000000000000c [ 19.780898] ---[ end trace e7d1d0f6a2d1d390 ]--- The id of 0 passed to st_kim_ref() found no device, keeping pdev null, and causing pdev->dev cause a NULL pointer dereference. After having st_kim_ref() check for NULL, the st_unregister() function needed to be updated to handle the case that st_gdata was not set by the st_kim_ref(). Signed-off-by: Steven Rostedt Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 2 +- drivers/misc/ti-st/st_kim.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index f91f82e..54c91ff 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -605,7 +605,7 @@ long st_unregister(struct st_proto_s *proto) pr_debug("%s: %d ", __func__, proto->chnl_id); st_kim_ref(&st_gdata, 0); - if (proto->chnl_id >= ST_MAX_CHANNELS) { + if (!st_gdata || proto->chnl_id >= ST_MAX_CHANNELS) { pr_err(" chnl_id %d not supported", proto->chnl_id); return -EPROTONOSUPPORT; } diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 5da93ee..3613c3b 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -604,6 +604,10 @@ void st_kim_ref(struct st_data_s **core_data, int id) struct kim_data_s *kim_gdata; /* get kim_gdata reference from platform device */ pdev = st_get_plat_device(id); + if (!pdev) { + *core_data = NULL; + return; + } kim_gdata = dev_get_drvdata(&pdev->dev); *core_data = kim_gdata->core_data; } -- cgit v1.1 From bb2b43fefab723f4a0760146e7bed59d41a50e53 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 23 May 2011 14:44:19 -0700 Subject: drivers/base/platform.c: don't mark platform_device_register_resndata() as __init_or_module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts 737a3bb9416ce2a7c7a4 ("Driver core: move platform device creation helpers to .init.text (if MODULE=n)"). That patch assumed that platform_device_register_resndata() is only ever called from __init code but that isn't true in the case ioctl->drm_ioctl->radeon_cp_init(). Addresses https://bugzilla.kernel.org/show_bug.cgi?id=35192 Cc: Uwe Kleine-König Reported-by: Anthony Basile Cc: Greg KH Cc: David Airlie Cc: Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/base/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 1c291af..6040717 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -367,7 +367,7 @@ EXPORT_SYMBOL_GPL(platform_device_unregister); * * Returns &struct platform_device pointer on success, or ERR_PTR() on error. */ -struct platform_device *__init_or_module platform_device_register_resndata( +struct platform_device *platform_device_register_resndata( struct device *parent, const char *name, int id, const struct resource *res, unsigned int num, -- cgit v1.1 From 9d031d94da453077bbc6108b7822fc751ac85299 Mon Sep 17 00:00:00 2001 From: Shahar Lev Date: Mon, 23 May 2011 11:36:11 +0300 Subject: drivers:misc: ti-st: fix skipping of change remote baud Before the incrementing of ptr in skip_change_remote_baud, it points to cur_action, but the increment is done by the size of nxt_action instead. This could cause ptr to not point to a bts_action structure, which is harmful for the increment of ptr done in download_firmware. Therefore, the skipping is first done for cur_action. Signed-off-by: Shahar Lev Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_kim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 3613c3b..38fd2f0 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -245,9 +245,9 @@ void skip_change_remote_baud(unsigned char **ptr, long *len) pr_err("invalid action after change remote baud command"); } else { *ptr = *ptr + sizeof(struct bts_action) + - ((struct bts_action *)nxt_action)->size; + ((struct bts_action *)cur_action)->size; *len = *len - (sizeof(struct bts_action) + - ((struct bts_action *)nxt_action)->size); + ((struct bts_action *)cur_action)->size); /* warn user on not commenting these in firmware */ pr_warn("skipping the wait event of change remote baud"); } -- cgit v1.1 From 29021bccea0dc42d7d101004058438a9a4e693b1 Mon Sep 17 00:00:00 2001 From: J Freyensee Date: Wed, 25 May 2011 14:38:18 -0700 Subject: pti: double-free security PTI fix This patch fixes a double-free error that will not always be seen unless /dev/pti char interface is stressed. Signed-off-by: J Freyensee Signed-off-by: Greg Kroah-Hartman --- drivers/misc/pti.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index bb6f925..be48573 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c @@ -317,7 +317,8 @@ EXPORT_SYMBOL_GPL(pti_request_masterchannel); * a master, channel ID address * used to write to PTI HW. * - * @mc: master, channel apeture ID address to be released. + * @mc: master, channel apeture ID address to be released. This + * will de-allocate the structure via kfree(). */ void pti_release_masterchannel(struct pti_masterchannel *mc) { @@ -581,7 +582,7 @@ static int pti_char_open(struct inode *inode, struct file *filp) static int pti_char_release(struct inode *inode, struct file *filp) { pti_release_masterchannel(filp->private_data); - kfree(filp->private_data); + filp->private_data = NULL; return 0; } -- cgit v1.1 From 1dae42bff57f7a61577ee881265985a660d35c07 Mon Sep 17 00:00:00 2001 From: J Freyensee Date: Wed, 25 May 2011 14:45:40 -0700 Subject: pti: ENXIO error case memory leak PTI fix. This patch fixes a memory leak that can occur in the error case ENXIO is returned in the pti_tty_install() routine. Signed-off-by: J Freyensee Signed-off-by: Greg Kroah-Hartman --- drivers/misc/pti.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index be48573..e74e7d2 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c @@ -476,8 +476,10 @@ static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty) else pti_tty_data->mc = pti_request_masterchannel(2); - if (pti_tty_data->mc == NULL) + if (pti_tty_data->mc == NULL) { + kfree(pti_tty_data); return -ENXIO; + } tty->driver_data = pti_tty_data; } -- cgit v1.1 From 1312ba40c0d00f0a5cfcfe3afc222fcef2a90b56 Mon Sep 17 00:00:00 2001 From: J Freyensee Date: Wed, 25 May 2011 14:56:43 -0700 Subject: pti: PTI semantics fix in pti_tty_cleanup. This patch fixes a semantics issue in the pti_tty_cleanup() routine. Signed-off-by: J Freyensee Signed-off-by: Greg Kroah-Hartman --- drivers/misc/pti.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index e74e7d2..374dfcf 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c @@ -498,7 +498,7 @@ static void pti_tty_cleanup(struct tty_struct *tty) if (pti_tty_data == NULL) return; pti_release_masterchannel(pti_tty_data->mc); - kfree(tty->driver_data); + kfree(pti_tty_data); tty->driver_data = NULL; } -- cgit v1.1 From 92f6fa09bd453ffe3351fa1f1377a1b7cfa911e6 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sun, 5 Jun 2011 14:16:16 +0200 Subject: TTY: ldisc, do not close until there are readers We restored tty_ldisc_wait_idle in 100eeae2c5c (TTY: restore tty_ldisc_wait_idle). We used it in the ldisc changing path to fix the case where there are tasks in n_tty_read waiting for data and somebody tries to change ldisc. Similar to the case above, there may be also tasks waiting in n_tty_read while hangup is performed. As 65b770468e98 (tty-ldisc: turn ldisc user count into a proper refcount) removed the wait-until-idle from all paths, hangup path won't wait for them to disappear either now. So add it back even to the hangup path. There is a difference, we need uninterruptible sleep as there is obviously HUP signal pending. So tty_ldisc_wait_idle now sleeps without possibility to be interrupted. This is what original tty_ldisc_wait_idle did. After the wait idle reintroduction (100eeae2c5c), we have had interruptible sleeps for the ldisc changing path. But as there is a 5s timeout anyway, we don't allow it to be interrupted from now on. It's not worth the added complexity of deciding what kind of sleep we want. Before 65b770468e98 tty_ldisc_release was called also from tty_ldisc_release. It is called from tty_release, so I don't think we need to restore that one. This is nicely reproducible after constifying the timing when drivers/tty/n_tty.c is patched as follows ("TTY: ntty, add one more sanity check" patch is needed to actually see it explode): %% -1548,6 +1549,7 @@ static int n_tty_open(struct tty_struct *tty) /* These are ugly. Currently a malloc failure here can panic */ if (!tty->read_buf) { + msleep(100); tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL); if (!tty->read_buf) return -ENOMEM; %% -1785,6 +1788,7 @@ do_it_again: break; } timeout = schedule_timeout(timeout); + msleep(20); continue; } __set_current_state(TASK_RUNNING); ===== With a process: ===== while (1) { int fd = open(argv[1], O_RDWR); read(fd, buf, sizeof(buf)); close(fd); } ===== and its child: ===== setsid(); while (1) { int fd = open(tty, O_RDWR|O_NOCTTY); ioctl(fd, TIOCSCTTY, 1); vhangup(); close(fd); usleep(100 * (10 + random() % 1000)); } ===== EOF ===== References: https://bugzilla.novell.com/show_bug.cgi?id=693374 References: https://bugzilla.novell.com/show_bug.cgi?id=694509 Signed-off-by: Jiri Slaby Cc: Alan Cox Cc: Linus Torvalds Cc: stable [32, 33, 34, 39] Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_ldisc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 5d01d32..ef925d5 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -555,7 +555,7 @@ static void tty_ldisc_flush_works(struct tty_struct *tty) static int tty_ldisc_wait_idle(struct tty_struct *tty) { int ret; - ret = wait_event_interruptible_timeout(tty_ldisc_idle, + ret = wait_event_timeout(tty_ldisc_idle, atomic_read(&tty->ldisc->users) == 1, 5 * HZ); if (ret < 0) return ret; @@ -763,6 +763,8 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) if (IS_ERR(ld)) return -1; + WARN_ON_ONCE(tty_ldisc_wait_idle(tty)); + tty_ldisc_close(tty, tty->ldisc); tty_ldisc_put(tty->ldisc); tty->ldisc = NULL; -- cgit v1.1 From 2872628680bad71a6734e7d379168f990a91cc09 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Sun, 5 Jun 2011 14:16:17 +0200 Subject: TTY: ntty, add one more sanity check With the previous patch, we fixed another bug where read_buf was freed while we still was in n_tty_read. We currently check whether read_buf is NULL at the start of the function. Add one more check after we wake up from waiting for input. Signed-off-by: Jiri Slaby Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_tty.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 0ad3288..c3954fb 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1815,6 +1815,7 @@ do_it_again: /* FIXME: does n_tty_set_room need locking ? */ n_tty_set_room(tty); timeout = schedule_timeout(timeout); + BUG_ON(!tty->read_buf); continue; } __set_current_state(TASK_RUNNING); -- cgit v1.1 From 663dd6dcaf7e95526e469e91f41972a9c0cca30c Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 17 May 2011 15:25:38 -0700 Subject: Connector: Correctly set the error code in case of success when dispatching receive callbacks The recent changes to the connector code introduced this bug where even when a callback was invoked, we would return an error resulting in double freeing of the skb. This patch fixes this bug. Signed-off-by: K. Y. Srinivasan Acked-by: Evgeniy Polyakov Cc: stable [.39] Signed-off-by: Greg Kroah-Hartman --- drivers/connector/connector.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index 219d88a..dde6a0f 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -139,6 +139,7 @@ static int cn_call_callback(struct sk_buff *skb) spin_unlock_bh(&dev->cbdev->queue_lock); if (cbq != NULL) { + err = 0; cbq->callback(msg, nsp); kfree_skb(skb); cn_queue_release_callback(cbq); -- cgit v1.1 From 72887c8644384c0cc43b9298ae0659de383f2e9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rton=20N=C3=A9meth?= Date: Mon, 30 May 2011 20:45:42 +0200 Subject: usb: musb: host: compare status for negative error values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Variable d is a struct usb_iso_packet_descriptor. The status filed is usually negative when an error happens. Signed-off-by: Márton Németh Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 7295e31..8b2473f 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -1575,7 +1575,7 @@ void musb_host_rx(struct musb *musb, u8 epnum) /* even if there was an error, we did the dma * for iso_frame_desc->length */ - if (d->status != EILSEQ && d->status != -EOVERFLOW) + if (d->status != -EILSEQ && d->status != -EOVERFLOW) d->status = 0; if (++qh->iso_idx >= urb->number_of_packets) -- cgit v1.1 From 4858f06e7d92ed2ebdb29ccbc079c127e675a89c Mon Sep 17 00:00:00 2001 From: Yauheni Kaliuta Date: Wed, 8 Jun 2011 17:12:02 +0300 Subject: usb: musb: gadget: clear TXPKTRDY flag when set FLUSHFIFO Fixes mis-use of MUSB's hardware feature where it won't flush FIFOs when TXPKTRDY flag was set before and we are flushing setting both FLUSHFIFO and TXPKTRDY. In other words, we need to ensure that when we try to flush FIFOs, we don't accidentaly set TXPKTRDY bit too due to a read-back of the register. The MUSB Programming Guide says "May be set simultaneously with TxPktRdy to abort the packet that is currently being loaded into the FIFO". This is a situation where TXPKTRDY hasn't been set yet, but some data already loaded into the fifo. It looks, that if TXPKTRDY has been set before, and there is no loading in progress, but we set FLUSHFIFO with the TXPKTRDY, controller tries to use the same logic to abort loading and as the result just does nothing (because there is no packet been loaded currently) Signed-off-by: Yauheni Kaliuta [ balbi@ti.com : fixed one whitespace git complained about improved the commit log slightly ] Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 0a50a35..6aeb363 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1524,6 +1524,12 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep) csr = musb_readw(epio, MUSB_TXCSR); if (csr & MUSB_TXCSR_FIFONOTEMPTY) { csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_TXCSR_P_WZC_BITS; + /* + * Setting both TXPKTRDY and FLUSHFIFO makes controller + * to interrupt current FIFO loading, but not flushing + * the already loaded ones. + */ + csr &= ~MUSB_TXCSR_TXPKTRDY; musb_writew(epio, MUSB_TXCSR, csr); /* REVISIT may be inappropriate w/o FIFONOTEMPTY ... */ musb_writew(epio, MUSB_TXCSR, csr); -- cgit v1.1 From 357f45db920393aac983a137bd74095f612d5a01 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 13 Jun 2011 22:50:41 +0200 Subject: USB: TI 3410/5052 USB Serial Driver: Fix mem leak when firmware is too big. If the size of the firmware exceeds TI_FIRMWARE_BUF_SIZE we'll leak 'fw_p' by failing to call release_firmware(). This patch fixes the leak. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ti_usb_3410_5052.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index c6d92a5..ea84456 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -1745,6 +1745,7 @@ static int ti_download_firmware(struct ti_device *tdev) } if (fw_p->size > TI_FIRMWARE_BUF_SIZE) { dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size); + release_firmware(fw_p); return -ENOENT; } -- cgit v1.1 From fa75ac379e63c2864e9049b5e8615e40f65c1e70 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Sun, 5 Jun 2011 23:10:04 -0700 Subject: xhci: Reject double add of active endpoints. While trying to switch a UAS device from the BOT configuration to the UAS configuration via the bConfigurationValue file, Tanya ran into an issue in the USB core. usb_disable_device() sets entries in udev->ep_out and udev->ep_out to NULL, but doesn't call into the xHCI bandwidth management functions to remove the BOT configuration endpoints from the xHCI host's internal structures. The USB core would then attempt to add endpoints for the UAS configuration, and some of the endpoints had the same address as endpoints in the BOT configuration. The xHCI driver blindly added the endpoints again, but the xHCI host controller rejected the Configure Endpoint command because active endpoints were added without being dropped. Make the xHCI driver reject calls to xhci_add_endpoint() that attempt to add active endpoints without first calling xhci_drop_endpoint(). This should be backported to kernels as old as 2.6.31. Signed-off-by: Sarah Sharp Reported-by: Tanya Brokhman Cc: stable@kernel.org --- drivers/usb/host/xhci.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 06e7023..e5a0171 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1401,6 +1401,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, u32 added_ctxs; unsigned int last_ctx; u32 new_add_flags, new_drop_flags, new_slot_info; + struct xhci_virt_device *virt_dev; int ret = 0; ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); @@ -1425,11 +1426,25 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, return 0; } - in_ctx = xhci->devs[udev->slot_id]->in_ctx; - out_ctx = xhci->devs[udev->slot_id]->out_ctx; + virt_dev = xhci->devs[udev->slot_id]; + in_ctx = virt_dev->in_ctx; + out_ctx = virt_dev->out_ctx; ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); ep_index = xhci_get_endpoint_index(&ep->desc); ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); + + /* If this endpoint is already in use, and the upper layers are trying + * to add it again without dropping it, reject the addition. + */ + if (virt_dev->eps[ep_index].ring && + !(le32_to_cpu(ctrl_ctx->drop_flags) & + xhci_get_endpoint_flag(&ep->desc))) { + xhci_warn(xhci, "Trying to add endpoint 0x%x " + "without dropping it.\n", + (unsigned int) ep->desc.bEndpointAddress); + return -EINVAL; + } + /* If the HCD has already noted the endpoint is enabled, * ignore this request. */ @@ -1445,8 +1460,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, * process context, not interrupt context (or so documenation * for usb_set_interface() and usb_set_configuration() claim). */ - if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], - udev, ep, GFP_NOIO) < 0) { + if (xhci_endpoint_init(xhci, virt_dev, udev, ep, GFP_NOIO) < 0) { dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", __func__, ep->desc.bEndpointAddress); return -ENOMEM; -- cgit v1.1 From fccf4e86200b8f5edd9a65da26f150e32ba79808 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Sun, 5 Jun 2011 23:22:22 -0700 Subject: USB: Free bandwidth when usb_disable_device is called. Tanya ran into an issue when trying to switch a UAS device from the BOT configuration to the UAS configuration via the bConfigurationValue sysfs file. Before installing the UAS configuration, set_bConfigurationValue() calls usb_disable_device(). That function is supposed to remove all host controller resources associated with that device, but it leaves some state in the xHCI host controller. Commit 0791971ba8fbc44e4f476079f856335ed45e6324 usb: allow drivers to use allocated bandwidth until unbound added a call to usb_disable_device() in usb_set_configuration(), before the xHCI bandwidth functions were invoked. That commit fixed a bug, but also introduced a bug that is triggered when a configured device is switched to a new configuration. usb_disable_device() goes through all the motions of unbinding the drivers attached to active interfaces and removing the USB core structures associated with those interfaces, but it doesn't actually remove the endpoints from the internal xHCI host controller bandwidth structures. When usb_disable_device() calls usb_disable_endpoint() with reset_hardware set to true, the entries in udev->ep_out and udev->ep_in will be set to NULL. Usually, when the USB core installs a new configuration, usb_hcd_alloc_bandwidth() will drop all non-NULL endpoints in udev->ep_out and udev->ep_in before adding any new endpoints. However, when the new UAS configuration was added, all those entries were null, so none of the old endpoints in the BOT configuration were dropped. The xHCI driver blindly added the UAS configuration endpoints, and some of the endpoint addresses overlapped with the old BOT configuration endpoints. This caused the xHCI host to reject the Configure Endpoint command. Now that the xHCI driver code is cleaned up to reject a double-add of active endpoints, we need to fix the USB core to properly drop old endpoints in usb_disable_device(). If the host controller driver needs bandwidth checking support, make usb_disable_device() call usb_disable_endpoint() with reset_hardware set to false, drop the endpoints from the xHCI host controller, and then call usb_disable_endpoint() again with reset_hardware set to true. The first call to usb_disable_endpoint() will cancel any pending URBs and wait on them to be freed in usb_hcd_disable_endpoint(), but will keep the pointers in udev->ep_out and udev->ep in intact. Then usb_hcd_alloc_bandwidth() will use those pointers to know which endpoints to drop. The final call to usb_disable_endpoint() will do two things: 1. It will call usb_hcd_disable_endpoint() again, which should be harmless since the ep->urb_list should be empty after the first call to usb_disable_endpoint() returns. 2. It will set the entries in udev->ep_out and udev->ep in to NULL, and call usb_hcd_disable_endpoint(). That call will have no effect, since the xHCI driver doesn't set the endpoint_disable function pointer. Note that usb_disable_device() will now need to be called with hcd->bandwidth_mutex held. This should be backported to kernels as old as 2.6.32. Signed-off-by: Sarah Sharp Reported-by: Tanya Brokhman Cc: ablay@codeaurora.org Cc: Alan Stern Cc: stable@kernel.org --- drivers/usb/core/hub.c | 3 +++ drivers/usb/core/message.c | 15 ++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 90ae175..ca339bc 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1634,6 +1634,7 @@ void usb_disconnect(struct usb_device **pdev) { struct usb_device *udev = *pdev; int i; + struct usb_hcd *hcd = bus_to_hcd(udev->bus); if (!udev) { pr_debug ("%s nodev\n", __func__); @@ -1661,7 +1662,9 @@ void usb_disconnect(struct usb_device **pdev) * so that the hardware is now fully quiesced. */ dev_dbg (&udev->dev, "unregistering device\n"); + mutex_lock(hcd->bandwidth_mutex); usb_disable_device(udev, 0); + mutex_unlock(hcd->bandwidth_mutex); usb_hcd_synchronize_unlinks(udev); usb_remove_ep_devs(&udev->ep0); diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 5701e85..64c7ab4 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1135,10 +1135,13 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, * Deallocates hcd/hardware state for the endpoints (nuking all or most * pending urbs) and usbcore state for the interfaces, so that usbcore * must usb_set_configuration() before any interfaces could be used. + * + * Must be called with hcd->bandwidth_mutex held. */ void usb_disable_device(struct usb_device *dev, int skip_ep0) { int i; + struct usb_hcd *hcd = bus_to_hcd(dev->bus); /* getting rid of interfaces will disconnect * any drivers bound to them (a key side effect) @@ -1172,6 +1175,16 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, skip_ep0 ? "non-ep0" : "all"); + if (hcd->driver->check_bandwidth) { + /* First pass: Cancel URBs, leave endpoint pointers intact. */ + for (i = skip_ep0; i < 16; ++i) { + usb_disable_endpoint(dev, i, false); + usb_disable_endpoint(dev, i + USB_DIR_IN, false); + } + /* Remove endpoints from the host controller internal state */ + usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); + /* Second pass: remove endpoint pointers */ + } for (i = skip_ep0; i < 16; ++i) { usb_disable_endpoint(dev, i, true); usb_disable_endpoint(dev, i + USB_DIR_IN, true); @@ -1727,6 +1740,7 @@ free_interfaces: /* if it's already configured, clear out old state first. * getting rid of old interfaces means unbinding their drivers. */ + mutex_lock(hcd->bandwidth_mutex); if (dev->state != USB_STATE_ADDRESS) usb_disable_device(dev, 1); /* Skip ep0 */ @@ -1739,7 +1753,6 @@ free_interfaces: * host controller will not allow submissions to dropped endpoints. If * this call fails, the device state is unchanged. */ - mutex_lock(hcd->bandwidth_mutex); ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); if (ret < 0) { mutex_unlock(hcd->bandwidth_mutex); -- cgit v1.1 From d23336329fa4c157ed6256d4279a73b87486a1b6 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Mon, 6 Jun 2011 00:53:47 -0700 Subject: xhci: Don't warn about zeroed bMaxBurst descriptor field. The USB 3.0 specification says that the bMaxBurst field in the SuperSpeed Endpoint Companion descriptor is supposed to indicate how many packets a SS device can handle before it needs to wait for an explicit handshake from the host controller. A zero value means the device can only handle one packet before it needs a handshake. Remove a warning in the xHCI driver that implies this is an invalid value. Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-mem.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 0f8e1d2..fcb7f7e 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1215,8 +1215,6 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet)); /* dig out max burst from ep companion desc */ max_packet = ep->ss_ep_comp.bMaxBurst; - if (!max_packet) - xhci_warn(xhci, "WARN no SS endpoint bMaxBurst\n"); ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_packet)); break; case USB_SPEED_HIGH: -- cgit v1.1 From e1cf486d881d853d710e2d86a7adfc5fd260990f Mon Sep 17 00:00:00 2001 From: Alex He Date: Fri, 3 Jun 2011 15:58:25 +0800 Subject: xHCI 1.0: Force Stopped Event(FSE) FSE shall occur on the TD natural boundary. The software ep_ring dequeue pointer exceed the hardware ep_ring dequeue pointer in these cases of Table-3. As a result, the event_trb(pointed by hardware dequeue pointer) of the FSE can't be found in the current TD(pointed by software dequeue pointer). What should we do is to figured out the FSE case and skip over it. Signed-off-by: Alex He Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ring.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 800f417..0c00849 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2063,6 +2063,20 @@ static int handle_tx_event(struct xhci_hcd *xhci, /* Is this a TRB in the currently executing TD? */ event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue, td->last_trb, event_dma); + + /* + * Skip the Force Stopped Event. The event_trb(event_dma) of FSE + * is not in the current TD pointed by ep_ring->dequeue because + * that the hardware dequeue pointer still at the previous TRB + * of the current TD. The previous TRB maybe a Link TD or the + * last TRB of the previous TD. The command completion handle + * will take care the rest. + */ + if (!event_seg && trb_comp_code == COMP_STOP_INVAL) { + ret = 0; + goto cleanup; + } + if (!event_seg) { if (!ep->skip || !usb_endpoint_xfer_isoc(&td->urb->ep->desc)) { -- cgit v1.1 From 578333ab95f70db13951d30a9ad6b565b61639a9 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 15 Jun 2011 16:32:46 -0400 Subject: USB: change maintainership of ohci-hcd and ehci-hcd Following the loss of David Brownell, I volunteer to maintain the ohci-hcd and ehci-hcd drivers. This patch (as1472) makes it official. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 4 ++++ drivers/usb/host/ohci-hcd.c | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index b435ed6..f8030ee 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1,4 +1,8 @@ /* + * Enhanced Host Controller Interface (EHCI) driver for USB. + * + * Maintainer: Alan Stern + * * Copyright (c) 2000-2004 by David Brownell * * This program is free software; you can redistribute it and/or modify it diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 9aa10bd..f9cf3f0 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1,5 +1,7 @@ /* - * OHCI HCD (Host Controller Driver) for USB. + * Open Host Controller Interface (OHCI) driver for USB. + * + * Maintainer: Alan Stern * * (C) Copyright 1999 Roman Weissgaerber * (C) Copyright 2000-2004 David Brownell -- cgit v1.1 From cbb330045e5df8f665ac60227ff898421fc8fb92 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 15 Jun 2011 16:29:16 -0400 Subject: USB: don't let the hub driver prevent system sleep This patch (as1465) continues implementation of the policy that errors during suspend or hibernation should not prevent the system from going to sleep. In this case, failure to turn on the Suspend feature for a hub port shouldn't be reported as an error. There are situations where this does actually occur (such as when the device plugged into that port was disconnected in the recent past), and it turns out to be harmless. There's no reason for it to prevent a system sleep. Also, don't allow the hub driver to fail a system suspend if the downstream ports aren't all suspended. This is also harmless (and should never happen, given the change mentioned above); printing a warning message in the kernel log is all we really need to do. Signed-off-by: Alan Stern CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 90ae175..c2ac087 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2362,6 +2362,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) USB_DEVICE_REMOTE_WAKEUP, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); + + /* System sleep transitions should never fail */ + if (!(msg.event & PM_EVENT_AUTO)) + status = 0; } else { /* device has up to 10 msec to fully suspend */ dev_dbg(&udev->dev, "usb %ssuspend\n", @@ -2611,16 +2615,15 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) struct usb_device *hdev = hub->hdev; unsigned port1; - /* fail if children aren't already suspended */ + /* Warn if children aren't already suspended */ for (port1 = 1; port1 <= hdev->maxchild; port1++) { struct usb_device *udev; udev = hdev->children [port1-1]; if (udev && udev->can_submit) { - if (!(msg.event & PM_EVENT_AUTO)) - dev_dbg(&intf->dev, "port %d nyet suspended\n", - port1); - return -EBUSY; + dev_warn(&intf->dev, "port %d nyet suspended\n", port1); + if (msg.event & PM_EVENT_AUTO) + return -EBUSY; } } -- cgit v1.1 From 0af212ba8f123c2eba151af7726c34a50b127962 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 15 Jun 2011 16:27:43 -0400 Subject: USB: don't let errors prevent system sleep This patch (as1464) implements the recommended policy that most errors during suspend or hibernation should not prevent the system from going to sleep. In particular, failure to suspend a USB driver or a USB device should not prevent the sleep from succeeding: Failure to suspend a device won't matter, because the device will automatically go into suspend mode when the USB bus stops carrying packets. (This might be less true for USB-3.0 devices, but let's not worry about them now.) Failure of a driver to suspend might lead to trouble later on when the system wakes up, but it isn't sufficient reason to prevent the system from going to sleep. Signed-off-by: Alan Stern CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index e35a176..81add81 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1187,13 +1187,22 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) for (i = n - 1; i >= 0; --i) { intf = udev->actconfig->interface[i]; status = usb_suspend_interface(udev, intf, msg); + + /* Ignore errors during system sleep transitions */ + if (!(msg.event & PM_EVENT_AUTO)) + status = 0; if (status != 0) break; } } - if (status == 0) + if (status == 0) { status = usb_suspend_device(udev, msg); + /* Again, ignore errors during system sleep transitions */ + if (!(msg.event & PM_EVENT_AUTO)) + status = 0; + } + /* If the suspend failed, resume interfaces that did get suspended */ if (status != 0) { msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME); -- cgit v1.1 From 7263287af93db4d5cf324a30546f2143419b7900 Mon Sep 17 00:00:00 2001 From: Russ Gorby Date: Tue, 14 Jun 2011 13:23:28 -0700 Subject: tty: n_gsm: Fixed logic to decode break signal from modem status The modem status can be one or 2 octets and contains the V.24 signals and in the 2 octet case also the break signal. We were improperly decoding the break signal from the modem in the 2 octet case. Signed-off-by: Russ Gorby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 09e8c7d..7290394 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -984,10 +984,22 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, u8 *data, */ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, - u32 modem) + u32 modem, int clen) { int mlines = 0; - u8 brk = modem >> 6; + u8 brk = 0; + + /* The modem status command can either contain one octet (v.24 signals) + or two octets (v.24 signals + break signals). The length field will + either be 2 or 3 respectively. This is specified in section + 5.4.6.3.7 of the 27.010 mux spec. */ + + if (clen == 2) + modem = modem & 0x7f; + else { + brk = modem & 0x7f; + modem = (modem >> 7) & 0x7f; + }; /* Flow control/ready to communicate */ if (modem & MDM_FC) { @@ -1061,7 +1073,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen) return; } tty = tty_port_tty_get(&dlci->port); - gsm_process_modem(tty, dlci, modem); + gsm_process_modem(tty, dlci, modem, clen); if (tty) { tty_wakeup(tty); tty_kref_put(tty); @@ -1482,12 +1494,13 @@ static void gsm_dlci_begin_close(struct gsm_dlci *dlci) * open we shovel the bits down it, if not we drop them. */ -static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int len) +static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int clen) { /* krefs .. */ struct tty_port *port = &dlci->port; struct tty_struct *tty = tty_port_tty_get(port); unsigned int modem = 0; + int len = clen; if (debug & 16) pr_debug("%d bytes for tty %p\n", len, tty); @@ -1507,7 +1520,7 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int len) if (len == 0) return; } - gsm_process_modem(tty, dlci, modem); + gsm_process_modem(tty, dlci, modem, clen); /* Line state will go via DLCI 0 controls only */ case 1: default: -- cgit v1.1 From 57f2104f39995bac332ddc492fbf60aa28e0c35e Mon Sep 17 00:00:00 2001 From: Russ Gorby Date: Tue, 14 Jun 2011 13:23:29 -0700 Subject: tty: n_gsm: improper skb_pull() use was leaking framed data gsm_dlci_data_output_framed() was doing: memcpy(dp, skb_pull(dlci->skb, len), len); The problem is skb_pull() returns the post-increment data ptr so the first chunk of dlci->skb->data is leaked. Signed-off-by: Russ Gorby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 7290394..19b4ae0 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -875,7 +875,8 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, *dp++ = last << 7 | first << 6 | 1; /* EA */ len--; } - memcpy(dp, skb_pull(dlci->skb, len), len); + memcpy(dp, dlci->skb->data, len); + skb_pull(dlci->skb, len); __gsm_data_queue(dlci, msg); if (last) dlci->skb = NULL; -- cgit v1.1 From c16d51a32bbb61ac8fd96f78b5ce2fccfe0fb4c3 Mon Sep 17 00:00:00 2001 From: Shreshtha Kumar Sahu Date: Mon, 13 Jun 2011 10:11:33 +0200 Subject: amba pl011: workaround for uart registers lockup This workaround aims to break the deadlock situation which raises during continuous transfer of data for long duration over uart with hardware flow control. It is observed that CTS interrupt cannot be cleared in uart interrupt register (ICR). Hence further transfer over uart gets blocked. It is seen that during such deadlock condition ICR don't get cleared even on multiple write. This leads pass_counter to decrease and finally reach zero. This can be taken as trigger point to run this UART_BT_WA. Workaround backups the register configuration, does soft reset of UART using BIT-0 of PRCC_K_SOFTRST_SET/CLEAR registers and restores the registers. This patch also provides support for uart init and exit function calls if present. Signed-off-by: Shreshtha Kumar Sahu Signed-off-by: Linus Walleij Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 123 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 8dc0541..f5f6831 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -65,6 +66,30 @@ #define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE) #define UART_DUMMY_DR_RX (1 << 16) + +#define UART_WA_SAVE_NR 14 + +static void pl011_lockup_wa(unsigned long data); +static const u32 uart_wa_reg[UART_WA_SAVE_NR] = { + ST_UART011_DMAWM, + ST_UART011_TIMEOUT, + ST_UART011_LCRH_RX, + UART011_IBRD, + UART011_FBRD, + ST_UART011_LCRH_TX, + UART011_IFLS, + ST_UART011_XFCR, + ST_UART011_XON1, + ST_UART011_XON2, + ST_UART011_XOFF1, + ST_UART011_XOFF2, + UART011_CR, + UART011_IMSC +}; + +static u32 uart_wa_regdata[UART_WA_SAVE_NR]; +static DECLARE_TASKLET(pl011_lockup_tlet, pl011_lockup_wa, 0); + /* There is by now at least one vendor with differing details, so handle it */ struct vendor_data { unsigned int ifls; @@ -72,6 +97,7 @@ struct vendor_data { unsigned int lcrh_tx; unsigned int lcrh_rx; bool oversampling; + bool interrupt_may_hang; /* vendor-specific */ bool dma_threshold; }; @@ -90,9 +116,12 @@ static struct vendor_data vendor_st = { .lcrh_tx = ST_UART011_LCRH_TX, .lcrh_rx = ST_UART011_LCRH_RX, .oversampling = true, + .interrupt_may_hang = true, .dma_threshold = true, }; +static struct uart_amba_port *amba_ports[UART_NR]; + /* Deals with DMA transactions */ struct pl011_sgbuf { @@ -132,6 +161,7 @@ struct uart_amba_port { unsigned int lcrh_rx; /* vendor-specific */ bool autorts; char type[12]; + bool interrupt_may_hang; /* vendor-specific */ #ifdef CONFIG_DMA_ENGINE /* DMA stuff */ bool using_tx_dma; @@ -1008,6 +1038,68 @@ static inline bool pl011_dma_rx_running(struct uart_amba_port *uap) #endif +/* + * pl011_lockup_wa + * This workaround aims to break the deadlock situation + * when after long transfer over uart in hardware flow + * control, uart interrupt registers cannot be cleared. + * Hence uart transfer gets blocked. + * + * It is seen that during such deadlock condition ICR + * don't get cleared even on multiple write. This leads + * pass_counter to decrease and finally reach zero. This + * can be taken as trigger point to run this UART_BT_WA. + * + */ +static void pl011_lockup_wa(unsigned long data) +{ + struct uart_amba_port *uap = amba_ports[0]; + void __iomem *base = uap->port.membase; + struct circ_buf *xmit = &uap->port.state->xmit; + struct tty_struct *tty = uap->port.state->port.tty; + int buf_empty_retries = 200; + int loop; + + /* Stop HCI layer from submitting data for tx */ + tty->hw_stopped = 1; + while (!uart_circ_empty(xmit)) { + if (buf_empty_retries-- == 0) + break; + udelay(100); + } + + /* Backup registers */ + for (loop = 0; loop < UART_WA_SAVE_NR; loop++) + uart_wa_regdata[loop] = readl(base + uart_wa_reg[loop]); + + /* Disable UART so that FIFO data is flushed out */ + writew(0x00, uap->port.membase + UART011_CR); + + /* Soft reset UART module */ + if (uap->port.dev->platform_data) { + struct amba_pl011_data *plat; + + plat = uap->port.dev->platform_data; + if (plat->reset) + plat->reset(); + } + + /* Restore registers */ + for (loop = 0; loop < UART_WA_SAVE_NR; loop++) + writew(uart_wa_regdata[loop] , + uap->port.membase + uart_wa_reg[loop]); + + /* Initialise the old status of the modem signals */ + uap->old_status = readw(uap->port.membase + UART01x_FR) & + UART01x_FR_MODEM_ANY; + + if (readl(base + UART011_MIS) & 0x2) + printk(KERN_EMERG "UART_BT_WA: ***FAILED***\n"); + + /* Start Tx/Rx */ + tty->hw_stopped = 0; +} + static void pl011_stop_tx(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; @@ -1158,8 +1250,11 @@ static irqreturn_t pl011_int(int irq, void *dev_id) if (status & UART011_TXIS) pl011_tx_chars(uap); - if (pass_counter-- == 0) + if (pass_counter-- == 0) { + if (uap->interrupt_may_hang) + tasklet_schedule(&pl011_lockup_tlet); break; + } status = readw(uap->port.membase + UART011_MIS); } while (status != 0); @@ -1339,6 +1434,14 @@ static int pl011_startup(struct uart_port *port) writew(uap->im, uap->port.membase + UART011_IMSC); spin_unlock_irq(&uap->port.lock); + if (uap->port.dev->platform_data) { + struct amba_pl011_data *plat; + + plat = uap->port.dev->platform_data; + if (plat->init) + plat->init(); + } + return 0; clk_dis: @@ -1394,6 +1497,15 @@ static void pl011_shutdown(struct uart_port *port) * Shut down the clock producer */ clk_disable(uap->clk); + + if (uap->port.dev->platform_data) { + struct amba_pl011_data *plat; + + plat = uap->port.dev->platform_data; + if (plat->exit) + plat->exit(); + } + } static void @@ -1700,6 +1812,14 @@ static int __init pl011_console_setup(struct console *co, char *options) if (!uap) return -ENODEV; + if (uap->port.dev->platform_data) { + struct amba_pl011_data *plat; + + plat = uap->port.dev->platform_data; + if (plat->init) + plat->init(); + } + uap->port.uartclk = clk_get_rate(uap->clk); if (options) @@ -1774,6 +1894,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) uap->lcrh_rx = vendor->lcrh_rx; uap->lcrh_tx = vendor->lcrh_tx; uap->fifosize = vendor->fifosize; + uap->interrupt_may_hang = vendor->interrupt_may_hang; uap->port.dev = &dev->dev; uap->port.mapbase = dev->res.start; uap->port.membase = base; -- cgit v1.1 From 3bc46b312b1486b1fe2db4246a34a30160d26d8d Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Fri, 10 Jun 2011 23:17:58 +0200 Subject: serial: bcm63xx_uart: fix irq storm after rx fifo overrun. RX fifo reset is required to clear irq. Signed-off-by: Maxime Bizon Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bcm63xx_uart.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index a1a0e55..c0b68b9 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -250,6 +250,20 @@ static void bcm_uart_do_rx(struct uart_port *port) /* get overrun/fifo empty information from ier * register */ iestat = bcm_uart_readl(port, UART_IR_REG); + + if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) { + unsigned int val; + + /* fifo reset is required to clear + * interrupt */ + val = bcm_uart_readl(port, UART_CTL_REG); + val |= UART_CTL_RSTRXFIFO_MASK; + bcm_uart_writel(port, val, UART_CTL_REG); + + port->icount.overrun++; + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } + if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY))) break; @@ -284,10 +298,6 @@ static void bcm_uart_do_rx(struct uart_port *port) if (uart_handle_sysrq_char(port, c)) continue; - if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) { - port->icount.overrun++; - tty_insert_flip_char(tty, 0, TTY_OVERRUN); - } if ((cstat & port->ignore_status_mask) == 0) tty_insert_flip_char(tty, c, flag); -- cgit v1.1 From f6ba6fe2d913da6707a71a413d6ec8ae98d6ce18 Mon Sep 17 00:00:00 2001 From: Alex He Date: Wed, 8 Jun 2011 18:34:06 +0800 Subject: xHCI 1.0: Incompatible Device Error It is one new TRB Completion Code for the xHCI spec v1.0. Asserted if the xHC detects a problem with a device that does not allow it to be successfully accessed, e.g. due to a device compliance or compatibility problem. This error may be returned by any command or transfer, and is fatal as far as the Slot is concerned. Return -EPROTO by urb->status or frame->status of ISOC for transfer case. And return -ENODEV for configure endpoint command, evaluate context command and address device command if there is an incompatible Device Error. The error codes will be sent back to the USB core to decide how to do. It's unnecessary for other commands because after the three commands run successfully means that the device has been accepted. Signed-off-by: Alex He Signed-off-by: Sarah Sharp --- drivers/usb/host/xhci-ring.c | 5 +++++ drivers/usb/host/xhci.c | 15 +++++++++++++++ drivers/usb/host/xhci.h | 2 ++ 3 files changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 0c00849..436332a 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1733,6 +1733,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, frame->status = -EOVERFLOW; skip_td = true; break; + case COMP_DEV_ERR: case COMP_STALL: frame->status = -EPROTO; skip_td = true; @@ -2016,6 +2017,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, TRB_TO_SLOT_ID(le32_to_cpu(event->flags)), ep_index); goto cleanup; + case COMP_DEV_ERR: + xhci_warn(xhci, "WARN: detect an incompatible device"); + status = -EPROTO; + break; case COMP_MISSED_INT: /* * When encounter missed service error, one or more isoc tds diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index e5a0171..15eb4c3 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1551,6 +1551,11 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci, "and endpoint is not disabled.\n"); ret = -EINVAL; break; + case COMP_DEV_ERR: + dev_warn(&udev->dev, "ERROR: Incompatible device for endpoint " + "configure command.\n"); + ret = -ENODEV; + break; case COMP_SUCCESS: dev_dbg(&udev->dev, "Successful Endpoint Configure command\n"); ret = 0; @@ -1585,6 +1590,11 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci, xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1); ret = -EINVAL; break; + case COMP_DEV_ERR: + dev_warn(&udev->dev, "ERROR: Incompatible device for evaluate " + "context command.\n"); + ret = -ENODEV; + break; case COMP_MEL_ERR: /* Max Exit Latency too large error */ dev_warn(&udev->dev, "WARN: Max Exit Latency too large\n"); @@ -2867,6 +2877,11 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) dev_warn(&udev->dev, "Device not responding to set address.\n"); ret = -EPROTO; break; + case COMP_DEV_ERR: + dev_warn(&udev->dev, "ERROR: Incompatible device for address " + "device command.\n"); + ret = -ENODEV; + break; case COMP_SUCCESS: xhci_dbg(xhci, "Successful Address Device command\n"); break; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 7d1ea3b..ba90af1 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -874,6 +874,8 @@ struct xhci_transfer_event { #define COMP_PING_ERR 20 /* Event Ring is full */ #define COMP_ER_FULL 21 +/* Incompatible Device Error */ +#define COMP_DEV_ERR 22 /* Missed Service Error - HC couldn't service an isoc ep within interval */ #define COMP_MISSED_INT 23 /* Successfully stopped command ring */ -- cgit v1.1 From c877b3b2ad5cb9d4fe523c5496185cc328ff3ae9 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Wed, 15 Jun 2011 23:47:21 +0200 Subject: xhci: Add reset on resume quirk for asrock p67 host The asrock p67 xhci controller completely dies on resume, add a quirk for this, to bring the host back online after a suspend. This should be backported to stable kernels as old as 2.6.37. Signed-off-by: Maarten Lankhorst Signed-off-by: Sarah Sharp Cc: stable@kernel.org --- drivers/usb/host/xhci-pci.c | 8 ++++++++ drivers/usb/host/xhci.c | 2 ++ drivers/usb/host/xhci.h | 1 + 3 files changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 17541d0..cb16de2 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -29,6 +29,9 @@ #define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73 #define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000 +#define PCI_VENDOR_ID_ETRON 0x1b6f +#define PCI_DEVICE_ID_ASROCK_P67 0x7023 + static const char hcd_name[] = "xhci_hcd"; /* called after powerup, by probe or system-pm "wakeup" */ @@ -134,6 +137,11 @@ static int xhci_pci_setup(struct usb_hcd *hcd) xhci->quirks |= XHCI_EP_LIMIT_QUIRK; xhci->limit_active_eps = 64; } + if (pdev->vendor == PCI_VENDOR_ID_ETRON && + pdev->device == PCI_DEVICE_ID_ASROCK_P67) { + xhci->quirks |= XHCI_RESET_ON_RESUME; + xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); + } /* Make sure the HC is halted. */ retval = xhci_halt(xhci); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 15eb4c3..f5fe1ac 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -759,6 +759,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) msleep(100); spin_lock_irq(&xhci->lock); + if (xhci->quirks & XHCI_RESET_ON_RESUME) + hibernated = true; if (!hibernated) { /* step 1: restore register */ diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index ba90af1..d8bbf5c 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1310,6 +1310,7 @@ struct xhci_hcd { */ #define XHCI_EP_LIMIT_QUIRK (1 << 5) #define XHCI_BROKEN_MSI (1 << 6) +#define XHCI_RESET_ON_RESUME (1 << 7) unsigned int num_active_eps; unsigned int limit_active_eps; /* There are two roothubs to keep track of bus suspend info for */ -- cgit v1.1 From b3df3f9c7df9a8d85e03e158d35487618a160901 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 15 Jun 2011 19:57:46 -0700 Subject: xhci: Always set urb->status to zero for isoc endpoints. When the xHCI driver encounters a Missed Service Interval event for an isochronous endpoint ring, it means the host controller skipped over one or more isochronous TDs. For TD that is skipped, skip_isoc_td() is called. This sets the frame descriptor status to -EXDEV, and also sets the value stored in the int pointed to by status to -EXDEV. If the isochronous TD happens to be the last TD in an URB, handle_tx_event() will use the status variable to give back the URB to the USB core. That means drivers will see urb->status as -EXDEV. It turns out that EHCI, UHCI, and OHCI always set urb->status to zero for an isochronous urb, regardless of what the frame status is. See itd_complete() in ehci-sched.c: } else { /* URB was too late */ desc->status = -EXDEV; } } /* handle completion now? */ if (likely ((urb_index + 1) != urb->number_of_packets)) goto done; /* ASSERT: it's really the last itd for this urb list_for_each_entry (itd, &stream->td_list, itd_list) BUG_ON (itd->urb == urb); */ /* give urb back to the driver; completion often (re)submits */ dev = urb->dev; ehci_urb_done(ehci, urb, 0); ehci_urb_done() completes the URB with the status of the third argument, which is always zero in this case. It turns out that many USB webcam drivers, such as uvcvideo, cannot handle urb->status set to a non-zero value. They will not resubmit their isochronous URBs in that case, and userspace will see a frozen video. Change the xHCI driver to be consistent with the EHCI and UHCI driver, and always set urb->status to 0 for isochronous URBs. This patch should be backported to kernels as old as 2.6.36 Signed-off-by: Sarah Sharp Cc: "Xu, Andiry" Cc: stable@kernel.org --- drivers/usb/host/xhci-ring.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 436332a..70cacbb 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1768,9 +1768,6 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, } } - if ((idx == urb_priv->length - 1) && *status == -EINPROGRESS) - *status = 0; - return finish_td(xhci, td, event_trb, event, ep, status, false); } @@ -1788,8 +1785,7 @@ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, idx = urb_priv->td_cnt; frame = &td->urb->iso_frame_desc[idx]; - /* The transfer is partly done */ - *status = -EXDEV; + /* The transfer is partly done. */ frame->status = -EXDEV; /* calc actual length */ @@ -2177,6 +2173,11 @@ cleanup: urb->transfer_buffer_length, status); spin_unlock(&xhci->lock); + /* EHCI, UHCI, and OHCI always unconditionally set the + * urb->status of an isochronous endpoint to 0. + */ + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) + status = 0; usb_hcd_giveback_urb(bus_to_hcd(urb->dev->bus), urb, status); spin_lock(&xhci->lock); } -- cgit v1.1 From 2ff7d09a1b0f20f2d9c1bde0e003d4e384de2313 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Wed, 1 Jun 2011 17:49:14 +0000 Subject: RDMA/cxgb4: Don't exceed hw IQ depth limit for user CQs Memory allocated for user CQs gets rounded up to the next page boundary. And after rounding, we recalculate the resulting IQ depth and we need to make sure we don't exceed the HW limits. This bug can result a much smaller CQ allocated than was expected if the HW size field is exceeded, resulting in CQ overflow failures. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/cq.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index 8d8f8ad..1720dc7 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c @@ -801,6 +801,10 @@ struct ib_cq *c4iw_create_cq(struct ib_device *ibdev, int entries, if (ucontext) { memsize = roundup(memsize, PAGE_SIZE); hwentries = memsize / sizeof *chp->cq.queue; + while (hwentries > T4_MAX_IQ_SIZE) { + memsize -= PAGE_SIZE; + hwentries = memsize / sizeof *chp->cq.queue; + } } chp->cq.size = hwentries; chp->cq.memsize = memsize; -- cgit v1.1 From 301c2c3f039a1f9478f6cbef60f2ccd4da9bd4a1 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Tue, 14 Jun 2011 20:59:21 +0000 Subject: RDMA/cxgb4: Don't truncate MR lengths Remove left-over code from T3 that limited MR sizes to 32b. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index 273ffe4..0347eed 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c @@ -625,7 +625,7 @@ pbl_done: mhp->attr.perms = c4iw_ib_to_tpt_access(acc); mhp->attr.va_fbo = virt; mhp->attr.page_size = shift - 12; - mhp->attr.len = (u32) length; + mhp->attr.len = length; err = register_mem(rhp, php, mhp, shift); if (err) -- cgit v1.1 From 8da7e7a55231543b84ac84e93ad5ca9d340773d7 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Tue, 14 Jun 2011 20:59:27 +0000 Subject: RDMA/cxgb4: Couple of abort fixes - fix a race where the driver could end up sending a close_con_req after an abort_rpl. In c4iw_ep_disconnect(), send abort or close request with the ep mutex held. - fix a hang where driver fails to wake up when a connection is reset during a normal close. Wake up any waiters in the interrupt path, and correctly cleanup after rdma_fini() failures. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/cm.c | 46 ++++++++++++++++++++++++++++++++-------- drivers/infiniband/hw/cxgb4/qp.c | 5 +---- 2 files changed, 38 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index f660cd0..31fb440 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -1463,9 +1463,9 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) struct c4iw_qp_attributes attrs; int disconnect = 1; int release = 0; - int abort = 0; struct tid_info *t = dev->rdev.lldi.tids; unsigned int tid = GET_TID(hdr); + int ret; ep = lookup_tid(t, tid); PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); @@ -1501,10 +1501,12 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) start_ep_timer(ep); __state_set(&ep->com, CLOSING); attrs.next_state = C4IW_QP_STATE_CLOSING; - abort = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, + ret = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); - peer_close_upcall(ep); - disconnect = 1; + if (ret != -ECONNRESET) { + peer_close_upcall(ep); + disconnect = 1; + } break; case ABORTING: disconnect = 0; @@ -2109,15 +2111,16 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp) break; } - mutex_unlock(&ep->com.mutex); if (close) { - if (abrupt) - ret = abort_connection(ep, NULL, gfp); - else + if (abrupt) { + close_complete_upcall(ep); + ret = send_abort(ep, NULL, gfp); + } else ret = send_halfclose(ep, gfp); if (ret) fatal = 1; } + mutex_unlock(&ep->com.mutex); if (fatal) release_ep_resources(ep); return ret; @@ -2301,6 +2304,31 @@ static int fw6_msg(struct c4iw_dev *dev, struct sk_buff *skb) return 0; } +static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb) +{ + struct cpl_abort_req_rss *req = cplhdr(skb); + struct c4iw_ep *ep; + struct tid_info *t = dev->rdev.lldi.tids; + unsigned int tid = GET_TID(req); + + ep = lookup_tid(t, tid); + if (is_neg_adv_abort(req->status)) { + PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep, + ep->hwtid); + kfree_skb(skb); + return 0; + } + PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid, + ep->com.state); + + /* + * Wake up any threads in rdma_init() or rdma_fini(). + */ + c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET); + sched(dev, skb); + return 0; +} + /* * Most upcalls from the T4 Core go to sched() to * schedule the processing on a work queue. @@ -2317,7 +2345,7 @@ c4iw_handler_func c4iw_handlers[NUM_CPL_CMDS] = { [CPL_PASS_ESTABLISH] = sched, [CPL_PEER_CLOSE] = sched, [CPL_CLOSE_CON_RPL] = sched, - [CPL_ABORT_REQ_RSS] = sched, + [CPL_ABORT_REQ_RSS] = peer_abort_intr, [CPL_RDMA_TERMINATE] = sched, [CPL_FW4_ACK] = sched, [CPL_SET_TCB_RPL] = set_tcb_rpl, diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 3b773b0..a41578e 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -1207,11 +1207,8 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, c4iw_get_ep(&qhp->ep->com); } ret = rdma_fini(rhp, qhp, ep); - if (ret) { - if (internal) - c4iw_get_ep(&qhp->ep->com); + if (ret) goto err; - } break; case C4IW_QP_STATE_TERMINATE: set_state(qhp, C4IW_QP_STATE_TERMINATE); -- cgit v1.1 From 3126448451105fae59de0058c68692aa09aa4c37 Mon Sep 17 00:00:00 2001 From: Mitko Haralanov Date: Thu, 9 Jun 2011 20:27:26 +0000 Subject: IB/qib: Ensure that LOS and DFE are being turned off Due to timing, it is possible for the LOS and DFE to remain on. This is due to the link progressing to LinkUP prior to the driver getting the first Status Changed interrupt. By expanding the conditions under which LOS is turned off and DFE timeout is being set, timing is no longer an issue. Signed-off-by: Mitko Haralanov Signed-off-by: Mike Marciniszyn Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_iba7322.c | 25 ++++++++++++++++++------- drivers/infiniband/hw/qib/qib_intr.c | 6 +++++- 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 9f53e68..8ec5237 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c @@ -469,6 +469,8 @@ static u8 ib_rate_to_delay[IB_RATE_120_GBPS + 1] = { #define IB_7322_LT_STATE_RECOVERIDLE 0x0f #define IB_7322_LT_STATE_CFGENH 0x10 #define IB_7322_LT_STATE_CFGTEST 0x11 +#define IB_7322_LT_STATE_CFGWAITRMTTEST 0x12 +#define IB_7322_LT_STATE_CFGWAITENH 0x13 /* link state machine states from IBC */ #define IB_7322_L_STATE_DOWN 0x0 @@ -498,8 +500,10 @@ static const u8 qib_7322_physportstate[0x20] = { IB_PHYSPORTSTATE_LINK_ERR_RECOVER, [IB_7322_LT_STATE_CFGENH] = IB_PHYSPORTSTATE_CFG_ENH, [IB_7322_LT_STATE_CFGTEST] = IB_PHYSPORTSTATE_CFG_TRAIN, - [0x12] = IB_PHYSPORTSTATE_CFG_TRAIN, - [0x13] = IB_PHYSPORTSTATE_CFG_WAIT_ENH, + [IB_7322_LT_STATE_CFGWAITRMTTEST] = + IB_PHYSPORTSTATE_CFG_TRAIN, + [IB_7322_LT_STATE_CFGWAITENH] = + IB_PHYSPORTSTATE_CFG_WAIT_ENH, [0x14] = IB_PHYSPORTSTATE_CFG_TRAIN, [0x15] = IB_PHYSPORTSTATE_CFG_TRAIN, [0x16] = IB_PHYSPORTSTATE_CFG_TRAIN, @@ -1692,7 +1696,9 @@ static void handle_serdes_issues(struct qib_pportdata *ppd, u64 ibcst) break; } - if (ibclt == IB_7322_LT_STATE_CFGTEST && + if (((ibclt >= IB_7322_LT_STATE_CFGTEST && + ibclt <= IB_7322_LT_STATE_CFGWAITENH) || + ibclt == IB_7322_LT_STATE_LINKUP) && (ibcst & SYM_MASK(IBCStatusA_0, LinkSpeedQDR))) { force_h1(ppd); ppd->cpspec->qdr_reforce = 1; @@ -7301,12 +7307,17 @@ static void ibsd_wr_allchans(struct qib_pportdata *ppd, int addr, unsigned data, static void serdes_7322_los_enable(struct qib_pportdata *ppd, int enable) { u64 data = qib_read_kreg_port(ppd, krp_serdesctrl); - printk(KERN_INFO QIB_DRV_NAME " IB%u:%u Turning LOS %s\n", - ppd->dd->unit, ppd->port, (enable ? "on" : "off")); - if (enable) + u8 state = SYM_FIELD(data, IBSerdesCtrl_0, RXLOSEN); + + if (enable && !state) { + printk(KERN_INFO QIB_DRV_NAME " IB%u:%u Turning LOS on\n", + ppd->dd->unit, ppd->port); data |= SYM_MASK(IBSerdesCtrl_0, RXLOSEN); - else + } else if (!enable && state) { + printk(KERN_INFO QIB_DRV_NAME " IB%u:%u Turning LOS off\n", + ppd->dd->unit, ppd->port); data &= ~SYM_MASK(IBSerdesCtrl_0, RXLOSEN); + } qib_write_kreg_port(ppd, krp_serdesctrl, data); } diff --git a/drivers/infiniband/hw/qib/qib_intr.c b/drivers/infiniband/hw/qib/qib_intr.c index a693c56..6ae57d2 100644 --- a/drivers/infiniband/hw/qib/qib_intr.c +++ b/drivers/infiniband/hw/qib/qib_intr.c @@ -96,8 +96,12 @@ void qib_handle_e_ibstatuschanged(struct qib_pportdata *ppd, u64 ibcs) * states, or if it transitions from any of the up (INIT or better) * states into any of the down states (except link recovery), then * call the chip-specific code to take appropriate actions. + * + * ppd->lflags could be 0 if this is the first time the interrupt + * handlers has been called but the link is already up. */ - if (lstate >= IB_PORT_INIT && (ppd->lflags & QIBL_LINKDOWN) && + if (lstate >= IB_PORT_INIT && + (!ppd->lflags || (ppd->lflags & QIBL_LINKDOWN)) && ltstate == IB_PHYSPORTSTATE_LINKUP) { /* transitioned to UP */ if (dd->f_ib_updown(ppd, 1, ibcs)) -- cgit v1.1 From c44048dea28b3febd38417f36f7b2924d93f9bb2 Mon Sep 17 00:00:00 2001 From: Chris Ball Date: Thu, 26 May 2011 23:15:49 -0400 Subject: mmc: vub300: fix null dereferences in error handling Reported-by: Dan Carpenter Signed-off-by: Chris Ball --- drivers/mmc/host/vub300.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c index cbb0330..d4455ff 100644 --- a/drivers/mmc/host/vub300.c +++ b/drivers/mmc/host/vub300.c @@ -2096,7 +2096,7 @@ static struct mmc_host_ops vub300_mmc_ops = { static int vub300_probe(struct usb_interface *interface, const struct usb_device_id *id) { /* NOT irq */ - struct vub300_mmc_host *vub300 = NULL; + struct vub300_mmc_host *vub300; struct usb_host_interface *iface_desc; struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface)); int i; @@ -2118,23 +2118,20 @@ static int vub300_probe(struct usb_interface *interface, command_out_urb = usb_alloc_urb(0, GFP_KERNEL); if (!command_out_urb) { retval = -ENOMEM; - dev_err(&vub300->udev->dev, - "not enough memory for the command_out_urb\n"); + dev_err(&udev->dev, "not enough memory for command_out_urb\n"); goto error0; } command_res_urb = usb_alloc_urb(0, GFP_KERNEL); if (!command_res_urb) { retval = -ENOMEM; - dev_err(&vub300->udev->dev, - "not enough memory for the command_res_urb\n"); + dev_err(&udev->dev, "not enough memory for command_res_urb\n"); goto error1; } /* this also allocates memory for our VUB300 mmc host device */ mmc = mmc_alloc_host(sizeof(struct vub300_mmc_host), &udev->dev); if (!mmc) { retval = -ENOMEM; - dev_err(&vub300->udev->dev, - "not enough memory for the mmc_host\n"); + dev_err(&udev->dev, "not enough memory for the mmc_host\n"); goto error4; } /* MMC core transfer sizes tunable parameters */ -- cgit v1.1 From b9c350a0a9d3564d20f5301f472b8841f8934c7d Mon Sep 17 00:00:00 2001 From: Wanlong Gao Date: Tue, 24 May 2011 21:03:22 +0800 Subject: mmc: of_mmc_spi: add NO_IRQ define to of_mmc_spi.c Provide a dummy value of NO_IRQ for architectures that don't support it (such as MIPS). Fixes the build error for MIPS. Signed-off-by: Wanlong Gao Acked-by: Grant Likely Signed-off-by: Chris Ball --- drivers/mmc/host/of_mmc_spi.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c index e2aecb7..ab66f24 100644 --- a/drivers/mmc/host/of_mmc_spi.c +++ b/drivers/mmc/host/of_mmc_spi.c @@ -25,6 +25,11 @@ #include #include +/* For archs that don't support NO_IRQ (such as mips), provide a dummy value */ +#ifndef NO_IRQ +#define NO_IRQ 0 +#endif + MODULE_LICENSE("GPL"); enum { -- cgit v1.1 From 742a0c7cae9bd0f913c71722289b8ec862d70a2b Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 27 May 2011 16:54:05 +0200 Subject: mmc: sdhi: fix module unloading MMC host drivers must be able to process interrupts during mmc_remove_host(). Signed-off-by: Guennadi Liakhovetski Signed-off-by: Chris Ball --- drivers/mmc/host/sh_mobile_sdhi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index b365429..2353bb7 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -165,13 +165,14 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev) p->pdata = NULL; + tmio_mmc_host_remove(host); + for (i = 0; i < 3; i++) { irq = platform_get_irq(pdev, i); if (irq >= 0) free_irq(irq, host); } - tmio_mmc_host_remove(host); clk_disable(priv->clk); clk_put(priv->clk); kfree(priv); -- cgit v1.1 From be98ca652faa6468916a9b7608befff215a8ca70 Mon Sep 17 00:00:00 2001 From: Manoj Iyer Date: Thu, 26 May 2011 11:19:05 -0500 Subject: mmc: Add PCI fixup quirks for Ricoh 1180:e823 reader Signed-off-by: Manoj Iyer Cc: Signed-off-by: Chris Ball --- drivers/pci/quirks.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e8a1406..02145e9 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2761,6 +2761,8 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832); +DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832); #endif /*CONFIG_MMC_RICOH_MMC*/ #if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP) -- cgit v1.1 From efc2924e733631a64c0afed8dbba2741d186998c Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 6 Jun 2011 17:12:49 -0700 Subject: drm/i915: Call intel_enable_plane from i9xx_crtc_mode_set (again) This change got placed in the ironlake path instead of the 9xx path during a recent code shuffle. Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/intel_display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 81a9059..aa43e7b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4687,6 +4687,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, I915_WRITE(DSPCNTR(plane), dspcntr); POSTING_READ(DSPCNTR(plane)); + intel_enable_plane(dev_priv, plane, pipe); ret = intel_pipe_set_base(crtc, x, y, old_fb); @@ -5217,8 +5218,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, I915_WRITE(DSPCNTR(plane), dspcntr); POSTING_READ(DSPCNTR(plane)); - if (!HAS_PCH_SPLIT(dev)) - intel_enable_plane(dev_priv, plane, pipe); ret = intel_pipe_set_base(crtc, x, y, old_fb); -- cgit v1.1 From ec6a890dfed7dd245beba5e5bcdfcffbd934c284 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 21 Jun 2011 18:37:59 +0100 Subject: drm/i915: Apply HWSTAM workaround for BSD ring on SandyBridge ...we need to apply exactly the same workaround for missing interrupts from BSD as for the BLT ring, apparently. See also commit 498e720b96379d8ee9c294950a01534a73defcf3 (drm/i915: Fix gen6 (SNB) missed BLT ring interrupts). Reported-and-tested-by: nkalkhof@web.de Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38529 Signed-off-by: Chris Wilson Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_irq.c | 1 + drivers/gpu/drm/i915/i915_reg.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 9e34a1a..ae2b499 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1749,6 +1749,7 @@ void ironlake_irq_preinstall(struct drm_device *dev) * happens. */ I915_WRITE(GEN6_BLITTER_HWSTAM, ~GEN6_BLITTER_USER_INTERRUPT); + I915_WRITE(GEN6_BSD_HWSTAM, ~GEN6_BSD_USER_INTERRUPT); } /* XXX hotplug from PCH */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2f967af..5d5def7 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -531,6 +531,7 @@ #define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE 0 #define GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR (1 << 3) +#define GEN6_BSD_HWSTAM 0x12098 #define GEN6_BSD_IMR 0x120a8 #define GEN6_BSD_USER_INTERRUPT (1 << 12) -- cgit v1.1 From e92d03bff9a0d0bcbb812c9b1290ca96c9338d45 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 14 Jun 2011 16:43:09 -0700 Subject: Revert "drm/i915: Kill GTT mappings when moving from GTT domain" This reverts commit 4a684a4117abd756291969336af454e8a958802f. Userland has always been required to set the object's domain to GTT before using it through a GTT mapping, it's not something that the kernel is supposed to enforce. (The pagefault support is so that we can handle multiple mappings without userland having to pin across them, not so that userland can use GTT after GPU domains without telling the kernel). Fixes 19.2% +/- 0.8% (n=6) performance regression in cairo-gl firefox-talos-gfx on my T420 latop. Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_gem.c | 10 ++++------ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 ---- 2 files changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 94c84d7..c6389de 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1219,11 +1219,11 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ret = i915_gem_object_bind_to_gtt(obj, 0, true); if (ret) goto unlock; - } - ret = i915_gem_object_set_to_gtt_domain(obj, write); - if (ret) - goto unlock; + ret = i915_gem_object_set_to_gtt_domain(obj, write); + if (ret) + goto unlock; + } if (obj->tiling_mode == I915_TILING_NONE) ret = i915_gem_object_put_fence(obj); @@ -2926,8 +2926,6 @@ i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj) */ wmb(); - i915_gem_release_mmap(obj); - old_write_domain = obj->base.write_domain; obj->base.write_domain = 0; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 20a4cc5..4934cf8 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -187,10 +187,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj, if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) i915_gem_clflush_object(obj); - /* blow away mappings if mapped through GTT */ - if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_GTT) - i915_gem_release_mmap(obj); - if (obj->base.pending_write_domain) cd->flips |= atomic_read(&obj->pending_flip); -- cgit v1.1 From f76b168b6f117a49d36307053e1acbe30580ea5b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Sat, 18 Jun 2011 20:22:23 +0200 Subject: PM: Rename dev_pm_info.in_suspend to is_prepared This patch (as1473) renames the "in_suspend" field in struct dev_pm_info to "is_prepared", in preparation for an upcoming change. The new name is more descriptive of what the field really means. Signed-off-by: Alan Stern Signed-off-by: Rafael J. Wysocki Cc: stable@kernel.org --- drivers/base/power/main.c | 14 +++++++++----- drivers/usb/core/driver.c | 6 +++--- 2 files changed, 12 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index aa632020..bf5a59a 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -57,7 +57,7 @@ static int async_error; */ void device_pm_init(struct device *dev) { - dev->power.in_suspend = false; + dev->power.is_prepared = false; init_completion(&dev->power.completion); complete_all(&dev->power.completion); dev->power.wakeup = NULL; @@ -91,7 +91,7 @@ void device_pm_add(struct device *dev) pr_debug("PM: Adding info for %s:%s\n", dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); mutex_lock(&dpm_list_mtx); - if (dev->parent && dev->parent->power.in_suspend) + if (dev->parent && dev->parent->power.is_prepared) dev_warn(dev, "parent %s should not be sleeping\n", dev_name(dev->parent)); list_add_tail(&dev->power.entry, &dpm_list); @@ -511,7 +511,11 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) dpm_wait(dev->parent, async); device_lock(dev); - dev->power.in_suspend = false; + /* + * This is a fib. But we'll allow new children to be added below + * a resumed device, even if the device hasn't been completed yet. + */ + dev->power.is_prepared = false; if (dev->pwr_domain) { pm_dev_dbg(dev, state, "power domain "); @@ -670,7 +674,7 @@ void dpm_complete(pm_message_t state) struct device *dev = to_device(dpm_prepared_list.prev); get_device(dev); - dev->power.in_suspend = false; + dev->power.is_prepared = false; list_move(&dev->power.entry, &list); mutex_unlock(&dpm_list_mtx); @@ -1042,7 +1046,7 @@ int dpm_prepare(pm_message_t state) put_device(dev); break; } - dev->power.in_suspend = true; + dev->power.is_prepared = true; if (!list_empty(&dev->power.entry)) list_move_tail(&dev->power.entry, &dpm_prepared_list); put_device(dev); diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index e35a176..aa3cc46 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -375,7 +375,7 @@ static int usb_unbind_interface(struct device *dev) * Just re-enable it without affecting the endpoint toggles. */ usb_enable_interface(udev, intf, false); - } else if (!error && !intf->dev.power.in_suspend) { + } else if (!error && !intf->dev.power.is_prepared) { r = usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); if (r < 0) @@ -960,7 +960,7 @@ void usb_rebind_intf(struct usb_interface *intf) } /* Try to rebind the interface */ - if (!intf->dev.power.in_suspend) { + if (!intf->dev.power.is_prepared) { intf->needs_binding = 0; rc = device_attach(&intf->dev); if (rc < 0) @@ -1107,7 +1107,7 @@ static int usb_resume_interface(struct usb_device *udev, if (intf->condition == USB_INTERFACE_UNBOUND) { /* Carry out a deferred switch to altsetting 0 */ - if (intf->needs_altsetting0 && !intf->dev.power.in_suspend) { + if (intf->needs_altsetting0 && !intf->dev.power.is_prepared) { usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); intf->needs_altsetting0 = 0; -- cgit v1.1 From 6d0e0e84f66d32c33511984dd3badd32364b863c Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Sat, 18 Jun 2011 22:42:09 +0200 Subject: PM: Fix async resume following suspend failure The PM core doesn't handle suspend failures correctly when it comes to asynchronously suspended devices. These devices are moved onto the dpm_suspended_list as soon as the corresponding async thread is started up, and they remain on the list even if they fail to suspend or the sleep transition is cancelled before they get suspended. As a result, when the PM core unwinds the transition, it tries to resume the devices even though they were never suspended. This patch (as1474) fixes the problem by adding a new "is_suspended" flag to dev_pm_info. Devices are resumed only if the flag is set. [rjw: * Moved the dev->power.is_suspended check into device_resume(), because we need to complete dev->power.completion and clear dev->power.is_prepared too for devices whose dev->power.is_suspended flags are unset. * Fixed __device_suspend() to avoid setting dev->power.is_suspended if async_error is different from zero.] Signed-off-by: Alan Stern Signed-off-by: Rafael J. Wysocki Cc: stable@kernel.org --- drivers/base/power/main.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index bf5a59a..06f09bf 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -58,6 +58,7 @@ static int async_error; void device_pm_init(struct device *dev) { dev->power.is_prepared = false; + dev->power.is_suspended = false; init_completion(&dev->power.completion); complete_all(&dev->power.completion); dev->power.wakeup = NULL; @@ -517,6 +518,9 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) */ dev->power.is_prepared = false; + if (!dev->power.is_suspended) + goto Unlock; + if (dev->pwr_domain) { pm_dev_dbg(dev, state, "power domain "); error = pm_op(dev, &dev->pwr_domain->ops, state); @@ -552,6 +556,9 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) } End: + dev->power.is_suspended = false; + + Unlock: device_unlock(dev); complete_all(&dev->power.completion); @@ -839,11 +846,11 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) device_lock(dev); if (async_error) - goto End; + goto Unlock; if (pm_wakeup_pending()) { async_error = -EBUSY; - goto End; + goto Unlock; } if (dev->pwr_domain) { @@ -881,6 +888,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) } End: + dev->power.is_suspended = !error; + + Unlock: device_unlock(dev); complete_all(&dev->power.completion); -- cgit v1.1 From 4d1518f5668ef1b3dff6c3b30fa761fe5573cdaa Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 21 Jun 2011 23:24:33 +0200 Subject: PM / Runtime: Handle clocks correctly if CONFIG_PM_RUNTIME is unset Commit 85eb8c8d0b0900c073b0e6f89979ac9c439ade1a (PM / Runtime: Generic clock manipulation rountines for runtime PM (v6)) converted the shmobile platform to using generic code for runtime PM clock management, but it changed the behavior for CONFIG_PM_RUNTIME unset incorrectly. Specifically, for CONFIG_PM_RUNTIME unset pm_runtime_clk_notify() should enable clocks for action equal to BUS_NOTIFY_BIND_DRIVER and it should disable them for action equal to BUS_NOTIFY_UNBOUND_DRIVER (instead of BUS_NOTIFY_ADD_DEVICE and BUS_NOTIFY_DEL_DEVICE, respectively). Make this function behave as appropriate. Signed-off-by: Rafael J. Wysocki Acked-by: Magnus Damm --- drivers/base/power/clock_ops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index eaa8a85..ad367c4 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -387,7 +387,7 @@ static int pm_runtime_clk_notify(struct notifier_block *nb, clknb = container_of(nb, struct pm_clk_notifier_block, nb); switch (action) { - case BUS_NOTIFY_ADD_DEVICE: + case BUS_NOTIFY_BIND_DRIVER: if (clknb->con_ids[0]) { for (con_id = clknb->con_ids; *con_id; con_id++) enable_clock(dev, *con_id); @@ -395,7 +395,7 @@ static int pm_runtime_clk_notify(struct notifier_block *nb, enable_clock(dev, NULL); } break; - case BUS_NOTIFY_DEL_DEVICE: + case BUS_NOTIFY_UNBOUND_DRIVER: if (clknb->con_ids[0]) { for (con_id = clknb->con_ids; *con_id; con_id++) disable_clock(dev, *con_id); -- cgit v1.1 From a5f76d5eba157bf637beb2dd18026db2917c512e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 21 Jun 2011 23:47:15 +0200 Subject: PCI / PM: Block races between runtime PM and system sleep After commit e8665002477f0278f84f898145b1f141ba26ee26 (PM: Allow pm_runtime_suspend() to succeed during system suspend) it is possible that a device resumed by the pm_runtime_resume(dev) in pci_pm_prepare() will be suspended immediately from a work item, timer function or otherwise, defeating the very purpose of calling pm_runtime_resume(dev) from there. To prevent that from happening it is necessary to increment the runtime PM usage counter of the device by replacing pm_runtime_resume() with pm_runtime_get_sync(). Moreover, the incremented runtime PM usage counter has to be decremented by the corresponding pci_pm_complete(), via pm_runtime_put_sync(). Signed-off-by: Rafael J. Wysocki Cc: stable@kernel.org Acked-by: Jesse Barnes --- drivers/pci/pci-driver.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 135df16..46767c5 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -624,7 +624,7 @@ static int pci_pm_prepare(struct device *dev) * system from the sleep state, we'll have to prevent it from signaling * wake-up. */ - pm_runtime_resume(dev); + pm_runtime_get_sync(dev); if (drv && drv->pm && drv->pm->prepare) error = drv->pm->prepare(dev); @@ -638,6 +638,8 @@ static void pci_pm_complete(struct device *dev) if (drv && drv->pm && drv->pm->complete) drv->pm->complete(dev); + + pm_runtime_put_sync(dev); } #else /* !CONFIG_PM_SLEEP */ -- cgit v1.1 From 58fa45973117ab7a79d5b6818275a887867fc4d7 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 21 Jun 2011 08:01:20 +0000 Subject: netconsole: fix build when CONFIG_NETCONSOLE_DYNAMIC is turned on When NETCONSOLE_DYNAMIC=y and CONFIGFS_FS=m, there are build errors in netconsole: drivers/built-in.o: In function `drop_netconsole_target': netconsole.c:(.text+0x1a100f): undefined reference to `config_item_put' drivers/built-in.o: In function `make_netconsole_target': netconsole.c:(.text+0x1a10b9): undefined reference to `config_item_init_type_name' drivers/built-in.o: In function `write_msg': netconsole.c:(.text+0x1a11a4): undefined reference to `config_item_get' netconsole.c:(.text+0x1a1211): undefined reference to `config_item_put' drivers/built-in.o: In function `netconsole_netdev_event': netconsole.c:(.text+0x1a12cc): undefined reference to `config_item_put' netconsole.c:(.text+0x1a12ec): undefined reference to `config_item_get' netconsole.c:(.text+0x1a1366): undefined reference to `config_item_put' drivers/built-in.o: In function `init_netconsole': netconsole.c:(.init.text+0x953a): undefined reference to `config_group_init' netconsole.c:(.init.text+0x9560): undefined reference to `configfs_register_subsystem' drivers/built-in.o: In function `dynamic_netconsole_exit': netconsole.c:(.exit.text+0x809): undefined reference to `configfs_unregister_subsystem' so fix the NETCONSOLE_DYNAMIC depends clause to prevent this. Based on email suggestion from Ben Hutchings. Thanks. Fixes https://bugzilla.kernel.org/show_bug.cgi?id=37992 Reported-by: David Hill Signed-off-by: Randy Dunlap Cc: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 19f04a3..93359fa 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -3416,7 +3416,8 @@ config NETCONSOLE config NETCONSOLE_DYNAMIC bool "Dynamic reconfiguration of logging targets" - depends on NETCONSOLE && SYSFS && CONFIGFS_FS + depends on NETCONSOLE && SYSFS && CONFIGFS_FS && \ + !(NETCONSOLE=y && CONFIGFS_FS=m) help This option enables the ability to dynamically reconfigure target parameters (interface, IP addresses, port numbers, MAC addresses) -- cgit v1.1 From c02a02ee4db5cd8b95ee3cc705b535f443612583 Mon Sep 17 00:00:00 2001 From: Shaohui Xie Date: Mon, 13 Jun 2011 10:23:12 +0800 Subject: powerpc/85xx: fix NAND_CMD_READID read bytes number when nand_get_flash_type() is called, it will read 8 bytes of ID instead of 5, but the driver only read 5 bytes, so kernel will dump error messages like: fsl-lbc ffe124000.localbus: read_byte beyond end of buffer fsl-lbc ffe124000.localbus: read_byte beyond end of buffer fsl-lbc ffe124000.localbus: read_byte beyond end of buffer Signed-off-by: Shaohui Xie Acked-by: Scott Wood Signed-off-by: Kumar Gala --- drivers/mtd/nand/fsl_elbc_nand.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 0bb254c..33d8aad 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -339,9 +339,9 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, (FIR_OP_UA << FIR_OP1_SHIFT) | (FIR_OP_RBW << FIR_OP2_SHIFT)); out_be32(&lbc->fcr, NAND_CMD_READID << FCR_CMD0_SHIFT); - /* 5 bytes for manuf, device and exts */ - out_be32(&lbc->fbcr, 5); - elbc_fcm_ctrl->read_bytes = 5; + /* nand_get_flash_type() reads 8 bytes of entire ID string */ + out_be32(&lbc->fbcr, 8); + elbc_fcm_ctrl->read_bytes = 8; elbc_fcm_ctrl->use_mdr = 1; elbc_fcm_ctrl->mdr = 0; -- cgit v1.1 From 483f1798998ede75b2575cc1813c3d89ba64a34e Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Wed, 22 Jun 2011 09:55:01 -0700 Subject: drm/i915: save/resume forcewake lock fixes The lock must be held for the saving and restoring of VGA state. Signed-off-by: Ben Widawsky CC: Alexander Zhaunerchyk CC: Andrey Rahmatullin Reviewed-by: Chris Wilson Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_suspend.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 60a94d2..e8152d2 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -678,6 +678,7 @@ void i915_save_display(struct drm_device *dev) } /* VGA state */ + mutex_lock(&dev->struct_mutex); dev_priv->saveVGA0 = I915_READ(VGA0); dev_priv->saveVGA1 = I915_READ(VGA1); dev_priv->saveVGA_PD = I915_READ(VGA_PD); @@ -687,6 +688,7 @@ void i915_save_display(struct drm_device *dev) dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); i915_save_vga(dev); + mutex_unlock(&dev->struct_mutex); } void i915_restore_display(struct drm_device *dev) @@ -780,6 +782,8 @@ void i915_restore_display(struct drm_device *dev) I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); else I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); + + mutex_lock(&dev->struct_mutex); I915_WRITE(VGA0, dev_priv->saveVGA0); I915_WRITE(VGA1, dev_priv->saveVGA1); I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); @@ -787,6 +791,7 @@ void i915_restore_display(struct drm_device *dev) udelay(150); i915_restore_vga(dev); + mutex_unlock(&dev->struct_mutex); } int i915_save_state(struct drm_device *dev) -- cgit v1.1 From 7cdfa4a348b6b199a3189604f2085f1b214b6458 Mon Sep 17 00:00:00 2001 From: "Marius B. Kotsbak" Date: Wed, 22 Jun 2011 05:26:16 +0000 Subject: net/usb: kalmia: Various fixes for better support of non-x86 architectures. -Support for big endian. -Do not use USB buffers at the stack. -Safer/more efficient code for local constants. Signed-off-by: Marius B. Kotsbak Signed-off-by: David S. Miller --- drivers/net/usb/kalmia.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c index d965fb1..d4edeb2 100644 --- a/drivers/net/usb/kalmia.c +++ b/drivers/net/usb/kalmia.c @@ -100,27 +100,35 @@ kalmia_send_init_packet(struct usbnet *dev, u8 *init_msg, u8 init_msg_len, static int kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr) { - char init_msg_1[] = + const static char init_msg_1[] = { 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00 }; - char init_msg_2[] = + const static char init_msg_2[] = { 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf4, 0x00, 0x00 }; - char receive_buf[28]; + const static int buflen = 28; + char *usb_buf; int status; - status = kalmia_send_init_packet(dev, init_msg_1, sizeof(init_msg_1) - / sizeof(init_msg_1[0]), receive_buf, 24); + usb_buf = kmalloc(buflen, GFP_DMA | GFP_KERNEL); + if (!usb_buf) + return -ENOMEM; + + memcpy(usb_buf, init_msg_1, 12); + status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_1) + / sizeof(init_msg_1[0]), usb_buf, 24); if (status != 0) return status; - status = kalmia_send_init_packet(dev, init_msg_2, sizeof(init_msg_2) - / sizeof(init_msg_2[0]), receive_buf, 28); + memcpy(usb_buf, init_msg_2, 12); + status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_2) + / sizeof(init_msg_2[0]), usb_buf, 28); if (status != 0) return status; - memcpy(ethernet_addr, receive_buf + 10, ETH_ALEN); + memcpy(ethernet_addr, usb_buf + 10, ETH_ALEN); + kfree(usb_buf); return status; } @@ -190,7 +198,8 @@ kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) dev_kfree_skb_any(skb); skb = skb2; - done: header_start = skb_push(skb, KALMIA_HEADER_LENGTH); +done: + header_start = skb_push(skb, KALMIA_HEADER_LENGTH); ether_type_1 = header_start[KALMIA_HEADER_LENGTH + 12]; ether_type_2 = header_start[KALMIA_HEADER_LENGTH + 13]; @@ -201,9 +210,8 @@ kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) header_start[0] = 0x57; header_start[1] = 0x44; content_len = skb->len - KALMIA_HEADER_LENGTH; - header_start[2] = (content_len & 0xff); /* low byte */ - header_start[3] = (content_len >> 8); /* high byte */ + put_unaligned_le16(content_len, &header_start[2]); header_start[4] = ether_type_1; header_start[5] = ether_type_2; @@ -231,13 +239,13 @@ kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb) * Our task here is to strip off framing, leaving skb with one * data frame for the usbnet framework code to process. */ - const u8 HEADER_END_OF_USB_PACKET[] = + const static u8 HEADER_END_OF_USB_PACKET[] = { 0x57, 0x5a, 0x00, 0x00, 0x08, 0x00 }; - const u8 EXPECTED_UNKNOWN_HEADER_1[] = + const static u8 EXPECTED_UNKNOWN_HEADER_1[] = { 0x57, 0x43, 0x1e, 0x00, 0x15, 0x02 }; - const u8 EXPECTED_UNKNOWN_HEADER_2[] = + const static u8 EXPECTED_UNKNOWN_HEADER_2[] = { 0x57, 0x50, 0x0e, 0x00, 0x00, 0x00 }; - u8 i = 0; + int i = 0; /* incomplete header? */ if (skb->len < KALMIA_HEADER_LENGTH) @@ -285,7 +293,7 @@ kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb) /* subtract start header and end header */ usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH); - ether_packet_length = header_start[2] + (header_start[3] << 8); + ether_packet_length = get_unaligned_le16(&header_start[2]); skb_pull(skb, KALMIA_HEADER_LENGTH); /* Some small packets misses end marker */ -- cgit v1.1 From 5c18e80be9ff362f6523b097d495bb2e2f939946 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 23 Jun 2011 03:15:39 -0700 Subject: net/usb/kalmia: signedness bug in kalmia_bind() "status" should be an int here for the error handling to work. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/usb/kalmia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c index d4edeb2..a9b6c63 100644 --- a/drivers/net/usb/kalmia.c +++ b/drivers/net/usb/kalmia.c @@ -135,7 +135,7 @@ kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr) static int kalmia_bind(struct usbnet *dev, struct usb_interface *intf) { - u8 status; + int status; u8 ethernet_addr[ETH_ALEN]; /* Don't bind to AT command interface */ -- cgit v1.1 From 0bb04bf3dfdfe1c981087cdfb0d9d772c3a0ba55 Mon Sep 17 00:00:00 2001 From: William Douglas Date: Thu, 23 Jun 2011 13:38:36 +0100 Subject: mrst_max3110: Change max missing message priority. Change print message to notice instead of error to clean up non critical messages showing on startup. The MAX3111 not being present is a normal path for end user systems. Signed-off-by: William Douglas [rebased on 3.0, switched to dev_dbg()] Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/tty/serial/mrst_max3110.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index 1bd2845..3be1b0d 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c @@ -823,7 +823,7 @@ static int __devinit serial_m3110_probe(struct spi_device *spi) res = RC_TAG; ret = max3110_write_then_read(max, (u8 *)&res, (u8 *)&res, 2, 0); if (ret < 0 || res == 0 || res == 0xffff) { - printk(KERN_ERR "MAX3111 deemed not present (conf reg %04x)", + dev_dbg(&spi->dev, "MAX3111 deemed not present (conf reg %04x)", res); ret = -ENODEV; goto err_get_page; -- cgit v1.1 From 33b1e6939f5c37ab8e64280fd3d54046607b5c80 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 23 Jun 2011 13:39:00 +0100 Subject: serial: mrst_max3110: initialize waitqueue earlier The driver went to initialize its waitqueue at the start of the main processing thread. However, it is possible that this thread is not scheduled on a CPU before the write function is called which leads to a following error: BUG: spinlock bad magic on CPU#1, swapper/1 lock: f5f3ebdc, .magic: 00000000, .owner: /-1, .owner_cpu: 0 Pid: 1, comm: swapper Not tainted 3.0.0-rc2+ #67 Call Trace: [] spin_bug+0xa3/0xf0 [] do_raw_spin_lock+0x7d/0x150 [] _raw_spin_lock_irqsave+0x4e/0x60 [] __wake_up+0x1b/0x50 [] serial_m3110_con_write+0x55/0x60 [] __call_console_drivers+0x75/0x90 [] _call_console_drivers+0x49/0x80 [] console_unlock+0xca/0x1f0 [] vprintk+0x18f/0x4f0 [] printk+0x18/0x1a [] register_console+0x2e0/0x350 [] uart_add_one_port+0x33e/0x3d0 [] serial_m3110_probe+0x1c2/0x1df [] spi_drv_probe+0x17/0x20 ... Fix this by initializing the waitqueue before the main thread is created. Signed-off-by: Mika Westerberg Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/tty/serial/mrst_max3110.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/mrst_max3110.c b/drivers/tty/serial/mrst_max3110.c index 3be1b0d..a764bf9 100644 --- a/drivers/tty/serial/mrst_max3110.c +++ b/drivers/tty/serial/mrst_max3110.c @@ -421,7 +421,6 @@ static int max3110_main_thread(void *_max) int ret = 0; struct circ_buf *xmit = &max->con_xmit; - init_waitqueue_head(wq); pr_info(PR_FMT "start main thread\n"); do { @@ -838,6 +837,8 @@ static int __devinit serial_m3110_probe(struct spi_device *spi) max->con_xmit.head = 0; max->con_xmit.tail = 0; + init_waitqueue_head(&max->wq); + max->main_thread = kthread_run(max3110_main_thread, max, "max3110_main"); if (IS_ERR(max->main_thread)) { -- cgit v1.1 From 8618ccd352dcd01628f39eb1fca4f9a7bc077ea1 Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Wed, 22 Jun 2011 23:29:20 -0700 Subject: drivers/ata/sata_dwc_460ex: Fix typo 'corrresponding' The patch below fixes a typo. Signed-off-by: Justin P. Mattock Signed-off-by: Jeff Garzik --- drivers/ata/sata_dwc_460ex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 1c4b3aa..dc88a39 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -389,7 +389,7 @@ static void sata_dwc_tf_dump(struct ata_taskfile *tf) /* * Function: get_burst_length_encode * arguments: datalength: length in bytes of data - * returns value to be programmed in register corrresponding to data length + * returns value to be programmed in register corresponding to data length * This value is effectively the log(base 2) of the length */ static int get_burst_length_encode(int datalength) -- cgit v1.1 From cd691876d73e24b4c0a2e96993251abbe3a320df Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 22 Jun 2011 12:13:10 +0200 Subject: libata: apply NOSETXFER horkage to the affected Pioneer drives regardless of firmware revision It's unlikely NOSETXFER works for a revision of drive but doesn't for another and pioneer doesn't seem to be fixing firmwares for the affected drives. Apply NOSETXFER to the affected pioneer drives regardless of firmware revision. http://article.gmane.org/gmane.linux.ide/49734 Signed-off-by: Tejun Heo Reported-by: fl-00@gmx.de Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 736bee5..000d03a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4143,9 +4143,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { * Devices which choke on SETXFER. Applies only if both the * device and controller are SATA. */ - { "PIONEER DVD-RW DVRTD08", "1.00", ATA_HORKAGE_NOSETXFER }, - { "PIONEER DVD-RW DVR-212D", "1.28", ATA_HORKAGE_NOSETXFER }, - { "PIONEER DVD-RW DVR-216D", "1.08", ATA_HORKAGE_NOSETXFER }, + { "PIONEER DVD-RW DVRTD08", NULL, ATA_HORKAGE_NOSETXFER }, + { "PIONEER DVD-RW DVR-212D", NULL, ATA_HORKAGE_NOSETXFER }, + { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, /* End Marker */ { } -- cgit v1.1 From 3f1e046ad3370d22d39529103667354eb50abc08 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Thu, 16 Jun 2011 08:28:36 -0700 Subject: libata/sas: only set FROZEN flag if new EH is supported On 16.06.2011 [08:28:39 -0500], Brian King wrote: > On 06/16/2011 02:51 AM, Tejun Heo wrote: > > On Wed, Jun 15, 2011 at 04:34:17PM -0700, Nishanth Aravamudan wrote: > >>> That looks like the right thing to do. For ipr's usage of > >>> libata, we don't have the concept of a port frozen state, so this flag > >>> should really never get set. The alternate way to fix this would be to > >>> only set ATA_PFLAG_FROZEN in ata_port_alloc if ap->ops->error_handler > >>> is not NULL. > >> > >> It seemed like ipr is as you say, but I wasn't sure if it was > >> appropriate to make the change above in the common libata-scis code or > >> not. I don't want to break some other device on accident. > >> > >> Also, I tried your suggestion, but I don't think that can happen in > >> ata_port_alloc? ata_port_alloc is allocated ap itself, and it seems like > >> ap->ops typically gets set only after ata_port_alloc returns? > > > > Maybe we can test error_handler in ata_sas_port_start()? > > Good point. Since libsas is converted to the new eh now, we would need to have > this test. Commit 7b3a24c57d2eeda8dba9c205342b12689c4679f9 ("ahci: don't enable port irq before handler is registered") caused a regression for CD-ROMs attached to the IPR SATA bus on Power machines: ata_port_alloc: ENTER ata_port_probe: ata1: bus probe begin ata1.00: ata_dev_read_id: ENTER ata1.00: failed to IDENTIFY (I/O error, err_mask=0x40) ata1.00: ata_dev_read_id: ENTER ata1.00: failed to IDENTIFY (I/O error, err_mask=0x40) ata1.00: limiting speed to UDMA7:PIO5 ata1.00: ata_dev_read_id: ENTER ata1.00: failed to IDENTIFY (I/O error, err_mask=0x40) ata1.00: disabled ata_port_probe: ata1: bus probe end scsi_alloc_sdev: Allocation failure during SCSI scanning, some SCSI devices might not be configured The FROZEN flag added in that commit is only cleared by the new EH code, which is not used by ipr. Clear this flag in the SAS code if we don't support new EH. Reported-by: Benjamin Herrenschmidt Signed-off-by: Nishanth Aravamudan Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index d51f979..927f968 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3797,6 +3797,12 @@ EXPORT_SYMBOL_GPL(ata_sas_port_alloc); */ int ata_sas_port_start(struct ata_port *ap) { + /* + * the port is marked as frozen at allocation time, but if we don't + * have new eh, we won't thaw it + */ + if (!ap->ops->error_handler) + ap->pflags &= ~ATA_PFLAG_FROZEN; return 0; } EXPORT_SYMBOL_GPL(ata_sas_port_start); -- cgit v1.1 From 03ad2d501e7189245bf6bf9dfc2a30511dd50602 Mon Sep 17 00:00:00 2001 From: Alexey Charkov Date: Wed, 22 Jun 2011 23:20:13 +0200 Subject: rtc: vt8500: Fix build error & cleanup rtc_class_ops->update_irq_enable() Now that the generic code handles UIE mode irqs via periodic alarm interrupts, no one calls the rtc_class_ops->update_irq_enable() method anymore. Further the rtc_class_ops doesn't have a update_irq_enable element anymore, so this causes a build error. This patch removes the driver hooks and implementations of update_irq_enable and the associated setup. [wsa: updated commit-message and removed update_irq_enable-function, too] [jstultz: improve commit message, clarifying build issue] Signed-off-by: Alexey Charkov Signed-off-by: Wolfram Sang Signed-off-by: John Stultz --- drivers/rtc/rtc-vt8500.c | 45 +++------------------------------------------ 1 file changed, 3 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c index b8bc862..efd6066 100644 --- a/drivers/rtc/rtc-vt8500.c +++ b/drivers/rtc/rtc-vt8500.c @@ -78,7 +78,6 @@ struct vt8500_rtc { void __iomem *regbase; struct resource *res; int irq_alarm; - int irq_hz; struct rtc_device *rtc; spinlock_t lock; /* Protects this structure */ }; @@ -100,10 +99,6 @@ static irqreturn_t vt8500_rtc_irq(int irq, void *dev_id) if (isr & 1) events |= RTC_AF | RTC_IRQF; - /* Only second/minute interrupts are supported */ - if (isr & 2) - events |= RTC_UF | RTC_IRQF; - rtc_update_irq(vt8500_rtc->rtc, 1, events); return IRQ_HANDLED; @@ -199,27 +194,12 @@ static int vt8500_alarm_irq_enable(struct device *dev, unsigned int enabled) return 0; } -static int vt8500_update_irq_enable(struct device *dev, unsigned int enabled) -{ - struct vt8500_rtc *vt8500_rtc = dev_get_drvdata(dev); - unsigned long tmp = readl(vt8500_rtc->regbase + VT8500_RTC_CR); - - if (enabled) - tmp |= VT8500_RTC_CR_SM_SEC | VT8500_RTC_CR_SM_ENABLE; - else - tmp &= ~VT8500_RTC_CR_SM_ENABLE; - - writel(tmp, vt8500_rtc->regbase + VT8500_RTC_CR); - return 0; -} - static const struct rtc_class_ops vt8500_rtc_ops = { .read_time = vt8500_rtc_read_time, .set_time = vt8500_rtc_set_time, .read_alarm = vt8500_rtc_read_alarm, .set_alarm = vt8500_rtc_set_alarm, .alarm_irq_enable = vt8500_alarm_irq_enable, - .update_irq_enable = vt8500_update_irq_enable, }; static int __devinit vt8500_rtc_probe(struct platform_device *pdev) @@ -248,13 +228,6 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev) goto err_free; } - vt8500_rtc->irq_hz = platform_get_irq(pdev, 1); - if (vt8500_rtc->irq_hz < 0) { - dev_err(&pdev->dev, "No 1Hz IRQ resource defined\n"); - ret = -ENXIO; - goto err_free; - } - vt8500_rtc->res = request_mem_region(vt8500_rtc->res->start, resource_size(vt8500_rtc->res), "vt8500-rtc"); @@ -272,9 +245,8 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev) goto err_release; } - /* Enable the second/minute interrupt generation and enable RTC */ - writel(VT8500_RTC_CR_ENABLE | VT8500_RTC_CR_24H - | VT8500_RTC_CR_SM_ENABLE | VT8500_RTC_CR_SM_SEC, + /* Enable RTC and set it to 24-hour mode */ + writel(VT8500_RTC_CR_ENABLE | VT8500_RTC_CR_24H, vt8500_rtc->regbase + VT8500_RTC_CR); vt8500_rtc->rtc = rtc_device_register("vt8500-rtc", &pdev->dev, @@ -286,26 +258,16 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev) goto err_unmap; } - ret = request_irq(vt8500_rtc->irq_hz, vt8500_rtc_irq, 0, - "rtc 1Hz", vt8500_rtc); - if (ret < 0) { - dev_err(&pdev->dev, "can't get irq %i, err %d\n", - vt8500_rtc->irq_hz, ret); - goto err_unreg; - } - ret = request_irq(vt8500_rtc->irq_alarm, vt8500_rtc_irq, 0, "rtc alarm", vt8500_rtc); if (ret < 0) { dev_err(&pdev->dev, "can't get irq %i, err %d\n", vt8500_rtc->irq_alarm, ret); - goto err_free_hz; + goto err_unreg; } return 0; -err_free_hz: - free_irq(vt8500_rtc->irq_hz, vt8500_rtc); err_unreg: rtc_device_unregister(vt8500_rtc->rtc); err_unmap: @@ -323,7 +285,6 @@ static int __devexit vt8500_rtc_remove(struct platform_device *pdev) struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev); free_irq(vt8500_rtc->irq_alarm, vt8500_rtc); - free_irq(vt8500_rtc->irq_hz, vt8500_rtc); rtc_device_unregister(vt8500_rtc->rtc); -- cgit v1.1 From 7fd29aa920273b70be50c14c4b7e2213fb6623ce Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Thu, 23 Jun 2011 23:48:32 +0000 Subject: target: Fix transport_get_lun_for_tmr failure cases This patch fixes two possible NULL pointer dereferences in target v4.0 code where se_tmr release path in core_tmr_release_req() can OOPs upon transport_get_lun_for_tmr() failure by attempting to access se_device or se_tmr->tmr_list without a valid member of se_device->tmr_list during transport_free_se_cmd() release. This patch moves the se_tmr->tmr_dev pointer assignment in transport_get_lun_for_tmr() until after possible -ENODEV failures during unpacked_lun lookup. This addresses an OOPs originally reported with LIO v4.1 upstream on .39 code here: TARGET_CORE[qla2xxx]: Detected NON_EXISTENT_LUN Access for 0x00000000 BUG: unable to handle kernel NULL pointer dereference at 0000000000000550 IP: [] __ticket_spin_trylock+0x4/0x20 PGD 0 Oops: 0000 [#1] SMP last sysfs file: /sys/devices/system/cpu/cpu23/cache/index2/shared_cpu_map CPU 1 Modules linked in: netconsole target_core_pscsi target_core_file tcm_qla2xxx target_core_iblock tcm_loop target_core_mod configfs ipmi_devintf ipmi_si ipmi_msghandler serio_raw i7core_edac ioatdma dca edac_core ps_bdrv ses enclosure usbhid usb_storage ahci qla2xxx hid uas e1000e mpt2sas libahci mlx4_core scsi_transport_fc scsi_transport_sas raid_class scsi_tgt [last unloaded: netconsole] Pid: 0, comm: kworker/0:0 Tainted: G W 2.6.39+ #1 Xyratex Storage Server RIP: 0010:[] []__ticket_spin_trylock+0x4/0x20 RSP: 0018:ffff88063e803c08 EFLAGS: 00010286 RAX: ffff880619ab45e0 RBX: 0000000000000550 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000550 RBP: ffff88063e803c08 R08: 0000000000000002 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000001 R12: 0000000000000568 R13: 0000000000000001 R14: 0000000000000000 R15: ffff88060cd96a20 FS: 0000000000000000(0000) GS:ffff88063e800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000550 CR3: 0000000001a03000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process kworker/0:0 (pid: 0, threadinfo ffff880619ab8000, task ffff880619ab45e0) Stack: ffff88063e803c28 ffffffff812cf039 0000000000000550 0000000000000568 ffff88063e803c58 ffffffff8157071e ffffffffa028a1dc ffff88060f7e4600 0000000000000550 ffff880616961480 ffff88063e803c78 ffffffffa028a1dc Call Trace: [] do_raw_spin_trylock+0x19/0x50 [] _raw_spin_lock+0x3e/0x70 [] ? core_tmr_release_req+0x2c/0x60 [target_core_mod] [] core_tmr_release_req+0x2c/0x60 [target_core_mod] [] transport_free_se_cmd+0x22/0x50 [target_core_mod] [] transport_release_cmd_to_pool+0x20/0x40 [target_core_mod] [] transport_generic_free_cmd+0xa5/0xb0 [target_core_mod] [] tcm_qla2xxx_handle_tmr+0xc4/0xd0 [tcm_qla2xxx] [] __qla24xx_handle_abts+0xd3/0x150 [qla2xxx] [] qla_tgt_response_pkt+0x171/0x520 [qla2xxx] [] qla_tgt_response_pkt_all_vps+0x2d/0x220 [qla2xxx] [] qla24xx_process_response_queue+0x1a3/0x670 [qla2xxx] [] ? qla24xx_atio_pkt+0x81/0x120 [qla2xxx] [] ? qla24xx_msix_default+0x45/0x2a0 [qla2xxx] [] qla24xx_msix_default+0x1b8/0x2a0 [qla2xxx] [] handle_irq_event_percpu+0x54/0x210 [] handle_irq_event+0x48/0x70 [] ? handle_edge_irq+0x1e/0x110 [] handle_edge_irq+0x77/0x110 [] handle_irq+0x22/0x40 [] do_IRQ+0x5d/0xe0 [] common_interrupt+0x13/0x13 [] ? intel_idle+0xd7/0x130 [] ? intel_idle+0xd0/0x130 [] cpuidle_idle_call+0xab/0x1c0 [] cpu_idle+0xab/0xf0 [] start_secondary+0x1cb/0x1d2 Reported-by: Roland Dreier Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_device.c | 3 ++- drivers/target/target_core_tmr.c | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 8407f9c..f8d8af7 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -192,7 +192,7 @@ int transport_get_lun_for_tmr( &SE_NODE_ACL(se_sess)->device_list[unpacked_lun]; if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) { se_lun = se_cmd->se_lun = se_tmr->tmr_lun = deve->se_lun; - dev = se_tmr->tmr_dev = se_lun->lun_se_dev; + dev = se_lun->lun_se_dev; se_cmd->pr_res_key = deve->pr_res_key; se_cmd->orig_fe_lun = unpacked_lun; se_cmd->se_orig_obj_ptr = SE_LUN(se_cmd)->lun_se_dev; @@ -216,6 +216,7 @@ int transport_get_lun_for_tmr( se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; return -1; } + se_tmr->tmr_dev = dev; spin_lock(&dev->se_tmr_lock); list_add_tail(&se_tmr->tmr_list, &dev->dev_tmr_list); diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 59b8b9c..179063d 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -75,10 +75,16 @@ void core_tmr_release_req( { struct se_device *dev = tmr->tmr_dev; + if (!dev) { + kmem_cache_free(se_tmr_req_cache, tmr); + return; + } + spin_lock(&dev->se_tmr_lock); list_del(&tmr->tmr_list); - kmem_cache_free(se_tmr_req_cache, tmr); spin_unlock(&dev->se_tmr_lock); + + kmem_cache_free(se_tmr_req_cache, tmr); } static void core_tmr_handle_tas_abort( -- cgit v1.1 From 233888644d80cc44330062e5e978c9e3a14c9cb9 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 22 Jun 2011 01:02:21 -0700 Subject: target: Convert transport_deregister_session_configfs nacl_sess_lock to save irq state This patch converts transport_deregister_session_configfs() to save/restore spinlock IRQ state for struct se_node_acl->nacl_sess_lock access as tcm_qla2xxx logic expects to call transport_deregister_session_configfs() code with irq save already held for struct qla_hw_data. Reported-by: Roland Dreier Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_transport.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 4dafeb8..4b9b716 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -536,13 +536,13 @@ EXPORT_SYMBOL(transport_register_session); void transport_deregister_session_configfs(struct se_session *se_sess) { struct se_node_acl *se_nacl; - + unsigned long flags; /* * Used by struct se_node_acl's under ConfigFS to locate active struct se_session */ se_nacl = se_sess->se_node_acl; if ((se_nacl)) { - spin_lock_irq(&se_nacl->nacl_sess_lock); + spin_lock_irqsave(&se_nacl->nacl_sess_lock, flags); list_del(&se_sess->sess_acl_list); /* * If the session list is empty, then clear the pointer. @@ -556,7 +556,7 @@ void transport_deregister_session_configfs(struct se_session *se_sess) se_nacl->acl_sess_list.prev, struct se_session, sess_acl_list); } - spin_unlock_irq(&se_nacl->nacl_sess_lock); + spin_unlock_irqrestore(&se_nacl->nacl_sess_lock, flags); } } EXPORT_SYMBOL(transport_deregister_session_configfs); -- cgit v1.1 From 552523dcbf0f33d44d816da310be8227a2c1502a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 15 Jun 2011 09:41:33 -0700 Subject: target: Fix ERR_PTR dereferencing bugs transport_init_session() and core_tmr_alloc_req() never return NULL, they only return ERR_PTRs on error. v2: Fix patch to return PTR_ERR(tl_nexus->se_sess) from Ankit Jain's feedback. Signed-off-by: Dan Carpenter Signed-off-by: Ankit Jain Signed-off-by: Nicholas Bellinger --- drivers/target/loopback/tcm_loop.c | 9 ++++++--- drivers/target/tcm_fc/tfc_sess.c | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index dee2a2c..d4fee2a9 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -386,7 +386,7 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc) */ se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd, (void *)tl_tmr, TMR_LUN_RESET); - if (!se_cmd->se_tmr_req) + if (IS_ERR(se_cmd->se_tmr_req)) goto release; /* * Locate the underlying TCM struct se_lun from sc->device->lun @@ -1017,6 +1017,7 @@ static int tcm_loop_make_nexus( struct se_portal_group *se_tpg; struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba; struct tcm_loop_nexus *tl_nexus; + int ret = -ENOMEM; if (tl_tpg->tl_hba->tl_nexus) { printk(KERN_INFO "tl_tpg->tl_hba->tl_nexus already exists\n"); @@ -1033,8 +1034,10 @@ static int tcm_loop_make_nexus( * Initialize the struct se_session pointer */ tl_nexus->se_sess = transport_init_session(); - if (!tl_nexus->se_sess) + if (IS_ERR(tl_nexus->se_sess)) { + ret = PTR_ERR(tl_nexus->se_sess); goto out; + } /* * Since we are running in 'demo mode' this call with generate a * struct se_node_acl for the tcm_loop struct se_portal_group with the SCSI @@ -1060,7 +1063,7 @@ static int tcm_loop_make_nexus( out: kfree(tl_nexus); - return -ENOMEM; + return ret; } static int tcm_loop_drop_nexus( diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index a3bd57f..03744c2 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c @@ -229,7 +229,7 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id, return NULL; sess->se_sess = transport_init_session(); - if (!sess->se_sess) { + if (IS_ERR(sess->se_sess)) { kfree(sess); return NULL; } -- cgit v1.1 From 5eff5be0b1993f4291f2b8c6d035b408010f96c5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 13 Jun 2011 23:10:49 +0300 Subject: target: Drop bogus ERR_PTR usage in target_fabric_configfs_init In the original code, there were several places inside the target_fabric_configfs_init() function that returned NULL on error and one place the returned an ERR_PTR. There are two places that call this function and they only check for NULL returns; they don't check for ERR_PTRs. So I've changed the ERR_PTR so now the function only returns NULL on error. Signed-off-by: Dan Carpenter Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_configfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index ee6fad9..b17abd1 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -312,7 +312,7 @@ struct target_fabric_configfs *target_fabric_configfs_init( tf = kzalloc(sizeof(struct target_fabric_configfs), GFP_KERNEL); if (!(tf)) - return ERR_PTR(-ENOMEM); + return NULL; INIT_LIST_HEAD(&tf->tf_list); atomic_set(&tf->tf_access_cnt, 0); -- cgit v1.1 From 60d645a4e9e7e7ddc20e534fea82aa4e6947f911 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 15 Jun 2011 10:03:05 -0700 Subject: target: Fix incorrect strlen() NULL terminator checks This patch fixes a number of cases in target core using an incorrectly if (strlen(foo) > SOME_MAX_SIZE) As strlen() returns the number of characters in the string not counting the NULL character at the end. So if you do something like: char buf[10]; if (strlen("0123456789") > 10) return -ETOOLONG; snprintf(buf, 10, "0123456789"); printf("%s\n", buf); then the last "9" gets chopped off and only "012345678" is printed. Plus I threw in one small related cleanup. Signed-off-by: Dan Carpenter Signed-off-by: Nicholas Bellinger --- drivers/target/loopback/tcm_loop.c | 4 ++-- drivers/target/target_core_configfs.c | 22 +++++++++++----------- drivers/target/target_core_device.c | 2 +- drivers/target/target_core_pr.c | 6 +++--- 4 files changed, 17 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index d4fee2a9..70c2e7f 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -1143,7 +1143,7 @@ static ssize_t tcm_loop_tpg_store_nexus( * the fabric protocol_id set in tcm_loop_make_scsi_hba(), and call * tcm_loop_make_nexus() */ - if (strlen(page) > TL_WWN_ADDR_LEN) { + if (strlen(page) >= TL_WWN_ADDR_LEN) { printk(KERN_ERR "Emulated NAA Sas Address: %s, exceeds" " max: %d\n", page, TL_WWN_ADDR_LEN); return -EINVAL; @@ -1324,7 +1324,7 @@ struct se_wwn *tcm_loop_make_scsi_hba( return ERR_PTR(-EINVAL); check_len: - if (strlen(name) > TL_WWN_ADDR_LEN) { + if (strlen(name) >= TL_WWN_ADDR_LEN) { printk(KERN_ERR "Emulated NAA %s Address: %s, exceeds" " max: %d\n", name, tcm_loop_dump_proto_id(tl_hba), TL_WWN_ADDR_LEN); diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index b17abd1..25c1f49 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -304,7 +304,7 @@ struct target_fabric_configfs *target_fabric_configfs_init( printk(KERN_ERR "Unable to locate passed fabric name\n"); return NULL; } - if (strlen(name) > TARGET_FABRIC_NAME_SIZE) { + if (strlen(name) >= TARGET_FABRIC_NAME_SIZE) { printk(KERN_ERR "Passed name: %s exceeds TARGET_FABRIC" "_NAME_SIZE\n", name); return NULL; @@ -851,7 +851,7 @@ static ssize_t target_core_dev_wwn_store_attr_vpd_unit_serial( return -EOPNOTSUPP; } - if ((strlen(page) + 1) > INQUIRY_VPD_SERIAL_LEN) { + if (strlen(page) >= INQUIRY_VPD_SERIAL_LEN) { printk(KERN_ERR "Emulated VPD Unit Serial exceeds" " INQUIRY_VPD_SERIAL_LEN: %d\n", INQUIRY_VPD_SERIAL_LEN); return -EOVERFLOW; @@ -917,7 +917,7 @@ static ssize_t target_core_dev_wwn_show_attr_vpd_protocol_identifier( transport_dump_vpd_proto_id(vpd, buf, VPD_TMP_BUF_SIZE); - if ((len + strlen(buf) > PAGE_SIZE)) + if ((len + strlen(buf) >= PAGE_SIZE)) break; len += sprintf(page+len, "%s", buf); @@ -962,19 +962,19 @@ static ssize_t target_core_dev_wwn_show_attr_##_name( \ \ memset(buf, 0, VPD_TMP_BUF_SIZE); \ transport_dump_vpd_assoc(vpd, buf, VPD_TMP_BUF_SIZE); \ - if ((len + strlen(buf) > PAGE_SIZE)) \ + if ((len + strlen(buf) >= PAGE_SIZE)) \ break; \ len += sprintf(page+len, "%s", buf); \ \ memset(buf, 0, VPD_TMP_BUF_SIZE); \ transport_dump_vpd_ident_type(vpd, buf, VPD_TMP_BUF_SIZE); \ - if ((len + strlen(buf) > PAGE_SIZE)) \ + if ((len + strlen(buf) >= PAGE_SIZE)) \ break; \ len += sprintf(page+len, "%s", buf); \ \ memset(buf, 0, VPD_TMP_BUF_SIZE); \ transport_dump_vpd_ident(vpd, buf, VPD_TMP_BUF_SIZE); \ - if ((len + strlen(buf) > PAGE_SIZE)) \ + if ((len + strlen(buf) >= PAGE_SIZE)) \ break; \ len += sprintf(page+len, "%s", buf); \ } \ @@ -1299,7 +1299,7 @@ static ssize_t target_core_dev_pr_show_attr_res_pr_registered_i_pts( &i_buf[0] : "", pr_reg->pr_res_key, pr_reg->pr_res_generation); - if ((len + strlen(buf) > PAGE_SIZE)) + if ((len + strlen(buf) >= PAGE_SIZE)) break; len += sprintf(page+len, "%s", buf); @@ -1496,7 +1496,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( ret = -ENOMEM; goto out; } - if (strlen(i_port) > PR_APTPL_MAX_IPORT_LEN) { + if (strlen(i_port) >= PR_APTPL_MAX_IPORT_LEN) { printk(KERN_ERR "APTPL metadata initiator_node=" " exceeds PR_APTPL_MAX_IPORT_LEN: %d\n", PR_APTPL_MAX_IPORT_LEN); @@ -1510,7 +1510,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( ret = -ENOMEM; goto out; } - if (strlen(isid) > PR_REG_ISID_LEN) { + if (strlen(isid) >= PR_REG_ISID_LEN) { printk(KERN_ERR "APTPL metadata initiator_isid" "= exceeds PR_REG_ISID_LEN: %d\n", PR_REG_ISID_LEN); @@ -1571,7 +1571,7 @@ static ssize_t target_core_dev_pr_store_attr_res_aptpl_metadata( ret = -ENOMEM; goto out; } - if (strlen(t_port) > PR_APTPL_MAX_TPORT_LEN) { + if (strlen(t_port) >= PR_APTPL_MAX_TPORT_LEN) { printk(KERN_ERR "APTPL metadata target_node=" " exceeds PR_APTPL_MAX_TPORT_LEN: %d\n", PR_APTPL_MAX_TPORT_LEN); @@ -3052,7 +3052,7 @@ static struct config_group *target_core_call_addhbatotarget( int ret; memset(buf, 0, TARGET_CORE_NAME_MAX_LEN); - if (strlen(name) > TARGET_CORE_NAME_MAX_LEN) { + if (strlen(name) >= TARGET_CORE_NAME_MAX_LEN) { printk(KERN_ERR "Passed *name strlen(): %d exceeds" " TARGET_CORE_NAME_MAX_LEN: %d\n", (int)strlen(name), TARGET_CORE_NAME_MAX_LEN); diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index f8d8af7..ba698ea 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -1431,7 +1431,7 @@ struct se_lun_acl *core_dev_init_initiator_node_lun_acl( struct se_lun_acl *lacl; struct se_node_acl *nacl; - if (strlen(initiatorname) > TRANSPORT_IQN_LEN) { + if (strlen(initiatorname) >= TRANSPORT_IQN_LEN) { printk(KERN_ERR "%s InitiatorName exceeds maximum size.\n", TPG_TFO(tpg)->get_fabric_name()); *ret = -EOVERFLOW; diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index a79f518..b662db3 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -1916,7 +1916,7 @@ static int __core_scsi3_update_aptpl_buf( pr_reg->pr_res_mapped_lun); } - if ((len + strlen(tmp) > pr_aptpl_buf_len)) { + if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { printk(KERN_ERR "Unable to update renaming" " APTPL metadata\n"); spin_unlock(&T10_RES(su_dev)->registration_lock); @@ -1934,7 +1934,7 @@ static int __core_scsi3_update_aptpl_buf( TPG_TFO(tpg)->tpg_get_tag(tpg), lun->lun_sep->sep_rtpi, lun->unpacked_lun, reg_count); - if ((len + strlen(tmp) > pr_aptpl_buf_len)) { + if ((len + strlen(tmp) >= pr_aptpl_buf_len)) { printk(KERN_ERR "Unable to update renaming" " APTPL metadata\n"); spin_unlock(&T10_RES(su_dev)->registration_lock); @@ -1986,7 +1986,7 @@ static int __core_scsi3_write_aptpl_to_file( memset(iov, 0, sizeof(struct iovec)); memset(path, 0, 512); - if (strlen(&wwn->unit_serial[0]) > 512) { + if (strlen(&wwn->unit_serial[0]) >= 512) { printk(KERN_ERR "WWN value for struct se_device does not fit" " into path buffer\n"); return -1; -- cgit v1.1 From 61db952713a8bc1b18515db3f2eac354ec8990bd Mon Sep 17 00:00:00 2001 From: Kiran Patil Date: Wed, 22 Jun 2011 16:30:22 -0700 Subject: tcm_fc: Fix ft_send_tm LUN lookup OOPs This patch fixes a bug in ft_send_tm() that was incorrectly calling ft_get_lun_for_cmd() -> transport_get_lun_for_cmd(), instead of using transport_get_lun_for_tmr() for the proper struct se_lun lookup that was triggering an OOPs in the se_cmd->tmr_req failure path. This patch fixes the issue by re-arranging the codepath where transport_get_lun_for_tmr() is called after tmr request is allocated and made it available as part of se_cmd. It also drops the now unnecessary ft_get_lun_for_cmd() unpacking code, and uses scsilun_to_int() directly ahead of transport_get_lun_for_cmd() and transport_get_lun_for_tmr() usage. Signed-off-by: Patil, Kiran Signed-off-by: Robert Love Signed-off-by: Nicholas A. Bellinger --- drivers/target/tcm_fc/tcm_fc.h | 2 +- drivers/target/tcm_fc/tfc_cmd.c | 64 +++++++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/target/tcm_fc/tcm_fc.h b/drivers/target/tcm_fc/tcm_fc.h index defff32..7b82f1b 100644 --- a/drivers/target/tcm_fc/tcm_fc.h +++ b/drivers/target/tcm_fc/tcm_fc.h @@ -144,7 +144,7 @@ enum ft_cmd_state { */ struct ft_cmd { enum ft_cmd_state state; - u16 lun; /* LUN from request */ + u32 lun; /* LUN from request */ struct ft_sess *sess; /* session held for cmd */ struct fc_seq *seq; /* sequence in exchange mgr */ struct se_cmd se_cmd; /* Local TCM I/O descriptor */ diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index c056a11..b2a1067 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c @@ -94,29 +94,6 @@ void ft_dump_cmd(struct ft_cmd *cmd, const char *caller) 16, 4, cmd->cdb, MAX_COMMAND_SIZE, 0); } -/* - * Get LUN from CDB. - */ -static int ft_get_lun_for_cmd(struct ft_cmd *cmd, u8 *lunp) -{ - u64 lun; - - lun = lunp[1]; - switch (lunp[0] >> 6) { - case 0: - break; - case 1: - lun |= (lunp[0] & 0x3f) << 8; - break; - default: - return -1; - } - if (lun >= TRANSPORT_MAX_LUNS_PER_TPG) - return -1; - cmd->lun = lun; - return transport_get_lun_for_cmd(&cmd->se_cmd, NULL, lun); -} - static void ft_queue_cmd(struct ft_sess *sess, struct ft_cmd *cmd) { struct se_queue_obj *qobj; @@ -418,6 +395,7 @@ static void ft_send_tm(struct ft_cmd *cmd) { struct se_tmr_req *tmr; struct fcp_cmnd *fcp; + struct ft_sess *sess; u8 tm_func; fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp)); @@ -425,13 +403,6 @@ static void ft_send_tm(struct ft_cmd *cmd) switch (fcp->fc_tm_flags) { case FCP_TMF_LUN_RESET: tm_func = TMR_LUN_RESET; - if (ft_get_lun_for_cmd(cmd, fcp->fc_lun) < 0) { - ft_dump_cmd(cmd, __func__); - transport_send_check_condition_and_sense(&cmd->se_cmd, - cmd->se_cmd.scsi_sense_reason, 0); - ft_sess_put(cmd->sess); - return; - } break; case FCP_TMF_TGT_RESET: tm_func = TMR_TARGET_WARM_RESET; @@ -463,6 +434,36 @@ static void ft_send_tm(struct ft_cmd *cmd) return; } cmd->se_cmd.se_tmr_req = tmr; + + switch (fcp->fc_tm_flags) { + case FCP_TMF_LUN_RESET: + cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun); + if (transport_get_lun_for_tmr(&cmd->se_cmd, cmd->lun) < 0) { + /* + * Make sure to clean up newly allocated TMR request + * since "unable to handle TMR request because failed + * to get to LUN" + */ + FT_TM_DBG("Failed to get LUN for TMR func %d, " + "se_cmd %p, unpacked_lun %d\n", + tm_func, &cmd->se_cmd, cmd->lun); + ft_dump_cmd(cmd, __func__); + sess = cmd->sess; + transport_send_check_condition_and_sense(&cmd->se_cmd, + cmd->se_cmd.scsi_sense_reason, 0); + transport_generic_free_cmd(&cmd->se_cmd, 0, 1, 0); + ft_sess_put(sess); + return; + } + break; + case FCP_TMF_TGT_RESET: + case FCP_TMF_CLR_TASK_SET: + case FCP_TMF_ABT_TASK_SET: + case FCP_TMF_CLR_ACA: + break; + default: + return; + } transport_generic_handle_tmr(&cmd->se_cmd); } @@ -635,7 +636,8 @@ static void ft_send_cmd(struct ft_cmd *cmd) fc_seq_exch(cmd->seq)->lp->tt.seq_set_resp(cmd->seq, ft_recv_seq, cmd); - ret = ft_get_lun_for_cmd(cmd, fcp->fc_lun); + cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun); + ret = transport_get_lun_for_cmd(&cmd->se_cmd, NULL, cmd->lun); if (ret < 0) { ft_dump_cmd(cmd, __func__); transport_send_check_condition_and_sense(&cmd->se_cmd, -- cgit v1.1 From 7c7cf3b9c31ed09822e5c186297991093ee13c49 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 13 Jun 2011 23:08:46 +0300 Subject: tcm_fc: Fix possible lock to unlock type deadlock There is a typo here, it should be an unlock instead of a lock. The original code will deadlock. Signed-off-by: Dan Carpenter Signed-off-by: Nicholas Bellinger --- drivers/target/tcm_fc/tfc_sess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index 03744c2..7491e21 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c @@ -332,7 +332,7 @@ void ft_sess_close(struct se_session *se_sess) lport = sess->tport->lport; port_id = sess->port_id; if (port_id == -1) { - mutex_lock(&ft_lport_lock); + mutex_unlock(&ft_lport_lock); return; } FT_SESS_DBG("port_id %x\n", port_id); -- cgit v1.1 From 95efa2863996b643083957079b9304fb3c01130f Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Thu, 23 Jun 2011 23:28:46 +0000 Subject: tcm_fc: Fix conversion spec warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes the following conversion specification warning for size_t drivers/target/tcm_fc/tfc_io.c: In function ‘ft_queue_data_in’: drivers/target/tcm_fc/tfc_io.c:209: warning: format ‘%x’ expects type ‘unsigned int’, but argument 5 has type ‘size_t’ Reported-by: Randy Dunlap Reported-by: Stephen Rothwell Signed-off-by: Nicholas Bellinger --- drivers/target/tcm_fc/tfc_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/target/tcm_fc/tfc_io.c b/drivers/target/tcm_fc/tfc_io.c index 4c3c0ef..8c4a240 100644 --- a/drivers/target/tcm_fc/tfc_io.c +++ b/drivers/target/tcm_fc/tfc_io.c @@ -203,7 +203,7 @@ int ft_queue_data_in(struct se_cmd *se_cmd) /* XXX For now, initiator will retry */ if (printk_ratelimit()) printk(KERN_ERR "%s: Failed to send frame %p, " - "xid <0x%x>, remaining <0x%x>, " + "xid <0x%x>, remaining %zu, " "lso_max <0x%x>\n", __func__, fp, ep->xid, remaining, lport->lso_max); -- cgit v1.1 From d698a34da7c5626c3c16a6311c6290522e902e7f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 23 Jun 2011 00:49:29 -0400 Subject: drm/radeon/kms: fix num_banks tiling config for fusion The field is encoded: 0 = 4 banks 1 = 8 banks 2 = 16 banks Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 445af79..12d2fdc 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2013,9 +2013,9 @@ static void evergreen_gpu_init(struct radeon_device *rdev) rdev->config.evergreen.tile_config |= (3 << 0); break; } - /* num banks is 8 on all fusion asics */ + /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */ if (rdev->flags & RADEON_IS_IGP) - rdev->config.evergreen.tile_config |= 8 << 4; + rdev->config.evergreen.tile_config |= 1 << 4; else rdev->config.evergreen.tile_config |= ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; -- cgit v1.1 From ee4017f4ac8163737793cc64df535cd246792887 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 23 Jun 2011 12:19:32 -0400 Subject: drm/radeon/kms: handle special cases for vddc A voltage value of 0xff01 requires that the driver look up the max voltage for the board based using the atom SetVoltage command table. Setting the proper voltage should fix stability on some newer asics. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_atombios.c | 36 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 27f4557..ef0e0e0 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -179,6 +179,7 @@ void radeon_pm_resume(struct radeon_device *rdev); void radeon_combios_get_power_modes(struct radeon_device *rdev); void radeon_atombios_get_power_modes(struct radeon_device *rdev); void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type); +int radeon_atom_get_max_vddc(struct radeon_device *rdev, u16 *voltage); void rs690_pm_info(struct radeon_device *rdev); extern int rv6xx_get_temp(struct radeon_device *rdev); extern int rv770_get_temp(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 1e725d9..bf2b615 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -2320,6 +2320,14 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, le16_to_cpu(clock_info->r600.usVDDC); } + /* patch up vddc if necessary */ + if (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage == 0xff01) { + u16 vddc; + + if (radeon_atom_get_max_vddc(rdev, &vddc) == 0) + rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc; + } + if (rdev->flags & RADEON_IS_IGP) { /* skip invalid modes */ if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) @@ -2630,7 +2638,35 @@ void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 v atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); } +int radeon_atom_get_max_vddc(struct radeon_device *rdev, + u16 *voltage) +{ + union set_voltage args; + int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); + u8 frev, crev; + + if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) + return -EINVAL; + + switch (crev) { + case 1: + return -EINVAL; + case 2: + args.v2.ucVoltageType = SET_VOLTAGE_GET_MAX_VOLTAGE; + args.v2.ucVoltageMode = 0; + args.v2.usVoltageLevel = 0; + + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + + *voltage = le16_to_cpu(args.v2.usVoltageLevel); + break; + default: + DRM_ERROR("Unknown table version %d, %d\n", frev, crev); + return -EINVAL; + } + return 0; +} void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) { -- cgit v1.1 From f920fe1cb74191a780d88937f36994231a8faba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Drewniak?= Date: Fri, 24 Jun 2011 02:07:35 -0400 Subject: pata_marvell: Add support for 88SE91A0, 88SE91A4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch enables support for Marvell IDE PATA controllers found on Asus P8P67LE motherboard. The formatting has been corrected and I also received a report from two users of this motherboard that the patch works. Signed-off-by: Paweł Drewniak Signed-off-by: Jeff Garzik --- drivers/ata/pata_marvell.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c index 75a6a0c..5d7f58a 100644 --- a/drivers/ata/pata_marvell.c +++ b/drivers/ata/pata_marvell.c @@ -161,6 +161,9 @@ static const struct pci_device_id marvell_pci_tbl[] = { { PCI_DEVICE(0x11AB, 0x6121), }, { PCI_DEVICE(0x11AB, 0x6123), }, { PCI_DEVICE(0x11AB, 0x6145), }, + { PCI_DEVICE(0x1B4B, 0x91A0), }, + { PCI_DEVICE(0x1B4B, 0x91A4), }, + { } /* terminate list */ }; -- cgit v1.1 From 50bc03ab5c7529fdfe4e01621efca7d26439ea00 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 21 Jun 2011 15:01:53 +0200 Subject: HID: hid-multitouch: ensure slots are initialized In case a device does not provide the feature "Maximum Contact Count", or set it at 0, the maxcontacts field may be at 0 while calling input_mt_init_slots. This patch ensures that hid-multitouch will allways report ABS_MT_SLOT and ABS_MT_TRACKING_ID to the user space. This corrects a bug found with some Ilitek devices that has been integrated in 3.0-rc0. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 0b2dcd0..3867656 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -271,6 +271,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi, } return 1; case HID_DG_CONTACTID: + if (!td->maxcontacts) + td->maxcontacts = MT_DEFAULT_MAXCONTACT; input_mt_init_slots(hi->input, td->maxcontacts); td->last_slot_field = usage->hid; td->last_field_index = field->index; @@ -547,9 +549,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) if (ret) goto fail; - if (!td->maxcontacts) - td->maxcontacts = MT_DEFAULT_MAXCONTACT; - td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot), GFP_KERNEL); if (!td->slots) { -- cgit v1.1 From 85a600825b425d52e466c6093dcdfeba85eb0044 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 21 Jun 2011 15:01:54 +0200 Subject: HID: hid-multitouch: correct VID for Stantum panels while merging hid-stantum into hid-multitouch, I did not correctly copy/paste the VIDs for those devices. This patch fixes it. Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-multitouch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 3867656..467b518 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -706,10 +706,10 @@ static const struct hid_device_id mt_devices[] = { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP)}, { .driver_data = MT_CLS_CONFIDENCE, - HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, + HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM)}, { .driver_data = MT_CLS_CONFIDENCE, - HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, + HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX)}, /* Touch International panels */ -- cgit v1.1 From c3ead6de4f6bd1c08a81f84e629e3dbf4a9078f0 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 21 Jun 2011 15:01:55 +0200 Subject: HID: hid-multitouch: add support for a new Lumio dual-touch panel Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-multitouch.c | 3 +++ 3 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index f7440e8..6f3289a 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1423,6 +1423,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH) }, + { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH_DUAL) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index aecb5a4..a756ee6 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -449,6 +449,7 @@ #define USB_VENDOR_ID_LUMIO 0x202e #define USB_DEVICE_ID_CRYSTALTOUCH 0x0006 +#define USB_DEVICE_ID_CRYSTALTOUCH_DUAL 0x0007 #define USB_VENDOR_ID_MCC 0x09db #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 467b518..62cac4d 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -676,6 +676,9 @@ static const struct hid_device_id mt_devices[] = { { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH) }, + { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, + HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, + USB_DEVICE_ID_CRYSTALTOUCH_DUAL) }, /* MosArt panels */ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, -- cgit v1.1 From 1e4e82baee8c2a8d753cbf6aa1a77326b71e59f0 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 24 Jun 2011 19:52:13 +0200 Subject: r8169: fix wrong register use. Signed-off-by: Francois Romieu Cc: Realtek linux nic maintainers --- drivers/net/r8169.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 05d8178..5990621 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -742,7 +742,7 @@ static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd) msleep(2); for (i = 0; i < 5; i++) { udelay(100); - if (!(RTL_R32(ERIDR) & ERIAR_FLAG)) + if (!(RTL_R32(ERIAR) & ERIAR_FLAG)) break; } -- cgit v1.1 From d6fe5f4eccc2a7d2ad885ecb26a192b08dcc7cd1 Mon Sep 17 00:00:00 2001 From: "John (Jay) Hernandez" Date: Thu, 23 Jun 2011 14:39:12 +0000 Subject: cxgb3: skb_record_rx_queue now records the queue index relative to the net_device. Fixed call to skb_record_rx_queue where we were passing the queue index relative to the adapter when it should have been relative to the net_device. Signed-off-by: John (Jay) Hernandez Signed-off-by: Divy Le Ray Reported-by: Shawn Bohrer Signed-off-by: David S. Miller --- drivers/net/cxgb3/sge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 3f562ba..76bf589 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -2026,7 +2026,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq, skb->ip_summed = CHECKSUM_UNNECESSARY; } else skb_checksum_none_assert(skb); - skb_record_rx_queue(skb, qs - &adap->sge.qs[0]); + skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]); if (unlikely(p->vlan_valid)) { struct vlan_group *grp = pi->vlan_grp; @@ -2145,7 +2145,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, if (!complete) return; - skb_record_rx_queue(skb, qs - &adap->sge.qs[0]); + skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]); if (unlikely(cpl->vlan_valid)) { struct vlan_group *grp = pi->vlan_grp; -- cgit v1.1 From 297c7f2f158f7dfa9ab5813260ff954f9c2f83d2 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Thu, 9 Jun 2011 23:40:27 +0000 Subject: mmc: sdio: fix runtime PM path during driver removal After commit e1866b3 "PM / Runtime: Rework runtime PM handling during driver removal" was introduced, the driver core stopped incrementing the runtime PM usage counter of the device during the invocation of the ->remove() callback. This indirectly broke SDIO's runtime PM path during driver removal, because no one calls _put_sync() anymore after ->remove() completes. This means that the power of runtime-PM-managed SDIO cards is kept high after their driver is removed (even if it was powered down beforehand). Fix that by directly calling _put_sync() when the last usage counter is downref'ed by the SDIO bus. Reported-and-tested-by: Daniel Drake Signed-off-by: Ohad Ben-Cohen Signed-off-by: Chris Ball --- drivers/mmc/core/sdio_bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index d29b9c3..d2565df 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -189,7 +189,7 @@ static int sdio_bus_remove(struct device *dev) /* Then undo the runtime PM settings in sdio_bus_probe() */ if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD) - pm_runtime_put_noidle(dev); + pm_runtime_put_sync(dev); out: return ret; -- cgit v1.1 From 4a3dc6ef344ccfe80bf986aec0b05f51af000720 Mon Sep 17 00:00:00 2001 From: Anand Gadiyar Date: Tue, 14 Jun 2011 15:59:59 +0530 Subject: mmc: omap_hsmmc: fix ocr mask usage The OMAP HSMMC driver uses an ocr_mask to determine the list of voltages supported by the card. It populates this mask based on the list of voltages supported by the regulator that supplies the voltage. Commit 64be97822b (omap4 hsmmc: Update ocr mask for MMC2 for regulator to use) passed a fixed ocr_mask from the OMAP4 SDP board file to limit the voltage to 2.9-3.0 Volts, and updated the driver to use this mask if provided, instead of using the regulator's supported voltages. However the commit is buggy - the ocr_mask is overridden by the regulator's capabilities anyway. Fix this. (The bug shows up when a system-wide suspend is attempted on the OMAP4 SDP/Blaze platforms. The eMMC card comes up at 3V, but drops to 1.65V after the system resumes). Signed-off-by: Anand Gadiyar Acked-by: Balaji T K Acked-by: Venkatraman S Tested-by: Kishore Kadiyala Signed-off-by: Sourav Poddar Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 5b2e215..8707bcd 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -429,7 +429,6 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host) return -EINVAL; } } - mmc_slot(host).ocr_mask = mmc_regulator_get_ocrmask(reg); /* Allow an aux regulator */ reg = regulator_get(host->dev, "vmmc_aux"); -- cgit v1.1 From a9120c33ffbb0b3448d833dae392edc90d6cfac2 Mon Sep 17 00:00:00 2001 From: Per Forlin Date: Fri, 17 Jun 2011 20:14:21 +0200 Subject: mmc: omap_hsmmc: use original sg_len for dma_unmap_sg Don't use the returned sg_len from dma_map_sg() as inparameter to dma_unmap_sg(). Use the original sg_len for both dma_map_sg and dma_unmap_sg according to the documentation in DMA-API.txt. Signed-off-by: Per Forlin Reviewed-by: Venkatraman S Signed-off-by: Chris Ball --- drivers/mmc/host/omap_hsmmc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 8707bcd..dedf3da 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -961,7 +961,8 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno) spin_unlock(&host->irq_lock); if (host->use_dma && dma_ch != -1) { - dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len, + dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, + host->data->sg_len, omap_hsmmc_get_dma_dir(host, host->data)); omap_free_dma(dma_ch); } @@ -1345,7 +1346,7 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data) return; } - dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len, + dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, omap_hsmmc_get_dma_dir(host, data)); req_in_progress = host->req_in_progress; -- cgit v1.1 From 7d8b4c2a4b73da8e3632603691838ca5b2a8c26d Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 20 Jun 2011 16:51:10 +0200 Subject: mmc: tmio: fix regression in TMIO_MMC_WRPROTECT_DISABLE handling Commit b6147490e6aac82 ("mmc: tmio: split core functionality, DMA and MFD glue") broke handling of the TMIO_MMC_WRPROTECT_DISABLE flag by the tmio-mmc driver. This patch restores the original behaviour. Signed-off-by: Guennadi Liakhovetski Cc: Signed-off-by: Chris Ball --- drivers/mmc/host/tmio_mmc_pio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index ad6347b..0b09e82 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c @@ -824,8 +824,8 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc) struct tmio_mmc_host *host = mmc_priv(mmc); struct tmio_mmc_data *pdata = host->pdata; - return ((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) || - !(sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT)); + return !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) || + (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT)); } static int tmio_mmc_get_cd(struct mmc_host *mmc) -- cgit v1.1 From 3e713373ce07b9f59c3901e7d39bc1edccda28da Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 24 May 2011 12:24:07 +0200 Subject: mmc: sdhi: DMA slave ID 0 is invalid Don't try to allocate DMA resources if the platform didn't specify positive DMA slave IDs. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Chris Ball --- drivers/mmc/host/sh_mobile_sdhi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index 2353bb7..ce500f0 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -92,7 +92,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev) mmc_data->ocr_mask = p->tmio_ocr_mask; mmc_data->capabilities |= p->tmio_caps; - if (p->dma_slave_tx >= 0 && p->dma_slave_rx >= 0) { + if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) { priv->param_tx.slave_id = p->dma_slave_tx; priv->param_rx.slave_id = p->dma_slave_rx; priv->dma_priv.chan_priv_tx = &priv->param_tx; -- cgit v1.1 From e9e8bcb8178e197d889ec31e79fa1ddc1732c8f9 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Tue, 21 Jun 2011 10:55:34 +0100 Subject: mmc: cb710: fix #ifdef HAVE_EFFICIENT_UNALIGNED_ACCESS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HAVE_EFFICIENT_UNALIGNED_ACCESS is a config option, therefore it needs the CONFIG_ before it when used by the preprocessor. Signed-off-by: James Hogan Acked-by: Michał Mirosław Signed-off-by: Chris Ball --- drivers/misc/cb710/sgbuf2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/cb710/sgbuf2.c b/drivers/misc/cb710/sgbuf2.c index d019746..2a40d0e 100644 --- a/drivers/misc/cb710/sgbuf2.c +++ b/drivers/misc/cb710/sgbuf2.c @@ -47,7 +47,7 @@ static uint32_t sg_dwiter_read_buffer(struct sg_mapping_iter *miter) static inline bool needs_unaligned_copy(const void *ptr) { -#ifdef HAVE_EFFICIENT_UNALIGNED_ACCESS +#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS return false; #else return ((ptr - NULL) & 3) != 0; -- cgit v1.1 From c6e633ad916e2af244dbfd11abd2bc077870bdfd Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Sat, 25 Jun 2011 19:20:11 +0100 Subject: mmc: sdio: reset card during power_restore mmc_sdio_power_restore() skips some steps that are performed in other power-related codepaths which are necessary to fully reset the card. Without this, runtime PM fails for SD8686 SDIO wifi on OLPC XO-1.5. Signed-off-by: Daniel Drake Signed-off-by: Chris Ball --- drivers/mmc/core/sdio.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 4d0c15b..262fff0 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -691,15 +691,54 @@ static int mmc_sdio_resume(struct mmc_host *host) static int mmc_sdio_power_restore(struct mmc_host *host) { int ret; + u32 ocr; BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); + + /* + * Reset the card by performing the same steps that are taken by + * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe. + * + * sdio_reset() is technically not needed. Having just powered up the + * hardware, it should already be in reset state. However, some + * platforms (such as SD8686 on OLPC) do not instantly cut power, + * meaning that a reset is required when restoring power soon after + * powering off. It is harmless in other cases. + * + * The CMD5 reset (mmc_send_io_op_cond()), according to the SDIO spec, + * is not necessary for non-removable cards. However, it is required + * for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and + * harmless in other situations. + * + * With these steps taken, mmc_select_voltage() is also required to + * restore the correct voltage setting of the card. + */ + sdio_reset(host); + mmc_go_idle(host); + mmc_send_if_cond(host, host->ocr_avail); + + ret = mmc_send_io_op_cond(host, 0, &ocr); + if (ret) + goto out; + + if (host->ocr_avail_sdio) + host->ocr_avail = host->ocr_avail_sdio; + + host->ocr = mmc_select_voltage(host, ocr & ~0x7F); + if (!host->ocr) { + ret = -EINVAL; + goto out; + } + ret = mmc_sdio_init_card(host, host->ocr, host->card, mmc_card_keep_power(host)); if (!ret && host->sdio_irqs) mmc_signal_sdio_irq(host); + +out: mmc_release_host(host); return ret; -- cgit v1.1 From ddd6fa7e794e62af3ec3eb4ffdc78489885701f2 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 23 Jun 2011 13:40:26 +0300 Subject: mmc: block: switch card to User Data Area when removing the block driver The MMC block driver and other drivers (e.g. mmc-test) will expect the card to be switched to the User Data Area eMMC partition when they start. Hence the MMC block driver should ensure it is that way when it is removed. Signed-off-by: Adrian Hunter Cc: Andrei Warkentin Signed-off-by: Chris Ball --- drivers/mmc/card/block.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 71da564..77cd083 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1297,6 +1297,9 @@ static void mmc_blk_remove(struct mmc_card *card) struct mmc_blk_data *md = mmc_get_drvdata(card); mmc_blk_remove_parts(card, md); + mmc_claim_host(card->host); + mmc_blk_part_switch(card, md); + mmc_release_host(card->host); mmc_blk_remove_req(md); mmc_set_drvdata(card, NULL); } -- cgit v1.1 From 4cf8c6dd2e261da94b87c4deadcc136ab022b6ac Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 23 Jun 2011 13:40:27 +0300 Subject: mmc: core: make erase timeout calculation allow for gated clock The erase timeout calculation may depend on clock rate which is zero if the clock is gated, so use mmc_host_clk_rate() which allows for that case. Signed-off-by: Adrian Hunter Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 68091dd..7843efe 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1245,7 +1245,7 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card, */ timeout_clks <<= 1; timeout_us += (timeout_clks * 1000) / - (card->host->ios.clock / 1000); + (mmc_host_clk_rate(card->host) / 1000); erase_timeout = timeout_us / 1000; -- cgit v1.1 From d09408ade08a08a710a247fb52aa50101e73ebf7 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 23 Jun 2011 13:40:28 +0300 Subject: mmc: queue: append partition subname to queue thread name For example, an eMMC with 2 boot partitions will have 3 threads. The names change from: 40 ? 00:00:00 mmcqd/0 41 ? 00:00:00 mmcqd/0 42 ? 00:00:00 mmcqd/0 to: 40 ? 00:00:00 mmcqd/0 41 ? 00:00:00 mmcqd/0boot0 42 ? 00:00:00 mmcqd/0boot1 Signed-off-by: Adrian Hunter Cc: Andrei Warkentin Signed-off-by: Chris Ball --- drivers/mmc/card/block.c | 2 +- drivers/mmc/card/queue.c | 8 +++++--- drivers/mmc/card/queue.h | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 77cd083..f85e422 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1024,7 +1024,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, INIT_LIST_HEAD(&md->part); md->usage = 1; - ret = mmc_init_queue(&md->queue, card, &md->lock); + ret = mmc_init_queue(&md->queue, card, &md->lock, subname); if (ret) goto err_putdisk; diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index c07322c..3e2db1c 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -106,10 +106,12 @@ static void mmc_request(struct request_queue *q) * @mq: mmc queue * @card: mmc card to attach this queue * @lock: queue lock + * @subname: partition subname * * Initialise a MMC card request queue. */ -int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock) +int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, + spinlock_t *lock, const char *subname) { struct mmc_host *host = card->host; u64 limit = BLK_BOUNCE_HIGH; @@ -209,8 +211,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock sema_init(&mq->thread_sem, 1); - mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd/%d", - host->index); + mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd/%d%s", + host->index, subname ? subname : ""); if (IS_ERR(mq->thread)) { ret = PTR_ERR(mq->thread); diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h index 64e66e0..6223ef8 100644 --- a/drivers/mmc/card/queue.h +++ b/drivers/mmc/card/queue.h @@ -19,7 +19,8 @@ struct mmc_queue { unsigned int bounce_sg_len; }; -extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *); +extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *, + const char *); extern void mmc_cleanup_queue(struct mmc_queue *); extern void mmc_queue_suspend(struct mmc_queue *); extern void mmc_queue_resume(struct mmc_queue *); -- cgit v1.1 From c31b55cd4eaf050bb5a15bd8251da1b3c7edeb1c Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 23 Jun 2011 13:40:29 +0300 Subject: mmc: queue: bring discard_granularity/alignment into line with SCSI SCSI defines discard alignment as the offset to the first optimal discard. In the case of SD/MMC, that is always zero which is the default. SCSI defines discard granularity as a hint of a optimal discard size. That is much better expressed by the MMC "preferred erase size" (pref_erase) field. Signed-off-by: Adrian Hunter Signed-off-by: Chris Ball --- drivers/mmc/card/queue.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index 3e2db1c..6413afa 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -135,12 +135,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, mq->queue->limits.max_discard_sectors = UINT_MAX; if (card->erased_byte == 0) mq->queue->limits.discard_zeroes_data = 1; - if (!mmc_can_trim(card) && is_power_of_2(card->erase_size)) { - mq->queue->limits.discard_granularity = - card->erase_size << 9; - mq->queue->limits.discard_alignment = - card->erase_size << 9; - } + mq->queue->limits.discard_granularity = card->pref_erase << 9; if (mmc_can_secure_erase_trim(card)) queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, mq->queue); -- cgit v1.1 From 8c9f3aaf8e174ca914889ab7a916586f8fd1e641 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 16 Jun 2011 09:19:13 -0700 Subject: drm/i915: split page flip queueing into per-chipset functions This makes things a little clearer and prevents us from running old code on a new chipset that may not be supported. Signed-off-by: Jesse Barnes Reviewied-by: Ben Widawsky Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_drv.h | 3 + drivers/gpu/drm/i915/intel_display.c | 269 ++++++++++++++++++++++++----------- 2 files changed, 189 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f63ee16..eddabf6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -211,6 +211,9 @@ struct drm_i915_display_funcs { void (*fdi_link_train)(struct drm_crtc *crtc); void (*init_clock_gating)(struct drm_device *dev); void (*init_pch_clock_gating)(struct drm_device *dev); + int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj); /* clock updates for mode set */ /* cursor updates */ /* render clock increase/decrease */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index aa43e7b..0f4ed2a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6261,6 +6261,164 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane) spin_unlock_irqrestore(&dev->event_lock, flags); } +static int intel_gen2_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + unsigned long offset; + u32 flip_mask; + int ret; + + ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); + if (ret) + goto out; + + /* Offset into the new buffer for cases of shared fbs between CRTCs */ + offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8; + + ret = BEGIN_LP_RING(6); + if (ret) + goto out; + + /* Can't queue multiple flips, so wait for the previous + * one to finish before executing the next. + */ + if (intel_crtc->plane) + flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; + else + flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; + OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); + OUT_RING(MI_NOOP); + OUT_RING(MI_DISPLAY_FLIP | + MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); + OUT_RING(fb->pitch); + OUT_RING(obj->gtt_offset + offset); + OUT_RING(MI_NOOP); + ADVANCE_LP_RING(); +out: + return ret; +} + +static int intel_gen3_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + unsigned long offset; + u32 flip_mask; + int ret; + + ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); + if (ret) + goto out; + + /* Offset into the new buffer for cases of shared fbs between CRTCs */ + offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8; + + ret = BEGIN_LP_RING(6); + if (ret) + goto out; + + if (intel_crtc->plane) + flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; + else + flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; + OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); + OUT_RING(MI_NOOP); + OUT_RING(MI_DISPLAY_FLIP_I915 | + MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); + OUT_RING(fb->pitch); + OUT_RING(obj->gtt_offset + offset); + OUT_RING(MI_NOOP); + + ADVANCE_LP_RING(); +out: + return ret; +} + +static int intel_gen4_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + uint32_t pf, pipesrc; + int ret; + + ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); + if (ret) + goto out; + + ret = BEGIN_LP_RING(4); + if (ret) + goto out; + + /* i965+ uses the linear or tiled offsets from the + * Display Registers (which do not change across a page-flip) + * so we need only reprogram the base address. + */ + OUT_RING(MI_DISPLAY_FLIP | + MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); + OUT_RING(fb->pitch); + OUT_RING(obj->gtt_offset | obj->tiling_mode); + + /* XXX Enabling the panel-fitter across page-flip is so far + * untested on non-native modes, so ignore it for now. + * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; + */ + pf = 0; + pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; + OUT_RING(pf | pipesrc); + ADVANCE_LP_RING(); +out: + return ret; +} + +static int intel_gen6_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + uint32_t pf, pipesrc; + int ret; + + ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); + if (ret) + goto out; + + ret = BEGIN_LP_RING(4); + if (ret) + goto out; + + OUT_RING(MI_DISPLAY_FLIP | + MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); + OUT_RING(fb->pitch | obj->tiling_mode); + OUT_RING(obj->gtt_offset); + + pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; + pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; + OUT_RING(pf | pipesrc); + ADVANCE_LP_RING(); +out: + return ret; +} + +static int intel_default_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj) +{ + return -ENODEV; +} + static int intel_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event) @@ -6271,9 +6429,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, struct drm_i915_gem_object *obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_unpin_work *work; - unsigned long flags, offset; - int pipe = intel_crtc->pipe; - u32 pf, pipesrc; + unsigned long flags; int ret; work = kzalloc(sizeof *work, GFP_KERNEL); @@ -6302,9 +6458,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, obj = intel_fb->obj; mutex_lock(&dev->struct_mutex); - ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); - if (ret) - goto cleanup_work; /* Reference the objects for the scheduled work. */ drm_gem_object_reference(&work->old_fb_obj->base); @@ -6316,91 +6469,18 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, if (ret) goto cleanup_objs; - if (IS_GEN3(dev) || IS_GEN2(dev)) { - u32 flip_mask; - - /* Can't queue multiple flips, so wait for the previous - * one to finish before executing the next. - */ - ret = BEGIN_LP_RING(2); - if (ret) - goto cleanup_objs; - - if (intel_crtc->plane) - flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; - else - flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; - OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); - OUT_RING(MI_NOOP); - ADVANCE_LP_RING(); - } - work->pending_flip_obj = obj; work->enable_stall_check = true; - /* Offset into the new buffer for cases of shared fbs between CRTCs */ - offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8; - - ret = BEGIN_LP_RING(4); - if (ret) - goto cleanup_objs; - /* Block clients from rendering to the new back buffer until * the flip occurs and the object is no longer visible. */ atomic_add(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); - switch (INTEL_INFO(dev)->gen) { - case 2: - OUT_RING(MI_DISPLAY_FLIP | - MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - OUT_RING(fb->pitch); - OUT_RING(obj->gtt_offset + offset); - OUT_RING(MI_NOOP); - break; - - case 3: - OUT_RING(MI_DISPLAY_FLIP_I915 | - MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - OUT_RING(fb->pitch); - OUT_RING(obj->gtt_offset + offset); - OUT_RING(MI_NOOP); - break; - - case 4: - case 5: - /* i965+ uses the linear or tiled offsets from the - * Display Registers (which do not change across a page-flip) - * so we need only reprogram the base address. - */ - OUT_RING(MI_DISPLAY_FLIP | - MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - OUT_RING(fb->pitch); - OUT_RING(obj->gtt_offset | obj->tiling_mode); - - /* XXX Enabling the panel-fitter across page-flip is so far - * untested on non-native modes, so ignore it for now. - * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; - */ - pf = 0; - pipesrc = I915_READ(PIPESRC(pipe)) & 0x0fff0fff; - OUT_RING(pf | pipesrc); - break; - - case 6: - case 7: - OUT_RING(MI_DISPLAY_FLIP | - MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - OUT_RING(fb->pitch | obj->tiling_mode); - OUT_RING(obj->gtt_offset); - - pf = I915_READ(PF_CTL(pipe)) & PF_ENABLE; - pipesrc = I915_READ(PIPESRC(pipe)) & 0x0fff0fff; - OUT_RING(pf | pipesrc); - break; - } - ADVANCE_LP_RING(); + ret = dev_priv->display.queue_flip(dev, crtc, fb, obj); + if (ret) + goto cleanup_pending; mutex_unlock(&dev->struct_mutex); @@ -6408,10 +6488,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, return 0; +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); -cleanup_work: mutex_unlock(&dev->struct_mutex); spin_lock_irqsave(&dev->event_lock, flags); @@ -7656,6 +7737,28 @@ static void intel_init_display(struct drm_device *dev) else dev_priv->display.get_fifo_size = i830_get_fifo_size; } + + /* Default just returns -ENODEV to indicate unsupported */ + dev_priv->display.queue_flip = intel_default_queue_flip; + + switch (INTEL_INFO(dev)->gen) { + case 2: + dev_priv->display.queue_flip = intel_gen2_queue_flip; + break; + + case 3: + dev_priv->display.queue_flip = intel_gen3_queue_flip; + break; + + case 4: + case 5: + dev_priv->display.queue_flip = intel_gen4_queue_flip; + break; + + case 6: + dev_priv->display.queue_flip = intel_gen6_queue_flip; + break; + } } /* -- cgit v1.1 From 7c9017e5b77118439952fe8dc22809bae4fae4b6 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 16 Jun 2011 12:18:54 -0700 Subject: drm/i915: add Ivy Bridge page flip support Use the blit ring for submitting flips since the render ring doesn't generate flip complete interrupts. Fixes bugs: https://bugs.freedesktop.org/show_bug.cgi?id=38362 https://bugs.freedesktop.org/show_bug.cgi?id=38392 https://bugs.freedesktop.org/show_bug.cgi?id=38393 Signed-off-by: Jesse Barnes Reviewed-by: Daniel Vetter Reviewed-by: Kenneth Graunke Reviewed-by: Ben Widawsky Tested-by: Jian J Zhao Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/intel_display.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0f4ed2a..21b6f93 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6411,6 +6411,39 @@ out: return ret; } +/* + * On gen7 we currently use the blit ring because (in early silicon at least) + * the render ring doesn't give us interrpts for page flip completion, which + * means clients will hang after the first flip is queued. Fortunately the + * blit ring generates interrupts properly, so use it instead. + */ +static int intel_gen7_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; + int ret; + + ret = intel_pin_and_fence_fb_obj(dev, obj, ring); + if (ret) + goto out; + + ret = intel_ring_begin(ring, 4); + if (ret) + goto out; + + intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | (intel_crtc->plane << 19)); + intel_ring_emit(ring, (fb->pitch | obj->tiling_mode)); + intel_ring_emit(ring, (obj->gtt_offset)); + intel_ring_emit(ring, (MI_NOOP)); + intel_ring_advance(ring); +out: + return ret; +} + static int intel_default_queue_flip(struct drm_device *dev, struct drm_crtc *crtc, struct drm_framebuffer *fb, @@ -7758,6 +7791,9 @@ static void intel_init_display(struct drm_device *dev) case 6: dev_priv->display.queue_flip = intel_gen6_queue_flip; break; + case 7: + dev_priv->display.queue_flip = intel_gen7_queue_flip; + break; } } -- cgit v1.1 From 8b1ab60c767f33d79894ef66037ef851a7a88fc8 Mon Sep 17 00:00:00 2001 From: Arvid Brodin Date: Fri, 17 Jun 2011 18:45:37 +0200 Subject: usb/isp1760: Fix bug preventing the unlinking of control urbs Both control and bulk transfers use isp1760 slots of type ATL, but the driver unlink code for ATL slots only acts on urbs describing a bulk transfer, letting the code for INT slots take care of the unlink instead, which often ended up removing the interrupt transfer for root hub events instead. That's not good, and gets fixed by this patch. Signed-off-by: Arvid Brodin Cc: Sebastian Andrzej Siewior Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp1760-hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index c9e6e45..55d3d58 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -1555,7 +1555,7 @@ static void kill_transfer(struct usb_hcd *hcd, struct urb *urb, /* We need to forcefully reclaim the slot since some transfers never return, e.g. interrupt transfers and NAKed bulk transfers. */ - if (usb_pipebulk(urb->pipe)) { + if (usb_pipecontrol(urb->pipe) || usb_pipebulk(urb->pipe)) { skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG); skip_map |= (1 << qh->slot); reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map); -- cgit v1.1 From 309427b6351b763917caac3e4b2ab5651df99823 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 17 Jun 2011 17:30:23 +0200 Subject: USB: Add new FT232H chip to drivers/usb/serial/ftdi_sio.c appended patch adds support for the new FTDI FT232H chip. This chip is a single channel version of the dual FT2232H/quad FT4232H, coming with it's own default PID 0x6014 (FT2232H uses the same PID 0x6010 like FT2232C, FT4232H has also it's own PID). The patch was checked on an UM232H module and a terminal program with TX/RX shorted to that typing in the terminal reproduced the characters. Signed-off-by: Uwe Bonnes Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 19 ++++++++++++++----- drivers/usb/serial/ftdi_sio.h | 3 ++- drivers/usb/serial/ftdi_sio_ids.h | 1 + 3 files changed, 17 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 1627289..2e06b90 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -179,6 +179,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) }, { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_232H_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) }, @@ -848,7 +849,8 @@ static const char *ftdi_chip_name[] = { [FT2232C] = "FT2232C", [FT232RL] = "FT232RL", [FT2232H] = "FT2232H", - [FT4232H] = "FT4232H" + [FT4232H] = "FT4232H", + [FT232H] = "FT232H" }; @@ -1168,6 +1170,7 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty, break; case FT2232H: /* FT2232H chip */ case FT4232H: /* FT4232H chip */ + case FT232H: /* FT232H chip */ if ((baud <= 12000000) & (baud >= 1200)) { div_value = ftdi_2232h_baud_to_divisor(baud); } else if (baud < 1200) { @@ -1429,9 +1432,12 @@ static void ftdi_determine_type(struct usb_serial_port *port) } else if (version < 0x600) { /* Assume it's an FT232BM (or FT245BM) */ priv->chip_type = FT232BM; - } else { - /* Assume it's an FT232R */ + } else if (version < 0x900) { + /* Assume it's an FT232RL */ priv->chip_type = FT232RL; + } else { + /* Assume it's an FT232H */ + priv->chip_type = FT232H; } dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]); } @@ -1559,7 +1565,8 @@ static int create_sysfs_attrs(struct usb_serial_port *port) priv->chip_type == FT2232C || priv->chip_type == FT232RL || priv->chip_type == FT2232H || - priv->chip_type == FT4232H)) { + priv->chip_type == FT4232H || + priv->chip_type == FT232H)) { retval = device_create_file(&port->dev, &dev_attr_latency_timer); } @@ -1580,7 +1587,8 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) priv->chip_type == FT2232C || priv->chip_type == FT232RL || priv->chip_type == FT2232H || - priv->chip_type == FT4232H) { + priv->chip_type == FT4232H || + priv->chip_type == FT232H) { device_remove_file(&port->dev, &dev_attr_latency_timer); } } @@ -2212,6 +2220,7 @@ static int ftdi_tiocmget(struct tty_struct *tty) case FT232RL: case FT2232H: case FT4232H: + case FT232H: len = 2; break; default: diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 213fe3d..19584fa 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -156,7 +156,8 @@ enum ftdi_chip_type { FT2232C = 4, FT232RL = 5, FT2232H = 6, - FT4232H = 7 + FT4232H = 7, + FT232H = 8 }; enum ftdi_sio_baudrate { diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index ab1fcdf..19156d1 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -22,6 +22,7 @@ #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */ #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */ #define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */ +#define FTDI_232H_PID 0x6014 /* Single channel hi-speed device */ #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */ #define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */ -- cgit v1.1 From c27d5368ef1f7ea40bcd1fb2626f4c99d77e0080 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Mon, 20 Jun 2011 17:22:36 +0200 Subject: USB: ehci-ath79: fix a NULL pointer dereference Loading the ehci-hcd module on the ath79 platform causes a NULL pointer dereference: CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == c0252928, ra == c00de968 Oops[#1]: Cpu 0 $ 0 : 00000000 00000070 00000001 00000000 $ 4 : 802cf870 0000117e ffffffff 8019c7bc $ 8 : 0000000a 00000002 00000001 fffffffb $12 : 8026ef20 0000000f ffffff80 802dad3c $16 : 8077a2d4 8077a200 c00f3484 8019ed84 $20 : c00f0000 00000003 000000a0 80262c2c $24 : 00000002 80079da0 $28 : 80788000 80789c80 80262b14 c00de968 Hi : 00000000 Lo : b61f0000 epc : c0252928 __mod_vermagic5+0xc260/0xc7e8 [ehci_hcd] Not tainted ra : c00de968 usb_add_hcd+0x2a4/0x858 [usbcore] Status: 1000c003 KERNEL EXL IE Cause : 00800008 BadVA : 00000000 PrId : 00019374 (MIPS 24Kc) Modules linked in: ehci_hcd(+) pppoe pppox ipt_REJECT xt_TCPMSS ipt_LOG xt_comment xt_multiport xt_mac xt_limit iptable_mangle iptable_filte r ip_tables xt_tcpudp x_tables ppp_async ppp_generic slhc ath mac80211 usbcore nls_base input_polldev crc_ccitt cfg80211 compat input_core a rc4 aes_generic crypto_algapi Process insmod (pid: 379, threadinfo=80788000, task=80ca2180, tls=77fe52d0) Stack : c0253184 80c57d80 80789cac 8077a200 00000001 8019edc0 807fa800 8077a200 8077a290 c00f3484 8019ed84 c00f0000 00000003 000000a0 80262c2c c00de968 802d0000 800878cc c0253228 c02528e4 c0253184 80c57d80 80bf6800 80ca2180 8007b75c 00000000 8077a200 802cf830 802d0000 00000003 fffffff4 00000015 00000348 00000124 800b189c c024bb4c c0255000 801a27e8 c0253228 c02528e4 ... Call Trace: [] __mod_vermagic5+0xc260/0xc7e8 [ehci_hcd] It is caused by: commit c430131a02d677aa708f56342c1565edfdacb3c0 Author: Jan Andersson Date: Tue May 3 20:11:57 2011 +0200 USB: EHCI: Support controllers with big endian capability regs The two first HC capability registers (CAPLENGTH and HCIVERSION) are defined as one 8-bit and one 16-bit register. Most HC implementations have selected to treat these registers as part of a 32-bit register, giving the same layout for both big and small endian systems. This patch adds a new quirk, big_endian_capbase, to support controllers with big endian register interfaces that treat HCIVERSION and CAPLENGTH as individual registers. Signed-off-by: Jan Andersson Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman The reading of the HC capability register has been moved by that commit to a place where the ehci->caps field is not initialized yet. This patch moves the reading of the register back to the original place. Acked-by: Jan Andersson Cc: Alan Stern Signed-off-by: Gabor Juhos Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-ath79.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-ath79.c b/drivers/usb/host/ehci-ath79.c index 98cc8a1..aa248c2 100644 --- a/drivers/usb/host/ehci-ath79.c +++ b/drivers/usb/host/ehci-ath79.c @@ -44,7 +44,6 @@ static int ehci_ath79_init(struct usb_hcd *hcd) struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct platform_device *pdev = to_platform_device(hcd->self.controller); const struct platform_device_id *id; - int hclength; int ret; id = platform_get_device_id(pdev); @@ -53,20 +52,23 @@ static int ehci_ath79_init(struct usb_hcd *hcd) return -EINVAL; } - hclength = HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); switch (id->driver_data) { case EHCI_ATH79_IP_V1: ehci->has_synopsys_hc_bug = 1; ehci->caps = hcd->regs; - ehci->regs = hcd->regs + hclength; + ehci->regs = hcd->regs + + HC_LENGTH(ehci, + ehci_readl(ehci, &ehci->caps->hc_capbase)); break; case EHCI_ATH79_IP_V2: hcd->has_tt = 1; ehci->caps = hcd->regs + 0x100; - ehci->regs = hcd->regs + 0x100 + hclength; + ehci->regs = hcd->regs + 0x100 + + HC_LENGTH(ehci, + ehci_readl(ehci, &ehci->caps->hc_capbase)); break; default: -- cgit v1.1 From 87abd0a92c72eea71542d6c972c67e39e584e989 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 21 Jun 2011 13:24:42 +0900 Subject: usb: r8a66597-hcd: fix cannot detect low/full speed device This controller can control "Transaction Translators", but the hcd->has_tt is not set. Since the commit d199c96d41d80a567493e12b8e96ea056a1350c1 ("USB: prevent buggy from crashing the USB stack") has checked it, the driver could not work the low/full speed device. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/r8a66597-hcd.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index db6f8b9..4586369 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2517,6 +2517,7 @@ static int __devinit r8a66597_probe(struct platform_device *pdev) INIT_LIST_HEAD(&r8a66597->child_device); hcd->rsrc_start = res->start; + hcd->has_tt = 1; ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger); if (ret != 0) { -- cgit v1.1 From 89089158d191ba0195b33ebf35f91ed217d44848 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 24 Jun 2011 09:28:32 -0700 Subject: Staging: fix more iio builds when IIO_RING_BUFFER is not enabled Fix lots more build errors in staging/iio when CONFIG_IIO_RING_BUFFER is not enabled by moving enums and defines outside of the CONFIG_IIO_RING_BUFFER ifdef block. Examples (one from each driver; there were 116 total errors): drivers/staging/iio/accel/adis16204_core.c:437: error: 'ADIS16204_SCAN_SUPPLY' undeclared here (not in a function) drivers/staging/iio/accel/adis16209_core.c:410: error: 'ADIS16209_SCAN_SUPPLY' undeclared here (not in a function) drivers/staging/iio/gyro/adis16260_core.c:420: error: 'ADIS16260_SCAN_GYRO' undeclared here (not in a function) drivers/staging/iio/imu/adis16400_core.c:565: error: 'ADIS16400_SCAN_SUPPLY' undeclared here (not in a function) Signed-off-by: Randy Dunlap Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16204.h | 2 +- drivers/staging/iio/accel/adis16209.h | 4 ++-- drivers/staging/iio/gyro/adis16260.h | 2 +- drivers/staging/iio/imu/adis16400.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16204.h b/drivers/staging/iio/accel/adis16204.h index 5310a42..1690c0d 100644 --- a/drivers/staging/iio/accel/adis16204.h +++ b/drivers/staging/iio/accel/adis16204.h @@ -84,7 +84,6 @@ struct adis16204_state { int adis16204_set_irq(struct iio_dev *indio_dev, bool enable); -#ifdef CONFIG_IIO_RING_BUFFER enum adis16204_scan { ADIS16204_SCAN_SUPPLY, ADIS16204_SCAN_ACC_X, @@ -93,6 +92,7 @@ enum adis16204_scan { ADIS16204_SCAN_TEMP, }; +#ifdef CONFIG_IIO_RING_BUFFER void adis16204_remove_trigger(struct iio_dev *indio_dev); int adis16204_probe_trigger(struct iio_dev *indio_dev); diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h index 58d08db..3153cbe 100644 --- a/drivers/staging/iio/accel/adis16209.h +++ b/drivers/staging/iio/accel/adis16209.h @@ -121,8 +121,6 @@ struct adis16209_state { int adis16209_set_irq(struct iio_dev *indio_dev, bool enable); -#ifdef CONFIG_IIO_RING_BUFFER - #define ADIS16209_SCAN_SUPPLY 0 #define ADIS16209_SCAN_ACC_X 1 #define ADIS16209_SCAN_ACC_Y 2 @@ -132,6 +130,8 @@ int adis16209_set_irq(struct iio_dev *indio_dev, bool enable); #define ADIS16209_SCAN_INCLI_Y 6 #define ADIS16209_SCAN_ROT 7 +#ifdef CONFIG_IIO_RING_BUFFER + void adis16209_remove_trigger(struct iio_dev *indio_dev); int adis16209_probe_trigger(struct iio_dev *indio_dev); diff --git a/drivers/staging/iio/gyro/adis16260.h b/drivers/staging/iio/gyro/adis16260.h index 702dc98..24bf70e 100644 --- a/drivers/staging/iio/gyro/adis16260.h +++ b/drivers/staging/iio/gyro/adis16260.h @@ -104,7 +104,6 @@ struct adis16260_state { int adis16260_set_irq(struct iio_dev *indio_dev, bool enable); -#ifdef CONFIG_IIO_RING_BUFFER /* At the moment triggers are only used for ring buffer * filling. This may change! */ @@ -115,6 +114,7 @@ int adis16260_set_irq(struct iio_dev *indio_dev, bool enable); #define ADIS16260_SCAN_TEMP 3 #define ADIS16260_SCAN_ANGL 4 +#ifdef CONFIG_IIO_RING_BUFFER void adis16260_remove_trigger(struct iio_dev *indio_dev); int adis16260_probe_trigger(struct iio_dev *indio_dev); diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h index db184d1..e87715b9 100644 --- a/drivers/staging/iio/imu/adis16400.h +++ b/drivers/staging/iio/imu/adis16400.h @@ -158,7 +158,6 @@ struct adis16400_state { int adis16400_set_irq(struct iio_dev *indio_dev, bool enable); -#ifdef CONFIG_IIO_RING_BUFFER /* At the moment triggers are only used for ring buffer * filling. This may change! */ @@ -182,6 +181,7 @@ int adis16400_set_irq(struct iio_dev *indio_dev, bool enable); #define ADIS16300_SCAN_INCLI_X 12 #define ADIS16300_SCAN_INCLI_Y 13 +#ifdef CONFIG_IIO_RING_BUFFER void adis16400_remove_trigger(struct iio_dev *indio_dev); int adis16400_probe_trigger(struct iio_dev *indio_dev); -- cgit v1.1 From 6fab3e1fbc83e6d61e8c28ceab513274183a96f6 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 23 Jun 2011 12:45:37 +0100 Subject: Staging: Comedi: Build only on arches providing PAGE_KERNEL_NOCACHE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On architectures that don't define PAGE_KERNEL_NOCACHE, the Comedi driver turns into tragedy: CC [M] drivers/staging/comedi/drivers.o drivers/staging/comedi/drivers.c: In function ‘comedi_buf_alloc’: drivers/staging/comedi/drivers.c:505:41: error: ‘PAGE_KERNEL_NOCACHE’ undeclared (first use in this function) drivers/staging/comedi/drivers.c:505:41: note: each undeclared identifier is rep orted only once for each function it appears in make[3]: *** [drivers/staging/comedi/drivers.o] Error 1 Restrict the driver to only those architectures that define PAGE_KERNEL_NOCACHE. PAGE_KERNEL_NOCACHE is a kludge - some system architectures such as SGI IP27 are even uable to offer uncached operation - at least in the way an unwitting driver might assume. I haven't looked in details how the driver is using the area vmaped with PAGE_KERNEL_NOCACHE but maybe doing it XFS-style using cached memory and the flush_kernel_vmap_range / invalidate_kernel_vmap_range APIs in conjunction with the DMA API is a practical alternative. Signed-off-by: Ralf Baechle Reported-by: David Miller Reported-by: Stephen Rothwell Acked-by: Geert Uytterhoeven Cc: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 1502d80..bccdc12 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -2,6 +2,7 @@ config COMEDI tristate "Data acquisition support (comedi)" default N depends on m + depends on BROKEN || FRV || M32R || MN10300 || SUPERH || TILE || X86 ---help--- Enable support a wide range of data acquisition devices for Linux. -- cgit v1.1 From fdf2df0e8ce634c9ee5f740a9303e8518ca78932 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 14 Jun 2011 15:00:18 -0700 Subject: Staging: fix iio builds when IIO_RING_BUFFER is not enabled Fix build by moving enum list outside of #ifdef CONFIG_IIO_RING_BUFFER. drivers/staging/iio/accel/adis16201_core.c:413: error: 'ADIS16201_SCAN_SUPPLY' undeclared here (not in a function) drivers/staging/iio/accel/adis16201_core.c:417: error: 'ADIS16201_SCAN_TEMP' undeclared here (not in a function) drivers/staging/iio/accel/adis16201_core.c:422: error: 'ADIS16201_SCAN_ACC_X' undeclared here (not in a function) drivers/staging/iio/accel/adis16201_core.c:427: error: 'ADIS16201_SCAN_ACC_Y' undeclared here (not in a function) drivers/staging/iio/accel/adis16201_core.c:432: error: 'ADIS16201_SCAN_AUX_ADC' undeclared here (not in a function) drivers/staging/iio/accel/adis16201_core.c:436: error: 'ADIS16201_SCAN_INCLI_X' undeclared here (not in a function) drivers/staging/iio/accel/adis16201_core.c:441: error: 'ADIS16201_SCAN_INCLI_Y' undeclared here (not in a function) vers/staging/iio/accel/adis16203_core.c:374: error: 'ADIS16203_SCAN_SUPPLY' undeclared here (not in a function) drivers/staging/iio/accel/adis16203_core.c:378: error: 'ADIS16203_SCAN_AUX_ADC' undeclared here (not in a function) drivers/staging/iio/accel/adis16203_core.c:382: error: 'ADIS16203_SCAN_INCLI_X' undeclared here (not in a function) drivers/staging/iio/accel/adis16203_core.c:388: error: 'ADIS16203_SCAN_INCLI_Y' undeclared here (not in a function) drivers/staging/iio/accel/adis16203_core.c:392: error: 'ADIS16203_SCAN_TEMP' undeclared here (not in a function) Signed-off-by: Randy Dunlap Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16201.h | 2 +- drivers/staging/iio/accel/adis16203.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/iio/accel/adis16201.h b/drivers/staging/iio/accel/adis16201.h index 0b9b854..4cc1a5b 100644 --- a/drivers/staging/iio/accel/adis16201.h +++ b/drivers/staging/iio/accel/adis16201.h @@ -81,7 +81,6 @@ struct adis16201_state { int adis16201_set_irq(struct iio_dev *indio_dev, bool enable); -#ifdef CONFIG_IIO_RING_BUFFER enum adis16201_scan { ADIS16201_SCAN_SUPPLY, ADIS16201_SCAN_ACC_X, @@ -92,6 +91,7 @@ enum adis16201_scan { ADIS16201_SCAN_INCLI_Y, }; +#ifdef CONFIG_IIO_RING_BUFFER void adis16201_remove_trigger(struct iio_dev *indio_dev); int adis16201_probe_trigger(struct iio_dev *indio_dev); diff --git a/drivers/staging/iio/accel/adis16203.h b/drivers/staging/iio/accel/adis16203.h index 8bb8ce5..175e21b 100644 --- a/drivers/staging/iio/accel/adis16203.h +++ b/drivers/staging/iio/accel/adis16203.h @@ -76,7 +76,6 @@ struct adis16203_state { int adis16203_set_irq(struct iio_dev *indio_dev, bool enable); -#ifdef CONFIG_IIO_RING_BUFFER enum adis16203_scan { ADIS16203_SCAN_SUPPLY, ADIS16203_SCAN_AUX_ADC, @@ -85,6 +84,7 @@ enum adis16203_scan { ADIS16203_SCAN_INCLI_Y, }; +#ifdef CONFIG_IIO_RING_BUFFER void adis16203_remove_trigger(struct iio_dev *indio_dev); int adis16203_probe_trigger(struct iio_dev *indio_dev); -- cgit v1.1 From a534bb6eea72c0d082dd2faab85450e5554ba1c8 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Mon, 13 Jun 2011 16:39:31 +0300 Subject: Staging: mei: fix suspend failure wait_event_interruptible_timeout return value was wrongly used. The remaining timeout was used as the error code. This fix translated wait_event_interruptible_timeout return value into error code that can be propagated. [10291.674121] pci_pm_suspend(): mei_pci_suspend+0x0/0x8b [mei] returns 2500 It's thinkpad t400 with 00:03.0 Communication controller [0780]: Intel Corporation Mobile 4 Series Chipset MEI Controller [8086:2a44] (rev 07) Reported-by: Arkadiusz Miskiewicz Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/staging/mei/init.c | 2 +- drivers/staging/mei/wd.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/mei/init.c b/drivers/staging/mei/init.c index d1ffa32..685fcf6 100644 --- a/drivers/staging/mei/init.c +++ b/drivers/staging/mei/init.c @@ -189,7 +189,7 @@ int mei_hw_init(struct mei_device *dev) mutex_lock(&dev->device_lock); } - if (!err && !dev->recvd_msg) { + if (err <= 0 && !dev->recvd_msg) { dev->mei_state = MEI_DISABLED; dev_dbg(&dev->pdev->dev, "wait_event_interruptible_timeout failed" diff --git a/drivers/staging/mei/wd.c b/drivers/staging/mei/wd.c index 2564b03..fff53d0 100644 --- a/drivers/staging/mei/wd.c +++ b/drivers/staging/mei/wd.c @@ -169,10 +169,15 @@ int mei_wd_stop(struct mei_device *dev, bool preserve) ret = wait_event_interruptible_timeout(dev->wait_stop_wd, dev->wd_stopped, 10 * HZ); mutex_lock(&dev->device_lock); - if (!dev->wd_stopped) - dev_dbg(&dev->pdev->dev, "stop wd failed to complete.\n"); - else - dev_dbg(&dev->pdev->dev, "stop wd complete.\n"); + if (dev->wd_stopped) { + dev_dbg(&dev->pdev->dev, "stop wd complete ret=%d.\n", ret); + ret = 0; + } else { + if (!ret) + ret = -ETIMEDOUT; + dev_warn(&dev->pdev->dev, + "stop wd failed to complete ret=%d.\n", ret); + } if (preserve) dev->wd_timeout = wd_timeout; -- cgit v1.1 From 928f9111662574c1ac1dfa221c4e502ec713aed9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 31 May 2011 11:37:40 +0200 Subject: Staging: iio: Make IIO depend on GENERIC_HARDIRQS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On m68k (which doesn't support generic hardirqs yet): drivers/staging/iio/industrialio-trigger.c: In function ‘iio_trigger_poll’: drivers/staging/iio/industrialio-trigger.c:180: error: implicit declaration of function ‘generic_handle_irq’ drivers/staging/iio/industrialio-trigger.c: In function ‘iio_trigger_poll_chained’: drivers/staging/iio/industrialio-trigger.c:200: error: implicit declaration of function ‘handle_nested_irq’ drivers/staging/iio/industrialio-trigger.c: In function ‘iio_trig_release’: drivers/staging/iio/industrialio-trigger.c:379: error: implicit declaration of function ‘irq_modify_status’ drivers/staging/iio/industrialio-trigger.c:382: error: implicit declaration of function ‘irq_set_chip’ drivers/staging/iio/industrialio-trigger.c:384: error: implicit declaration of function ‘irq_set_handler’ drivers/staging/iio/industrialio-trigger.c:388: error: implicit declaration of function ‘irq_free_descs’ drivers/staging/iio/industrialio-trigger.c: In function ‘iio_trig_subirqmask’: drivers/staging/iio/industrialio-trigger.c:402: error: implicit declaration of function ‘irq_data_get_irq_chip’ drivers/staging/iio/industrialio-trigger.c:402: warning: initialization makes pointer from integer without a cast drivers/staging/iio/industrialio-trigger.c: In function ‘iio_trig_subirqunmask’: drivers/staging/iio/industrialio-trigger.c:411: warning: initialization makes pointer from integer without a cast drivers/staging/iio/industrialio-trigger.c: In function ‘iio_allocate_trigger’: drivers/staging/iio/industrialio-trigger.c:432: error: implicit declaration of function ‘irq_alloc_descs’ drivers/staging/iio/industrialio-trigger.c:455: error: ‘handle_simple_irq’ undeclared (first use in this function) drivers/staging/iio/industrialio-trigger.c:455: error: (Each undeclared identifier is reported only once drivers/staging/iio/industrialio-trigger.c:455: error: for each function it appears in.) Hence IIO_TRIGGER should depend on GENERIC_HARDIRQS. But as IIO_TRIGGER and IIO_RING_BUFFER form a maze of dependencies and selects, just make the whole IIO subsystem depend on GENERIC_HARDIRQS. This dependency also covers !S390, so that one can be removed again. Signed-off-by: Geert Uytterhoeven Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index f96d5b5..d329635 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -4,7 +4,7 @@ menuconfig IIO tristate "Industrial I/O support" - depends on !S390 + depends on GENERIC_HARDIRQS help The industrial I/O subsystem provides a unified framework for drivers for many different types of embedded sensors using a -- cgit v1.1 From 15e5201dfd4eebfce5e50b068ed40cb5f574fee6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 9 Jun 2011 13:16:13 -0700 Subject: Staging: brcm80211: disable drivers for PPC platforms Right now, bad things happen if you try to build these drivers for the PPC platform as it seems that the code only has been tested and built on the MIPS big endian platform. So disable it on the PPC32 and PPC64 platforms for now, hopefully this will be resolved in the future as I'm sure someone will want to use these chips with that platform someday. Reported-by: Stephen Rothwell Cc: Henry Ptasinski Cc: Brett Rudley Cc: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/Kconfig b/drivers/staging/brcm80211/Kconfig index f4cf9b2..2d1a29b 100644 --- a/drivers/staging/brcm80211/Kconfig +++ b/drivers/staging/brcm80211/Kconfig @@ -7,6 +7,7 @@ config BRCMSMAC default n depends on PCI depends on WLAN && MAC80211 + depends on !PPC64 && !PPC32 select BRCMUTIL select FW_LOADER select CRC_CCITT @@ -20,6 +21,7 @@ config BRCMFMAC default n depends on MMC depends on WLAN && CFG80211 + depends on !PPC64 && !PPC32 select BRCMUTIL select FW_LOADER select WIRELESS_EXT -- cgit v1.1 From d4620396d7e9759dd3f37a8155827477cf2b5309 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 27 Jun 2011 14:34:42 -0700 Subject: Staging: brcm80211: disable drivers except for X86 or MIPS platforms As David points out, the driver is also broken on SPARC, so might as well just only enable it on platforms where people have reported it working, instead of trying to list all of the ones where it doesn't work, as the working platform list is much smaller... Reported-by: David Miller Reported-by: Stephen Rothwell Cc: Henry Ptasinski Cc: Brett Rudley Cc: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/brcm80211/Kconfig b/drivers/staging/brcm80211/Kconfig index 2d1a29b..379cf16 100644 --- a/drivers/staging/brcm80211/Kconfig +++ b/drivers/staging/brcm80211/Kconfig @@ -7,7 +7,7 @@ config BRCMSMAC default n depends on PCI depends on WLAN && MAC80211 - depends on !PPC64 && !PPC32 + depends on X86 || MIPS select BRCMUTIL select FW_LOADER select CRC_CCITT @@ -21,7 +21,7 @@ config BRCMFMAC default n depends on MMC depends on WLAN && CFG80211 - depends on !PPC64 && !PPC32 + depends on X86 || MIPS select BRCMUTIL select FW_LOADER select WIRELESS_EXT -- cgit v1.1 From a73738e9f85fa6ba3f1f9a6ea95b5e5fa99579a2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 27 Jun 2011 14:43:34 -0700 Subject: Staging: comedi: fix build breakages on some platforms Some platforms do not have virt_to_bus(), so properly depend on CONFIG_VIRT_TO_BUS for the Comedi drivers that need this function. Reported-by: Stephen Rothwell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index bccdc12..20008a4 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -161,6 +161,7 @@ config COMEDI_PCL730 config COMEDI_PCL812 tristate "Advantech PCL-812/813 and ADlink ACL-8112/8113/8113/8216" + depends on VIRT_TO_BUS default N ---help--- Enable support for Advantech PCL-812/PG, PCL-813/B, ADLink @@ -172,6 +173,7 @@ config COMEDI_PCL812 config COMEDI_PCL816 tristate "Advantech PCL-814 and PCL-816 ISA card support" + depends on VIRT_TO_BUS default N ---help--- Enable support for Advantech PCL-814 and PCL-816 ISA cards @@ -181,6 +183,7 @@ config COMEDI_PCL816 config COMEDI_PCL818 tristate "Advantech PCL-718 and PCL-818 ISA card support" + depends on VIRT_TO_BUS default N ---help--- Enable support for Advantech PCL-818 ISA cards @@ -270,6 +273,7 @@ config COMEDI_DAS800 config COMEDI_DAS1800 tristate "DAS1800 and compatible ISA card support" + depends on VIRT_TO_BUS select COMEDI_FC default N ---help--- @@ -341,6 +345,7 @@ config COMEDI_DT2817 config COMEDI_DT282X tristate "Data Translation DT2821 series and DT-EZ ISA card support" select COMEDI_FC + depends on VIRT_TO_BUS default N ---help--- Enable support for Data Translation DT2821 series including DT-EZ @@ -420,6 +425,7 @@ config COMEDI_ADQ12B config COMEDI_NI_AT_A2150 tristate "NI AT-A2150 ISA card support" depends on COMEDI_NI_COMMON + depends on VIRT_TO_BUS default N ---help--- Enable support for National Instruments AT-A2150 cards @@ -537,6 +543,7 @@ if COMEDI_PCI_DRIVERS && PCI config COMEDI_ADDI_APCI_035 tristate "ADDI-DATA APCI_035 support" + depends on VIRT_TO_BUS default N ---help--- Enable support for ADDI-DATA APCI_035 cards @@ -546,6 +553,7 @@ config COMEDI_ADDI_APCI_035 config COMEDI_ADDI_APCI_1032 tristate "ADDI-DATA APCI_1032 support" + depends on VIRT_TO_BUS default N ---help--- Enable support for ADDI-DATA APCI_1032 cards @@ -555,6 +563,7 @@ config COMEDI_ADDI_APCI_1032 config COMEDI_ADDI_APCI_1500 tristate "ADDI-DATA APCI_1500 support" + depends on VIRT_TO_BUS default N ---help--- Enable support for ADDI-DATA APCI_1500 cards @@ -564,6 +573,7 @@ config COMEDI_ADDI_APCI_1500 config COMEDI_ADDI_APCI_1516 tristate "ADDI-DATA APCI_1516 support" + depends on VIRT_TO_BUS default N ---help--- Enable support for ADDI-DATA APCI_1516 cards @@ -573,6 +583,7 @@ config COMEDI_ADDI_APCI_1516 config COMEDI_ADDI_APCI_1564 tristate "ADDI-DATA APCI_1564 support" + depends on VIRT_TO_BUS default N ---help--- Enable support for ADDI-DATA APCI_1564 cards @@ -582,6 +593,7 @@ config COMEDI_ADDI_APCI_1564 config COMEDI_ADDI_APCI_16XX tristate "ADDI-DATA APCI_16xx support" + depends on VIRT_TO_BUS default N ---help--- Enable support for ADDI-DATA APCI_16xx cards @@ -591,6 +603,7 @@ config COMEDI_ADDI_APCI_16XX config COMEDI_ADDI_APCI_2016 tristate "ADDI-DATA APCI_2016 support" + depends on VIRT_TO_BUS default N ---help--- Enable support for ADDI-DATA APCI_2016 cards @@ -600,6 +613,7 @@ config COMEDI_ADDI_APCI_2016 config COMEDI_ADDI_APCI_2032 tristate "ADDI-DATA APCI_2032 support" + depends on VIRT_TO_BUS default N ---help--- Enable support for ADDI-DATA APCI_2032 cards @@ -609,6 +623,7 @@ config COMEDI_ADDI_APCI_2032 config COMEDI_ADDI_APCI_2200 tristate "ADDI-DATA APCI_2200 support" + depends on VIRT_TO_BUS default N ---help--- Enable support for ADDI-DATA APCI_2200 cards @@ -618,6 +633,7 @@ config COMEDI_ADDI_APCI_2200 config COMEDI_ADDI_APCI_3001 tristate "ADDI-DATA APCI_3001 support" + depends on VIRT_TO_BUS select COMEDI_FC default N ---help--- @@ -628,6 +644,7 @@ config COMEDI_ADDI_APCI_3001 config COMEDI_ADDI_APCI_3120 tristate "ADDI-DATA APCI_3520 support" + depends on VIRT_TO_BUS select COMEDI_FC default N ---help--- @@ -638,6 +655,7 @@ config COMEDI_ADDI_APCI_3120 config COMEDI_ADDI_APCI_3501 tristate "ADDI-DATA APCI_3501 support" + depends on VIRT_TO_BUS default N ---help--- Enable support for ADDI-DATA APCI_3501 cards @@ -647,6 +665,7 @@ config COMEDI_ADDI_APCI_3501 config COMEDI_ADDI_APCI_3XXX tristate "ADDI-DATA APCI_3xxx support" + depends on VIRT_TO_BUS default N ---help--- Enable support for ADDI-DATA APCI_3xxx cards @@ -713,6 +732,7 @@ config COMEDI_ADL_PCI9111 config COMEDI_ADL_PCI9118 tristate "ADLink PCI-9118DG, PCI-9118HG, PCI-9118HR support" select COMEDI_FC + depends on VIRT_TO_BUS default N ---help--- Enable support for ADlink PCI-9118DG, PCI-9118HG, PCI-9118HR cards @@ -1288,6 +1308,7 @@ config COMEDI_NI_LABPC depends on COMEDI_MITE select COMEDI_8255 select COMEDI_FC + depends on VIRT_TO_BUS default N ---help--- Enable support for National Instruments Lab-PC and compatibles -- cgit v1.1 From 31c1771cdbf0edea96e109e24dae387d331b6d96 Mon Sep 17 00:00:00 2001 From: Priyanka Jain Date: Mon, 27 Jun 2011 16:18:04 -0700 Subject: drivers/rtc/rtc-ds1307.c: add support for RTC device pt7c4338 PT7C4338 chip is being manufactured by Pericom Technology Inc. It is a serial real-time clock which provides: 1) Low-power clock/calendar. 2) Programmable square-wave output. It has 56 bytes of nonvolatile RAM. Its register set is same as that of rtc device: DS1307. Signed-off-by: Priyanka Jain Acked-by: Timur Tabi Reviewed-by: Wolfram Sang Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-ds1307.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index 4724ba3..b2005b4 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -149,6 +149,7 @@ static const struct i2c_device_id ds1307_id[] = { { "ds1340", ds_1340 }, { "ds3231", ds_3231 }, { "m41t00", m41t00 }, + { "pt7c4338", ds_1307 }, { "rx8025", rx_8025 }, { } }; -- cgit v1.1 From aa2c96d6f329e66cc59352b0f12e8f04e6a9593b Mon Sep 17 00:00:00 2001 From: Josh Hunt Date: Mon, 27 Jun 2011 16:18:08 -0700 Subject: drivers/misc/lkdtm.c: fix race when crashpoint is hit multiple times before checking count We observed the crash point count going negative in cases where the crash point is hit multiple times before the check of "count == 0" is done. Because of this we never call lkdtm_do_action(). This patch just adds a spinlock to protect count. Reported-by: Tapan Dhimant Signed-off-by: Josh Hunt Acked-by: Ankita Garg Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/lkdtm.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index 81d7fa4..150cd70 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c @@ -120,6 +120,7 @@ static int recur_count = REC_NUM_DEFAULT; static enum cname cpoint = CN_INVALID; static enum ctype cptype = CT_NONE; static int count = DEFAULT_COUNT; +static DEFINE_SPINLOCK(count_lock); module_param(recur_count, int, 0644); MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ @@ -230,11 +231,14 @@ static const char *cp_name_to_str(enum cname name) static int lkdtm_parse_commandline(void) { int i; + unsigned long flags; if (cpoint_count < 1 || recur_count < 1) return -EINVAL; + spin_lock_irqsave(&count_lock, flags); count = cpoint_count; + spin_unlock_irqrestore(&count_lock, flags); /* No special parameters */ if (!cpoint_type && !cpoint_name) @@ -349,6 +353,9 @@ static void lkdtm_do_action(enum ctype which) static void lkdtm_handler(void) { + unsigned long flags; + + spin_lock_irqsave(&count_lock, flags); count--; printk(KERN_INFO "lkdtm: Crash point %s of type %s hit, trigger in %d rounds\n", cp_name_to_str(cpoint), cp_type_to_str(cptype), count); @@ -357,6 +364,7 @@ static void lkdtm_handler(void) lkdtm_do_action(cptype); count = cpoint_count; } + spin_unlock_irqrestore(&count_lock, flags); } static int lkdtm_register_cpoint(enum cname which) -- cgit v1.1 From 5286bd953645408634daa880d04c73dd18d0224a Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 27 Jun 2011 16:18:13 -0700 Subject: drivers/leds/leds-lp5521.c: fix section mismatches Fix this section mismatch: WARNING: drivers/leds/leds-lp5521.o(.text+0xf2c): Section mismatch in reference from the function lp5521_probe() to the function .init.text:lp5521_init_led() The function lp5521_probe() references the function __init lp5521_init_led(). This is often because lp5521_probe lacks a __init annotation or the annotation of lp5521_init_led is wrong. Fixing this mismatch triggers one more mismatch, fix that one as well. Signed-off-by: Ralf Baechle Cc: Richard Purdie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/leds/leds-lp5521.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c index c0cff64..cc1dc48 100644 --- a/drivers/leds/leds-lp5521.c +++ b/drivers/leds/leds-lp5521.c @@ -593,7 +593,7 @@ static void lp5521_unregister_sysfs(struct i2c_client *client) &lp5521_led_attribute_group); } -static int __init lp5521_init_led(struct lp5521_led *led, +static int __devinit lp5521_init_led(struct lp5521_led *led, struct i2c_client *client, int chan, struct lp5521_platform_data *pdata) { @@ -637,7 +637,7 @@ static int __init lp5521_init_led(struct lp5521_led *led, return 0; } -static int lp5521_probe(struct i2c_client *client, +static int __devinit lp5521_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct lp5521_chip *chip; -- cgit v1.1 From 33721bd3d00e7a235f70ba4ec19eb64bcd060c0b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 27 Jun 2011 16:18:14 -0700 Subject: drivers/leds/leds-lp5523.c: fix section mismatches Fix this section mismatch: WARNING: drivers/leds/leds-lp5523.o(.text+0x12f4): Section mismatch in reference from the function lp5523_probe() to the function .init.text:lp5523_init_led() The function lp5523_probe() references the function __init lp5523_init_led(). This is often because lp5523_probe lacks a __init annotation or the annotation of lp5523_init_led is wrong. Fixing this one triggers one more mismatch, fix that one as well. Signed-off-by: Ralf Baechle Cc: Richard Purdie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/leds/leds-lp5523.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c index e19fed2..5971e309 100644 --- a/drivers/leds/leds-lp5523.c +++ b/drivers/leds/leds-lp5523.c @@ -826,7 +826,7 @@ static int __init lp5523_init_engine(struct lp5523_engine *engine, int id) return 0; } -static int __init lp5523_init_led(struct lp5523_led *led, struct device *dev, +static int __devinit lp5523_init_led(struct lp5523_led *led, struct device *dev, int chan, struct lp5523_platform_data *pdata) { char name[32]; @@ -872,7 +872,7 @@ static int __init lp5523_init_led(struct lp5523_led *led, struct device *dev, static struct i2c_driver lp5523_driver; -static int lp5523_probe(struct i2c_client *client, +static int __devinit lp5523_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct lp5523_chip *chip; -- cgit v1.1 From 1fc6e987d8f606371337211f52ff74c6753298a6 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 27 Jun 2011 16:18:15 -0700 Subject: drivers/misc/ioc4.c: fix section mismatch / race condition Fix this section mismatch: WARNING: drivers/misc/ioc4.o(.data+0x144): Section mismatch in reference from the variable ioc4_load_modules_work to the function .devinit.text:ioc4_load_modules() The variable ioc4_load_modules_work references the function __devinit ioc4_load_modules() If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *driver, *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console This one is potentially fatal; by the time ioc4_load_modules is invoked it may already have been freed. For that reason ioc4_load_modules_work can't be turned to __devinitdata but also because it's referenced in ioc4_exit. Signed-off-by: Ralf Baechle Acked-by: Brent Casavant Cc: Tejun Heo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/misc/ioc4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c index 668d41e..df03dd3 100644 --- a/drivers/misc/ioc4.c +++ b/drivers/misc/ioc4.c @@ -270,7 +270,7 @@ ioc4_variant(struct ioc4_driver_data *idd) return IOC4_VARIANT_PCI_RT; } -static void __devinit +static void ioc4_load_modules(struct work_struct *work) { request_module("sgiioc4"); -- cgit v1.1 From a39bce7bf60e728cb33b6b0415c3f44e7f1a102b Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 27 Jun 2011 16:18:16 -0700 Subject: drivers/tty/serial/8250_pci.c: fix warning Fis the warning drivers/tty/serial/8250_pci.c:1457: warning: initialization from incompatible pointer type Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/tty/serial/8250_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c index 4b4968a..78e98a5 100644 --- a/drivers/tty/serial/8250_pci.c +++ b/drivers/tty/serial/8250_pci.c @@ -973,7 +973,7 @@ ce4100_serial_setup(struct serial_private *priv, static int pci_omegapci_setup(struct serial_private *priv, - struct pciserial_board *board, + const struct pciserial_board *board, struct uart_port *port, int idx) { return setup_port(priv, port, 2, idx * 8, 0); -- cgit v1.1 From 3142b651ad2232cf0e375c291ee4b893c8559df5 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Mon, 27 Jun 2011 16:18:17 -0700 Subject: drm/ttm: use shmem_read_mapping_page Soon tmpfs will stop supporting ->readpage and read_mapping_page(): once "tmpfs: add shmem_read_mapping_page_gfp" has been applied, this patch can be applied to ease the transition. ttm_tt_swapin() and ttm_tt_swapout() use shmem_read_mapping_page() in place of read_mapping_page(), since their swap_space has been created with shmem_file_setup(). Signed-off-by: Hugh Dickins Cc: Christoph Hellwig Cc: Thomas Hellstrom Cc: Dave Airlie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpu/drm/ttm/ttm_tt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 90e23e0..58c271e 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -484,7 +485,7 @@ static int ttm_tt_swapin(struct ttm_tt *ttm) swap_space = swap_storage->f_path.dentry->d_inode->i_mapping; for (i = 0; i < ttm->num_pages; ++i) { - from_page = read_mapping_page(swap_space, i, NULL); + from_page = shmem_read_mapping_page(swap_space, i); if (IS_ERR(from_page)) { ret = PTR_ERR(from_page); goto out_err; @@ -557,7 +558,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage) from_page = ttm->pages[i]; if (unlikely(from_page == NULL)) continue; - to_page = read_mapping_page(swap_space, i, NULL); + to_page = shmem_read_mapping_page(swap_space, i); if (unlikely(IS_ERR(to_page))) { ret = PTR_ERR(to_page); goto out_err; -- cgit v1.1 From 5949eac4d9b5bf936c12cb7ec3a09084c1326834 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Mon, 27 Jun 2011 16:18:18 -0700 Subject: drm/i915: use shmem_read_mapping_page Soon tmpfs will stop supporting ->readpage and read_cache_page_gfp(): once "tmpfs: add shmem_read_mapping_page_gfp" has been applied, this patch can be applied to ease the transition. Make i915_gem_object_get_pages_gtt() use shmem_read_mapping_page_gfp() in the one place it's needed; elsewhere use shmem_read_mapping_page(), with the mapping's gfp_mask properly initialized. Forget about __GFP_COLD: since tmpfs initializes its pages with memset, asking for a cold page is counter-productive. Include linux/shmem_fs.h also in drm_gem.c: with shmem_file_setup() now declared there too, we shall remove the prototype from linux/mm.h later. Signed-off-by: Hugh Dickins Cc: Christoph Hellwig Cc: Chris Wilson Cc: Keith Packard Cc: Dave Airlie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpu/drm/drm_gem.c | 1 + drivers/gpu/drm/i915/i915_gem.c | 31 ++++++++++++++----------------- 2 files changed, 15 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 74e4ff5..4012fe4 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "drmP.h" /** @file drm_gem.c diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c6389de..fa560ce 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -31,6 +31,7 @@ #include "i915_drv.h" #include "i915_trace.h" #include "intel_drv.h" +#include #include #include #include @@ -359,8 +360,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, if ((page_offset + remain) > PAGE_SIZE) page_length = PAGE_SIZE - page_offset; - page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, - GFP_HIGHUSER | __GFP_RECLAIMABLE); + page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); if (IS_ERR(page)) return PTR_ERR(page); @@ -463,8 +463,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, if ((data_page_offset + page_length) > PAGE_SIZE) page_length = PAGE_SIZE - data_page_offset; - page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, - GFP_HIGHUSER | __GFP_RECLAIMABLE); + page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); if (IS_ERR(page)) { ret = PTR_ERR(page); goto out; @@ -797,8 +796,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, if ((page_offset + remain) > PAGE_SIZE) page_length = PAGE_SIZE - page_offset; - page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, - GFP_HIGHUSER | __GFP_RECLAIMABLE); + page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); if (IS_ERR(page)) return PTR_ERR(page); @@ -907,8 +905,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, if ((data_page_offset + page_length) > PAGE_SIZE) page_length = PAGE_SIZE - data_page_offset; - page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, - GFP_HIGHUSER | __GFP_RECLAIMABLE); + page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); if (IS_ERR(page)) { ret = PTR_ERR(page); goto out; @@ -1558,12 +1555,10 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, inode = obj->base.filp->f_path.dentry->d_inode; mapping = inode->i_mapping; + gfpmask |= mapping_gfp_mask(mapping); + for (i = 0; i < page_count; i++) { - page = read_cache_page_gfp(mapping, i, - GFP_HIGHUSER | - __GFP_COLD | - __GFP_RECLAIMABLE | - gfpmask); + page = shmem_read_mapping_page_gfp(mapping, i, gfpmask); if (IS_ERR(page)) goto err_pages; @@ -3565,6 +3560,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj; + struct address_space *mapping; obj = kzalloc(sizeof(*obj), GFP_KERNEL); if (obj == NULL) @@ -3575,6 +3571,9 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, return NULL; } + mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; + mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE); + i915_gem_info_add_obj(dev_priv, size); obj->base.write_domain = I915_GEM_DOMAIN_CPU; @@ -3950,8 +3949,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev, page_count = obj->base.size / PAGE_SIZE; for (i = 0; i < page_count; i++) { - struct page *page = read_cache_page_gfp(mapping, i, - GFP_HIGHUSER | __GFP_RECLAIMABLE); + struct page *page = shmem_read_mapping_page(mapping, i); if (!IS_ERR(page)) { char *dst = kmap_atomic(page); memcpy(dst, vaddr + i*PAGE_SIZE, PAGE_SIZE); @@ -4012,8 +4010,7 @@ i915_gem_attach_phys_object(struct drm_device *dev, struct page *page; char *dst, *src; - page = read_cache_page_gfp(mapping, i, - GFP_HIGHUSER | __GFP_RECLAIMABLE); + page = shmem_read_mapping_page(mapping, i); if (IS_ERR(page)) return PTR_ERR(page); -- cgit v1.1 From e2377fe0b65e3c7577ff6df1701c56ef477d336f Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Mon, 27 Jun 2011 16:18:19 -0700 Subject: drm/i915: use shmem_truncate_range The interface to ->truncate_range is changing very slightly: once "tmpfs: take control of its truncate_range" has been applied, this can be applied. For now there is only a slight inefficiency while this remains unapplied, but it will soon become essential for managing shmem's use of swap. Change i915_gem_object_truncate() to use shmem_truncate_range() directly: which should also spare i915 later change if we switch from inode_operations->truncate_range to file_operations->fallocate. Signed-off-by: Hugh Dickins Cc: Christoph Hellwig Cc: Chris Wilson Cc: Keith Packard Cc: Dave Airlie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpu/drm/i915/i915_gem.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index fa560ce..85f7137 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1696,13 +1696,10 @@ i915_gem_object_truncate(struct drm_i915_gem_object *obj) /* Our goal here is to return as much of the memory as * is possible back to the system as we are called from OOM. * To do this we must instruct the shmfs to drop all of its - * backing pages, *now*. Here we mirror the actions taken - * when by shmem_delete_inode() to release the backing store. + * backing pages, *now*. */ inode = obj->base.filp->f_path.dentry->d_inode; - truncate_inode_pages(inode->i_mapping, 0); - if (inode->i_op->truncate_range) - inode->i_op->truncate_range(inode, 0, (loff_t)-1); + shmem_truncate_range(inode, 0, (loff_t)-1); obj->madv = __I915_MADV_PURGED; } -- cgit v1.1 From ecbec53b1d00ba582f71b210ed96cafc05ebd189 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Mon, 27 Jun 2011 16:18:20 -0700 Subject: drm/i915: more struct_mutex locking When auditing the locking in i915_gem.c (for a prospective change which I then abandoned), I noticed two places where struct_mutex is not held across GEM object manipulations that would usually require it. Since one is in initial setup and the other in driver unload, I'm guessing the mutex is not required for either; but post a patch in case it is. Signed-off-by: Hugh Dickins Cc: Chris Wilson Cc: Keith Packard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/gpu/drm/i915/i915_dma.c | 3 +-- drivers/gpu/drm/i915/intel_overlay.c | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 0239e99..2b79588 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2182,9 +2182,8 @@ int i915_driver_unload(struct drm_device *dev) /* Flush any outstanding unpin_work. */ flush_workqueue(dev_priv->wq); - i915_gem_free_all_phys_object(dev); - mutex_lock(&dev->struct_mutex); + i915_gem_free_all_phys_object(dev); i915_gem_cleanup_ringbuffer(dev); mutex_unlock(&dev->struct_mutex); if (I915_HAS_FBC(dev) && i915_powersave) diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index a670c00..56a8e2a 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -1416,6 +1416,8 @@ void intel_setup_overlay(struct drm_device *dev) goto out_free; overlay->reg_bo = reg_bo; + mutex_lock(&dev->struct_mutex); + if (OVERLAY_NEEDS_PHYSICAL(dev)) { ret = i915_gem_attach_phys_object(dev, reg_bo, I915_GEM_PHYS_OVERLAY_REGS, @@ -1440,6 +1442,8 @@ void intel_setup_overlay(struct drm_device *dev) } } + mutex_unlock(&dev->struct_mutex); + /* init all values */ overlay->color_key = 0x0101fe; overlay->brightness = -19; @@ -1464,6 +1468,7 @@ out_unpin_bo: i915_gem_object_unpin(reg_bo); out_free_bo: drm_gem_object_unreference(®_bo->base); + mutex_unlock(&dev->struct_mutex); out_free: kfree(overlay); return; -- cgit v1.1 From 4274215d24633df7302069e51426659d4759c5ed Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 28 Jun 2011 16:59:42 +1000 Subject: md: avoid endless recovery loop when waiting for fail device to complete. If a device fails in a way that causes pending request to take a while to complete, md will not be able to immediately remove it from the array in remove_and_add_spares. It will then incorrectly look like a spare device and md will try to recover it even though it is failed. This leads to a recovery process starting and instantly aborting over and over again. We should check if the device is faulty before considering it to be a spare. This will avoid trying to start a recovery that cannot proceed. This bug was introduced in 2.6.26 so that patch is suitable for any kernel since then. Cc: stable@kernel.org Reported-by: Jim Paradis Signed-off-by: NeilBrown --- drivers/md/md.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 4332fc2..91e31e2 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7088,6 +7088,7 @@ static int remove_and_add_spares(mddev_t *mddev) list_for_each_entry(rdev, &mddev->disks, same_set) { if (rdev->raid_disk >= 0 && !test_bit(In_sync, &rdev->flags) && + !test_bit(Faulty, &rdev->flags) && !test_bit(Blocked, &rdev->flags)) spares++; if (rdev->raid_disk < 0 -- cgit v1.1 From 076bad7c4d2c51d9484f0ac60d68838139d2bf72 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 31 May 2011 14:46:55 +0100 Subject: watchdog: Handle multiple wm831x watchdogs being registered Due to the whole single instance based watchdog API we use static data for the wm831x watchdog which means that if the system tries to register a second one we end up trying to register the same miscdevice again, corrupting the miscdevice list. Work around this by checking for duplicate registrations until we get a watchdog core. Signed-off-by: Mark Brown Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/wm831x_wdt.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c index 8c4b2d5..871caea 100644 --- a/drivers/watchdog/wm831x_wdt.c +++ b/drivers/watchdog/wm831x_wdt.c @@ -320,6 +320,11 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev) struct wm831x_watchdog_pdata *pdata; int reg, ret; + if (wm831x) { + dev_err(&pdev->dev, "wm831x watchdog already registered\n"); + return -EBUSY; + } + wm831x = dev_get_drvdata(pdev->dev.parent); ret = wm831x_reg_read(wm831x, WM831X_WATCHDOG); -- cgit v1.1 From 9b19d40aa3ebaf1078779da10555da2ab8512422 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 15 Jun 2011 19:15:23 +0200 Subject: watchdog: mtx1-wdt: request gpio before using it Otherwise, the gpiolib autorequest feature will produce a WARN_ON(): WARNING: at drivers/gpio/gpiolib.c:101 0x8020ec6c() autorequest GPIO-215 [...] Signed-off-by: Florian Fainelli Signed-off-by: Wim Van Sebroeck Cc: stable --- drivers/watchdog/mtx-1_wdt.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index 1479dc4..aa011da 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c @@ -214,6 +214,12 @@ static int __devinit mtx1_wdt_probe(struct platform_device *pdev) int ret; mtx1_wdt_device.gpio = pdev->resource[0].start; + ret = gpio_request_one(mtx1_wdt_device.gpio, + GPIOF_OUT_INIT_HIGH, "mtx1-wdt"); + if (ret < 0) { + dev_err(&pdev->dev, "failed to request gpio"); + return ret; + } spin_lock_init(&mtx1_wdt_device.lock); init_completion(&mtx1_wdt_device.stop); @@ -239,6 +245,8 @@ static int __devexit mtx1_wdt_remove(struct platform_device *pdev) mtx1_wdt_device.queue = 0; wait_for_completion(&mtx1_wdt_device.stop); } + + gpio_free(mtx1_wdt_device.gpio); misc_deregister(&mtx1_wdt_misc); return 0; } -- cgit v1.1 From 2ea4e76e997019ae25ac3417aa46e31ddf7ecb17 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 15 Jun 2011 19:15:41 +0200 Subject: watchdog: mtx1-wdt: fix GPIO toggling Commit e391be76 (MIPS: Alchemy: Clean up GPIO registers and accessors) changed the way the GPIO was toggled. Prior to this patch, we would always actively drive the GPIO output to either 0 or 1, this patch drove the GPIO active to 0, and put the GPIO in tristate to drive it to 1, unfortunately this does not work, revert back to active driving. Using a signed variable (gstate) to hold the gpio state and using a bit- wise operation on it also resulted in toggling value from 1 to -2 since the variable is signed. This value was then passed on to gpio_direction_ output, which always perform a if (value) ... to set the value to the gpio, so we were always writing a 1 to this GPIO instead of 1 -> 0 -> 1 ... Signed-off-by: Florian Fainelli Signed-off-by: Wim Van Sebroeck Cc: stable --- drivers/watchdog/mtx-1_wdt.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index aa011da..54aa900 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c @@ -66,7 +66,7 @@ static struct { int default_ticks; unsigned long inuse; unsigned gpio; - int gstate; + unsigned int gstate; } mtx1_wdt_device; static void mtx1_wdt_trigger(unsigned long unused) @@ -78,11 +78,8 @@ static void mtx1_wdt_trigger(unsigned long unused) ticks--; /* toggle wdt gpio */ - mtx1_wdt_device.gstate = ~mtx1_wdt_device.gstate; - if (mtx1_wdt_device.gstate) - gpio_direction_output(mtx1_wdt_device.gpio, 1); - else - gpio_direction_input(mtx1_wdt_device.gpio); + mtx1_wdt_device.gstate = !mtx1_wdt_device.gstate; + gpio_set_value(mtx1_wdt_device.gpio, mtx1_wdt_device.gstate); if (mtx1_wdt_device.queue && ticks) mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); @@ -105,7 +102,7 @@ static void mtx1_wdt_start(void) if (!mtx1_wdt_device.queue) { mtx1_wdt_device.queue = 1; mtx1_wdt_device.gstate = 1; - gpio_direction_output(mtx1_wdt_device.gpio, 1); + gpio_set_value(mtx1_wdt_device.gpio, 1); mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL); } mtx1_wdt_device.running++; @@ -120,7 +117,7 @@ static int mtx1_wdt_stop(void) if (mtx1_wdt_device.queue) { mtx1_wdt_device.queue = 0; mtx1_wdt_device.gstate = 0; - gpio_direction_output(mtx1_wdt_device.gpio, 0); + gpio_set_value(mtx1_wdt_device.gpio, 0); } ticks = mtx1_wdt_device.default_ticks; spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags); -- cgit v1.1 From db98f89a2807966c6e82601f5c57e1a9c214c91a Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 15 Jun 2011 19:15:52 +0200 Subject: watchdog: mtx1-wdt: fix section mismatch Fix section mismatch and remove unused variable 'tmp'. Signed-off-by: Florian Fainelli Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/mtx-1_wdt.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c index 54aa900..0430e09 100644 --- a/drivers/watchdog/mtx-1_wdt.c +++ b/drivers/watchdog/mtx-1_wdt.c @@ -71,8 +71,6 @@ static struct { static void mtx1_wdt_trigger(unsigned long unused) { - u32 tmp; - spin_lock(&mtx1_wdt_device.lock); if (mtx1_wdt_device.running) ticks--; @@ -248,7 +246,7 @@ static int __devexit mtx1_wdt_remove(struct platform_device *pdev) return 0; } -static struct platform_driver mtx1_wdt = { +static struct platform_driver mtx1_wdt_driver = { .probe = mtx1_wdt_probe, .remove = __devexit_p(mtx1_wdt_remove), .driver.name = "mtx1-wdt", @@ -257,12 +255,12 @@ static struct platform_driver mtx1_wdt = { static int __init mtx1_wdt_init(void) { - return platform_driver_register(&mtx1_wdt); + return platform_driver_register(&mtx1_wdt_driver); } static void __exit mtx1_wdt_exit(void) { - platform_driver_unregister(&mtx1_wdt); + platform_driver_unregister(&mtx1_wdt_driver); } module_init(mtx1_wdt_init); -- cgit v1.1 From e376fd664b1547e29e264e3cfb97553a1be9054b Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 26 May 2011 11:12:53 +0200 Subject: watchdog: Intel SCU Watchdog: Fix build and remove duplicate code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trying to build the Intel SCU Watchdog fails for me with gcc 4.6.0 - $ gcc --version | head -n 1 gcc (GCC) 4.6.0 20110513 (prerelease) like this : CC drivers/watchdog/intel_scu_watchdog.o In file included from drivers/watchdog/intel_scu_watchdog.c:49:0: /home/jj/src/linux-2.6/arch/x86/include/asm/apb_timer.h: In function ‘apbt_time_init’: /home/jj/src/linux-2.6/arch/x86/include/asm/apb_timer.h:65:42: warning: ‘return’ with a value, in function returning void [enabled by default] drivers/watchdog/intel_scu_watchdog.c: In function ‘intel_scu_watchdog_init’: drivers/watchdog/intel_scu_watchdog.c:468:2: error: implicit declaration of function ‘sfi_get_mtmr’ [-Werror=implicit-function-declaration] drivers/watchdog/intel_scu_watchdog.c:468:32: warning: assignment makes pointer from integer without a cast [enabled by default] cc1: some warnings being treated as errors make[1]: *** [drivers/watchdog/intel_scu_watchdog.o] Error 1 make: *** [drivers/watchdog/intel_scu_watchdog.o] Error 2 Additionally, linux/types.h is needlessly being included twice in drivers/watchdog/intel_scu_watchdog.c Signed-off-by: Jesper Juhl Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/Kconfig | 3 +-- drivers/watchdog/intel_scu_watchdog.c | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 022f9eb..9536d38 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -535,8 +535,7 @@ config I6300ESB_WDT config INTEL_SCU_WATCHDOG bool "Intel SCU Watchdog for Mobile Platforms" - depends on WATCHDOG - depends on INTEL_SCU_IPC + depends on X86_MRST ---help--- Hardware driver for the watchdog time built into the Intel SCU for Intel Mobile Platforms. diff --git a/drivers/watchdog/intel_scu_watchdog.c b/drivers/watchdog/intel_scu_watchdog.c index 919bdd1..ba43860 100644 --- a/drivers/watchdog/intel_scu_watchdog.c +++ b/drivers/watchdog/intel_scu_watchdog.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include -- cgit v1.1 From ae2a00607463ceb647ada550d7f34ba33177ef38 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 27 Jun 2011 22:37:16 +0800 Subject: watchdog: gef_wdt: fix MODULE_ALIAS Remove the space between "platform:" prefix and the driver name. Signed-off-by: Axel Lin Acked-by: Martyn Welch Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/gef_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index 29a7cd4..b146082 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c @@ -329,4 +329,4 @@ MODULE_AUTHOR("Martyn Welch "); MODULE_DESCRIPTION("GE watchdog driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -MODULE_ALIAS("platform: gef_wdt"); +MODULE_ALIAS("platform:gef_wdt"); -- cgit v1.1 From 25732821cb965f00475922ca46e84f78e4bada95 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Fri, 24 Jun 2011 14:31:47 -0700 Subject: drm/i915: forcewake fix after reset The failure is as follows: 1. Userspace gets forcewake lock, lock count >=1 2. GPU hang/reset occurs (forcewake bit is reset) 3. count is now incorrect The failure can only occur when using the forcewake userspace lock. This has the unfortunate consequence of messing up the driver as well as userspace, unless userspace closes the debugfs file, the kernel will never end up waking the GT since the refcount will be > 1. The solution is to try to recover the correct forcewake state based on the refcount. There is a period of time where userspace reads/writes may occur after the reset, before the GT has been forcewaked. The interface was never designed to be a perfect solution for userspace reads/writes, and the kernel portion is fixed by this patch. Suggested-by: Chris Wilson Signed-off-by: Ben Widawsky Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_drv.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0defd42..609358f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -579,6 +579,9 @@ int i915_reset(struct drm_device *dev, u8 flags) } else switch (INTEL_INFO(dev)->gen) { case 6: ret = gen6_do_reset(dev, flags); + /* If reset with a user forcewake, try to restore */ + if (atomic_read(&dev_priv->forcewake_count)) + __gen6_gt_force_wake_get(dev_priv); break; case 5: ret = ironlake_do_reset(dev, flags); -- cgit v1.1 From f01c22fd59aa10a3738ede20fd4b9b6fd1e2eac3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 28 Jun 2011 11:48:51 +0100 Subject: drm/i915: Use chipset-specific irq installers Konstantin Belousov pointed out that 4697995b98417 replaced the generic i915_driver_irq_*install() functions with chipset specific routines accessible only through driver->irq_*install(). So update the sanity check in i915_request_wait() to match. Signed-off-by: Chris Wilson Signed-off-by: Keith Packard --- drivers/gpu/drm/i915/i915_gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c6389de..e81dbe5 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2080,8 +2080,8 @@ i915_wait_request(struct intel_ring_buffer *ring, if (!ier) { DRM_ERROR("something (likely vbetool) disabled " "interrupts, re-enabling\n"); - i915_driver_irq_preinstall(ring->dev); - i915_driver_irq_postinstall(ring->dev); + ring->dev->driver->irq_preinstall(ring->dev); + ring->dev->driver->irq_postinstall(ring->dev); } trace_i915_gem_request_wait_begin(ring, seqno); -- cgit v1.1 From aeb0aea143e958d5218162d73b1ed4d6ff0ed7c4 Mon Sep 17 00:00:00 2001 From: Hans-Christian Egtvedt Date: Tue, 28 Jun 2011 17:01:14 +0200 Subject: watchdog: update author email for at32ap700x_wdt This patch updates the email address of the at32ap700x_wdt driver supported by me to an email account I will use on a more regular basis in the future. Signed-off-by: Hans-Christian Egtvedt Signed-off-by: Wim Van Sebroeck --- drivers/watchdog/at32ap700x_wdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c index 750bc52..4ca5d40 100644 --- a/drivers/watchdog/at32ap700x_wdt.c +++ b/drivers/watchdog/at32ap700x_wdt.c @@ -448,7 +448,7 @@ static void __exit at32_wdt_exit(void) } module_exit(at32_wdt_exit); -MODULE_AUTHOR("Hans-Christian Egtvedt "); +MODULE_AUTHOR("Hans-Christian Egtvedt "); MODULE_DESCRIPTION("Watchdog driver for Atmel AT32AP700X"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); -- cgit v1.1 From 9b640f2e154268cb516efcaf9c434f2e73c6783e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 29 Jun 2011 11:36:10 +0200 Subject: i2c-taos-evm: Fix log messages * Print all error and information messages even when debugging is disabled. * Don't use adapter device to log messages before it is ready. Signed-off-by: Jean Delvare Cc: stable@kernel.org --- drivers/i2c/busses/i2c-taos-evm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-taos-evm.c b/drivers/i2c/busses/i2c-taos-evm.c index dd39c1e..26c352a 100644 --- a/drivers/i2c/busses/i2c-taos-evm.c +++ b/drivers/i2c/busses/i2c-taos-evm.c @@ -234,7 +234,7 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv) if (taos->state != TAOS_STATE_IDLE) { err = -ENODEV; - dev_dbg(&serio->dev, "TAOS EVM reset failed (state=%d, " + dev_err(&serio->dev, "TAOS EVM reset failed (state=%d, " "pos=%d)\n", taos->state, taos->pos); goto exit_close; } @@ -255,7 +255,7 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv) msecs_to_jiffies(250)); if (taos->state != TAOS_STATE_IDLE) { err = -ENODEV; - dev_err(&adapter->dev, "Echo off failed " + dev_err(&serio->dev, "TAOS EVM echo off failed " "(state=%d)\n", taos->state); goto exit_close; } @@ -263,7 +263,7 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv) err = i2c_add_adapter(adapter); if (err) goto exit_close; - dev_dbg(&serio->dev, "Connected to TAOS EVM\n"); + dev_info(&serio->dev, "Connected to TAOS EVM\n"); taos->client = taos_instantiate_device(adapter); return 0; @@ -288,7 +288,7 @@ static void taos_disconnect(struct serio *serio) serio_set_drvdata(serio, NULL); kfree(taos); - dev_dbg(&serio->dev, "Disconnected from TAOS EVM\n"); + dev_info(&serio->dev, "Disconnected from TAOS EVM\n"); } static struct serio_device_id taos_serio_ids[] = { -- cgit v1.1 From cd823db8b1161ef0d756514d280715a576d65cc3 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Wed, 29 Jun 2011 11:36:11 +0200 Subject: i2c/pca954x: Initialize the mux to disconnected state pca954x power-on default is channel 0 connected. If multiple pca954x muxes are connected to the same physical I2C bus, the parent bus will see channel 0 devices behind both muxes by default. This is bad. Scenario: -- pca954x @ 0x70 -- ch 0 (I2C-bus-101) -- EEPROM @ 0x50 | I2C-bus-1 --- | -- pca954x @ 0x71 -- ch 0 (I2C-bus-111) -- EEPROM @ 0x50 1. Load I2C bus driver: creates I2C-bus-1 2. Load pca954x driver: creates virtual I2C-bus-101 and I2C-bus-111 3. Load eeprom driver 4. Try to read EEPROM @ 0x50 on I2C-bus-101. The transaction will also bleed onto I2C-bus-111 because pca954x @ 0x71 channel 0 is connected by default. Fix: Initialize pca954x to disconnected state in pca954x_probe() Signed-off-by: Petri Gynther Signed-off-by: Jean Delvare Cc: stable@kernel.org --- drivers/i2c/muxes/pca954x.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/muxes/pca954x.c b/drivers/i2c/muxes/pca954x.c index 54e1ce7..6f89536 100644 --- a/drivers/i2c/muxes/pca954x.c +++ b/drivers/i2c/muxes/pca954x.c @@ -201,10 +201,11 @@ static int pca954x_probe(struct i2c_client *client, i2c_set_clientdata(client, data); - /* Read the mux register at addr to verify - * that the mux is in fact present. + /* Write the mux register at addr to verify + * that the mux is in fact present. This also + * initializes the mux to disconnected state. */ - if (i2c_smbus_read_byte(client) < 0) { + if (i2c_smbus_write_byte(client, 0) < 0) { dev_warn(&client->dev, "probe failed\n"); goto exit_free; } -- cgit v1.1 From 7ab24bfdf9a9a9f87ac8e5ad9a25f80b5b947be7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 29 Jun 2011 05:48:41 -0700 Subject: net+crypto: Use vmalloc for zlib inflate buffers. They are 64K and result in order-4 allocations, even with SLUB. Therefore, just like we always have for the deflate buffers, use vmalloc. Reported-by: Martin Jackson Acked-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_main.c | 6 +++--- drivers/net/ppp_deflate.c | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index 4b70311..74be989 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -49,6 +49,7 @@ #include #include #include +#include #define BNX2X_MAIN #include "bnx2x.h" @@ -4537,8 +4538,7 @@ static int bnx2x_gunzip_init(struct bnx2x *bp) if (bp->strm == NULL) goto gunzip_nomem2; - bp->strm->workspace = kmalloc(zlib_inflate_workspacesize(), - GFP_KERNEL); + bp->strm->workspace = vmalloc(zlib_inflate_workspacesize()); if (bp->strm->workspace == NULL) goto gunzip_nomem3; @@ -4562,7 +4562,7 @@ gunzip_nomem1: static void bnx2x_gunzip_end(struct bnx2x *bp) { if (bp->strm) { - kfree(bp->strm->workspace); + vfree(bp->strm->workspace); kfree(bp->strm); bp->strm = NULL; } diff --git a/drivers/net/ppp_deflate.c b/drivers/net/ppp_deflate.c index 31e9407..1dbdf82 100644 --- a/drivers/net/ppp_deflate.c +++ b/drivers/net/ppp_deflate.c @@ -305,7 +305,7 @@ static void z_decomp_free(void *arg) if (state) { zlib_inflateEnd(&state->strm); - kfree(state->strm.workspace); + vfree(state->strm.workspace); kfree(state); } } @@ -345,8 +345,7 @@ static void *z_decomp_alloc(unsigned char *options, int opt_len) state->w_size = w_size; state->strm.next_out = NULL; - state->strm.workspace = kmalloc(zlib_inflate_workspacesize(), - GFP_KERNEL|__GFP_REPEAT); + state->strm.workspace = vmalloc(zlib_inflate_workspacesize()); if (state->strm.workspace == NULL) goto out_free; -- cgit v1.1 From 55caa9241ece1c07a930e3d05a624061adcf2653 Mon Sep 17 00:00:00 2001 From: Yinglin Luan Date: Sat, 25 Jun 2011 18:12:12 +0000 Subject: rionet: fix NULL pointer dereference in rionet_remove Function rionet_remove initializes local variable 'ndev' to NULL and do nothing changes before the call to unregister_netdev(ndev), this could cause a NULL pointer dereference. Reported-by: Jesper Juhl Signed-off-by: Yinglin Luan Signed-off-by: David S. Miller --- drivers/net/rionet.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 77c5092..5d3436d 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -378,7 +378,7 @@ static int rionet_close(struct net_device *ndev) static void rionet_remove(struct rio_dev *rdev) { - struct net_device *ndev = NULL; + struct net_device *ndev = rio_get_drvdata(rdev); struct rionet_peer *peer, *tmp; free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ? @@ -433,22 +433,12 @@ static const struct net_device_ops rionet_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, }; -static int rionet_setup_netdev(struct rio_mport *mport) +static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev) { int rc = 0; - struct net_device *ndev = NULL; struct rionet_private *rnet; u16 device_id; - /* Allocate our net_device structure */ - ndev = alloc_etherdev(sizeof(struct rionet_private)); - if (ndev == NULL) { - printk(KERN_INFO "%s: could not allocate ethernet device.\n", - DRV_NAME); - rc = -ENOMEM; - goto out; - } - rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL, mport->sys_size ? __fls(sizeof(void *)) + 4 : 0); if (!rionet_active) { @@ -504,11 +494,21 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) int rc = -ENODEV; u32 lpef, lsrc_ops, ldst_ops; struct rionet_peer *peer; + struct net_device *ndev = NULL; /* If local device is not rionet capable, give up quickly */ if (!rionet_capable) goto out; + /* Allocate our net_device structure */ + ndev = alloc_etherdev(sizeof(struct rionet_private)); + if (ndev == NULL) { + printk(KERN_INFO "%s: could not allocate ethernet device.\n", + DRV_NAME); + rc = -ENOMEM; + goto out; + } + /* * First time through, make sure local device is rionet * capable, setup netdev, and set flags so this is skipped @@ -529,7 +529,7 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) goto out; } - rc = rionet_setup_netdev(rdev->net->hport); + rc = rionet_setup_netdev(rdev->net->hport, ndev); rionet_check = 1; } @@ -546,6 +546,8 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) list_add_tail(&peer->node, &rionet_peers); } + rio_set_drvdata(rdev, ndev); + out: return rc; } -- cgit v1.1 From a30d5155a4f80af3cbe1fe0366e9f0c6fdbfd8dd Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Sun, 26 Jun 2011 21:39:51 +0000 Subject: net/can: activate bit-timing calculation and netlink based drivers by default The two options "CAN bit-timing calculation" and "Platform CAN drivers with Netlink support" have a "default Y". In order to activate them by default, change to "default y". Signed-off-by: Marc Kleine-Budde Acked-by: Wolfgang Grandegger Acked-by: Kurt Van Dijck Signed-off-by: David S. Miller --- drivers/net/can/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 1d699e3..754df5e 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -36,7 +36,7 @@ config CAN_SLCAN config CAN_DEV tristate "Platform CAN drivers with Netlink support" depends on CAN - default Y + default y ---help--- Enables the common framework for platform CAN drivers with Netlink support. This is the standard library for CAN drivers. @@ -45,7 +45,7 @@ config CAN_DEV config CAN_CALC_BITTIMING bool "CAN bit-timing calculation" depends on CAN_DEV - default Y + default y ---help--- If enabled, CAN bit-timing parameters will be calculated for the bit-rate specified via Netlink argument "bitrate" when the device -- cgit v1.1 From 16adf5d07987d93675945f3cecf0e33706566005 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Fri, 17 Jun 2011 20:02:10 -0400 Subject: usbnet: Remove over-broad module alias from zaurus. This module and a bunch of dependancies are getting loaded on several of laptops I have (probably picking up the mobile broadband device), that have nothing to do with zaurus. Matching by class without any vendor/device pair isn't the right thing to do here, as it will prevent any other driver from correctly binding to it. (Or in the absense of a driver, will just waste time & memory by unnecessarily loading modules) Signed-off-by: Dave Jones Signed-off-by: David S. Miller --- drivers/net/usb/zaurus.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c index 241756e..1a2234c 100644 --- a/drivers/net/usb/zaurus.c +++ b/drivers/net/usb/zaurus.c @@ -331,17 +331,7 @@ static const struct usb_device_id products [] = { ZAURUS_MASTER_INTERFACE, .driver_info = ZAURUS_PXA_INFO, }, - - -/* At least some of the newest PXA units have very different lies about - * their standards support: they claim to be cell phones offering - * direct access to their radios! (No, they don't conform to CDC MDLM.) - */ { - USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, - USB_CDC_PROTO_NONE), - .driver_info = (unsigned long) &bogus_mdlm_info, -}, { /* Motorola MOTOMAGX phones */ USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6425, USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), -- cgit v1.1 From 49743170556e13156a64f8f20fa412805771b4e1 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 29 Jun 2011 10:10:07 -0700 Subject: ahci: change 'masking port_map' printk to KERN_WARNING level It's not so much an error as a warning about normal Marvell crazines. So don't use KERN_ERR that ends up spamming the console even in quiet mode, it's not _that_ critical. Explained by Jeff: "Long explanation, it's a mess: Marvell took standard AHCI, and bastardized it to include a weird mode whereby PATA devices appear inside the AHCI DMA and interrupt infrastructure you're familiar with. So, PATA devices appear via pata_marvell driver, using basic legacy IDE programming interface. But SATA devices, which might also be attached to this chip, either work in under-performing mode or simply don't work at all (e.g. newer 6 Gbps devices or port multiplier attachments, NCQ, ...) On the other hand, 'ahci' driver loads and works with the chip's attached SATA devices quite beautifully, but is completely unable to drive any attached PATA devices, due to the Marvell-specific PATA-under-AHCI interface. The "masking port_map 0x7 -> 0x3" message is the ahci driver "hiding" the PATA port(s) from itself, making sure it will only drive the SATA ports it knows how to drive." Acked-by: Jeff Garzik Signed-off-by: Linus Torvalds --- drivers/ata/libahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index d38c40f..41223c7 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -452,7 +452,7 @@ void ahci_save_initial_config(struct device *dev, } if (mask_port_map) { - dev_printk(KERN_ERR, dev, "masking port_map 0x%x -> 0x%x\n", + dev_printk(KERN_WARNING, dev, "masking port_map 0x%x -> 0x%x\n", port_map, port_map & mask_port_map); port_map &= mask_port_map; -- cgit v1.1 From c31eb8e926835582cd186b33a7a864880a4c0c79 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 28 Jun 2011 18:21:19 +0530 Subject: ath9k: Fix suspend/resume when no interface is UP When no interface has been brought up, the chip's power state continued as AWAKE. So during resume, the chip never been powered up. Cc: stable@kernel.org Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/pci.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index b8cbfc7..3bad0b2 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -278,6 +278,12 @@ static int ath_pci_suspend(struct device *device) ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); + /* The device has to be moved to FULLSLEEP forcibly. + * Otherwise the chip never moved to full sleep, + * when no interface is up. + */ + ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); + return 0; } -- cgit v1.1 From a0b8de350be458b33248e48b2174d9af8a4c4798 Mon Sep 17 00:00:00 2001 From: "Eugene A. Shatokhin" Date: Tue, 28 Jun 2011 23:04:51 -0400 Subject: ath5k: fix memory leak when fewer than N_PD_CURVES are in use We would free the proper number of curves, but in the wrong slots, due to a missing level of indirection through the pdgain_idx table. It's simpler just to try to free all four slots, so do that. Cc: stable@kernel.org Signed-off-by: Bob Copeland Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/eeprom.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 1fef84f..392771f 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -691,14 +691,12 @@ ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) if (!chinfo[pier].pd_curves) continue; - for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { + for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) { struct ath5k_pdgain_info *pd = &chinfo[pier].pd_curves[pdg]; - if (pd != NULL) { - kfree(pd->pd_step); - kfree(pd->pd_pwr); - } + kfree(pd->pd_step); + kfree(pd->pd_pwr); } kfree(chinfo[pier].pd_curves); -- cgit v1.1 From a18b989a5c12ca82ed37f94279273ddbc073758a Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Thu, 26 May 2011 13:30:34 +1000 Subject: crypto: caam - fix operator precedence in shared descriptor allocation setkey allocates 16 bytes (CAAM_CMD_SZ * DESC_AEAD_SHARED_TEXT_LEN) shy of what is needed to store the shared descriptor, resulting in memory corruption. Fix this. Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index d0e65d6..676d957 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -238,9 +238,9 @@ static int build_sh_desc_ipsec(struct caam_ctx *ctx) /* build shared descriptor for this session */ sh_desc = kmalloc(CAAM_CMD_SZ * DESC_AEAD_SHARED_TEXT_LEN + - keys_fit_inline ? - ctx->split_key_pad_len + ctx->enckeylen : - CAAM_PTR_SZ * 2, GFP_DMA | GFP_KERNEL); + (keys_fit_inline ? + ctx->split_key_pad_len + ctx->enckeylen : + CAAM_PTR_SZ * 2), GFP_DMA | GFP_KERNEL); if (!sh_desc) { dev_err(jrdev, "could not allocate shared descriptor\n"); return -ENOMEM; -- cgit v1.1 From b271a988eb9c3944c50fb62c21ac61860090d3ba Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 24 Jun 2011 13:15:38 +0000 Subject: drm/radeon/kms: increase rom size for atrm method The vbios rom is >64k on a lot of modern asics. Increase the fetch size for atrm to make sure we don't miss part of a larger rom. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_bios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 1aba85c..3fc5fa1 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c @@ -104,7 +104,7 @@ static bool radeon_read_bios(struct radeon_device *rdev) static bool radeon_atrm_get_bios(struct radeon_device *rdev) { int ret; - int size = 64 * 1024; + int size = 256 * 1024; int i; if (!radeon_atrm_supported(rdev->pdev)) -- cgit v1.1 From 6e4e2f811bade330126d4029c88c831784a7efd9 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 1 Jul 2011 17:30:00 -0700 Subject: 6pack,mkiss: fix lock inconsistency Lockdep found a locking inconsistency in the mkiss_close function: > kernel: [ INFO: inconsistent lock state ] > kernel: 2.6.39.1 #3 > kernel: --------------------------------- > kernel: inconsistent {IN-SOFTIRQ-R} -> {SOFTIRQ-ON-W} usage. > kernel: ax25ipd/2813 [HC0[0]:SC0[0]:HE1:SE1] takes: > kernel: (disc_data_lock){+++?.-}, at: [] mkiss_close+0x1b/0x90 [mkiss] > kernel: {IN-SOFTIRQ-R} state was registered at: The message hints that disc_data_lock is aquired with softirqs disabled, but does not itself disable softirqs, which can in rare circumstances lead to a deadlock. The same problem is present in the 6pack driver, this patch fixes both by using write_lock_bh instead of write_lock. Reported-by: Bernard F6BVP Tested-by: Bernard F6BVP Signed-off-by: Arnd Bergmann Acked-by: Ralf Baechle Cc: stable@kernel.org Signed-off-by: David S. Miller --- drivers/net/hamradio/6pack.c | 4 ++-- drivers/net/hamradio/mkiss.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 3e5d0b6..0d28378 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c @@ -692,10 +692,10 @@ static void sixpack_close(struct tty_struct *tty) { struct sixpack *sp; - write_lock(&disc_data_lock); + write_lock_bh(&disc_data_lock); sp = tty->disc_data; tty->disc_data = NULL; - write_unlock(&disc_data_lock); + write_unlock_bh(&disc_data_lock); if (!sp) return; diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 4c62839..bc02968 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -813,10 +813,10 @@ static void mkiss_close(struct tty_struct *tty) { struct mkiss *ax; - write_lock(&disc_data_lock); + write_lock_bh(&disc_data_lock); ax = tty->disc_data; tty->disc_data = NULL; - write_unlock(&disc_data_lock); + write_unlock_bh(&disc_data_lock); if (!ax) return; -- cgit v1.1 From da92b393e0bfc8e6d056885453201b0e7d8190dd Mon Sep 17 00:00:00 2001 From: Jitendra Kalsaria Date: Thu, 30 Jun 2011 10:02:05 +0000 Subject: qlge:Fix crash caused by mailbox execution on wedged chip. When we are in a recover process from a chip fatal error, driver should skip over execution of mailbox commands during resetting chip. Signed-off-by: Jitendra Kalsaria Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 1 + drivers/net/qlge/qlge_main.c | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index d328507..b2c8612 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -1996,6 +1996,7 @@ enum { QL_LB_LINK_UP = 10, QL_FRC_COREDUMP = 11, QL_EEH_FATAL = 12, + QL_ASIC_RECOVERY = 14, /* We are in ascic recovery. */ }; /* link_status bit definitions */ diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 930ae45..4fbefcf 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -2152,6 +2152,10 @@ void ql_queue_asic_error(struct ql_adapter *qdev) * thread */ clear_bit(QL_ADAPTER_UP, &qdev->flags); + /* Set asic recovery bit to indicate reset process that we are + * in fatal error recovery process rather than normal close + */ + set_bit(QL_ASIC_RECOVERY, &qdev->flags); queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); } @@ -3818,11 +3822,17 @@ static int ql_adapter_reset(struct ql_adapter *qdev) end_jiffies = jiffies + max((unsigned long)1, usecs_to_jiffies(30)); - /* Stop management traffic. */ - ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP); + /* Check if bit is set then skip the mailbox command and + * clear the bit, else we are in normal reset process. + */ + if (!test_bit(QL_ASIC_RECOVERY, &qdev->flags)) { + /* Stop management traffic. */ + ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP); - /* Wait for the NIC and MGMNT FIFOs to empty. */ - ql_wait_fifo_empty(qdev); + /* Wait for the NIC and MGMNT FIFOs to empty. */ + ql_wait_fifo_empty(qdev); + } else + clear_bit(QL_ASIC_RECOVERY, &qdev->flags); ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR); -- cgit v1.1 From 5069ee555eb41192e7a5003ba3b1f91880cfec06 Mon Sep 17 00:00:00 2001 From: Jitendra Kalsaria Date: Thu, 30 Jun 2011 10:02:06 +0000 Subject: qlge: Fix printk priority so chip fatal errors are always reported. Precedence of the printk should be at higher level so chip fatal errors are always reported. Signed-off-by: Jitendra Kalsaria Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge_main.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 4fbefcf..6b4ff97 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -2170,23 +2170,20 @@ static void ql_process_chip_ae_intr(struct ql_adapter *qdev, return; case CAM_LOOKUP_ERR_EVENT: - netif_err(qdev, link, qdev->ndev, - "Multiple CAM hits lookup occurred.\n"); - netif_err(qdev, drv, qdev->ndev, - "This event shouldn't occur.\n"); + netdev_err(qdev->ndev, "Multiple CAM hits lookup occurred.\n"); + netdev_err(qdev->ndev, "This event shouldn't occur.\n"); ql_queue_asic_error(qdev); return; case SOFT_ECC_ERROR_EVENT: - netif_err(qdev, rx_err, qdev->ndev, - "Soft ECC error detected.\n"); + netdev_err(qdev->ndev, "Soft ECC error detected.\n"); ql_queue_asic_error(qdev); break; case PCI_ERR_ANON_BUF_RD: - netif_err(qdev, rx_err, qdev->ndev, - "PCI error occurred when reading anonymous buffers from rx_ring %d.\n", - ib_ae_rsp->q_id); + netdev_err(qdev->ndev, "PCI error occurred when reading " + "anonymous buffers from rx_ring %d.\n", + ib_ae_rsp->q_id); ql_queue_asic_error(qdev); break; @@ -2441,11 +2438,10 @@ static irqreturn_t qlge_isr(int irq, void *dev_id) */ if (var & STS_FE) { ql_queue_asic_error(qdev); - netif_err(qdev, intr, qdev->ndev, - "Got fatal error, STS = %x.\n", var); + netdev_err(qdev->ndev, "Got fatal error, STS = %x.\n", var); var = ql_read32(qdev, ERR_STS); - netif_err(qdev, intr, qdev->ndev, - "Resetting chip. Error Status Register = 0x%x\n", var); + netdev_err(qdev->ndev, "Resetting chip. " + "Error Status Register = 0x%x\n", var); return IRQ_HANDLED; } -- cgit v1.1 From b4e4fe848c25af645a069bb2f21ba6456246e5de Mon Sep 17 00:00:00 2001 From: Jitendra Kalsaria Date: Thu, 30 Jun 2011 10:02:07 +0000 Subject: qlge:Version change to v1.00.00.29 Signed-off-by: Jitendra Kalsaria Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index b2c8612..ca306fd 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -16,7 +16,7 @@ */ #define DRV_NAME "qlge" #define DRV_STRING "QLogic 10 Gigabit PCI-E Ethernet Driver " -#define DRV_VERSION "v1.00.00.27.00.00-01" +#define DRV_VERSION "v1.00.00.29.00.00-01" #define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ -- cgit v1.1 From 5f77898de17ff983ff0e2988b73a6bdf4b6f9f8b Mon Sep 17 00:00:00 2001 From: Shyam Iyer Date: Tue, 28 Jun 2011 08:58:05 +0000 Subject: Fix call trace when interrupts are disabled while sleeping function kzalloc is called request_threaded irq will call kzalloc that can sleep. Initializing the flags variable outside of spin_lock_irqsave/restore in bnad_mbox_irq_alloc will avoid call traces like below. Jun 27 08:15:24 home-t710 kernel: [11735.634550] Brocade 10G Ethernet driver Jun 27 08:15:24 home-t710 kernel: [11735.634590] bnad_pci_probe : (0xffff880427f3d000, 0xffffffffa020f3e0) PCI Func : (2) Jun 27 08:15:24 home-t710 kernel: [11735.637677] bna 0000:82:00.2: PCI INT A -> GSI 66 (level, low) -> IRQ 66 Jun 27 08:15:24 home-t710 kernel: [11735.638290] bar0 mapped to ffffc90014980000, len 262144 Jun 27 08:15:24 home-t710 kernel: [11735.638732] BUG: sleeping function called from invalid context at mm/slub.c:847 Jun 27 08:15:24 home-t710 kernel: [11735.638736] in_atomic(): 0, irqs_disabled(): 1, pid: 11243, name: insmod Jun 27 08:15:24 home-t710 kernel: [11735.638740] Pid: 11243, comm: insmod Not tainted 3.0.0-rc4+ #6 Jun 27 08:15:24 home-t710 kernel: [11735.638743] Call Trace: Jun 27 08:15:24 home-t710 kernel: [11735.638755] [] __might_sleep+0xeb/0xf0 Jun 27 08:15:24 home-t710 kernel: [11735.638766] [] ? netif_wake_queue+0x3d/0x3d [bna] Jun 27 08:15:24 home-t710 kernel: [11735.638773] [] kmem_cache_alloc_trace+0x43/0xd8 Jun 27 08:15:24 home-t710 kernel: [11735.638782] [] ? netif_wake_queue+0x3d/0x3d [bna] Jun 27 08:15:24 home-t710 kernel: [11735.638787] [] request_threaded_irq+0xa1/0x113 Jun 27 08:15:24 home-t710 kernel: [11735.638798] [] bnad_pci_probe+0x612/0x8e5 [bna] Jun 27 08:15:24 home-t710 kernel: [11735.638807] [] ? netif_wake_queue+0x3d/0x3d [bna] Jun 27 08:15:24 home-t710 kernel: [11735.638816] [] ? _raw_spin_unlock_irqrestore+0x17/0x19 Jun 27 08:15:24 home-t710 kernel: [11735.638822] [] local_pci_probe+0x44/0x75 Jun 27 08:15:24 home-t710 kernel: [11735.638826] [] pci_device_probe+0xd0/0xff Jun 27 08:15:24 home-t710 kernel: [11735.638832] [] driver_probe_device+0x131/0x213 Jun 27 08:15:24 home-t710 kernel: [11735.638836] [] __driver_attach+0x5a/0x7e Jun 27 08:15:24 home-t710 kernel: [11735.638840] [] ? driver_probe_device+0x213/0x213 Jun 27 08:15:24 home-t710 kernel: [11735.638844] [] bus_for_each_dev+0x53/0x89 Jun 27 08:15:24 home-t710 kernel: [11735.638848] [] driver_attach+0x1e/0x20 Jun 27 08:15:24 home-t710 kernel: [11735.638852] [] bus_add_driver+0xd1/0x224 Jun 27 08:15:24 home-t710 kernel: [11735.638858] [] ? 0xffffffffa01b7fff Jun 27 08:15:24 home-t710 kernel: [11735.638862] [] driver_register+0x98/0x105 Jun 27 08:15:24 home-t710 kernel: [11735.638866] [] ? 0xffffffffa01b7fff Jun 27 08:15:24 home-t710 kernel: [11735.638871] [] __pci_register_driver+0x56/0xc1 Jun 27 08:15:24 home-t710 kernel: [11735.638875] [] ? 0xffffffffa01b7fff Jun 27 08:15:24 home-t710 kernel: [11735.638884] [] bnad_module_init+0x40/0x60 [bna] Jun 27 08:15:24 home-t710 kernel: [11735.638892] [] do_one_initcall+0x7f/0x136 Jun 27 08:15:24 home-t710 kernel: [11735.638899] [] sys_init_module+0x88/0x1d0 Jun 27 08:15:24 home-t710 kernel: [11735.638906] [] system_call_fastpath+0x16/0x1b Jun 27 08:15:24 home-t710 kernel: [11735.639642] bnad_pci_probe : (0xffff880427f3e000, 0xffffffffa020f3e0) PCI Func : (3) Jun 27 08:15:24 home-t710 kernel: [11735.639665] bna 0000:82:00.3: PCI INT A -> GSI 66 (level, low) -> IRQ 66 Jun 27 08:15:24 home-t710 kernel: [11735.639735] bar0 mapped to ffffc90014400000, len 262144 Signed-off-by: Shyam Iyer Acked-by: Rasesh Mody Signed-off-by: David S. Miller --- drivers/net/bna/bnad.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 7d25a97..44e219c 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c @@ -1111,7 +1111,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad, struct bna_intr_info *intr_info) { int err = 0; - unsigned long flags; + unsigned long irq_flags = 0, flags; u32 irq; irq_handler_t irq_handler; @@ -1125,18 +1125,17 @@ bnad_mbox_irq_alloc(struct bnad *bnad, if (bnad->cfg_flags & BNAD_CF_MSIX) { irq_handler = (irq_handler_t)bnad_msix_mbox_handler; irq = bnad->msix_table[bnad->msix_num - 1].vector; - flags = 0; intr_info->intr_type = BNA_INTR_T_MSIX; intr_info->idl[0].vector = bnad->msix_num - 1; } else { irq_handler = (irq_handler_t)bnad_isr; irq = bnad->pcidev->irq; - flags = IRQF_SHARED; + irq_flags = IRQF_SHARED; intr_info->intr_type = BNA_INTR_T_INTX; /* intr_info->idl.vector = 0 ? */ } spin_unlock_irqrestore(&bnad->bna_lock, flags); - + flags = irq_flags; sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME); /* -- cgit v1.1 From 60b677034fcb3e48ffa30d638b09ac925afb4b36 Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Fri, 1 Jul 2011 22:06:44 +0000 Subject: net: 8139too: Initial necessary vlan_features to support vlan Offload setting of vlan device requires vlan_features to be initialized. Signed-off-by: Shan Wei Acked-by: Francois Romieu Signed-off-by: David S. Miller --- drivers/net/8139too.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 98517a3..e3bad82 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -992,6 +992,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, * features */ dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA; + dev->vlan_features = dev->features; dev->irq = pdev->irq; -- cgit v1.1 From 2fb83cd618be34546fb526a9051eceaa95517026 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Sun, 3 Jul 2011 22:34:29 -0700 Subject: natsemi: silence dma-debug warnings This silences dma-debug warnings: https://lkml.org/lkml/2011/6/30/341 ------------[ cut here ]------------ WARNING: at /home/jimc/projects/lx/linux-2.6/lib/dma-debug.c:820 check_unmap+0x1fe/0x56a() natsemi 0000:00:06.0: DMA-API: device driver frees DMA memory with different size [device address=0x0000000006ef0040] [map size=1538 bytes] [unmap size=1522 bytes] Modules linked in: pc8736x_gpio pc87360 hwmon_vid scx200_gpio nsc_gpio scx200_hrt scx200_acb i2c_core arc4 rtl8180 mac80211 eeprom_93cx6 cfg80211 pcspkr rfkill scx200 ide_gd_mod ide_pci_generic ohci_hcd usbcore sc1200 ide_core Pid: 870, comm: collector Not tainted 3.0.0-rc5-sk-00080-gca56a95 #1 Call Trace: [] warn_slowpath_common+0x4a/0x5f [] ? check_unmap+0x1fe/0x56a [] warn_slowpath_fmt+0x26/0x2a [] check_unmap+0x1fe/0x56a [] debug_dma_unmap_page+0x53/0x5b [] pci_unmap_single+0x4d/0x57 [] natsemi_poll+0x343/0x5ca [] ? try_to_wake_up+0xea/0xfc [] ? spin_unlock_irq.clone.28+0x18/0x23 [] net_rx_action+0x3f/0xe5 [] __do_softirq+0x5b/0xd1 [] ? local_bh_enable+0xa/0xa [] ? irq_exit+0x34/0x75 [] ? do_IRQ+0x66/0x79 [] ? common_interrupt+0x29/0x30 [] ? finish_task_switch.clone.118+0x31/0x72 [] ? schedule+0x3b2/0x3f1 [] ? hrtimer_start_range_ns+0x10/0x12 [] ? hrtimer_start_expires+0x1c/0x24 [] ? schedule_hrtimeout_range_clock+0x8e/0xb4 [] ? update_rmtp+0x68/0x68 [] ? schedule_hrtimeout_range+0xa/0xc [] ? poll_schedule_timeout+0x27/0x3e [] ? do_select+0x488/0x4cd [] ? finish_task_switch.clone.118+0x43/0x72 [] ? need_resched+0x14/0x1e [] ? poll_freewait+0x74/0x74 [] ? need_resched+0x14/0x1e [] ? schedule+0x3e1/0x3f1 [] ? irq_exit+0x47/0x75 [] ? need_resched+0x14/0x1e [] ? preempt_schedule_irq+0x44/0x4a [] ? need_resched+0x17/0x19 [] ? put_dec_full+0x7b/0xaa [] ? blkdev_ioctl+0x434/0x618 [] ? put_dec+0x2f/0x6d [] ? number.clone.1+0x10b/0x1d0 [] ? preempt_schedule_irq+0x44/0x4a [] ? need_resched+0x17/0x19 [] ? vsnprintf+0x225/0x264 [] ? vsnprintf+0x7f/0x264 [] ? seq_printf+0x22/0x40 [] ? do_task_stat+0x582/0x5a3 [] ? poll_schedule_timeout+0x27/0x3e [] ? core_sys_select+0x11f/0x1a3 [] ? poll_schedule_timeout+0x27/0x3e [] ? proc_tgid_stat+0xd/0xf [] ? recalc_sigpending+0x32/0x35 [] ? __set_task_blocked+0x64/0x6a [] ? timespec_add_safe+0x24/0x48 [] ? spin_unlock_irq.clone.16+0x18/0x23 [] ? sys_pselect6+0xe5/0x13e [] ? syscall_call+0x7/0xb [] ? rpc_clntdir_depopulate+0x26/0x30 ---[ end trace 180dcac41a50938b ]--- Reported-by: Jim Cromie Signed-off-by: FUJITA Tomonori Tested-by: Jim Cromie Signed-off-by: David S. Miller --- drivers/net/natsemi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index b78be08..8f8b65a 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -2360,7 +2360,8 @@ static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do) PCI_DMA_FROMDEVICE); } else { pci_unmap_single(np->pci_dev, np->rx_dma[entry], - buflen, PCI_DMA_FROMDEVICE); + buflen + NATSEMI_PADDING, + PCI_DMA_FROMDEVICE); skb_put(skb = np->rx_skbuff[entry], pkt_len); np->rx_skbuff[entry] = NULL; } -- cgit v1.1 From 9b9cfe7cf663c16c0d93349cc0094bb28ae7135a Mon Sep 17 00:00:00 2001 From: Kristoffer Glembo Date: Mon, 4 Jul 2011 21:39:10 -0700 Subject: greth: greth_set_mac_add would corrupt the MAC address. The MAC address was set using the signed char sockaddr->sa_addr field and thus the address could be corrupted through sign extension. Signed-off-by: Kristoffer Glembo Signed-off-by: David S. Miller --- drivers/net/greth.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/greth.c b/drivers/net/greth.c index f181304..672f096 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -1015,11 +1015,10 @@ static int greth_set_mac_add(struct net_device *dev, void *p) return -EINVAL; memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + GRETH_REGSAVE(regs->esa_msb, dev->dev_addr[0] << 8 | dev->dev_addr[1]); + GRETH_REGSAVE(regs->esa_lsb, dev->dev_addr[2] << 24 | dev->dev_addr[3] << 16 | + dev->dev_addr[4] << 8 | dev->dev_addr[5]); - GRETH_REGSAVE(regs->esa_msb, addr->sa_data[0] << 8 | addr->sa_data[1]); - GRETH_REGSAVE(regs->esa_lsb, - addr->sa_data[2] << 24 | addr-> - sa_data[3] << 16 | addr->sa_data[4] << 8 | addr->sa_data[5]); return 0; } -- cgit v1.1 From 5318d809d7b4975ce5e5303e8508f89a5458c2b6 Mon Sep 17 00:00:00 2001 From: Shreyas Bhatewara Date: Tue, 5 Jul 2011 14:34:05 +0000 Subject: vmxnet3: fix starving rx ring whenoc_skb kb fails If the rx ring is completely empty, then the device may never fire an rx interrupt. Unfortunately, the rx interrupt is what triggers populating the rx ring with fresh buffers, so this will cause networking to lock up. This patch replenishes the skb in recv descriptor as soon as it is peeled off while processing rx completions. If the skb/buffer allocation fails, existing one is recycled and the packet in hand is dropped. This way none of the RX desc is ever left empty, thus avoiding starvation Signed-off-by: Scott J. Goldman Signed-off-by: Shreyas N Bhatewara Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 135 ++++++++++++++++++++++++++------------ drivers/net/vmxnet3/vmxnet3_int.h | 4 +- 2 files changed, 96 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index fa6e2ac..45a23b2 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -575,7 +575,7 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx, struct vmxnet3_cmd_ring *ring = &rq->rx_ring[ring_idx]; u32 val; - while (num_allocated < num_to_alloc) { + while (num_allocated <= num_to_alloc) { struct vmxnet3_rx_buf_info *rbi; union Vmxnet3_GenericDesc *gd; @@ -621,9 +621,15 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx, BUG_ON(rbi->dma_addr == 0); gd->rxd.addr = cpu_to_le64(rbi->dma_addr); - gd->dword[2] = cpu_to_le32((ring->gen << VMXNET3_RXD_GEN_SHIFT) + gd->dword[2] = cpu_to_le32((!ring->gen << VMXNET3_RXD_GEN_SHIFT) | val | rbi->len); + /* Fill the last buffer but dont mark it ready, or else the + * device will think that the queue is full */ + if (num_allocated == num_to_alloc) + break; + + gd->dword[2] |= cpu_to_le32(ring->gen << VMXNET3_RXD_GEN_SHIFT); num_allocated++; vmxnet3_cmd_ring_adv_next2fill(ring); } @@ -1140,6 +1146,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2 }; u32 num_rxd = 0; + bool skip_page_frags = false; struct Vmxnet3_RxCompDesc *rcd; struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx; #ifdef __BIG_ENDIAN_BITFIELD @@ -1150,11 +1157,12 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, &rxComp); while (rcd->gen == rq->comp_ring.gen) { struct vmxnet3_rx_buf_info *rbi; - struct sk_buff *skb; + struct sk_buff *skb, *new_skb = NULL; + struct page *new_page = NULL; int num_to_alloc; struct Vmxnet3_RxDesc *rxd; u32 idx, ring_idx; - + struct vmxnet3_cmd_ring *ring = NULL; if (num_rxd >= quota) { /* we may stop even before we see the EOP desc of * the current pkt @@ -1165,6 +1173,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2); idx = rcd->rxdIdx; ring_idx = rcd->rqID < adapter->num_rx_queues ? 0 : 1; + ring = rq->rx_ring + ring_idx; vmxnet3_getRxDesc(rxd, &rq->rx_ring[ring_idx].base[idx].rxd, &rxCmdDesc); rbi = rq->buf_info[ring_idx] + idx; @@ -1193,37 +1202,80 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, goto rcd_done; } + skip_page_frags = false; ctx->skb = rbi->skb; - rbi->skb = NULL; + new_skb = dev_alloc_skb(rbi->len + NET_IP_ALIGN); + if (new_skb == NULL) { + /* Skb allocation failed, do not handover this + * skb to stack. Reuse it. Drop the existing pkt + */ + rq->stats.rx_buf_alloc_failure++; + ctx->skb = NULL; + rq->stats.drop_total++; + skip_page_frags = true; + goto rcd_done; + } pci_unmap_single(adapter->pdev, rbi->dma_addr, rbi->len, PCI_DMA_FROMDEVICE); skb_put(ctx->skb, rcd->len); + + /* Immediate refill */ + new_skb->dev = adapter->netdev; + skb_reserve(new_skb, NET_IP_ALIGN); + rbi->skb = new_skb; + rbi->dma_addr = pci_map_single(adapter->pdev, + rbi->skb->data, rbi->len, + PCI_DMA_FROMDEVICE); + rxd->addr = cpu_to_le64(rbi->dma_addr); + rxd->len = rbi->len; + } else { - BUG_ON(ctx->skb == NULL); + BUG_ON(ctx->skb == NULL && !skip_page_frags); + /* non SOP buffer must be type 1 in most cases */ - if (rbi->buf_type == VMXNET3_RX_BUF_PAGE) { - BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY); + BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_PAGE); + BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY); - if (rcd->len) { - pci_unmap_page(adapter->pdev, - rbi->dma_addr, rbi->len, - PCI_DMA_FROMDEVICE); + /* If an sop buffer was dropped, skip all + * following non-sop fragments. They will be reused. + */ + if (skip_page_frags) + goto rcd_done; - vmxnet3_append_frag(ctx->skb, rcd, rbi); - rbi->page = NULL; - } - } else { - /* - * The only time a non-SOP buffer is type 0 is - * when it's EOP and error flag is raised, which - * has already been handled. + new_page = alloc_page(GFP_ATOMIC); + if (unlikely(new_page == NULL)) { + /* Replacement page frag could not be allocated. + * Reuse this page. Drop the pkt and free the + * skb which contained this page as a frag. Skip + * processing all the following non-sop frags. */ - BUG_ON(true); + rq->stats.rx_buf_alloc_failure++; + dev_kfree_skb(ctx->skb); + ctx->skb = NULL; + skip_page_frags = true; + goto rcd_done; + } + + if (rcd->len) { + pci_unmap_page(adapter->pdev, + rbi->dma_addr, rbi->len, + PCI_DMA_FROMDEVICE); + + vmxnet3_append_frag(ctx->skb, rcd, rbi); } + + /* Immediate refill */ + rbi->page = new_page; + rbi->dma_addr = pci_map_page(adapter->pdev, rbi->page, + 0, PAGE_SIZE, + PCI_DMA_FROMDEVICE); + rxd->addr = cpu_to_le64(rbi->dma_addr); + rxd->len = rbi->len; } + skb = ctx->skb; if (rcd->eop) { skb->len += skb->data_len; @@ -1244,26 +1296,27 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, } rcd_done: - /* device may skip some rx descs */ - rq->rx_ring[ring_idx].next2comp = idx; - VMXNET3_INC_RING_IDX_ONLY(rq->rx_ring[ring_idx].next2comp, - rq->rx_ring[ring_idx].size); - - /* refill rx buffers frequently to avoid starving the h/w */ - num_to_alloc = vmxnet3_cmd_ring_desc_avail(rq->rx_ring + - ring_idx); - if (unlikely(num_to_alloc > VMXNET3_RX_ALLOC_THRESHOLD(rq, - ring_idx, adapter))) { - vmxnet3_rq_alloc_rx_buf(rq, ring_idx, num_to_alloc, - adapter); - - /* if needed, update the register */ - if (unlikely(rq->shared->updateRxProd)) { - VMXNET3_WRITE_BAR0_REG(adapter, - rxprod_reg[ring_idx] + rq->qid * 8, - rq->rx_ring[ring_idx].next2fill); - rq->uncommitted[ring_idx] = 0; - } + /* device may have skipped some rx descs */ + ring->next2comp = idx; + num_to_alloc = vmxnet3_cmd_ring_desc_avail(ring); + ring = rq->rx_ring + ring_idx; + while (num_to_alloc) { + vmxnet3_getRxDesc(rxd, &ring->base[ring->next2fill].rxd, + &rxCmdDesc); + BUG_ON(!rxd->addr); + + /* Recv desc is ready to be used by the device */ + rxd->gen = ring->gen; + vmxnet3_cmd_ring_adv_next2fill(ring); + num_to_alloc--; + } + + /* if needed, update the register */ + if (unlikely(rq->shared->updateRxProd)) { + VMXNET3_WRITE_BAR0_REG(adapter, + rxprod_reg[ring_idx] + rq->qid * 8, + ring->next2fill); + rq->uncommitted[ring_idx] = 0; } vmxnet3_comp_ring_adv_next2proc(&rq->comp_ring); diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index f50d36f..8db7ecf 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -68,10 +68,10 @@ /* * Version numbers */ -#define VMXNET3_DRIVER_VERSION_STRING "1.1.9.0-k" +#define VMXNET3_DRIVER_VERSION_STRING "1.1.14.0-k" /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ -#define VMXNET3_DRIVER_VERSION_NUM 0x01010900 +#define VMXNET3_DRIVER_VERSION_NUM 0x01010E00 #if defined(CONFIG_PCI_MSI) /* RSS only makes sense if MSI-X is supported. */ -- cgit v1.1