From b690c425fe07c725e7f1f7d40303588416cba67f Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Fri, 29 Oct 2010 13:25:24 -0700 Subject: [PATCH 001/300] SPARC/LEON: removed constant timer initialization as if HZ=100, now it reflects the value of HZ Signed-off-by: Daniel Hellstrom Signed-off-by: David S. Miller --- arch/sparc/kernel/leon_kernel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 2d51527d810f..f01c42661ee5 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -114,7 +114,7 @@ void __init leon_init_timers(irq_handler_t counter_fn) if (leon3_gptimer_regs && leon3_irqctrl_regs) { LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0); LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld, - (((1000000 / 100) - 1))); + (((1000000 / HZ) - 1))); LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0); #ifdef CONFIG_SMP @@ -128,7 +128,7 @@ void __init leon_init_timers(irq_handler_t counter_fn) } LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0); - LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/100) - 1))); + LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/HZ) - 1))); LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0); # endif From ce05a94efaf71d562eeefd30d6bbc2ab42b06bac Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 16 Nov 2010 12:08:23 -0800 Subject: [PATCH 002/300] sparc64: Delete prom_puts() unused. Signed-off-by: David S. Miller --- arch/sparc/prom/console_64.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index 10322dc2f557..de67fc73d91e 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c @@ -81,19 +81,3 @@ prom_putchar(char c) { prom_nbputchar(c); } - -void -prom_puts(const char *s, int len) -{ - unsigned long args[7]; - - args[0] = (unsigned long) "write"; - args[1] = 3; - args[2] = 1; - args[3] = (unsigned int) prom_stdout; - args[4] = (unsigned long) s; - args[5] = len; - args[6] = (unsigned long) -1; - - p1275_cmd_direct(args); -} From 17d70d6df0c4ea7a203b444001572a91ad9c2bef Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 16 Nov 2010 12:11:15 -0800 Subject: [PATCH 003/300] sparc: Remove prom_pathtoinode() Unused. Signed-off-by: David S. Miller --- arch/sparc/include/asm/oplib_32.h | 1 - arch/sparc/include/asm/oplib_64.h | 1 - arch/sparc/prom/tree_32.c | 16 ---------------- arch/sparc/prom/tree_64.c | 18 ------------------ 4 files changed, 36 deletions(-) diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index 51296a6f5005..b0f79beffc3b 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h @@ -238,7 +238,6 @@ extern int prom_node_has_property(phandle node, char *property); extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, int value_size); -extern phandle prom_pathtoinode(char *path); extern phandle prom_inst2pkg(int); /* Dorking with Bus ranges... */ diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index c9cc078e3e31..9b01a4b8ae18 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h @@ -279,7 +279,6 @@ extern phandle prom_finddevice(const char *name); extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, int value_size); -extern phandle prom_pathtoinode(const char *path); extern phandle prom_inst2pkg(int); extern int prom_service_exists(const char *service_name); extern void prom_sun4v_guest_soft_state(void); diff --git a/arch/sparc/prom/tree_32.c b/arch/sparc/prom/tree_32.c index 63e08e149774..535e2e69ac1d 100644 --- a/arch/sparc/prom/tree_32.c +++ b/arch/sparc/prom/tree_32.c @@ -342,19 +342,3 @@ phandle prom_inst2pkg(int inst) if (node == -1) return 0; return node; } - -/* Return 'node' assigned to a particular prom 'path' - * FIXME: Should work for v0 as well - */ -phandle prom_pathtoinode(char *path) -{ - phandle node; - int inst; - - inst = prom_devopen (path); - if (inst == -1) return 0; - node = prom_inst2pkg (inst); - prom_devclose (inst); - if (node == -1) return 0; - return node; -} diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c index 691be68932f8..d93660048376 100644 --- a/arch/sparc/prom/tree_64.c +++ b/arch/sparc/prom/tree_64.c @@ -374,24 +374,6 @@ inline phandle prom_inst2pkg(int inst) return node; } -/* Return 'node' assigned to a particular prom 'path' - * FIXME: Should work for v0 as well - */ -phandle prom_pathtoinode(const char *path) -{ - phandle node; - int inst; - - inst = prom_devopen (path); - if (inst == 0) - return 0; - node = prom_inst2pkg(inst); - prom_devclose(inst); - if (node == -1) - return 0; - return node; -} - int prom_ihandle2path(int handle, char *buffer, int bufsize) { unsigned long args[7]; From b148246912bea92bde2a0cba125ca94f1f776b12 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 16 Nov 2010 12:23:20 -0800 Subject: [PATCH 004/300] sparc: Kill prom devops_{32,64}.c Completely unused. Signed-off-by: David S. Miller --- arch/sparc/include/asm/oplib_32.h | 19 ------- arch/sparc/include/asm/oplib_64.h | 21 -------- arch/sparc/prom/Makefile | 1 - arch/sparc/prom/devops_32.c | 87 ------------------------------- arch/sparc/prom/devops_64.c | 67 ------------------------ 5 files changed, 195 deletions(-) delete mode 100644 arch/sparc/prom/devops_32.c delete mode 100644 arch/sparc/prom/devops_64.c diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index b0f79beffc3b..1d893fa6374c 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h @@ -60,25 +60,6 @@ extern char *prom_getbootargs(void); extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes); extern void prom_unmapio(char *virt_addr, unsigned int num_bytes); -/* Device operations. */ - -/* Open the device described by the passed string. Note, that the format - * of the string is different on V0 vs. V2->higher proms. The caller must - * know what he/she is doing! Returns the device descriptor, an int. - */ -extern int prom_devopen(char *device_string); - -/* Close a previously opened device described by the passed integer - * descriptor. - */ -extern int prom_devclose(int device_handle); - -/* Do a seek operation on the device described by the passed integer - * descriptor. - */ -extern void prom_seek(int device_handle, unsigned int seek_hival, - unsigned int seek_lowval); - /* Miscellaneous routines, don't really fit in any category per se. */ /* Reboot the machine with the command line passed. */ diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index 9b01a4b8ae18..8441d1aa31c8 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h @@ -67,27 +67,6 @@ extern void prom_init(void *cif_handler, void *cif_stack); /* Boot argument acquisition, returns the boot command line string. */ extern char *prom_getbootargs(void); -/* Device utilities. */ - -/* Device operations. */ - -/* Open the device described by the passed string. Note, that the format - * of the string is different on V0 vs. V2->higher proms. The caller must - * know what he/she is doing! Returns the device descriptor, an int. - */ -extern int prom_devopen(const char *device_string); - -/* Close a previously opened device described by the passed integer - * descriptor. - */ -extern int prom_devclose(int device_handle); - -/* Do a seek operation on the device described by the passed integer - * descriptor. - */ -extern void prom_seek(int device_handle, unsigned int seek_hival, - unsigned int seek_lowval); - /* Miscellaneous routines, don't really fit in any category per se. */ /* Reboot the machine with the command line passed. */ diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile index 1b8c073adb44..816c0fa12dc0 100644 --- a/arch/sparc/prom/Makefile +++ b/arch/sparc/prom/Makefile @@ -6,7 +6,6 @@ ccflags := -Werror lib-y := bootstr_$(BITS).o lib-$(CONFIG_SPARC32) += devmap.o -lib-y += devops_$(BITS).o lib-y += init_$(BITS).o lib-$(CONFIG_SPARC32) += memory.o lib-y += misc_$(BITS).o diff --git a/arch/sparc/prom/devops_32.c b/arch/sparc/prom/devops_32.c deleted file mode 100644 index 9c5d4687242a..000000000000 --- a/arch/sparc/prom/devops_32.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * devops.c: Device operations using the PROM. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - */ -#include -#include -#include - -#include -#include - -extern void restore_current(void); - -/* Open the device described by the string 'dstr'. Returns the handle - * to that device used for subsequent operations on that device. - * Returns -1 on failure. - */ -int -prom_devopen(char *dstr) -{ - int handle; - unsigned long flags; - spin_lock_irqsave(&prom_lock, flags); - switch(prom_vers) { - case PROM_V0: - handle = (*(romvec->pv_v0devops.v0_devopen))(dstr); - if(handle == 0) handle = -1; - break; - case PROM_V2: - case PROM_V3: - handle = (*(romvec->pv_v2devops.v2_dev_open))(dstr); - break; - default: - handle = -1; - break; - }; - restore_current(); - spin_unlock_irqrestore(&prom_lock, flags); - - return handle; -} - -/* Close the device described by device handle 'dhandle'. */ -int -prom_devclose(int dhandle) -{ - unsigned long flags; - spin_lock_irqsave(&prom_lock, flags); - switch(prom_vers) { - case PROM_V0: - (*(romvec->pv_v0devops.v0_devclose))(dhandle); - break; - case PROM_V2: - case PROM_V3: - (*(romvec->pv_v2devops.v2_dev_close))(dhandle); - break; - default: - break; - }; - restore_current(); - spin_unlock_irqrestore(&prom_lock, flags); - return 0; -} - -/* Seek to specified location described by 'seekhi' and 'seeklo' - * for device 'dhandle'. - */ -void -prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) -{ - unsigned long flags; - spin_lock_irqsave(&prom_lock, flags); - switch(prom_vers) { - case PROM_V0: - (*(romvec->pv_v0devops.v0_seekdev))(dhandle, seekhi, seeklo); - break; - case PROM_V2: - case PROM_V3: - (*(romvec->pv_v2devops.v2_dev_seek))(dhandle, seekhi, seeklo); - break; - default: - break; - }; - restore_current(); - spin_unlock_irqrestore(&prom_lock, flags); -} diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c deleted file mode 100644 index a017119e7ef1..000000000000 --- a/arch/sparc/prom/devops_64.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * devops.c: Device operations using the PROM. - * - * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) - * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) - */ -#include -#include -#include - -#include -#include - -/* Open the device described by the string 'dstr'. Returns the handle - * to that device used for subsequent operations on that device. - * Returns 0 on failure. - */ -int -prom_devopen(const char *dstr) -{ - unsigned long args[5]; - - args[0] = (unsigned long) "open"; - args[1] = 1; - args[2] = 1; - args[3] = (unsigned long) dstr; - args[4] = (unsigned long) -1; - - p1275_cmd_direct(args); - - return (int) args[4]; -} - -/* Close the device described by device handle 'dhandle'. */ -int -prom_devclose(int dhandle) -{ - unsigned long args[4]; - - args[0] = (unsigned long) "close"; - args[1] = 1; - args[2] = 0; - args[3] = (unsigned int) dhandle; - - p1275_cmd_direct(args); - - return 0; -} - -/* Seek to specified location described by 'seekhi' and 'seeklo' - * for device 'dhandle'. - */ -void -prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) -{ - unsigned long args[7]; - - args[0] = (unsigned long) "seek"; - args[1] = 3; - args[2] = 1; - args[3] = (unsigned int) dhandle; - args[4] = seekhi; - args[5] = seeklo; - args[6] = (unsigned long) -1; - - p1275_cmd_direct(args); -} From f7b5f55ac1623dfde24ef5319ad77c1746645f3f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 16 Nov 2010 12:24:16 -0800 Subject: [PATCH 005/300] sparc64: Unexport prom_service_exists(). Only used by functions in misc_64.c so make it private to that file. Signed-off-by: David S. Miller --- arch/sparc/include/asm/oplib_64.h | 1 - arch/sparc/prom/misc_64.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index 8441d1aa31c8..daf02d314279 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h @@ -259,7 +259,6 @@ extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, int value_size); extern phandle prom_inst2pkg(int); -extern int prom_service_exists(const char *service_name); extern void prom_sun4v_guest_soft_state(void); extern int prom_ihandle2path(int handle, char *buffer, int bufsize); diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c index d24bc44e361e..b900fdf829a0 100644 --- a/arch/sparc/prom/misc_64.c +++ b/arch/sparc/prom/misc_64.c @@ -18,7 +18,7 @@ #include #include -int prom_service_exists(const char *service_name) +static int prom_service_exists(const char *service_name) { unsigned long args[5]; From c540ee70e49b573535c7ddfd0e9a0fc9d549c8b7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 16 Nov 2010 12:50:19 -0800 Subject: [PATCH 006/300] sparc64: Delete prom_setcallback(). Unused. Signed-off-by: David S. Miller --- arch/sparc/include/asm/oplib_64.h | 8 -------- arch/sparc/prom/misc_64.c | 14 -------------- 2 files changed, 22 deletions(-) diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index daf02d314279..56985e300471 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h @@ -88,14 +88,6 @@ extern void prom_halt(void) __attribute__ ((noreturn)); /* Halt and power-off the machine. */ extern void prom_halt_power_off(void) __attribute__ ((noreturn)); -/* Set the PROM 'sync' callback function to the passed function pointer. - * When the user gives the 'sync' command at the prom prompt while the - * kernel is still active, the prom will call this routine. - * - */ -typedef int (*callback_func_t)(long *cmd); -extern void prom_setcallback(callback_func_t func_ptr); - /* Acquire the IDPROM of the root node in the prom device tree. This * gets passed a buffer where you would like it stuffed. The return value * is the format type of this idprom or 0xff on error. diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c index b900fdf829a0..e4f31d4d3715 100644 --- a/arch/sparc/prom/misc_64.c +++ b/arch/sparc/prom/misc_64.c @@ -150,20 +150,6 @@ void prom_halt_power_off(void) prom_halt(); } -/* Set prom sync handler to call function 'funcp'. */ -void prom_setcallback(callback_func_t funcp) -{ - unsigned long args[5]; - if (!funcp) - return; - args[0] = (unsigned long) "set-callback"; - args[1] = 1; - args[2] = 1; - args[3] = (unsigned long) funcp; - args[4] = (unsigned long) -1; - p1275_cmd_direct(args); -} - /* Get the idprom and stuff it into buffer 'idbuf'. Returns the * format type. 'num_bytes' is the number of bytes that your idbuf * has space for. Returns 0xff on error. From 91921fef7c658b12de53376b312d071d757f7770 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 17 Nov 2010 10:22:56 -0800 Subject: [PATCH 007/300] sparc: Do not export prom_nb{get,put}char(). Never used outside of console_{32,64}.c Signed-off-by: David S. Miller --- arch/sparc/include/asm/oplib_32.h | 6 ------ arch/sparc/include/asm/oplib_64.h | 6 ------ arch/sparc/prom/console_32.c | 6 ++---- arch/sparc/prom/console_64.c | 6 ++---- 4 files changed, 4 insertions(+), 20 deletions(-) diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index 1d893fa6374c..49fe4266f86a 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h @@ -104,12 +104,6 @@ extern int prom_getprev(void); /* Character operations to/from the console.... */ -/* Non-blocking get character from console. */ -extern int prom_nbgetchar(void); - -/* Non-blocking put character to console. */ -extern int prom_nbputchar(char character); - /* Blocking get character from console. */ extern char prom_getchar(void); diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index 56985e300471..d541de4b6844 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h @@ -96,12 +96,6 @@ extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); /* Character operations to/from the console.... */ -/* Non-blocking get character from console. */ -extern int prom_nbgetchar(void); - -/* Non-blocking put character to console. */ -extern int prom_nbputchar(char character); - /* Blocking get character from console. */ extern char prom_getchar(void); diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c index 5340264b78f5..2ce5acb45f2d 100644 --- a/arch/sparc/prom/console_32.c +++ b/arch/sparc/prom/console_32.c @@ -19,8 +19,7 @@ extern void restore_current(void); /* Non blocking get character from console input device, returns -1 * if no input was taken. This can be used for polling. */ -int -prom_nbgetchar(void) +static int prom_nbgetchar(void) { static char inc; int i = -1; @@ -51,8 +50,7 @@ prom_nbgetchar(void) /* Non blocking put character to console device, returns -1 if * unsuccessful. */ -int -prom_nbputchar(char c) +static int prom_nbputchar(char c) { static char outc; unsigned long flags; diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index de67fc73d91e..33a8b275d6af 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c @@ -18,8 +18,7 @@ extern int prom_stdin, prom_stdout; /* Non blocking get character from console input device, returns -1 * if no input was taken. This can be used for polling. */ -inline int -prom_nbgetchar(void) +static int prom_nbgetchar(void) { unsigned long args[7]; char inc; @@ -42,8 +41,7 @@ prom_nbgetchar(void) /* Non blocking put character to console device, returns -1 if * unsuccessful. */ -inline int -prom_nbputchar(char c) +static int prom_nbputchar(char c) { unsigned long args[7]; char outc; From 09910509ebc74643e94fe6f3feb4c23b019aeb34 Mon Sep 17 00:00:00 2001 From: Glenn Sommer Date: Mon, 22 Nov 2010 12:00:05 -0800 Subject: [PATCH 008/300] Input: usbtouchscreen - add support for LG Flatron T1710B I've recently got my hands on a LG Flatron T1710B touchscreen. As other LG products, this seems to use the ITM panel. Signed-off-by: Glenn Sommer Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/usbtouchscreen.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index f45f80f6d336..73fd6642b681 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -178,6 +178,7 @@ static const struct usb_device_id usbtouch_devices[] = { #ifdef CONFIG_TOUCHSCREEN_USB_ITM {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, + {USB_DEVICE(0x16e3, 0xf9e9), .driver_info = DEVTYPE_ITM}, #endif #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO From c89ad7372232b69fd37edf90d6f5d2a8d6381214 Mon Sep 17 00:00:00 2001 From: "Gustavo F. Padovan" Date: Mon, 1 Nov 2010 19:08:50 +0000 Subject: [PATCH 009/300] Bluetooth: Fix not returning proper error in SCO Return 0 in that situation could lead to errors in the caller. Signed-off-by: Gustavo F. Padovan --- net/bluetooth/sco.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index d0927d1fdada..66b9e5c0523a 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -882,7 +882,7 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) int lm = 0; if (type != SCO_LINK && type != ESCO_LINK) - return 0; + return -EINVAL; BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); @@ -908,7 +908,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status) BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) - return 0; + return -EINVAL; if (!status) { struct sco_conn *conn; @@ -927,7 +927,7 @@ static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) BT_DBG("hcon %p reason %d", hcon, reason); if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) - return 0; + return -EINVAL; sco_conn_del(hcon, bt_err(reason)); From c72b844ed2f55c442b464e382a2eb2ecab5292a8 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 22 Oct 2010 16:18:47 -0700 Subject: [PATCH 010/300] ibm_rtl: fix printk format warning Fix printk format warning: drivers/platform/x86/ibm_rtl.c:305:warning: format '%#llx' expects type 'long long unsigned int', but argument 2 has type 'phys_addr_t' Signed-off-by: Randy Dunlap Cc: Keith Mannthey Cc: Vernon Mauery Cc: platform-driver-x86@vger.kernel.org Cc: Matthew Garrett Signed-off-by: Matthew Garrett --- drivers/platform/x86/ibm_rtl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/ibm_rtl.c b/drivers/platform/x86/ibm_rtl.c index 3c2c6b91ecb3..a884f5498846 100644 --- a/drivers/platform/x86/ibm_rtl.c +++ b/drivers/platform/x86/ibm_rtl.c @@ -302,7 +302,7 @@ static int __init ibm_rtl_init(void) { RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n", rtl_cmd_width, rtl_cmd_type); addr = ioread32(&rtl_table->cmd_port_address); - RTL_DEBUG("addr = %#llx\n", addr); + RTL_DEBUG("addr = %#llx\n", (unsigned long long)addr); plen = rtl_cmd_width/sizeof(char); rtl_cmd_addr = rtl_port_map(addr, plen); RTL_DEBUG("rtl_cmd_addr = %#llx\n", (u64)rtl_cmd_addr); From a49010f53b723ed0711d645ec43bde498c6756dc Mon Sep 17 00:00:00 2001 From: Jon Dowland Date: Wed, 27 Oct 2010 00:24:59 +0100 Subject: [PATCH 011/300] toshiba_acpi.c: Add key_entry for a lone FN keypress MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A lone FN key press on a Toshiba Portégé R700 without another key in conjunction results in an ACPI event and a spurious error message on the console. Add a key entry to map this event to a KEY_FN keypress. This prevents the console message. Signed-off-by: Jon Dowland Signed-off-by: Matthew Garrett --- drivers/platform/x86/toshiba_acpi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 06f304f46e02..4276da7291b8 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -135,6 +135,7 @@ static const struct key_entry toshiba_acpi_keymap[] __initconst = { { KE_KEY, 0x141, { KEY_BRIGHTNESSUP } }, { KE_KEY, 0x142, { KEY_WLAN } }, { KE_KEY, 0x143, { KEY_PROG1 } }, + { KE_KEY, 0x17f, { KEY_FN } }, { KE_KEY, 0xb05, { KEY_PROG2 } }, { KE_KEY, 0xb06, { KEY_WWW } }, { KE_KEY, 0xb07, { KEY_MAIL } }, From e599ab2556006398ba9aad536a58eedad515e807 Mon Sep 17 00:00:00 2001 From: Chris Bagwell Date: Mon, 25 Oct 2010 21:08:39 -0500 Subject: [PATCH 012/300] eeepc-wmi: add cpufv sysfs documentation Based on cpufv text from sysfs-platform-eeepc-laptop that has almost same behavior. Signed-off-by: Chris Bagwell Signed-off-by: Matthew Garrett Acked-by: Corentin Chary --- Documentation/ABI/testing/sysfs-platform-eeepc-wmi | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-platform-eeepc-wmi diff --git a/Documentation/ABI/testing/sysfs-platform-eeepc-wmi b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi new file mode 100644 index 000000000000..e4b5fef5fadd --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi @@ -0,0 +1,10 @@ +What: /sys/devices/platform/eeepc-wmi/cpufv +Date: Oct 2010 +KernelVersion: 2.6.37 +Contact: "Corentin Chary" +Description: + Change CPU clock configuration (write-only). + There are three available clock configuration: + * 0 -> Super Performance Mode + * 1 -> High Performance Mode + * 2 -> Power Saving Mode From d41014b92d60a6b375aad9b6ebc52201ee58df70 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 26 Oct 2010 12:25:37 +0200 Subject: [PATCH 013/300] drivers/platform/x86/thinkpad_acpi.c: delete double assignment Delete successive assignments to the same location. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression i; @@ *i = ...; i = ...; // Signed-off-by: Julia Lawall Signed-off-by: Matthew Garrett --- drivers/platform/x86/thinkpad_acpi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 2d61186ad5a2..e8c21994b36d 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -8497,7 +8497,6 @@ static void ibm_exit(struct ibm_struct *ibm) ibm->acpi->type, dispatch_acpi_notify); ibm->flags.acpi_notify_installed = 0; - ibm->flags.acpi_notify_installed = 0; } if (ibm->flags.proc_created) { From a2262260f9eaee4acd56b5624b5d2bf4be9bb38a Mon Sep 17 00:00:00 2001 From: Vernon Mauery Date: Tue, 2 Nov 2010 13:08:10 -0700 Subject: [PATCH 014/300] ibm_rtl: Loosen the DMI criteria to all IBM machines Allow all IBM machines to pass the DMI check so that we don't have to add them one by one to the driver. Any IBM machine that has the _RTL_ table in the EBDA will work. Signed-off-by: Vernon Mauery Signed-off-by: Matthew Garrett --- drivers/platform/x86/ibm_rtl.c | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/drivers/platform/x86/ibm_rtl.c b/drivers/platform/x86/ibm_rtl.c index a884f5498846..5c975edb3c81 100644 --- a/drivers/platform/x86/ibm_rtl.c +++ b/drivers/platform/x86/ibm_rtl.c @@ -220,32 +220,13 @@ static void rtl_teardown_sysfs(void) { sysdev_class_unregister(&class_rtl); } -static int dmi_check_cb(const struct dmi_system_id *id) -{ - RTL_DEBUG("found IBM server '%s'\n", id->ident); - return 0; -} - -#define ibm_dmi_entry(NAME, TYPE) \ -{ \ - .ident = NAME, \ - .matches = { \ - DMI_MATCH(DMI_SYS_VENDOR, "IBM"), \ - DMI_MATCH(DMI_PRODUCT_NAME, TYPE), \ - }, \ - .callback = dmi_check_cb \ -} static struct dmi_system_id __initdata ibm_rtl_dmi_table[] = { - ibm_dmi_entry("BladeCenter LS21", "7971"), - ibm_dmi_entry("BladeCenter LS22", "7901"), - ibm_dmi_entry("BladeCenter HS21 XM", "7995"), - ibm_dmi_entry("BladeCenter HS22", "7870"), - ibm_dmi_entry("BladeCenter HS22V", "7871"), - ibm_dmi_entry("System x3550 M2", "7946"), - ibm_dmi_entry("System x3650 M2", "7947"), - ibm_dmi_entry("System x3550 M3", "7944"), - ibm_dmi_entry("System x3650 M3", "7945"), + { \ + .matches = { \ + DMI_MATCH(DMI_SYS_VENDOR, "IBM"), \ + }, \ + }, { } }; From 1d37db77c1aa199ae9a4114af7c0412c8417e949 Mon Sep 17 00:00:00 2001 From: Vernon Mauery Date: Tue, 2 Nov 2010 13:08:11 -0700 Subject: [PATCH 015/300] ibm_rtl: _RTL_ is not available in UEFI mode Some of the IBM servers that are supported by ibm_rtl can run in both Legacy mode (BIOS) and in UEFI mode. When running in UEFI mode, it is possible that the EBDA table exists but cannot be mapped and reports errors. We need to make sure that by default we don't try to probe the machines if they are running in UEFI mode. Signed-off-by: Vernon Mauery Signed-off-by: Matthew Garrett --- drivers/platform/x86/ibm_rtl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/platform/x86/ibm_rtl.c b/drivers/platform/x86/ibm_rtl.c index 5c975edb3c81..94a114aa8e28 100644 --- a/drivers/platform/x86/ibm_rtl.c +++ b/drivers/platform/x86/ibm_rtl.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -238,7 +239,7 @@ static int __init ibm_rtl_init(void) { if (force) pr_warning("ibm-rtl: module loaded by force\n"); /* first ensure that we are running on IBM HW */ - else if (!dmi_check_system(ibm_rtl_dmi_table)) + else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table)) return -ENODEV; /* Get the address for the Extended BIOS Data Area */ From 67fa38ec097a3e270ab175636338185017b49fa7 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 3 Nov 2010 11:14:01 -0700 Subject: [PATCH 016/300] eeepc-wmi: fix compiler warning This fixes the following: CC [M] drivers/platform/x86/eeepc-wmi.o drivers/platform/x86/eeepc-wmi.c:322: warning: initialization from incompatible pointer type Signed-off-by: Dmitry Torokhov Signed-off-by: Matthew Garrett --- drivers/platform/x86/eeepc-wmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index 462ceab93f87..0d50fbbe2478 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c @@ -298,8 +298,8 @@ static void eeepc_wmi_notify(u32 value, void *context) kfree(obj); } -static int store_cpufv(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { int value; struct acpi_buffer input = { (acpi_size)sizeof(value), &value }; From ba1ff5be52163a97ac4ce8bc51beae2c96861a43 Mon Sep 17 00:00:00 2001 From: Corentin Chary Date: Sun, 14 Nov 2010 17:40:12 +0100 Subject: [PATCH 017/300] asus-laptop: add wimax and wwan support Asus UL30A has a 3G chip, but the radio is disabled by default. The DSDT also reference a WIMAX device, which is not present on this model. This patch adds two new files: wwan and wimax to control WWAN and WIMAX devices. It does not use rfkill, because like WLED and BLED, we don't know yet that the two ACPI functions will always control the radio, they may control only the leds on some hardware. We may add rfkill switchs later. Signed-off-by: Corentin Chary Signed-off-by: Matthew Garrett --- .../ABI/testing/sysfs-platform-asus-laptop | 16 ++- drivers/platform/x86/asus-laptop.c | 97 ++++++++++++++++++- 2 files changed, 111 insertions(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-platform-asus-laptop b/Documentation/ABI/testing/sysfs-platform-asus-laptop index 1d775390e856..41ff8ae4dee0 100644 --- a/Documentation/ABI/testing/sysfs-platform-asus-laptop +++ b/Documentation/ABI/testing/sysfs-platform-asus-laptop @@ -47,6 +47,20 @@ Date: January 2007 KernelVersion: 2.6.20 Contact: "Corentin Chary" Description: - Control the bluetooth device. 1 means on, 0 means off. + Control the wlan device. 1 means on, 0 means off. This may control the led, the device or both. Users: Lapsus + +What: /sys/devices/platform/asus_laptop/wimax +Date: October 2010 +KernelVersion: 2.6.37 +Contact: "Corentin Chary" +Description: + Control the wimax device. 1 means on, 0 means off. + +What: /sys/devices/platform/asus_laptop/wwan +Date: October 2010 +KernelVersion: 2.6.37 +Contact: "Corentin Chary" +Description: + Control the wwan (3G) device. 1 means on, 0 means off. diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 60a5a5c6b50a..d235f44fd7a3 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -81,6 +81,8 @@ MODULE_PARM_DESC(wapf, "WAPF value"); static int wlan_status = 1; static int bluetooth_status = 1; +static int wimax_status = -1; +static int wwan_status = -1; module_param(wlan_status, int, 0444); MODULE_PARM_DESC(wlan_status, "Set the wireless status on boot " @@ -92,6 +94,16 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot " "(0 = disabled, 1 = enabled, -1 = don't do anything). " "default is 1"); +module_param(wimax_status, int, 0444); +MODULE_PARM_DESC(wimax_status, "Set the wireless status on boot " + "(0 = disabled, 1 = enabled, -1 = don't do anything). " + "default is 1"); + +module_param(wwan_status, int, 0444); +MODULE_PARM_DESC(wwan_status, "Set the wireless status on boot " + "(0 = disabled, 1 = enabled, -1 = don't do anything). " + "default is 1"); + /* * Some events we use, same for all Asus */ @@ -114,6 +126,8 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot " */ #define WL_RSTS 0x01 /* internal Wifi */ #define BT_RSTS 0x02 /* internal Bluetooth */ +#define WM_RSTS 0x08 /* internal wimax */ +#define WW_RSTS 0x20 /* internal wwan */ /* LED */ #define METHOD_MLED "MLED" @@ -132,6 +146,11 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot " */ #define METHOD_WLAN "WLED" #define METHOD_BLUETOOTH "BLED" + +/* WWAN and WIMAX */ +#define METHOD_WWAN "GSMC" +#define METHOD_WIMAX "WMXC" + #define METHOD_WL_STATUS "RSTS" /* Brightness */ @@ -882,6 +901,64 @@ static ssize_t store_bluetooth(struct device *dev, return sysfs_acpi_set(asus, buf, count, METHOD_BLUETOOTH); } +/* + * Wimax + */ +static int asus_wimax_set(struct asus_laptop *asus, int status) +{ + if (write_acpi_int(asus->handle, METHOD_WIMAX, !!status)) { + pr_warning("Error setting wimax status to %d", status); + return -EIO; + } + return 0; +} + +static ssize_t show_wimax(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct asus_laptop *asus = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", asus_wireless_status(asus, WM_RSTS)); +} + +static ssize_t store_wimax(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct asus_laptop *asus = dev_get_drvdata(dev); + + return sysfs_acpi_set(asus, buf, count, METHOD_WIMAX); +} + +/* + * Wwan + */ +static int asus_wwan_set(struct asus_laptop *asus, int status) +{ + if (write_acpi_int(asus->handle, METHOD_WWAN, !!status)) { + pr_warning("Error setting wwan status to %d", status); + return -EIO; + } + return 0; +} + +static ssize_t show_wwan(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct asus_laptop *asus = dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", asus_wireless_status(asus, WW_RSTS)); +} + +static ssize_t store_wwan(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) +{ + struct asus_laptop *asus = dev_get_drvdata(dev); + + return sysfs_acpi_set(asus, buf, count, METHOD_WWAN); +} + /* * Display */ @@ -1202,6 +1279,8 @@ static DEVICE_ATTR(infos, S_IRUGO, show_infos, NULL); static DEVICE_ATTR(wlan, S_IRUGO | S_IWUSR, show_wlan, store_wlan); static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR, show_bluetooth, store_bluetooth); +static DEVICE_ATTR(wimax, S_IRUGO | S_IWUSR, show_wimax, store_wimax); +static DEVICE_ATTR(wwan, S_IRUGO | S_IWUSR, show_wwan, store_wwan); static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp); static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd); static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl); @@ -1212,6 +1291,8 @@ static struct attribute *asus_attributes[] = { &dev_attr_infos.attr, &dev_attr_wlan.attr, &dev_attr_bluetooth.attr, + &dev_attr_wimax.attr, + &dev_attr_wwan.attr, &dev_attr_display.attr, &dev_attr_ledd.attr, &dev_attr_ls_level.attr, @@ -1239,6 +1320,13 @@ static mode_t asus_sysfs_is_visible(struct kobject *kobj, } else if (attr == &dev_attr_display.attr) { supported = !acpi_check_handle(handle, METHOD_SWITCH_DISPLAY, NULL); + } else if (attr == &dev_attr_wimax.attr) { + supported = + !acpi_check_handle(asus->handle, METHOD_WIMAX, NULL); + + } else if (attr == &dev_attr_wwan.attr) { + supported = !acpi_check_handle(asus->handle, METHOD_WWAN, NULL); + } else if (attr == &dev_attr_ledd.attr) { supported = !acpi_check_handle(handle, METHOD_LEDD, NULL); @@ -1397,7 +1485,8 @@ static int asus_laptop_get_info(struct asus_laptop *asus) /* * The HWRS method return informations about the hardware. - * 0x80 bit is for WLAN, 0x100 for Bluetooth. + * 0x80 bit is for WLAN, 0x100 for Bluetooth, + * 0x40 for WWAN, 0x10 for WIMAX. * The significance of others is yet to be found. */ status = @@ -1440,6 +1529,12 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus) if (wlan_status >= 0) asus_wlan_set(asus, !!wlan_status); + if (wimax_status >= 0) + asus_wimax_set(asus, !!wimax_status); + + if (wwan_status >= 0) + asus_wwan_set(asus, !!wwan_status); + /* Keyboard Backlight is on by default */ if (!acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_SET, NULL)) asus_kled_set(asus, 1); From 92f61cbc614fb422759790739cbd3e5a68c9a6fc Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Thu, 18 Nov 2010 13:00:53 +0100 Subject: [PATCH 018/300] msi-wmi: Add mute key support Add new MUTE key seen on Medion Akoya AIO PC P4010D using MSI motherboard (Product Name: MS-7621) Reported-and-tested-by: Mark Huijgen Signed-off-by: Anisse Astier Signed-off-by: Matthew Garrett --- drivers/platform/x86/msi-wmi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index 42a5469a2459..bde607d98d6f 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c @@ -48,11 +48,13 @@ MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2"); #define MSI_WMI_BRIGHTNESSDOWN (KEYCODE_BASE + 1) #define MSI_WMI_VOLUMEUP (KEYCODE_BASE + 2) #define MSI_WMI_VOLUMEDOWN (KEYCODE_BASE + 3) +#define MSI_WMI_MUTE (KEYCODE_BASE + 4) static struct key_entry msi_wmi_keymap[] = { { KE_KEY, MSI_WMI_BRIGHTNESSUP, {KEY_BRIGHTNESSUP} }, { KE_KEY, MSI_WMI_BRIGHTNESSDOWN, {KEY_BRIGHTNESSDOWN} }, { KE_KEY, MSI_WMI_VOLUMEUP, {KEY_VOLUMEUP} }, { KE_KEY, MSI_WMI_VOLUMEDOWN, {KEY_VOLUMEDOWN} }, + { KE_KEY, MSI_WMI_MUTE, {KEY_MUTE} }, { KE_END, 0} }; static ktime_t last_pressed[ARRAY_SIZE(msi_wmi_keymap) - 1]; From a80e1cd70144fe7727f2e2d838611b6b8cf8a6d5 Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Thu, 18 Nov 2010 13:00:54 +0100 Subject: [PATCH 019/300] msi-wmi: fix semantically incorrect use of keycode instead of scancode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I didn't know the difference between the two when I wrote this code in commit c30116c6f0d26cd6e46dfa578163d573ef4730b2. Signed-off-by: Anisse Astier Signed-off-by: Matthew Garrett --- drivers/platform/x86/msi-wmi.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index bde607d98d6f..35278ad7e628 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c @@ -43,12 +43,12 @@ MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2"); #define dprintk(msg...) pr_debug(DRV_PFX msg) -#define KEYCODE_BASE 0xD0 -#define MSI_WMI_BRIGHTNESSUP KEYCODE_BASE -#define MSI_WMI_BRIGHTNESSDOWN (KEYCODE_BASE + 1) -#define MSI_WMI_VOLUMEUP (KEYCODE_BASE + 2) -#define MSI_WMI_VOLUMEDOWN (KEYCODE_BASE + 3) -#define MSI_WMI_MUTE (KEYCODE_BASE + 4) +#define SCANCODE_BASE 0xD0 +#define MSI_WMI_BRIGHTNESSUP SCANCODE_BASE +#define MSI_WMI_BRIGHTNESSDOWN (SCANCODE_BASE + 1) +#define MSI_WMI_VOLUMEUP (SCANCODE_BASE + 2) +#define MSI_WMI_VOLUMEDOWN (SCANCODE_BASE + 3) +#define MSI_WMI_MUTE (SCANCODE_BASE + 4) static struct key_entry msi_wmi_keymap[] = { { KE_KEY, MSI_WMI_BRIGHTNESSUP, {KEY_BRIGHTNESSUP} }, { KE_KEY, MSI_WMI_BRIGHTNESSDOWN, {KEY_BRIGHTNESSDOWN} }, @@ -171,7 +171,7 @@ static void msi_wmi_notify(u32 value, void *context) ktime_t diff; cur = ktime_get_real(); diff = ktime_sub(cur, last_pressed[key->code - - KEYCODE_BASE]); + SCANCODE_BASE]); /* Ignore event if the same event happened in a 50 ms timeframe -> Key press may result in 10-20 GPEs */ if (ktime_to_us(diff) < 1000 * 50) { @@ -180,7 +180,7 @@ static void msi_wmi_notify(u32 value, void *context) key->code, ktime_to_us(diff)); return; } - last_pressed[key->code - KEYCODE_BASE] = cur; + last_pressed[key->code - SCANCODE_BASE] = cur; if (key->type == KE_KEY && /* Brightness is served via acpi video driver */ From 53c96dfdd0c0ccbba7aee84c60ce0f2aa466413f Mon Sep 17 00:00:00 2001 From: Zeng Zhaoming Date: Fri, 19 Nov 2010 00:46:19 +0800 Subject: [PATCH 020/300] ACPI, hp-wmi: Fix memory leak in acpi query Free acpi return memory after query. Signed-off-by: Zeng Zhaoming Signed-off-by: Matthew Garrett --- drivers/platform/x86/hp-wmi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 1dac659b5e0c..9e05af9c41cb 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -172,6 +172,8 @@ static int hp_wmi_perform_query(int query, int write, u32 *buffer, bios_return = *((struct bios_return *)obj->buffer.pointer); memcpy(buffer, &bios_return.value, sizeof(bios_return.value)); + + kfree(obj); return 0; } From e5cba24e3f018d4beb6acd101a82483c98f91ce7 Mon Sep 17 00:00:00 2001 From: Hitoshi Mitake Date: Fri, 26 Nov 2010 12:06:44 +0100 Subject: [PATCH 021/300] workqueue: check the allocation of system_unbound_wq I found a trivial bug on initialization of workqueue. Current init_workqueues doesn't check the result of allocation of system_unbound_wq, this should be checked like other queues. Signed-off-by: Hitoshi Mitake Cc: Arjan van de Ven Cc: David Howells Signed-off-by: Tejun Heo --- kernel/workqueue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 90db1bd1a978..ca017ce8bc6b 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -3692,7 +3692,8 @@ static int __init init_workqueues(void) system_nrt_wq = alloc_workqueue("events_nrt", WQ_NON_REENTRANT, 0); system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE); - BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq); + BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq || + !system_unbound_wq); return 0; } early_initcall(init_workqueues); From 49f4138346b3cec2706adff02658fe27ceb1e46f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 26 Nov 2010 13:42:47 +0100 Subject: [PATCH 022/300] printk: Fix wake_up_klogd() vs cpu hotplug wake_up_klogd() may get called from preemptible context but uses __raw_get_cpu_var() to write to a per cpu variable. If it gets preempted between getting the address and writing to it, the cpu in question could be offline if the process gets scheduled back and hence writes to the per cpu data of an offline cpu. This buggy behaviour was introduced with fa33507a "printk: robustify printk, fix #2" which was supposed to fix a "using smp_processor_id() in preemptible" warning. Let's use this_cpu_write() instead which disables preemption and makes sure that the outlined scenario cannot happen. Signed-off-by: Heiko Carstens Acked-by: Eric Dumazet Signed-off-by: Peter Zijlstra LKML-Reference: <20101126124247.GC7023@osiris.boeblingen.de.ibm.com> Signed-off-by: Ingo Molnar --- kernel/printk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/printk.c b/kernel/printk.c index 9a2264fc42ca..cf7588e93f6f 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -1088,7 +1088,7 @@ int printk_needs_cpu(int cpu) void wake_up_klogd(void) { if (waitqueue_active(&log_wait)) - __raw_get_cpu_var(printk_pending) = 1; + this_cpu_write(printk_pending, 1); } /** From 61ab25447ad6334a74e32f60efb135a3467223f8 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 26 Nov 2010 13:00:59 +0100 Subject: [PATCH 023/300] nohz: Fix printk_needs_cpu() return value on offline cpus This patch fixes a hang observed with 2.6.32 kernels where timers got enqueued on offline cpus. printk_needs_cpu() may return 1 if called on offline cpus. When a cpu gets offlined it schedules the idle process which, before killing its own cpu, will call tick_nohz_stop_sched_tick(). That function in turn will call printk_needs_cpu() in order to check if the local tick can be disabled. On offline cpus this function should naturally return 0 since regardless if the tick gets disabled or not the cpu will be dead short after. That is besides the fact that __cpu_disable() should already have made sure that no interrupts on the offlined cpu will be delivered anyway. In this case it prevents tick_nohz_stop_sched_tick() to call select_nohz_load_balancer(). No idea if that really is a problem. However what made me debug this is that on 2.6.32 the function get_nohz_load_balancer() is used within __mod_timer() to select a cpu on which a timer gets enqueued. If printk_needs_cpu() returns 1 then the nohz_load_balancer cpu doesn't get updated when a cpu gets offlined. It may contain the cpu number of an offline cpu. In turn timers get enqueued on an offline cpu and not very surprisingly they never expire and cause system hangs. This has been observed 2.6.32 kernels. On current kernels __mod_timer() uses get_nohz_timer_target() which doesn't have that problem. However there might be other problems because of the too early exit tick_nohz_stop_sched_tick() in case a cpu goes offline. Easiest way to fix this is just to test if the current cpu is offline and call printk_tick() directly which clears the condition. Alternatively I tried a cpu hotplug notifier which would clear the condition, however between calling the notifier function and printk_needs_cpu() something could have called printk() again and the problem is back again. This seems to be the safest fix. Signed-off-by: Heiko Carstens Signed-off-by: Peter Zijlstra Cc: stable@kernel.org LKML-Reference: <20101126120235.406766476@de.ibm.com> Signed-off-by: Ingo Molnar --- kernel/printk.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/printk.c b/kernel/printk.c index cf7588e93f6f..a23315dc4498 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -1082,6 +1082,8 @@ void printk_tick(void) int printk_needs_cpu(int cpu) { + if (unlikely(cpu_is_offline(cpu))) + printk_tick(); return per_cpu(printk_pending, cpu); } From e7a3481c0246c8e45e79c629efd63b168e91fcda Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Mon, 25 Oct 2010 16:53:46 -0700 Subject: [PATCH 024/300] x86/pvclock: Zero last_value on resume If the guest domain has been suspend/resumed or migrated, then the system clock backing the pvclock clocksource may revert to a smaller value (ie, can be non-monotonic across the migration/save-restore). Make sure we zero last_value in that case so that the domain continues to see clock updates. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- arch/x86/include/asm/pvclock.h | 1 + arch/x86/kernel/pvclock.c | 5 +++++ arch/x86/xen/time.c | 2 ++ 3 files changed, 8 insertions(+) diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h index 7f7e577a0e39..31d84acc1512 100644 --- a/arch/x86/include/asm/pvclock.h +++ b/arch/x86/include/asm/pvclock.h @@ -11,6 +11,7 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src); void pvclock_read_wallclock(struct pvclock_wall_clock *wall, struct pvclock_vcpu_time_info *vcpu, struct timespec *ts); +void pvclock_resume(void); /* * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index 008b91eefa18..42eb3300dfc6 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c @@ -83,6 +83,11 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src) static atomic64_t last_value = ATOMIC64_INIT(0); +void pvclock_resume(void) +{ + atomic64_set(&last_value, 0); +} + cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) { struct pvclock_shadow_time shadow; diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index b2bb5aa3b054..5da5e53fb94c 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c @@ -426,6 +426,8 @@ void xen_timer_resume(void) { int cpu; + pvclock_resume(); + if (xen_clockevent != &xen_vcpuop_clockevent) return; From e4dde731ae70072338352c6f8fb75fd04a42cf8d Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Mon, 29 Nov 2010 10:19:07 +0200 Subject: [PATCH 025/300] vhost: correctly set bits of dirty pages Fix two bugs in dirty page logging: When counting pages we should increase address by 1 instead of VHOST_PAGE_SIZE. Make log_write() correctly process requests that cross pages with write_address not starting at page boundary. Reported-by: Jason Wang Signed-off-by: Michael S. Tsirkin --- drivers/vhost/vhost.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 94701ff3a23a..159c77a5746f 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -884,6 +884,7 @@ static int log_write(void __user *log_base, int r; if (!write_length) return 0; + write_length += write_address % VHOST_PAGE_SIZE; write_address /= VHOST_PAGE_SIZE; for (;;) { u64 base = (u64)(unsigned long)log_base; @@ -897,7 +898,7 @@ static int log_write(void __user *log_base, if (write_length <= VHOST_PAGE_SIZE) break; write_length -= VHOST_PAGE_SIZE; - write_address += VHOST_PAGE_SIZE; + write_address += 1; } return r; } From 517ff43146b17a0d067125f098f675d1e0ac2d82 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Wed, 24 Nov 2010 16:00:49 +0000 Subject: [PATCH 026/300] libertas: fix memory corruption in lbs_remove_card() "priv" is stored at the end of the wiphy structure, which is freed during the call to lbs_cfg_free(). It must not be touched afterwards. Remove the unnecessary NULL assignment causing this memory corruption. Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 46b88b118c99..fcd1bbfc632d 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -915,8 +915,6 @@ void lbs_remove_card(struct lbs_private *priv) lbs_free_adapter(priv); lbs_cfg_free(priv); - - priv->dev = NULL; free_netdev(dev); lbs_deb_leave(LBS_DEB_MAIN); From 16ccdf0dbc84b11bc8b7fdbad66804d06a683554 Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Wed, 24 Nov 2010 16:02:00 +0000 Subject: [PATCH 027/300] libertas: fix invalid access card->priv must not be accessed after lbs_remove_card() was called as lbs_remove_card() frees card->priv via free_netdev(). For libertas_sdio this is a regression introduced by 23b149c1890f9. The correct fix to the issue described there is simply to remove the assignment. This flag is set at the appropriate time inside lbs_remove_card anyway. Reported-by: Daniel Drake Signed-off-by: Sven Neumann Signed-off-by: Daniel Drake Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_sdio.c | 1 - drivers/net/wireless/libertas/if_spi.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index e5685dc317a8..b4de0ca10feb 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -1170,7 +1170,6 @@ static void if_sdio_remove(struct sdio_func *func) lbs_deb_sdio("call remove card\n"); lbs_stop_card(card->priv); lbs_remove_card(card->priv); - card->priv->surpriseremoved = 1; flush_workqueue(card->workqueue); destroy_workqueue(card->workqueue); diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 79bcb4e5d2ca..ecd4d04b2c3c 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -1055,7 +1055,6 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) lbs_stop_card(priv); lbs_remove_card(priv); /* will call free_netdev */ - priv->surpriseremoved = 1; free_irq(spi->irq, card); if_spi_terminate_spi_thread(card); if (card->pdata->teardown) From 98c316e348bedffa730e6f1e4baeb8a3c3e0f28b Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Thu, 25 Nov 2010 18:26:07 +0100 Subject: [PATCH 028/300] ath9k: use per-device struct for pm_qos_* operations The ath9k driver uses a shared pm_qos_request_list structure for all devices. This causes the following warning if more than one device is present in the system: WARNING: at kernel/pm_qos_params.c:234 ath9k_init_device+0x5e8/0x6b0() pm_qos_add_request() called for already added request Modules linked in: Call Trace: [<802b1cdc>] dump_stack+0x8/0x34 [<8007dd90>] warn_slowpath_common+0x78/0xa4 [<8007de44>] warn_slowpath_fmt+0x2c/0x38 [<801b0828>] ath9k_init_device+0x5e8/0x6b0 [<801bc508>] ath_pci_probe+0x2dc/0x39c [<80176254>] pci_device_probe+0x64/0xa4 [<8019471c>] driver_probe_device+0xbc/0x188 [<80194854>] __driver_attach+0x6c/0xa4 [<80193e20>] bus_for_each_dev+0x60/0xb0 [<80193580>] bus_add_driver+0xcc/0x268 [<80194c08>] driver_register+0xe0/0x198 [<801764e0>] __pci_register_driver+0x50/0xe0 [<80365f48>] ath9k_init+0x3c/0x6c [<8006050c>] do_one_initcall+0xfc/0x1d8 [<80355340>] kernel_init+0xd4/0x174 [<800639a4>] kernel_thread_helper+0x10/0x18 ---[ end trace 5345fc6f870564a6 ]--- This patch fixes that warning by using a separate pm_qos_request_list sructure for each device. Signed-off-by: Gabor Juhos Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 4 +++- drivers/net/wireless/ath/ath9k/init.c | 7 ++----- drivers/net/wireless/ath/ath9k/main.c | 5 ++--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 170d44a35ccb..0d0bec3628ec 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -21,6 +21,7 @@ #include #include #include +#include #include "debug.h" #include "common.h" @@ -646,6 +647,8 @@ struct ath_softc { struct ath_descdma txsdma; struct ath_ant_comb ant_comb; + + struct pm_qos_request_list pm_qos_req; }; struct ath_wiphy { @@ -675,7 +678,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) } extern struct ieee80211_ops ath9k_ops; -extern struct pm_qos_request_list ath9k_pm_qos_req; extern int modparam_nohwcrypt; extern int led_blink; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 92bc5c5f4876..c29eea26a777 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -15,7 +15,6 @@ */ #include -#include #include "ath9k.h" @@ -180,8 +179,6 @@ static const struct ath_ops ath9k_common_ops = { .write = ath9k_iowrite32, }; -struct pm_qos_request_list ath9k_pm_qos_req; - /**************************/ /* Initialization */ /**************************/ @@ -759,7 +756,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, ath_init_leds(sc); ath_start_rfkill_poll(sc); - pm_qos_add_request(&ath9k_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, + pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); return 0; @@ -830,7 +827,7 @@ void ath9k_deinit_device(struct ath_softc *sc) } ieee80211_unregister_hw(hw); - pm_qos_remove_request(&ath9k_pm_qos_req); + pm_qos_remove_request(&sc->pm_qos_req); ath_rx_cleanup(sc); ath_tx_cleanup(sc); ath9k_deinit_softc(sc); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 25d3ef4c338e..1cdbdbe33ab5 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -15,7 +15,6 @@ */ #include -#include #include "ath9k.h" #include "btcoex.h" @@ -1244,7 +1243,7 @@ static int ath9k_start(struct ieee80211_hw *hw) ath9k_btcoex_timer_resume(sc); } - pm_qos_update_request(&ath9k_pm_qos_req, 55); + pm_qos_update_request(&sc->pm_qos_req, 55); mutex_unlock: mutex_unlock(&sc->mutex); @@ -1423,7 +1422,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) sc->sc_flags |= SC_OP_INVALID; - pm_qos_update_request(&ath9k_pm_qos_req, PM_QOS_DEFAULT_VALUE); + pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE); mutex_unlock(&sc->mutex); From c426ee247e40a70490f3d67d3c9c7d1aba54516f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 26 Nov 2010 11:38:04 +0100 Subject: [PATCH 029/300] ath9k/carl9170: advertise P2P With some upcoming changes we'd like to use the interface types for P2P capability tests. Enable them now so that when we add those tests in wpa_supplicant, nothing will break. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/init.c | 2 ++ drivers/net/wireless/ath/carl9170/fw.c | 3 ++- drivers/net/wireless/ath/carl9170/main.c | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index c29eea26a777..14b8ab386daf 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -661,6 +661,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->flags |= IEEE80211_HW_MFP_CAPABLE; hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_WDS) | BIT(NL80211_IFTYPE_STATION) | diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index ae6c006bbc56..546b4e4ec5ea 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -291,7 +291,8 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) if (SUPP(CARL9170FW_WLANTX_CAB)) { ar->hw->wiphy->interface_modes |= - BIT(NL80211_IFTYPE_AP); + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_GO); } } diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index a314c2c2bfbe..dc7b30b170d0 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1631,7 +1631,8 @@ void *carl9170_alloc(size_t priv_size) * supports these modes. The code which will add the * additional interface_modes is in fw.c. */ - hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_P2P_CLIENT); hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_REPORTS_TX_ACK_STATUS | From 46047784b8cdcfc916f6c1cccee0c18dd1223dfd Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Fri, 26 Nov 2010 23:24:31 +0530 Subject: [PATCH 030/300] ath9k: Disable SWBA interrupt on remove_interface while removing beaconing mode interface, SWBA interrupt was never disabled when there are no other beaconing interfaces. Cc: stable@kernel.org Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 1cdbdbe33ab5..dace215b693e 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1519,6 +1519,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, struct ath_softc *sc = aphy->sc; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_vif *avp = (void *)vif->drv_priv; + bool bs_valid = false; int i; ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); @@ -1547,7 +1548,15 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, "slot\n", __func__); sc->beacon.bslot[i] = NULL; sc->beacon.bslot_aphy[i] = NULL; - } + } else if (sc->beacon.bslot[i]) + bs_valid = true; + } + if (!bs_valid && (sc->sc_ah->imask & ATH9K_INT_SWBA)) { + /* Disable SWBA interrupt */ + sc->sc_ah->imask &= ~ATH9K_INT_SWBA; + ath9k_ps_wakeup(sc); + ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); + ath9k_ps_restore(sc); } sc->nvifs--; From 7dff3125534c1d035a910052335a3a39fbb31aa7 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 26 Nov 2010 20:41:55 +0200 Subject: [PATCH 031/300] mac80211: Fix frame injection using non-AP vif In order for frame injection to work properly for some use cases (e.g., finding the station entry and keys for encryption), mac80211 needs to find the correct sdata entry. This works when the main vif is in AP mode, but commit a2c1e3dad516618cb0fbfb1a62c36d0b0744573a broke this particular use case for station main vif. While this type of injection is quite unusual operation, it has some uses and we should fix it. Do this by changing the monitor vif sdata selection to allow station vif to be selected instead of limiting it to just AP vifs. We still need to skip some iftypes to avoid selecting unsuitable vif for injection. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- net/mac80211/tx.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 96c594309506..df6aac523532 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1587,7 +1587,12 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, list) { if (!ieee80211_sdata_running(tmp_sdata)) continue; - if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) + if (tmp_sdata->vif.type == + NL80211_IFTYPE_MONITOR || + tmp_sdata->vif.type == + NL80211_IFTYPE_AP_VLAN || + tmp_sdata->vif.type == + NL80211_IFTYPE_WDS) continue; if (compare_ether_addr(tmp_sdata->vif.addr, hdr->addr2) == 0) { From 5c5e138b590a748c57d54b39634cda974ab9af1d Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 26 Nov 2010 23:29:23 +0100 Subject: [PATCH 032/300] carl9170: fix carl9170_tx_prepare typo commit: "carl9170: revamp carl9170_tx_prepare" introduced a peculiar bug that would only show up if the the module parameter noht is set to 1. Then all outbound voice, video and background frames would each invoke a (bogus) RTS/CTS handshake. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index b575c865142d..7e6506a77bbb 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -810,7 +810,7 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | AR9170_TX_MAC_BACKOFF); - mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) && + mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) & AR9170_TX_MAC_QOS); no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK); From 4249f8acf993046948dc1f2e74244fe484c8cb8f Mon Sep 17 00:00:00 2001 From: Yauhen Kharuzhy Date: Sun, 28 Nov 2010 20:30:19 +0200 Subject: [PATCH 033/300] ARM: SMDK2416: Select MACH_SMDK, S3C_DEV_NAND, S3C_DEV_USB_HOST Enable compilation of platform devices and initialization code used in SMDK2416 board file. Signed-off-by: Yauhen Kharuzhy Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2416/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig index 87b9c9f003bd..27b3e7c9d613 100644 --- a/arch/arm/mach-s3c2416/Kconfig +++ b/arch/arm/mach-s3c2416/Kconfig @@ -35,9 +35,12 @@ menu "S3C2416 Machines" config MACH_SMDK2416 bool "SMDK2416" select CPU_S3C2416 + select MACH_SMDK select S3C_DEV_FB select S3C_DEV_HSMMC select S3C_DEV_HSMMC1 + select S3C_DEV_NAND + select S3C_DEV_USB_HOST select S3C2416_PM if PM help Say Y here if you are using an SMDK2416 From 71f608ef56c987c5325c3aaf9c3fadd4ddc77f64 Mon Sep 17 00:00:00 2001 From: Yauhen Kharuzhy Date: Sun, 28 Nov 2010 20:30:23 +0200 Subject: [PATCH 034/300] ARM: S3C2443: Select properly ARM core type Select ARM920T core when compiling kernel for s3c2443. Signed-off-by: Yauhen Kharuzhy Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2443/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig index 4fef723126fa..31babec90cec 100644 --- a/arch/arm/mach-s3c2443/Kconfig +++ b/arch/arm/mach-s3c2443/Kconfig @@ -5,6 +5,7 @@ config CPU_S3C2443 bool depends on ARCH_S3C2410 + select CPU_ARM920T select S3C2443_DMA if S3C2410_DMA select CPU_LLSERIAL_S3C2440 select SAMSUNG_CLKSRC From 4acf89fb3bbb01ba9de4a7cc102e46095a12c94e Mon Sep 17 00:00:00 2001 From: Yauhen Kharuzhy Date: Sun, 28 Nov 2010 20:30:27 +0200 Subject: [PATCH 035/300] ARM: S3C2412: Fix typo in CONFIG_CPU_S3C2412_ONLY definition Dependency on (CPU_S3C2416 is not selected) was defined as "!CPU_2416", instead of "!CPU_S3C2416". Fix it. Signed-off-by: Yauhen Kharuzhy Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2412/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig index cef6a65637bd..fa2e5bffbb8e 100644 --- a/arch/arm/mach-s3c2412/Kconfig +++ b/arch/arm/mach-s3c2412/Kconfig @@ -16,7 +16,7 @@ config CPU_S3C2412 config CPU_S3C2412_ONLY bool depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \ - !CPU_2416 && !CPU_S3C2440 && !CPU_S3C2442 && \ + !CPU_S3C2416 && !CPU_S3C2440 && !CPU_S3C2442 && \ !CPU_S3C2443 && CPU_S3C2412 default y if CPU_S3C2412 From 1db550118c46d96f371de5b3d0bd51edb148bd54 Mon Sep 17 00:00:00 2001 From: Jason Chagas Date: Mon, 15 Nov 2010 09:50:12 +0800 Subject: [PATCH 036/300] ARM: mmp2: remove not used clk_rtc RTC clock will remain at 32KHz and powered on, there is no need for it at this moment. Signed-off-by: Jason Chagas Signed-off-by: Eric Miao --- arch/arm/mach-mmp/mmp2.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index daf3993349f8..2e3dd08ccc3f 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c @@ -126,7 +126,6 @@ static APBC_CLK(twsi3, MMP2_TWSI3, 0, 26000000); static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000); static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000); static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000); -static APBC_CLK(rtc, MMP2_RTC, 0, 32768); static APMU_CLK(nand, NAND, 0xbf, 100000000); From f9d1bf755315a66353a7f42319cff471b36fffb3 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 10 Oct 2010 00:34:28 +0200 Subject: [PATCH 037/300] ARM: pxa: fix pxa2xx-flash section mismatch Signed-off-by: Marek Vasut Acked-by: Haojian Zhuang Signed-off-by: Eric Miao --- drivers/mtd/maps/pxa2xx-flash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index dd90880048cf..d8ae634d347e 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c @@ -51,7 +51,7 @@ struct pxa2xx_flash_info { static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; -static int __init pxa2xx_flash_probe(struct platform_device *pdev) +static int __devinit pxa2xx_flash_probe(struct platform_device *pdev) { struct flash_platform_data *flash = pdev->dev.platform_data; struct pxa2xx_flash_info *info; From 9f1ee150fc7039eb65039ab17d9a95dfa6250133 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 6 Nov 2010 23:34:03 +0100 Subject: [PATCH 038/300] ARM: pxa/palm: fix ifdef around gen_nand driver registration Reported-by: Rafael Gandolfi Signed-off-by: Marek Vasut Signed-off-by: Eric Miao --- arch/arm/mach-pxa/palmtx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index d2060a1d1d68..e5c9932b7588 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c @@ -241,7 +241,8 @@ static inline void palmtx_keys_init(void) {} /****************************************************************************** * NAND Flash ******************************************************************************/ -#if defined(CONFIG_MTD_NAND_GPIO) || defined(CONFIG_MTD_NAND_GPIO_MODULE) +#if defined(CONFIG_MTD_NAND_PLATFORM) || \ + defined(CONFIG_MTD_NAND_PLATFORM_MODULE) static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) { From d9d318d39dd5cb686660504a3565aac453709ccc Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 30 Nov 2010 16:39:27 +0100 Subject: [PATCH 039/300] fuse: fix ioctl when server is 32bit If a 32bit CUSE server is run on 64bit this results in EIO being returned to the caller. The reason is that FUSE_IOCTL_RETRY reply was defined to use 'struct iovec', which is different on 32bit and 64bit archs. Work around this by looking at the size of the reply to determine which struct was used. This is only needed if CONFIG_COMPAT is defined. A more permanent fix for the interface will be to use the same struct on both 32bit and 64bit. Reported-by: "ccmail111" Signed-off-by: Miklos Szeredi CC: Tejun Heo CC: [2.6.31+] --- fs/fuse/file.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 9242d294fe90..0e2e25b114a6 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -13,6 +13,7 @@ #include #include #include +#include static const struct file_operations fuse_direct_io_file_operations; @@ -1627,6 +1628,44 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov, return 0; } +/* + * CUSE servers compiled on 32bit broke on 64bit kernels because the + * ABI was defined to be 'struct iovec' which is different on 32bit + * and 64bit. Fortunately we can determine which structure the server + * used from the size of the reply. + */ +static int fuse_copy_ioctl_iovec(struct iovec *dst, void *src, + size_t transferred, unsigned count, + bool is_compat) +{ +#ifdef CONFIG_COMPAT + if (count * sizeof(struct compat_iovec) == transferred) { + struct compat_iovec *ciov = src; + unsigned i; + + /* + * With this interface a 32bit server cannot support + * non-compat (i.e. ones coming from 64bit apps) ioctl + * requests + */ + if (!is_compat) + return -EINVAL; + + for (i = 0; i < count; i++) { + dst[i].iov_base = compat_ptr(ciov[i].iov_base); + dst[i].iov_len = ciov[i].iov_len; + } + return 0; + } +#endif + + if (count * sizeof(struct iovec) != transferred) + return -EIO; + + memcpy(dst, src, transferred); + return 0; +} + /* * For ioctls, there is no generic way to determine how much memory * needs to be read and/or written. Furthermore, ioctls are allowed @@ -1808,14 +1847,13 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV) goto out; - err = -EIO; - if ((in_iovs + out_iovs) * sizeof(struct iovec) != transferred) - goto out; - - /* okay, copy in iovs and retry */ vaddr = kmap_atomic(pages[0], KM_USER0); - memcpy(page_address(iov_page), vaddr, transferred); + err = fuse_copy_ioctl_iovec(page_address(iov_page), vaddr, + transferred, in_iovs + out_iovs, + (flags & FUSE_IOCTL_COMPAT) != 0); kunmap_atomic(vaddr, KM_USER0); + if (err) + goto out; in_iov = page_address(iov_page); out_iov = in_iov + in_iovs; From 7572777eef78ebdee1ecb7c258c0ef94d35bad16 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 30 Nov 2010 16:39:27 +0100 Subject: [PATCH 040/300] fuse: verify ioctl retries Verify that the total length of the iovec returned in FUSE_IOCTL_RETRY doesn't overflow iov_length(). Signed-off-by: Miklos Szeredi CC: Tejun Heo CC: [2.6.31+] --- fs/fuse/file.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 0e2e25b114a6..8b984a2cebbd 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1666,6 +1666,20 @@ static int fuse_copy_ioctl_iovec(struct iovec *dst, void *src, return 0; } +/* Make sure iov_length() won't overflow */ +static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count) +{ + size_t n; + u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT; + + for (n = 0; n < count; n++) { + if (iov->iov_len > (size_t) max) + return -ENOMEM; + max -= iov->iov_len; + } + return 0; +} + /* * For ioctls, there is no generic way to determine how much memory * needs to be read and/or written. Furthermore, ioctls are allowed @@ -1858,6 +1872,14 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, in_iov = page_address(iov_page); out_iov = in_iov + in_iovs; + err = fuse_verify_ioctl_iov(in_iov, in_iovs); + if (err) + goto out; + + err = fuse_verify_ioctl_iov(out_iov, out_iovs); + if (err) + goto out; + goto retry; } From 8a9533123f43f2cdb3eb601c17ff2ad336882eff Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 29 Nov 2010 12:44:15 -0200 Subject: [PATCH 041/300] perf symbols: Fix kallsyms kernel/module map splitting On ARM, module addresss space is ahead of kernel space, so the module symbols are handled before kernel symbol in dso__split_kallsyms, then was causing one map to be created for each kernel symbol. Reported-by: Ming Lei Tested-by: Ming Lei Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Ming Lei Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi LKML-Reference: <20101124144540.GB15875@ghostprotocols.net> Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 0500895a45af..2af4d7d22373 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -532,7 +532,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, struct machine *machine = kmaps->machine; struct map *curr_map = map; struct symbol *pos; - int count = 0; + int count = 0, moved = 0; struct rb_root *root = &self->symbols[map->type]; struct rb_node *next = rb_first(root); int kernel_range = 0; @@ -590,6 +590,11 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, char dso_name[PATH_MAX]; struct dso *dso; + if (count == 0) { + curr_map = map; + goto filter_symbol; + } + if (self->kernel == DSO_TYPE_GUEST_KERNEL) snprintf(dso_name, sizeof(dso_name), "[guest.kernel].%d", @@ -615,7 +620,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, map_groups__insert(kmaps, curr_map); ++kernel_range; } - +filter_symbol: if (filter && filter(curr_map, pos)) { discard_symbol: rb_erase(&pos->rb_node, root); symbol__delete(pos); @@ -623,8 +628,9 @@ discard_symbol: rb_erase(&pos->rb_node, root); if (curr_map != map) { rb_erase(&pos->rb_node, root); symbols__insert(&curr_map->dso->symbols[curr_map->type], pos); - } - count++; + ++moved; + } else + ++count; } } @@ -634,7 +640,7 @@ discard_symbol: rb_erase(&pos->rb_node, root); dso__set_loaded(curr_map->dso, curr_map->type); } - return count; + return count + moved; } int dso__load_kallsyms(struct dso *self, const char *filename, From d214afbd81405d4da2c5745fe867e6b313fd4178 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Thu, 25 Nov 2010 19:27:25 +0800 Subject: [PATCH 042/300] perf symbols: Figure out start address of kernel map from kallsyms On ARM, module symbol start address is ahead of kernel symbol start address, so we can't suppose that the start address of kernel map always is zero, otherwise may cause incorrect .start and .end of kernel map (caused by fixup) when there are modules loaded, then map_groups__find may return incorrect map for symbol query. This patch always figures out the start address of kernel map from /proc/kallsyms if the file is available, so fix the issues on ARM for module loaded case. This patch fixes the following issues on ARM when modules are loaded: - vmlinux symbol can't be found by kallsyms maps doing 'perf test' - module symbols are parsed mistakenlly when doing 'perf top'/'perf report' Cc: Ian Munsie Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Tom Zanussi LKML-Reference: <20101125192725.62d31b42@tom-lei> Signed-off-by: Ming Lei Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 43 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 2af4d7d22373..d628c8d1cf5e 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -2131,14 +2131,55 @@ static struct dso *machine__create_kernel(struct machine *self) return kernel; } +struct process_args { + u64 start; +}; + +static int symbol__in_kernel(void *arg, const char *name, + char type __used, u64 start) +{ + struct process_args *args = arg; + + if (strchr(name, '[')) + return 0; + + args->start = start; + return 1; +} + +/* Figure out the start address of kernel map from /proc/kallsyms */ +static u64 machine__get_kernel_start_addr(struct machine *machine) +{ + const char *filename; + char path[PATH_MAX]; + struct process_args args; + + if (machine__is_host(machine)) { + filename = "/proc/kallsyms"; + } else { + if (machine__is_default_guest(machine)) + filename = (char *)symbol_conf.default_guest_kallsyms; + else { + sprintf(path, "%s/proc/kallsyms", machine->root_dir); + filename = path; + } + } + + if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0) + return 0; + + return args.start; +} + int __machine__create_kernel_maps(struct machine *self, struct dso *kernel) { enum map_type type; + u64 start = machine__get_kernel_start_addr(self); for (type = 0; type < MAP__NR_TYPES; ++type) { struct kmap *kmap; - self->vmlinux_maps[type] = map__new2(0, kernel, type); + self->vmlinux_maps[type] = map__new2(start, kernel, type); if (self->vmlinux_maps[type] == NULL) return -1; From 60e677373be9c0bf7c9a22937601d5a40e51c042 Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Tue, 30 Nov 2010 12:50:14 +0100 Subject: [PATCH 043/300] perf header: Don't assume there's no attr info if no sample ids is provided This primarily fixes perf-report, which didn't report the correct type of event if perf-record was called to record one event different from 'cycles': $ perf record -e instructions true [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.007 MB perf.data (~295 samples) ] $ perf report | head -n1 # Events: 7 cycles LPU-Reference: Signed-off-by: Franck Bui-Huu --- tools/perf/util/header.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index d7e67b167ea3..64a85bafde63 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -946,11 +946,16 @@ perf_header__find_attr(u64 id, struct perf_header *header) /* * We set id to -1 if the data file doesn't contain sample - * ids. Check for this and avoid walking through the entire - * list of ids which may be large. + * ids. This can happen when the data file contains one type + * of event and in that case, the header can still store the + * event attribute information. Check for this and avoid + * walking through the entire list of ids which may be large. */ - if (id == -1ULL) + if (id == -1ULL) { + if (header->attrs > 0) + return &header->attr[0]->attr; return NULL; + } for (i = 0; i < header->attrs; i++) { struct perf_header_attr *attr = header->attr[i]; From cf63495d0dbe435b475a44672f5dee150da6471b Mon Sep 17 00:00:00 2001 From: David Kilroy Date: Wed, 24 Nov 2010 20:33:02 +0000 Subject: [PATCH 044/300] orinoco: abort scan on interface down This fixes the problem causing the following trace: ------------[ cut here ]------------ WARNING: at linux-2.6.34/net/wireless/core.c:633 wdev_cleanup_work+0xb7/0xe0 [cfg80211]() Hardware name: Latitude C840 Pid: 707, comm: cfg80211 Not tainted 2.6.34.7-0.5-desktop #1 Call Trace: [] try_stack_unwind+0x173/0x190 [] dump_trace+0x3f/0xe0 [] show_trace_log_lvl+0x4b/0x60 [] show_trace+0x18/0x20 [] dump_stack+0x6d/0x72 [] warn_slowpath_common+0x6e/0xb0 [] warn_slowpath_null+0x13/0x20 [] wdev_cleanup_work+0xb7/0xe0 [cfg80211] [] run_workqueue+0x79/0x170 [] worker_thread+0x83/0xe0 [] kthread+0x74/0x80 [] kernel_thread_helper+0x6/0x10 ---[ end trace 3f0348b3b0c6f4ff ]--- Reported by: Giacomo Comes Signed-off-by: David Kilroy Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/main.c | 12 +++++------- drivers/net/wireless/orinoco/scan.c | 8 ++++++++ drivers/net/wireless/orinoco/scan.h | 1 + 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index e8e2d0f4763d..fa0cf744958f 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c @@ -1392,10 +1392,9 @@ static void orinoco_process_scan_results(struct work_struct *work) orinoco_add_hostscan_results(priv, buf, len); kfree(buf); - } else if (priv->scan_request) { + } else { /* Either abort or complete the scan */ - cfg80211_scan_done(priv->scan_request, (len < 0)); - priv->scan_request = NULL; + orinoco_scan_done(priv, (len < 0)); } spin_lock_irqsave(&priv->scan_lock, flags); @@ -1684,6 +1683,8 @@ static int __orinoco_down(struct orinoco_private *priv) hermes_write_regn(hw, EVACK, 0xffff); } + orinoco_scan_done(priv, true); + /* firmware will have to reassociate */ netif_carrier_off(dev); priv->last_linkstatus = 0xffff; @@ -1762,10 +1763,7 @@ void orinoco_reset(struct work_struct *work) orinoco_unlock(priv, &flags); /* Scanning support: Notify scan cancellation */ - if (priv->scan_request) { - cfg80211_scan_done(priv->scan_request, 1); - priv->scan_request = NULL; - } + orinoco_scan_done(priv, true); if (priv->hard_reset) { err = (*priv->hard_reset)(priv); diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c index 4300d9db7d8c..86cb54c842e7 100644 --- a/drivers/net/wireless/orinoco/scan.c +++ b/drivers/net/wireless/orinoco/scan.c @@ -229,3 +229,11 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv, priv->scan_request = NULL; } } + +void orinoco_scan_done(struct orinoco_private *priv, bool abort) +{ + if (priv->scan_request) { + cfg80211_scan_done(priv->scan_request, abort); + priv->scan_request = NULL; + } +} diff --git a/drivers/net/wireless/orinoco/scan.h b/drivers/net/wireless/orinoco/scan.h index 2dc4e046dbdb..27281fb0a6dc 100644 --- a/drivers/net/wireless/orinoco/scan.h +++ b/drivers/net/wireless/orinoco/scan.h @@ -16,5 +16,6 @@ void orinoco_add_extscan_result(struct orinoco_private *priv, void orinoco_add_hostscan_results(struct orinoco_private *dev, unsigned char *buf, size_t len); +void orinoco_scan_done(struct orinoco_private *priv, bool abort); #endif /* _ORINOCO_SCAN_H_ */ From 2c31333a8fde7e26936a9f5371d02ff12c490993 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 29 Nov 2010 20:53:23 +0100 Subject: [PATCH 045/300] mac80211: ignore non-bcast mcast deauth/disassoc franes This patch fixes an curious issue due to insufficient rx frame filtering. Saqeb Akhter reported frequent disconnects while streaming videos over samba: > [ 1166.512087] wlan1: deauthenticated from 30:46:9a:10:49:f7 (Reason: 7) > [ 1526.059997] wlan1: deauthenticated from 30:46:9a:10:49:f7 (Reason: 7) > [ 2125.324356] wlan1: deauthenticated from 30:46:9a:10:49:f7 (Reason: 7) > [...] The reason is that the device generates frames with slightly bogus SA/TA addresses. e.g.: [ 2314.402316] Ignore 9f:1f:31:f8:64:ff [ 2314.402321] Ignore 9f:1f:31:f8:64:ff [ 2352.453804] Ignore 0d:1f:31:f8:64:ff [ 2352.453808] Ignore 0d:1f:31:f8:64:ff ^^ the group-address flag is set! (the correct SA/TA would be: 00:1f:31:f8:64:ff) Since the AP does not know from where the frames come, it generates a DEAUTH response for the (invalid) mcast address. This mcast deauth frame then passes through all filters and tricks the stack into thinking that the AP brutally kicked us! This patch fixes the problem by simply ignoring non-broadcast, group-addressed deauth/disassoc frames. Cc: Jouni Malinen Cc: Johannes Berg Reported-by: Saqeb Akhter Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- net/mac80211/rx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 902b03ee8f60..3c87293cb078 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2247,6 +2247,10 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) break; case cpu_to_le16(IEEE80211_STYPE_DEAUTH): case cpu_to_le16(IEEE80211_STYPE_DISASSOC): + if (is_multicast_ether_addr(mgmt->da) && + !is_broadcast_ether_addr(mgmt->da)) + return RX_DROP_MONITOR; + /* process only for station */ if (sdata->vif.type != NL80211_IFTYPE_STATION) return RX_DROP_MONITOR; From 8e26d5ad2f9c038609d42eebc676cd1107709eef Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Tue, 30 Nov 2010 20:15:38 +0530 Subject: [PATCH 046/300] mac80211: Fix STA disconnect due to MIC failure Th commit titled "mac80211: clean up rx handling wrt. found_sta" removed found_sta variable which caused a MIC failure event to be reported twice for a single failure to supplicant resulted in STA disconnect. This should fix WPA specific countermeasures WiFi test case (5.2.17) issues with mac80211 based drivers which report MIC failure events in rx status. Cc: Stable (2.6.37) Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- net/mac80211/rx.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 3c87293cb078..54fb4a0e76f0 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2745,6 +2745,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) return; + goto out; } } @@ -2784,6 +2785,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, return; } + out: dev_kfree_skb(skb); } From 916448e77f6bcaaa7f13c3de0c3851783ae2bfd0 Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Tue, 30 Nov 2010 20:15:39 +0530 Subject: [PATCH 047/300] ath9k: Fix STA disconnect issue due to received MIC failed bcast frames AR_RxKeyIdxValid will not be set for bcast/mcast frames and so relying this status for MIC failed frames is buggy. Due to this, MIC failure events for broadcast frames are not sent to supplicant resulted in AP disconnecting the STA. Able to pass Wifi Test case 5.2.18 with this fix. Cc: Stable (2.6.36+) Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mac.c | 3 +-- drivers/net/wireless/ath/ath9k/recv.c | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 8c13479b17cd..c996963ab339 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -703,8 +703,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, rs->rs_phyerr = phyerr; } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) rs->rs_status |= ATH9K_RXERR_DECRYPT; - else if ((ads.ds_rxstatus8 & AR_MichaelErr) && - rs->rs_keyix != ATH9K_RXKEYIX_INVALID) + else if (ads.ds_rxstatus8 & AR_MichaelErr) rs->rs_status |= ATH9K_RXERR_MIC; else if (ads.ds_rxstatus8 & AR_KeyMiss) rs->rs_status |= ATH9K_RXERR_DECRYPT; diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 1a62e351ec77..14d479f8d8ac 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -1049,9 +1049,11 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, int hdrlen, padpos, padsize; u8 keyix; __le16 fc; + bool is_mc; /* see if any padding is done by the hw and remove it */ hdr = (struct ieee80211_hdr *) skb->data; + is_mc = !!is_multicast_ether_addr(hdr->addr1); hdrlen = ieee80211_get_hdrlen_from_skb(skb); fc = hdr->frame_control; padpos = ath9k_cmn_padpos(hdr->frame_control); @@ -1072,7 +1074,7 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, keyix = rx_stats->rs_keyix; - if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error && + if ((is_mc || !(keyix == ATH9K_RXKEYIX_INVALID)) && !decrypt_error && ieee80211_has_protected(fc)) { rxs->flag |= RX_FLAG_DECRYPTED; } else if (ieee80211_has_protected(fc) From e62cac1fd035b4cde707285008499dbe71955a86 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 30 Nov 2010 14:33:29 -0800 Subject: [PATCH 048/300] sparc: Pass buffer pointer all the way down to prom_{get,put}char(). This gets us closer to being able to eliminate the use of dynamic and stack based buffers, so that we can adhere to the "no buffer addresses above 4GB" rule for PROM calls. Signed-off-by: David S. Miller --- arch/sparc/include/asm/openprom.h | 2 +- arch/sparc/include/asm/oplib_32.h | 4 +-- arch/sparc/include/asm/oplib_64.h | 4 +-- arch/sparc/prom/console_32.c | 50 +++++++++++++++---------------- arch/sparc/prom/console_64.c | 34 ++++++++++----------- arch/sparc/prom/printf.c | 15 +++++----- 6 files changed, 55 insertions(+), 54 deletions(-) diff --git a/arch/sparc/include/asm/openprom.h b/arch/sparc/include/asm/openprom.h index 81cd43432dc0..47eaafad15ce 100644 --- a/arch/sparc/include/asm/openprom.h +++ b/arch/sparc/include/asm/openprom.h @@ -39,7 +39,7 @@ struct linux_dev_v2_funcs { int (*v2_dev_open)(char *devpath); void (*v2_dev_close)(int d); int (*v2_dev_read)(int d, char *buf, int nbytes); - int (*v2_dev_write)(int d, char *buf, int nbytes); + int (*v2_dev_write)(int d, const char *buf, int nbytes); int (*v2_dev_seek)(int d, int hi, int lo); /* Never issued (multistage load support) */ diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index 49fe4266f86a..4c2539243e46 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h @@ -105,10 +105,10 @@ extern int prom_getprev(void); /* Character operations to/from the console.... */ /* Blocking get character from console. */ -extern char prom_getchar(void); +extern void prom_getchar(char *buf); /* Blocking put character to console. */ -extern void prom_putchar(char character); +extern void prom_putchar(const char *buf); /* Prom's internal routines, don't use in kernel/boot code. */ extern void prom_printf(const char *fmt, ...); diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index d541de4b6844..384e558a6a3c 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h @@ -97,10 +97,10 @@ extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); /* Character operations to/from the console.... */ /* Blocking get character from console. */ -extern char prom_getchar(void); +extern void prom_getchar(char *buf); /* Blocking put character to console. */ -extern void prom_putchar(char character); +extern void prom_putchar(const char *buf); /* Prom's internal routines, don't use in kernel/boot code. */ extern void prom_printf(const char *fmt, ...); diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c index 2ce5acb45f2d..69c16bbf1f48 100644 --- a/arch/sparc/prom/console_32.c +++ b/arch/sparc/prom/console_32.c @@ -19,27 +19,27 @@ extern void restore_current(void); /* Non blocking get character from console input device, returns -1 * if no input was taken. This can be used for polling. */ -static int prom_nbgetchar(void) +static int prom_nbgetchar(char *buf) { - static char inc; - int i = -1; unsigned long flags; + int i = -1; spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: i = (*(romvec->pv_nbgetchar))(); + if (i != -1) { + *buf = i; + i = 0; + } break; case PROM_V2: case PROM_V3: - if( (*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin , &inc, 0x1) == 1) { - i = inc; - } else { - i = -1; - } + if ((*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin, + buf, 0x1) == 1) + i = 0; break; default: - i = -1; break; }; restore_current(); @@ -50,27 +50,23 @@ static int prom_nbgetchar(void) /* Non blocking put character to console device, returns -1 if * unsuccessful. */ -static int prom_nbputchar(char c) +static int prom_nbputchar(const char *buf) { - static char outc; unsigned long flags; int i = -1; spin_lock_irqsave(&prom_lock, flags); switch(prom_vers) { case PROM_V0: - i = (*(romvec->pv_nbputchar))(c); + i = (*(romvec->pv_nbputchar))(*buf); break; case PROM_V2: case PROM_V3: - outc = c; - if( (*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, &outc, 0x1) == 1) + if ((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, + buf, 0x1) == 1) i = 0; - else - i = -1; break; default: - i = -1; break; }; restore_current(); @@ -79,17 +75,21 @@ static int prom_nbputchar(char c) } /* Blocking version of get character routine above. */ -char -prom_getchar(void) +void prom_getchar(char *buf) { - int character; - while((character = prom_nbgetchar()) == -1) ; - return (char) character; + while (1) { + int err = prom_nbgetchar(buf); + if (!err) + break; + } } /* Blocking version of put character routine above. */ -void -prom_putchar(char c) +void prom_putchar(const char *buf) { - while(prom_nbputchar(c) == -1) ; + while (1) { + int err = prom_nbputchar(buf); + if (!err) + break; + } } diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index 33a8b275d6af..a9a575433ce9 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c @@ -18,41 +18,37 @@ extern int prom_stdin, prom_stdout; /* Non blocking get character from console input device, returns -1 * if no input was taken. This can be used for polling. */ -static int prom_nbgetchar(void) +static int prom_nbgetchar(char *buf) { unsigned long args[7]; - char inc; args[0] = (unsigned long) "read"; args[1] = 3; args[2] = 1; args[3] = (unsigned int) prom_stdin; - args[4] = (unsigned long) &inc; + args[4] = (unsigned long) buf; args[5] = 1; args[6] = (unsigned long) -1; p1275_cmd_direct(args); if (args[6] == 1) - return inc; + return 0; return -1; } /* Non blocking put character to console device, returns -1 if * unsuccessful. */ -static int prom_nbputchar(char c) +static int prom_nbputchar(const char *buf) { unsigned long args[7]; - char outc; - - outc = c; args[0] = (unsigned long) "write"; args[1] = 3; args[2] = 1; args[3] = (unsigned int) prom_stdout; - args[4] = (unsigned long) &outc; + args[4] = (unsigned long) buf; args[5] = 1; args[6] = (unsigned long) -1; @@ -65,17 +61,21 @@ static int prom_nbputchar(char c) } /* Blocking version of get character routine above. */ -char -prom_getchar(void) +void prom_getchar(char *buf) { - int character; - while((character = prom_nbgetchar()) == -1) ; - return (char) character; + while (1) { + int err = prom_nbgetchar(buf); + if (!err) + break; + } } /* Blocking version of put character routine above. */ -void -prom_putchar(char c) +void prom_putchar(const char *buf) { - prom_nbputchar(c); + while (1) { + int err = prom_nbputchar(buf); + if (!err) + break; + } } diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c index ca869266b9f3..24031971f806 100644 --- a/arch/sparc/prom/printf.c +++ b/arch/sparc/prom/printf.c @@ -23,13 +23,14 @@ static char ppbuf[1024]; void notrace prom_write(const char *buf, unsigned int n) { - char ch; - - while (n != 0) { - --n; - if ((ch = *buf++) == '\n') - prom_putchar('\r'); - prom_putchar(ch); + while (n-- != 0) { + char ch = *buf; + if (ch == '\n') { + char tmp = '\r'; + prom_putchar(&tmp); + } + prom_putchar(buf); + buf++; } } From 12c7a35ee6a1c605e740733f2cbd5b5079f09f0f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 30 Nov 2010 14:53:05 -0800 Subject: [PATCH 049/300] sparc: Delete prom_*getchar(). Completely unused. Signed-off-by: David S. Miller --- arch/sparc/include/asm/oplib_32.h | 5 ---- arch/sparc/include/asm/oplib_64.h | 5 ---- arch/sparc/prom/console_32.c | 41 ------------------------------- arch/sparc/prom/console_64.c | 32 ------------------------ 4 files changed, 83 deletions(-) diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index 4c2539243e46..40bc9efb1ac4 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h @@ -102,11 +102,6 @@ extern int prom_getrev(void); /* Get the prom firmware revision. */ extern int prom_getprev(void); -/* Character operations to/from the console.... */ - -/* Blocking get character from console. */ -extern void prom_getchar(char *buf); - /* Blocking put character to console. */ extern void prom_putchar(const char *buf); diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index 384e558a6a3c..d4613738c537 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h @@ -94,11 +94,6 @@ extern void prom_halt_power_off(void) __attribute__ ((noreturn)); */ extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); -/* Character operations to/from the console.... */ - -/* Blocking get character from console. */ -extern void prom_getchar(char *buf); - /* Blocking put character to console. */ extern void prom_putchar(const char *buf); diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c index 69c16bbf1f48..157019e29fd4 100644 --- a/arch/sparc/prom/console_32.c +++ b/arch/sparc/prom/console_32.c @@ -16,37 +16,6 @@ extern void restore_current(void); -/* Non blocking get character from console input device, returns -1 - * if no input was taken. This can be used for polling. - */ -static int prom_nbgetchar(char *buf) -{ - unsigned long flags; - int i = -1; - - spin_lock_irqsave(&prom_lock, flags); - switch(prom_vers) { - case PROM_V0: - i = (*(romvec->pv_nbgetchar))(); - if (i != -1) { - *buf = i; - i = 0; - } - break; - case PROM_V2: - case PROM_V3: - if ((*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin, - buf, 0x1) == 1) - i = 0; - break; - default: - break; - }; - restore_current(); - spin_unlock_irqrestore(&prom_lock, flags); - return i; /* Ugh, we could spin forever on unsupported proms ;( */ -} - /* Non blocking put character to console device, returns -1 if * unsuccessful. */ @@ -74,16 +43,6 @@ static int prom_nbputchar(const char *buf) return i; /* Ugh, we could spin forever on unsupported proms ;( */ } -/* Blocking version of get character routine above. */ -void prom_getchar(char *buf) -{ - while (1) { - int err = prom_nbgetchar(buf); - if (!err) - break; - } -} - /* Blocking version of put character routine above. */ void prom_putchar(const char *buf) { diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index a9a575433ce9..0da88d10beff 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c @@ -15,28 +15,6 @@ extern int prom_stdin, prom_stdout; -/* Non blocking get character from console input device, returns -1 - * if no input was taken. This can be used for polling. - */ -static int prom_nbgetchar(char *buf) -{ - unsigned long args[7]; - - args[0] = (unsigned long) "read"; - args[1] = 3; - args[2] = 1; - args[3] = (unsigned int) prom_stdin; - args[4] = (unsigned long) buf; - args[5] = 1; - args[6] = (unsigned long) -1; - - p1275_cmd_direct(args); - - if (args[6] == 1) - return 0; - return -1; -} - /* Non blocking put character to console device, returns -1 if * unsuccessful. */ @@ -60,16 +38,6 @@ static int prom_nbputchar(const char *buf) return -1; } -/* Blocking version of get character routine above. */ -void prom_getchar(char *buf) -{ - while (1) { - int err = prom_nbgetchar(buf); - if (!err) - break; - } -} - /* Blocking version of put character routine above. */ void prom_putchar(const char *buf) { From 595a251c0740785fd3c0d2156d78578c7479811e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 30 Nov 2010 20:15:58 -0800 Subject: [PATCH 050/300] sparc: Write to prom console using indirect buffer. sparc64 systems have a restriction in that passing in buffer addressses above 4GB to prom calls is not reliable. We end up violating this when we do prom console writes, because we use an on-stack buffer to translate '\n' into '\r\n'. So instead, do this translation into an intermediate buffer, which is in the kernel image and thus below 4GB, then pass that to the PROM console write calls. On the 32-bit side we don't have to deal with any of these issues, so the new prom_console_write_buf() uses the existing prom_nbputchar() implementation. However we can now mark those routines static. Since the 64-bit side completely uses new code we can delete the putchar bits as they are now completely unused. Signed-off-by: David S. Miller --- arch/sparc/include/asm/oplib_32.h | 4 ++-- arch/sparc/include/asm/oplib_64.h | 4 ++-- arch/sparc/prom/console_32.c | 14 ++++++++------ arch/sparc/prom/console_64.c | 27 +++++++++++++------------- arch/sparc/prom/printf.c | 32 ++++++++++++++++++++++++++----- 5 files changed, 52 insertions(+), 29 deletions(-) diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index 40bc9efb1ac4..9e5c64084b86 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h @@ -102,8 +102,8 @@ extern int prom_getrev(void); /* Get the prom firmware revision. */ extern int prom_getprev(void); -/* Blocking put character to console. */ -extern void prom_putchar(const char *buf); +/* Write a buffer of characters to the console. */ +extern void prom_console_write_buf(const char *buf, int len); /* Prom's internal routines, don't use in kernel/boot code. */ extern void prom_printf(const char *fmt, ...); diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index d4613738c537..8cd0df34e82b 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h @@ -94,8 +94,8 @@ extern void prom_halt_power_off(void) __attribute__ ((noreturn)); */ extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); -/* Blocking put character to console. */ -extern void prom_putchar(const char *buf); +/* Write a buffer of characters to the console. */ +extern void prom_console_write_buf(const char *buf, int len); /* Prom's internal routines, don't use in kernel/boot code. */ extern void prom_printf(const char *fmt, ...); diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c index 157019e29fd4..48863108a44c 100644 --- a/arch/sparc/prom/console_32.c +++ b/arch/sparc/prom/console_32.c @@ -43,12 +43,14 @@ static int prom_nbputchar(const char *buf) return i; /* Ugh, we could spin forever on unsupported proms ;( */ } -/* Blocking version of put character routine above. */ -void prom_putchar(const char *buf) +void prom_console_write_buf(const char *buf, int len) { - while (1) { - int err = prom_nbputchar(buf); - if (!err) - break; + while (len) { + int n = prom_nbputchar(buf); + if (n) + continue; + len--; + buf++; } } + diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index 0da88d10beff..ed39e75828bd 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c @@ -15,35 +15,34 @@ extern int prom_stdin, prom_stdout; -/* Non blocking put character to console device, returns -1 if - * unsuccessful. - */ -static int prom_nbputchar(const char *buf) +static int __prom_console_write_buf(const char *buf, int len) { unsigned long args[7]; + int ret; args[0] = (unsigned long) "write"; args[1] = 3; args[2] = 1; args[3] = (unsigned int) prom_stdout; args[4] = (unsigned long) buf; - args[5] = 1; + args[5] = (unsigned int) len; args[6] = (unsigned long) -1; p1275_cmd_direct(args); - if (args[6] == 1) - return 0; - else + ret = (int) args[6]; + if (ret < 0) return -1; + return ret; } -/* Blocking version of put character routine above. */ -void prom_putchar(const char *buf) +void prom_console_write_buf(const char *buf, int len) { - while (1) { - int err = prom_nbputchar(buf); - if (!err) - break; + while (len) { + int n = __prom_console_write_buf(buf, len); + if (n < 0) + continue; + len -= n; + buf += len; } } diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c index 24031971f806..d9682f06b3b0 100644 --- a/arch/sparc/prom/printf.c +++ b/arch/sparc/prom/printf.c @@ -15,23 +15,45 @@ #include #include +#include #include #include +#define CONSOLE_WRITE_BUF_SIZE 1024 + static char ppbuf[1024]; +static char console_write_buf[CONSOLE_WRITE_BUF_SIZE]; +static DEFINE_RAW_SPINLOCK(console_write_lock); void notrace prom_write(const char *buf, unsigned int n) { + unsigned int dest_len; + unsigned long flags; + char *dest; + + dest = console_write_buf; + raw_spin_lock_irqsave(&console_write_lock, flags); + + dest_len = 0; while (n-- != 0) { - char ch = *buf; + char ch = *buf++; if (ch == '\n') { - char tmp = '\r'; - prom_putchar(&tmp); + *dest++ = '\r'; + dest_len++; + } + *dest++ = ch; + dest_len++; + if (dest_len >= CONSOLE_WRITE_BUF_SIZE - 1) { + prom_console_write_buf(console_write_buf, dest_len); + dest = console_write_buf; + dest_len = 0; } - prom_putchar(buf); - buf++; } + if (dest_len) + prom_console_write_buf(console_write_buf, dest_len); + + raw_spin_unlock_irqrestore(&console_write_lock, flags); } void notrace prom_printf(const char *fmt, ...) From 0417596f66dd6621f4fd46563c7c56a95311dbe8 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 29 Nov 2010 23:33:05 -0800 Subject: [PATCH 051/300] Input: add keycodes for touchpad on/off keys Some laptops will have a "touchpad toggle" soft button, which expects user-space to turn off the touchpad themselves, some other devices will do this in hardware, but send key events telling us that the touchpad has been turned off/on. KEY_TOUCHPAD_ON/KEY_TOUCHPAD_OFF will be used by user-space to show a popup with the status of the touchpad. Signed-off-by: Bastien Nocera Signed-off-by: Dmitry Torokhov --- include/linux/input.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/input.h b/include/linux/input.h index 6ef44465db8d..a50046f15372 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -624,6 +624,10 @@ struct input_keymap_entry { #define KEY_CAMERA_FOCUS 0x210 #define KEY_WPS_BUTTON 0x211 /* WiFi Protected Setup key */ +#define KEY_TOUCHPAD_TOGGLE 0x212 /* Request switch touchpad on or off */ +#define KEY_TOUCHPAD_ON 0x213 +#define KEY_TOUCHPAD_OFF 0x214 + #define BTN_TRIGGER_HAPPY 0x2c0 #define BTN_TRIGGER_HAPPY1 0x2c0 #define BTN_TRIGGER_HAPPY2 0x2c1 From 86b17f76f462db460d6d916e105a4c44cb353e36 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 29 Nov 2010 23:33:04 -0800 Subject: [PATCH 052/300] Input: document struct input_absinfo Add documentation for struct input_absinfo that is used in EVIOCGABS and EVIOCSABS ioctl and specify units of measure used for reporting resolution for an axis. Acked-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- include/linux/input.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/include/linux/input.h b/include/linux/input.h index a50046f15372..a8af21d42bc1 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -47,6 +47,25 @@ struct input_id { __u16 version; }; +/** + * struct input_absinfo - used by EVIOCGABS/EVIOCSABS ioctls + * @value: latest reported value for the axis. + * @minimum: specifies minimum value for the axis. + * @maximum: specifies maximum value for the axis. + * @fuzz: specifies fuzz value that is used to filter noise from + * the event stream. + * @flat: values that are within this value will be discarded by + * joydev interface and reported as 0 instead. + * @resolution: specifies resolution for the values reported for + * the axis. + * + * Note that input core does not clamp reported values to the + * [minimum, maximum] limits, such task is left to userspace. + * + * Resolution for main axes (ABS_X, ABS_Y, ABS_Z) is reported in + * units per millimeter (units/mm), resolution for rotational axes + * (ABS_RX, ABS_RY, ABS_RZ) is reported in units per radian. + */ struct input_absinfo { __s32 value; __s32 minimum; @@ -1134,7 +1153,7 @@ struct input_mt_slot { * of tracked contacts * @mtsize: number of MT slots the device uses * @slot: MT slot currently being transmitted - * @absinfo: array of &struct absinfo elements holding information + * @absinfo: array of &struct input_absinfo elements holding information * about absolute axes (current value, min, max, flat, fuzz, * resolution) * @key: reflects current state of device's keys/buttons From 25c9170ed64a6551beefe9315882f754e14486f4 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Tue, 30 Nov 2010 17:36:08 +0900 Subject: [PATCH 053/300] genirq: Fix incorrect proc spurious output Since commit a1afb637(switch /proc/irq/*/spurious to seq_file) all /proc/irq/XX/spurious files show the information of irq 0. Current irq_spurious_proc_open() passes on NULL as the 3rd argument, which is used as an IRQ number in irq_spurious_proc_show(), to the single_open(). Because of this, all the /proc/irq/XX/spurious file shows IRQ 0 information regardless of the IRQ number. To fix the problem, irq_spurious_proc_open() must pass on the appropreate data (IRQ number) to single_open(). Signed-off-by: Kenji Kaneshige Reviewed-by: Yong Zhang LKML-Reference: <4CF4B778.90604@jp.fujitsu.com> Cc: stable@kernel.org [2.6.33+] Signed-off-by: Thomas Gleixner --- kernel/irq/proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index 01b1d3a88983..6c8a2a9f8a7b 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c @@ -214,7 +214,7 @@ static int irq_spurious_proc_show(struct seq_file *m, void *v) static int irq_spurious_proc_open(struct inode *inode, struct file *file) { - return single_open(file, irq_spurious_proc_show, NULL); + return single_open(file, irq_spurious_proc_show, PDE(inode)->data); } static const struct file_operations irq_spurious_proc_fops = { From a318e6b1a04c9d8882712508eb9c8a061796c06b Mon Sep 17 00:00:00 2001 From: David Foley Date: Tue, 30 Nov 2010 23:45:46 -0800 Subject: [PATCH 054/300] Input: wacom - add IDs for two new Bamboo PTs Add two new Bamboo Pen & Touch models: Bamboo Comic Medium (CTH661/S1; Product ID = 0xd8) Bamboo P & T Special Edition Small (CTH461/L; Product ID = 0xdA) Tested-by: IRIE Shinsuke Tested-by: Andrea Cadeddu Signed-off-by: David Foley Reviewed-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index b3252ef1e279..db747e4c4c4c 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1436,6 +1436,10 @@ static struct wacom_features wacom_features_0xD2 = { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; static struct wacom_features wacom_features_0xD3 = { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; +static struct wacom_features wacom_features_0xD8 = + { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; +static struct wacom_features wacom_features_0xDA = + { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; #define USB_DEVICE_WACOM(prod) \ USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ @@ -1504,6 +1508,8 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0xD1) }, { USB_DEVICE_WACOM(0xD2) }, { USB_DEVICE_WACOM(0xD3) }, + { USB_DEVICE_WACOM(0xD8) }, + { USB_DEVICE_WACOM(0xDA) }, { USB_DEVICE_WACOM(0xF0) }, { USB_DEVICE_WACOM(0xCC) }, { USB_DEVICE_WACOM(0x90) }, From 3bfa321e662edf90fb8123a02c987c2965fa50bb Mon Sep 17 00:00:00 2001 From: Yan Li Date: Tue, 30 Nov 2010 23:51:03 -0800 Subject: [PATCH 055/300] Input: synaptics - fix handling of 2-button ClickPads Lenovo S10-3t's ClickPad is a 2-button ClickPad that reports BTN_LEFT and BTN_RIGHT as normal touchpad, unlike the 1-button ClickPad used in HP mini 210 that reports solely BTN_MIDDLE. In 0xc0-cap response, the 1-button ClickPad has the 20-bit set while 2-button ClickPad has the 8-bit set. This patch makes the kernel only handle 1-button ClickPad specially, and treat 2-button ClickPad in the same fashion as regular touchpads. This fixes kernel bug #18122 and MeeGo bug #4807. Signed-off-by: Yan Li Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 613a3652f98f..0aefaa885871 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -51,7 +51,8 @@ #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) #define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) -#define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100100) +#define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ +#define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) /* synaptics modes query bits */ From 398812159e328478ae49b4bd01f0d71efea96c39 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 1 Dec 2010 10:08:01 +0100 Subject: [PATCH 056/300] [S390] nohz/s390: fix arch_needs_cpu() return value on offline cpus This fixes the same problem as described in the patch "nohz: fix printk_needs_cpu() return value on offline cpus" for the arch_needs_cpu() primitive: arch_needs_cpu() may return 1 if called on offline cpus. When a cpu gets offlined it schedules the idle process which, before killing its own cpu, will call tick_nohz_stop_sched_tick(). That function in turn will call arch_needs_cpu() in order to check if the local tick can be disabled. On offline cpus this function should naturally return 0 since regardless if the tick gets disabled or not the cpu will be dead short after. That is besides the fact that __cpu_disable() should already have made sure that no interrupts on the offlined cpu will be delivered anyway. In this case it prevents tick_nohz_stop_sched_tick() to call select_nohz_load_balancer(). No idea if that really is a problem. However what made me debug this is that on 2.6.32 the function get_nohz_load_balancer() is used within __mod_timer() to select a cpu on which a timer gets enqueued. If arch_needs_cpu() returns 1 then the nohz_load_balancer cpu doesn't get updated when a cpu gets offlined. It may contain the cpu number of an offline cpu. In turn timers get enqueued on an offline cpu and not very surprisingly they never expire and cause system hangs. This has been observed 2.6.32 kernels. On current kernels __mod_timer() uses get_nohz_timer_target() which doesn't have that problem. However there might be other problems because of the too early exit tick_nohz_stop_sched_tick() in case a cpu goes offline. This specific bug was indrocuded with 3c5d92a0 "nohz: Introduce arch_needs_cpu". In this case a cpu hotplug notifier is used to fix the issue in order to keep the normal/fast path small. All we need to do is to clear the condition that makes arch_needs_cpu() return 1 since it is just a performance improvement which is supposed to keep the local tick running for a short period if a cpu goes idle. Nothing special needs to be done except for clearing the condition. Cc: stable@kernel.org Acked-by: Peter Zijlstra Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/vtime.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 56c8687b29b3..7eff9b7347c0 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -566,6 +567,23 @@ void init_cpu_vtimer(void) __ctl_set_bit(0,10); } +static int __cpuinit s390_nohz_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + struct s390_idle_data *idle; + long cpu = (long) hcpu; + + idle = &per_cpu(s390_idle, cpu); + switch (action) { + case CPU_DYING: + case CPU_DYING_FROZEN: + idle->nohz_delay = 0; + default: + break; + } + return NOTIFY_OK; +} + void __init vtime_init(void) { /* request the cpu timer external interrupt */ @@ -574,5 +592,6 @@ void __init vtime_init(void) /* Enable cpu timer interrupts on the boot cpu. */ init_cpu_vtimer(); + cpu_notifier(s390_nohz_notify, 0); } From 8d7bfb4a891d606d52e1a99cf7231b4417b935dc Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Wed, 1 Dec 2010 10:08:02 +0100 Subject: [PATCH 057/300] [S390] css: fix rsid evaluation for 2nd crw Use correct bit positions of rsid field. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/css.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index a5050e217150..825951b6b83f 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -635,7 +635,7 @@ static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow) init_subchannel_id(&mchk_schid); mchk_schid.sch_no = crw0->rsid; if (crw1) - mchk_schid.ssid = (crw1->rsid >> 8) & 3; + mchk_schid.ssid = (crw1->rsid >> 4) & 3; /* * Since we are always presented with IPI in the CRW, we have to From 0aded708d125a3ff7e5abaea9c2d9c6d7ebbfdcd Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 30 Nov 2010 21:56:32 -0500 Subject: [PATCH 058/300] NFS: Ensure we use the correct cookie in nfs_readdir_xdr_filler We need to use the cookie from the previous array entry, not the actual cookie that we are searching for (except for the case of uncached_readdir). Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index f0a384e2ae63..e03537ff9350 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -178,6 +178,7 @@ typedef struct { struct page *page; unsigned long page_index; u64 *dir_cookie; + u64 last_cookie; loff_t current_index; decode_dirent_t decode; @@ -344,6 +345,8 @@ int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc) else status = nfs_readdir_search_for_cookie(array, desc); + if (status == -EAGAIN) + desc->last_cookie = array->last_cookie; nfs_readdir_release_array(desc->page); out: return status; @@ -563,7 +566,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, unsigned int array_size = ARRAY_SIZE(pages); entry.prev_cookie = 0; - entry.cookie = *desc->dir_cookie; + entry.cookie = desc->last_cookie; entry.eof = 0; entry.fh = nfs_alloc_fhandle(); entry.fattr = nfs_alloc_fattr(); @@ -672,8 +675,10 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc) { int res; - if (desc->page_index == 0) + if (desc->page_index == 0) { desc->current_index = 0; + desc->last_cookie = 0; + } while (1) { res = find_cache_page(desc); if (res != -EAGAIN) @@ -764,6 +769,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, } desc->page_index = 0; + desc->last_cookie = *desc->dir_cookie; desc->page = page; status = nfs_readdir_xdr_to_array(desc, page, inode); From 8ed9e0e1b602a0bcdc3bef52ec05fdab5b484341 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 1 Dec 2010 09:19:45 -0800 Subject: [PATCH 059/300] Input: turbografx - fix reference counting The ref-count of parport gained from parport_find_number() was not released in normal path. Signed-off-by: Namhyung Kim Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/turbografx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index d53b9e900234..27b6a3ce18ca 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c @@ -245,6 +245,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) goto err_free_tgfx; } + parport_put_port(pp); return tgfx; err_free_dev: From 61faddf661a65a179751dc9fd209cb694d9a28af Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Tue, 30 Nov 2010 21:49:08 +0100 Subject: [PATCH 060/300] Bluetooth: Fix log spamming in btusb due to autosuspend If a device is autosuspended an inability to resubmit URBs is to be expected. Check the error code and only log real errors. (Now that autosuspend is default enabled for btusb, those log messages were happening all the time e.g. with a BT mouse) Signed-off-by: Stefan Seyfried Signed-off-by: Oliver Neukum Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/btusb.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index ab3894f742c3..d323c1a8ecbb 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -239,7 +239,8 @@ static void btusb_intr_complete(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - BT_ERR("%s urb %p failed to resubmit (%d)", + if (err != -EPERM) + BT_ERR("%s urb %p failed to resubmit (%d)", hdev->name, urb, -err); usb_unanchor_urb(urb); } @@ -323,7 +324,8 @@ static void btusb_bulk_complete(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - BT_ERR("%s urb %p failed to resubmit (%d)", + if (err != -EPERM) + BT_ERR("%s urb %p failed to resubmit (%d)", hdev->name, urb, -err); usb_unanchor_urb(urb); } @@ -412,7 +414,8 @@ static void btusb_isoc_complete(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err < 0) { - BT_ERR("%s urb %p failed to resubmit (%d)", + if (err != -EPERM) + BT_ERR("%s urb %p failed to resubmit (%d)", hdev->name, urb, -err); usb_unanchor_urb(urb); } From be93112accb42c5586a459683d71975cc70673ca Mon Sep 17 00:00:00 2001 From: Bala Shanmugam Date: Fri, 26 Nov 2010 17:35:46 +0530 Subject: [PATCH 061/300] Bluetooth: Add new PID for Atheros 3011 Atheros 3011 has small sflash firmware and needs to be blacklisted in transport driver to load actual firmware in DFU driver. Signed-off-by: Bala Shanmugam Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/ath3k.c | 4 ++++ drivers/bluetooth/btusb.c | 3 +++ 2 files changed, 7 insertions(+) diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 128cae4e8629..949ed09c6361 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -35,6 +35,10 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3011 */ { USB_DEVICE(0x0CF3, 0x3000) }, + + /* Atheros AR3011 with sflash firmware*/ + { USB_DEVICE(0x0CF3, 0x3002) }, + { } /* Terminating entry */ }; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index d323c1a8ecbb..1da773f899a2 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -99,6 +99,9 @@ static struct usb_device_id blacklist_table[] = { /* Broadcom BCM2033 without firmware */ { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE }, + /* Atheros 3011 with sflash firmware */ + { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, + /* Broadcom BCM2035 */ { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, From 381601e5bbae78d7c18d946fe874a63957edea13 Mon Sep 17 00:00:00 2001 From: Anders Franzen Date: Wed, 24 Nov 2010 05:47:18 +0000 Subject: [PATCH 062/300] Make the ip6_tunnel reflect the true mtu. The ip6_tunnel always assumes it consumes 40 bytes (ip6 hdr) of the mtu of the underlaying device. So for a normal ethernet bearer, the mtu of the ip6_tunnel is 1460. However, when creating a tunnel the encap limit option is enabled by default, and it consumes 8 bytes more, so the true mtu shall be 1452. I dont really know if this breaks some statement in some RFC, so this is a request for comments. Signed-off-by: Anders Franzen Signed-off-by: David S. Miller --- net/ipv6/ip6_tunnel.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 2a59610c2a58..70e891a20fb9 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1175,6 +1175,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) sizeof (struct ipv6hdr); dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr); + if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) + dev->mtu-=8; if (dev->mtu < IPV6_MIN_MTU) dev->mtu = IPV6_MIN_MTU; @@ -1363,12 +1365,17 @@ static const struct net_device_ops ip6_tnl_netdev_ops = { static void ip6_tnl_dev_setup(struct net_device *dev) { + struct ip6_tnl *t; + dev->netdev_ops = &ip6_tnl_netdev_ops; dev->destructor = ip6_dev_free; dev->type = ARPHRD_TUNNEL6; dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr); + t = netdev_priv(dev); + if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) + dev->mtu-=8; dev->flags |= IFF_NOARP; dev->addr_len = sizeof(struct in6_addr); dev->features |= NETIF_F_NETNS_LOCAL; From 6c08af030212d1a34593397bb01f262ff31c3629 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 27 Nov 2010 06:47:43 +0000 Subject: [PATCH 063/300] b44: fix workarround for wap54g10 The code for the b44_wap54g10_workaround was never included, because the config option was wrong. The nvram_get function was never in mainline kernel, only in external OpenWrt patches. The code should be compiled in when CONFIG_BCM47XX is selected and not when CONFIG_SSB_DRIVER_MIPS is selected, because nvram_getenv is only available on bcm47xx platforms and now in the mainline kernel code. Using an include is better than a second function declaration, to fix this when the function signature changes. Signed-off-by: Hauke Mehrtens Signed-off-by: David S. Miller --- drivers/net/b44.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/b44.c b/drivers/net/b44.c index c6e86315b3f8..2e2b76258ab4 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -381,11 +381,11 @@ static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote) __b44_set_flow_ctrl(bp, pause_enab); } -#ifdef SSB_DRIVER_MIPS -extern char *nvram_get(char *name); +#ifdef CONFIG_BCM47XX +#include static void b44_wap54g10_workaround(struct b44 *bp) { - const char *str; + char buf[20]; u32 val; int err; @@ -394,10 +394,9 @@ static void b44_wap54g10_workaround(struct b44 *bp) * see https://dev.openwrt.org/ticket/146 * check and reset bit "isolate" */ - str = nvram_get("boardnum"); - if (!str) + if (nvram_getenv("boardnum", buf, sizeof(buf)) < 0) return; - if (simple_strtoul(str, NULL, 0) == 2) { + if (simple_strtoul(buf, NULL, 0) == 2) { err = __b44_readphy(bp, 0, MII_BMCR, &val); if (err) goto error; From d13a2cb63d06fe2e3067c7d40f9a5946abd614c8 Mon Sep 17 00:00:00 2001 From: David Strand Date: Wed, 1 Dec 2010 11:43:08 -0800 Subject: [PATCH 064/300] bonding: check for assigned mac before adopting the slaves mac address Restore the check for an unassigned mac address before adopting the first slaves as it's own. The change in behavior was introduced by: commit c20811a79e671a6a1fe86a8c1afe04aca8a7f085 Author: Jiri Pirko bonding: move dev_addr cpy to bond_enslave Signed-off-by: David Strand Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 71a169740d05..2fee00a4c9ef 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1576,7 +1576,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) /* If this is the first slave, then we need to set the master's hardware * address to be the same as the slave's. */ - if (bond->slave_cnt == 0) + if (is_zero_ether_addr(bond->dev->dev_addr)) memcpy(bond->dev->dev_addr, slave_dev->dev_addr, slave_dev->addr_len); From 6dcdd1b3694a4fa2b85167a9c860c7613a7553c7 Mon Sep 17 00:00:00 2001 From: David McCullough Date: Mon, 29 Nov 2010 19:32:34 +0000 Subject: [PATCH 065/300] net/ipv6/sit.c: return unhandled skb to tunnel4_rcv I found a problem using an IPv6 over IPv4 tunnel. When CONFIG_IPV6_SIT was enabled, the packets would be rejected as net/ipv6/sit.c was catching all IPPROTO_IPV6 packets and returning an ICMP port unreachable error. I think this patch fixes the problem cleanly. I believe the code in net/ipv4/tunnel4.c:tunnel4_rcv takes care of it properly if none of the handlers claim the skb. Signed-off-by: David McCullough Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv6/sit.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index d6bfaec3bbbf..8c4d00c7cd2b 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -606,8 +606,9 @@ static int ipip6_rcv(struct sk_buff *skb) return 0; } - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); + /* no tunnel matched, let upstream know, ipsec may handle it */ rcu_read_unlock(); + return 1; out: kfree_skb(skb); return 0; From 212967c69afd348342548272aedbe4d46a9325d6 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 25 Nov 2010 00:02:36 +0100 Subject: [PATCH 066/300] ACPI / PM: Check device state before refcounting power resources Commit 3e384ee6c687cb397581ee8f9440fc8220cfac80 (ACPI / PM: Fix reference counting of power resources) introduced a regression by causing fan power resources to be turned on and reference counted unnecessarily during resume, so on some boxes fans are always on after resume. Fix the problem by checking if the current device state is different from the new state before reference counting and turning on power resources in acpi_power_transition(). Addresses https://bugzilla.kernel.org/show_bug.cgi?id=22932 . Signed-off-by: Rafael J. Wysocki Reported-and-tested-by: Maciej Rutecki Signed-off-by: Len Brown --- drivers/acpi/power.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 67dedeed144c..792a8309d074 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -465,10 +465,12 @@ int acpi_power_transition(struct acpi_device *device, int state) struct acpi_handle_list *tl = NULL; /* Target Resources */ int i = 0; - if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) return -EINVAL; + if (device->power.state == state) + return 0; + if ((device->power.state < ACPI_STATE_D0) || (device->power.state > ACPI_STATE_D3)) return -ENODEV; @@ -488,10 +490,6 @@ int acpi_power_transition(struct acpi_device *device, int state) goto end; } - if (device->power.state == state) { - goto end; - } - /* * Then we dereference all power resources used in the current list. */ From 12b3b5afed67e08aa641d30e57df20dab2e33432 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 25 Nov 2010 00:03:32 +0100 Subject: [PATCH 067/300] ACPI / PM: Do not refcount power resources that can't be turned on If turning on a power resource fails, do not reference count it, since it cannot be in use in that case. Signed-off-by: Rafael J. Wysocki Signed-off-by: Len Brown --- drivers/acpi/power.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 792a8309d074..4c9c2fb5d98f 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -213,11 +213,13 @@ static int acpi_power_on(acpi_handle handle) resource->name)); } else { result = __acpi_power_on(resource); + if (result) + resource->ref_count--; } mutex_unlock(&resource->resource_lock); - return 0; + return result; } static int acpi_power_off_device(acpi_handle handle) From 884ea892763d4dfba509743f65961c782c0442db Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 22 Nov 2010 22:58:06 -0800 Subject: [PATCH 068/300] ceph: avoid possible null deref in readdir after dir llseek last may be NULL, but we dereference it in the else branch without checking. Normally it doesn't trigger because last == NULL when fpos == 2, but it could happen on a newly opened dir if the user seeks forward. Reported-by: Dan Carpenter Signed-off-by: Sage Weil --- fs/ceph/dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 7d447af84ec4..158c700fdca5 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -114,8 +114,8 @@ static int __dcache_readdir(struct file *filp, spin_lock(&dcache_lock); /* start at beginning? */ - if (filp->f_pos == 2 || (last && - filp->f_pos < ceph_dentry(last)->offset)) { + if (filp->f_pos == 2 || last == NULL || + filp->f_pos < ceph_dentry(last)->offset) { if (list_empty(&parent->d_subdirs)) goto out_unlock; p = parent->d_subdirs.prev; From 25933abdd8c562182ca6dc9f8c4c2cc8265c3a80 Mon Sep 17 00:00:00 2001 From: Herb Shiu Date: Wed, 1 Dec 2010 14:14:38 -0800 Subject: [PATCH 069/300] ceph: Handle file locks in replies from the MDS. Previously the kernel client incorrectly assumed everything was a directory. Signed-off-by: Herb Shiu Acked-by: Greg Farnum Signed-off-by: Sage Weil --- fs/ceph/mds_client.c | 41 +++++++++++++++++++++++++++++++++++++---- fs/ceph/mds_client.h | 31 +++++++++++++++++++++---------- 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 098b18508479..38800eaa81d0 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -201,6 +201,38 @@ out_bad: return err; } +/* + * parse fcntl F_GETLK results + */ +static int parse_reply_info_filelock(void **p, void *end, + struct ceph_mds_reply_info_parsed *info) +{ + if (*p + sizeof(*info->filelock_reply) > end) + goto bad; + + info->filelock_reply = *p; + *p += sizeof(*info->filelock_reply); + + if (unlikely(*p != end)) + goto bad; + return 0; + +bad: + return -EIO; +} + +/* + * parse extra results + */ +static int parse_reply_info_extra(void **p, void *end, + struct ceph_mds_reply_info_parsed *info) +{ + if (info->head->op == CEPH_MDS_OP_GETFILELOCK) + return parse_reply_info_filelock(p, end, info); + else + return parse_reply_info_dir(p, end, info); +} + /* * parse entire mds reply */ @@ -223,10 +255,10 @@ static int parse_reply_info(struct ceph_msg *msg, goto out_bad; } - /* dir content */ + /* extra */ ceph_decode_32_safe(&p, end, len, bad); if (len > 0) { - err = parse_reply_info_dir(&p, p+len, info); + err = parse_reply_info_extra(&p, p+len, info); if (err < 0) goto out_bad; } @@ -2074,7 +2106,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) mutex_lock(&session->s_mutex); if (err < 0) { - pr_err("mdsc_handle_reply got corrupt reply mds%d\n", mds); + pr_err("mdsc_handle_reply got corrupt reply mds%d(tid:%lld)\n", mds, tid); ceph_msg_dump(msg); goto out_err; } @@ -2094,7 +2126,8 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) mutex_lock(&req->r_fill_mutex); err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session); if (err == 0) { - if (result == 0 && rinfo->dir_nr) + if (result == 0 && req->r_op != CEPH_MDS_OP_GETFILELOCK && + rinfo->dir_nr) ceph_readdir_prepopulate(req, req->r_session); ceph_unreserve_caps(mdsc, &req->r_caps_reservation); } diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 9341fd4f1432..aabe563b54db 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h @@ -42,26 +42,37 @@ struct ceph_mds_reply_info_in { }; /* - * parsed info about an mds reply, including information about the - * target inode and/or its parent directory and dentry, and directory - * contents (for readdir results). + * parsed info about an mds reply, including information about + * either: 1) the target inode and/or its parent directory and dentry, + * and directory contents (for readdir results), or + * 2) the file range lock info (for fcntl F_GETLK results). */ struct ceph_mds_reply_info_parsed { struct ceph_mds_reply_head *head; + /* trace */ struct ceph_mds_reply_info_in diri, targeti; struct ceph_mds_reply_dirfrag *dirfrag; char *dname; u32 dname_len; struct ceph_mds_reply_lease *dlease; - struct ceph_mds_reply_dirfrag *dir_dir; - int dir_nr; - char **dir_dname; - u32 *dir_dname_len; - struct ceph_mds_reply_lease **dir_dlease; - struct ceph_mds_reply_info_in *dir_in; - u8 dir_complete, dir_end; + /* extra */ + union { + /* for fcntl F_GETLK results */ + struct ceph_filelock *filelock_reply; + + /* for readdir results */ + struct { + struct ceph_mds_reply_dirfrag *dir_dir; + int dir_nr; + char **dir_dname; + u32 *dir_dname_len; + struct ceph_mds_reply_lease **dir_dlease; + struct ceph_mds_reply_info_in *dir_in; + u8 dir_complete, dir_end; + }; + }; /* encoded blob describing snapshot contexts for certain operations (e.g., open) */ From 637ae8d547390df75bad42a7e9cb65e625119767 Mon Sep 17 00:00:00 2001 From: Herb Shiu Date: Tue, 23 Nov 2010 13:42:23 -0800 Subject: [PATCH 070/300] ceph: pass lock information by struct file_lock instead of as individual params. Signed-off-by: Herb Shiu Acked-by: Greg Farnum Signed-off-by: Sage Weil --- fs/ceph/locks.c | 58 ++++++++++++++++++------------------------------- 1 file changed, 21 insertions(+), 37 deletions(-) diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index 40abde93c345..7b7ac310f052 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c @@ -11,40 +11,49 @@ * Implement fcntl and flock locking functions. */ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, - u64 pid, u64 pid_ns, - int cmd, u64 start, u64 length, u8 wait) + int cmd, u8 wait, struct file_lock *fl) { struct inode *inode = file->f_dentry->d_inode; struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; struct ceph_mds_request *req; int err; + u64 length = 0; req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS); if (IS_ERR(req)) return PTR_ERR(req); req->r_inode = igrab(inode); + /* mds requires start and length rather than start and end */ + if (LLONG_MAX == fl->fl_end) + length = 0; + else + length = fl->fl_end - fl->fl_start + 1; + dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " "length: %llu, wait: %d, type`: %d", (int)lock_type, - (int)operation, pid, start, length, wait, cmd); + (int)operation, (u64)fl->fl_pid, fl->fl_start, + length, wait, fl->fl_type); + req->r_args.filelock_change.rule = lock_type; req->r_args.filelock_change.type = cmd; - req->r_args.filelock_change.pid = cpu_to_le64(pid); + req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid); /* This should be adjusted, but I'm not sure if namespaces actually get id numbers*/ req->r_args.filelock_change.pid_namespace = - cpu_to_le64((u64)pid_ns); - req->r_args.filelock_change.start = cpu_to_le64(start); + cpu_to_le64((u64)(unsigned long)fl->fl_nspid); + req->r_args.filelock_change.start = cpu_to_le64(fl->fl_start); req->r_args.filelock_change.length = cpu_to_le64(length); req->r_args.filelock_change.wait = wait; err = ceph_mdsc_do_request(mdsc, inode, req); ceph_mdsc_put_request(req); dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " - "length: %llu, wait: %d, type`: %d err code %d", (int)lock_type, - (int)operation, pid, start, length, wait, cmd, err); + "length: %llu, wait: %d, type`: %d, err code %d", (int)lock_type, + (int)operation, (u64)fl->fl_pid, fl->fl_start, + length, wait, fl->fl_type, err); return err; } @@ -54,7 +63,6 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, */ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) { - u64 length; u8 lock_cmd; int err; u8 wait = 0; @@ -76,16 +84,7 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) else lock_cmd = CEPH_LOCK_UNLOCK; - if (LLONG_MAX == fl->fl_end) - length = 0; - else - length = fl->fl_end - fl->fl_start + 1; - - err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, - (u64)fl->fl_pid, - (u64)(unsigned long)fl->fl_nspid, - lock_cmd, fl->fl_start, - length, wait); + err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, lock_cmd, wait, fl); if (!err) { dout("mds locked, locking locally"); err = posix_lock_file(file, fl, NULL); @@ -93,10 +92,7 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) /* undo! This should only happen if the kernel detects * local deadlock. */ ceph_lock_message(CEPH_LOCK_FCNTL, op, file, - (u64)fl->fl_pid, - (u64)(unsigned long)fl->fl_nspid, - CEPH_LOCK_UNLOCK, fl->fl_start, - length, 0); + CEPH_LOCK_UNLOCK, 0, fl); dout("got %d on posix_lock_file, undid lock", err); } } else { @@ -107,7 +103,6 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) int ceph_flock(struct file *file, int cmd, struct file_lock *fl) { - u64 length; u8 lock_cmd; int err; u8 wait = 1; @@ -127,26 +122,15 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) lock_cmd = CEPH_LOCK_EXCL; else lock_cmd = CEPH_LOCK_UNLOCK; - /* mds requires start and length rather than start and end */ - if (LLONG_MAX == fl->fl_end) - length = 0; - else - length = fl->fl_end - fl->fl_start + 1; err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK, - file, (u64)fl->fl_pid, - (u64)(unsigned long)fl->fl_nspid, - lock_cmd, fl->fl_start, - length, wait); + file, lock_cmd, wait, fl); if (!err) { err = flock_lock_file_wait(file, fl); if (err) { ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK, - file, (u64)fl->fl_pid, - (u64)(unsigned long)fl->fl_nspid, - CEPH_LOCK_UNLOCK, fl->fl_start, - length, 0); + file, CEPH_LOCK_UNLOCK, 0, fl); dout("got %d on flock_lock_file_wait, undid lock", err); } } else { From a5b10629edfa521071ccdb3b1e0e7fb350a044db Mon Sep 17 00:00:00 2001 From: Herb Shiu Date: Tue, 23 Nov 2010 13:58:29 -0800 Subject: [PATCH 071/300] ceph: Behave better when handling file lock replies. Fill in the local lock with response data if appropriate, and don't call posix_lock_file when reading locks. Signed-off-by: Herb Shiu Acked-by: Greg Farnum Signed-off-by: Sage Weil --- fs/ceph/locks.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index 7b7ac310f052..476b329867d4 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c @@ -49,6 +49,25 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, req->r_args.filelock_change.wait = wait; err = ceph_mdsc_do_request(mdsc, inode, req); + + if ( operation == CEPH_MDS_OP_GETFILELOCK){ + fl->fl_pid = le64_to_cpu(req->r_reply_info.filelock_reply->pid); + if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type) + fl->fl_type = F_RDLCK; + else if (CEPH_LOCK_EXCL == req->r_reply_info.filelock_reply->type) + fl->fl_type = F_WRLCK; + else + fl->fl_type = F_UNLCK; + + fl->fl_start = le64_to_cpu(req->r_reply_info.filelock_reply->start); + length = le64_to_cpu(req->r_reply_info.filelock_reply->start) + + le64_to_cpu(req->r_reply_info.filelock_reply->length); + if (length >= 1) + fl->fl_end = length -1; + else + fl->fl_end = 0; + + } ceph_mdsc_put_request(req); dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " "length: %llu, wait: %d, type`: %d, err code %d", (int)lock_type, @@ -86,15 +105,18 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, lock_cmd, wait, fl); if (!err) { - dout("mds locked, locking locally"); - err = posix_lock_file(file, fl, NULL); - if (err && (CEPH_MDS_OP_SETFILELOCK == op)) { - /* undo! This should only happen if the kernel detects - * local deadlock. */ - ceph_lock_message(CEPH_LOCK_FCNTL, op, file, - CEPH_LOCK_UNLOCK, 0, fl); - dout("got %d on posix_lock_file, undid lock", err); + if ( op != CEPH_MDS_OP_GETFILELOCK ){ + dout("mds locked, locking locally"); + err = posix_lock_file(file, fl, NULL); + if (err && (CEPH_MDS_OP_SETFILELOCK == op)) { + /* undo! This should only happen if the kernel detects + * local deadlock. */ + ceph_lock_message(CEPH_LOCK_FCNTL, op, file, + CEPH_LOCK_UNLOCK, 0, fl); + dout("got %d on posix_lock_file, undid lock", err); + } } + } else { dout("mds returned error code %d", err); } From 56b9aea3b740be7665be100872a913da9bdc653b Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 2 Dec 2010 01:19:32 -0500 Subject: [PATCH 072/300] intel_idle: recognize ARAT on WSM-EX We erroneously ignored the Always Running APIC Timer on WSM-EX. Move the check for ARAT down so that it can apply to any/all models. Signed-off-by: Len Brown --- drivers/idle/intel_idle.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 41665d2f9f93..c131d58bcb50 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -273,8 +273,6 @@ static int intel_idle_probe(void) pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); - if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ - lapic_timer_reliable_states = 0xFFFFFFFF; if (boot_cpu_data.x86 != 6) /* family 6 */ return -ENODEV; @@ -286,8 +284,6 @@ static int intel_idle_probe(void) case 0x1F: /* Core i7 and i5 Processor - Nehalem */ case 0x2E: /* Nehalem-EX Xeon */ case 0x2F: /* Westmere-EX Xeon */ - lapic_timer_reliable_states = (1 << 1); /* C1 */ - case 0x25: /* Westmere */ case 0x2C: /* Westmere */ cpuidle_state_table = nehalem_cstates; @@ -295,7 +291,6 @@ static int intel_idle_probe(void) case 0x1C: /* 28 - Atom Processor */ case 0x26: /* 38 - Lincroft Atom Processor */ - lapic_timer_reliable_states = (1 << 1); /* C1 */ cpuidle_state_table = atom_cstates; break; @@ -303,10 +298,6 @@ static int intel_idle_probe(void) case 0x2D: /* SNB Xeon */ cpuidle_state_table = snb_cstates; break; -#ifdef FUTURE_USE - case 0x17: /* 23 - Core 2 Duo */ - lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */ -#endif default: pr_debug(PREFIX "does not run on family %d model %d\n", @@ -314,6 +305,9 @@ static int intel_idle_probe(void) return -ENODEV; } + if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ + lapic_timer_reliable_states = 0xFFFFFFFF; + pr_debug(PREFIX "v" INTEL_IDLE_VERSION " model 0x%X\n", boot_cpu_data.x86_model); From 6072d13c429373c5d63b69dadbbef40a9b035552 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 1 Dec 2010 13:35:19 -0500 Subject: [PATCH 073/300] Call the filesystem back whenever a page is removed from the page cache NFS needs to be able to release objects that are stored in the page cache once the page itself is no longer visible from the page cache. This patch adds a callback to the address space operations that allows filesystems to perform page cleanups once the page has been removed from the page cache. Original patch by: Linus Torvalds [trondmy: cover the cases of invalidate_inode_pages2() and truncate_inode_pages()] Signed-off-by: Trond Myklebust --- Documentation/filesystems/Locking | 7 ++++++- Documentation/filesystems/vfs.txt | 7 +++++++ include/linux/fs.h | 1 + mm/filemap.c | 5 +++++ mm/truncate.c | 4 ++++ mm/vmscan.c | 7 +++++++ 6 files changed, 30 insertions(+), 1 deletion(-) diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index a91f30890011..b6426f15b4ae 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking @@ -173,12 +173,13 @@ prototypes: sector_t (*bmap)(struct address_space *, sector_t); int (*invalidatepage) (struct page *, unsigned long); int (*releasepage) (struct page *, int); + void (*freepage)(struct page *); int (*direct_IO)(int, struct kiocb *, const struct iovec *iov, loff_t offset, unsigned long nr_segs); int (*launder_page) (struct page *); locking rules: - All except set_page_dirty may block + All except set_page_dirty and freepage may block BKL PageLocked(page) i_mutex writepage: no yes, unlocks (see below) @@ -193,6 +194,7 @@ perform_write: no n/a yes bmap: no invalidatepage: no yes releasepage: no yes +freepage: no yes direct_IO: no launder_page: no yes @@ -288,6 +290,9 @@ buffers from the page in preparation for freeing it. It returns zero to indicate that the buffers are (or may be) freeable. If ->releasepage is zero, the kernel assumes that the fs has no private interest in the buffers. + ->freepage() is called when the kernel is done dropping the page +from the page cache. + ->launder_page() may be called prior to releasing a page if it is still found to be dirty. It returns zero if the page was successfully cleaned, or an error value if not. Note that in order to prevent the page diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index ed7e5efc06d8..3b14a557eca6 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt @@ -534,6 +534,7 @@ struct address_space_operations { sector_t (*bmap)(struct address_space *, sector_t); int (*invalidatepage) (struct page *, unsigned long); int (*releasepage) (struct page *, int); + void (*freepage)(struct page *); ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov, loff_t offset, unsigned long nr_segs); struct page* (*get_xip_page)(struct address_space *, sector_t, @@ -679,6 +680,12 @@ struct address_space_operations { need to ensure this. Possibly it can clear the PageUptodate bit if it cannot free private data yet. + freepage: freepage is called once the page is no longer visible in + the page cache in order to allow the cleanup of any private + data. Since it may be called by the memory reclaimer, it + should not assume that the original address_space mapping still + exists, and it should not block. + direct_IO: called by the generic read/write routines to perform direct_IO - that is IO requests which bypass the page cache and transfer data directly between the storage and the diff --git a/include/linux/fs.h b/include/linux/fs.h index c9e06cc70dad..090f0eacde29 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -602,6 +602,7 @@ struct address_space_operations { sector_t (*bmap)(struct address_space *, sector_t); void (*invalidatepage) (struct page *, unsigned long); int (*releasepage) (struct page *, gfp_t); + void (*freepage)(struct page *); ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov, loff_t offset, unsigned long nr_segs); int (*get_xip_mem)(struct address_space *, pgoff_t, int, diff --git a/mm/filemap.c b/mm/filemap.c index ea89840fc65f..6b9aee20f242 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -143,13 +143,18 @@ void __remove_from_page_cache(struct page *page) void remove_from_page_cache(struct page *page) { struct address_space *mapping = page->mapping; + void (*freepage)(struct page *); BUG_ON(!PageLocked(page)); + freepage = mapping->a_ops->freepage; spin_lock_irq(&mapping->tree_lock); __remove_from_page_cache(page); spin_unlock_irq(&mapping->tree_lock); mem_cgroup_uncharge_cache_page(page); + + if (freepage) + freepage(page); } EXPORT_SYMBOL(remove_from_page_cache); diff --git a/mm/truncate.c b/mm/truncate.c index ba887bff48c5..3c2d5ddfa0d4 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -390,6 +390,10 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page) __remove_from_page_cache(page); spin_unlock_irq(&mapping->tree_lock); mem_cgroup_uncharge_cache_page(page); + + if (mapping->a_ops->freepage) + mapping->a_ops->freepage(page); + page_cache_release(page); /* pagecache ref */ return 1; failed: diff --git a/mm/vmscan.c b/mm/vmscan.c index d31d7ce52c0e..9ca587c69274 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -494,9 +494,16 @@ static int __remove_mapping(struct address_space *mapping, struct page *page) spin_unlock_irq(&mapping->tree_lock); swapcache_free(swap, page); } else { + void (*freepage)(struct page *); + + freepage = mapping->a_ops->freepage; + __remove_from_page_cache(page); spin_unlock_irq(&mapping->tree_lock); mem_cgroup_uncharge_cache_page(page); + + if (freepage != NULL) + freepage(page); } return 1; From 11de3b11e08cac26d59e88efaf4e316701883552 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 1 Dec 2010 14:17:06 -0500 Subject: [PATCH 074/300] NFS: Fix a memory leak in nfs_readdir We need to ensure that the entries in the nfs_cache_array get cleared when the page is removed from the page cache. To do so, we use the freepage address_space operation. Change nfs_readdir_clear_array to use kmap_atomic(), so that the function can be safely called from all contexts. Finally, modify the cache_page_release helper to call nfs_readdir_clear_array directly, when dealing with an anonymous page from 'uncached_readdir'. Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 18 +++++++++--------- fs/nfs/inode.c | 1 + include/linux/nfs_fs.h | 1 + 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index e03537ff9350..d529e0e99efa 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -57,7 +57,7 @@ static int nfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); static int nfs_fsync_dir(struct file *, int); static loff_t nfs_llseek_dir(struct file *, loff_t, int); -static int nfs_readdir_clear_array(struct page*, gfp_t); +static void nfs_readdir_clear_array(struct page*); const struct file_operations nfs_dir_operations = { .llseek = nfs_llseek_dir, @@ -83,8 +83,8 @@ const struct inode_operations nfs_dir_inode_operations = { .setattr = nfs_setattr, }; -const struct address_space_operations nfs_dir_addr_space_ops = { - .releasepage = nfs_readdir_clear_array, +const struct address_space_operations nfs_dir_aops = { + .freepage = nfs_readdir_clear_array, }; #ifdef CONFIG_NFS_V3 @@ -214,17 +214,15 @@ void nfs_readdir_release_array(struct page *page) * we are freeing strings created by nfs_add_to_readdir_array() */ static -int nfs_readdir_clear_array(struct page *page, gfp_t mask) +void nfs_readdir_clear_array(struct page *page) { - struct nfs_cache_array *array = nfs_readdir_get_array(page); + struct nfs_cache_array *array; int i; - if (IS_ERR(array)) - return PTR_ERR(array); + array = kmap_atomic(page, KM_USER0); for (i = 0; i < array->size; i++) kfree(array->array[i].string.name); - nfs_readdir_release_array(page); - return 0; + kunmap_atomic(array, KM_USER0); } /* @@ -639,6 +637,8 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page) static void cache_page_release(nfs_readdir_descriptor_t *desc) { + if (!desc->page->mapping) + nfs_readdir_clear_array(desc->page); page_cache_release(desc->page); desc->page = NULL; } diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 314f57164602..e67e31c73416 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -289,6 +289,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) } else if (S_ISDIR(inode->i_mode)) { inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops; inode->i_fop = &nfs_dir_operations; + inode->i_data.a_ops = &nfs_dir_aops; if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS)) set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags); /* Deal with crossing mountpoints */ diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index c66fdb7d6998..29d504d5d1c3 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -401,6 +401,7 @@ extern const struct inode_operations nfs3_file_inode_operations; #endif /* CONFIG_NFS_V3 */ extern const struct file_operations nfs_file_operations; extern const struct address_space_operations nfs_file_aops; +extern const struct address_space_operations nfs_dir_aops; static inline struct nfs_open_context *nfs_file_open_context(struct file *filp) { From 9306990a656d9cfd8bf3586938012729c1f2ea50 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 30 Nov 2010 23:24:09 -0800 Subject: [PATCH 075/300] ath9k: Fix bug in reading input gpio state for ar9003 The register which gives input gpio state is 0x404c for ar9003, currently 0x4048 is wrongly used. This will disable RF and make it unusable on some of AR9003. Cc:stable@kernel.org Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 3 ++- drivers/net/wireless/ath/ath9k/reg.h | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 6ebc68bca91f..c7fbe25cc128 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2044,7 +2044,8 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) val = REG_READ(ah, AR7010_GPIO_IN); return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0; } else if (AR_SREV_9300_20_OR_LATER(ah)) - return MS_REG_READ(AR9300, gpio) != 0; + return (MS(REG_READ(ah, AR_GPIO_IN), AR9300_GPIO_IN_VAL) & + AR_GPIO_BIT(gpio)) != 0; else if (AR_SREV_9271(ah)) return MS_REG_READ(AR9271, gpio) != 0; else if (AR_SREV_9287_11_OR_LATER(ah)) diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index dddf579aacf1..2c6a22fbb0f0 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -984,11 +984,13 @@ enum { #define AR9287_GPIO_IN_VAL_S 11 #define AR9271_GPIO_IN_VAL 0xFFFF0000 #define AR9271_GPIO_IN_VAL_S 16 -#define AR9300_GPIO_IN_VAL 0x0001FFFF -#define AR9300_GPIO_IN_VAL_S 0 #define AR7010_GPIO_IN_VAL 0x0000FFFF #define AR7010_GPIO_IN_VAL_S 0 +#define AR_GPIO_IN 0x404c +#define AR9300_GPIO_IN_VAL 0x0001FFFF +#define AR9300_GPIO_IN_VAL_S 0 + #define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c) #define AR_GPIO_OE_OUT_DRV 0x3 #define AR_GPIO_OE_OUT_DRV_NO 0x0 From e702ba18f25887c76d26c8a85cc1706463c62e9a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 1 Dec 2010 19:07:46 +0100 Subject: [PATCH 076/300] ath9k_hw: fix endian issues with CTLs on AR9003 Parsing data using bitfields is messy, because it makes endian handling much harder. AR9002 and earlier got it right, AR9003 got it wrong. This might lead to either using too high or too low tx power values, depending on frequency and eeprom settings. Fix it by getting rid of the CTL related bitfields entirely and use masks instead. Signed-off-by: Felix Fietkau Cc: stable@kernel.org Signed-off-by: John W. Linville --- .../net/wireless/ath/ath9k/ar9003_eeprom.c | 73 ++++++++++--------- .../net/wireless/ath/ath9k/ar9003_eeprom.h | 9 +-- drivers/net/wireless/ath/ath9k/eeprom.c | 6 +- drivers/net/wireless/ath/ath9k/eeprom.h | 13 +--- 4 files changed, 47 insertions(+), 54 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c4182359bee4..a7b82f0085d2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -55,6 +55,8 @@ #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ +#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6)) + static const struct ar9300_eeprom ar9300_default = { .eepromVersion = 2, .templateVersion = 2, @@ -290,20 +292,21 @@ static const struct ar9300_eeprom ar9300_default = { } }, .ctlPowerData_2G = { - { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, - { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, - { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, - { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } }, - { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, - { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, - { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } }, - { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, - { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, - { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, - { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } }, + { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } }, }, .modalHeader5G = { /* 4 idle,t1,t2,b (4 bits per setting) */ @@ -568,56 +571,56 @@ static const struct ar9300_eeprom ar9300_default = { .ctlPowerData_5G = { { { - {60, 1}, {60, 1}, {60, 1}, {60, 1}, - {60, 1}, {60, 1}, {60, 1}, {60, 0}, + CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), + CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), } }, { { - {60, 1}, {60, 1}, {60, 1}, {60, 1}, - {60, 1}, {60, 1}, {60, 1}, {60, 0}, + CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), + CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), } }, { { - {60, 0}, {60, 1}, {60, 0}, {60, 1}, - {60, 1}, {60, 1}, {60, 1}, {60, 1}, + CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1), + CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), } }, { { - {60, 0}, {60, 1}, {60, 1}, {60, 0}, - {60, 1}, {60, 0}, {60, 0}, {60, 0}, + CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0), + CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0), } }, { { - {60, 1}, {60, 1}, {60, 1}, {60, 0}, - {60, 0}, {60, 0}, {60, 0}, {60, 0}, + CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), + CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0), } }, { { - {60, 1}, {60, 1}, {60, 1}, {60, 1}, - {60, 1}, {60, 0}, {60, 0}, {60, 0}, + CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), + CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0), } }, { { - {60, 1}, {60, 1}, {60, 1}, {60, 1}, - {60, 1}, {60, 1}, {60, 1}, {60, 1}, + CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), + CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), } }, { { - {60, 1}, {60, 1}, {60, 0}, {60, 1}, - {60, 1}, {60, 1}, {60, 1}, {60, 0}, + CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1), + CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), } }, { { - {60, 1}, {60, 0}, {60, 1}, {60, 1}, - {60, 1}, {60, 1}, {60, 0}, {60, 1}, + CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1), + CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1), } }, } @@ -1827,9 +1830,9 @@ static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep, struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G; if (is2GHz) - return ctl_2g[idx].ctlEdges[edge].tPower; + return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]); else - return ctl_5g[idx].ctlEdges[edge].tPower; + return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]); } static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, @@ -1847,12 +1850,12 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, if (is2GHz) { if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq && - ctl_2g[idx].ctlEdges[edge - 1].flag) - return ctl_2g[idx].ctlEdges[edge - 1].tPower; + CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1])) + return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]); } else { if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq && - ctl_5g[idx].ctlEdges[edge - 1].flag) - return ctl_5g[idx].ctlEdges[edge - 1].tPower; + CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1])) + return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]); } return AR9300_MAX_RATE_POWER; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 3c533bb983c7..655b3033396c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -261,17 +261,12 @@ struct cal_tgt_pow_ht { u8 tPow2x[14]; } __packed; -struct cal_ctl_edge_pwr { - u8 tPower:6, - flag:2; -} __packed; - struct cal_ctl_data_2g { - struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_2G]; + u8 ctlEdges[AR9300_NUM_BAND_EDGES_2G]; } __packed; struct cal_ctl_data_5g { - struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G]; + u8 ctlEdges[AR9300_NUM_BAND_EDGES_5G]; } __packed; struct ar9300_eeprom { diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index 1266333f586d..2bbf94d0191e 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c @@ -240,16 +240,16 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, for (i = 0; (i < num_band_edges) && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) { if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { - twiceMaxEdgePower = pRdEdgesPower[i].tPower; + twiceMaxEdgePower = CTL_EDGE_TPOWER(pRdEdgesPower[i].ctl); break; } else if ((i > 0) && (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz))) { if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel, is2GHz) < freq && - pRdEdgesPower[i - 1].flag) { + CTL_EDGE_FLAGS(pRdEdgesPower[i - 1].ctl)) { twiceMaxEdgePower = - pRdEdgesPower[i - 1].tPower; + CTL_EDGE_TPOWER(pRdEdgesPower[i - 1].ctl); } break; } diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index dacb45e1b906..41ad1fe62527 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -233,6 +233,9 @@ #define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1) +#define CTL_EDGE_TPOWER(_ctl) ((_ctl) & 0x3f) +#define CTL_EDGE_FLAGS(_ctl) (((_ctl) >> 6) & 0x03) + enum eeprom_param { EEP_NFTHRESH_5, EEP_NFTHRESH_2, @@ -535,18 +538,10 @@ struct cal_target_power_ht { u8 tPow2x[8]; } __packed; - -#ifdef __BIG_ENDIAN_BITFIELD struct cal_ctl_edges { u8 bChannel; - u8 flag:2, tPower:6; + u8 ctl; } __packed; -#else -struct cal_ctl_edges { - u8 bChannel; - u8 tPower:6, flag:2; -} __packed; -#endif struct cal_data_op_loop_ar9287 { u8 pwrPdg[2][5]; From f67e07eb3decd7840b621fba37fd600adfdf99f8 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 1 Dec 2010 19:07:47 +0100 Subject: [PATCH 077/300] ath9k_hw: fix more bitfield related endian issues A few LNA control related flags were also specified as a bitfields, however for some strange reason they were written in big-endian order this time. Fix this by using flags instead. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom.h | 14 ++++++++++---- drivers/net/wireless/ath/ath9k/eeprom_def.c | 11 ++++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 41ad1fe62527..dd59f09441a3 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -236,6 +236,15 @@ #define CTL_EDGE_TPOWER(_ctl) ((_ctl) & 0x3f) #define CTL_EDGE_FLAGS(_ctl) (((_ctl) >> 6) & 0x03) +#define LNA_CTL_BUF_MODE BIT(0) +#define LNA_CTL_ISEL_LO BIT(1) +#define LNA_CTL_ISEL_HI BIT(2) +#define LNA_CTL_BUF_IN BIT(3) +#define LNA_CTL_FEM_BAND BIT(4) +#define LNA_CTL_LOCAL_BIAS BIT(5) +#define LNA_CTL_FORCE_XPA BIT(6) +#define LNA_CTL_USE_ANT1 BIT(7) + enum eeprom_param { EEP_NFTHRESH_5, EEP_NFTHRESH_2, @@ -381,10 +390,7 @@ struct modal_eep_header { u8 xatten2Margin[AR5416_MAX_CHAINS]; u8 ob_ch1; u8 db_ch1; - u8 useAnt1:1, - force_xpaon:1, - local_bias:1, - femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1; + u8 lna_ctl; u8 miscBits; u16 xpaBiasLvlFreq[3]; u8 futureModal[6]; diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 76b4d65472dd..526d7c933f7f 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -451,9 +451,10 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah, ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, AR_AN_TOP2_LOCALBIAS, AR_AN_TOP2_LOCALBIAS_S, - pModal->local_bias); + !!(pModal->lna_ctl & + LNA_CTL_LOCAL_BIAS)); REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, - pModal->force_xpaon); + !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA)); } REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, @@ -1428,9 +1429,9 @@ static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, num_ant_config = 1; - if (pBase->version >= 0x0E0D) - if (pModal->useAnt1) - num_ant_config += 1; + if (pBase->version >= 0x0E0D && + (pModal->lna_ctl & LNA_CTL_USE_ANT1)) + num_ant_config += 1; return num_ant_config; } From d89197c7f34934fbb0f96d938a0d6cfe0b8bcb1c Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Thu, 2 Dec 2010 14:10:58 -0500 Subject: [PATCH 078/300] Revert "ath9k: Fix STA disconnect issue due to received MIC failed bcast frames" This reverts commit 916448e77f6bcaaa7f13c3de0c3851783ae2bfd0. "As far as I can tell, either of these patches breaks multiple VIF scenarios. I'm not sure exactly why, but I had to revert this to get any of my interfaces to associate." -- Ben Greear http://marc.info/?l=linux-wireless&m=129123368719339&w=2 Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mac.c | 3 ++- drivers/net/wireless/ath/ath9k/recv.c | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index c996963ab339..8c13479b17cd 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -703,7 +703,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, rs->rs_phyerr = phyerr; } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) rs->rs_status |= ATH9K_RXERR_DECRYPT; - else if (ads.ds_rxstatus8 & AR_MichaelErr) + else if ((ads.ds_rxstatus8 & AR_MichaelErr) && + rs->rs_keyix != ATH9K_RXKEYIX_INVALID) rs->rs_status |= ATH9K_RXERR_MIC; else if (ads.ds_rxstatus8 & AR_KeyMiss) rs->rs_status |= ATH9K_RXERR_DECRYPT; diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 14d479f8d8ac..1a62e351ec77 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -1049,11 +1049,9 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, int hdrlen, padpos, padsize; u8 keyix; __le16 fc; - bool is_mc; /* see if any padding is done by the hw and remove it */ hdr = (struct ieee80211_hdr *) skb->data; - is_mc = !!is_multicast_ether_addr(hdr->addr1); hdrlen = ieee80211_get_hdrlen_from_skb(skb); fc = hdr->frame_control; padpos = ath9k_cmn_padpos(hdr->frame_control); @@ -1074,7 +1072,7 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, keyix = rx_stats->rs_keyix; - if ((is_mc || !(keyix == ATH9K_RXKEYIX_INVALID)) && !decrypt_error && + if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error && ieee80211_has_protected(fc)) { rxs->flag |= RX_FLAG_DECRYPTED; } else if (ieee80211_has_protected(fc) From 6d20e8406f0942228a73000663c2b33f488103ea Mon Sep 17 00:00:00 2001 From: Suresh Jayaraman Date: Wed, 1 Dec 2010 14:42:28 +0530 Subject: [PATCH 079/300] cifs: add attribute cache timeout (actimeo) tunable Currently, the attribute cache timeout for CIFS is hardcoded to 1 second. This means that the client might have to issue a QPATHINFO/QFILEINFO call every 1 second to verify if something has changes, which seems too expensive. On the other hand, if the timeout is hardcoded to a higher value, workloads that expect strict cache coherency might see unexpected results. Making attribute cache timeout as a tunable will allow us to make a tradeoff between performance and cache metadata correctness depending on the application/workload needs. Add 'actimeo' tunable that can be used to tune the attribute cache timeout. The default timeout is set to 1 second. Also, display actimeo option value in /proc/mounts. It appears to me that 'actimeo' and the proposed (but not yet merged) 'strictcache' option cannot coexist, so care must be taken that we reset the other option if one of them is set. Changes since last post: - fix option parsing and handle possible values correcly Reviewed-by: Jeff Layton Signed-off-by: Suresh Jayaraman Signed-off-by: Steve French --- fs/cifs/README | 9 +++++++++ fs/cifs/cifs_fs_sb.h | 1 + fs/cifs/cifsfs.c | 2 ++ fs/cifs/cifsglob.h | 10 ++++++++++ fs/cifs/connect.c | 15 +++++++++++++++ fs/cifs/inode.c | 7 ++++--- 6 files changed, 41 insertions(+), 3 deletions(-) diff --git a/fs/cifs/README b/fs/cifs/README index ee68d1036544..46af99ab3614 100644 --- a/fs/cifs/README +++ b/fs/cifs/README @@ -337,6 +337,15 @@ A partial list of the supported mount options follows: wsize default write size (default 57344) maximum wsize currently allowed by CIFS is 57344 (fourteen 4096 byte pages) + actimeo=n attribute cache timeout in seconds (default 1 second). + After this timeout, the cifs client requests fresh attribute + information from the server. This option allows to tune the + attribute cache timeout to suit the workload needs. Shorter + timeouts mean better the cache coherency, but increased number + of calls to the server. Longer timeouts mean reduced number + of calls to the server at the expense of less stricter cache + coherency checks (i.e. incorrect attribute cache for a short + period of time). rw mount the network share read-write (note that the server may still consider the share read-only) ro mount network share read-only diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index e9a393c9c2ca..7852cd677051 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -48,6 +48,7 @@ struct cifs_sb_info { struct nls_table *local_nls; unsigned int rsize; unsigned int wsize; + unsigned long actimeo; /* attribute cache timeout (jiffies) */ atomic_t active; uid_t mnt_uid; gid_t mnt_gid; diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 76c8a906a63e..56a4b7544c3c 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -463,6 +463,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) seq_printf(s, ",rsize=%d", cifs_sb->rsize); seq_printf(s, ",wsize=%d", cifs_sb->wsize); + /* convert actimeo and display it in seconds */ + seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); return 0; } diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index b577bf0a1bb3..94ccfacaed8a 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -44,6 +44,16 @@ #define CIFS_MIN_RCV_POOL 4 +/* + * default attribute cache timeout (jiffies) + */ +#define CIFS_DEF_ACTIMEO (1 * HZ) + +/* + * max attribute cache timeout (jiffies) - 2^30 + */ +#define CIFS_MAX_ACTIMEO (1 << 30) + /* * MAX_REQ is the maximum number of requests that WE will send * on one socket concurrently. It also matches the most common diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 32fa4d9b5dbc..bb17ee2ba782 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -105,6 +105,7 @@ struct smb_vol { unsigned int wsize; bool sockopt_tcp_nodelay:1; unsigned short int port; + unsigned long actimeo; /* attribute cache timeout (jiffies) */ char *prepath; struct sockaddr_storage srcaddr; /* allow binding to a local IP */ struct nls_table *local_nls; @@ -840,6 +841,8 @@ cifs_parse_mount_options(char *options, const char *devname, /* default to using server inode numbers where available */ vol->server_ino = 1; + vol->actimeo = CIFS_DEF_ACTIMEO; + if (!options) return 1; @@ -1214,6 +1217,16 @@ cifs_parse_mount_options(char *options, const char *devname, printk(KERN_WARNING "CIFS: server net" "biosname longer than 15 truncated.\n"); } + } else if (strnicmp(data, "actimeo", 7) == 0) { + if (value && *value) { + vol->actimeo = HZ * simple_strtoul(value, + &value, 0); + if (vol->actimeo > CIFS_MAX_ACTIMEO) { + cERROR(1, "CIFS: attribute cache" + "timeout too large"); + return 1; + } + } } else if (strnicmp(data, "credentials", 4) == 0) { /* ignore */ } else if (strnicmp(data, "version", 3) == 0) { @@ -2571,6 +2584,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, cFYI(1, "file mode: 0x%x dir mode: 0x%x", cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode); + cifs_sb->actimeo = pvolume_info->actimeo; + if (pvolume_info->noperm) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; if (pvolume_info->setuids) diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 28cb6e735943..bb5ca4848e81 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1653,6 +1653,7 @@ static bool cifs_inode_needs_reval(struct inode *inode) { struct cifsInodeInfo *cifs_i = CIFS_I(inode); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); if (cifs_i->clientCanCacheRead) return false; @@ -1663,12 +1664,12 @@ cifs_inode_needs_reval(struct inode *inode) if (cifs_i->time == 0) return true; - /* FIXME: the actimeo should be tunable */ - if (time_after_eq(jiffies, cifs_i->time + HZ)) + if (!time_in_range(jiffies, cifs_i->time, + cifs_i->time + cifs_sb->actimeo)) return true; /* hardlinked files w/ noserverino get "special" treatment */ - if (!(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && + if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && S_ISREG(inode->i_mode) && inode->i_nlink != 1) return true; From f8e9616108c7003e6499c162459258f11c9dc85e Mon Sep 17 00:00:00 2001 From: Vlad Lungu Date: Mon, 29 Nov 2010 22:52:52 +0000 Subject: [PATCH 080/300] stmmac: priv->lock can be used uninitialized To reproduce: if connman (http://connman.net/) is started, inserting the stmmac module triggers a "BUG: spinlock bad magic on CPU#0". Registering the device in stmmac_probe() sends a notification to connman which brings the interface up before the lock is initialized. Signed-off-by: Vlad Lungu Signed-off-by: David S. Miller --- drivers/net/stmmac/stmmac_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 06bc6034ce81..2114837809e7 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -1509,6 +1509,8 @@ static int stmmac_probe(struct net_device *dev) pr_warning("\tno valid MAC address;" "please, use ifconfig or nwhwconfig!\n"); + spin_lock_init(&priv->lock); + ret = register_netdev(dev); if (ret) { pr_err("%s: ERROR %i registering the device\n", @@ -1520,8 +1522,6 @@ static int stmmac_probe(struct net_device *dev) dev->name, (dev->features & NETIF_F_SG) ? "on" : "off", (dev->features & NETIF_F_HW_CSUM) ? "on" : "off"); - spin_lock_init(&priv->lock); - return ret; } From e7dfc8dbdf9a7fa1ef04c63100a71f4102b82ed3 Mon Sep 17 00:00:00 2001 From: "Alexander V. Lukyanov" Date: Tue, 30 Nov 2010 03:57:39 +0000 Subject: [PATCH 081/300] tulip: fix hang in dmfe driver on sending of big packet This patch fixes hang in dmfe driver on attempt of sending a big packet. Without this patch the code stops the queue and never wakes it again. Signed-off-by: Alexander V. Lukyanov Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/tulip/dmfe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index a9f7d5d1a269..7064e035757a 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -688,9 +688,6 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb, DMFE_DBUG(0, "dmfe_start_xmit", 0); - /* Resource flag check */ - netif_stop_queue(dev); - /* Too large packet check */ if (skb->len > MAX_PACKET_SIZE) { pr_err("big packet = %d\n", (u16)skb->len); @@ -698,6 +695,9 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } + /* Resource flag check */ + netif_stop_queue(dev); + spin_lock_irqsave(&db->lock, flags); /* No Tx resource check, it never happen nromally */ From 220cad3cbf553f893432919b458da36489373fc6 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Nov 2010 09:32:58 +0800 Subject: [PATCH 082/300] drm/i915: Always set the DP transcoder config to 8BPC. The pipe is always set to 8BPC, but here we were leaving whatever previous bits were set by the BIOS in place. Signed-off-by: Eric Anholt Tested-by: Keith Packard Signed-off-by: Chris Wilson Cc: stable@kernel.org --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_display.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 25ed911a3112..878fc766a12c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3033,6 +3033,7 @@ #define TRANS_DP_10BPC (1<<9) #define TRANS_DP_6BPC (2<<9) #define TRANS_DP_12BPC (3<<9) +#define TRANS_DP_BPC_MASK (3<<9) #define TRANS_DP_VSYNC_ACTIVE_HIGH (1<<4) #define TRANS_DP_VSYNC_ACTIVE_LOW 0 #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 255b52ee0091..9d3af3cb5a0b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2120,9 +2120,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) reg = TRANS_DP_CTL(pipe); temp = I915_READ(reg); temp &= ~(TRANS_DP_PORT_SEL_MASK | - TRANS_DP_SYNC_MASK); + TRANS_DP_SYNC_MASK | + TRANS_DP_BPC_MASK); temp |= (TRANS_DP_OUTPUT_ENABLE | TRANS_DP_ENH_FRAMING); + temp |= TRANS_DP_8BPC; if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; From 5bddd17fec58f253cddd0bc9eab2cd9eb1bbab4a Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Nov 2010 09:32:59 +0800 Subject: [PATCH 083/300] drm/i915: Apply a workaround for transitioning from DP on pipe B to HDMI. This workaround only applies to Ironlake. Signed-off-by: Eric Anholt Signed-off-by: Chris Wilson Cc: stable@kernel.org --- drivers/gpu/drm/i915/intel_dp.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 300f64b4238b..1d8d068bc473 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1374,6 +1374,7 @@ intel_dp_link_down(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); uint32_t DP = intel_dp->DP; DRM_DEBUG_KMS("\n"); @@ -1398,6 +1399,26 @@ intel_dp_link_down(struct intel_dp *intel_dp) if (is_edp(intel_dp)) DP |= DP_LINK_TRAIN_OFF; + + if (!HAS_PCH_CPT(dev) && (DP & DP_PIPEB_SELECT)) { + /* Hardware workaround: leaving our transcoder select + * set to transcoder B while it's off will prevent the + * corresponding HDMI output on transcoder A. + * + * Combine this with another hardware workaround: + * transcoder select bit can only be cleared while the + * port is enabled. + */ + DP &= ~DP_PIPEB_SELECT; + I915_WRITE(intel_dp->output_reg, DP); + + /* Changes to enable or select take place the vblank + * after being written. + */ + intel_wait_for_vblank(intel_dp->base.base.dev, + intel_crtc->pipe); + } + I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); POSTING_READ(intel_dp->output_reg); } From 9f5ead76d402f591ab810e71eae59ec28bf39eb9 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 1 Dec 2010 10:55:46 +0000 Subject: [PATCH 084/300] omap: PM debug: fix wake-on-timer debugfs dependency Wakeup-on-timer code does not have/need debugfs dependency. Move the function out of debugfs ifdef. Fixes compile error when CONFIG_DEBUG_FS is disabled but PM debug is enabled. Reported-by: Tony Lindgren Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/pm-debug.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 5e81517a7af2..a8afb610c7d8 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -161,6 +161,23 @@ void omap2_pm_dump(int mode, int resume, unsigned int us) printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val); } +void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds) +{ + u32 tick_rate, cycles; + + if (!seconds && !milliseconds) + return; + + tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); + cycles = tick_rate * seconds + tick_rate * milliseconds / 1000; + omap_dm_timer_stop(gptimer_wakeup); + omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); + + pr_info("PM: Resume timer in %u.%03u secs" + " (%d ticks at %d ticks/sec.)\n", + seconds, milliseconds, cycles, tick_rate); +} + #ifdef CONFIG_DEBUG_FS #include #include @@ -354,23 +371,6 @@ void pm_dbg_update_time(struct powerdomain *pwrdm, int prev) pwrdm->timer = t; } -void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds) -{ - u32 tick_rate, cycles; - - if (!seconds && !milliseconds) - return; - - tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); - cycles = tick_rate * seconds + tick_rate * milliseconds / 1000; - omap_dm_timer_stop(gptimer_wakeup); - omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); - - pr_info("PM: Resume timer in %u.%03u secs" - " (%d ticks at %d ticks/sec.)\n", - seconds, milliseconds, cycles, tick_rate); -} - static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user) { struct seq_file *s = (struct seq_file *)user; From cbeae41888bddb2d8c23db281de5f38f4be6a9bb Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 2 Nov 2010 09:12:57 +0800 Subject: [PATCH 085/300] dma: imx-dma: fix imxdma_probe error path otherwise, i will be -1 inside the latest iteration of the while loop. Signed-off-by: Axel Lin Acked-by: Sascha Hauer Signed-off-by: Dan Williams --- drivers/dma/imx-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index f629e4961af5..e53d438142bb 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -379,7 +379,7 @@ static int __init imxdma_probe(struct platform_device *pdev) return 0; err_init: - while (i-- >= 0) { + while (--i >= 0) { struct imxdma_channel *imxdmac = &imxdma->channel[i]; imx_dma_free(imxdmac->imxdma_channel); } From 51a1efe2e84493439db32c07471e835c752a7923 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 2 Nov 2010 09:52:17 +0800 Subject: [PATCH 086/300] dma: intel_mid_dma: fix double free on mid_setup_dma error path We should not call kfree(dma) in mid_setup_dma error path because the memory is allocated in intel_mid_dma_probe and will be freed in intel_mid_dma_probe error path if mid_setup_dma return error. Signed-off-by: Axel Lin Signed-off-by: Dan Williams --- drivers/dma/intel_mid_dma.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c index 338bc4eed1f3..4c55d451b613 100644 --- a/drivers/dma/intel_mid_dma.c +++ b/drivers/dma/intel_mid_dma.c @@ -1075,7 +1075,6 @@ static int mid_setup_dma(struct pci_dev *pdev) if (NULL == dma->dma_pool) { pr_err("ERR_MDMA:pci_pool_create failed\n"); err = -ENOMEM; - kfree(dma); goto err_dma_pool; } @@ -1186,7 +1185,6 @@ err_engine: free_irq(pdev->irq, dma); err_irq: pci_pool_destroy(dma->dma_pool); - kfree(dma); err_dma_pool: pr_err("ERR_MDMA:setup_dma failed: %d\n", err); return err; From 87e51107323a84e26a5004337217fc954e8d9545 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sat, 6 Nov 2010 17:01:36 -0400 Subject: [PATCH 087/300] drivers/dma/: Use the ccflag-y instead of EXTRA_CFLAGS Use the ccflag-y flag instead of EXTRA_CFLAGS because EXTRA_CFLAGS is deprecated and should now be switched. According to (documentation/kbuild/makefiles.txt). Signed-off-by: Tracey Dent Acked-by: Linus Walleij Signed-off-by: Andrew Morton Signed-off-by: Dan Williams --- drivers/dma/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index a8a84f4587f2..64b21f5cd740 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -1,8 +1,8 @@ ifeq ($(CONFIG_DMADEVICES_DEBUG),y) - EXTRA_CFLAGS += -DDEBUG + ccflags-y += -DDEBUG endif ifeq ($(CONFIG_DMADEVICES_VDEBUG),y) - EXTRA_CFLAGS += -DVERBOSE_DEBUG + ccflags-y += -DVERBOSE_DEBUG endif obj-$(CONFIG_DMA_ENGINE) += dmaengine.o From 77c4d5cdb81d25a45fbdfb84dd3348121219a072 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Thu, 2 Dec 2010 22:45:45 -0500 Subject: [PATCH 088/300] ALSA: hda: Use model=lg quirk for LG P1 Express to enable playback and capture BugLink: https://launchpad.net/bugs/595482 The original reporter states that audible playback from the internal speaker is inaudible despite the hardware being properly detected. To work around this symptom, he uses the model=lg quirk to properly enable both playback, capture, and jack sense. Another user corroborates this workaround on separate hardware. Add this PCI SSID to the quirk table to enable it for further LG P1 Expresses. Reported-and-tested-by: Philip Peitsch Tested-by: nikhov Cc: [2.6.32+] Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8fddc9d08726..2d7d7de8498a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4595,6 +4595,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), + SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG), SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), From 3a253445e327d0295bbe51bcbec5f44f86b54a8c Mon Sep 17 00:00:00 2001 From: John Baboval Date: Thu, 2 Dec 2010 11:21:31 -0500 Subject: [PATCH 089/300] ALSA: hda - Fix ThinkPad T410[s] docking station line-out On the docking station for the Lenovo T410 and T410s, the line-out doesn't work. The trouble seems to be that it generates a plug event, but then doesn't report that the jack is connected. So automute mutes the jack when you plug something into it. The following patch (next message) fixes it. Signed-off-by: John Baboval Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 846d1ead47fd..e652b34b1bd9 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -2116,8 +2116,8 @@ static void cxt5066_update_speaker(struct hda_codec *codec) struct conexant_spec *spec = codec->spec; unsigned int pinctl; - snd_printdd("CXT5066: update speaker, hp_present=%d\n", - spec->hp_present); + snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n", + spec->hp_present, spec->cur_eapd); /* Port A (HP) */ pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0; @@ -2125,11 +2125,20 @@ static void cxt5066_update_speaker(struct hda_codec *codec) pinctl); /* Port D (HP/LO) */ - pinctl = ((spec->hp_present & 2) && spec->cur_eapd) - ? spec->port_d_mode : 0; - /* Mute if Port A is connected on Thinkpad */ - if (spec->thinkpad && (spec->hp_present & 1)) - pinctl = 0; + if (spec->dell_automute) { + /* DELL AIO Port Rule: PortA> PortD> IntSpk */ + pinctl = (!(spec->hp_present & 1) && spec->cur_eapd) + ? PIN_OUT : 0; + } else if (spec->thinkpad) { + if (spec->cur_eapd) + pinctl = spec->port_d_mode; + /* Mute dock line-out if Port A (laptop HP) is present */ + if (spec->hp_present& 1) + pinctl = 0; + } else { + pinctl = ((spec->hp_present & 2) && spec->cur_eapd) + ? spec->port_d_mode : 0; + } snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); @@ -2137,14 +2146,6 @@ static void cxt5066_update_speaker(struct hda_codec *codec) pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); - - if (spec->dell_automute) { - /* DELL AIO Port Rule: PortA > PortD > IntSpk */ - pinctl = (!(spec->hp_present & 1) && spec->cur_eapd) - ? PIN_OUT : 0; - snd_hda_codec_write(codec, 0x1c, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); - } } /* turn on/off EAPD (+ mute HP) as a master switch */ From 47f1c6c9ffdec0c0e5a2c2709bd63c7380b325c4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 3 Dec 2010 15:37:31 +0000 Subject: [PATCH 090/300] drm/i915: Clean conflicting modesetting registers upon init If we leave the registers in a conflicting state then when we attempt to teardown the active mode, we will not disable the pipes and planes in the correct order -- leaving a plane reading from a disabled pipe and possibly leading to undefined behaviour. Reported-and-tested-by: Andy Whitcroft Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=32078 Signed-off-by: Chris Wilson Cc: stable@kernel.org --- drivers/gpu/drm/i915/intel_display.c | 51 ++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 9d3af3cb5a0b..e5badadbdcd2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5238,6 +5238,55 @@ static const struct drm_crtc_funcs intel_crtc_funcs = { .page_flip = intel_crtc_page_flip, }; +static void intel_sanitize_modesetting(struct drm_device *dev, + int pipe, int plane) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + u32 reg, val; + + if (HAS_PCH_SPLIT(dev)) + return; + + /* Who knows what state these registers were left in by the BIOS or + * grub? + * + * If we leave the registers in a conflicting state (e.g. with the + * display plane reading from the other pipe than the one we intend + * to use) then when we attempt to teardown the active mode, we will + * not disable the pipes and planes in the correct order -- leaving + * a plane reading from a disabled pipe and possibly leading to + * undefined behaviour. + */ + + reg = DSPCNTR(plane); + val = I915_READ(reg); + + if ((val & DISPLAY_PLANE_ENABLE) == 0) + return; + if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe) + return; + + /* This display plane is active and attached to the other CPU pipe. */ + pipe = !pipe; + + /* Disable the plane and wait for it to stop reading from the pipe. */ + I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE); + intel_flush_display_plane(dev, plane); + + if (IS_GEN2(dev)) + intel_wait_for_vblank(dev, pipe); + + if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) + return; + + /* Switch off the pipe. */ + reg = PIPECONF(pipe); + val = I915_READ(reg); + if (val & PIPECONF_ENABLE) { + I915_WRITE(reg, val & ~PIPECONF_ENABLE); + intel_wait_for_pipe_off(dev, pipe); + } +} static void intel_crtc_init(struct drm_device *dev, int pipe) { @@ -5289,6 +5338,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, (unsigned long)intel_crtc); + + intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); } int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, From 2e18edf75d586d9044c1f1e6b1bc8e7c26c4149f Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 3 Dec 2010 18:00:06 +0000 Subject: [PATCH 091/300] ARM: mini2440: Fix Kconfig to allow kernel to build The MACH_MINI2440 entry requires the backlight LED driver, but this subsystem has not been enabled and the select of LEDS_TRIGGER_BACKLIGHT alone is insufficient to enable the necessary bits of the LED driver. Add NEW_LEDS, LEDS_CLASS and LEDS_TRIGGER to the select to allow the kernel to link. This fixes the following error: drivers/built-in.o: In function `led_trigger_set': /home/ben/linux.git/drivers/leds/led-triggers.c:116: undefined reference to `led_brightness_set' Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2440/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig index ff024a6c0f85..adea6b924cf1 100644 --- a/arch/arm/mach-s3c2440/Kconfig +++ b/arch/arm/mach-s3c2440/Kconfig @@ -178,6 +178,9 @@ config MACH_MINI2440 bool "MINI2440 development board" select CPU_S3C2440 select EEPROM_AT24 + select NEW_LEDS + select LEDS_CLASS + select LEDS_TRIGGER select LEDS_TRIGGER_BACKLIGHT select S3C_DEV_NAND select S3C_DEV_USB_HOST From 22ed1113a9adda6e193c329119a384362da01289 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 4 Dec 2010 01:01:29 +0000 Subject: [PATCH 092/300] drm/i915: Death to the unnecessary 64bit divide Use the hardware DDA to calculate the ratio with as much accuracy as is possible. Signed-off-by: Chris Wilson Cc: stable@kernel.org --- drivers/gpu/drm/i915/intel_display.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e5badadbdcd2..fac118b2df7d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2714,27 +2714,19 @@ fdi_reduce_ratio(u32 *num, u32 *den) } } -#define DATA_N 0x800000 -#define LINK_N 0x80000 - static void ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, int link_clock, struct fdi_m_n *m_n) { - u64 temp; - m_n->tu = 64; /* default size */ - temp = (u64) DATA_N * pixel_clock; - temp = div_u64(temp, link_clock); - m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes); - m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */ - m_n->gmch_n = DATA_N; + /* BUG_ON(pixel_clock > INT_MAX / 36); */ + m_n->gmch_m = bits_per_pixel * pixel_clock; + m_n->gmch_n = link_clock * nlanes * 8; fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); - temp = (u64) LINK_N * pixel_clock; - m_n->link_m = div_u64(temp, link_clock); - m_n->link_n = LINK_N; + m_n->link_m = pixel_clock; + m_n->link_n = link_clock; fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); } From ef61d4e6d88da80dc2b417cf8ad3c77aa94f0c8f Mon Sep 17 00:00:00 2001 From: Manoj Iyer Date: Fri, 3 Dec 2010 18:43:55 -0600 Subject: [PATCH 093/300] ALSA: hda - Enable jack sense for Thinkpad Edge 13 Added a quirk to cxt5066_cfg_tbl to enable jack sense for ThinkPad Edge 13. Reference: http://launchpad.net/bugs/685015 Signed-off-by: Manoj Iyer Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index e652b34b1bd9..4ab5ea9f0530 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3110,6 +3110,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), + SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD), From 49078f7d108f132582e5af46304c317b55f83948 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 4 Dec 2010 07:45:57 +0000 Subject: [PATCH 094/300] drm/i915: Factor in pixel-repeat in FDI M/N calculation Fixes the modesetting on the secondary panel of the Libretto W100 and presumably many more Ironlake laptops with SDVO LVDS displays. Reported-and-tested-by: Matthew Willoughby Signed-off-by: Chris Wilson Cc: stable@kernel.org --- drivers/gpu/drm/i915/intel_display.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fac118b2df7d..d9b7092439ef 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3710,6 +3710,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* FDI link */ if (HAS_PCH_SPLIT(dev)) { + int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); int lane = 0, link_bw, bpp; /* CPU eDP doesn't require FDI link, so just set DP M/N according to current link config */ @@ -3793,6 +3794,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, intel_crtc->fdi_lanes = lane; + if (pixel_multiplier > 1) + link_bw *= pixel_multiplier; ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); } From bca364d30d63825f36a03dcacf390943d4c2cb74 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sat, 6 Nov 2010 17:01:37 -0400 Subject: [PATCH 095/300] drivers/dma/ioat: Use the ccflag-y instead of EXTRA_CFLAGS Changed Makefile to use -y instead of -objs. Following (documentation/kbuild/makefiles.txt). Signed-off-by: Tracey Dent Signed-off-by: Andrew Morton Signed-off-by: Dan Williams --- drivers/dma/ioat/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/ioat/Makefile b/drivers/dma/ioat/Makefile index 8997d3fb9051..0ff7270af25b 100644 --- a/drivers/dma/ioat/Makefile +++ b/drivers/dma/ioat/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o -ioatdma-objs := pci.o dma.o dma_v2.o dma_v3.o dca.o +ioatdma-y := pci.o dma.o dma_v2.o dma_v3.o dca.o From a584bff5efae8c1d026e3a930e3d13a90264fafc Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 12 Nov 2010 13:37:54 -0800 Subject: [PATCH 096/300] drivers/dma/ppc4xx: Use printf extension %pR for struct resource Using %pR standardizes the struct resource output. Signed-off-by: Joe Perches Signed-off-by: Dan Williams --- drivers/dma/ppc4xx/adma.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index 0d58a4a4487f..cef584533ee8 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -4449,9 +4449,8 @@ static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev, if (!request_mem_region(res.start, resource_size(&res), dev_driver_string(&ofdev->dev))) { - dev_err(&ofdev->dev, "failed to request memory region " - "(0x%016llx-0x%016llx)\n", - (u64)res.start, (u64)res.end); + dev_err(&ofdev->dev, "failed to request memory region %pR\n", + &res); initcode = PPC_ADMA_INIT_MEMREG; ret = -EBUSY; goto out; From d2f5c276ea4b7b7e1b953926bac9d0b148fcce4e Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 22 Nov 2010 18:35:18 +0100 Subject: [PATCH 097/300] dmaengine: imx-sdma: fix bug in buffer descriptor initialization Currently while submitting scatterlists with more than one SG entry the DMA buffer address from the first SG entry is inserted into all initialized DMA buffer descriptors. This is due to the typo in the for_each_sg() loop where the scatterlist pointer is used for obtaining the DMA buffer address and _not_ the SG list iterator. As a result all received data will be written only into the first DMA buffer while reading. While writing the data from the first DMA buffer is send to the device multiple times. This caused the filesystem destruction on the MMC card when using DMA in mxcmmc driver. Signed-off-by: Anatolij Gustschin Acked-by: Sascha Hauer Signed-off-by: Dan Williams --- drivers/dma/imx-sdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 0834323a0599..13d6447a35f6 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -951,7 +951,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( struct sdma_buffer_descriptor *bd = &sdmac->bd[i]; int param; - bd->buffer_addr = sgl->dma_address; + bd->buffer_addr = sg->dma_address; count = sg->length; From cf2f9c59807f173b1c6a537fde7c83c8da876e56 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 4 Dec 2010 14:53:32 -0800 Subject: [PATCH 098/300] intel_mid_dma: fix section mismatch warnings Rename intel_mid_dma_pci to intel_mid_dma_pci_driver to pick up the applied annotations of that suffix. Reported-by: Signed-off-by: Dan Williams --- drivers/dma/intel_mid_dma.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c index 4c55d451b613..3109bd94bc4f 100644 --- a/drivers/dma/intel_mid_dma.c +++ b/drivers/dma/intel_mid_dma.c @@ -1411,7 +1411,7 @@ static const struct dev_pm_ops intel_mid_dma_pm = { .runtime_idle = dma_runtime_idle, }; -static struct pci_driver intel_mid_dma_pci = { +static struct pci_driver intel_mid_dma_pci_driver = { .name = "Intel MID DMA", .id_table = intel_mid_dma_ids, .probe = intel_mid_dma_probe, @@ -1429,13 +1429,13 @@ static int __init intel_mid_dma_init(void) { pr_debug("INFO_MDMA: LNW DMA Driver Version %s\n", INTEL_MID_DMA_DRIVER_VERSION); - return pci_register_driver(&intel_mid_dma_pci); + return pci_register_driver(&intel_mid_dma_pci_driver); } fs_initcall(intel_mid_dma_init); static void __exit intel_mid_dma_exit(void) { - pci_unregister_driver(&intel_mid_dma_pci); + pci_unregister_driver(&intel_mid_dma_pci_driver); } module_exit(intel_mid_dma_exit); From 136711be41ec97f7f1a9c3a5e8535eb7da5fea59 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 4 Dec 2010 16:13:06 +0100 Subject: [PATCH 099/300] agp/intel: Fix wrong kunmap in i830_cleanup() Add a missing NULL check and fix the wrong address passed to kunmap() in i830_cleanup(). Cc: stable@kernel.org Signed-off-by: Takashi Iwai [danvet: added cc stable] Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 9272c38dd3c6..16a2847b7cdb 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -812,8 +812,10 @@ static int intel_fake_agp_fetch_size(void) static void i830_cleanup(void) { - kunmap(intel_private.i8xx_page); - intel_private.i8xx_flush_page = NULL; + if (intel_private.i8xx_flush_page) { + kunmap(intel_private.i8xx_flush_page); + intel_private.i8xx_flush_page = NULL; + } __free_page(intel_private.i8xx_page); intel_private.i8xx_page = NULL; From bbf0c6b3620b3872929ef7d3c392ce436889110f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 5 Dec 2010 11:30:40 +0100 Subject: [PATCH 100/300] drm/i915: announce to userspace that the bsd ring is coherent Otherwise we can't really fix the abi-braindeadness of forcing libva to manually wait for rendering when switching rings. Which in turn makes implementing hw semaphores a pointless exercise (at least for ironlake). [Also added the relaxed fencing param to explain the jump in numbering - relaxed fencing is in -next.] Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 3 +++ include/drm/i915_drm.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7a26f4dd21ae..e6800819bca8 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -767,6 +767,9 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_HAS_BLT: value = HAS_BLT(dev); break; + case I915_PARAM_HAS_COHERENT_RINGS: + value = 1; + break; default: DRM_DEBUG_DRIVER("Unknown parameter %d\n", param->param); diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 8c641bed9bbd..a2776e2807a4 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -287,6 +287,8 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_HAS_EXECBUF2 9 #define I915_PARAM_HAS_BSD 10 #define I915_PARAM_HAS_BLT 11 +#define I915_PARAM_HAS_RELAXED_FENCING 12 +#define I915_PARAM_HAS_COHERENT_RINGS 13 typedef struct drm_i915_getparam { int param; From 6fd0d56e3bc1abfb237b8824261b613e21e77bc8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 5 Dec 2010 20:42:33 +0000 Subject: [PATCH 101/300] drm/i915/ringbuffer: Only print an error on the second attempt to reset head There's not much we can do here but hope for the best. However the first failure happens quite frequently and if often remedied by the second attempt to reset HEAD. So only print the error if that attempt also fails. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=19802 Reported-by: Thomas Meyer Signed-off-by: Chris Wilson Cc: stable@kernel.org --- drivers/gpu/drm/i915/intel_ringbuffer.c | 30 +++++++++++++------------ 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b83306f9244b..89a65be8a3f3 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -156,23 +156,25 @@ static int init_ring_common(struct drm_device *dev, /* G45 ring initialization fails to reset head to zero */ if (head != 0) { - DRM_ERROR("%s head not reset to zero " - "ctl %08x head %08x tail %08x start %08x\n", - ring->name, - I915_READ_CTL(ring), - I915_READ_HEAD(ring), - I915_READ_TAIL(ring), - I915_READ_START(ring)); + DRM_DEBUG_KMS("%s head not reset to zero " + "ctl %08x head %08x tail %08x start %08x\n", + ring->name, + I915_READ_CTL(ring), + I915_READ_HEAD(ring), + I915_READ_TAIL(ring), + I915_READ_START(ring)); I915_WRITE_HEAD(ring, 0); - DRM_ERROR("%s head forced to zero " - "ctl %08x head %08x tail %08x start %08x\n", - ring->name, - I915_READ_CTL(ring), - I915_READ_HEAD(ring), - I915_READ_TAIL(ring), - I915_READ_START(ring)); + if (I915_READ_HEAD(ring) & HEAD_ADDR) { + DRM_ERROR("failed to set %s head to zero " + "ctl %08x head %08x tail %08x start %08x\n", + ring->name, + I915_READ_CTL(ring), + I915_READ_HEAD(ring), + I915_READ_TAIL(ring), + I915_READ_START(ring)); + } } I915_WRITE_CTL(ring, From 2a1292fd4cf1558b4a60781227d503c9111d9075 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 5 Dec 2010 19:21:18 +0000 Subject: [PATCH 102/300] drm/i915/lvds: Always restore panel-fitter when enabling the LVDS Linus Torvalds pointed out that our code was unbalanced when powering on the panel with respect to the power off sequence in that we were failing to restore the panel-fitter. The consequence of this would be that across a simple DPMS off/on for a non-native mode, without an intervening modeset, the panel fitter would remain disabled and the output would shift on the panel. Reported-by: Linus Torvalds Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_lvds.c | 100 ++++++++++++++++-------------- 1 file changed, 55 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index f79327fc6653..25bcedf386fd 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -68,7 +68,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) /** * Sets the power state for the panel. */ -static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on) +static void intel_lvds_enable(struct intel_lvds *intel_lvds) { struct drm_device *dev = intel_lvds->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -82,26 +82,61 @@ static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on) lvds_reg = LVDS; } - if (on) { - I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); - I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); - intel_panel_set_backlight(dev, dev_priv->backlight_level); - } else { - dev_priv->backlight_level = intel_panel_get_backlight(dev); + I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); - intel_panel_set_backlight(dev, 0); - I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); - - if (intel_lvds->pfit_control) { - if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) - DRM_ERROR("timed out waiting for panel to power off\n"); - I915_WRITE(PFIT_CONTROL, 0); - intel_lvds->pfit_control = 0; + if (intel_lvds->pfit_dirty) { + /* + * Enable automatic panel scaling so that non-native modes + * fill the screen. The panel fitter should only be + * adjusted whilst the pipe is disabled, according to + * register description and PRM. + */ + DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", + intel_lvds->pfit_control, + intel_lvds->pfit_pgm_ratios); + if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) { + DRM_ERROR("timed out waiting for panel to power off\n"); + } else { + I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); + I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); intel_lvds->pfit_dirty = false; } - - I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); } + + I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); + POSTING_READ(lvds_reg); + + intel_panel_set_backlight(dev, dev_priv->backlight_level); +} + +static void intel_lvds_disable(struct intel_lvds *intel_lvds) +{ + struct drm_device *dev = intel_lvds->base.base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 ctl_reg, lvds_reg; + + if (HAS_PCH_SPLIT(dev)) { + ctl_reg = PCH_PP_CONTROL; + lvds_reg = PCH_LVDS; + } else { + ctl_reg = PP_CONTROL; + lvds_reg = LVDS; + } + + dev_priv->backlight_level = intel_panel_get_backlight(dev); + intel_panel_set_backlight(dev, 0); + + I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); + + if (intel_lvds->pfit_control) { + if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) + DRM_ERROR("timed out waiting for panel to power off\n"); + + I915_WRITE(PFIT_CONTROL, 0); + intel_lvds->pfit_dirty = true; + } + + I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); POSTING_READ(lvds_reg); } @@ -110,9 +145,9 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) struct intel_lvds *intel_lvds = to_intel_lvds(encoder); if (mode == DRM_MODE_DPMS_ON) - intel_lvds_set_power(intel_lvds, true); + intel_lvds_enable(intel_lvds); else - intel_lvds_set_power(intel_lvds, false); + intel_lvds_disable(intel_lvds); /* XXX: We never power down the LVDS pairs. */ } @@ -411,43 +446,18 @@ static void intel_lvds_commit(struct drm_encoder *encoder) /* Always do a full power on as we do not know what state * we were left in. */ - intel_lvds_set_power(intel_lvds, true); + intel_lvds_enable(intel_lvds); } static void intel_lvds_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_lvds *intel_lvds = to_intel_lvds(encoder); - /* * The LVDS pin pair will already have been turned on in the * intel_crtc_mode_set since it has a large impact on the DPLL * settings. */ - - if (HAS_PCH_SPLIT(dev)) - return; - - if (!intel_lvds->pfit_dirty) - return; - - /* - * Enable automatic panel scaling so that non-native modes fill the - * screen. Should be enabled before the pipe is enabled, according to - * register description and PRM. - */ - DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", - intel_lvds->pfit_control, - intel_lvds->pfit_pgm_ratios); - if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) - DRM_ERROR("timed out waiting for panel to power off\n"); - - I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); - I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); - intel_lvds->pfit_dirty = false; } /** From dd5a089edfa51a74692604b4b427953d8e16bc35 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 5 Dec 2010 08:43:14 -0500 Subject: [PATCH 103/300] ALSA: hda: Use position_fix=1 for Acer Aspire 5538 to enable capture on internal mic BugLink: https://launchpad.net/bugs/685161 The reporter of the bug states that he must use position_fix=1 to enable capture for the internal microphone, so set it for his machine's PCI SSID. Verified using 2.6.35 and the 2010-12-04 alsa-driver build. Reported-and-tested-by: Ralph Wabel Cc: Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 21aa9b0e28f6..b030c8eba21f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2296,6 +2296,7 @@ static int azx_dev_free(struct snd_device *device) */ static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB), + SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB), SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), From 3fcc0afbb9c93f3599ba03273e59915670b6c2c2 Mon Sep 17 00:00:00 2001 From: Uk Kim Date: Sun, 5 Dec 2010 17:32:16 +0900 Subject: [PATCH 104/300] ASoC: Fix off by one error in WM8994 EQ register bank size Signed-off-by: Uk Kim Acked-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@kernel.org --- include/linux/mfd/wm8994/pdata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index 5c51f367c061..add8a1b8bcf0 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h @@ -29,7 +29,7 @@ struct wm8994_ldo_pdata { #define WM8994_CONFIGURE_GPIO 0x8000 #define WM8994_DRC_REGS 5 -#define WM8994_EQ_REGS 19 +#define WM8994_EQ_REGS 20 /** * DRC configurations are specified with a label and a set of register From ed8cc471d75365f8590c76f580def899d58028c0 Mon Sep 17 00:00:00 2001 From: Uk Kim Date: Sun, 5 Dec 2010 17:26:07 +0900 Subject: [PATCH 105/300] ASoC: Fix swap of left and right channels for WM8993/4 speaker boost gain SPKOUTL_BOOST start from third bit, SPKOUTLR_BOOST start from 0 bit. Signed-off-by: Uk Kim Acked-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@kernel.org --- sound/soc/codecs/wm_hubs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 19ca782ac970..0e24092722c3 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -293,7 +293,7 @@ SOC_DOUBLE_R("Speaker Switch", SOC_DOUBLE_R("Speaker ZC Switch", WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT, 7, 1, 0), -SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 0, 3, 7, 0, +SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0, spkboost_tlv), SOC_ENUM("Speaker Reference", speaker_ref), SOC_ENUM("Speaker Mode", speaker_mode), From 1dcb4f38e5bc28dfce0f8c7eef184a090b03bfc7 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 6 Dec 2010 16:48:03 +0800 Subject: [PATCH 106/300] ASoC: Hold client_mutex while calling snd_soc_instantiate_cards() As the comments of snd_soc_instantiate_cards() said, snd_soc_instantiate_cards() must be called with client_mutex. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 441285ade024..02ae7bea3b50 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3072,7 +3072,9 @@ int snd_soc_register_dais(struct device *dev, pr_debug("Registered DAI '%s'\n", dai->name); } + mutex_lock(&client_mutex); snd_soc_instantiate_cards(); + mutex_unlock(&client_mutex); return 0; err: From 18483b81ee7e70ee68d4b18be618be5cfcc0b290 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 6 Dec 2010 15:13:38 -0200 Subject: [PATCH 107/300] perf record: Fix eternal wait for stillborn child When execvp fails to find the specified command on the path we won't get SIGCHLD, so send a SIGUSR1 and exit right away. Current situation would require a SIGINT performed by the user and would produce meaningless summary. Now: [acme@emilia linux]$ ./foo -bash: ./foo: No such file or directory [acme@emilia linux]$ perf record ./foo ./foo: No such file or directory [acme@emilia linux]$ Acked-by: Thomas Gleixner Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Mike Galbraith Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Tom Zanussi Cc: Thomas Gleixner LKML-Reference: Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e2c2de201eec..564491fa18b2 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -197,7 +197,7 @@ static void sig_atexit(void) if (child_pid > 0) kill(child_pid, SIGTERM); - if (signr == -1) + if (signr == -1 || signr == SIGUSR1) return; signal(signr, SIG_DFL); @@ -515,6 +515,7 @@ static int __cmd_record(int argc, const char **argv) atexit(sig_atexit); signal(SIGCHLD, sig_handler); signal(SIGINT, sig_handler); + signal(SIGUSR1, sig_handler); if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { perror("failed to create pipes"); @@ -606,6 +607,7 @@ static int __cmd_record(int argc, const char **argv) execvp(argv[0], (char **)argv); perror(argv[0]); + kill(getppid(), SIGUSR1); exit(-1); } @@ -762,7 +764,7 @@ static int __cmd_record(int argc, const char **argv) } } - if (quiet) + if (quiet || signr == SIGUSR1) return 0; fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); From 46bcf14f44d8f31ecfdc8b6708ec15a3b33316d9 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 6 Dec 2010 09:29:43 -0800 Subject: [PATCH 108/300] filter: fix sk_filter rcu handling Pavel Emelyanov tried to fix a race between sk_filter_(de|at)tach and sk_clone() in commit 47e958eac280c263397 Problem is we can have several clones sharing a common sk_filter, and these clones might want to sk_filter_attach() their own filters at the same time, and can overwrite old_filter->rcu, corrupting RCU queues. We can not use filter->rcu without being sure no other thread could do the same thing. Switch code to a more conventional ref-counting technique : Do the atomic decrement immediately and queue one rcu call back when last reference is released. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/sock.h | 4 +++- net/core/filter.c | 19 ++++++------------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index a6338d039857..659d968d95c5 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1155,6 +1155,8 @@ extern void sk_common_release(struct sock *sk); /* Initialise core socket variables */ extern void sock_init_data(struct socket *sock, struct sock *sk); +extern void sk_filter_release_rcu(struct rcu_head *rcu); + /** * sk_filter_release - release a socket filter * @fp: filter to remove @@ -1165,7 +1167,7 @@ extern void sock_init_data(struct socket *sock, struct sock *sk); static inline void sk_filter_release(struct sk_filter *fp) { if (atomic_dec_and_test(&fp->refcnt)) - kfree(fp); + call_rcu_bh(&fp->rcu, sk_filter_release_rcu); } static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp) diff --git a/net/core/filter.c b/net/core/filter.c index c1ee800bc080..ae21a0d3c4a2 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -589,23 +589,16 @@ int sk_chk_filter(struct sock_filter *filter, int flen) EXPORT_SYMBOL(sk_chk_filter); /** - * sk_filter_rcu_release - Release a socket filter by rcu_head + * sk_filter_release_rcu - Release a socket filter by rcu_head * @rcu: rcu_head that contains the sk_filter to free */ -static void sk_filter_rcu_release(struct rcu_head *rcu) +void sk_filter_release_rcu(struct rcu_head *rcu) { struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); - sk_filter_release(fp); -} - -static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp) -{ - unsigned int size = sk_filter_len(fp); - - atomic_sub(size, &sk->sk_omem_alloc); - call_rcu_bh(&fp->rcu, sk_filter_rcu_release); + kfree(fp); } +EXPORT_SYMBOL(sk_filter_release_rcu); /** * sk_attach_filter - attach a socket filter @@ -649,7 +642,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) rcu_assign_pointer(sk->sk_filter, fp); if (old_fp) - sk_filter_delayed_uncharge(sk, old_fp); + sk_filter_uncharge(sk, old_fp); return 0; } EXPORT_SYMBOL_GPL(sk_attach_filter); @@ -663,7 +656,7 @@ int sk_detach_filter(struct sock *sk) sock_owned_by_user(sk)); if (filter) { rcu_assign_pointer(sk->sk_filter, NULL); - sk_filter_delayed_uncharge(sk, filter); + sk_filter_uncharge(sk, filter); ret = 0; } return ret; From 1cd275f609ba46c8cae3ee77e499c54a0d13a983 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 6 Dec 2010 09:45:22 -0800 Subject: [PATCH 109/300] ceph: fix ioctl magic The ioctl magic was inadvertently changed in 571dba52. Signed-off-by: Sage Weil --- fs/ceph/ioctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ceph/ioctl.h b/fs/ceph/ioctl.h index a6ce54e94eb5..52e8fd74d450 100644 --- a/fs/ceph/ioctl.h +++ b/fs/ceph/ioctl.h @@ -4,7 +4,7 @@ #include #include -#define CEPH_IOCTL_MAGIC 0x98 +#define CEPH_IOCTL_MAGIC 0x97 /* just use u64 to align sanely on all archs */ struct ceph_ioctl_layout { From 79df1baeec29022e4181f2964187b88661ef5517 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 6 Dec 2010 12:52:08 -0500 Subject: [PATCH 110/300] cifs: fix use of CONFIG_CIFS_ACL Some of the code under CONFIG_CIFS_ACL is dependent upon code under CONFIG_CIFS_EXPERIMENTAL, but the Kconfig options don't reflect that dependency. Move more of the ACL code out from under CONFIG_CIFS_EXPERIMENTAL and under CONFIG_CIFS_ACL. Also move find_readable_file out from other any sort of Kconfig option and make it a function normally compiled in. Reported-and-Acked-by: Randy Dunlap Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/Makefile | 4 +- fs/cifs/cifsacl.c | 3 - fs/cifs/cifsacl.h | 4 - fs/cifs/cifsproto.h | 2 - fs/cifs/cifssmb.c | 183 ++++++++++++++++++++++---------------------- fs/cifs/file.c | 2 - fs/cifs/inode.c | 8 +- 7 files changed, 99 insertions(+), 107 deletions(-) diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile index adefa60a9bdc..43b19dd39191 100644 --- a/fs/cifs/Makefile +++ b/fs/cifs/Makefile @@ -6,7 +6,9 @@ obj-$(CONFIG_CIFS) += cifs.o cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \ md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \ - readdir.o ioctl.o sess.o export.o cifsacl.o + readdir.o ioctl.o sess.o export.o + +cifs-$(CONFIG_CIFS_ACL) += cifsacl.o cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index c6ebea088ac7..a437ec391a01 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -30,8 +30,6 @@ #include "cifs_debug.h" -#ifdef CONFIG_CIFS_EXPERIMENTAL - static struct cifs_wksid wksidarr[NUM_WK_SIDS] = { {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"}, {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"}, @@ -774,4 +772,3 @@ int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode) return rc; } -#endif /* CONFIG_CIFS_EXPERIMENTAL */ diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h index 6c8096cf5155..c4ae7d036563 100644 --- a/fs/cifs/cifsacl.h +++ b/fs/cifs/cifsacl.h @@ -74,11 +74,7 @@ struct cifs_wksid { char sidname[SIDNAMELENGTH]; } __attribute__((packed)); -#ifdef CONFIG_CIFS_EXPERIMENTAL - extern int match_sid(struct cifs_sid *); extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *); -#endif /* CONFIG_CIFS_EXPERIMENTAL */ - #endif /* _CIFSACL_H */ diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index db961dc4fd3d..5523047b1ebd 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -79,9 +79,7 @@ extern bool is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *); extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool); -#ifdef CONFIG_CIFS_EXPERIMENTAL extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool); -#endif extern unsigned int smbCalcSize(struct smb_hdr *ptr); extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); extern int decode_negTokenInit(unsigned char *security_blob, int length, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 2f2632b6df5a..67acfb3acad2 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -2478,95 +2478,6 @@ querySymLinkRetry: } #ifdef CONFIG_CIFS_EXPERIMENTAL -/* Initialize NT TRANSACT SMB into small smb request buffer. - This assumes that all NT TRANSACTS that we init here have - total parm and data under about 400 bytes (to fit in small cifs - buffer size), which is the case so far, it easily fits. NB: - Setup words themselves and ByteCount - MaxSetupCount (size of returned setup area) and - MaxParameterCount (returned parms size) must be set by caller */ -static int -smb_init_nttransact(const __u16 sub_command, const int setup_count, - const int parm_len, struct cifsTconInfo *tcon, - void **ret_buf) -{ - int rc; - __u32 temp_offset; - struct smb_com_ntransact_req *pSMB; - - rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, - (void **)&pSMB); - if (rc) - return rc; - *ret_buf = (void *)pSMB; - pSMB->Reserved = 0; - pSMB->TotalParameterCount = cpu_to_le32(parm_len); - pSMB->TotalDataCount = 0; - pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf - - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); - pSMB->ParameterCount = pSMB->TotalParameterCount; - pSMB->DataCount = pSMB->TotalDataCount; - temp_offset = offsetof(struct smb_com_ntransact_req, Parms) + - (setup_count * 2) - 4 /* for rfc1001 length itself */; - pSMB->ParameterOffset = cpu_to_le32(temp_offset); - pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len); - pSMB->SetupCount = setup_count; /* no need to le convert byte fields */ - pSMB->SubCommand = cpu_to_le16(sub_command); - return 0; -} - -static int -validate_ntransact(char *buf, char **ppparm, char **ppdata, - __u32 *pparmlen, __u32 *pdatalen) -{ - char *end_of_smb; - __u32 data_count, data_offset, parm_count, parm_offset; - struct smb_com_ntransact_rsp *pSMBr; - - *pdatalen = 0; - *pparmlen = 0; - - if (buf == NULL) - return -EINVAL; - - pSMBr = (struct smb_com_ntransact_rsp *)buf; - - /* ByteCount was converted from little endian in SendReceive */ - end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount + - (char *)&pSMBr->ByteCount; - - data_offset = le32_to_cpu(pSMBr->DataOffset); - data_count = le32_to_cpu(pSMBr->DataCount); - parm_offset = le32_to_cpu(pSMBr->ParameterOffset); - parm_count = le32_to_cpu(pSMBr->ParameterCount); - - *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; - *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; - - /* should we also check that parm and data areas do not overlap? */ - if (*ppparm > end_of_smb) { - cFYI(1, "parms start after end of smb"); - return -EINVAL; - } else if (parm_count + *ppparm > end_of_smb) { - cFYI(1, "parm end after end of smb"); - return -EINVAL; - } else if (*ppdata > end_of_smb) { - cFYI(1, "data starts after end of smb"); - return -EINVAL; - } else if (data_count + *ppdata > end_of_smb) { - cFYI(1, "data %p + count %d (%p) past smb end %p start %p", - *ppdata, data_count, (data_count + *ppdata), - end_of_smb, pSMBr); - return -EINVAL; - } else if (parm_count + data_count > pSMBr->ByteCount) { - cFYI(1, "parm count and data count larger than SMB"); - return -EINVAL; - } - *pdatalen = data_count; - *pparmlen = parm_count; - return 0; -} - int CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, @@ -3056,7 +2967,97 @@ GetExtAttrOut: #endif /* CONFIG_POSIX */ -#ifdef CONFIG_CIFS_EXPERIMENTAL +#ifdef CONFIG_CIFS_ACL +/* + * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that + * all NT TRANSACTS that we init here have total parm and data under about 400 + * bytes (to fit in small cifs buffer size), which is the case so far, it + * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of + * returned setup area) and MaxParameterCount (returned parms size) must be set + * by caller + */ +static int +smb_init_nttransact(const __u16 sub_command, const int setup_count, + const int parm_len, struct cifsTconInfo *tcon, + void **ret_buf) +{ + int rc; + __u32 temp_offset; + struct smb_com_ntransact_req *pSMB; + + rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, + (void **)&pSMB); + if (rc) + return rc; + *ret_buf = (void *)pSMB; + pSMB->Reserved = 0; + pSMB->TotalParameterCount = cpu_to_le32(parm_len); + pSMB->TotalDataCount = 0; + pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf - + MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); + pSMB->ParameterCount = pSMB->TotalParameterCount; + pSMB->DataCount = pSMB->TotalDataCount; + temp_offset = offsetof(struct smb_com_ntransact_req, Parms) + + (setup_count * 2) - 4 /* for rfc1001 length itself */; + pSMB->ParameterOffset = cpu_to_le32(temp_offset); + pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len); + pSMB->SetupCount = setup_count; /* no need to le convert byte fields */ + pSMB->SubCommand = cpu_to_le16(sub_command); + return 0; +} + +static int +validate_ntransact(char *buf, char **ppparm, char **ppdata, + __u32 *pparmlen, __u32 *pdatalen) +{ + char *end_of_smb; + __u32 data_count, data_offset, parm_count, parm_offset; + struct smb_com_ntransact_rsp *pSMBr; + + *pdatalen = 0; + *pparmlen = 0; + + if (buf == NULL) + return -EINVAL; + + pSMBr = (struct smb_com_ntransact_rsp *)buf; + + /* ByteCount was converted from little endian in SendReceive */ + end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount + + (char *)&pSMBr->ByteCount; + + data_offset = le32_to_cpu(pSMBr->DataOffset); + data_count = le32_to_cpu(pSMBr->DataCount); + parm_offset = le32_to_cpu(pSMBr->ParameterOffset); + parm_count = le32_to_cpu(pSMBr->ParameterCount); + + *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; + *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; + + /* should we also check that parm and data areas do not overlap? */ + if (*ppparm > end_of_smb) { + cFYI(1, "parms start after end of smb"); + return -EINVAL; + } else if (parm_count + *ppparm > end_of_smb) { + cFYI(1, "parm end after end of smb"); + return -EINVAL; + } else if (*ppdata > end_of_smb) { + cFYI(1, "data starts after end of smb"); + return -EINVAL; + } else if (data_count + *ppdata > end_of_smb) { + cFYI(1, "data %p + count %d (%p) past smb end %p start %p", + *ppdata, data_count, (data_count + *ppdata), + end_of_smb, pSMBr); + return -EINVAL; + } else if (parm_count + data_count > pSMBr->ByteCount) { + cFYI(1, "parm count and data count larger than SMB"); + return -EINVAL; + } + *pdatalen = data_count; + *pparmlen = parm_count; + return 0; +} + /* Get Security Descriptor (by handle) from remote server for a file or dir */ int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, @@ -3214,7 +3215,7 @@ setCifsAclRetry: return (rc); } -#endif /* CONFIG_CIFS_EXPERIMENTAL */ +#endif /* CONFIG_CIFS_ACL */ /* Legacy Query Path Information call for lookup to old servers such as Win9x/WinME */ diff --git a/fs/cifs/file.c b/fs/cifs/file.c index b857ce5db775..5a28660ca2b5 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1108,7 +1108,6 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file, return total_written; } -#ifdef CONFIG_CIFS_EXPERIMENTAL struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only) { @@ -1142,7 +1141,6 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, spin_unlock(&cifs_file_list_lock); return NULL; } -#endif struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only) diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index bb5ca4848e81..aa48521a78c1 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -686,7 +686,7 @@ int cifs_get_inode_info(struct inode **pinode, cFYI(1, "cifs_sfu_type failed: %d", tmprc); } -#ifdef CONFIG_CIFS_EXPERIMENTAL +#ifdef CONFIG_CIFS_ACL /* fill in 0777 bits from ACL */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, @@ -697,7 +697,7 @@ int cifs_get_inode_info(struct inode **pinode, goto cgii_exit; } } -#endif +#endif /* CONFIG_CIFS_ACL */ /* fill in remaining high mode bits e.g. SUID, VTX */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) @@ -2122,7 +2122,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) if (attrs->ia_valid & ATTR_MODE) { rc = 0; -#ifdef CONFIG_CIFS_EXPERIMENTAL +#ifdef CONFIG_CIFS_ACL if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { rc = mode_to_cifs_acl(inode, full_path, mode); if (rc) { @@ -2131,7 +2131,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) goto cifs_setattr_exit; } } else -#endif +#endif /* CONFIG_CIFS_ACL */ if (((mode & S_IWUGO) == 0) && (cifsInode->cifsAttrs & ATTR_READONLY) == 0) { From b8eb3a1046f68a5b8f284830d971c62688cd606b Mon Sep 17 00:00:00 2001 From: Don Skidmore Date: Wed, 1 Dec 2010 20:54:53 +0000 Subject: [PATCH 111/300] ixgbe: fix possible NULL pointer deference in shutdown path After freeing the rings we were not zeroing out the ring count values. This patch now clears these counts correctly. Reported-by: Yinghai Lu Signed-off-by: Don Skidmore Tested-by: Stephen Ko Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ixgbe/ixgbe_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fbad4d819608..eee0b298bd36 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -4771,6 +4771,9 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter) adapter->rx_ring[i] = NULL; } + adapter->num_tx_queues = 0; + adapter->num_rx_queues = 0; + ixgbe_free_q_vectors(adapter); ixgbe_reset_interrupt_capability(adapter); } From 8b14d7b22c61f17ccb869e0047d9df6dd9f50a9f Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Sun, 28 Nov 2010 19:46:50 -0200 Subject: [PATCH 112/300] wmi: use memcmp instead of strncmp to compare GUIDs While looking for the duplicates in /sys/class/wmi/, I couldn't find them. The code that looks for duplicates uses strncmp in a binary GUID, which may contain zero bytes. The right function is memcmp, which is also used in another section of wmi code. It was finding 49142400-C6A3-40FA-BADB-8A2652834100 as a duplicate of 39142400-C6A3-40FA-BADB-8A2652834100. Since the first byte is the fourth printed, they were found as equal by strncmp. Signed-off-by: Thadeu Lima de Souza Cascardo Signed-off-by: Matthew Garrett Cc: stable@kernel.org --- drivers/platform/x86/wmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 104b77c87ef5..aecd9a9b549f 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -755,7 +755,7 @@ static bool guid_already_parsed(const char *guid_string) struct wmi_block *wblock; list_for_each_entry(wblock, &wmi_block_list, list) - if (strncmp(wblock->gblock.guid, guid_string, 16) == 0) + if (memcmp(wblock->gblock.guid, guid_string, 16) == 0) return true; return false; From 884639996814585ef7079daa9e03a1eb562e235c Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 22 Nov 2010 15:31:03 -0500 Subject: [PATCH 113/300] cifs: remove Local_System_Name ...this string is zeroed out and nothing ever changes it. Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 1 - fs/cifs/cifsglob.h | 2 -- fs/cifs/connect.c | 23 ++++++++++------------- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 56a4b7544c3c..3936aa7f2c22 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -937,7 +937,6 @@ init_cifs(void) GlobalCurrentXid = 0; GlobalTotalActiveXid = 0; GlobalMaxActiveXid = 0; - memset(Local_System_Name, 0, 15); spin_lock_init(&cifs_tcp_ses_lock); spin_lock_init(&cifs_file_list_lock); spin_lock_init(&GlobalMid_Lock); diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 94ccfacaed8a..7136c0c3e2f9 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -756,8 +756,6 @@ GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */ GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */ GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */ /* on midQ entries */ -GLOBAL_EXTERN char Local_System_Name[15]; - /* * Global counters, updated atomically */ diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index bb17ee2ba782..53f9c31a52b2 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -807,23 +807,20 @@ cifs_parse_mount_options(char *options, const char *devname, short int override_gid = -1; bool uid_specified = false; bool gid_specified = false; + char *nodename = utsname()->nodename; separator[0] = ','; separator[1] = 0; - if (Local_System_Name[0] != 0) - memcpy(vol->source_rfc1001_name, Local_System_Name, 15); - else { - char *nodename = utsname()->nodename; - int n = strnlen(nodename, 15); - memset(vol->source_rfc1001_name, 0x20, 15); - for (i = 0; i < n; i++) { - /* does not have to be perfect mapping since field is - informational, only used for servers that do not support - port 445 and it can be overridden at mount time */ - vol->source_rfc1001_name[i] = toupper(nodename[i]); - } - } + /* + * does not have to be perfect mapping since field is + * informational, only used for servers that do not support + * port 445 and it can be overridden at mount time + */ + memset(vol->source_rfc1001_name, 0x20, 15); + for (i = 0; i < strnlen(nodename, 15); i++) + vol->source_rfc1001_name[i] = toupper(nodename[i]); + vol->source_rfc1001_name[15] = 0; /* null target name indicates to use *SMBSERVR default called name if we end up sending RFC1001 session initialize */ From f811036476d7c8a9b594ebcdcf481bdbe497eb13 Mon Sep 17 00:00:00 2001 From: Ohad Ben-Cohen Date: Fri, 26 Nov 2010 23:59:24 +0000 Subject: [PATCH 114/300] omap: zoom: wl1271 slot is MMC_CAP_POWER_OFF_CARD This patch complements ed919b0 "mmc: sdio: fix runtime PM anomalies by introducing MMC_CAP_POWER_OFF_CARD" by declaring MMC_CAP_POWER_OFF_CARD on the ZOOM's wl1271 mmc slot. This is required in order not to break runtime PM support for the wl1271 sdio driver. Signed-off-by: Ohad Ben-Cohen Signed-off-by: Chris Ball Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-zoom-peripherals.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 86c9b2102952..9db9203667df 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -216,7 +216,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = { { .name = "wl1271", .mmc = 3, - .caps = MMC_CAP_4_BIT_DATA, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, .gpio_wp = -EINVAL, .gpio_cd = -EINVAL, .nonremovable = true, From 859158bfab7e72af440622fb9731bcaef4e7d6dc Mon Sep 17 00:00:00 2001 From: Sukumar Ghorai Date: Fri, 19 Nov 2010 14:45:26 +0000 Subject: [PATCH 115/300] omap: nand: remove hardware ECC as default Commit 2c01946c6b9ebaa5a89710bc42ca224a7f52f227 (omap3 nand: cleanup virtual address usages) wrongly enabled CONFIG_MTD_NAND_OMAP_HWECC which breaks boards like beagle and pandora that use software ECC for write. Boards like beagle and pandora uses sw ecc for write (e.g. binary flushed from u-boot) and read from kernel. Signed-off-by: Sukumar Ghorai Acked-by: David Woodhouse [tony@atomide.com: updated comments] Signed-off-by: Tony Lindgren --- drivers/mtd/nand/omap2.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index cd41c58b5bbd..15682ec8530e 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -7,7 +7,6 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#define CONFIG_MTD_NAND_OMAP_HWECC #include #include From cb9675f3282f5565cc9e3698cc847355c1194871 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Fri, 26 Nov 2010 17:06:02 +0000 Subject: [PATCH 116/300] arm: plat-omap: counter_32k: use IS_ERR() instead of NULL check clk_get() returns ERR_PTR() on error, not NULL. Signed-off-by: Vasiliy Kulikov Acked-by: Kevin Hilman [tony@atomide.com: updated to include err.h to compile on omap1] Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/counter_32k.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c index 155fe43a672b..8722a136f3a5 100644 --- a/arch/arm/plat-omap/counter_32k.c +++ b/arch/arm/plat-omap/counter_32k.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -164,7 +165,7 @@ static int __init omap_init_clocksource_32k(void) return -ENODEV; sync_32k_ick = clk_get(NULL, "omap_32ksync_ick"); - if (sync_32k_ick) + if (!IS_ERR(sync_32k_ick)) clk_enable(sync_32k_ick); clocksource_32k.mult = clocksource_hz2mult(32768, From 0e7d0c860a0dee49dacb7bbb248d1eba637075ad Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Mon, 6 Dec 2010 17:14:47 -0800 Subject: [PATCH 117/300] Input: add input driver for polled GPIO buttons The existing gpio-keys driver can be usable only for GPIO lines with interrupt support. Several devices have buttons connected to a GPIO line which is not capable to generate interrupts. This patch adds a new input driver using the generic GPIO layer and the input-polldev to support such buttons. [Ben Gardiner Signed-off-by: Ben Gardiner Tested-by: Ben Gardiner Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/Kconfig | 16 ++ drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/gpio_keys_polled.c | 261 ++++++++++++++++++++++ include/linux/gpio_keys.h | 2 + 4 files changed, 280 insertions(+) create mode 100644 drivers/input/keyboard/gpio_keys_polled.c diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index b8c51b9781db..3a87f3ba5f75 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -179,6 +179,22 @@ config KEYBOARD_GPIO To compile this driver as a module, choose M here: the module will be called gpio_keys. +config KEYBOARD_GPIO_POLLED + tristate "Polled GPIO buttons" + depends on GENERIC_GPIO + select INPUT_POLLDEV + help + This driver implements support for buttons connected + to GPIO pins that are not capable of generating interrupts. + + Say Y here if your device has buttons connected + directly to such GPIO pins. Your board-specific + setup logic must also provide a platform device, + with configuration data saying which GPIOs are used. + + To compile this driver as a module, choose M here: the + module will be called gpio_keys_polled. + config KEYBOARD_TCA6416 tristate "TCA6416 Keypad Support" depends on I2C diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index a34452e8ebe2..622de73a445d 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o +obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c new file mode 100644 index 000000000000..4c17aff20657 --- /dev/null +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -0,0 +1,261 @@ +/* + * Driver for buttons on GPIO lines not capable of generating interrupts + * + * Copyright (C) 2007-2010 Gabor Juhos + * Copyright (C) 2010 Nuno Goncalves + * + * This file was based on: /drivers/input/misc/cobalt_btns.c + * Copyright (C) 2007 Yoichi Yuasa + * + * also was based on: /drivers/input/keyboard/gpio_keys.c + * Copyright 2005 Phil Blundell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "gpio-keys-polled" + +struct gpio_keys_button_data { + int last_state; + int count; + int threshold; + int can_sleep; +}; + +struct gpio_keys_polled_dev { + struct input_polled_dev *poll_dev; + struct device *dev; + struct gpio_keys_platform_data *pdata; + struct gpio_keys_button_data data[0]; +}; + +static void gpio_keys_polled_check_state(struct input_dev *input, + struct gpio_keys_button *button, + struct gpio_keys_button_data *bdata) +{ + int state; + + if (bdata->can_sleep) + state = !!gpio_get_value_cansleep(button->gpio); + else + state = !!gpio_get_value(button->gpio); + + if (state != bdata->last_state) { + unsigned int type = button->type ?: EV_KEY; + + input_event(input, type, button->code, + !!(state ^ button->active_low)); + input_sync(input); + bdata->count = 0; + bdata->last_state = state; + } +} + +static void gpio_keys_polled_poll(struct input_polled_dev *dev) +{ + struct gpio_keys_polled_dev *bdev = dev->private; + struct gpio_keys_platform_data *pdata = bdev->pdata; + struct input_dev *input = dev->input; + int i; + + for (i = 0; i < bdev->pdata->nbuttons; i++) { + struct gpio_keys_button_data *bdata = &bdev->data[i]; + + if (bdata->count < bdata->threshold) + bdata->count++; + else + gpio_keys_polled_check_state(input, &pdata->buttons[i], + bdata); + } +} + +static void gpio_keys_polled_open(struct input_polled_dev *dev) +{ + struct gpio_keys_polled_dev *bdev = dev->private; + struct gpio_keys_platform_data *pdata = bdev->pdata; + + if (pdata->enable) + pdata->enable(bdev->dev); +} + +static void gpio_keys_polled_close(struct input_polled_dev *dev) +{ + struct gpio_keys_polled_dev *bdev = dev->private; + struct gpio_keys_platform_data *pdata = bdev->pdata; + + if (pdata->disable) + pdata->disable(bdev->dev); +} + +static int __devinit gpio_keys_polled_probe(struct platform_device *pdev) +{ + struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; + struct device *dev = &pdev->dev; + struct gpio_keys_polled_dev *bdev; + struct input_polled_dev *poll_dev; + struct input_dev *input; + int error; + int i; + + if (!pdata || !pdata->poll_interval) + return -EINVAL; + + bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) + + pdata->nbuttons * sizeof(struct gpio_keys_button_data), + GFP_KERNEL); + if (!bdev) { + dev_err(dev, "no memory for private data\n"); + return -ENOMEM; + } + + poll_dev = input_allocate_polled_device(); + if (!poll_dev) { + dev_err(dev, "no memory for polled device\n"); + error = -ENOMEM; + goto err_free_bdev; + } + + poll_dev->private = bdev; + poll_dev->poll = gpio_keys_polled_poll; + poll_dev->poll_interval = pdata->poll_interval; + poll_dev->open = gpio_keys_polled_open; + poll_dev->close = gpio_keys_polled_close; + + input = poll_dev->input; + + input->evbit[0] = BIT(EV_KEY); + input->name = pdev->name; + input->phys = DRV_NAME"/input0"; + input->dev.parent = &pdev->dev; + + input->id.bustype = BUS_HOST; + input->id.vendor = 0x0001; + input->id.product = 0x0001; + input->id.version = 0x0100; + + for (i = 0; i < pdata->nbuttons; i++) { + struct gpio_keys_button *button = &pdata->buttons[i]; + struct gpio_keys_button_data *bdata = &bdev->data[i]; + unsigned int gpio = button->gpio; + unsigned int type = button->type ?: EV_KEY; + + if (button->wakeup) { + dev_err(dev, DRV_NAME " does not support wakeup\n"); + error = -EINVAL; + goto err_free_gpio; + } + + error = gpio_request(gpio, + button->desc ? button->desc : DRV_NAME); + if (error) { + dev_err(dev, "unable to claim gpio %u, err=%d\n", + gpio, error); + goto err_free_gpio; + } + + error = gpio_direction_input(gpio); + if (error) { + dev_err(dev, + "unable to set direction on gpio %u, err=%d\n", + gpio, error); + goto err_free_gpio; + } + + bdata->can_sleep = gpio_cansleep(gpio); + bdata->last_state = -1; + bdata->threshold = DIV_ROUND_UP(button->debounce_interval, + pdata->poll_interval); + + input_set_capability(input, type, button->code); + } + + bdev->poll_dev = poll_dev; + bdev->dev = dev; + bdev->pdata = pdata; + platform_set_drvdata(pdev, bdev); + + error = input_register_polled_device(poll_dev); + if (error) { + dev_err(dev, "unable to register polled device, err=%d\n", + error); + goto err_free_gpio; + } + + /* report initial state of the buttons */ + for (i = 0; i < pdata->nbuttons; i++) + gpio_keys_polled_check_state(input, &pdata->buttons[i], + &bdev->data[i]); + + return 0; + +err_free_gpio: + while (--i >= 0) + gpio_free(pdata->buttons[i].gpio); + + input_free_polled_device(poll_dev); + +err_free_bdev: + kfree(bdev); + + platform_set_drvdata(pdev, NULL); + return error; +} + +static int __devexit gpio_keys_polled_remove(struct platform_device *pdev) +{ + struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev); + struct gpio_keys_platform_data *pdata = bdev->pdata; + int i; + + input_unregister_polled_device(bdev->poll_dev); + + for (i = 0; i < pdata->nbuttons; i++) + gpio_free(pdata->buttons[i].gpio); + + input_free_polled_device(bdev->poll_dev); + + kfree(bdev); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver gpio_keys_polled_driver = { + .probe = gpio_keys_polled_probe, + .remove = __devexit_p(gpio_keys_polled_remove), + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init gpio_keys_polled_init(void) +{ + return platform_driver_register(&gpio_keys_polled_driver); +} + +static void __exit gpio_keys_polled_exit(void) +{ + platform_driver_unregister(&gpio_keys_polled_driver); +} + +module_init(gpio_keys_polled_init); +module_exit(gpio_keys_polled_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Gabor Juhos "); +MODULE_DESCRIPTION("Polled GPIO Buttons driver"); +MODULE_ALIAS("platform:" DRV_NAME); diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index ce73a30113b4..dd1a56fbe924 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h @@ -16,6 +16,8 @@ struct gpio_keys_button { struct gpio_keys_platform_data { struct gpio_keys_button *buttons; int nbuttons; + unsigned int poll_interval; /* polling interval in msecs - + for polling driver only */ unsigned int rep:1; /* enable input subsystem auto repeat */ int (*enable)(struct device *dev); void (*disable)(struct device *dev); From 7a1948768c2998f5bddb2327696cbe3161f468ed Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 7 Dec 2010 10:38:40 +0000 Subject: [PATCH 118/300] drm/i915: Emit a request to clear a flushed and idle ring for unbusy bo In order for bos to retire eventually, a request must be sent down the ring. This is expected, for example, by occlusion queries for which mesa will wait upon (whilst running glean) before issuing more batches and so the normal activity upon the ring is suspended and we need to emit a request to clear the idle ring. Reported-by: Jinjin, Wang Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=30380 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5e54821af996..275ec6ed43ae 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4374,10 +4374,20 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, * use this buffer rather sooner than later, so issuing the required * flush earlier is beneficial. */ - if (obj->write_domain & I915_GEM_GPU_DOMAINS) + if (obj->write_domain & I915_GEM_GPU_DOMAINS) { i915_gem_flush_ring(dev, file_priv, obj_priv->ring, 0, obj->write_domain); + } else if (obj_priv->ring->outstanding_lazy_request) { + /* This ring is not being cleared by active usage, + * so emit a request to do so. + */ + u32 seqno = i915_add_request(dev, + NULL, NULL, + obj_priv->ring); + if (seqno == 0) + ret = -ENOMEM; + } /* Update the active list for the hardware's current position. * Otherwise this only updates on a delayed timer or when irqs From 681e36924788aeea2717c07cc42a21c9c86d7559 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 7 Dec 2010 20:56:30 +0800 Subject: [PATCH 119/300] ASoC: Fix resource leak if soc_register_ac97_dai_link failed Properly free the resources in the case of soc_register_ac97_dai_link failure. Signed-off-by: Axel Lin Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 02ae7bea3b50..85b7d548f167 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1619,12 +1619,14 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) #ifdef CONFIG_SND_SOC_AC97_BUS /* register any AC97 codecs */ for (i = 0; i < card->num_rtd; i++) { - ret = soc_register_ac97_dai_link(&card->rtd[i]); - if (ret < 0) { - printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name); - goto probe_dai_err; - } + ret = soc_register_ac97_dai_link(&card->rtd[i]); + if (ret < 0) { + printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name); + while (--i >= 0) + soc_unregister_ac97_dai_link(&card->rtd[i]); + goto probe_dai_err; } + } #endif card->instantiated = 1; From de47de7404e29df8de82f5822b4fde1a6ed97b54 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Tue, 7 Dec 2010 13:04:00 +0800 Subject: [PATCH 120/300] autofs4 - remove ioctl mutex (bz23142) With the recent changes to remove the BKL a mutex was added to the ioctl entry point for calls to the old ioctl interface. This mutex needs to be removed because of the need for the expire ioctl to call back to the daemon to perform a umount and receive a completion status (via another ioctl). This should be fine as the new ioctl interface uses much of the same code and it has been used without a mutex for around a year without issue, as was the original intention. Ref: Bugzilla bug 23142 Signed-off-by: Ian Kent Acked-by: Arnd Bergmann Signed-off-by: Linus Torvalds --- fs/autofs4/root.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index d5c1401f0031..d34896cfb19f 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -980,19 +980,11 @@ static int autofs4_root_ioctl_unlocked(struct inode *inode, struct file *filp, } } -static DEFINE_MUTEX(autofs4_ioctl_mutex); - static long autofs4_root_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - long ret; struct inode *inode = filp->f_dentry->d_inode; - - mutex_lock(&autofs4_ioctl_mutex); - ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg); - mutex_unlock(&autofs4_ioctl_mutex); - - return ret; + return autofs4_root_ioctl_unlocked(inode, filp, cmd, arg); } #ifdef CONFIG_COMPAT @@ -1002,13 +994,11 @@ static long autofs4_root_compat_ioctl(struct file *filp, struct inode *inode = filp->f_path.dentry->d_inode; int ret; - mutex_lock(&autofs4_ioctl_mutex); if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL) ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg); else ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, (unsigned long)compat_ptr(arg)); - mutex_unlock(&autofs4_ioctl_mutex); return ret; } From 6b464321d276e448d478c99202c19d83f2bd25f4 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 7 Dec 2010 19:23:07 +0900 Subject: [PATCH 121/300] ASoC: WM8580: Debug BCLK and sample size In case of SNDRV_PCM_FORMAT_S32_LE, we need to set WM8580_AIF_LENGTH_32, rather than WM8580_AIF_LENGTH_24. Also, the BCLK has to be 64fs, for sample size of 20, 24 and 32 bits. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm8580.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index a2e0ed59b376..879dff2714dd 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -491,16 +491,16 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream, paifa |= 0x8; break; case SNDRV_PCM_FORMAT_S20_3LE: - paifa |= 0x10; + paifa |= 0x0; paifb |= WM8580_AIF_LENGTH_20; break; case SNDRV_PCM_FORMAT_S24_LE: - paifa |= 0x10; + paifa |= 0x0; paifb |= WM8580_AIF_LENGTH_24; break; case SNDRV_PCM_FORMAT_S32_LE: - paifa |= 0x10; - paifb |= WM8580_AIF_LENGTH_24; + paifa |= 0x0; + paifb |= WM8580_AIF_LENGTH_32; break; default: return -EINVAL; From 2a7b1a00206895cfa444fd83477dca67a88a9d25 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 7 Dec 2010 15:32:38 +0000 Subject: [PATCH 122/300] ASoC: Correct WM8962 interrupt mask register read Fix mismerge from the out of tree BSP where this support was developed. Signed-off-by: Mark Brown --- sound/soc/codecs/wm8962.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index e8092745a207..1304ca91a11c 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3339,7 +3339,7 @@ static irqreturn_t wm8962_irq(int irq, void *data) int mask; int active; - mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); + mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK); active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); active &= ~mask; From 18fb5fe40ce7f789b5cfc3aa81ff1e6175b0a5be Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 7 Dec 2010 12:41:58 -0500 Subject: [PATCH 123/300] NFS: nfs_readdir_search_for_cookie() don't mark as eof if cookie not found If we're searching for a specific cookie, and it isn't found in the page cache, we should try an uncached_readdir(). To do so, we return EBADCOOKIE, but we don't set desc->eof. Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index d529e0e99efa..ad2fde23446d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -316,8 +316,9 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des } } if (i == array->eof_index) { - desc->eof = 1; status = -EBADCOOKIE; + if (*desc->dir_cookie == array->last_cookie) + desc->eof = 1; } out: return status; From 47c716cbf638a16583441d78be3fc24345eab636 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 7 Dec 2010 12:44:56 -0500 Subject: [PATCH 124/300] NFS: Readdir cleanups No functional changes, but clarify the code. Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 47 +++++++++++++++++------------------------------ 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index ad2fde23446d..996dd8989a91 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -271,7 +271,7 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page) goto out; array->last_cookie = entry->cookie; array->size++; - if (entry->eof == 1) + if (entry->eof != 0) array->eof_index = array->size; out: nfs_readdir_release_array(page); @@ -311,16 +311,14 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des for (i = 0; i < array->size; i++) { if (array->array[i].cookie == *desc->dir_cookie) { desc->cache_entry_index = i; - status = 0; - goto out; + return 0; } } - if (i == array->eof_index) { + if (array->eof_index >= 0) { status = -EBADCOOKIE; if (*desc->dir_cookie == array->last_cookie) desc->eof = 1; } -out: return status; } @@ -328,10 +326,7 @@ static int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc) { struct nfs_cache_array *array; - int status = -EBADCOOKIE; - - if (desc->dir_cookie == NULL) - goto out; + int status; array = nfs_readdir_get_array(desc->page); if (IS_ERR(array)) { @@ -344,8 +339,10 @@ int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc) else status = nfs_readdir_search_for_cookie(array, desc); - if (status == -EAGAIN) + if (status == -EAGAIN) { desc->last_cookie = array->last_cookie; + desc->page_index++; + } nfs_readdir_release_array(desc->page); out: return status; @@ -492,7 +489,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en count++; - if (desc->plus == 1) + if (desc->plus != 0) nfs_prime_dcache(desc->file->f_path.dentry, entry); status = nfs_readdir_add_to_array(entry, page); @@ -500,7 +497,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en break; } while (!entry->eof); - if (count == 0 || (status == -EBADCOOKIE && entry->eof == 1)) { + if (count == 0 || (status == -EBADCOOKIE && entry->eof != 0)) { array = nfs_readdir_get_array(page); if (!IS_ERR(array)) { array->eof_index = array->size; @@ -664,9 +661,8 @@ int find_cache_page(nfs_readdir_descriptor_t *desc) return PTR_ERR(desc->page); res = nfs_readdir_search_array(desc); - if (res == 0) - return 0; - cache_page_release(desc); + if (res != 0) + cache_page_release(desc); return res; } @@ -680,20 +676,12 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc) desc->current_index = 0; desc->last_cookie = 0; } - while (1) { + do { res = find_cache_page(desc); - if (res != -EAGAIN) - break; - desc->page_index++; - } + } while (res == -EAGAIN); return res; } -static inline unsigned int dt_type(struct inode *inode) -{ - return (inode->i_mode >> 12) & 15; -} - /* * Once we've found the start of the dirent within a page: fill 'er up... */ @@ -723,13 +711,12 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent, break; } file->f_pos++; - desc->cache_entry_index = i; if (i < (array->size-1)) *desc->dir_cookie = array->array[i+1].cookie; else *desc->dir_cookie = array->last_cookie; } - if (i == array->eof_index) + if (array->eof_index >= 0) desc->eof = 1; nfs_readdir_release_array(desc->page); @@ -798,7 +785,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) struct inode *inode = dentry->d_inode; nfs_readdir_descriptor_t my_desc, *desc = &my_desc; - int res = -ENOMEM; + int res; dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n", dentry->d_parent->d_name.name, dentry->d_name.name, @@ -823,7 +810,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) if (res < 0) goto out; - while (desc->eof != 1) { + do { res = readdir_search_pagecache(desc); if (res == -EBADCOOKIE) { @@ -851,7 +838,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) res = nfs_do_filldir(desc, dirent, filldir); if (res < 0) break; - } + } while (!desc->eof); out: nfs_unblock_sillyrename(dentry); if (res > 0) From 4b0dbdb17f846a8887e5f7fbeea2deb0703236bd Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Tue, 7 Dec 2010 18:41:35 +0200 Subject: [PATCH 125/300] ALSA: hda - Do not wrongly restrict min_channels based on ELD Commit bbbe33900d1f3c added functionality to restrict PCM parameters based on ELD info (derived from EDID data) of the audio sink. However, it wrongly assumes that the bits 0-2 of the first byte of CEA Short Audio Descriptors mean a supported number of channels. In reality, they mean the maximum number of channels (as per CEA-861-D 7.5.2). This means that the channel count can only be used to restrict max_channels, not min_channels. Restricting min_channels causes us to deny opening the device in stereo mode if the sink only has SADs that declare larger numbers of channels (like Primare SP32 AV Processor does). Fix that by not restricting min_channels based on ELD information. Signed-off-by: Anssi Hannula Reported-by: Jean-Yves Avenard Tested-by: Jean-Yves Avenard Cc: stable@kernel.org Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_eld.c | 4 ---- sound/pci/hda/patch_hdmi.c | 1 - 2 files changed, 5 deletions(-) diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index cb0c23a6b473..47ef8aa4a844 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -601,13 +601,10 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, pcm->rates = 0; pcm->formats = 0; pcm->maxbps = 0; - pcm->channels_min = -1; pcm->channels_max = 0; for (i = 0; i < eld->sad_count; i++) { struct cea_sad *a = &eld->sad[i]; pcm->rates |= a->rates; - if (a->channels < pcm->channels_min) - pcm->channels_min = a->channels; if (a->channels > pcm->channels_max) pcm->channels_max = a->channels; if (a->format == AUDIO_CODING_TYPE_LPCM) { @@ -635,7 +632,6 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, /* restrict the parameters by the values the codec provides */ pcm->rates &= codec_pars->rates; pcm->formats &= codec_pars->formats; - pcm->channels_min = max(pcm->channels_min, codec_pars->channels_min); pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max); pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); } diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index d3e49aa5b9ec..31df7747990d 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -834,7 +834,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, return -ENODEV; } else { /* fallback to the codec default */ - hinfo->channels_min = codec_pars->channels_min; hinfo->channels_max = codec_pars->channels_max; hinfo->rates = codec_pars->rates; hinfo->formats = codec_pars->formats; From 3dc86429032910bdf762adeb2969112bb303924c Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Tue, 7 Dec 2010 20:56:19 +0200 Subject: [PATCH 126/300] ALSA: hda - Always allow basic audio irrespective of ELD info Commit bbbe33900d1f3c added functionality to restrict PCM parameters based on ELD info (derived from EDID data) of the audio sink. However, according to CEA-861-D no SAD is needed for basic audio (32/44.1/48kHz stereo 16-bit audio), which is instead indicated with a basic audio flag in the CEA EDID Extension. The flag is not present in ELD. However, as all audio capable sinks are required to support basic audio, we can assume it to be always available. Fix allowed audio formats with sinks that have SADs (Short Audio Descriptors) which do not completely overlap with the basic audio formats (there are no reports of affected devices so far) by always assuming that basic audio is supported. Reported-by: Stephen Warren Signed-off-by: Anssi Hannula Cc: stable@kernel.org Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_eld.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 47ef8aa4a844..009031fae2ba 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -598,21 +598,19 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, { int i; - pcm->rates = 0; - pcm->formats = 0; - pcm->maxbps = 0; - pcm->channels_max = 0; + /* assume basic audio support (the basic audio flag is not in ELD; + * however, all audio capable sinks are required to support basic + * audio) */ + pcm->rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; + pcm->formats = SNDRV_PCM_FMTBIT_S16_LE; + pcm->maxbps = 16; + pcm->channels_max = 2; for (i = 0; i < eld->sad_count; i++) { struct cea_sad *a = &eld->sad[i]; pcm->rates |= a->rates; if (a->channels > pcm->channels_max) pcm->channels_max = a->channels; if (a->format == AUDIO_CODING_TYPE_LPCM) { - if (a->sample_bits & AC_SUPPCM_BITS_16) { - pcm->formats |= SNDRV_PCM_FMTBIT_S16_LE; - if (pcm->maxbps < 16) - pcm->maxbps = 16; - } if (a->sample_bits & AC_SUPPCM_BITS_20) { pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE; if (pcm->maxbps < 20) From 03ceace5c6923ffbcf2b4d2e37afbffbdb5d4a67 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 6 Dec 2010 21:07:33 -0500 Subject: [PATCH 127/300] cifs: fix check of error return from is_path_accessable This function will return 0 if everything went ok. Commit 9d002df4 however added a block of code after the following check for rc == -EREMOTE. With that change and when rc == 0, doing the "goto mount_fail_check" here skips that code, leaving the tlink_tree and master_tlink pointer unpopulated. That causes an oops later in cifs_root_iget. Reported-and-Tested-by: Robbert Kouprie Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/connect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 53f9c31a52b2..387b91ae7400 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2839,7 +2839,7 @@ remote_path_check: goto mount_fail_check; } rc = is_path_accessible(xid, tcon, cifs_sb, full_path); - if (rc != -EREMOTE) { + if (rc != 0 && rc != -EREMOTE) { kfree(full_path); goto mount_fail_check; } From 7d161b7f41e24203b54b0f18ae0d26c18a6c6fab Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 7 Dec 2010 02:10:35 -0500 Subject: [PATCH 128/300] cifs: allow calling cifs_build_path_to_root on incomplete cifs_sb It's possible that cifs_mount will call cifs_build_path_to_root on a newly instantiated cifs_sb. In that case, it's likely that the master_tlink pointer has not yet been instantiated. Fix this by having cifs_build_path_to_root take a cifsTconInfo pointer as well, and have the caller pass that in. Reported-and-Tested-by: Robbert Kouprie Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 3 ++- fs/cifs/connect.c | 2 +- fs/cifs/inode.c | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 5523047b1ebd..e6d1481b16c1 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -54,7 +54,8 @@ do { \ __func__, curr_xid, (int)rc); \ } while (0) extern char *build_path_from_dentry(struct dentry *); -extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb); +extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb, + struct cifsTconInfo *tcon); extern char *build_wildcard_path_from_dentry(struct dentry *direntry); extern char *cifs_compose_mount_options(const char *sb_mountdata, const char *fullpath, const struct dfs_info3_param *ref, diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 387b91ae7400..cc1a8604a790 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2833,7 +2833,7 @@ remote_path_check: /* check if a whole path (including prepath) is not remote */ if (!rc && cifs_sb->prepathlen && tcon) { /* build_path_to_root works only when we have a valid tcon */ - full_path = cifs_build_path_to_root(cifs_sb); + full_path = cifs_build_path_to_root(cifs_sb, tcon); if (full_path == NULL) { rc = -ENOMEM; goto mount_fail_check; diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index aa48521a78c1..589f3e3f6e00 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -728,12 +728,12 @@ static const struct inode_operations cifs_ipc_inode_ops = { .lookup = cifs_lookup, }; -char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) +char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb, + struct cifsTconInfo *tcon) { int pplen = cifs_sb->prepathlen; int dfsplen; char *full_path = NULL; - struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); /* if no prefix path, simply set path to the root of share to "" */ if (pplen == 0) { @@ -875,7 +875,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) char *full_path; struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); - full_path = cifs_build_path_to_root(cifs_sb); + full_path = cifs_build_path_to_root(cifs_sb, tcon); if (full_path == NULL) return ERR_PTR(-ENOMEM); From 6142e05f30b101adeafb0d12e35983f44f68233e Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 7 Dec 2010 17:41:40 +0000 Subject: [PATCH 129/300] MN10300: Fix interrupt mask alteration function call name in gdbstub Fix the name of interrupt mask alteration function (ie the local_change_intr_mask_level() fn) called in gdbstub to have an arch_ prefix to match the definition in asm/irqflags.h. Signed-off-by: David Howells Signed-off-by: Linus Torvalds --- arch/mn10300/kernel/gdb-io-serial.c | 3 ++- arch/mn10300/kernel/gdb-io-ttysm.c | 3 ++- arch/mn10300/kernel/gdb-stub.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/mn10300/kernel/gdb-io-serial.c b/arch/mn10300/kernel/gdb-io-serial.c index 0d5d63c91dc3..f28dc99c6f72 100644 --- a/arch/mn10300/kernel/gdb-io-serial.c +++ b/arch/mn10300/kernel/gdb-io-serial.c @@ -73,7 +73,8 @@ void gdbstub_io_init(void) GDBPORT_SERIAL_IER = UART_IER_RDI | UART_IER_RLSI; /* permit level 0 IRQs to take place */ - local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); + arch_local_change_intr_mask_level( + NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); } /* diff --git a/arch/mn10300/kernel/gdb-io-ttysm.c b/arch/mn10300/kernel/gdb-io-ttysm.c index 97dfda23342c..abdeea153c89 100644 --- a/arch/mn10300/kernel/gdb-io-ttysm.c +++ b/arch/mn10300/kernel/gdb-io-ttysm.c @@ -87,7 +87,8 @@ void __init gdbstub_io_init(void) tmp = *gdbstub_port->_control; /* permit level 0 IRQs only */ - local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); + arch_local_change_intr_mask_level( + NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); } /* diff --git a/arch/mn10300/kernel/gdb-stub.c b/arch/mn10300/kernel/gdb-stub.c index a5fc3f05309b..b169d99d9f20 100644 --- a/arch/mn10300/kernel/gdb-stub.c +++ b/arch/mn10300/kernel/gdb-stub.c @@ -1194,7 +1194,8 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) asm volatile("mov mdr,%0" : "=d"(mdr)); local_save_flags(epsw); - local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); + arch_local_change_intr_mask_level( + NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); gdbstub_store_fpu(); From 94dec6a2d20a26a779b63bb584e48db5fb0ddb53 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 7 Dec 2010 19:24:45 +0000 Subject: [PATCH 130/300] sfc: Fix crash in legacy onterrupt handler during ring reallocation If we are using a legacy interrupt, our IRQ may be shared and our interrupt handler may be called even though interrupts are disabled on the NIC. When we change ring sizes, we reallocate the event queue and the interrupt handler may use an invalid pointer when called for another device's interrupt. Maintain a legacy_irq_enabled flag and test that at the top of the interrupt handler. Note that this problem results from the need to work around broken INT_ISR0 reads, and does not affect the legacy interrupt handler for Falcon A1. Signed-off-by: Ben Hutchings --- drivers/net/sfc/efx.c | 12 ++++++++++-- drivers/net/sfc/net_driver.h | 2 ++ drivers/net/sfc/nic.c | 6 ++++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 05df20e47976..d06cb742164b 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -335,8 +335,10 @@ void efx_process_channel_now(struct efx_channel *channel) /* Disable interrupts and wait for ISRs to complete */ efx_nic_disable_interrupts(efx); - if (efx->legacy_irq) + if (efx->legacy_irq) { synchronize_irq(efx->legacy_irq); + efx->legacy_irq_enabled = false; + } if (channel->irq) synchronize_irq(channel->irq); @@ -351,6 +353,8 @@ void efx_process_channel_now(struct efx_channel *channel) efx_channel_processed(channel); napi_enable(&channel->napi_str); + if (efx->legacy_irq) + efx->legacy_irq_enabled = true; efx_nic_enable_interrupts(efx); } @@ -1400,6 +1404,8 @@ static void efx_start_all(struct efx_nic *efx) efx_start_channel(channel); } + if (efx->legacy_irq) + efx->legacy_irq_enabled = true; efx_nic_enable_interrupts(efx); /* Switch to event based MCDI completions after enabling interrupts. @@ -1460,8 +1466,10 @@ static void efx_stop_all(struct efx_nic *efx) /* Disable interrupts and wait for ISR to complete */ efx_nic_disable_interrupts(efx); - if (efx->legacy_irq) + if (efx->legacy_irq) { synchronize_irq(efx->legacy_irq); + efx->legacy_irq_enabled = false; + } efx_for_each_channel(channel, efx) { if (channel->irq) synchronize_irq(channel->irq); diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 0a7e26d73b52..b137c889152b 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -621,6 +621,7 @@ struct efx_filter_state; * @pci_dev: The PCI device * @type: Controller type attributes * @legacy_irq: IRQ number + * @legacy_irq_enabled: Are IRQs enabled on NIC (INT_EN_KER register)? * @workqueue: Workqueue for port reconfigures and the HW monitor. * Work items do not hold and must not acquire RTNL. * @workqueue_name: Name of workqueue @@ -709,6 +710,7 @@ struct efx_nic { struct pci_dev *pci_dev; const struct efx_nic_type *type; int legacy_irq; + bool legacy_irq_enabled; struct workqueue_struct *workqueue; char workqueue_name[16]; struct work_struct reset_work; diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 41c36b9a4244..67cb0c96838c 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -1418,6 +1418,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) u32 queues; int syserr; + /* Could this be ours? If interrupts are disabled then the + * channel state may not be valid. + */ + if (!efx->legacy_irq_enabled) + return result; + /* Read the ISR which also ACKs the interrupts */ efx_readd(efx, ®, FR_BZ_INT_ISR0); queues = EFX_EXTRACT_DWORD(reg, 0, 31); From 841051602e3fa18ea468fe5a177aa92b6eb44b56 Mon Sep 17 00:00:00 2001 From: Matteo Croce Date: Fri, 3 Dec 2010 02:25:08 +0100 Subject: [PATCH 131/300] ath9k: fix bug in tx power The ath9k driver subtracts 3 dBm to the txpower as with two radios the signal power is doubled. The resulting value is assigned in an u16 which overflows and makes the card work at full power. Cc: stable@kernel.org Signed-off-by: Matteo Croce Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/eeprom_def.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 526d7c933f7f..a3ccb1b9638d 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -1063,15 +1063,19 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, case 1: break; case 2: - scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; + if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) + scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; + else + scaledPower = 0; break; case 3: - scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; + if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) + scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; + else + scaledPower = 0; break; } - scaledPower = max((u16)0, scaledPower); - if (IS_CHAN_2GHZ(chan)) { numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40; From 080e1a259acea10b6df8e2a8e49b47481940220a Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 5 Dec 2010 20:17:53 +0100 Subject: [PATCH 132/300] ath9k: fix a DMA related race condition on reset When ath_drain_all_txq fails to stop DMA, it issues a hw reset. This reset happens at a very problematic point in time, when the hardware rx path has not been stopped yet. This could lead to memory corruption, hardware hangs or other issues. To fix these issues, simply remove the reset entirely and check the tx DMA stop status to prevent problems with fast channel changes. Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ath9k.h | 2 +- drivers/net/wireless/ath/ath9k/main.c | 5 +++-- drivers/net/wireless/ath/ath9k/xmit.c | 22 ++++++---------------- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 0d0bec3628ec..0963071e8f90 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -329,7 +329,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); int ath_tx_setup(struct ath_softc *sc, int haltype); -void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); +bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx); void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index dace215b693e..928ef68ab40c 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -244,11 +244,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, * the relevant bits of the h/w. */ ath9k_hw_set_interrupts(ah, 0); - ath_drain_all_txq(sc, false); + stopped = ath_drain_all_txq(sc, false); spin_lock_bh(&sc->rx.pcu_lock); - stopped = ath_stoprecv(sc); + if (!ath_stoprecv(sc)) + stopped = false; /* XXX: do not flush receive queue here. We don't want * to flush data frames already in queue because of diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index f2ade2402ce2..aff04789f794 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1120,7 +1120,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) } } -void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) +bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(sc->sc_ah); @@ -1128,7 +1128,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) int i, npend = 0; if (sc->sc_flags & SC_OP_INVALID) - return; + return true; /* Stop beacon queue */ ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); @@ -1142,25 +1142,15 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) } } - if (npend) { - int r; - - ath_print(common, ATH_DBG_FATAL, - "Failed to stop TX DMA. Resetting hardware!\n"); - - spin_lock_bh(&sc->sc_resetlock); - r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); - if (r) - ath_print(common, ATH_DBG_FATAL, - "Unable to reset hardware; reset status %d\n", - r); - spin_unlock_bh(&sc->sc_resetlock); - } + if (npend) + ath_print(common, ATH_DBG_FATAL, "Failed to stop TX DMA!\n"); for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { if (ATH_TXQ_SETUP(sc, i)) ath_draintxq(sc, &sc->tx.txq[i], retry_tx); } + + return !npend; } void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) From 38852b20c8b6d97618204ac64abbf14f0080393e Mon Sep 17 00:00:00 2001 From: Senthil Balasubramanian Date: Mon, 6 Dec 2010 19:09:27 +0530 Subject: [PATCH 133/300] ath9k: Fix STA disconnect issue due to received MIC failed bcast frames AR_RxKeyIdxValid will not be set for bcast/mcast frames and so relying this status for MIC failed frames is buggy. Due to this, MIC failure events for broadcast frames are not sent to supplicant resulted in AP disconnecting the STA. Able to pass Wifi Test case 5.2.18 with this fix. Cc: Stable (2.6.36+) Signed-off-by: Senthil Balasubramanian Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/mac.c | 3 +-- drivers/net/wireless/ath/ath9k/recv.c | 9 ++++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 8c13479b17cd..c996963ab339 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -703,8 +703,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, rs->rs_phyerr = phyerr; } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) rs->rs_status |= ATH9K_RXERR_DECRYPT; - else if ((ads.ds_rxstatus8 & AR_MichaelErr) && - rs->rs_keyix != ATH9K_RXKEYIX_INVALID) + else if (ads.ds_rxstatus8 & AR_MichaelErr) rs->rs_status |= ATH9K_RXERR_MIC; else if (ads.ds_rxstatus8 & AR_KeyMiss) rs->rs_status |= ATH9K_RXERR_DECRYPT; diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 1a62e351ec77..fdc2ec52b42f 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -838,6 +838,10 @@ static bool ath9k_rx_accept(struct ath_common *common, struct ath_rx_status *rx_stats, bool *decrypt_error) { +#define is_mc_or_valid_tkip_keyix ((is_mc || \ + (rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \ + test_bit(rx_stats->rs_keyix, common->tkip_keymap)))) + struct ath_hw *ah = common->ah; __le16 fc; u8 rx_status_len = ah->caps.rx_status_len; @@ -879,15 +883,18 @@ static bool ath9k_rx_accept(struct ath_common *common, if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { *decrypt_error = true; } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { + bool is_mc; /* * The MIC error bit is only valid if the frame * is not a control frame or fragment, and it was * decrypted using a valid TKIP key. */ + is_mc = !!is_multicast_ether_addr(hdr->addr1); + if (!ieee80211_is_ctl(fc) && !ieee80211_has_morefrags(fc) && !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && - test_bit(rx_stats->rs_keyix, common->tkip_keymap)) + is_mc_or_valid_tkip_keyix) rxs->flag |= RX_FLAG_MMIC_ERROR; else rx_stats->rs_status &= ~ATH9K_RXERR_MIC; From 884a963fa1c828a5c5fa7a46b2877dd463bfd47c Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Tue, 7 Dec 2010 17:42:18 +0530 Subject: [PATCH 134/300] ath9k: fix beacon resource related race condition The beacon tasklet is accesssing the bslot info for beacon generation. Meanwhile the same slot can be freed on interface deletion. Current the remove_interface disables the beacon alert after freeing the slot. This may leads to null pointer access. This patch disables SWBA and kills the beacon tasklet to prevent access to the slot to be freed. After releasing the slot, swba will be enabled again upon the availablity of beaconing interfaces. Signed-off-by: Rajkumar Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 928ef68ab40c..c0c3464d3a86 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1520,8 +1520,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, struct ath_softc *sc = aphy->sc; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_vif *avp = (void *)vif->drv_priv; - bool bs_valid = false; - int i; ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); @@ -1535,26 +1533,21 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { + /* Disable SWBA interrupt */ + sc->sc_ah->imask &= ~ATH9K_INT_SWBA; ath9k_ps_wakeup(sc); + ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); ath9k_ps_restore(sc); + tasklet_kill(&sc->bcon_tasklet); } ath_beacon_return(sc, avp); sc->sc_flags &= ~SC_OP_BEACONS; - for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { - if (sc->beacon.bslot[i] == vif) { - printk(KERN_DEBUG "%s: vif had allocated beacon " - "slot\n", __func__); - sc->beacon.bslot[i] = NULL; - sc->beacon.bslot_aphy[i] = NULL; - } else if (sc->beacon.bslot[i]) - bs_valid = true; - } - if (!bs_valid && (sc->sc_ah->imask & ATH9K_INT_SWBA)) { - /* Disable SWBA interrupt */ - sc->sc_ah->imask &= ~ATH9K_INT_SWBA; + if (sc->nbcnvifs) { + /* Re-enable SWBA interrupt */ + sc->sc_ah->imask |= ATH9K_INT_SWBA; ath9k_ps_wakeup(sc); ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); ath9k_ps_restore(sc); From e8f149924a3111015d16dfbbb4816cfc75ba53cd Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 7 Dec 2010 19:47:34 +0000 Subject: [PATCH 135/300] sfc: Fix NAPI list corruption during ring reallocation Call netif_napi_{add,del}() on the NAPI contexts in the new and old channels, respectively. Since efx_init_napi() cannot fail, make its return type void. Signed-off-by: Ben Hutchings --- drivers/net/sfc/efx.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index d06cb742164b..fb83cdd94643 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -197,7 +197,9 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value"); static void efx_remove_channels(struct efx_nic *efx); static void efx_remove_port(struct efx_nic *efx); +static void efx_init_napi(struct efx_nic *efx); static void efx_fini_napi(struct efx_nic *efx); +static void efx_fini_napi_channel(struct efx_channel *channel); static void efx_fini_struct(struct efx_nic *efx); static void efx_start_all(struct efx_nic *efx); static void efx_stop_all(struct efx_nic *efx); @@ -430,6 +432,7 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel) *channel = *old_channel; + channel->napi_dev = NULL; memset(&channel->eventq, 0, sizeof(channel->eventq)); rx_queue = &channel->rx_queue; @@ -740,9 +743,13 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries) if (rc) goto rollback; + efx_init_napi(efx); + /* Destroy old channels */ - for (i = 0; i < efx->n_channels; i++) + for (i = 0; i < efx->n_channels; i++) { + efx_fini_napi_channel(other_channel[i]); efx_remove_channel(other_channel[i]); + } out: /* Free unused channel structures */ for (i = 0; i < efx->n_channels; i++) @@ -1601,7 +1608,7 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) * **************************************************************************/ -static int efx_init_napi(struct efx_nic *efx) +static void efx_init_napi(struct efx_nic *efx) { struct efx_channel *channel; @@ -1610,18 +1617,21 @@ static int efx_init_napi(struct efx_nic *efx) netif_napi_add(channel->napi_dev, &channel->napi_str, efx_poll, napi_weight); } - return 0; +} + +static void efx_fini_napi_channel(struct efx_channel *channel) +{ + if (channel->napi_dev) + netif_napi_del(&channel->napi_str); + channel->napi_dev = NULL; } static void efx_fini_napi(struct efx_nic *efx) { struct efx_channel *channel; - efx_for_each_channel(channel, efx) { - if (channel->napi_dev) - netif_napi_del(&channel->napi_str); - channel->napi_dev = NULL; - } + efx_for_each_channel(channel, efx) + efx_fini_napi_channel(channel); } /************************************************************************** @@ -2343,9 +2353,7 @@ static int efx_pci_probe_main(struct efx_nic *efx) if (rc) goto fail1; - rc = efx_init_napi(efx); - if (rc) - goto fail2; + efx_init_napi(efx); rc = efx->type->init(efx); if (rc) { @@ -2376,7 +2384,6 @@ static int efx_pci_probe_main(struct efx_nic *efx) efx->type->fini(efx); fail3: efx_fini_napi(efx); - fail2: efx_remove_all(efx); fail1: return rc; From 1b39d6f37622f1da70aa2cfd38bfff9a52c13e05 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 6 Dec 2010 11:20:45 +0000 Subject: [PATCH 136/300] drm/i915/dp: Only apply the workaround if the select is still active As we may try to power down the link at various times, it is not necessarily still coupled with an encoder and so we must be careful not to depend upon an operation that is only valid when the link is still attached to a pipe. Fixes regression in 5bddd17. Reported-and-tested-by: Daniel Vetter Signed-off-by: Chris Wilson Cc: stable@kernel.org [after applying 5bddd17] --- drivers/gpu/drm/i915/intel_dp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1d8d068bc473..df648cb4c296 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1374,9 +1374,11 @@ intel_dp_link_down(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); uint32_t DP = intel_dp->DP; + if ((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0) + return; + DRM_DEBUG_KMS("\n"); if (is_edp(intel_dp)) { @@ -1400,7 +1402,9 @@ intel_dp_link_down(struct intel_dp *intel_dp) if (is_edp(intel_dp)) DP |= DP_LINK_TRAIN_OFF; - if (!HAS_PCH_CPT(dev) && (DP & DP_PIPEB_SELECT)) { + if (!HAS_PCH_CPT(dev) && + I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { + struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); /* Hardware workaround: leaving our transcoder select * set to transcoder B while it's off will prevent the * corresponding HDMI output on transcoder A. From 943d8d8bca431d6c93f17bf38f4b09c65e0a81d7 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Wed, 1 Dec 2010 19:49:48 +0900 Subject: [PATCH 137/300] dma : EG20T PCH: Fix miss-setting DMA descriptor Currently, in case of using scatter/gather mode, head of data is not sent to destination. The cause is second descriptor address is set to NEXT. The NEXT must have head of descriptor address. This patch sets head of descriptor address to the NEXT. Acked-by: Yong Wang Signed-off-by: Tomoya MORINAGA [dan.j.williams@intel.com: fixed up usage of virt_to_phys()] Signed-off-by: Dan Williams --- drivers/dma/pch_dma.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index 92b679024fed..c064c89420d0 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c @@ -259,11 +259,6 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) return; } - channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr); - channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr); - channel_writel(pd_chan, SIZE, desc->regs.size); - channel_writel(pd_chan, NEXT, desc->regs.next); - dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n", pd_chan->chan.chan_id, desc->regs.dev_addr); dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n", @@ -273,10 +268,16 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n", pd_chan->chan.chan_id, desc->regs.next); - if (list_empty(&desc->tx_list)) + if (list_empty(&desc->tx_list)) { + channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr); + channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr); + channel_writel(pd_chan, SIZE, desc->regs.size); + channel_writel(pd_chan, NEXT, desc->regs.next); pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT); - else + } else { + channel_writel(pd_chan, NEXT, desc->txd.phys); pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); + } val = dma_readl(pd, CTL2); val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id); From ea5d552c73707645c53d42e8a71c9a4d9cbb85c1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 1 Dec 2010 19:41:31 +0000 Subject: [PATCH 138/300] drm: Add missing drm_vblank_put() along queue vblank error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Chris Wilson Cc: Kristian Høgsberg Acked-by: Jesse Barnes Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_irq.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 9d3a5030b6e1..722700d5d73e 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -585,10 +585,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, struct timeval now; unsigned long flags; unsigned int seq; + int ret; e = kzalloc(sizeof *e, GFP_KERNEL); - if (e == NULL) - return -ENOMEM; + if (e == NULL) { + ret = -ENOMEM; + goto err_put; + } e->pipe = pipe; e->base.pid = current->pid; @@ -603,9 +606,8 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, spin_lock_irqsave(&dev->event_lock, flags); if (file_priv->event_space < sizeof e->event) { - spin_unlock_irqrestore(&dev->event_lock, flags); - kfree(e); - return -ENOMEM; + ret = -EBUSY; + goto err_unlock; } file_priv->event_space -= sizeof e->event; @@ -638,6 +640,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, spin_unlock_irqrestore(&dev->event_lock, flags); return 0; + +err_unlock: + spin_unlock_irqrestore(&dev->event_lock, flags); + kfree(e); +err_put: + drm_vblank_put(dev, e->pipe); + return ret; } /** From 541cc966915b6756e54c20eebe60ae957afdb537 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 6 Dec 2010 11:24:07 +0000 Subject: [PATCH 139/300] drm: Don't try and disable an encoder that was never enabled Prevents code that assumes that the encoder is active when asked to be disabled from dying a horrible death. Reported-by: Daniel Vetter Signed-off-by: Chris Wilson Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 7ca59359fee2..bede10a03407 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -241,7 +241,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) } list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (!drm_helper_encoder_in_use(encoder)) { + if (encoder->crtc && !drm_helper_encoder_in_use(encoder)) { drm_encoder_disable(encoder); /* disconnector encoder from any connector */ encoder->crtc = NULL; From 93225b0d7bc030f4a93165347a65893685822d70 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Fri, 3 Dec 2010 16:38:19 -0500 Subject: [PATCH 140/300] drm/radeon/kms: forbid big bo allocation (fdo 31708) v3 Forbid allocating buffer bigger than visible VRAM or GTT, also properly set lpfn field. v2 - use max macro - silence warning v3 - don't explicitly set range limit - use min macro Cc: stable Signed-off-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_object.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1d067743fee0..a598d0049aa5 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -69,7 +69,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) u32 c = 0; rbo->placement.fpfn = 0; - rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT; + rbo->placement.lpfn = 0; rbo->placement.placement = rbo->placements; rbo->placement.busy_placement = rbo->placements; if (domain & RADEON_GEM_DOMAIN_VRAM) @@ -91,7 +91,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, { struct radeon_bo *bo; enum ttm_bo_type type; - int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; + unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; + unsigned long max_size = 0; int r; if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { @@ -104,6 +105,14 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, } *bo_ptr = NULL; + /* maximun bo size is the minimun btw visible vram and gtt size */ + max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); + if ((page_align << PAGE_SHIFT) >= max_size) { + printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n", + __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20); + return -ENOMEM; + } + retry: bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); if (bo == NULL) From dd7cc55a258400440aff5869d3e1e111142297cd Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 3 Dec 2010 14:37:21 -0500 Subject: [PATCH 141/300] drm/radeon/kms: fix formatting of vram and gtt info print the full 64 bit values. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index d8ac1849180d..e12e79326cb1 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -286,7 +286,7 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 mc->mc_vram_size = mc->aper_size; } mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; - dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", + dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", mc->mc_vram_size >> 20, mc->vram_start, mc->vram_end, mc->real_vram_size >> 20); } @@ -323,7 +323,7 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align; } mc->gtt_end = mc->gtt_start + mc->gtt_size - 1; - dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n", + dev_info(rdev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n", mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end); } From 8961d52d4cc52edf5672f8f2712c57162b736793 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 3 Dec 2010 14:37:22 -0500 Subject: [PATCH 142/300] drm/radeon/kms: fix vram base calculation on rs780/rs880 Avoid overflowing a 32 bit value. Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a3552594ccc4..a322d4f647bd 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1195,8 +1195,10 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) mc->vram_end, mc->real_vram_size >> 20); } else { u64 base = 0; - if (rdev->flags & RADEON_IS_IGP) - base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; + if (rdev->flags & RADEON_IS_IGP) { + base = RREG32(MC_VM_FB_LOCATION) & 0xFFFF; + base <<= 24; + } radeon_vram_location(rdev, &rdev->mc, base); rdev->mc.gtt_base_align = 0; radeon_gtt_location(rdev, mc); From c989a7fc139ec8975fdc230e2de42f3c4555880e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 6 Dec 2010 11:09:57 +0100 Subject: [PATCH 143/300] dmaengine i.MX SDMA: initialize on module_init The firmware framework gets initialized during fs_initcall time, so we are not allowed to call request_firmware earlier. Signed-off-by: Sascha Hauer Signed-off-by: Dan Williams --- drivers/dma/imx-sdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 13d6447a35f6..d0602dd5d1b2 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1385,7 +1385,7 @@ static int __init sdma_module_init(void) { return platform_driver_probe(&sdma_driver, sdma_probe); } -subsys_initcall(sdma_module_init); +module_init(sdma_module_init); MODULE_AUTHOR("Sascha Hauer, Pengutronix "); MODULE_DESCRIPTION("i.MX SDMA driver"); From 08a22b392a141c201d7ed4d435de942aa853acd3 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Wed, 1 Dec 2010 10:42:16 +0000 Subject: [PATCH 144/300] nfs: Discard ACL cache on mode update An update of mode bits can result in ACL value being changed. We need to mark the acl cache invalid when we update mode. Similarly we need to update file attribute when we change ACL value Signed-off-by: Aneesh Kumar K.V Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 6a653ffd8e4e..4435e5e1f904 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -3361,6 +3361,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen) ret = nfs_revalidate_inode(server, inode); if (ret < 0) return ret; + if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL) + nfs_zap_acl_cache(inode); ret = nfs4_read_cached_acl(inode, buf, buflen); if (ret != -ENOENT) return ret; @@ -3389,6 +3391,13 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl nfs_inode_return_delegation(inode); buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); ret = nfs4_call_sync(server, &msg, &arg, &res, 1); + /* + * Acl update can result in inode attribute update. + * so mark the attribute cache invalid. + */ + spin_lock(&inode->i_lock); + NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR; + spin_unlock(&inode->i_lock); nfs_access_zap_cache(inode); nfs_zap_acl_cache(inode); return ret; From 21ac19d484a8ffb66f64487846c8d53afef04d2b Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Sun, 28 Nov 2010 21:04:05 +0000 Subject: [PATCH 145/300] NFS: Fix fcntl F_GETLK not reporting some conflicts The commit 129a84de2347002f09721cda3155ccfd19fade40 (locks: fix F_GETLK regression (failure to find conflicts)) fixed the posix_test_lock() function by itself, however, its usage in NFS changed by the commit 9d6a8c5c213e34c475e72b245a8eb709258e968c (locks: give posix_test_lock same interface as ->lock) remained broken - subsequent NFS-specific locking code received F_UNLCK instead of the user-specified lock type. To fix the problem, fl->fl_type needs to be saved before the posix_test_lock() call and restored if no local conflicts were reported. Reference: https://bugzilla.kernel.org/show_bug.cgi?id=23892 Tested-by: Alexander Morozov Signed-off-by: Sergey Vlasov Cc: Signed-off-by: Trond Myklebust --- fs/nfs/file.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 60677f9f1311..7bf029ef4084 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -693,6 +693,7 @@ do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) { struct inode *inode = filp->f_mapping->host; int status = 0; + unsigned int saved_type = fl->fl_type; /* Try local locking first */ posix_test_lock(filp, fl); @@ -700,6 +701,7 @@ do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) /* found a conflict */ goto out; } + fl->fl_type = saved_type; if (nfs_have_delegation(inode, FMODE_READ)) goto out_noconflict; From 0de1b7e800188782973598158e0acbb9e08e6c99 Mon Sep 17 00:00:00 2001 From: Mi Jinlong Date: Sat, 30 Oct 2010 10:19:33 +0800 Subject: [PATCH 146/300] nfs: kernel should return EPROTONOSUPPORT when not support NFSv4 When nfs client(kernel) don't support NFSv4, maybe user build kernel without NFSv4, there is a problem. Using command "mount SERVER-IP:/nfsv3 /mnt/" to mount NFSv3 filesystem, mount should should success, but fail and get error: "mount.nfs: an incorrect mount option was specified" System call mount "nfs"(not "nfs4") with "vers=4", if CONFIG_NFS_V4 is not defined, the "vers=4" will be parsed as invalid argument and kernel return EINVAL to nfs-utils. About that, we really want get EPROTONOSUPPORT rather than EINVAL. This path make sure kernel parses argument success, and return EPROTONOSUPPORT at nfs_validate_mount_data(). Signed-off-by: Mi Jinlong Signed-off-by: Trond Myklebust --- fs/nfs/super.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 3c045044fca2..4100630c9a5b 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -1069,12 +1069,10 @@ static int nfs_parse_mount_options(char *raw, mnt->flags |= NFS_MOUNT_VER3; mnt->version = 3; break; -#ifdef CONFIG_NFS_V4 case Opt_v4: mnt->flags &= ~NFS_MOUNT_VER3; mnt->version = 4; break; -#endif case Opt_udp: mnt->flags &= ~NFS_MOUNT_TCP; mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; @@ -1286,12 +1284,10 @@ static int nfs_parse_mount_options(char *raw, mnt->flags |= NFS_MOUNT_VER3; mnt->version = 3; break; -#ifdef CONFIG_NFS_V4 case NFS4_VERSION: mnt->flags &= ~NFS_MOUNT_VER3; mnt->version = 4; break; -#endif default: goto out_invalid_value; } From 812c4e40c27b6ea103ecfbf91d43654356629b81 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Wed, 1 Dec 2010 08:29:23 +0200 Subject: [PATCH 147/300] ARM: S3C24XX: Fix mess with gpio {set,get}_pull callbacks Currently the {set,get}_pull callbacks of the s3c24xx_gpiocfg_default structure are initalized via s3c_gpio_{get,set}pull_1up. This results in a linker error when only CONFIG_CPU_S3C2442 is selected: arch/arm/plat-s3c24xx/built-in.o:(.data+0x13f4): undefined reference to `s3c_gpio_getpull_1up' arch/arm/plat-s3c24xx/built-in.o:(.data+0x13f8): undefined reference to `s3c_gpio_setpull_1up' The s3c2442 has pulldowns instead of pullups compared to the s3c2440. The method of controlling them is the same though. So this patch modifies the existing s3c_gpio_{get,set}pull_1up helper functions to take an additional parameter deciding whether the pin has a pullup or pulldown. The s3c_gpio_{get,set}pull_1{down,up} functions then wrap that functions passing either S3C_GPIO_PULL_UP or S3C_GPIO_PULL_DOWN. Furthermore this patch sets up the s3c24xx_gpiocfg_default.{get,set}_pull fields in the s3c244{0,2}_map_io function to the new pulldown helper functions. Based on patch from "Lars-Peter Clausen" Signed-off-by: Vasily Khoruzhick Signed-off-by: Ben Dooks --- arch/arm/mach-s3c2440/Kconfig | 1 + arch/arm/mach-s3c2440/s3c2440.c | 11 +++-- arch/arm/mach-s3c2440/s3c2442.c | 14 ++++++ arch/arm/plat-s3c24xx/cpu.c | 8 ++-- arch/arm/plat-s3c24xx/gpiolib.c | 2 - arch/arm/plat-s3c24xx/include/plat/s3c244x.h | 7 ++- arch/arm/plat-samsung/gpio-config.c | 47 +++++++++++++++---- .../include/plat/gpio-cfg-helpers.h | 11 +++++ 8 files changed, 81 insertions(+), 20 deletions(-) diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig index adea6b924cf1..a0cb2581894f 100644 --- a/arch/arm/mach-s3c2440/Kconfig +++ b/arch/arm/mach-s3c2440/Kconfig @@ -18,6 +18,7 @@ config CPU_S3C2440 config CPU_S3C2442 bool select CPU_ARM920T + select S3C_GPIO_PULL_DOWN select S3C2410_CLOCK select S3C2410_GPIO select S3C2410_PM if PM diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c index d50f3ae6173d..f7663f731ea0 100644 --- a/arch/arm/mach-s3c2440/s3c2440.c +++ b/arch/arm/mach-s3c2440/s3c2440.c @@ -46,9 +46,6 @@ int __init s3c2440_init(void) { printk("S3C2440: Initialising architecture\n"); - s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up; - s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up; - /* change irq for watchdog */ s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT; @@ -58,3 +55,11 @@ int __init s3c2440_init(void) return sysdev_register(&s3c2440_sysdev); } + +void __init s3c2440_map_io(void) +{ + s3c244x_map_io(); + + s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up; + s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up; +} diff --git a/arch/arm/mach-s3c2440/s3c2442.c b/arch/arm/mach-s3c2440/s3c2442.c index 188ad1e57dc0..ecf813546554 100644 --- a/arch/arm/mach-s3c2440/s3c2442.c +++ b/arch/arm/mach-s3c2440/s3c2442.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -43,6 +44,11 @@ #include #include +#include + +#include +#include +#include /* S3C2442 extended clock support */ @@ -163,3 +169,11 @@ int __init s3c2442_init(void) return sysdev_register(&s3c2442_sysdev); } + +void __init s3c2442_map_io(void) +{ + s3c244x_map_io(); + + s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1down; + s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1down; +} diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c index 76d0858c3cbb..4a10c0f684b2 100644 --- a/arch/arm/plat-s3c24xx/cpu.c +++ b/arch/arm/plat-s3c24xx/cpu.c @@ -88,7 +88,7 @@ static struct cpu_table cpu_ids[] __initdata = { { .idcode = 0x32440000, .idmask = 0xffffffff, - .map_io = s3c244x_map_io, + .map_io = s3c2440_map_io, .init_clocks = s3c244x_init_clocks, .init_uarts = s3c244x_init_uarts, .init = s3c2440_init, @@ -97,7 +97,7 @@ static struct cpu_table cpu_ids[] __initdata = { { .idcode = 0x32440001, .idmask = 0xffffffff, - .map_io = s3c244x_map_io, + .map_io = s3c2440_map_io, .init_clocks = s3c244x_init_clocks, .init_uarts = s3c244x_init_uarts, .init = s3c2440_init, @@ -106,7 +106,7 @@ static struct cpu_table cpu_ids[] __initdata = { { .idcode = 0x32440aaa, .idmask = 0xffffffff, - .map_io = s3c244x_map_io, + .map_io = s3c2442_map_io, .init_clocks = s3c244x_init_clocks, .init_uarts = s3c244x_init_uarts, .init = s3c2442_init, @@ -115,7 +115,7 @@ static struct cpu_table cpu_ids[] __initdata = { { .idcode = 0x32440aab, .idmask = 0xffffffff, - .map_io = s3c244x_map_io, + .map_io = s3c2442_map_io, .init_clocks = s3c244x_init_clocks, .init_uarts = s3c244x_init_uarts, .init = s3c2442_init, diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c index 24c6f5a30596..243b6411050d 100644 --- a/arch/arm/plat-s3c24xx/gpiolib.c +++ b/arch/arm/plat-s3c24xx/gpiolib.c @@ -82,8 +82,6 @@ static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = { struct s3c_gpio_cfg s3c24xx_gpiocfg_default = { .set_config = s3c_gpio_setcfg_s3c24xx, .get_config = s3c_gpio_getcfg_s3c24xx, - .set_pull = s3c_gpio_setpull_1up, - .get_pull = s3c_gpio_getpull_1up, }; struct s3c_gpio_chip s3c24xx_gpios[] = { diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c244x.h b/arch/arm/plat-s3c24xx/include/plat/s3c244x.h index 307248d1ccbb..89e8d0a25f87 100644 --- a/arch/arm/plat-s3c24xx/include/plat/s3c244x.h +++ b/arch/arm/plat-s3c24xx/include/plat/s3c244x.h @@ -21,17 +21,22 @@ extern void s3c244x_init_clocks(int xtal); #else #define s3c244x_init_clocks NULL #define s3c244x_init_uarts NULL -#define s3c244x_map_io NULL #endif #ifdef CONFIG_CPU_S3C2440 extern int s3c2440_init(void); + +extern void s3c2440_map_io(void); #else #define s3c2440_init NULL +#define s3c2440_map_io NULL #endif #ifdef CONFIG_CPU_S3C2442 extern int s3c2442_init(void); + +extern void s3c2442_map_io(void); #else #define s3c2442_init NULL +#define s3c2442_map_io NULL #endif diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c index b732b773b9af..0aa32f242ee4 100644 --- a/arch/arm/plat-samsung/gpio-config.c +++ b/arch/arm/plat-samsung/gpio-config.c @@ -280,18 +280,17 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, } #endif -#ifdef CONFIG_S3C_GPIO_PULL_UP -int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, - unsigned int off, s3c_gpio_pull_t pull) +#if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN) +static int s3c_gpio_setpull_1(struct s3c_gpio_chip *chip, + unsigned int off, s3c_gpio_pull_t pull, + s3c_gpio_pull_t updown) { void __iomem *reg = chip->base + 0x08; u32 pup = __raw_readl(reg); - pup = __raw_readl(reg); - - if (pup == S3C_GPIO_PULL_UP) + if (pull == updown) pup &= ~(1 << off); - else if (pup == S3C_GPIO_PULL_NONE) + else if (pull == S3C_GPIO_PULL_NONE) pup |= (1 << off); else return -EINVAL; @@ -300,17 +299,45 @@ int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, return 0; } -s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, - unsigned int off) +static s3c_gpio_pull_t s3c_gpio_getpull_1(struct s3c_gpio_chip *chip, + unsigned int off, s3c_gpio_pull_t updown) { void __iomem *reg = chip->base + 0x08; u32 pup = __raw_readl(reg); pup &= (1 << off); - return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP; + return pup ? S3C_GPIO_PULL_NONE : updown; +} +#endif /* CONFIG_S3C_GPIO_PULL_UP || CONFIG_S3C_GPIO_PULL_DOWN */ + +#ifdef CONFIG_S3C_GPIO_PULL_UP +s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, + unsigned int off) +{ + return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP); +} + +int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, + unsigned int off, s3c_gpio_pull_t pull) +{ + return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP); } #endif /* CONFIG_S3C_GPIO_PULL_UP */ +#ifdef CONFIG_S3C_GPIO_PULL_DOWN +s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip, + unsigned int off) +{ + return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN); +} + +int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip, + unsigned int off, s3c_gpio_pull_t pull) +{ + return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN); +} +#endif /* CONFIG_S3C_GPIO_PULL_DOWN */ + #ifdef CONFIG_S5P_GPIO_DRVSTR s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) { diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h index 8fd65d8b5863..0d2c5703f1ee 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h @@ -209,6 +209,17 @@ extern s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, unsigned int off); +/** + * s3c_gpio_getpull_1down() - Get configuration for choice of down or none + * @chip: The gpio chip that the GPIO pin belongs to + * @off: The offset to the pin to get the configuration of. + * + * This helper function reads the state of the pull-down resistor for the + * given GPIO in the same case as s3c_gpio_setpull_1down. +*/ +extern s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip, + unsigned int off); + /** * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443. * @chip: The gpio chip that is being configured. From ed2849d3ecfa339435818eeff28f6c3424300cec Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 16 Nov 2010 16:55:19 +1100 Subject: [PATCH 148/300] sunrpc: prevent use-after-free on clearing XPT_BUSY When an xprt is created, it has a refcount of 1, and XPT_BUSY is set. The refcount is *not* owned by the thread that created the xprt (as is clear from the fact that creators never put the reference). Rather, it is owned by the absence of XPT_DEAD. Once XPT_DEAD is set, (And XPT_BUSY is clear) that initial reference is dropped and the xprt can be freed. So when a creator clears XPT_BUSY it is dropping its only reference and so must not touch the xprt again. However svc_recv, after calling ->xpo_accept (and so getting an XPT_BUSY reference on a new xprt), calls svc_xprt_recieved. This clears XPT_BUSY and then svc_xprt_enqueue - this last without owning a reference. This is dangerous and has been seen to leave svc_xprt_enqueue working with an xprt containing garbage. So we need to hold an extra counted reference over that call to svc_xprt_received. For safety, any time we clear XPT_BUSY and then use the xprt again, we first get a reference, and the put it again afterwards. Note that svc_close_all does not need this extra protection as there are no threads running, and the final free can only be called asynchronously from such a thread. Signed-off-by: NeilBrown Cc: stable@kernel.org Signed-off-by: J. Bruce Fields --- net/sunrpc/svc_xprt.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index ea2ff78dcf7b..3f2c5559ca1a 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -212,6 +212,7 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, spin_lock(&svc_xprt_class_lock); list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) { struct svc_xprt *newxprt; + unsigned short newport; if (strcmp(xprt_name, xcl->xcl_name)) continue; @@ -230,8 +231,9 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, spin_lock_bh(&serv->sv_lock); list_add(&newxprt->xpt_list, &serv->sv_permsocks); spin_unlock_bh(&serv->sv_lock); + newport = svc_xprt_local_port(newxprt); clear_bit(XPT_BUSY, &newxprt->xpt_flags); - return svc_xprt_local_port(newxprt); + return newport; } err: spin_unlock(&svc_xprt_class_lock); @@ -425,8 +427,13 @@ void svc_xprt_received(struct svc_xprt *xprt) { BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); xprt->xpt_pool = NULL; + /* As soon as we clear busy, the xprt could be closed and + * 'put', so we need a reference to call svc_xprt_enqueue with: + */ + svc_xprt_get(xprt); clear_bit(XPT_BUSY, &xprt->xpt_flags); svc_xprt_enqueue(xprt); + svc_xprt_put(xprt); } EXPORT_SYMBOL_GPL(svc_xprt_received); From e281f7ec95fbbf905c10e11c83231f3d9090c22f Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 30 Nov 2010 14:17:58 +0000 Subject: [PATCH 149/300] arm: omap2: io: fix clk_get() error check clk_get() return value should be checked with IS_ERR(). Signed-off-by: Aaro Koskinen Acked-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 40562ddd3ee4..a1939b1e6f82 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -297,7 +297,7 @@ static int __init _omap2_init_reprogram_sdrc(void) return 0; dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck"); - if (!dpll3_m2_ck) + if (IS_ERR(dpll3_m2_ck)) return -EINVAL; rate = clk_get_rate(dpll3_m2_ck); From 2df485a774ba59c3f43bfe84107672c1d9b731a0 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 7 Dec 2010 22:39:17 -0500 Subject: [PATCH 150/300] nfs: remove extraneous and problematic calls to nfs_clear_request When a nfs_page is freed, nfs_free_request is called which also calls nfs_clear_request to clean out the lock and open contexts and free the pagecache page. However, a couple of places in the nfs code call nfs_clear_request themselves. What happens here if the refcount on the request is still high? We'll be releasing contexts and freeing pointers while the request is possibly still in use. Remove those bare calls to nfs_clear_context. That should only be done when the request is being freed. Note that when doing this, we need to watch out for tests of req->wb_page. Previously, nfs_set_page_tag_locked() and nfs_clear_page_tag_locked() would check the value of req->wb_page to figure out if the page is mapped into the nfsi->nfs_page_tree. We now indicate the page is mapped using the new bit PG_MAPPED in req->wb_flags . Reported-by: Jeff Layton Signed-off-by: Trond Myklebust --- fs/nfs/pagelist.c | 4 ++-- fs/nfs/read.c | 1 - fs/nfs/write.c | 3 ++- include/linux/nfs_page.h | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 137b549e63db..b68536cc9046 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -115,7 +115,7 @@ int nfs_set_page_tag_locked(struct nfs_page *req) { if (!nfs_lock_request_dontget(req)) return 0; - if (req->wb_page != NULL) + if (test_bit(PG_MAPPED, &req->wb_flags)) radix_tree_tag_set(&NFS_I(req->wb_context->path.dentry->d_inode)->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); return 1; } @@ -125,7 +125,7 @@ int nfs_set_page_tag_locked(struct nfs_page *req) */ void nfs_clear_page_tag_locked(struct nfs_page *req) { - if (req->wb_page != NULL) { + if (test_bit(PG_MAPPED, &req->wb_flags)) { struct inode *inode = req->wb_context->path.dentry->d_inode; struct nfs_inode *nfsi = NFS_I(inode); diff --git a/fs/nfs/read.c b/fs/nfs/read.c index e4b62c6f5a6e..aedcaa7f291f 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -152,7 +152,6 @@ static void nfs_readpage_release(struct nfs_page *req) (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), req->wb_bytes, (long long)req_offset(req)); - nfs_clear_request(req); nfs_release_request(req); } diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 4c14c17a5276..10d648ea128b 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -390,6 +390,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) if (nfs_have_delegation(inode, FMODE_WRITE)) nfsi->change_attr++; } + set_bit(PG_MAPPED, &req->wb_flags); SetPagePrivate(req->wb_page); set_page_private(req->wb_page, (unsigned long)req); nfsi->npages++; @@ -415,6 +416,7 @@ static void nfs_inode_remove_request(struct nfs_page *req) spin_lock(&inode->i_lock); set_page_private(req->wb_page, 0); ClearPagePrivate(req->wb_page); + clear_bit(PG_MAPPED, &req->wb_flags); radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); nfsi->npages--; if (!nfsi->npages) { @@ -422,7 +424,6 @@ static void nfs_inode_remove_request(struct nfs_page *req) iput(inode); } else spin_unlock(&inode->i_lock); - nfs_clear_request(req); nfs_release_request(req); } diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index f8b60e7f4c44..d55cee73f634 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h @@ -29,6 +29,7 @@ */ enum { PG_BUSY = 0, + PG_MAPPED, PG_CLEAN, PG_NEED_COMMIT, PG_NEED_RESCHED, From 47d092352c132a2d0ee4156b5dca263eaad2c17f Mon Sep 17 00:00:00 2001 From: David Foley Date: Tue, 7 Dec 2010 21:05:59 -0800 Subject: [PATCH 151/300] Input: wacom - add new Bamboo PT (0xdb) Adds new Bamboo Pen & Touch model - Bamboo P & T Special Edition Medium (CTH661/L; Product ID = 0xdb). Tested-by: Tobias Verbeke Signed-off-by: David Foley Acked-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index db747e4c4c4c..4852b440960a 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1440,6 +1440,8 @@ static struct wacom_features wacom_features_0xD8 = { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; static struct wacom_features wacom_features_0xDA = { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; +static struct wacom_features wacom_features_0xDB = + { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; #define USB_DEVICE_WACOM(prod) \ USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ @@ -1510,6 +1512,7 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0xD3) }, { USB_DEVICE_WACOM(0xD8) }, { USB_DEVICE_WACOM(0xDA) }, + { USB_DEVICE_WACOM(0xDB) }, { USB_DEVICE_WACOM(0xF0) }, { USB_DEVICE_WACOM(0xCC) }, { USB_DEVICE_WACOM(0x90) }, From 599bbb9de0fe9c494a223a34d790b353ad4d69f8 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 6 Dec 2010 12:42:46 +1000 Subject: [PATCH 152/300] drm/i915: i915 cannot provide switcher services. it has a DSM but the switcher is done via WMI. Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_acpi.c | 34 ------------------------------- 1 file changed, 34 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c index 65c88f9ba12c..2cb8e0b9f1ee 100644 --- a/drivers/gpu/drm/i915/intel_acpi.c +++ b/drivers/gpu/drm/i915/intel_acpi.c @@ -190,37 +190,6 @@ out: kfree(output.pointer); } -static int intel_dsm_switchto(enum vga_switcheroo_client_id id) -{ - return 0; -} - -static int intel_dsm_power_state(enum vga_switcheroo_client_id id, - enum vga_switcheroo_state state) -{ - return 0; -} - -static int intel_dsm_init(void) -{ - return 0; -} - -static int intel_dsm_get_client_id(struct pci_dev *pdev) -{ - if (intel_dsm_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) - return VGA_SWITCHEROO_IGD; - else - return VGA_SWITCHEROO_DIS; -} - -static struct vga_switcheroo_handler intel_dsm_handler = { - .switchto = intel_dsm_switchto, - .power_state = intel_dsm_power_state, - .init = intel_dsm_init, - .get_client_id = intel_dsm_get_client_id, -}; - static bool intel_dsm_pci_probe(struct pci_dev *pdev) { acpi_handle dhandle, intel_handle; @@ -276,11 +245,8 @@ void intel_register_dsm_handler(void) { if (!intel_dsm_detect()) return; - - vga_switcheroo_register_handler(&intel_dsm_handler); } void intel_unregister_dsm_handler(void) { - vga_switcheroo_unregister_handler(); } From 0bbaee3a58c379c4f7bab9635c71d7bad9c422a2 Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Tue, 7 Dec 2010 21:19:23 +0200 Subject: [PATCH 153/300] ALSA: hda - Reset sample sizes and max bitrates when reading ELD When a new HDMI/DP device is plugged in, hdmi_update_short_audio_desc() is called for every SAD (Short Audio Descriptor) in the ELD data. For LPCM coding type SAD defines the supported sample sizes. For several other coding types (such as AC-3), a maximum bitrate is defined. The maximum bitrate and sample size fields are not always cleared. Therefore, if a device is unplugged and a different one is plugged in, and the coding types of some SAD positions differ between the devices, the old max_bitrate or sample_bits values will persist if the new SADs do not define those values. The leftover max_bitrate and sample_bits do not cause any issues other than wrongly showing up in eld#X.Y procfs file and kernel log. Fix that by always clearing sample_bits and max_bitrate when reading SADs. Signed-off-by: Anssi Hannula Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_eld.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 009031fae2ba..4a663471dadc 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -189,6 +189,9 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a, a->channels = GRAB_BITS(buf, 0, 0, 3); a->channels++; + a->sample_bits = 0; + a->max_bitrate = 0; + a->format = GRAB_BITS(buf, 0, 3, 4); switch (a->format) { case AUDIO_CODING_TYPE_REF_STREAM_HEADER: @@ -198,7 +201,6 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a, case AUDIO_CODING_TYPE_LPCM: val = GRAB_BITS(buf, 2, 0, 3); - a->sample_bits = 0; for (i = 0; i < 3; i++) if (val & (1 << i)) a->sample_bits |= cea_sample_sizes[i + 1]; From 6229cdb23648d0c2875b3fb102cdaf4bf08fcfa4 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 8 Dec 2010 16:27:22 +0100 Subject: [PATCH 154/300] hwmon: (it87) Fix manual fan speed control on IT8721F The manual fan speed control logic of the IT8721F is much different from what older devices had. Update the code to properly support that. Signed-off-by: Jean Delvare Acked-by: Guenter Roeck --- drivers/hwmon/it87.c | 61 ++++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 14a5d981be7d..a428a9264195 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -187,6 +187,7 @@ static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 }; #define IT87_REG_FAN_MAIN_CTRL 0x13 #define IT87_REG_FAN_CTL 0x14 #define IT87_REG_PWM(nr) (0x15 + (nr)) +#define IT87_REG_PWM_DUTY(nr) (0x63 + (nr) * 8) #define IT87_REG_VIN(nr) (0x20 + (nr)) #define IT87_REG_TEMP(nr) (0x29 + (nr)) @@ -251,12 +252,16 @@ struct it87_data { u8 fan_main_ctrl; /* Register value */ u8 fan_ctl; /* Register value */ - /* The following 3 arrays correspond to the same registers. The - * meaning of bits 6-0 depends on the value of bit 7, and we want - * to preserve settings on mode changes, so we have to track all - * values separately. */ + /* The following 3 arrays correspond to the same registers up to + * the IT8720F. The meaning of bits 6-0 depends on the value of bit + * 7, and we want to preserve settings on mode changes, so we have + * to track all values separately. + * Starting with the IT8721F, the manual PWM duty cycles are stored + * in separate registers (8-bit values), so the separate tracking + * is no longer needed, but it is still done to keep the driver + * simple. */ u8 pwm_ctrl[3]; /* Register value */ - u8 pwm_duty[3]; /* Manual PWM value set by user (bit 6-0) */ + u8 pwm_duty[3]; /* Manual PWM value set by user */ u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */ /* Automatic fan speed control registers */ @@ -832,7 +837,9 @@ static ssize_t set_pwm_enable(struct device *dev, data->fan_main_ctrl); } else { if (val == 1) /* Manual mode */ - data->pwm_ctrl[nr] = data->pwm_duty[nr]; + data->pwm_ctrl[nr] = data->type == it8721 ? + data->pwm_temp_map[nr] : + data->pwm_duty[nr]; else /* Automatic mode */ data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); @@ -858,12 +865,25 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, return -EINVAL; mutex_lock(&data->update_lock); - data->pwm_duty[nr] = pwm_to_reg(data, val); - /* If we are in manual mode, write the duty cycle immediately; - * otherwise, just store it for later use. */ - if (!(data->pwm_ctrl[nr] & 0x80)) { - data->pwm_ctrl[nr] = data->pwm_duty[nr]; - it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); + if (data->type == it8721) { + /* If we are in automatic mode, the PWM duty cycle register + * is read-only so we can't write the value */ + if (data->pwm_ctrl[nr] & 0x80) { + mutex_unlock(&data->update_lock); + return -EBUSY; + } + data->pwm_duty[nr] = pwm_to_reg(data, val); + it87_write_value(data, IT87_REG_PWM_DUTY(nr), + data->pwm_duty[nr]); + } else { + data->pwm_duty[nr] = pwm_to_reg(data, val); + /* If we are in manual mode, write the duty cycle immediately; + * otherwise, just store it for later use. */ + if (!(data->pwm_ctrl[nr] & 0x80)) { + data->pwm_ctrl[nr] = data->pwm_duty[nr]; + it87_write_value(data, IT87_REG_PWM(nr), + data->pwm_ctrl[nr]); + } } mutex_unlock(&data->update_lock); return count; @@ -1958,7 +1978,10 @@ static void __devinit it87_init_device(struct platform_device *pdev) * channels to use when later setting to automatic mode later. * Use a 1:1 mapping by default (we are clueless.) * In both cases, the value can (and should) be changed by the user - * prior to switching to a different mode. */ + * prior to switching to a different mode. + * Note that this is no longer needed for the IT8721F and later, as + * these have separate registers for the temperature mapping and the + * manual duty cycle. */ for (i = 0; i < 3; i++) { data->pwm_temp_map[i] = i; data->pwm_duty[i] = 0x7f; /* Full speed */ @@ -2034,10 +2057,16 @@ static void __devinit it87_init_device(struct platform_device *pdev) static void it87_update_pwm_ctrl(struct it87_data *data, int nr) { data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); - if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */ + if (data->type == it8721) { data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; - else /* Manual mode */ - data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f; + data->pwm_duty[nr] = it87_read_value(data, + IT87_REG_PWM_DUTY(nr)); + } else { + if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */ + data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; + else /* Manual mode */ + data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f; + } if (has_old_autopwm(data)) { int i; From 52bc9802ce849d0d287cc5fe76d06b0daa3986ca Mon Sep 17 00:00:00 2001 From: Gabriele Gorla Date: Wed, 8 Dec 2010 16:27:22 +0100 Subject: [PATCH 155/300] hwmon: (adm1026) Fix setting fan_div Prevent setting fan_div from stomping on other fans that share the same I2C register. Signed-off-by: Gabriele Gorla Cc: stable@kernel.org Signed-off-by: Jean Delvare --- drivers/hwmon/adm1026.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 4bf969c0a32b..6f257ce1ae07 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -916,7 +916,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, int nr = sensor_attr->index; struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); - int val, orig_div, new_div, shift; + int val, orig_div, new_div; val = simple_strtol(buf, NULL, 10); new_div = DIV_TO_REG(val); @@ -928,15 +928,17 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, data->fan_div[nr] = DIV_FROM_REG(new_div); if (nr < 4) { /* 0 <= nr < 4 */ - shift = 2 * nr; adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3, - ((DIV_TO_REG(orig_div) & (~(0x03 << shift))) | - (new_div << shift))); + (DIV_TO_REG(data->fan_div[0]) << 0) | + (DIV_TO_REG(data->fan_div[1]) << 2) | + (DIV_TO_REG(data->fan_div[2]) << 4) | + (DIV_TO_REG(data->fan_div[3]) << 6)); } else { /* 3 < nr < 8 */ - shift = 2 * (nr - 4); adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7, - ((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) | - (new_div << shift))); + (DIV_TO_REG(data->fan_div[4]) << 0) | + (DIV_TO_REG(data->fan_div[5]) << 2) | + (DIV_TO_REG(data->fan_div[6]) << 4) | + (DIV_TO_REG(data->fan_div[7]) << 6)); } if (data->fan_div[nr] != orig_div) { From 8b0f1840a46449e1946fc88860ef3ec8d6b1c2c7 Mon Sep 17 00:00:00 2001 From: Gabriele Gorla Date: Wed, 8 Dec 2010 16:27:22 +0100 Subject: [PATCH 156/300] hwmon: (adm1026) Allow 1 as a valid divider value Allow 1 as a valid div value as specified in the ADM1026 datasheet. Signed-off-by: Gabriele Gorla Cc: stable@kernel.org Signed-off-by: Jean Delvare --- drivers/hwmon/adm1026.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 6f257ce1ae07..be0fdd58aa29 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c @@ -920,9 +920,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, val = simple_strtol(buf, NULL, 10); new_div = DIV_TO_REG(val); - if (new_div == 0) { - return -EINVAL; - } + mutex_lock(&data->update_lock); orig_div = data->fan_div[nr]; data->fan_div[nr] = DIV_FROM_REG(new_div); From e83293233faf6e49870e7bfdcddf5374cb463d54 Mon Sep 17 00:00:00 2001 From: Kim Lilliestierna XX Date: Tue, 30 Nov 2010 09:11:22 +0000 Subject: [PATCH 157/300] CAIF: Fix U5500 compile error for shared memory driver Rearrange pr_fmt so it compiles. Signed-off-by: Sjur Braendeland Signed-off-by: David S. Miller --- drivers/net/caif/caif_shm_u5500.c | 2 +- drivers/net/caif/caif_shmcore.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/caif/caif_shm_u5500.c b/drivers/net/caif/caif_shm_u5500.c index 1cd90da86f13..32b1c6fb2de1 100644 --- a/drivers/net/caif/caif_shm_u5500.c +++ b/drivers/net/caif/caif_shm_u5500.c @@ -5,7 +5,7 @@ * License terms: GNU General Public License (GPL) version 2 */ -#define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt +#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt #include #include diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c index 19f9c0656667..80511167f35b 100644 --- a/drivers/net/caif/caif_shmcore.c +++ b/drivers/net/caif/caif_shmcore.c @@ -6,7 +6,7 @@ * License terms: GNU General Public License (GPL) version 2 */ -#define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt +#define pr_fmt(fmt) KBUILD_MODNAME ":" fmt #include #include From c1ac3ffcd0bc7e9617f62be8c7043d53ab84deac Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Thu, 2 Dec 2010 11:14:30 +1100 Subject: [PATCH 158/300] nfsd: Fix possible BUG_ON firing in set_change_info If vfs_getattr in fill_post_wcc returns an error, we don't set fh_post_change. For NFSv4, this can result in set_change_info triggering a BUG_ON. i.e. fh_post_saved being zero isn't really a bug. So: - instead of BUGging when fh_post_saved is zero, just clear ->atomic. - if vfs_getattr fails in fill_post_wcc, take a copy of i_ctime anyway. This will be used i seg_change_info, but not overly trusted. - While we are there, remove the pointless 'if' statements in set_change_info. There is no harm setting all the values. Signed-off-by: NeilBrown Cc: stable@kernel.org Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs3xdr.c | 6 ++++-- fs/nfsd/xdr4.h | 21 ++++++++++----------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 2a533a0af2a9..7e84a852cdae 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -260,9 +260,11 @@ void fill_post_wcc(struct svc_fh *fhp) err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry, &fhp->fh_post_attr); fhp->fh_post_change = fhp->fh_dentry->d_inode->i_version; - if (err) + if (err) { fhp->fh_post_saved = 0; - else + /* Grab the ctime anyway - set_change_info might use it */ + fhp->fh_post_attr.ctime = fhp->fh_dentry->d_inode->i_ctime; + } else fhp->fh_post_saved = 1; } diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 4d476ff08ae6..60fce3dc5cb5 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -484,18 +484,17 @@ static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp) static inline void set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) { - BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved); - cinfo->atomic = 1; + BUG_ON(!fhp->fh_pre_saved); + cinfo->atomic = fhp->fh_post_saved; cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode); - if (cinfo->change_supported) { - cinfo->before_change = fhp->fh_pre_change; - cinfo->after_change = fhp->fh_post_change; - } else { - cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; - cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; - cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec; - cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec; - } + + cinfo->before_change = fhp->fh_pre_change; + cinfo->after_change = fhp->fh_post_change; + cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; + cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; + cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec; + cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec; + } int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); From ce9aeb583a1071304d0e4ab8db600bfc8a6a1b44 Mon Sep 17 00:00:00 2001 From: Dimitris Michailidis Date: Fri, 3 Dec 2010 10:39:04 +0000 Subject: [PATCH 159/300] cxgb4: fix MAC address hash filter Fix the calculation of the inexact hash-based MAC address filter. It's 64 bits but current code is missing a ULL. Results in filtering out some legitimate packets. Signed-off-by: Dimitris Michailidis Signed-off-by: David S. Miller --- drivers/net/cxgb4/t4_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c index bb813d94aea8..e97521c801ea 100644 --- a/drivers/net/cxgb4/t4_hw.c +++ b/drivers/net/cxgb4/t4_hw.c @@ -2408,7 +2408,7 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, if (index < NEXACT_MAC) ret++; else if (hash) - *hash |= (1 << hash_mac_addr(addr[i])); + *hash |= (1ULL << hash_mac_addr(addr[i])); } return ret; } From b1afde60f2b9ee8444fba4e012dc99a3b28d224d Mon Sep 17 00:00:00 2001 From: Nandita Dukkipati Date: Fri, 3 Dec 2010 13:33:44 +0000 Subject: [PATCH 160/300] tcp: Bug fix in initialization of receive window. The bug has to do with boundary checks on the initial receive window. If the initial receive window falls between init_cwnd and the receive window specified by the user, the initial window is incorrectly brought down to init_cwnd. The correct behavior is to allow it to remain unchanged. Signed-off-by: Nandita Dukkipati Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 05b1ecf36763..3c59ab42df2b 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -231,11 +231,10 @@ void tcp_select_initial_window(int __space, __u32 mss, /* when initializing use the value from init_rcv_wnd * rather than the default from above */ - if (init_rcv_wnd && - (*rcv_wnd > init_rcv_wnd * mss)) - *rcv_wnd = init_rcv_wnd * mss; - else if (*rcv_wnd > init_cwnd * mss) - *rcv_wnd = init_cwnd * mss; + if (init_rcv_wnd) + *rcv_wnd = min(*rcv_wnd, init_rcv_wnd * mss); + else + *rcv_wnd = min(*rcv_wnd, init_cwnd * mss); } /* Set the clamp no higher than max representable value */ From 75c1c82566f23dd539fb7ccbf57a1caa7ba82628 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Sat, 4 Dec 2010 14:09:08 +0000 Subject: [PATCH 161/300] ifb: goto resched directly if error happens and dp->tq isn't empty If we break the loop when there are still skbs in tq and no skb in rq, the skbs will be left in txq until new skbs are enqueued into rq. In rare cases, no new skb is queued, then these skbs will stay in rq forever. After this patch, if tq isn't empty when we break the loop, we goto resched directly. Signed-off-by: Changli Gao Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- drivers/net/ifb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index ab9f675c5b8b..fe337bd121aa 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -104,6 +104,8 @@ static void ri_tasklet(unsigned long dev) rcu_read_unlock(); dev_kfree_skb(skb); stats->tx_dropped++; + if (skb_queue_len(&dp->tq) != 0) + goto resched; break; } rcu_read_unlock(); From 35d9b0c906ad92d32a0b8db5daa6fabfcc2f068d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 5 Dec 2010 02:03:26 +0000 Subject: [PATCH 162/300] llc: fix a device refcount imbalance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le dimanche 05 décembre 2010 à 12:23 +0100, Eric Dumazet a écrit : > Le dimanche 05 décembre 2010 à 09:19 +0100, Eric Dumazet a écrit : > > > Hmm.. > > > > If somebody can explain why RTNL is held in arp_ioctl() (and therefore > > in arp_req_delete()), we might first remove RTNL use in arp_ioctl() so > > that your patch can be applied. > > > > Right now it is not good, because RTNL wont be necessarly held when you > > are going to call arp_invalidate() ? > > While doing this analysis, I found a refcount bug in llc, I'll send a > patch for net-2.6 Oh well, of course I must first fix the bug in net-2.6, and wait David pull the fix in net-next-2.6 before sending this rcu conversion. Note: this patch should be sent to stable teams (2.6.34 and up) [PATCH net-2.6] llc: fix a device refcount imbalance commit abf9d537fea225 (llc: add support for SO_BINDTODEVICE) added one refcount imbalance in llc_ui_bind(), because dev_getbyhwaddr() doesnt take a reference on device, while dev_get_by_index() does. Fix this using RCU locking. And since an RCU conversion will be done for 2.6.38 for dev_getbyhwaddr(), put the rcu_read_lock/unlock exactly at their final place. Signed-off-by: Eric Dumazet Cc: stable@kernel.org Cc: Octavian Purdila Signed-off-by: David S. Miller --- net/llc/af_llc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 582612998211..e35dbe55f520 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c @@ -317,8 +317,9 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) goto out; rc = -ENODEV; rtnl_lock(); + rcu_read_lock(); if (sk->sk_bound_dev_if) { - llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); + llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if); if (llc->dev) { if (!addr->sllc_arphrd) addr->sllc_arphrd = llc->dev->type; @@ -329,13 +330,13 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) !llc_mac_match(addr->sllc_mac, llc->dev->dev_addr)) { rc = -EINVAL; - dev_put(llc->dev); llc->dev = NULL; } } } else llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd, addr->sllc_mac); + rcu_read_unlock(); rtnl_unlock(); if (!llc->dev) goto out; From 545c988b2018a593f24d291b66776a0d08525acd Mon Sep 17 00:00:00 2001 From: Suresh Jayaraman Date: Mon, 6 Dec 2010 13:45:50 +0530 Subject: [PATCH 163/300] cifs: remove bogus remapping of error in cifs_filldir() As the FIXME points out correctly, now filldir() itself returns -EOVERFLOW if it not possible to represent the inode number supplied by the filesystem in the field provided by userspace. Signed-off-by: Suresh Jayaraman Reviewed-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/readdir.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 32d300e8f20e..a73eb9f4bdaf 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -759,18 +759,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir, rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, ino, fattr.cf_dtype); - /* - * we can not return filldir errors to the caller since they are - * "normal" when the stat blocksize is too small - we return remapped - * error instead - * - * FIXME: This looks bogus. filldir returns -EOVERFLOW in the above - * case already. Why should we be clobbering other errors from it? - */ - if (rc) { - cFYI(1, "filldir rc = %d", rc); - rc = -EOVERFLOW; - } dput(tmp_dentry); return rc; } From bb31b3122c0dd07d2d958da17a50ad771ce79e2b Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Thu, 2 Dec 2010 17:48:35 +0100 Subject: [PATCH 164/300] EDAC: Fix workqueue-related crashes 00740c58541b6087d78418cebca1fcb86dc6077d changed edac_core to un-/register a workqueue item only if a lowlevel driver supplies a polling routine. Normally, when we remove a polling low-level driver, we go and cancel all the queued work. However, the workqueue unreg happens based on the ->op_state setting, and edac_mc_del_mc() sets this to OP_OFFLINE _before_ we cancel the work item, leading to NULL ptr oops on the workqueue list. Fix it by putting the unreg stuff in proper order. Cc: #36.x Reported-and-tested-by: Tobias Karnat LKML-Reference: <1291201307.3029.21.camel@Tobias-Karnat> Signed-off-by: Borislav Petkov --- drivers/edac/edac_mc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index ba6586a69ccc..795ea69c4d8f 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -586,14 +586,16 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev) return NULL; } - /* marking MCI offline */ - mci->op_state = OP_OFFLINE; - del_mc_from_global_list(mci); mutex_unlock(&mem_ctls_mutex); - /* flush workq processes and remove sysfs */ + /* flush workq processes */ edac_mc_workq_teardown(mci); + + /* marking MCI offline */ + mci->op_state = OP_OFFLINE; + + /* remove from sysfs */ edac_remove_sysfs_mci_device(mci); edac_printk(KERN_INFO, EDAC_MC, From 76f04f2591e60fa76e70a2736965bc810bf1c764 Mon Sep 17 00:00:00 2001 From: Andrei Konovalov Date: Tue, 7 Dec 2010 07:48:00 -0500 Subject: [PATCH 165/300] EDAC: Correct MiB_TO_PAGES() macro This corrects the misprint introduced when moving '#if PAGE_SHIFT' from i7core_edac.c to edac_core.h (commit e9144601d364d5b81f3e63949337f8507eb58dca) Cc: Mauro Carvalho Chehab Signed-off-by: Andrei Konovalov Signed-off-by: Borislav Petkov --- drivers/edac/edac_core.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index d7ca43a828bd..251440cd50a3 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h @@ -41,10 +41,10 @@ #define MC_PROC_NAME_MAX_LEN 7 #if PAGE_SHIFT < 20 -#define PAGES_TO_MiB( pages ) ( ( pages ) >> ( 20 - PAGE_SHIFT ) ) -#define MiB_TO_PAGES(mb) ((mb) >> (20 - PAGE_SHIFT)) +#define PAGES_TO_MiB(pages) ((pages) >> (20 - PAGE_SHIFT)) +#define MiB_TO_PAGES(mb) ((mb) << (20 - PAGE_SHIFT)) #else /* PAGE_SHIFT > 20 */ -#define PAGES_TO_MiB( pages ) ( ( pages ) << ( PAGE_SHIFT - 20 ) ) +#define PAGES_TO_MiB(pages) ((pages) << (PAGE_SHIFT - 20)) #define MiB_TO_PAGES(mb) ((mb) >> (PAGE_SHIFT - 20)) #endif From e726f3c368e7c1919a7166ec09c5705759f1a69d Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 6 Dec 2010 16:20:25 +0100 Subject: [PATCH 166/300] amd64_edac: Fix interleaving check When matching error address to the range contained by one memory node, we're in valid range when node interleaving 1. is disabled, or 2. enabled and when the address bits we interleave on match the interleave selector on this node (see the "Node Interleaving" section in the BKDG for an enlightening example). Thus, when we early-exit, we need to reverse the compound logic statement properly. Cc: Signed-off-by: Borislav Petkov --- drivers/edac/amd64_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 8521401bbd75..eca9ba193e94 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1572,7 +1572,7 @@ static int f10_match_to_this_node(struct amd64_pvt *pvt, int dram_range, debugf1(" HoleOffset=0x%x HoleValid=0x%x IntlvSel=0x%x\n", hole_off, hole_valid, intlv_sel); - if (intlv_en || + if (intlv_en && (intlv_sel != ((sys_addr >> 12) & intlv_en))) return -EINVAL; From 0c62fc6dd02c8d793c75ae76a9b6881fc36388ad Mon Sep 17 00:00:00 2001 From: Nelson Elhage Date: Wed, 8 Dec 2010 10:13:55 -0800 Subject: [PATCH 167/300] econet: Do the correct cleanup after an unprivileged SIOCSIFADDR. We need to drop the mutex and do a dev_put, so set an error code and break like the other paths, instead of returning directly. Signed-off-by: Nelson Elhage Signed-off-by: David S. Miller --- net/econet/af_econet.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 13992e1d2726..f180371fa415 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c @@ -661,8 +661,10 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg) err = 0; switch (cmd) { case SIOCSIFADDR: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; + if (!capable(CAP_NET_ADMIN)) { + err = -EPERM; + break; + } edev = dev->ec_ptr; if (edev == NULL) { From e8d34a884e4ff118920bb57664def8a73b1b784f Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Mon, 6 Dec 2010 02:39:12 +0000 Subject: [PATCH 168/300] l2tp: Fix modalias of l2tp_ip Using the SOCK_DGRAM enum results in "net-pf-2-proto-SOCK_DGRAM-type-115", so use the numeric value like it is done in net/dccp. Signed-off-by: Michal Marek Signed-off-by: David S. Miller --- net/l2tp/l2tp_ip.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 0bf6a59545ab..522e219f3558 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -674,4 +674,8 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("James Chapman "); MODULE_DESCRIPTION("L2TP over IP"); MODULE_VERSION("1.0"); -MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, SOCK_DGRAM, IPPROTO_L2TP); + +/* Use the value of SOCK_DGRAM (2) directory, because __stringify does't like + * enums + */ +MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 2, IPPROTO_L2TP); From 408cc293c29ada769ae772420a39961320da1854 Mon Sep 17 00:00:00 2001 From: Joe Jin Date: Mon, 6 Dec 2010 03:00:59 +0000 Subject: [PATCH 169/300] driver/net/benet: fix be_cmd_multicast_set() memcpy bug Regarding benet be_cmd_multicast_set() function, now using netdev_for_each_mc_addr() helper for mac address copy, but when copying to req->mac[] did not increase of the index. Cc: Sathya Perla Cc: Subbu Seetharaman Cc: Sarveshwar Bandi Cc: Ajit Khaparde Signed-off-by: Joe Jin Signed-off-by: David S. Miller --- drivers/net/benet/be_cmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 36eca1ce75d4..e4465d222a7d 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -1235,7 +1235,7 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, i = 0; netdev_for_each_mc_addr(ha, netdev) - memcpy(req->mac[i].byte, ha->addr, ETH_ALEN); + memcpy(req->mac[i++].byte, ha->addr, ETH_ALEN); } else { req->promiscuous = 1; } From 171995e5d82dcc92bea37a7d2a2ecc21068a0f19 Mon Sep 17 00:00:00 2001 From: Apollon Oikonomopoulos Date: Tue, 7 Dec 2010 09:43:30 +0000 Subject: [PATCH 170/300] x25: decrement netdev reference counts on unload x25 does not decrement the network device reference counts on module unload. Thus unregistering any pre-existing interface after unloading the x25 module hangs and results in unregister_netdevice: waiting for tap0 to become free. Usage count = 1 This patch decrements the reference counts of all interfaces in x25_link_free, the way it is already done in x25_link_device_down for NETDEV_DOWN events. Signed-off-by: Apollon Oikonomopoulos Signed-off-by: David S. Miller --- net/x25/x25_link.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c index 73e7b954ad28..b25c6463c3e9 100644 --- a/net/x25/x25_link.c +++ b/net/x25/x25_link.c @@ -394,6 +394,7 @@ void __exit x25_link_free(void) list_for_each_safe(entry, tmp, &x25_neigh_list) { nb = list_entry(entry, struct x25_neigh, node); __x25_remove_neigh(nb); + dev_put(nb->dev); } write_unlock_bh(&x25_neigh_list_lock); } From 67631510a318d5a930055fe927607f483716e100 Mon Sep 17 00:00:00 2001 From: Tom Herbert Date: Wed, 8 Dec 2010 12:16:33 -0800 Subject: [PATCH 171/300] tcp: Replace time wait bucket msg by counter Rather than printing the message to the log, use a mib counter to keep track of the count of occurences of time wait bucket overflow. Reduces spam in logs. Signed-off-by: Tom Herbert Signed-off-by: David S. Miller --- include/linux/snmp.h | 1 + net/ipv4/proc.c | 1 + net/ipv4/tcp_minisocks.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/snmp.h b/include/linux/snmp.h index ebb0c80ffd6e..12b2b18e50c1 100644 --- a/include/linux/snmp.h +++ b/include/linux/snmp.h @@ -230,6 +230,7 @@ enum LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */ LINUX_MIB_TCPDEFERACCEPTDROP, LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */ + LINUX_MIB_TCPTIMEWAITOVERFLOW, /* TCPTimeWaitOverflow */ __LINUX_MIB_MAX }; diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 1b48eb1ed453..b14ec7d03b6e 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -253,6 +253,7 @@ static const struct snmp_mib snmp4_net_list[] = { SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP), SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP), SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER), + SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW), SNMP_MIB_SENTINEL }; diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 43cf901d7659..a66735f75963 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -347,7 +347,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) * socket up. We've got bigger problems than * non-graceful socket closings. */ - LIMIT_NETDEBUG(KERN_INFO "TCP: time wait bucket table overflow\n"); + NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW); } tcp_update_metrics(sk); From c7757fdb41dfcf6add9f8a4576eb85aa5e77a4eb Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Wed, 8 Dec 2010 12:19:14 -0800 Subject: [PATCH 172/300] ehea: Fixing LRO configuration In order to set LRO on ehea, the user must set a module parameter, which is not the standard way to do so. This patch adds a way to set LRO using the ethtool tool. Signed-off-by: Breno Leitao Signed-off-by: David S. Miller --- drivers/net/ehea/ehea_ethtool.c | 9 +++++++++ drivers/net/ehea/ehea_main.c | 7 +++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c index 75b099ce49c9..1f37ee6b2a26 100644 --- a/drivers/net/ehea/ehea_ethtool.c +++ b/drivers/net/ehea/ehea_ethtool.c @@ -261,6 +261,13 @@ static void ehea_get_ethtool_stats(struct net_device *dev, } +static int ehea_set_flags(struct net_device *dev, u32 data) +{ + return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO + | ETH_FLAG_TXVLAN + | ETH_FLAG_RXVLAN); +} + const struct ethtool_ops ehea_ethtool_ops = { .get_settings = ehea_get_settings, .get_drvinfo = ehea_get_drvinfo, @@ -273,6 +280,8 @@ const struct ethtool_ops ehea_ethtool_ops = { .get_ethtool_stats = ehea_get_ethtool_stats, .get_rx_csum = ehea_get_rx_csum, .set_settings = ehea_set_settings, + .get_flags = ethtool_op_get_flags, + .set_flags = ehea_set_flags, .nway_reset = ehea_nway_reset, /* Restart autonegotiation */ }; diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 3d0af08483a1..b95f087cd5a9 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -683,7 +683,7 @@ static void ehea_proc_skb(struct ehea_port_res *pr, struct ehea_cqe *cqe, int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) && pr->port->vgrp); - if (use_lro) { + if (skb->dev->features & NETIF_F_LRO) { if (vlan_extracted) lro_vlan_hwaccel_receive_skb(&pr->lro_mgr, skb, pr->port->vgrp, @@ -787,7 +787,7 @@ static int ehea_proc_rwqes(struct net_device *dev, } cqe = ehea_poll_rq1(qp, &wqe_index); } - if (use_lro) + if (dev->features & NETIF_F_LRO) lro_flush_all(&pr->lro_mgr); pr->rx_packets += processed; @@ -3278,6 +3278,9 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, | NETIF_F_LLTX; dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; + if (use_lro) + dev->features |= NETIF_F_LRO; + INIT_WORK(&port->reset_task, ehea_reset_port); ret = register_netdev(dev); From 229bd792be0bad245b78ed8f119952733a4752e5 Mon Sep 17 00:00:00 2001 From: David Kilroy Date: Tue, 7 Dec 2010 18:50:42 +0000 Subject: [PATCH 173/300] orinoco: initialise priv->hw before assigning the interrupt The interrupt handler takes a lock - but since commit bcad6e80f3f this lock goes through an indirection specified in the hermes_t structure. We must therefore initialise the structure before setting up the interrupt handler. Fix orinoco_cs and spectrum_cs Bisected by: Matt Domsch Signed-off by: David Kilroy Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/orinoco_cs.c | 14 +++++++------- drivers/net/wireless/orinoco/spectrum_cs.c | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 71b3d68b9403..32954c4b243a 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c @@ -151,20 +151,20 @@ orinoco_cs_config(struct pcmcia_device *link) goto failed; } - ret = pcmcia_request_irq(link, orinoco_interrupt); - if (ret) - goto failed; - - /* We initialize the hermes structure before completing PCMCIA - * configuration just in case the interrupt handler gets - * called. */ mem = ioport_map(link->resource[0]->start, resource_size(link->resource[0])); if (!mem) goto failed; + /* We initialize the hermes structure before completing PCMCIA + * configuration just in case the interrupt handler gets + * called. */ hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); + ret = pcmcia_request_irq(link, orinoco_interrupt); + if (ret) + goto failed; + ret = pcmcia_enable_device(link); if (ret) goto failed; diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index fb859a5ad2eb..db34c282e59b 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c @@ -214,21 +214,21 @@ spectrum_cs_config(struct pcmcia_device *link) goto failed; } - ret = pcmcia_request_irq(link, orinoco_interrupt); - if (ret) - goto failed; - - /* We initialize the hermes structure before completing PCMCIA - * configuration just in case the interrupt handler gets - * called. */ mem = ioport_map(link->resource[0]->start, resource_size(link->resource[0])); if (!mem) goto failed; + /* We initialize the hermes structure before completing PCMCIA + * configuration just in case the interrupt handler gets + * called. */ hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); hw->eeprom_pda = true; + ret = pcmcia_request_irq(link, orinoco_interrupt); + if (ret) + goto failed; + ret = pcmcia_enable_device(link); if (ret) goto failed; From d82b577b8cf89a17cab932db272769dfc69a98df Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Tue, 7 Dec 2010 13:35:55 -0800 Subject: [PATCH 174/300] ath5k: Fix beaconing in mesh mode This patch fixes the oops below when attempting to bring up a mesh interface on ath5k hardware. [ 128.933099] kernel BUG at drivers/net/wireless/ath/ath5k/base.c:197! [ 128.933099] invalid opcode: 0000 [#1] (...) [ 128.933099] Call Trace: [ 128.933099] [] ? ath5k_beacon_update+0x57/0x1f8 [ath5k] [ 128.933099] [] ? __sysfs_add_one+0x28/0x76 [ 128.933099] [] ? ath5k_bss_info_changed+0x13f/0x173 [ath5k] [ 128.933099] [] ? ieee80211_config_beacon+0xc0/0x17e [mac80211] [ 128.933099] [] ? ieee80211_bss_info_change_notify+0x182/0x18b [mac80211] [ 128.933099] [] ? ath5k_bss_info_changed+0x0/0x173 [ath5k] [ 128.933099] [] ? ieee80211_config_beacon+0x16d/0x17e [mac80211] [ 128.933099] [] ? ieee80211_add_beacon+0x34/0x39 [mac80211] [ 128.933099] [] ? ieee80211s_init+0xf8/0x10f [mac80211] [ 128.933099] [] ? ieee80211_mesh_init_sdata+0xdb/0x154 [mac80211] Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 8251946842e6..29b855c426bb 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1949,8 +1949,9 @@ ath5k_beacon_send(struct ath5k_softc *sc) /* NB: hw still stops DMA, so proceed */ } - /* refresh the beacon for AP mode */ - if (sc->opmode == NL80211_IFTYPE_AP) + /* refresh the beacon for AP or MESH mode */ + if (sc->opmode == NL80211_IFTYPE_AP || + sc->opmode == NL80211_IFTYPE_MESH_POINT) ath5k_beacon_update(sc->hw, vif); ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); @@ -2851,7 +2852,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, /* Assign the vap/adhoc to a beacon xmit slot. */ if ((avf->opmode == NL80211_IFTYPE_AP) || - (avf->opmode == NL80211_IFTYPE_ADHOC)) { + (avf->opmode == NL80211_IFTYPE_ADHOC) || + (avf->opmode == NL80211_IFTYPE_MESH_POINT)) { int slot; WARN_ON(list_empty(&sc->bcbuf)); From c26d5339424e68f8643cf3448986c4f77b941a65 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Tue, 7 Dec 2010 13:36:55 -0800 Subject: [PATCH 175/300] ath5k: Prevent mesh interfaces from being counted as ad-hoc This results in an erroneus num_adhoc_vifs count, as the this counter was incremented but not decremented for mesh interfaces. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 29b855c426bb..888502e2bf86 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2872,7 +2872,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, sc->bslot[avf->bslot] = vif; if (avf->opmode == NL80211_IFTYPE_AP) sc->num_ap_vifs++; - else + else if (avf->opmode == NL80211_IFTYPE_ADHOC) sc->num_adhoc_vifs++; } From b93996cf67d47597efad03d5e5431c7b8b11e688 Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Tue, 7 Dec 2010 13:37:56 -0800 Subject: [PATCH 176/300] ath5k: Put the right tsf value in mesh beacons Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 888502e2bf86..42ed923cdb1a 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1917,7 +1917,8 @@ ath5k_beacon_send(struct ath5k_softc *sc) sc->bmisscount = 0; } - if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) { + if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) || + sc->opmode == NL80211_IFTYPE_MESH_POINT) { u64 tsf = ath5k_hw_get_tsf64(ah); u32 tsftu = TSF_TO_TU(tsf); int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval; From f933ebed7888a9a7d73ebeeb6bcbb3f710c423b4 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Wed, 1 Dec 2010 12:30:27 +0530 Subject: [PATCH 177/300] ath9k_htc: Fix suspend/resume The HW has to be set to FULLSLEEP mode during suspend, when no interface has been brought up. Not doing this would break resume, as the chip won't be powered up at all. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 7 +++++++ drivers/net/wireless/ath/ath9k/htc.h | 3 +++ drivers/net/wireless/ath/ath9k/htc_drv_init.c | 6 ++++++ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 4 ++-- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index dfb6560dab92..0de3c3d3c245 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -1024,6 +1024,13 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface, struct hif_device_usb *hif_dev = (struct hif_device_usb *) usb_get_intfdata(interface); + /* + * The device has to be set to FULLSLEEP mode in case no + * interface is up. + */ + if (!(hif_dev->flags & HIF_USB_START)) + ath9k_htc_suspend(hif_dev->htc_handle); + ath9k_hif_usb_dealloc_urbs(hif_dev); return 0; diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 75ecf6a30d25..c3b561daa6c1 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -455,6 +455,8 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv); void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv); void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv); void ath9k_ps_work(struct work_struct *work); +bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, + enum ath9k_power_mode mode); void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); void ath9k_init_leds(struct ath9k_htc_priv *priv); @@ -464,6 +466,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, u16 devid, char *product); void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); #ifdef CONFIG_PM +void ath9k_htc_suspend(struct htc_target *htc_handle); int ath9k_htc_resume(struct htc_target *htc_handle); #endif #ifdef CONFIG_ATH9K_HTC_DEBUGFS diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 7c8a38d04561..8776f49ffd41 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -891,6 +891,12 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug) } #ifdef CONFIG_PM + +void ath9k_htc_suspend(struct htc_target *htc_handle) +{ + ath9k_htc_setpower(htc_handle->drv_priv, ATH9K_PM_FULL_SLEEP); +} + int ath9k_htc_resume(struct htc_target *htc_handle) { int ret; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9a3be8da755d..51977caca47f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -63,8 +63,8 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv, return mode; } -static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, - enum ath9k_power_mode mode) +bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, + enum ath9k_power_mode mode) { bool ret; From 7e2447075690860e2cea96b119fc9cadbaa7e83c Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Thu, 2 Dec 2010 18:44:09 +0100 Subject: [PATCH 178/300] mac80211: Fix BUG in pskb_expand_head when transmitting shared skbs mac80211 doesn't handle shared skbs correctly at the moment. As a result a possible resize can trigger a BUG in pskb_expand_head. [ 676.030000] Kernel bug detected[#1]: [ 676.030000] Cpu 0 [ 676.030000] $ 0 : 00000000 00000000 819662ff 00000002 [ 676.030000] $ 4 : 81966200 00000020 00000000 00000020 [ 676.030000] $ 8 : 819662e0 800043c0 00000002 00020000 [ 676.030000] $12 : 3b9aca00 00000000 00000000 00470000 [ 676.030000] $16 : 80ea2000 00000000 00000000 00000000 [ 676.030000] $20 : 818aa200 80ea2018 80ea2000 00000008 [ 676.030000] $24 : 00000002 800ace5c [ 676.030000] $28 : 8199a000 8199bd20 81938f88 80f180d4 [ 676.030000] Hi : 0000026e [ 676.030000] Lo : 0000757e [ 676.030000] epc : 801245e4 pskb_expand_head+0x44/0x1d8 [ 676.030000] Not tainted [ 676.030000] ra : 80f180d4 ieee80211_skb_resize+0xb0/0x114 [mac80211] [ 676.030000] Status: 1000a403 KERNEL EXL IE [ 676.030000] Cause : 10800024 [ 676.030000] PrId : 0001964c (MIPS 24Kc) [ 676.030000] Modules linked in: mac80211_hwsim rt2800lib rt2x00soc rt2x00pci rt2x00lib mac80211 crc_itu_t crc_ccitt cfg80211 compat arc4 aes_generic deflate ecb cbc [last unloaded: rt2800pci] [ 676.030000] Process kpktgend_0 (pid: 97, threadinfo=8199a000, task=81879f48, tls=00000000) [ 676.030000] Stack : ffffffff 00000000 00000000 00000014 00000004 80ea2000 00000000 00000000 [ 676.030000] 818aa200 80f180d4 ffffffff 0000000a 81879f78 81879f48 81879f48 00000018 [ 676.030000] 81966246 80ea2000 818432e0 80f1a420 80203050 81814d98 00000001 81879f48 [ 676.030000] 81879f48 00000018 81966246 818432e0 0000001a 8199bdd4 0000001c 80f1b72c [ 676.030000] 80203020 8001292c 80ef4aa2 7f10b55d 801ab5b8 81879f48 00000188 80005c90 [ 676.030000] ... [ 676.030000] Call Trace: [ 676.030000] [<801245e4>] pskb_expand_head+0x44/0x1d8 [ 676.030000] [<80f180d4>] ieee80211_skb_resize+0xb0/0x114 [mac80211] [ 676.030000] [<80f1a420>] ieee80211_xmit+0x150/0x22c [mac80211] [ 676.030000] [<80f1b72c>] ieee80211_subif_start_xmit+0x6f4/0x73c [mac80211] [ 676.030000] [<8014361c>] pktgen_thread_worker+0xfac/0x16f8 [ 676.030000] [<8002ebe8>] kthread+0x7c/0x88 [ 676.030000] [<80008e0c>] kernel_thread_helper+0x10/0x18 [ 676.030000] [ 676.030000] [ 676.030000] Code: 24020001 10620005 2502001f <0200000d> 0804917a 00000000 2502001f 00441023 00531021 Fix this by making a local copy of shared skbs prior to mangeling them. To avoid copying the skb unnecessarily move the skb_copy call below the checks that don't need write access to the skb. Also, move the assignment of nh_pos and h_pos below the skb_copy to point to the correct skb. It would be possible to avoid another resize of the copied skb by using skb_copy_expand instead of skb_copy but that would make the patch more complex. Also, shared skbs are a corner case right now, so the resize shouldn't matter much. Cc: Johannes Berg Signed-off-by: Helmut Schaa Cc: stable@kernel.org Signed-off-by: John W. Linville --- net/mac80211/tx.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index df6aac523532..7a637b80a62e 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1737,15 +1737,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, int nh_pos, h_pos; struct sta_info *sta = NULL; u32 sta_flags = 0; + struct sk_buff *tmp_skb; if (unlikely(skb->len < ETH_HLEN)) { ret = NETDEV_TX_OK; goto fail; } - nh_pos = skb_network_header(skb) - skb->data; - h_pos = skb_transport_header(skb) - skb->data; - /* convert Ethernet header to proper 802.11 header (based on * operation mode) */ ethertype = (skb->data[12] << 8) | skb->data[13]; @@ -1918,6 +1916,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, goto fail; } + /* + * If the skb is shared we need to obtain our own copy. + */ + if (skb_shared(skb)) { + tmp_skb = skb; + skb = skb_copy(skb, GFP_ATOMIC); + kfree_skb(tmp_skb); + + if (!skb) { + ret = NETDEV_TX_OK; + goto fail; + } + } + hdr.frame_control = fc; hdr.duration_id = 0; hdr.seq_ctrl = 0; @@ -1936,6 +1948,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, encaps_len = 0; } + nh_pos = skb_network_header(skb) - skb->data; + h_pos = skb_transport_header(skb) - skb->data; + skb_pull(skb, skip_header_bytes); nh_pos -= skip_header_bytes; h_pos -= skip_header_bytes; From ba34fcee476d11e7c9df95932787a22a96ff6e68 Mon Sep 17 00:00:00 2001 From: David Kilroy Date: Sun, 5 Dec 2010 15:45:58 +0000 Subject: [PATCH 179/300] orinoco: clear countermeasure setting on commit ... and interface up. In these situations, you are usually trying to connect to a new AP, so keeping TKIP countermeasures active is confusing. This is already how the driver behaves (inadvertently). However, querying SIOCGIWAUTH may tell userspace that countermeasures are active when they aren't. Clear the setting so that the reporting matches what the driver has done.. Signed-off by: David Kilroy Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/main.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index fa0cf744958f..f3d396e7544b 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c @@ -1811,6 +1811,12 @@ static int __orinoco_commit(struct orinoco_private *priv) struct net_device *dev = priv->ndev; int err = 0; + /* If we've called commit, we are reconfiguring or bringing the + * interface up. Maintaining countermeasures across this would + * be confusing, so note that we've disabled them. The port will + * be enabled later in orinoco_commit or __orinoco_up. */ + priv->tkip_cm_active = 0; + err = orinoco_hw_program_rids(priv); /* FIXME: what about netif_tx_lock */ From 0a54917c3fc295cb61f3fb52373c173fd3b69f48 Mon Sep 17 00:00:00 2001 From: David Kilroy Date: Sun, 5 Dec 2010 15:43:55 +0000 Subject: [PATCH 180/300] orinoco: fix TKIP countermeasure behaviour Enable the port when disabling countermeasures, and disable it on enabling countermeasures. This bug causes the response of the system to certain attacks to be ineffective. It also prevents wpa_supplicant from getting scan results, as wpa_supplicant disables countermeasures on startup - preventing the hardware from scanning. wpa_supplicant works with ap_mode=2 despite this bug because the commit handler re-enables the port. The log tends to look like: State: DISCONNECTED -> SCANNING Starting AP scan for wildcard SSID Scan requested (ret=0) - scan timeout 5 seconds EAPOL: disable timer tick EAPOL: Supplicant port status: Unauthorized Scan timeout - try to get results Failed to get scan results Failed to get scan results - try scanning again Setting scan request: 1 sec 0 usec Starting AP scan for wildcard SSID Scan requested (ret=-1) - scan timeout 5 seconds Failed to initiate AP scan. Reported by: Giacomo Comes Signed-off by: David Kilroy Cc: stable@kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/wext.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index 93505f93bf97..e5afabee60d1 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c @@ -911,10 +911,10 @@ static int orinoco_ioctl_set_auth(struct net_device *dev, */ if (param->value) { priv->tkip_cm_active = 1; - ret = hermes_enable_port(hw, 0); + ret = hermes_disable_port(hw, 0); } else { priv->tkip_cm_active = 0; - ret = hermes_disable_port(hw, 0); + ret = hermes_enable_port(hw, 0); } break; From ad9f4f50fe9288bbe65b7dfd76d8820afac6a24c Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 7 Dec 2010 12:03:55 +0000 Subject: [PATCH 181/300] tcp: avoid a possible divide by zero sysctl_tcp_tso_win_divisor might be set to zero while one cpu runs in tcp_tso_should_defer(). Make sure we dont allow a divide by zero by reading sysctl_tcp_tso_win_divisor exactly once. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 3c59ab42df2b..0d4a3cebfb46 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1512,6 +1512,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) struct tcp_sock *tp = tcp_sk(sk); const struct inet_connection_sock *icsk = inet_csk(sk); u32 send_win, cong_win, limit, in_flight; + int win_divisor; if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) goto send_now; @@ -1543,13 +1544,14 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len)) goto send_now; - if (sysctl_tcp_tso_win_divisor) { + win_divisor = ACCESS_ONCE(sysctl_tcp_tso_win_divisor); + if (win_divisor) { u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); /* If at least some fraction of a window is available, * just use it. */ - chunk /= sysctl_tcp_tso_win_divisor; + chunk /= win_divisor; if (limit >= chunk) goto send_now; } else { From f19872575ff7819a3723154657a497d9bca66b33 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 7 Dec 2010 12:20:47 +0000 Subject: [PATCH 182/300] tcp: protect sysctl_tcp_cookie_size reads Make sure sysctl_tcp_cookie_size is read once in tcp_cookie_size_check(), or we might return an illegal value to caller if sysctl_tcp_cookie_size is changed by another cpu. Signed-off-by: Eric Dumazet Cc: Ben Hutchings Cc: William Allen Simpson Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 0d4a3cebfb46..61c2463e2753 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -385,27 +385,30 @@ struct tcp_out_options { */ static u8 tcp_cookie_size_check(u8 desired) { - if (desired > 0) { + int cookie_size; + + if (desired > 0) /* previously specified */ return desired; - } - if (sysctl_tcp_cookie_size <= 0) { + + cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size); + if (cookie_size <= 0) /* no default specified */ return 0; - } - if (sysctl_tcp_cookie_size <= TCP_COOKIE_MIN) { + + if (cookie_size <= TCP_COOKIE_MIN) /* value too small, specify minimum */ return TCP_COOKIE_MIN; - } - if (sysctl_tcp_cookie_size >= TCP_COOKIE_MAX) { + + if (cookie_size >= TCP_COOKIE_MAX) /* value too large, specify maximum */ return TCP_COOKIE_MAX; - } - if (0x1 & sysctl_tcp_cookie_size) { + + if (cookie_size & 1) /* 8-bit multiple, illegal, fix it */ - return (u8)(sysctl_tcp_cookie_size + 0x1); - } - return (u8)sysctl_tcp_cookie_size; + cookie_size++; + + return (u8)cookie_size; } /* Write previously computed TCP options to the packet. From 7182afea8d1afd432a17c18162cc3fd441d0da93 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 13 Oct 2010 09:13:12 +0000 Subject: [PATCH 183/300] IB/uverbs: Handle large number of entries in poll CQ In ib_uverbs_poll_cq() code there is a potential integer overflow if userspace passes in a large cmd.ne. The calls to kmalloc() would allocate smaller buffers than intended, leading to memory corruption. There iss also an information leak if resp wasn't all used. Unprivileged userspace may call this function, although only if an RDMA device that uses this function is present. Fix this by copying CQ entries one at a time, which avoids the allocation entirely, and also by moving this copying into a function that makes sure to initialize all memory copied to userspace. Special thanks to Jason Gunthorpe for his help and advice. Cc: Signed-off-by: Dan Carpenter [ Monkey around with things a bit to avoid bad code generation by gcc when designated initializers are used. - Roland ] Signed-off-by: Roland Dreier --- drivers/infiniband/core/uverbs_cmd.c | 105 +++++++++++++++------------ 1 file changed, 59 insertions(+), 46 deletions(-) diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index b342248aec05..c42699285f8e 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -893,68 +893,81 @@ out: return ret ? ret : in_len; } +static int copy_wc_to_user(void __user *dest, struct ib_wc *wc) +{ + struct ib_uverbs_wc tmp; + + tmp.wr_id = wc->wr_id; + tmp.status = wc->status; + tmp.opcode = wc->opcode; + tmp.vendor_err = wc->vendor_err; + tmp.byte_len = wc->byte_len; + tmp.ex.imm_data = (__u32 __force) wc->ex.imm_data; + tmp.qp_num = wc->qp->qp_num; + tmp.src_qp = wc->src_qp; + tmp.wc_flags = wc->wc_flags; + tmp.pkey_index = wc->pkey_index; + tmp.slid = wc->slid; + tmp.sl = wc->sl; + tmp.dlid_path_bits = wc->dlid_path_bits; + tmp.port_num = wc->port_num; + tmp.reserved = 0; + + if (copy_to_user(dest, &tmp, sizeof tmp)) + return -EFAULT; + + return 0; +} + ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, const char __user *buf, int in_len, int out_len) { struct ib_uverbs_poll_cq cmd; - struct ib_uverbs_poll_cq_resp *resp; + struct ib_uverbs_poll_cq_resp resp; + u8 __user *header_ptr; + u8 __user *data_ptr; struct ib_cq *cq; - struct ib_wc *wc; - int ret = 0; - int i; - int rsize; + struct ib_wc wc; + int ret; if (copy_from_user(&cmd, buf, sizeof cmd)) return -EFAULT; - wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL); - if (!wc) - return -ENOMEM; - - rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc); - resp = kmalloc(rsize, GFP_KERNEL); - if (!resp) { - ret = -ENOMEM; - goto out_wc; - } - cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0); - if (!cq) { - ret = -EINVAL; - goto out; + if (!cq) + return -EINVAL; + + /* we copy a struct ib_uverbs_poll_cq_resp to user space */ + header_ptr = (void __user *)(unsigned long) cmd.response; + data_ptr = header_ptr + sizeof resp; + + memset(&resp, 0, sizeof resp); + while (resp.count < cmd.ne) { + ret = ib_poll_cq(cq, 1, &wc); + if (ret < 0) + goto out_put; + if (!ret) + break; + + ret = copy_wc_to_user(data_ptr, &wc); + if (ret) + goto out_put; + + data_ptr += sizeof(struct ib_uverbs_wc); + ++resp.count; } - resp->count = ib_poll_cq(cq, cmd.ne, wc); - - put_cq_read(cq); - - for (i = 0; i < resp->count; i++) { - resp->wc[i].wr_id = wc[i].wr_id; - resp->wc[i].status = wc[i].status; - resp->wc[i].opcode = wc[i].opcode; - resp->wc[i].vendor_err = wc[i].vendor_err; - resp->wc[i].byte_len = wc[i].byte_len; - resp->wc[i].ex.imm_data = (__u32 __force) wc[i].ex.imm_data; - resp->wc[i].qp_num = wc[i].qp->qp_num; - resp->wc[i].src_qp = wc[i].src_qp; - resp->wc[i].wc_flags = wc[i].wc_flags; - resp->wc[i].pkey_index = wc[i].pkey_index; - resp->wc[i].slid = wc[i].slid; - resp->wc[i].sl = wc[i].sl; - resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits; - resp->wc[i].port_num = wc[i].port_num; - } - - if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize)) + if (copy_to_user(header_ptr, &resp, sizeof resp)) { ret = -EFAULT; + goto out_put; + } -out: - kfree(resp); + ret = in_len; -out_wc: - kfree(wc); - return ret ? ret : in_len; +out_put: + put_cq_read(cq); + return ret; } ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file, From 4e085e76cbe558b79b54cbab772f61185879bc64 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 8 Dec 2010 18:42:23 -0800 Subject: [PATCH 184/300] econet: Fix crash in aun_incoming(). Unconditional use of skb->dev won't work here, try to fetch the econet device via skb_dst()->dev instead. Suggested by Eric Dumazet. Reported-by: Nelson Elhage Tested-by: Nelson Elhage Signed-off-by: David S. Miller --- net/econet/af_econet.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index f180371fa415..15dcc1a586b4 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c @@ -851,9 +851,13 @@ static void aun_incoming(struct sk_buff *skb, struct aunhdr *ah, size_t len) { struct iphdr *ip = ip_hdr(skb); unsigned char stn = ntohl(ip->saddr) & 0xff; + struct dst_entry *dst = skb_dst(skb); + struct ec_device *edev = NULL; struct sock *sk = NULL; struct sk_buff *newskb; - struct ec_device *edev = skb->dev->ec_ptr; + + if (dst) + edev = dst->dev->ec_ptr; if (! edev) goto bad; From 2b74e12e567feb4163e32815bce0be57489e73b9 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 9 Dec 2010 15:59:01 +1100 Subject: [PATCH 185/300] md: remove handling of flush_pending in md_submit_flush_data None of the functions called between setting flush_pending to 1, and atomic_dec_and_test can change flush_pending, or will anything running in any other thread (as ->flush_bio is not NULL). So the atomic_dec_and_test will always succeed. So remove the atomic_sec and the atomic_dec_and_test. Signed-off-by: NeilBrown --- drivers/md/md.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 84c46a161927..83b6cb3e7025 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -404,8 +404,6 @@ static void md_submit_flush_data(struct work_struct *ws) mddev_t *mddev = container_of(ws, mddev_t, flush_work); struct bio *bio = mddev->flush_bio; - atomic_set(&mddev->flush_pending, 1); - if (bio->bi_size == 0) /* an empty barrier - all done */ bio_endio(bio, 0); @@ -414,10 +412,9 @@ static void md_submit_flush_data(struct work_struct *ws) if (mddev->pers->make_request(mddev, bio)) generic_make_request(bio); } - if (atomic_dec_and_test(&mddev->flush_pending)) { - mddev->flush_bio = NULL; - wake_up(&mddev->sb_wait); - } + + mddev->flush_bio = NULL; + wake_up(&mddev->sb_wait); } void md_flush_request(mddev_t *mddev, struct bio *bio) From a7a07e69653acf8540daa1da053cd84bf86e8e66 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 9 Dec 2010 16:04:25 +1100 Subject: [PATCH 186/300] md: move code in to submit_flushes. submit_flushes is called from exactly one place. Move the code that is before and after that call into submit_flushes. This has not functional change, but will make the next patch smaller and easier to follow. Signed-off-by: NeilBrown --- drivers/md/md.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 83b6cb3e7025..31f8e151d893 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -371,10 +371,14 @@ static void md_end_flush(struct bio *bio, int err) bio_put(bio); } +static void md_submit_flush_data(struct work_struct *ws); + static void submit_flushes(mddev_t *mddev) { mdk_rdev_t *rdev; + INIT_WORK(&mddev->flush_work, md_submit_flush_data); + atomic_set(&mddev->flush_pending, 1); rcu_read_lock(); list_for_each_entry_rcu(rdev, &mddev->disks, same_set) if (rdev->raid_disk >= 0 && @@ -397,6 +401,8 @@ static void submit_flushes(mddev_t *mddev) rdev_dec_pending(rdev, mddev); } rcu_read_unlock(); + if (atomic_dec_and_test(&mddev->flush_pending)) + queue_work(md_wq, &mddev->flush_work); } static void md_submit_flush_data(struct work_struct *ws) @@ -426,13 +432,7 @@ void md_flush_request(mddev_t *mddev, struct bio *bio) mddev->flush_bio = bio; spin_unlock_irq(&mddev->write_lock); - atomic_set(&mddev->flush_pending, 1); - INIT_WORK(&mddev->flush_work, md_submit_flush_data); - submit_flushes(mddev); - - if (atomic_dec_and_test(&mddev->flush_pending)) - queue_work(md_wq, &mddev->flush_work); } EXPORT_SYMBOL(md_flush_request); From a035fc3e2531703b539f23bec4ca7943cfc69349 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 9 Dec 2010 16:17:51 +1100 Subject: [PATCH 187/300] md: fix possible deadlock in handling flush requests. As recorded in https://bugzilla.kernel.org/show_bug.cgi?id=24012 it is possible for a flush request through md to hang. This is due to an interaction between the recursion avoidance in generic_make_request, the insistence in md of only having one flush active at a time, and the possibility of dm (or md) submitting two flush requests to a device from the one generic_make_request. If a generic_make_request call into dm causes two flush requests to be queued (as happens if the dm table has two targets - they get one each), these two will be queued inside generic_make_request. Assume they are for the same md device. The first is processed and causes 1 or more flush requests to be sent to lower devices. These get queued within generic_make_request too. Then the second flush to the md device gets handled and it blocks waiting for the first flush to complete. But it won't complete until the two lower-device requests complete, and they haven't even been submitted yet as they are on the generic_make_request queue. The deadlock can be broken by using a separate thread to submit the requests to lower devices. md has such a thread readily available: md_wq. So use it to submit these requests. Reported-by: Giacomo Catenazzi Tested-by: Giacomo Catenazzi Signed-off-by: NeilBrown --- drivers/md/md.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 31f8e151d893..d66aaeddf95d 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -373,8 +373,9 @@ static void md_end_flush(struct bio *bio, int err) static void md_submit_flush_data(struct work_struct *ws); -static void submit_flushes(mddev_t *mddev) +static void submit_flushes(struct work_struct *ws) { + mddev_t *mddev = container_of(ws, mddev_t, flush_work); mdk_rdev_t *rdev; INIT_WORK(&mddev->flush_work, md_submit_flush_data); @@ -432,7 +433,8 @@ void md_flush_request(mddev_t *mddev, struct bio *bio) mddev->flush_bio = bio; spin_unlock_irq(&mddev->write_lock); - submit_flushes(mddev); + INIT_WORK(&mddev->flush_work, submit_flushes); + queue_work(md_wq, &mddev->flush_work); } EXPORT_SYMBOL(md_flush_request); From 1a855a0606653d2d82506281e2c686bacb4b2f45 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 9 Dec 2010 16:36:28 +1100 Subject: [PATCH 188/300] md: fix bug with re-adding of partially recovered device. With v0.90 metadata, a hot-spare does not become a full member of the array until recovery is complete. So if we re-add such a device to the array, we know that all of it is as up-to-date as the event count would suggest, and so it a bitmap-based recovery is possible. However with v1.x metadata, the hot-spare immediately becomes a full member of the array, but it record how much of the device has been recovered. If the array is stopped and re-assembled recovery starts from this point. When such a device is hot-added to an array we currently lose the 'how much is recovered' information and incorrectly included it as a full in-sync member (after bitmap-based fixup). This is wrong and unsafe and could corrupt data. So be more careful about setting saved_raid_disk - which is what guides the re-adding of devices back into an array. The new code matches the code in slot_store which does a similar thing, which is encouraging. This is suitable for any -stable kernel. Reported-by: "Dailey, Nate" Cc: stable@kernel.org Signed-off-by: NeilBrown --- drivers/md/md.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index d66aaeddf95d..b757da175180 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5159,7 +5159,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) PTR_ERR(rdev)); return PTR_ERR(rdev); } - /* set save_raid_disk if appropriate */ + /* set saved_raid_disk if appropriate */ if (!mddev->persistent) { if (info->state & (1<raid_disk < mddev->raid_disks) @@ -5169,7 +5169,10 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) } else super_types[mddev->major_version]. validate_super(mddev, rdev); - rdev->saved_raid_disk = rdev->raid_disk; + if (test_bit(In_sync, &rdev->flags)) + rdev->saved_raid_disk = rdev->raid_disk; + else + rdev->saved_raid_disk = -1; clear_bit(In_sync, &rdev->flags); /* just to be sure */ if (info->state & (1< Date: Thu, 9 Dec 2010 17:02:14 +1100 Subject: [PATCH 189/300] md: protect against NULL reference when waiting to start a raid10. When we fail to start a raid10 for some reason, we call md_unregister_thread to kill the thread that was created. Unfortunately md_thread() will then make one call into the handler (raid10d) even though md_wakeup_thread has not been called. This is not safe and as md_unregister_thread is called after mddev->private has been set to NULL, it will definitely cause a NULL dereference. So fix this at both ends: - md_thread should only call the handler if THREAD_WAKEUP has been set. - raid10 should call md_unregister_thread before setting things to NULL just like all the other raid modules do. This is applicable to 2.6.35 and later. Cc: stable@kernel.org Reported-by: "Citizen" Signed-off-by: NeilBrown --- drivers/md/md.c | 5 ++--- drivers/md/raid10.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index b757da175180..e71c5fa527f5 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6044,9 +6044,8 @@ static int md_thread(void * arg) || kthread_should_stop(), thread->timeout); - clear_bit(THREAD_WAKEUP, &thread->flags); - - thread->run(thread->mddev); + if (test_and_clear_bit(THREAD_WAKEUP, &thread->flags)) + thread->run(thread->mddev); } return 0; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index c67aa54694ae..0641674827f0 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -2397,13 +2397,13 @@ static int run(mddev_t *mddev) return 0; out_free_conf: + md_unregister_thread(mddev->thread); if (conf->r10bio_pool) mempool_destroy(conf->r10bio_pool); safe_put_page(conf->tmppage); kfree(conf->mirrors); kfree(conf); mddev->private = NULL; - md_unregister_thread(mddev->thread); out: return -EIO; } From e76116ca9671e2e5239054a40303b94feab585ad Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 8 Dec 2010 19:09:42 -0500 Subject: [PATCH 190/300] drm/kms: remove spaces from connector names (v2) Grub doesn't parse spaces in parameters correctly, so this makes it impossible to force video= parameters for kms on the grub kernel command line. v2: shorten the names to make them easier to type. Reported-by: Sergej Pupykin Cc: Sergej Pupykin Signed-off-by: Alex Deucher Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 6985cb1da72c..2baa6708e44c 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -156,12 +156,12 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 }, { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 }, { DRM_MODE_CONNECTOR_Component, "Component", 0 }, - { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 }, - { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 }, - { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 }, - { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 }, + { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 }, + { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 }, + { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 }, + { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 }, { DRM_MODE_CONNECTOR_TV, "TV", 0 }, - { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 }, + { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, }; static struct drm_prop_enum_list drm_encoder_enum_list[] = From 8a96b1e02029aa512199b1b6d281dcede9ed81f1 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Thu, 9 Dec 2010 07:17:27 +0100 Subject: [PATCH 191/300] ALSA: HDA: Quirk for Dell Vostro 320 to make microphone work BugLink: http://launchpad.net/497546 Confirmed that the ideapad model works better than the current quirk for Dell Vostro 320. Cc: stable@kernel.org (2.6.35+) Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 4ab5ea9f0530..76bd58a0e2b6 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3096,8 +3096,7 @@ static const char *cxt5066_models[CXT5066_MODELS] = { static struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), - SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", - CXT5066_DELL_LAPTOP), + SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), From 6f331623b99e1900e3a664bbe6e95406ff4b27f4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 9 Dec 2010 08:35:40 +0300 Subject: [PATCH 192/300] drm: use after free in drm_queue_vblank_event() The "e" pointer is either NULL or freed when we call drm_vblank_put(dev, e->pipe) on the error path. Just pass the "pipe" variable directly instead. I changed another caller to use "pipe" as well for consistency. Signed-off-by: Dan Carpenter Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 722700d5d73e..16d5155edad1 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -628,7 +628,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, if ((seq - vblwait->request.sequence) <= (1 << 23)) { e->event.tv_sec = now.tv_sec; e->event.tv_usec = now.tv_usec; - drm_vblank_put(dev, e->pipe); + drm_vblank_put(dev, pipe); list_add_tail(&e->base.link, &e->base.file_priv->event_list); wake_up_interruptible(&e->base.file_priv->event_wait); trace_drm_vblank_event_delivered(current->pid, pipe, @@ -645,7 +645,7 @@ err_unlock: spin_unlock_irqrestore(&dev->event_lock, flags); kfree(e); err_put: - drm_vblank_put(dev, e->pipe); + drm_vblank_put(dev, pipe); return ret; } From f3886f85cfde578f1d0ba6e40ac5f9d70043923b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 8 Dec 2010 10:05:34 -0500 Subject: [PATCH 193/300] drm/radeon/kms: don't apply 7xx HDP flush workaround on AGP It should be required for all 7xx asics, but seems to cause problems on some AGP 7xx chips. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=19002 Signed-off-by: Alex Deucher Reported-and-Tested-by: Duncan <1i5t5.duncan@cox.net> Cc: stable@kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a322d4f647bd..4d7a2e1bdb90 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -878,12 +878,15 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) u32 tmp; /* flush hdp cache so updates hit vram */ - if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { + if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && + !(rdev->flags & RADEON_IS_AGP)) { void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; u32 tmp; /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL + * This seems to cause problems on some AGP cards. Just use the old + * method for them. */ WREG32(HDP_DEBUG1, 0); tmp = readl((void __iomem *)ptr); @@ -3485,10 +3488,12 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev) void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) { /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read - * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL + * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL. + * This seems to cause problems on some AGP cards. Just use the old + * method for them. */ if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && - rdev->vram_scratch.ptr) { + rdev->vram_scratch.ptr && !(rdev->flags & RADEON_IS_AGP)) { void __iomem *ptr = (void *)rdev->vram_scratch.ptr; u32 tmp; From 4f58670709af7b890eceab325e9e470f209459ca Mon Sep 17 00:00:00 2001 From: Danny Huang Date: Wed, 1 Dec 2010 13:37:28 -0700 Subject: [PATCH 194/300] regulator: tps6586x: Add missing bit mask generation Change-Id: I76eaceb31b56264f6978af15db1e6fc7e2e01b5a Signed-off-by: Danny Huang Signed-off-by: Olof Johansson Signed-off-by: Stephen Warren Acked-by: Mark Brown (Split into separate patches) Signed-off-by: Liam Girdwood --- drivers/regulator/tps6586x-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 51237fbb1bbb..0e59e81fb87d 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -298,14 +298,14 @@ static inline int tps6586x_regulator_preinit(struct device *parent, if (ret) return ret; - if (!(val2 & ri->enable_bit[1])) + if (!(val2 & (1 << ri->enable_bit[1]))) return 0; /* * The regulator is on, but it's enabled with the bit we don't * want to use, so we switch the enable bits */ - if (!(val1 & ri->enable_bit[0])) { + if (!(val1 & (1 << ri->enable_bit[0]))) { ret = tps6586x_set_bits(parent, ri->enable_reg[0], 1 << ri->enable_bit[0]); if (ret) From 64db657b5a45f1676d421e2bdfb7d4910dce87d3 Mon Sep 17 00:00:00 2001 From: Danny Huang Date: Wed, 1 Dec 2010 13:37:29 -0700 Subject: [PATCH 195/300] regulator: tps6586x: Fix TPS6586X_DVM to store goreg/bit Change-Id: Idacf5e1e51dbbbcd5ea93f310a4e907977e7359e Signed-off-by: Danny Huang Signed-off-by: Olof Johansson Signed-off-by: Stephen Warren Acked-by: Mark Brown (Split into separate patches) (Minor formatting fixes) Signed-off-by: Liam Girdwood --- drivers/regulator/tps6586x-regulator.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 0e59e81fb87d..effa6770ead3 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -231,8 +231,7 @@ static int tps6586x_dvm_voltages[] = { }; #define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \ - ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ -{ \ + ereg0, ebit0, ereg1, ebit1) \ .desc = { \ .name = "REG-" #_id, \ .ops = &tps6586x_regulator_##_ops, \ @@ -248,18 +247,26 @@ static int tps6586x_dvm_voltages[] = { .enable_bit[0] = (ebit0), \ .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ .enable_bit[1] = (ebit1), \ - .voltages = tps6586x_##vdata##_voltages, \ -} + .voltages = tps6586x_##vdata##_voltages, + +#define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ + .go_reg = TPS6586X_##goreg, \ + .go_bit = (gobit), #define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \ ereg0, ebit0, ereg1, ebit1) \ +{ \ TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits, \ - ereg0, ebit0, ereg1, ebit1, 0, 0) + ereg0, ebit0, ereg1, ebit1) \ +} #define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \ ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ +{ \ TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits, \ - ereg0, ebit0, ereg1, ebit1, goreg, gobit) + ereg0, ebit0, ereg1, ebit1) \ + TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ +} static struct tps6586x_regulator tps6586x_regulator[] = { TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0), From 1dbcf35cb5b775e564a793a338c7c3eb65fc6980 Mon Sep 17 00:00:00 2001 From: Danny Huang Date: Wed, 1 Dec 2010 13:37:30 -0700 Subject: [PATCH 196/300] regulator: tps6586x: Handle both enable reg/bits being the same Change-Id: I40400bb65eab496bb1becd26b37a9653b99d4f41 Signed-off-by: Danny Huang Signed-off-by: Olof Johansson Signed-off-by: Stephen Warren Acked-by: Mark Brown (Split into separate patches) Signed-off-by: Liam Girdwood --- drivers/regulator/tps6586x-regulator.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index effa6770ead3..c668944dc3ad 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -297,6 +297,10 @@ static inline int tps6586x_regulator_preinit(struct device *parent, uint8_t val1, val2; int ret; + if (ri->enable_reg[0] == ri->enable_reg[1] && + ri->enable_bit[0] == ri->enable_bit[1]) + return 0; + ret = tps6586x_read(parent, ri->enable_reg[0], &val1); if (ret) return ret; From 1b39ed0cf51193f3ba03044369ab4d144712a9b8 Mon Sep 17 00:00:00 2001 From: Danny Huang Date: Wed, 1 Dec 2010 13:37:31 -0700 Subject: [PATCH 197/300] regulator: tps6586x: correct register table Correct the register table for SM2, LDO8, RTC Change-Id: I45348cec5ffbb7da9bd7523764fb611b537236b8 Signed-off-by: Danny Huang Signed-off-by: Olof Johansson Signed-off-by: Stephen Warren Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- drivers/regulator/tps6586x-regulator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index c668944dc3ad..6d20b0454a1d 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -274,11 +274,11 @@ static struct tps6586x_regulator tps6586x_regulator[] = { TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), - TPS6586X_LDO(LDO_8, ldo, SUPPLYV1, 5, 3, ENC, 6, END, 6), + TPS6586X_LDO(LDO_8, ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6), TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), - TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, ENE, 7, ENE, 7), + TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), - TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 1, END, 1), + TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6), TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6), From 057f02a38e67a944a2d0b89bb0111efb9dbe6e6e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 12 Nov 2010 07:31:46 +0300 Subject: [PATCH 198/300] [SCSI] osd: checking NULL instead of ERR_PTR() bio_map_kern() returns ERR_PTRs on failure and never returns NULL. [jejb: remove redundant unlikely spotted by Tobias Klauser] Signed-off-by: Dan Carpenter Acked-by: Boaz Harrosh Signed-off-by: James Bottomley --- drivers/scsi/osd/osd_initiator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 0433ea6f27c9..b37c8a3c1bb0 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c @@ -951,8 +951,8 @@ static int _osd_req_finalize_cdb_cont(struct osd_request *or, const u8 *cap_key) /* create a bio for continuation segment */ bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes, GFP_KERNEL); - if (unlikely(!bio)) - return -ENOMEM; + if (IS_ERR(bio)) + return PTR_ERR(bio); bio->bi_rw |= REQ_WRITE; From c7a841f3aca469187db76842676951a672fd27d1 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 14 Nov 2010 11:12:04 -0500 Subject: [PATCH 199/300] [SCSI] bsg: correct fault if queue object removed while dev_t open This patch corrects an issue in bsg that results in a general protection fault if an LLD is removed while an application is using an open file handle to a bsg device, and the application issues an ioctl. The fault occurs because the class_dev is NULL, having been cleared in bsg_unregister_queue() when the driver was removed. With this patch, a check is made for the class_dev, and the application will receive ENXIO if the related object is gone. Signed-off-by: Carl Lajeunesse Signed-off-by: James Smart Signed-off-by: James Bottomley --- block/bsg.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/block/bsg.c b/block/bsg.c index f20d6a789d48..0c8b64a16484 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -250,6 +250,14 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm, int ret, rw; unsigned int dxfer_len; void *dxferp = NULL; + struct bsg_class_device *bcd = &q->bsg_dev; + + /* if the LLD has been removed then the bsg_unregister_queue will + * eventually be called and the class_dev was freed, so we can no + * longer use this request_queue. Return no such address. + */ + if (!bcd->class_dev) + return ERR_PTR(-ENXIO); dprintk("map hdr %llx/%u %llx/%u\n", (unsigned long long) hdr->dout_xferp, hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp, From 5da61410054d125e63aeab9cc7a11874a69465c0 Mon Sep 17 00:00:00 2001 From: Anil Ravindranath Date: Tue, 16 Nov 2010 13:43:41 -0800 Subject: [PATCH 200/300] [SCSI] pmcraid: disable msix and expand device config entry Firmware requires a larger configuration entry size than the driver currently allows, and MSI-X pretty much doesn't work with current FW, so disable it for now. Signed-off-by: Anil Ravindranath Signed-off-by: James Bottomley --- drivers/scsi/pmcraid.c | 4 +++- drivers/scsi/pmcraid.h | 6 ++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 5e76a624cb08..300d59f389da 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -62,6 +62,7 @@ static unsigned int pmcraid_debug_log; static unsigned int pmcraid_disable_aen; static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST; +static unsigned int pmcraid_enable_msix; /* * Data structures to support multiple adapters by the LLD. @@ -4691,7 +4692,8 @@ pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance) int rc; struct pci_dev *pdev = pinstance->pdev; - if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { + if ((pmcraid_enable_msix) && + (pci_find_capability(pdev, PCI_CAP_ID_MSIX))) { int num_hrrq = PMCRAID_NUM_MSIX_VECTORS; struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS]; int i; diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h index 1134279604e8..4db210d93947 100644 --- a/drivers/scsi/pmcraid.h +++ b/drivers/scsi/pmcraid.h @@ -42,7 +42,7 @@ */ #define PMCRAID_DRIVER_NAME "PMC MaxRAID" #define PMCRAID_DEVFILE "pmcsas" -#define PMCRAID_DRIVER_VERSION "2.0.3" +#define PMCRAID_DRIVER_VERSION "1.0.3" #define PMCRAID_DRIVER_DATE __DATE__ #define PMCRAID_FW_VERSION_1 0x002 @@ -333,11 +333,9 @@ struct pmcraid_config_table_entry { __u8 lun[PMCRAID_LUN_LEN]; } __attribute__((packed, aligned(4))); -/* extended configuration table sizes are of 64 bytes in size */ -#define PMCRAID_CFGTE_EXT_SIZE 32 +/* extended configuration table sizes are also of 32 bytes in size */ struct pmcraid_config_table_entry_ext { struct pmcraid_config_table_entry cfgte; - __u8 cfgte_ext[PMCRAID_CFGTE_EXT_SIZE]; }; /* resource types (config_table_entry.resource_type values) */ From 459dbf72e4d2b4aa13620e6b70d54f098547bf13 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Wed, 17 Nov 2010 10:10:57 -0600 Subject: [PATCH 201/300] [SCSI] Eliminate error handler overload of the SCSI serial number The error handler is using the test cmd->serial_number == 0 in the abort routines to signal that the command to be aborted has already completed normally. This design was to close a race window in the original error handler where a command could go through the normal completion routines after it timed out but before error handling was started. Mike Anderson pointed out that when we converted our timeout and softirq completions, we picked up atomicity here because the block layer now mediates this with the REQ_ATOM_COMPLETE flag and guarantees that *either* the command times out or our done routine is called, but ensures we can't get both occurring. That makes the serial number zero check redundant and it can be removed. Signed-off-by: James Bottomley --- drivers/scsi/scsi_error.c | 26 ++------------------------ drivers/scsi/scsi_lib.c | 5 ----- 2 files changed, 2 insertions(+), 29 deletions(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 824b8fc03ce5..30ac116186f5 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -615,7 +615,7 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd) return rtn; } -static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) +static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) { if (!scmd->device->host->hostt->eh_abort_handler) return FAILED; @@ -623,31 +623,9 @@ static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) return scmd->device->host->hostt->eh_abort_handler(scmd); } -/** - * scsi_try_to_abort_cmd - Ask host to abort a running command. - * @scmd: SCSI cmd to abort from Lower Level. - * - * Notes: - * This function will not return until the user's completion function - * has been called. there is no timeout on this operation. if the - * author of the low-level driver wishes this operation to be timed, - * they can provide this facility themselves. helper functions in - * scsi_error.c can be supplied to make this easier to do. - */ -static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) -{ - /* - * scsi_done was called just after the command timed out and before - * we had a chance to process it. (db) - */ - if (scmd->serial_number == 0) - return SUCCESS; - return __scsi_try_to_abort_cmd(scmd); -} - static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) { - if (__scsi_try_to_abort_cmd(scmd) != SUCCESS) + if (scsi_try_to_abort_cmd(scmd) != SUCCESS) if (scsi_try_bus_device_reset(scmd) != SUCCESS) if (scsi_try_target_reset(scmd) != SUCCESS) if (scsi_try_bus_reset(scmd) != SUCCESS) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index eafeeda6e194..5b6bbaea59fe 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1403,11 +1403,6 @@ static void scsi_softirq_done(struct request *rq) INIT_LIST_HEAD(&cmd->eh_entry); - /* - * Set the serial numbers back to zero - */ - cmd->serial_number = 0; - atomic_inc(&cmd->device->iodone_cnt); if (cmd->result) atomic_inc(&cmd->device->ioerr_cnt); From 5bfb2c31487eaff3840e02548e6acf89a048765b Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 17 Nov 2010 14:23:40 +0100 Subject: [PATCH 202/300] [SCSI] zfcp: Fix common FCP request reception The reception of a common FCP request should only be evaluated if the corresponding SCSI request data is available. Therefore put the information under the lock protection and verify the existence before processing. This fixes the following kernel panic. Unable to handle kernel pointer dereference at virtual kernel address 0000000180000000 Oops: 003b [#1] PREEMPT SMP DEBUG_PAGEALLOC CPU: 0 Not tainted 2.6.35.7-45.x.20101007-s390xdefault #1 Process blast (pid: 9711, task: 00000000a3be8e40, ksp: 00000000b221bac0) Krnl PSW : 0704300180000000 0000000000489878 (zfcp_fsf_fcp_handler_common+0x4c/0x3a0) R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:0 CC:3 PM:0 EA:3 Krnl GPRS: 00000000b663c1b8 0000000180000000 000000007ab5bdf0 0000000000000000 00000000b0ccd800 0000000000000018 07000000a3be8e78 00000000b5d3e600 000000007ab5bdf0 0000000000000066 00000000b72137f0 00000000b72137f0 0000000000000000 00000000005a8178 00000000bdf37a60 00000000bdf379f0 Krnl Code: 0000000000489866: e3c030000004 lg %r12,0(%r3) 000000000048986c: e310c0000004 lg %r1,0(%r12) 0000000000489872: e31011e00004 lg %r1,480(%r1) >0000000000489878: 581011ec l %r1,492(%r1) 000000000048987c: a774001c brc 7,4898b4 0000000000489880: b91400b1 lgfr %r11,%r1 0000000000489884: 5810405c l %r1,92(%r4) 0000000000489888: 5510d00c cl %r1,12(%r13) Call Trace: ([<000000000010d344>] debug_event_common+0x22c/0x244) [<000000000048a0b4>] zfcp_fsf_fcp_cmnd_handler+0x2c/0x3b4 [<000000000048b5b6>] zfcp_fsf_req_complete+0x1b6/0x9dc [<000000000048bede>] zfcp_fsf_reqid_check+0x102/0x138 [<000000000048e478>] zfcp_qdio_int_resp+0x70/0x110 [<000000000044a1ec>] qdio_kick_handler+0xb0/0x19c [<000000000044c228>] __tiqdio_inbound_processing+0x30c/0xebc [<000000000014a5fc>] tasklet_action+0x1b4/0x1e8 [<000000000014b676>] __do_softirq+0x106/0x1cc [<000000000010d91a>] do_softirq+0xe6/0xec [<000000000014b0c8>] irq_exit+0xd4/0xd8 [<00000000004307ec>] do_IRQ+0x7c0/0xf54 [<0000000000114d28>] io_return+0x0/0x16 [<000000000055fef0>] sub_preempt_count+0x50/0xe4 ([<00000000b1f873c0>] 0xb1f873c0) [<000000000055e25a>] _raw_spin_unlock+0x46/0x74 [<0000000000241c40>] __d_lookup+0x288/0x2c8 [<000000000023502c>] do_lookup+0x7c/0x25c [<0000000000237fa8>] link_path_walk+0x5e4/0xe2c [<0000000000238a00>] path_walk+0x98/0x148 [<0000000000238c98>] do_path_lookup+0x74/0xc0 [<000000000023989c>] user_path_at+0x64/0xa4 [<000000000022e366>] vfs_fstatat+0x4e/0xb0 [<000000000022e4d6>] SyS_newstat+0x2e/0x54 [<00000000001146de>] sysc_noemu+0x10/0x16 [<0000020000153456>] 0x20000153456 INFO: lockdep is turned off. Last Breaking-Event-Address: [<000000000048a0ae>] zfcp_fsf_fcp_cmnd_handler+0x26/0x3b4 Signed-off-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_fsf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index be0317457147..aa0cd2322738 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -2069,8 +2069,6 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req) struct fcp_resp_with_ext *fcp_rsp; unsigned long flags; - zfcp_fsf_fcp_handler_common(req); - read_lock_irqsave(&req->adapter->abort_lock, flags); scpnt = req->data; @@ -2079,6 +2077,8 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req) return; } + zfcp_fsf_fcp_handler_common(req); + if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) { set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED); goto skip_fsfstatus; From 6fbf25e86beef1c6719e760a241a7aef9ad145e3 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 17 Nov 2010 14:23:41 +0100 Subject: [PATCH 203/300] [SCSI] zfcp: Correct false abort data assignment. The request data assignment between the fsf abort initiator and its corresponding handler is not consistent and leads to an unpredictable behaviour, e.g. kernel panic. This patch fixes this issue and assigns the correct value. Signed-off-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_fsf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index aa0cd2322738..f75707a8de2b 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -851,7 +851,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd) zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); - req->data = zfcp_sdev; + req->data = sdev; req->handler = zfcp_fsf_abort_fcp_command_handler; req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; req->qtcb->header.port_handle = zfcp_sdev->port->handle; From d3e1088d68735eb7da12f79a0c3c0d951cbc89f1 Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 17 Nov 2010 14:23:42 +0100 Subject: [PATCH 204/300] [SCSI] zfcp: No ERP escalation on gpn_ft eval If the evaluation of GPN_FT requests wants to remove an invalid port from the system the zfcp_erp_port_shutdown function is triggered. Depending on the system status a superior action (e.g. adapter reopen) is required. This can lead to an invalid mem access of the port struct which might be freed at the time since the superior action is not holding a reference of the port which triggered this ERP action. Signed-off-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_erp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index d37c7331f244..63422c13c7da 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -156,6 +156,8 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) || a_status & ZFCP_STATUS_COMMON_ERP_FAILED) return 0; + if (p_status & ZFCP_STATUS_COMMON_NOESC) + return need; if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED)) need = ZFCP_ERP_ACTION_REOPEN_ADAPTER; /* fall through */ From 14718e3cd8e9c6937114cebbf3ce5d504328da8c Mon Sep 17 00:00:00 2001 From: Swen Schillig Date: Wed, 17 Nov 2010 14:23:43 +0100 Subject: [PATCH 205/300] [SCSI] zfcp: Prevent usage w/o holding a reference The ERP got values assigned for which no reference was taken. This can lead to an unpredictable race condition. Fix this by only assigning the values which are required and for which a reference was pulled or is held implicitly. Signed-off-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_erp.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 63422c13c7da..0bcd5806bd9a 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -190,6 +190,9 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &zfcp_sdev->status); erp_action = &zfcp_sdev->erp_action; + memset(erp_action, 0, sizeof(struct zfcp_erp_action)); + erp_action->port = port; + erp_action->sdev = sdev; if (!(atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_RUNNING)) act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; @@ -202,6 +205,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, zfcp_erp_action_dismiss_port(port); atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); erp_action = &port->erp_action; + memset(erp_action, 0, sizeof(struct zfcp_erp_action)); + erp_action->port = port; if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING)) act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; break; @@ -211,6 +216,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, zfcp_erp_action_dismiss_adapter(adapter); atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); erp_action = &adapter->erp_action; + memset(erp_action, 0, sizeof(struct zfcp_erp_action)); if (!(atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_RUNNING)) act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; @@ -220,10 +226,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, return NULL; } - memset(erp_action, 0, sizeof(struct zfcp_erp_action)); erp_action->adapter = adapter; - erp_action->port = port; - erp_action->sdev = sdev; erp_action->action = need; erp_action->status = act_status; From e55f87531c2c1eb071a296df7eb67f83d5f0b5df Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Thu, 18 Nov 2010 14:53:18 +0100 Subject: [PATCH 206/300] [SCSI] zfcp: Issue FCP command without holding SCSI host_lock Interrupting the connection to the FCP channel while I/O requests are being issued can lead to this deadlock. scsi_dispatch_cmd already holds the host_lock while the recovery trigger tries to acquire the host_lock again when iterating through the scsi_devices. INFO: lockdep is turned off. BUG: spinlock lockup on CPU#1, blast/9660, 0000000078f38878 CPU: 1 Not tainted 2.6.35.7SWEN2 #2 Process blast (pid: 9660, task: 0000000071f75940, ksp: 0000000074393ac0) 0000000074393640 00000000743935c0 0000000000000002 0000000000000000 0000000074393660 00000000743935d8 00000000743935d8 00000000005590c2 0000000000000000 0000000078f38878 0000000026ede800 0000000078f38878 000000000000000d 040000000000000c 0000000074393628 0000000000000000 0000000000000000 0000000000100b2a 00000000743935c0 0000000074393600 Call Trace: ([<0000000000100a32>] show_trace+0xee/0x144) [<00000000003be202>] do_raw_spin_lock+0x112/0x178 [<000000000055d408>] _raw_spin_lock_irqsave+0x90/0xb0 [<00000000003f1514>] __scsi_iterate_devices+0x38/0xbc [<00000000004849b0>] zfcp_erp_clear_adapter_status+0xd0/0x16c [<000000000048587a>] zfcp_erp_adapter_reopen+0x3a/0xb4 [<0000000000489812>] zfcp_fsf_req_send+0x166/0x180 [<000000000048c8d6>] zfcp_fsf_fcp_cmnd+0x272/0x408 [<000000000048f864>] zfcp_scsi_queuecommand+0x11c/0x1e0 [<00000000003f1f2a>] scsi_dispatch_cmd+0x1d6/0x324 [<00000000003f9910>] scsi_request_fn+0x42c/0x56c [<00000000003828ae>] __blk_run_queue+0x86/0x140 [<000000000037f742>] elv_insert+0x11a/0x208 [<000000000038104c>] blk_insert_cloned_request+0x84/0xe4 [<000003c0032b7c64>] dm_dispatch_request+0x6c/0x94 [dm_mod] [<000003c0032b7d5c>] map_request+0xd0/0x100 [dm_mod] [<000003c0032b9a78>] dm_request_fn+0xec/0x1bc [dm_mod] [<0000000000382c0e>] generic_unplug_device+0x5a/0x6c [<000003c0032b7f98>] dm_unplug_all+0x74/0x9c [dm_mod] [<00000000001d1272>] sync_page+0x76/0x9c [<00000000001d12ba>] sync_page_killable+0x22/0x60 [<000000000055a768>] __wait_on_bit_lock+0xc0/0x124 [<00000000001d1140>] __lock_page_killable+0x78/0x84 [<00000000001d351c>] generic_file_aio_read+0x5a4/0x7e8 [<0000000000228ec0>] do_sync_read+0xc8/0x12c [<0000000000229edc>] vfs_read+0xac/0x1ac [<000000000022a0d8>] SyS_read+0x58/0xa8 [<00000000001146de>] sysc_noemu+0x10/0x16 [<00000200000493c4>] 0x200000493c4 INFO: lockdep is turned off. Call zfcp_fsf_fcp_cmnd without the host_lock and disable the interrupts when acquiring the req_q_lock. According to the patch description in "[PATCH] Eliminate error handler overload of the SCSI serial number", the serial_number is not used, so simply drop the queuecommand wrapper function and run zfcp_scsi_queuecommand without holding the host_lock. Reviewed-by: Swen Schillig Signed-off-by: Christof Schmitt Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_fsf.c | 5 +++-- drivers/s390/scsi/zfcp_scsi.c | 7 ++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index f75707a8de2b..2eb7dd56ab80 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -2170,12 +2170,13 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd) struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; struct zfcp_qdio *qdio = adapter->qdio; struct fsf_qtcb_bottom_io *io; + unsigned long flags; if (unlikely(!(atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_UNBLOCKED))) return -EBUSY; - spin_lock(&qdio->req_q_lock); + spin_lock_irqsave(&qdio->req_q_lock, flags); if (atomic_read(&qdio->req_q_free) <= 0) { atomic_inc(&qdio->req_q_full); goto out; @@ -2239,7 +2240,7 @@ failed_scsi_cmnd: zfcp_fsf_req_free(req); scsi_cmnd->host_scribble = NULL; out: - spin_unlock(&qdio->req_q_lock); + spin_unlock_irqrestore(&qdio->req_q_lock, flags); return retval; } diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 6bd2dbc4c316..63529ed801eb 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -76,8 +76,8 @@ static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) scpnt->scsi_done(scpnt); } -static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt, - void (*done) (struct scsi_cmnd *)) +static +int zfcp_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scpnt) { struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; @@ -87,7 +87,6 @@ static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt, /* reset the status for this request */ scpnt->result = 0; scpnt->host_scribble = NULL; - scpnt->scsi_done = done; scsi_result = fc_remote_port_chkready(rport); if (unlikely(scsi_result)) { @@ -127,8 +126,6 @@ static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt, return ret; } -static DEF_SCSI_QCMD(zfcp_scsi_queuecommand) - static int zfcp_scsi_slave_alloc(struct scsi_device *sdev) { struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); From 955256f2c3e25c94ad373c43fbc38d2ac8af2a71 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 19 Nov 2010 09:41:10 -0500 Subject: [PATCH 207/300] Btrfs: fix use after free in O_DIRECT This fixes a bug where we use dip after we have freed it. Instead just use the file_offset that was passed to the function. Thanks, Signed-off-by: Josef Bacik --- fs/btrfs/inode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 0f34cae0a633..ae6c0d190bc1 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5934,8 +5934,7 @@ free_ordered: */ if (write) { struct btrfs_ordered_extent *ordered; - ordered = btrfs_lookup_ordered_extent(inode, - dip->logical_offset); + ordered = btrfs_lookup_ordered_extent(inode, file_offset); if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) && !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) btrfs_free_reserved_extent(root, ordered->start, From 2b20982e3154266106573beac2a4d4ba57a2789a Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 3 Dec 2010 13:17:53 -0500 Subject: [PATCH 208/300] Btrfs: deal with space cache errors better Currently if the space cache inode generation number doesn't match the generation number in the space cache header we will just fail to load the space cache, but we won't mark the space cache as an error, so we'll keep getting that error each time somebody tries to cache that block group until we actually clear the thing. Fix this by marking the space cache as having an error so we only get the message once. This patch also makes it so that we don't try and setup space cache for a block group that isn't cached, since we won't be able to write it out anyway. None of these problems are actual problems, they are just annoying and sub-optimal. Thanks, Signed-off-by: Josef Bacik --- fs/btrfs/extent-tree.c | 10 ++++++---- fs/btrfs/free-space-cache.c | 12 +++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index ddaf6340fe7f..8c56f5b38948 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -2742,6 +2742,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group, struct btrfs_root *root = block_group->fs_info->tree_root; struct inode *inode = NULL; u64 alloc_hint = 0; + int dcs = BTRFS_DC_ERROR; int num_pages = 0; int retries = 0; int ret = 0; @@ -2796,6 +2797,8 @@ again: spin_lock(&block_group->lock); if (block_group->cached != BTRFS_CACHE_FINISHED) { + /* We're not cached, don't bother trying to write stuff out */ + dcs = BTRFS_DC_WRITTEN; spin_unlock(&block_group->lock); goto out_put; } @@ -2822,6 +2825,8 @@ again: ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages, num_pages, num_pages, &alloc_hint); + if (!ret) + dcs = BTRFS_DC_SETUP; btrfs_free_reserved_data_space(inode, num_pages); out_put: iput(inode); @@ -2829,10 +2834,7 @@ out_free: btrfs_release_path(root, path); out: spin_lock(&block_group->lock); - if (ret) - block_group->disk_cache_state = BTRFS_DC_ERROR; - else - block_group->disk_cache_state = BTRFS_DC_SETUP; + block_group->disk_cache_state = dcs; spin_unlock(&block_group->lock); return ret; diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 22ee0dc2e6b8..60d684266959 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -290,7 +290,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, (unsigned long long)BTRFS_I(inode)->generation, (unsigned long long)generation, (unsigned long long)block_group->key.objectid); - goto out; + goto free_cache; } if (!num_entries) @@ -524,6 +524,12 @@ int btrfs_write_out_cache(struct btrfs_root *root, return 0; } + node = rb_first(&block_group->free_space_offset); + if (!node) { + iput(inode); + return 0; + } + last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT; filemap_write_and_wait(inode->i_mapping); btrfs_wait_ordered_range(inode, inode->i_size & @@ -543,10 +549,6 @@ int btrfs_write_out_cache(struct btrfs_root *root, */ first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64); - node = rb_first(&block_group->free_space_offset); - if (!node) - goto out_free; - /* * Lock all pages first so we can lock the extent safely. * From b8399dee478db7939cd0d6fda8ecacddf2facd03 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 8 Dec 2010 09:15:11 -0500 Subject: [PATCH 209/300] Btrfs: do not do fast caching if we are allocating blocks for tree_root Since the fast caching uses normal tree locking, we can possibly deadlock if we get to the caching via a btrfs_search_slot() on the tree_root. So just check to see if the root we are on is the tree root, and just don't do the fast caching. Reported-by: Sage Weil Signed-off-by: Josef Bacik --- fs/btrfs/extent-tree.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 8c56f5b38948..cec05e100142 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -429,6 +429,7 @@ err: static int cache_block_group(struct btrfs_block_group_cache *cache, struct btrfs_trans_handle *trans, + struct btrfs_root *root, int load_cache_only) { struct btrfs_fs_info *fs_info = cache->fs_info; @@ -442,9 +443,12 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, /* * We can't do the read from on-disk cache during a commit since we need - * to have the normal tree locking. + * to have the normal tree locking. Also if we are currently trying to + * allocate blocks for the tree root we can't do the fast caching since + * we likely hold important locks. */ - if (!trans->transaction->in_commit) { + if (!trans->transaction->in_commit && + (root && root != root->fs_info->tree_root)) { spin_lock(&cache->lock); if (cache->cached != BTRFS_CACHE_NO) { spin_unlock(&cache->lock); @@ -4083,7 +4087,7 @@ static int update_block_group(struct btrfs_trans_handle *trans, * space back to the block group, otherwise we will leak space. */ if (!alloc && cache->cached == BTRFS_CACHE_NO) - cache_block_group(cache, trans, 1); + cache_block_group(cache, trans, NULL, 1); byte_in_group = bytenr - cache->key.objectid; WARN_ON(byte_in_group > cache->key.offset); @@ -4937,7 +4941,8 @@ have_block_group: if (unlikely(block_group->cached == BTRFS_CACHE_NO)) { u64 free_percent; - ret = cache_block_group(block_group, trans, 1); + ret = cache_block_group(block_group, trans, + orig_root, 1); if (block_group->cached == BTRFS_CACHE_FINISHED) goto have_block_group; @@ -4961,7 +4966,8 @@ have_block_group: if (loop > LOOP_CACHING_NOWAIT || (loop > LOOP_FIND_IDEAL && atomic_read(&space_info->caching_threads) < 2)) { - ret = cache_block_group(block_group, trans, 0); + ret = cache_block_group(block_group, trans, + orig_root, 0); BUG_ON(ret); } found_uncached_bg = true; @@ -5518,7 +5524,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, u64 num_bytes = ins->offset; block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid); - cache_block_group(block_group, trans, 0); + cache_block_group(block_group, trans, NULL, 0); caching_ctl = get_caching_control(block_group); if (!caching_ctl) { From 7e1fea731da8c1b5fcf5d8e157befd389b030760 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 8 Dec 2010 12:22:34 -0500 Subject: [PATCH 210/300] Btrfs: fixup return code for btrfs_del_orphan_item If the orphan item doesn't exist, we return 1, which doesn't make any sense to the callers. Instead return -ENOENT if we didn't find the item. Thanks, Signed-off-by: Josef Bacik --- fs/btrfs/orphan.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/orphan.c b/fs/btrfs/orphan.c index 79cba5fbc28e..f8be250963a0 100644 --- a/fs/btrfs/orphan.c +++ b/fs/btrfs/orphan.c @@ -56,8 +56,12 @@ int btrfs_del_orphan_item(struct btrfs_trans_handle *trans, return -ENOMEM; ret = btrfs_search_slot(trans, root, &key, path, -1, 1); - if (ret) + if (ret < 0) goto out; + if (ret) { + ret = -ENOENT; + goto out; + } ret = btrfs_del_item(trans, root, path); From 85727e1f78bd8392a0657ad6a4ff85fef1cc4a6d Mon Sep 17 00:00:00 2001 From: Mike Hernandez Date: Tue, 23 Nov 2010 16:52:46 -0800 Subject: [PATCH 211/300] [SCSI] qla2xxx: Populate Command Type 6 LUN field properly. Use the host_to_fcp_swap call to correctly populate the LUN field in the Command Type 6 path. This field is used during LUN reset cleanup and must match the field used in the FCP command. Cc: stable@kernel.org Signed-off-by: Mike Hernandez Signed-off-by: Madhuranath Iyengar Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_iocb.c | 1 + drivers/scsi/qla2xxx/qla_nx.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 5f94430b42f0..4c1ba6263eb3 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -1061,6 +1061,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, fcp_cmnd->additional_cdb_len |= 2; int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun); + host_to_fcp_swap((uint8_t *)&fcp_cmnd->lun, sizeof(fcp_cmnd->lun)); memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32( diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 8d9edfb39803..ae2acacc0003 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -2749,6 +2749,7 @@ sufficient_dsds: goto queuing_error_fcp_cmnd; int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); + host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); /* build FCP_CMND IU */ memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); From 7992abfc8b851456f2dfac3229ecb3a5e5637df0 Mon Sep 17 00:00:00 2001 From: Mike Hernandez Date: Tue, 23 Nov 2010 16:52:47 -0800 Subject: [PATCH 212/300] [SCSI] qla2xxx: Change MSI initialization from using incorrect request_irq parameter. IRQF_SHARED flag should not be set when calling request_irq for MSI since this interrupt mechanism cannot be shared like standard INTx. Signed-off-by: Mike Hernandez Signed-off-by: Madhuranath Iyengar Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_def.h | 1 - drivers/scsi/qla2xxx/qla_isr.c | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3a22effced5f..9ce539d4557e 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2409,7 +2409,6 @@ struct qla_hw_data { uint32_t enable_target_reset :1; uint32_t enable_lip_full_login :1; uint32_t enable_led_scheme :1; - uint32_t inta_enabled :1; uint32_t msi_enabled :1; uint32_t msix_enabled :1; uint32_t disable_serdes :1; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 1f06ddd9bdd1..7f77898486a9 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -2491,14 +2491,15 @@ skip_msix: skip_msi: ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler, - IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp); + ha->flags.msi_enabled ? 0 : IRQF_SHARED, + QLA2XXX_DRIVER_NAME, rsp); if (ret) { qla_printk(KERN_WARNING, ha, "Failed to reserve interrupt %d already in use.\n", ha->pdev->irq); goto fail; } - ha->flags.inta_enabled = 1; + clear_risc_ints: /* From 087c621e22f49c326cdc65d98c6fc0737ac13533 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Tue, 23 Nov 2010 16:52:48 -0800 Subject: [PATCH 213/300] [SCSI] qla2xxx: Correct issue where NPIV-config data was not being allocated for 82xx parts. This would cause a panic while reading the NPIV-config data. Cc: stable@kernel.org Signed-off-by: Andrew Vasquez Signed-off-by: Madhuranath Iyengar Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 1644eabaafeb..b8731567aea5 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2064,6 +2064,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ha->init_cb_size = sizeof(struct mid_init_cb_81xx); ha->gid_list_info_size = 8; ha->optrom_size = OPTROM_SIZE_82XX; + ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX; ha->isp_ops = &qla82xx_isp_ops; ha->flash_conf_off = FARX_ACCESS_FLASH_CONF; ha->flash_data_off = FARX_ACCESS_FLASH_DATA; From 69abf61ea1005bc362b678639a4ae219e23829f3 Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Tue, 23 Nov 2010 16:52:49 -0800 Subject: [PATCH 214/300] [SCSI] qla2xxx: Properly set the return value in qla2xxx_eh_abort function. A return value is not set for the successful case and it has a garbage value. This fix will set the default value to SUCCESS and in case of any failures it is changed. Signed-off-by: Saurav Kashyap Signed-off-by: Madhuranath Iyengar Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index b8731567aea5..2c0876c81a3f 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -829,7 +829,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) { scsi_qla_host_t *vha = shost_priv(cmd->device->host); srb_t *sp; - int ret; + int ret = SUCCESS; unsigned int id, lun; unsigned long flags; int wait = 0; From 13d38d9df26b5b9a5ad5f9fbc065078bc42a8748 Mon Sep 17 00:00:00 2001 From: Madhuranath Iyengar Date: Tue, 23 Nov 2010 16:52:50 -0800 Subject: [PATCH 215/300] [SCSI] qla2xxx: Update version number to 8.03.05-k0. Signed-off-by: Madhuranath Iyengar Signed-off-by: James Bottomley --- drivers/scsi/qla2xxx/qla_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 8edbccb3232d..cf0075a2d0c2 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,9 +7,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.03.04-k0" +#define QLA2XXX_VERSION "8.03.05-k0" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 3 -#define QLA_DRIVER_PATCH_VER 4 +#define QLA_DRIVER_PATCH_VER 5 #define QLA_DRIVER_BETA_VER 0 From 3151dbb04ad5a5bd6358371c0bfb457216d00205 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 8 Dec 2010 10:40:45 +0800 Subject: [PATCH 216/300] ACPI ac: update AC status upon sysfs query http://marc.info/?l=linux-acpi&m=128855015826728&w=2 https://bugzilla.kernel.org/show_bug.cgi?id=21722 Tested_by: Seblu Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/ac.c | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index ba9afeaa23ac..25d3aaebc10d 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -100,24 +100,7 @@ static const struct file_operations acpi_ac_fops = { .release = single_release, }; #endif -static int get_ac_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct acpi_ac *ac = to_acpi_ac(psy); - switch (psp) { - case POWER_SUPPLY_PROP_ONLINE: - val->intval = ac->state; - break; - default: - return -EINVAL; - } - return 0; -} -static enum power_supply_property ac_props[] = { - POWER_SUPPLY_PROP_ONLINE, -}; /* -------------------------------------------------------------------------- AC Adapter Management -------------------------------------------------------------------------- */ @@ -140,6 +123,35 @@ static int acpi_ac_get_state(struct acpi_ac *ac) return 0; } +/* -------------------------------------------------------------------------- + sysfs I/F + -------------------------------------------------------------------------- */ +static int get_ac_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct acpi_ac *ac = to_acpi_ac(psy); + + if (!ac) + return -ENODEV; + + if (acpi_ac_get_state(ac)) + return -ENODEV; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = ac->state; + break; + default: + return -EINVAL; + } + return 0; +} + +static enum power_supply_property ac_props[] = { + POWER_SUPPLY_PROP_ONLINE, +}; + #ifdef CONFIG_ACPI_PROCFS_POWER /* -------------------------------------------------------------------------- FS Interface (/proc) From 3138b32d5e0998ba3cbd1c74bdc1887d74c5279b Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 8 Dec 2010 10:40:49 +0800 Subject: [PATCH 217/300] ACPI battery: update status upon sysfs query Sometimes the Battery driver doesn't get notifications when it's plugged/unplugged. And this results in the incorrect Battery status reported by the power supply sysfs I/F. Update Battery status first when querying from sysfs. http://marc.info/?l=linux-acpi&m=128855015826728&w=2 Tested_by: Seblu Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/battery.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 95649d373071..9fb9d5ac939d 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -130,6 +130,8 @@ struct acpi_battery { unsigned long flags; }; +static int acpi_battery_update(struct acpi_battery *battery); + #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); inline int acpi_battery_present(struct acpi_battery *battery) @@ -184,6 +186,9 @@ static int acpi_battery_get_property(struct power_supply *psy, int ret = 0; struct acpi_battery *battery = to_acpi_battery(psy); + if (acpi_battery_update(battery)) + return -ENODEV; + if (acpi_battery_present(battery)) { /* run battery update only if it is present */ acpi_battery_get_state(battery); From 7c03b87048f2467087ae7e51392e5fb57ea8f58b Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Wed, 1 Dec 2010 11:16:07 -0600 Subject: [PATCH 218/300] [SCSI] hpsa: fix redefinition of PCI_DEVICE_ID_CISSF PCI_DEVICE_ID_CISSF is defined as 323b in pci_ids.h but redefined as 3fff in hpsa.c. The ID of 3fff will _never_ ship as a standalone controller. It is intended only as part a complete storage solution. As such, this patch removes the redefinition and the StorageWorks P1210m from the product table. It also removes a duplicate line for the "unknown" controller support. Signed-off-by: James Bottomley --- drivers/scsi/hpsa.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index b2fb2b2a6e70..a6dea08664fc 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -90,11 +90,7 @@ static const struct pci_device_id hpsa_pci_device_id[] = { {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3252}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3253}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3254}, -#define PCI_DEVICE_ID_HP_CISSF 0x333f - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x333F}, - {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, - {PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, {0,} }; @@ -113,8 +109,6 @@ static struct board_type products[] = { {0x3249103C, "Smart Array P812", &SA5_access}, {0x324a103C, "Smart Array P712m", &SA5_access}, {0x324b103C, "Smart Array P711m", &SA5_access}, - {0x3233103C, "StorageWorks P1210m", &SA5_access}, - {0x333F103C, "StorageWorks P1210m", &SA5_access}, {0x3250103C, "Smart Array", &SA5_access}, {0x3250113C, "Smart Array", &SA5_access}, {0x3250123C, "Smart Array", &SA5_access}, From a5dc4f898c2a0f66e2cefada6c687db82ba2fcbc Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Thu, 9 Dec 2010 17:07:54 -0500 Subject: [PATCH 219/300] ACPI: EC: Add another dmi match entry for MSI hardware http://bugzilla.kernel.org/show_bug.cgi?id=15418 Signed-off-by: Alexey Starikovskiy cc: stable@kernel.org Signed-off-by: Len Brown --- drivers/acpi/ec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 372ff80b7b0c..302b31ed31f1 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -934,6 +934,9 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { ec_flag_msi, "MSI hardware", { DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, { + ec_flag_msi, "MSI hardware", { + DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL}, + { ec_validate_ecdt, "ASUS hardware", { DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, {}, From 05340d4ab2ec2b6b4962c1c41c6ea8fb550f947b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 7 Dec 2010 10:16:41 +0000 Subject: [PATCH 220/300] xfs: log timestamp changes to the source inode in rename Now that we don't mark VFS inodes dirty anymore for internal timestamp changes, but rely on the transaction subsystem to push them out, we need to explicitly log the source inode in rename after updating it's timestamps to make sure the changes actually get forced out by sync/fsync or an AIL push. We already account for the fourth inode in the log reservation, as a rename of directories needs to update the nlink field, so just adding the xfs_trans_log_inode call is enough. This fixes the xfsqa 065 regression introduced by: "xfs: don't use vfs writeback for pure metadata modifications" Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Alex Elder --- fs/xfs/xfs_rename.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index d2af0a8381a6..77a59891734e 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c @@ -297,6 +297,7 @@ xfs_rename( * it and some incremental backup programs won't work without it. */ xfs_trans_ichgtime(tp, src_ip, XFS_ICHGTIME_CHG); + xfs_trans_log_inode(tp, src_ip, XFS_ILOG_CORE); /* * Adjust the link count on src_dp. This is necessary when From 28dd31983f6c3a4d89369ff8f0c93de2cda868db Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 8 Dec 2010 01:02:12 +0000 Subject: [PATCH 221/300] OMAP1: SRAM: fix size for OMAP1611 SoCs Kernel was failing to boot on omap1611 based OSK boards due to mis-configured SRAM size. Existing code was using a hard-coded value for 250k, which was then rounded down by PAGE_SIZE. Increasing this to 256k allows kernel to boot on omap1611 SoCs. Problem reported by and initial fix suggested by Tim Bird. Thanks to Tony Lindgren for helping diagnose the problem to being specific to OMAP1611 and not affecting OMAP1610/OMAP1623. Reported-by: Tim Bird Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/sram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index e2c8eebe6b3a..74dac419d328 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -166,7 +166,7 @@ static void __init omap_detect_sram(void) cpu_is_omap1710()) omap_sram_size = 0x4000; /* 16K */ else if (cpu_is_omap1611()) - omap_sram_size = 0x3e800; /* 250K */ + omap_sram_size = SZ_256K; else { printk(KERN_ERR "Could not detect SRAM size\n"); omap_sram_size = 0x4000; From e83df17f178360a8e7874441bca04a710c869e42 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 8 Dec 2010 22:40:40 +0000 Subject: [PATCH 222/300] OMAP2+: PM/serial: fix console semaphore acquire during suspend commit 0d8e2d0dad98a693bad88aea6876ac8b94ad95c6 (OMAP2+: PM/serial: hold console semaphore while OMAP UARTs are disabled) added use of the console semaphore to protect UARTs from being accessed after disabled during idle, but this causes problems in suspend. During suspend, the console semaphore is acquired by the console suspend method (console_suspend()) so the try_acquire_console_sem() will always fail and suspend will be aborted. To fix, introduce a check so the console semaphore is only attempted during idle, and not during suspend. Also use the same check so that the console semaphore is not prematurely released during resume. Thanks to Paul Walmsley for suggesting adding the same check during resume. Cc: Paul Walmsley Tested-by: Jean Pihet Tested-by: Paul Walmsley Signed-off-by: Kevin Hilman Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/pm24xx.c | 34 +++++++++++++++++++++++++++++++--- arch/arm/mach-omap2/pm34xx.c | 27 ++++++++++++++++++++------- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index c85923e56b85..aaeea49b9bdd 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -53,6 +53,19 @@ #include #include +#ifdef CONFIG_SUSPEND +static suspend_state_t suspend_state = PM_SUSPEND_ON; +static inline bool is_suspending(void) +{ + return (suspend_state != PM_SUSPEND_ON); +} +#else +static inline bool is_suspending(void) +{ + return false; +} +#endif + static void (*omap2_sram_idle)(void); static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, void __iomem *sdrc_power); @@ -120,8 +133,9 @@ static void omap2_enter_full_retention(void) goto no_sleep; /* Block console output in case it is on one of the OMAP UARTs */ - if (try_acquire_console_sem()) - goto no_sleep; + if (!is_suspending()) + if (try_acquire_console_sem()) + goto no_sleep; omap_uart_prepare_idle(0); omap_uart_prepare_idle(1); @@ -136,7 +150,8 @@ static void omap2_enter_full_retention(void) omap_uart_resume_idle(1); omap_uart_resume_idle(0); - release_console_sem(); + if (!is_suspending()) + release_console_sem(); no_sleep: if (omap2_pm_debug) { @@ -284,6 +299,12 @@ out: local_irq_enable(); } +static int omap2_pm_begin(suspend_state_t state) +{ + suspend_state = state; + return 0; +} + static int omap2_pm_prepare(void) { /* We cannot sleep in idle until we have resumed */ @@ -333,10 +354,17 @@ static void omap2_pm_finish(void) enable_hlt(); } +static void omap2_pm_end(void) +{ + suspend_state = PM_SUSPEND_ON; +} + static struct platform_suspend_ops omap_pm_ops = { + .begin = omap2_pm_begin, .prepare = omap2_pm_prepare, .enter = omap2_pm_enter, .finish = omap2_pm_finish, + .end = omap2_pm_end, .valid = suspend_valid_only_mem, }; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 0ec8a04b7473..648b8c50d024 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -50,6 +50,19 @@ #include "sdrc.h" #include "control.h" +#ifdef CONFIG_SUSPEND +static suspend_state_t suspend_state = PM_SUSPEND_ON; +static inline bool is_suspending(void) +{ + return (suspend_state != PM_SUSPEND_ON); +} +#else +static inline bool is_suspending(void) +{ + return false; +} +#endif + /* Scratchpad offsets */ #define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4 #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 @@ -387,10 +400,11 @@ void omap_sram_idle(void) } /* Block console output in case it is on one of the OMAP UARTs */ - if (per_next_state < PWRDM_POWER_ON || - core_next_state < PWRDM_POWER_ON) - if (try_acquire_console_sem()) - goto console_still_active; + if (!is_suspending()) + if (per_next_state < PWRDM_POWER_ON || + core_next_state < PWRDM_POWER_ON) + if (try_acquire_console_sem()) + goto console_still_active; /* PER */ if (per_next_state < PWRDM_POWER_ON) { @@ -470,7 +484,8 @@ void omap_sram_idle(void) omap_uart_resume_idle(3); } - release_console_sem(); + if (!is_suspending()) + release_console_sem(); console_still_active: /* Disable IO-PAD and IO-CHAIN wakeup */ @@ -514,8 +529,6 @@ out: } #ifdef CONFIG_SUSPEND -static suspend_state_t suspend_state; - static int omap3_pm_prepare(void) { disable_hlt(); From fb4fa76a1fa59340154c42d998d700e1f8bf21e0 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 6 Dec 2010 09:05:50 +0000 Subject: [PATCH 223/300] net: Convert netpoll blocking api in bonding driver to be a counter A while back I made some changes to enable netpoll in the bonding driver. Among them was a per-cpu flag that indicated we were in a path that held locks which could cause the netpoll path to block in during tx, and as such the tx path should queue the frame for later use. This appears to have given rise to a regression. If one of those paths on which we hold the per-cpu flag yields the cpu, its possible for us to come back on a different cpu, leading to us clearing a different flag than we set. This results in odd netpoll drops, and BUG backtraces appearing in the log, as we check to make sure that we only clear set bits, and only set clear bits. I had though briefly about changing the offending paths so that they wouldn't sleep, but looking at my origional work more closely, it doesn't appear that a per-cpu flag is warranted. We alrady gate the checking of this flag on IFF_IN_NETPOLL, so we don't hit this in the normal tx case anyway. And practically speaking, the normal use case for netpoll is to only have one client anyway, so we're not going to erroneously queue netpoll frames when its actually safe to do so. As such, lets just convert that per-cpu flag to an atomic counter. It fixes the rescheduling bugs, is equivalent from a performance perspective and actually eliminates some code in the process. Tested by the reporter and myself, successfully Reported-by: Liang Zheng CC: Jay Vosburgh CC: Andy Gospodarek CC: David S. Miller Signed-off-by: Neil Horman Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 17 +++++------------ drivers/net/bonding/bonding.h | 12 ++++-------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2fee00a4c9ef..d0ea760ce419 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -171,7 +171,7 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link /*----------------------------- Global variables ----------------------------*/ #ifdef CONFIG_NET_POLL_CONTROLLER -cpumask_var_t netpoll_block_tx; +atomic_t netpoll_block_tx = ATOMIC_INIT(0); #endif static const char * const version = @@ -5299,13 +5299,6 @@ static int __init bonding_init(void) if (res) goto out; -#ifdef CONFIG_NET_POLL_CONTROLLER - if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) { - res = -ENOMEM; - goto out; - } -#endif - res = register_pernet_subsys(&bond_net_ops); if (res) goto out; @@ -5334,9 +5327,6 @@ err: rtnl_link_unregister(&bond_link_ops); err_link: unregister_pernet_subsys(&bond_net_ops); -#ifdef CONFIG_NET_POLL_CONTROLLER - free_cpumask_var(netpoll_block_tx); -#endif goto out; } @@ -5353,7 +5343,10 @@ static void __exit bonding_exit(void) unregister_pernet_subsys(&bond_net_ops); #ifdef CONFIG_NET_POLL_CONTROLLER - free_cpumask_var(netpoll_block_tx); + /* + * Make sure we don't have an imbalance on our netpoll blocking + */ + WARN_ON(atomic_read(&netpoll_block_tx)); #endif } diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 4eedb12df6ca..c2f081352a03 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -119,26 +119,22 @@ #ifdef CONFIG_NET_POLL_CONTROLLER -extern cpumask_var_t netpoll_block_tx; +extern atomic_t netpoll_block_tx; static inline void block_netpoll_tx(void) { - preempt_disable(); - BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(), - netpoll_block_tx)); + atomic_inc(&netpoll_block_tx); } static inline void unblock_netpoll_tx(void) { - BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(), - netpoll_block_tx)); - preempt_enable(); + atomic_dec(&netpoll_block_tx); } static inline int is_netpoll_tx_blocked(struct net_device *dev) { if (unlikely(dev->priv_flags & IFF_IN_NETPOLL)) - return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx); + return atomic_read(&netpoll_block_tx); return 0; } #else From 78347c8c6b2ddf20535bc1b18d749a3bbdea2a60 Mon Sep 17 00:00:00 2001 From: Thomas Egerer Date: Mon, 6 Dec 2010 23:28:56 +0000 Subject: [PATCH 224/300] xfrm: Fix xfrm_state_migrate leak xfrm_state_migrate calls kfree instead of xfrm_state_put to free a failed state. According to git commit 553f9118 this can cause memory leaks. Signed-off-by: Thomas Egerer Signed-off-by: Steffen Klassert Acked-by: Herbert Xu Signed-off-by: David S. Miller --- net/xfrm/xfrm_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index eb96ce52f178..220ebc05c7af 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -1268,7 +1268,7 @@ struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x, return xc; error: - kfree(xc); + xfrm_state_put(xc); return NULL; } EXPORT_SYMBOL(xfrm_state_migrate); From 6934d33556b366d22392a415ca09d720fed6a442 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Tue, 7 Dec 2010 22:21:52 +0000 Subject: [PATCH 225/300] hso: IP checksuming doesn't work on GE0301 option cards There is definitly a problem, that some option cards send up broken IP pakets leading to corrupted IP packets. These corruptions aren't detected, because the driver claims that the packets are already checksummed. This change removes the CHECKSUM_UNNECESSARY option and let IP detect broken data. Signed-off-by: Thomas Bogendoerfer Signed-off-by: David S. Miller --- drivers/net/usb/hso.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 62e9e8dc8190..812edf85d6d3 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -958,10 +958,6 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, /* Packet is complete. Inject into stack. */ /* We have IP packet here */ odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP); - /* don't check it */ - odev->skb_rx_buf->ip_summed = - CHECKSUM_UNNECESSARY; - skb_reset_mac_header(odev->skb_rx_buf); /* Ship it off to the kernel */ From 5b362ac3799ff4225c40935500f520cad4d7ed66 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 10 Dec 2010 12:31:14 -0500 Subject: [PATCH 226/300] NFS: Fix panic after nfs_umount() After a few unsuccessful NFS mount attempts in which the client and server cannot agree on an authentication flavor both support, the client panics. nfs_umount() is invoked in the kernel in this case. Turns out nfs_umount()'s UMNT RPC invocation causes the RPC client to write off the end of the rpc_clnt's iostat array. This is because the mount client's nrprocs field is initialized with the count of defined procedures (two: MNT and UMNT), rather than the size of the client's proc array (four). The fix is to use the same initialization technique used by most other upper layer clients in the kernel. Introduced by commit 0b524123, which failed to update nrprocs when support was added for UMNT in the kernel. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=24302 BugLink: http://bugs.launchpad.net/bugs/683938 Reported-by: Stefan Bader Tested-by: Stefan Bader Cc: stable@kernel.org # >= 2.6.32 Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/nfs/mount_clnt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index eceafe74f473..4f981f1f6689 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c @@ -505,13 +505,13 @@ static struct rpc_procinfo mnt3_procedures[] = { static struct rpc_version mnt_version1 = { .number = 1, - .nrprocs = 2, + .nrprocs = ARRAY_SIZE(mnt_procedures), .procs = mnt_procedures, }; static struct rpc_version mnt_version3 = { .number = 3, - .nrprocs = 2, + .nrprocs = ARRAY_SIZE(mnt3_procedures), .procs = mnt3_procedures, }; From e4fbce740f078bbc925ba5c86648d9c883968479 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 8 Dec 2010 15:32:14 +0000 Subject: [PATCH 227/300] r8169: Fix runtime power management I noticed that one of the post-2.6.36 patches broke runtime PM of the r8169 on my MSI Wind test machine in such a way that the link was not brought up after reconnecting the network cable. In the process of debugging the issue I realized that we only should invoke the runtime PM functions in rtl8169_check_link_status() when link change is reported and if we do so, the problem goes away. Moreover, this allows rtl8169_runtime_idle() to be simplified quite a bit. Signed-off-by: Rafael J. Wysocki Acked-by: Francois Romieu Signed-off-by: David S. Miller --- drivers/net/r8169.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 7d33ef4bcb4a..53b13deade95 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -744,26 +744,36 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr) mdio_write(ioaddr, MII_BMCR, val & 0xffff); } -static void rtl8169_check_link_status(struct net_device *dev, +static void __rtl8169_check_link_status(struct net_device *dev, struct rtl8169_private *tp, - void __iomem *ioaddr) + void __iomem *ioaddr, + bool pm) { unsigned long flags; spin_lock_irqsave(&tp->lock, flags); if (tp->link_ok(ioaddr)) { /* This is to cancel a scheduled suspend if there's one. */ - pm_request_resume(&tp->pci_dev->dev); + if (pm) + pm_request_resume(&tp->pci_dev->dev); netif_carrier_on(dev); netif_info(tp, ifup, dev, "link up\n"); } else { netif_carrier_off(dev); netif_info(tp, ifdown, dev, "link down\n"); - pm_schedule_suspend(&tp->pci_dev->dev, 100); + if (pm) + pm_schedule_suspend(&tp->pci_dev->dev, 100); } spin_unlock_irqrestore(&tp->lock, flags); } +static void rtl8169_check_link_status(struct net_device *dev, + struct rtl8169_private *tp, + void __iomem *ioaddr) +{ + __rtl8169_check_link_status(dev, tp, ioaddr, false); +} + #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) static u32 __rtl8169_get_wol(struct rtl8169_private *tp) @@ -4600,7 +4610,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) } if (status & LinkChg) - rtl8169_check_link_status(dev, tp, ioaddr); + __rtl8169_check_link_status(dev, tp, ioaddr, true); /* We need to see the lastest version of tp->intr_mask to * avoid ignoring an MSI interrupt and having to wait for @@ -4890,11 +4900,7 @@ static int rtl8169_runtime_idle(struct device *device) struct net_device *dev = pci_get_drvdata(pdev); struct rtl8169_private *tp = netdev_priv(dev); - if (!tp->TxDescArray) - return 0; - - rtl8169_check_link_status(dev, tp, tp->mmio_addr); - return -EBUSY; + return tp->TxDescArray ? -EBUSY : 0; } static const struct dev_pm_ops rtl8169_pm_ops = { From c1249c0aae4c93a753c70496ab2e9a51430a6f02 Mon Sep 17 00:00:00 2001 From: Martin Lucina Date: Fri, 10 Dec 2010 00:04:05 +0000 Subject: [PATCH 228/300] net: Document the kernel_recvmsg() function Signed-off-by: Martin Lucina Signed-off-by: David S. Miller --- net/socket.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/net/socket.c b/net/socket.c index 3ca2fd9e3720..088fb3fd45e0 100644 --- a/net/socket.c +++ b/net/socket.c @@ -732,6 +732,21 @@ static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg, return ret; } +/** + * kernel_recvmsg - Receive a message from a socket (kernel space) + * @sock: The socket to receive the message from + * @msg: Received message + * @vec: Input s/g array for message data + * @num: Size of input s/g array + * @size: Number of bytes to read + * @flags: Message flags (MSG_DONTWAIT, etc...) + * + * On return the msg structure contains the scatter/gather array passed in the + * vec argument. The array is modified so that it consists of the unfilled + * portion of the original array. + * + * The returned value is the total number of bytes received, or an error. + */ int kernel_recvmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t num, size_t size, int flags) { From 3700c3c2934467d53d443682f020cc5c1f75f1f2 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 10 Dec 2010 12:27:49 -0800 Subject: [PATCH 229/300] connector: add module alias Since connector can be built as a module and uses netlink socket to communicate. The module should have an alias to autoload when socket of NETLINK_CONNECTOR type is requested. Signed-off-by: Stephen Hemminger Acked-by: Evgeniy Polyakov Signed-off-by: David S. Miller --- drivers/connector/connector.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index e16c3fa8d2e3..05117f1ad867 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c @@ -36,6 +36,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Evgeniy Polyakov "); MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); +MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_CONNECTOR); static struct cn_dev cdev; From 5f75a1042feca37c0a436ba42a4b1f7f75c35778 Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Tue, 7 Dec 2010 23:38:31 +0000 Subject: [PATCH 230/300] ipv6: fix nl group when advertising a new link New idev are advertised with NL group RTNLGRP_IPV6_IFADDR, but should use RTNLGRP_IPV6_IFINFO. Bug was introduced by commit 8d7a76c9. Signed-off-by: Wang Xuefu Signed-off-by: Nicolas Dichtel Acked-by: Thomas Graf Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 23cc8e1ce8d4..93b7a933a775 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -4021,11 +4021,11 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev) kfree_skb(skb); goto errout; } - rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); + rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFINFO, NULL, GFP_ATOMIC); return; errout: if (err < 0) - rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err); + rtnl_set_sk_err(net, RTNLGRP_IPV6_IFINFO, err); } static inline size_t inet6_prefix_nlmsg_size(void) From 84cd948cb11041f205242de457e680b9bb872a36 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 8 Dec 2010 12:24:01 -0500 Subject: [PATCH 231/300] Btrfs: do not BUG if we fail to remove the orphan item for dead snapshots Not being able to delete an orphan item isn't a horrible thing. The worst that happens is the next time around we try and do the orphan cleanup and we can't find the referenced object and just delete the item and move on. Signed-off-by: Josef Bacik --- fs/btrfs/extent-tree.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index cec05e100142..41133b064d72 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -6309,9 +6309,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root, NULL, NULL); BUG_ON(ret < 0); if (ret > 0) { - ret = btrfs_del_orphan_item(trans, tree_root, - root->root_key.objectid); - BUG_ON(ret); + /* if we fail to delete the orphan item this time + * around, it'll get picked up the next time. + * + * The most common failure here is just -ENOENT. + */ + btrfs_del_orphan_item(trans, tree_root, + root->root_key.objectid); } } From 24ae63656a165c870c0d69fcc8aac1dc35e25e34 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Mon, 6 Dec 2010 07:02:36 +0000 Subject: [PATCH 232/300] Btrfs: Fix page leak in compressed writeback path "start + num_bytes >= actual_end" can happen when compressed page writeback races with file truncation. In that case we need unlock and release pages past the end of file. Signed-off-by: Yan, Zheng Signed-off-by: Chris Mason --- fs/btrfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index ae6c0d190bc1..4875d69871b5 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -495,7 +495,7 @@ again: add_async_extent(async_cow, start, num_bytes, total_compressed, pages, nr_pages_ret); - if (start + num_bytes < end && start + num_bytes < actual_end) { + if (start + num_bytes < end) { start += num_bytes; pages = NULL; cond_resched(); From 75eaa0e22c055e38982df267d0f84cc510ba38bf Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 10 Dec 2010 00:36:28 +0000 Subject: [PATCH 233/300] Btrfs: fix sync subvol/snapshot creation We were incorrectly taking the async path even for the sync ioctls by passing in &transid unconditionally. There's ample room for further cleanup here, but this keeps the fix simple. Signed-off-by: Sage Weil Reviewed-by: Li Zefan Signed-off-by: Chris Mason --- fs/btrfs/ioctl.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index f1c9bb4079ed..7cc2e8e075b4 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -964,6 +964,15 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, name = async_vol_args->name; fd = async_vol_args->fd; async_vol_args->name[BTRFS_SNAPSHOT_NAME_MAX] = '\0'; + + ret = btrfs_ioctl_snap_create_transid(file, name, fd, + subvol, &transid); + + if (ret == 0 && + copy_to_user(arg + + offsetof(struct btrfs_ioctl_async_vol_args, + transid), &transid, sizeof(transid))) + ret = -EFAULT; } else { vol_args = memdup_user(arg, sizeof(*vol_args)); if (IS_ERR(vol_args)) @@ -971,16 +980,9 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, name = vol_args->name; fd = vol_args->fd; vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; - } - ret = btrfs_ioctl_snap_create_transid(file, name, fd, - subvol, &transid); - - if (!ret && async) { - if (copy_to_user(arg + - offsetof(struct btrfs_ioctl_async_vol_args, - transid), &transid, sizeof(transid))) - return -EFAULT; + ret = btrfs_ioctl_snap_create_transid(file, name, fd, + subvol, NULL); } kfree(vol_args); From f106e82caaa0d943e47cacc184f5b40d538e0044 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 7 Dec 2010 01:51:26 +0000 Subject: [PATCH 234/300] Btrfs: Fix a crash when mounting a subvolume We should drop dentry before deactivating the superblock, otherwise we can hit this bug: BUG: Dentry f349a690{i=100,n=/} still in use (1) [unmount of btrfs loop1] ... Steps to reproduce the bug: # mount /dev/loop1 /mnt # mkdir save # btrfs subvolume snapshot /mnt save/snap1 # umount /mnt # mount -o subvol=save/snap1 /dev/loop1 /mnt (crash) Reported-by: Michael Niederle Signed-off-by: Li Zefan Signed-off-by: Chris Mason --- fs/btrfs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 47bf67cbe6bf..61bd79abb805 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -685,9 +685,9 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, mutex_unlock(&root->d_inode->i_mutex); if (IS_ERR(new_root)) { + dput(root); deactivate_locked_super(s); error = PTR_ERR(new_root); - dput(root); goto error_free_subvol_name; } if (!new_root->d_inode) { From 914ee295af418e936ec20a08c1663eaabe4cd07a Mon Sep 17 00:00:00 2001 From: Xin Zhong Date: Thu, 9 Dec 2010 09:30:14 +0000 Subject: [PATCH 235/300] Btrfs: pwrite blocked when writing from the mmaped buffer of the same page This problem is found in meego testing: http://bugs.meego.com/show_bug.cgi?id=6672 A file in btrfs is mmaped and the mmaped buffer is passed to pwrite to write to the same page of the same file. In btrfs_file_aio_write(), the pages is locked by prepare_pages(). So when btrfs_copy_from_user() is called, page fault happens and the same page needs to be locked again in filemap_fault(). The fix is to move iov_iter_fault_in_readable() before prepage_pages() to make page fault happen before pages are locked. And also disable page fault in critical region in btrfs_copy_from_user(). Reviewed-by: Yan, Zheng Signed-off-by: Zhong, Xin Signed-off-by: Chris Mason --- fs/btrfs/file.c | 94 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 33 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index c1faded5fca0..66836d85763b 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -48,30 +48,34 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, struct page **prepared_pages, struct iov_iter *i) { - size_t copied; + size_t copied = 0; int pg = 0; int offset = pos & (PAGE_CACHE_SIZE - 1); + int total_copied = 0; while (write_bytes > 0) { size_t count = min_t(size_t, PAGE_CACHE_SIZE - offset, write_bytes); struct page *page = prepared_pages[pg]; -again: - if (unlikely(iov_iter_fault_in_readable(i, count))) - return -EFAULT; - - /* Copy data from userspace to the current page */ - copied = iov_iter_copy_from_user(page, i, offset, count); + /* + * Copy data from userspace to the current page + * + * Disable pagefault to avoid recursive lock since + * the pages are already locked + */ + pagefault_disable(); + copied = iov_iter_copy_from_user_atomic(page, i, offset, count); + pagefault_enable(); /* Flush processor's dcache for this page */ flush_dcache_page(page); iov_iter_advance(i, copied); write_bytes -= copied; + total_copied += copied; + /* Return to btrfs_file_aio_write to fault page */ if (unlikely(copied == 0)) { - count = min_t(size_t, PAGE_CACHE_SIZE - offset, - iov_iter_single_seg_count(i)); - goto again; + break; } if (unlikely(copied < PAGE_CACHE_SIZE - offset)) { @@ -81,7 +85,7 @@ again: offset = 0; } } - return 0; + return total_copied; } /* @@ -854,6 +858,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, unsigned long last_index; int will_write; int buffered = 0; + int copied = 0; + int dirty_pages = 0; will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) || (file->f_flags & O_DIRECT)); @@ -970,7 +976,17 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, WARN_ON(num_pages > nrptrs); memset(pages, 0, sizeof(struct page *) * nrptrs); - ret = btrfs_delalloc_reserve_space(inode, write_bytes); + /* + * Fault pages before locking them in prepare_pages + * to avoid recursive lock + */ + if (unlikely(iov_iter_fault_in_readable(&i, write_bytes))) { + ret = -EFAULT; + goto out; + } + + ret = btrfs_delalloc_reserve_space(inode, + num_pages << PAGE_CACHE_SHIFT); if (ret) goto out; @@ -978,37 +994,49 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, pos, first_index, last_index, write_bytes); if (ret) { - btrfs_delalloc_release_space(inode, write_bytes); + btrfs_delalloc_release_space(inode, + num_pages << PAGE_CACHE_SHIFT); goto out; } - ret = btrfs_copy_from_user(pos, num_pages, + copied = btrfs_copy_from_user(pos, num_pages, write_bytes, pages, &i); - if (ret == 0) { + dirty_pages = (copied + PAGE_CACHE_SIZE - 1) >> + PAGE_CACHE_SHIFT; + + if (num_pages > dirty_pages) { + if (copied > 0) + atomic_inc( + &BTRFS_I(inode)->outstanding_extents); + btrfs_delalloc_release_space(inode, + (num_pages - dirty_pages) << + PAGE_CACHE_SHIFT); + } + + if (copied > 0) { dirty_and_release_pages(NULL, root, file, pages, - num_pages, pos, write_bytes); + dirty_pages, pos, copied); } btrfs_drop_pages(pages, num_pages); - if (ret) { - btrfs_delalloc_release_space(inode, write_bytes); - goto out; + + if (copied > 0) { + if (will_write) { + filemap_fdatawrite_range(inode->i_mapping, pos, + pos + copied - 1); + } else { + balance_dirty_pages_ratelimited_nr( + inode->i_mapping, + dirty_pages); + if (dirty_pages < + (root->leafsize >> PAGE_CACHE_SHIFT) + 1) + btrfs_btree_balance_dirty(root, 1); + btrfs_throttle(root); + } } - if (will_write) { - filemap_fdatawrite_range(inode->i_mapping, pos, - pos + write_bytes - 1); - } else { - balance_dirty_pages_ratelimited_nr(inode->i_mapping, - num_pages); - if (num_pages < - (root->leafsize >> PAGE_CACHE_SHIFT) + 1) - btrfs_btree_balance_dirty(root, 1); - btrfs_throttle(root); - } - - pos += write_bytes; - num_written += write_bytes; + pos += copied; + num_written += copied; cond_resched(); } From fdfb1e4f6c61477a61890b64974d65cdc3a98702 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 10 Dec 2010 06:41:56 +0000 Subject: [PATCH 236/300] Btrfs: Make async snapshot ioctl more generic If we had reserved some bytes in struct btrfs_ioctl_vol_args, we wouldn't have to create a new structure for async snapshot creation. Here we convert async snapshot ioctl to use a more generic ABI, as we'll add more ioctls for snapshots/subvolumes in the future, readonly snapshots for example. Signed-off-by: Li Zefan Signed-off-by: Chris Mason --- fs/btrfs/ioctl.c | 44 +++++++++++++++++++++++++++----------------- fs/btrfs/ioctl.h | 14 +++++++++----- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 7cc2e8e075b4..f87552a1d7ea 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -947,31 +947,41 @@ out: static noinline int btrfs_ioctl_snap_create(struct file *file, void __user *arg, int subvol, - int async) + int v2) { struct btrfs_ioctl_vol_args *vol_args = NULL; - struct btrfs_ioctl_async_vol_args *async_vol_args = NULL; + struct btrfs_ioctl_vol_args_v2 *vol_args_v2 = NULL; char *name; u64 fd; - u64 transid = 0; int ret; - if (async) { - async_vol_args = memdup_user(arg, sizeof(*async_vol_args)); - if (IS_ERR(async_vol_args)) - return PTR_ERR(async_vol_args); + if (v2) { + u64 transid = 0; + u64 *ptr = NULL; - name = async_vol_args->name; - fd = async_vol_args->fd; - async_vol_args->name[BTRFS_SNAPSHOT_NAME_MAX] = '\0'; + vol_args_v2 = memdup_user(arg, sizeof(*vol_args_v2)); + if (IS_ERR(vol_args_v2)) + return PTR_ERR(vol_args_v2); + + if (vol_args_v2->flags & ~BTRFS_SUBVOL_CREATE_ASYNC) { + ret = -EINVAL; + goto out; + } + + name = vol_args_v2->name; + fd = vol_args_v2->fd; + vol_args_v2->name[BTRFS_SUBVOL_NAME_MAX] = '\0'; + + if (vol_args_v2->flags & BTRFS_SUBVOL_CREATE_ASYNC) + ptr = &transid; ret = btrfs_ioctl_snap_create_transid(file, name, fd, - subvol, &transid); + subvol, ptr); - if (ret == 0 && + if (ret == 0 && ptr && copy_to_user(arg + - offsetof(struct btrfs_ioctl_async_vol_args, - transid), &transid, sizeof(transid))) + offsetof(struct btrfs_ioctl_vol_args_v2, + transid), ptr, sizeof(*ptr))) ret = -EFAULT; } else { vol_args = memdup_user(arg, sizeof(*vol_args)); @@ -984,9 +994,9 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, ret = btrfs_ioctl_snap_create_transid(file, name, fd, subvol, NULL); } - +out: kfree(vol_args); - kfree(async_vol_args); + kfree(vol_args_v2); return ret; } @@ -2248,7 +2258,7 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_getversion(file, argp); case BTRFS_IOC_SNAP_CREATE: return btrfs_ioctl_snap_create(file, argp, 0, 0); - case BTRFS_IOC_SNAP_CREATE_ASYNC: + case BTRFS_IOC_SNAP_CREATE_V2: return btrfs_ioctl_snap_create(file, argp, 0, 1); case BTRFS_IOC_SUBVOL_CREATE: return btrfs_ioctl_snap_create(file, argp, 1, 0); diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 17c99ebdf960..c344d12c646b 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -30,11 +30,15 @@ struct btrfs_ioctl_vol_args { char name[BTRFS_PATH_NAME_MAX + 1]; }; -#define BTRFS_SNAPSHOT_NAME_MAX 4079 -struct btrfs_ioctl_async_vol_args { +#define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0) + +#define BTRFS_SUBVOL_NAME_MAX 4039 +struct btrfs_ioctl_vol_args_v2 { __s64 fd; __u64 transid; - char name[BTRFS_SNAPSHOT_NAME_MAX + 1]; + __u64 flags; + __u64 unused[4]; + char name[BTRFS_SUBVOL_NAME_MAX + 1]; }; #define BTRFS_INO_LOOKUP_PATH_MAX 4080 @@ -187,6 +191,6 @@ struct btrfs_ioctl_space_args { struct btrfs_ioctl_space_args) #define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64) #define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64) -#define BTRFS_IOC_SNAP_CREATE_ASYNC _IOW(BTRFS_IOCTL_MAGIC, 23, \ - struct btrfs_ioctl_async_vol_args) +#define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \ + struct btrfs_ioctl_vol_args_v2) #endif From 3dd1462e82bcab7625cec129952f26dae7a8b742 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 7 Dec 2010 14:54:09 +0000 Subject: [PATCH 237/300] Btrfs: fix compiler warnings ... regarding an unused function when !MIGRATION, and regarding a printk() format string vs argument mismatch. Signed-off-by: Jan Beulich Signed-off-by: Chris Mason --- fs/btrfs/disk-io.c | 6 ++---- fs/btrfs/inode.c | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 33b6d459494c..b803c2667673 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -696,6 +696,7 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, __btree_submit_bio_done); } +#ifdef CONFIG_MIGRATION static int btree_migratepage(struct address_space *mapping, struct page *newpage, struct page *page) { @@ -712,12 +713,9 @@ static int btree_migratepage(struct address_space *mapping, if (page_has_private(page) && !try_to_release_page(page, GFP_KERNEL)) return -EAGAIN; -#ifdef CONFIG_MIGRATION return migrate_page(mapping, newpage, page); -#else - return -ENOSYS; -#endif } +#endif static int btree_writepage(struct page *page, struct writeback_control *wbc) { diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 4875d69871b5..5f9194438f7c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5712,9 +5712,9 @@ static void btrfs_end_dio_bio(struct bio *bio, int err) if (err) { printk(KERN_ERR "btrfs direct IO failed ino %lu rw %lu " - "disk_bytenr %lu len %u err no %d\n", - dip->inode->i_ino, bio->bi_rw, bio->bi_sector, - bio->bi_size, err); + "sector %#Lx len %u err no %d\n", + dip->inode->i_ino, bio->bi_rw, + (unsigned long long)bio->bi_sector, bio->bi_size, err); dip->errors = 1; /* From 79aeec5822cea63cf732bbc0c9f3337542352616 Mon Sep 17 00:00:00 2001 From: Vasanthy Kolluri Date: Wed, 8 Dec 2010 13:05:45 +0000 Subject: [PATCH 238/300] enic: Bug Fix: Pass napi reference to the isr that services receive queue Pass reference to napi instead of enic device to the isr that services receive queue. Signed-off-by: Vasanthy Kolluri Signed-off-by: Roopa Prabhu Signed-off-by: David Wang Signed-off-by: David S. Miller --- drivers/net/enic/enic_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index a466ef91dd43..aa28b270c045 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -1962,7 +1962,8 @@ static void enic_poll_controller(struct net_device *netdev) case VNIC_DEV_INTR_MODE_MSIX: for (i = 0; i < enic->rq_count; i++) { intr = enic_msix_rq_intr(enic, i); - enic_isr_msix_rq(enic->msix_entry[intr].vector, enic); + enic_isr_msix_rq(enic->msix_entry[intr].vector, + &enic->napi[i]); } intr = enic_msix_wq_intr(enic, i); enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); From 40a010395cd66053f07bffeb3da5e44683bac30e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 7 Dec 2010 17:11:09 +0000 Subject: [PATCH 239/300] SCTP: Fix SCTP_SET_PEER_PRIMARY_ADDR to accpet v4mapped address SCTP_SET_PEER_PRIMARY_ADDR does not accpet v4mapped address, using v4mapped address in SCTP_SET_PEER_PRIMARY_ADDR socket option will get -EADDRNOTAVAIL error if v4map is enabled. This patch try to fix it by mapping v4mapped address to v4 address if allowed. Signed-off-by: Wei Yongjun Acked-by: Vlad Yasevich Signed-off-by: David S. Miller --- net/sctp/socket.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 6bd554323a34..0b9ee34ad35c 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -2932,6 +2932,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva struct sctp_association *asoc = NULL; struct sctp_setpeerprim prim; struct sctp_chunk *chunk; + struct sctp_af *af; int err; sp = sctp_sk(sk); @@ -2959,6 +2960,13 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva if (!sctp_state(asoc, ESTABLISHED)) return -ENOTCONN; + af = sctp_get_af_specific(prim.sspp_addr.ss_family); + if (!af) + return -EINVAL; + + if (!af->addr_valid((union sctp_addr *)&prim.sspp_addr, sp, NULL)) + return -EADDRNOTAVAIL; + if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr)) return -EADDRNOTAVAIL; From fb890ae7d615f4b4f5689144b6832230ab2046aa Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Thu, 9 Dec 2010 09:50:08 +0000 Subject: [PATCH 240/300] MAINTAINERS: remove me from tulip It was a nice idea, but -ENOTIME and -ENOHW. I never got around to doing a lot of the clean up that I intended to. Signed-off-by: Kyle McMartin Acked-by: Grant Grundler Signed-off-by: David S. Miller --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 9206cb462913..dec390dff141 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5926,7 +5926,6 @@ F: include/linux/tty.h TULIP NETWORK DRIVERS M: Grant Grundler -M: Kyle McMartin L: netdev@vger.kernel.org S: Maintained F: drivers/net/tulip/ From d9ca676bcb26e1fdff9265a3e70f697cd381c889 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 8 Dec 2010 19:40:47 +0000 Subject: [PATCH 241/300] atm: correct sysfs 'device' link creation and parent relationships The ATM subsystem was incorrectly creating the 'device' link for ATM nodes in sysfs. This led to incorrect device/parent relationships exposed by sysfs and udev. Instead of rolling the 'device' link by hand in the generic ATM code, pass each ATM driver's bus device down to the sysfs code and let sysfs do this stuff correctly. Signed-off-by: Dan Williams Signed-off-by: David S. Miller --- drivers/atm/adummy.c | 2 +- drivers/atm/ambassador.c | 3 ++- drivers/atm/atmtcp.c | 2 +- drivers/atm/eni.c | 2 +- drivers/atm/firestream.c | 2 +- drivers/atm/fore200e.c | 14 +++++++------- drivers/atm/he.c | 2 +- drivers/atm/horizon.c | 3 ++- drivers/atm/idt77252.c | 3 ++- drivers/atm/iphase.c | 2 +- drivers/atm/lanai.c | 2 +- drivers/atm/nicstar.c | 3 ++- drivers/atm/solos-pci.c | 8 ++++---- drivers/atm/zatm.c | 2 +- drivers/usb/atm/usbatm.c | 15 +++------------ include/linux/atmdev.h | 6 ++++-- net/atm/atm_sysfs.c | 3 ++- net/atm/resources.c | 7 ++++--- net/atm/resources.h | 2 +- 19 files changed, 41 insertions(+), 42 deletions(-) diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c index 46b94762125b..f9b983ae6877 100644 --- a/drivers/atm/adummy.c +++ b/drivers/atm/adummy.c @@ -154,7 +154,7 @@ static int __init adummy_init(void) err = -ENOMEM; goto out; } - atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL); + atm_dev = atm_dev_register(DEV_LABEL, NULL, &adummy_ops, -1, NULL); if (!atm_dev) { printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n"); err = -ENODEV; diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index a33896a482e6..ffe9b655292e 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c @@ -2244,7 +2244,8 @@ static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_ goto out_reset; } - dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL); + dev->atm_dev = atm_dev_register (DEV_LABEL, &pci_dev->dev, &amb_ops, -1, + NULL); if (!dev->atm_dev) { PRINTD (DBG_ERR, "failed to register Madge ATM adapter"); err = -EINVAL; diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c index b9101818b47b..2b464b631f22 100644 --- a/drivers/atm/atmtcp.c +++ b/drivers/atm/atmtcp.c @@ -366,7 +366,7 @@ static int atmtcp_create(int itf,int persist,struct atm_dev **result) if (!dev_data) return -ENOMEM; - dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL); + dev = atm_dev_register(DEV_LABEL,NULL,&atmtcp_v_dev_ops,itf,NULL); if (!dev) { kfree(dev_data); return itf == -1 ? -ENOMEM : -EBUSY; diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index 97c5898cd76e..c495fae74200 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c @@ -2244,7 +2244,7 @@ static int __devinit eni_init_one(struct pci_dev *pci_dev, &zeroes); if (!cpu_zeroes) goto out1; } - dev = atm_dev_register(DEV_LABEL,&ops,-1,NULL); + dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL); if (!dev) goto out2; pci_set_drvdata(pci_dev, dev); eni_dev->pci_dev = pci_dev; diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 5d86bb803e94..7d912baf01d4 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -1911,7 +1911,7 @@ static int __devinit firestream_init_one (struct pci_dev *pci_dev, fs_dev, sizeof (struct fs_dev)); if (!fs_dev) goto err_out; - atm_dev = atm_dev_register("fs", &ops, -1, NULL); + atm_dev = atm_dev_register("fs", &pci_dev->dev, &ops, -1, NULL); if (!atm_dev) goto err_out_free_fs_dev; diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index c8fc69c85a06..962c309b40c0 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -2567,14 +2567,14 @@ release: static int __devinit -fore200e_register(struct fore200e* fore200e) +fore200e_register(struct fore200e* fore200e, struct device *parent) { struct atm_dev* atm_dev; DPRINTK(2, "device %s being registered\n", fore200e->name); - atm_dev = atm_dev_register(fore200e->bus->proc_name, &fore200e_ops, -1, - NULL); + atm_dev = atm_dev_register(fore200e->bus->proc_name, parent, &fore200e_ops, + -1, NULL); if (atm_dev == NULL) { printk(FORE200E "unable to register device %s\n", fore200e->name); return -ENODEV; @@ -2594,9 +2594,9 @@ fore200e_register(struct fore200e* fore200e) static int __devinit -fore200e_init(struct fore200e* fore200e) +fore200e_init(struct fore200e* fore200e, struct device *parent) { - if (fore200e_register(fore200e) < 0) + if (fore200e_register(fore200e, parent) < 0) return -ENODEV; if (fore200e->bus->configure(fore200e) < 0) @@ -2662,7 +2662,7 @@ static int __devinit fore200e_sba_probe(struct platform_device *op, sprintf(fore200e->name, "%s-%d", bus->model_name, index); - err = fore200e_init(fore200e); + err = fore200e_init(fore200e, &op->dev); if (err < 0) { fore200e_shutdown(fore200e); kfree(fore200e); @@ -2740,7 +2740,7 @@ fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent sprintf(fore200e->name, "%s-%d", bus->model_name, index); - err = fore200e_init(fore200e); + err = fore200e_init(fore200e, &pci_dev->dev); if (err < 0) { fore200e_shutdown(fore200e); goto out_free; diff --git a/drivers/atm/he.c b/drivers/atm/he.c index 801e8b6e9d1f..6cf59bf281dc 100644 --- a/drivers/atm/he.c +++ b/drivers/atm/he.c @@ -366,7 +366,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent) goto init_one_failure; } - atm_dev = atm_dev_register(DEV_LABEL, &he_ops, -1, NULL); + atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &he_ops, -1, NULL); if (!atm_dev) { err = -ENODEV; goto init_one_failure; diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index a95790452a68..24761e1d6642 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c @@ -2733,7 +2733,8 @@ static int __devinit hrz_probe(struct pci_dev *pci_dev, const struct pci_device_ PRINTD(DBG_INFO, "found Madge ATM adapter (hrz) at: IO %x, IRQ %u, MEM %p", iobase, irq, membase); - dev->atm_dev = atm_dev_register(DEV_LABEL, &hrz_ops, -1, NULL); + dev->atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &hrz_ops, -1, + NULL); if (!(dev->atm_dev)) { PRINTD(DBG_ERR, "failed to register Madge ATM adapter"); err = -EINVAL; diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index bce57328ddde..bfb7feee0400 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -3698,7 +3698,8 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id) goto err_out_iounmap; } - dev = atm_dev_register("idt77252", &idt77252_ops, -1, NULL); + dev = atm_dev_register("idt77252", &pcidev->dev, &idt77252_ops, -1, + NULL); if (!dev) { printk("%s: can't register atm device\n", card->name); err = -EIO; diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index 9309d4724e13..729254053758 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -3172,7 +3172,7 @@ static int __devinit ia_init_one(struct pci_dev *pdev, ret = -ENODEV; goto err_out_free_iadev; } - dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL); + dev = atm_dev_register(DEV_LABEL, &pdev->dev, &ops, -1, NULL); if (!dev) { ret = -ENOMEM; goto err_out_disable_dev; diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index cbe15a86c669..a395c9aab146 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c @@ -2591,7 +2591,7 @@ static int __devinit lanai_init_one(struct pci_dev *pci, return -ENOMEM; } - atmdev = atm_dev_register(DEV_LABEL, &ops, -1, NULL); + atmdev = atm_dev_register(DEV_LABEL, &pci->dev, &ops, -1, NULL); if (atmdev == NULL) { printk(KERN_ERR DEV_LABEL ": couldn't register atm device!\n"); diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 2f3516b7f118..6b313ee9231b 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c @@ -771,7 +771,8 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev) } /* Register device */ - card->atmdev = atm_dev_register("nicstar", &atm_ops, -1, NULL); + card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops, + -1, NULL); if (card->atmdev == NULL) { printk("nicstar%d: can't register device.\n", i); error = 17; diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 2e08c996fd30..73fb1c4f4cd4 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -166,7 +166,7 @@ static irqreturn_t solos_irq(int irq, void *dev_id); static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci); static int list_vccs(int vci); static void release_vccs(struct atm_dev *dev); -static int atm_init(struct solos_card *); +static int atm_init(struct solos_card *, struct device *); static void atm_remove(struct solos_card *); static int send_command(struct solos_card *card, int dev, const char *buf, size_t size); static void solos_bh(unsigned long); @@ -1210,7 +1210,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) if (db_firmware_upgrade) flash_upgrade(card, 3); - err = atm_init(card); + err = atm_init(card, &dev->dev); if (err) goto out_free_irq; @@ -1233,7 +1233,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) return err; } -static int atm_init(struct solos_card *card) +static int atm_init(struct solos_card *card, struct device *parent) { int i; @@ -1244,7 +1244,7 @@ static int atm_init(struct solos_card *card) skb_queue_head_init(&card->tx_queue[i]); skb_queue_head_init(&card->cli_queue[i]); - card->atmdev[i] = atm_dev_register("solos-pci", &fpga_ops, -1, NULL); + card->atmdev[i] = atm_dev_register("solos-pci", parent, &fpga_ops, -1, NULL); if (!card->atmdev[i]) { dev_err(&card->dev->dev, "Could not register ATM device %d\n", i); atm_remove(card); diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index 4e885d2da49c..624917902b65 100644 --- a/drivers/atm/zatm.c +++ b/drivers/atm/zatm.c @@ -1597,7 +1597,7 @@ static int __devinit zatm_init_one(struct pci_dev *pci_dev, goto out; } - dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL); + dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL); if (!dev) goto out_free; diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 05bf5a27b5b0..989e16e4ab5c 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -951,7 +951,9 @@ static int usbatm_atm_init(struct usbatm_data *instance) * condition: callbacks we register can be executed at once, before we have * initialized the struct atm_dev. To protect against this, all callbacks * abort if atm_dev->dev_data is NULL. */ - atm_dev = atm_dev_register(instance->driver_name, &usbatm_atm_devops, -1, NULL); + atm_dev = atm_dev_register(instance->driver_name, + &instance->usb_intf->dev, &usbatm_atm_devops, + -1, NULL); if (!atm_dev) { usb_err(instance, "%s: failed to register ATM device!\n", __func__); return -1; @@ -966,14 +968,6 @@ static int usbatm_atm_init(struct usbatm_data *instance) /* temp init ATM device, set to 128kbit */ atm_dev->link_rate = 128 * 1000 / 424; - ret = sysfs_create_link(&atm_dev->class_dev.kobj, - &instance->usb_intf->dev.kobj, "device"); - if (ret) { - atm_err(instance, "%s: sysfs_create_link failed: %d\n", - __func__, ret); - goto fail_sysfs; - } - if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) { atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret); goto fail; @@ -992,8 +986,6 @@ static int usbatm_atm_init(struct usbatm_data *instance) return 0; fail: - sysfs_remove_link(&atm_dev->class_dev.kobj, "device"); - fail_sysfs: instance->atm_dev = NULL; atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */ return ret; @@ -1329,7 +1321,6 @@ void usbatm_usb_disconnect(struct usb_interface *intf) /* ATM finalize */ if (instance->atm_dev) { - sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device"); atm_dev_deregister(instance->atm_dev); instance->atm_dev = NULL; } diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index a8e4e832cdbb..475f8c42c0e9 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -427,8 +427,10 @@ extern rwlock_t vcc_sklist_lock; #define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb)) -struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops, - int number,unsigned long *flags); /* number == -1: pick first available */ +struct atm_dev *atm_dev_register(const char *type, struct device *parent, + const struct atmdev_ops *ops, + int number, /* -1 == pick first available */ + unsigned long *flags); struct atm_dev *atm_dev_lookup(int number); void atm_dev_deregister(struct atm_dev *dev); diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c index 799c631f0fed..f7fa67c78766 100644 --- a/net/atm/atm_sysfs.c +++ b/net/atm/atm_sysfs.c @@ -143,12 +143,13 @@ static struct class atm_class = { .dev_uevent = atm_uevent, }; -int atm_register_sysfs(struct atm_dev *adev) +int atm_register_sysfs(struct atm_dev *adev, struct device *parent) { struct device *cdev = &adev->class_dev; int i, j, err; cdev->class = &atm_class; + cdev->parent = parent; dev_set_drvdata(cdev, adev); dev_set_name(cdev, "%s%d", adev->type, adev->number); diff --git a/net/atm/resources.c b/net/atm/resources.c index d29e58261511..23f45ce6f351 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c @@ -74,8 +74,9 @@ struct atm_dev *atm_dev_lookup(int number) } EXPORT_SYMBOL(atm_dev_lookup); -struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, - int number, unsigned long *flags) +struct atm_dev *atm_dev_register(const char *type, struct device *parent, + const struct atmdev_ops *ops, int number, + unsigned long *flags) { struct atm_dev *dev, *inuse; @@ -115,7 +116,7 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, goto out_fail; } - if (atm_register_sysfs(dev) < 0) { + if (atm_register_sysfs(dev, parent) < 0) { pr_err("atm_register_sysfs failed for dev %s\n", type); atm_proc_dev_deregister(dev); goto out_fail; diff --git a/net/atm/resources.h b/net/atm/resources.h index 126fb1840dfb..521431e30507 100644 --- a/net/atm/resources.h +++ b/net/atm/resources.h @@ -42,6 +42,6 @@ static inline void atm_proc_dev_deregister(struct atm_dev *dev) #endif /* CONFIG_PROC_FS */ -int atm_register_sysfs(struct atm_dev *adev); +int atm_register_sysfs(struct atm_dev *adev, struct device *parent); void atm_unregister_sysfs(struct atm_dev *adev); #endif From 377ecca9ba6d98f31517e2322075e94d1be94561 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 8 Dec 2010 23:05:13 +0000 Subject: [PATCH 242/300] phy: add the IC+ IP1001 driver This patch adds the IC+ IP1001 (Gigabit Ethernet Transceiver) driver. I've had to add an additional delay (2ns) to adjust RX clock phase at GMII/ RGMII interface (according to the PHY data-sheet). This helps to have the RGMII working on some ST platforms. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/phy/Kconfig | 2 +- drivers/net/phy/icplus.c | 59 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index cb3d13e4e074..35fda5ac8120 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -64,7 +64,7 @@ config BCM63XX_PHY config ICPLUS_PHY tristate "Drivers for ICPlus PHYs" ---help--- - Currently supports the IP175C PHY. + Currently supports the IP175C and IP1001 PHYs. config REALTEK_PHY tristate "Drivers for Realtek PHYs" diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index c1d2d251fe8b..9a09e24c30bc 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c @@ -30,7 +30,7 @@ #include #include -MODULE_DESCRIPTION("ICPlus IP175C PHY driver"); +MODULE_DESCRIPTION("ICPlus IP175C/IC1001 PHY drivers"); MODULE_AUTHOR("Michael Barkowski"); MODULE_LICENSE("GPL"); @@ -89,6 +89,33 @@ static int ip175c_config_init(struct phy_device *phydev) return 0; } +static int ip1001_config_init(struct phy_device *phydev) +{ + int err, value; + + /* Software Reset PHY */ + value = phy_read(phydev, MII_BMCR); + value |= BMCR_RESET; + err = phy_write(phydev, MII_BMCR, value); + if (err < 0) + return err; + + do { + value = phy_read(phydev, MII_BMCR); + } while (value & BMCR_RESET); + + /* Additional delay (2ns) used to adjust RX clock phase + * at GMII/ RGMII interface */ + value = phy_read(phydev, 16); + value |= 0x3; + + err = phy_write(phydev, 16, value); + if (err < 0) + return err; + + return err; +} + static int ip175c_read_status(struct phy_device *phydev) { if (phydev->addr == 4) /* WAN port */ @@ -121,21 +148,43 @@ static struct phy_driver ip175c_driver = { .driver = { .owner = THIS_MODULE,}, }; -static int __init ip175c_init(void) +static struct phy_driver ip1001_driver = { + .phy_id = 0x02430d90, + .name = "ICPlus IP1001", + .phy_id_mask = 0x0ffffff0, + .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | + SUPPORTED_Asym_Pause, + .config_init = &ip1001_config_init, + .config_aneg = &genphy_config_aneg, + .read_status = &genphy_read_status, + .suspend = genphy_suspend, + .resume = genphy_resume, + .driver = { .owner = THIS_MODULE,}, +}; + +static int __init icplus_init(void) { + int ret = 0; + + ret = phy_driver_register(&ip1001_driver); + if (ret < 0) + return -ENODEV; + return phy_driver_register(&ip175c_driver); } -static void __exit ip175c_exit(void) +static void __exit icplus_exit(void) { + phy_driver_unregister(&ip1001_driver); phy_driver_unregister(&ip175c_driver); } -module_init(ip175c_init); -module_exit(ip175c_exit); +module_init(icplus_init); +module_exit(icplus_exit); static struct mdio_device_id __maybe_unused icplus_tbl[] = { { 0x02430d80, 0x0ffffff0 }, + { 0x02430d90, 0x0ffffff0 }, { } }; From c710245caa41060e983cc9cb5ffcc020e02ca45f Mon Sep 17 00:00:00 2001 From: Casey Leedom Date: Thu, 9 Dec 2010 09:38:24 +0000 Subject: [PATCH 243/300] cxgb4vf: Ingress Queue Entry Size needs to be 64 bytes Was using L1_CACHE_BYTES for the Ingress Queue Entry Size but it really needs to be 64 bytes in order to support the largest message sizes. Signed-off-by: Casey Leedom Signed-off-by: David S. Miller --- drivers/net/cxgb4vf/cxgb4vf_main.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index d887a76cd39d..6bf464afa90e 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -2269,6 +2269,7 @@ static void __devinit cfg_queues(struct adapter *adapter) { struct sge *s = &adapter->sge; int q10g, n10g, qidx, pidx, qs; + size_t iqe_size; /* * We should not be called till we know how many Queue Sets we can @@ -2312,6 +2313,13 @@ static void __devinit cfg_queues(struct adapter *adapter) } s->ethqsets = qidx; + /* + * The Ingress Queue Entry Size for our various Response Queues needs + * to be big enough to accommodate the largest message we can receive + * from the chip/firmware; which is 64 bytes ... + */ + iqe_size = 64; + /* * Set up default Queue Set parameters ... Start off with the * shortest interrupt holdoff timer. @@ -2320,7 +2328,7 @@ static void __devinit cfg_queues(struct adapter *adapter) struct sge_eth_rxq *rxq = &s->ethrxq[qs]; struct sge_eth_txq *txq = &s->ethtxq[qs]; - init_rspq(&rxq->rspq, 0, 0, 1024, L1_CACHE_BYTES); + init_rspq(&rxq->rspq, 0, 0, 1024, iqe_size); rxq->fl.size = 72; txq->q.size = 1024; } @@ -2329,8 +2337,7 @@ static void __devinit cfg_queues(struct adapter *adapter) * The firmware event queue is used for link state changes and * notifications of TX DMA completions. */ - init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, - L1_CACHE_BYTES); + init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, iqe_size); /* * The forwarded interrupt queue is used when we're in MSI interrupt @@ -2346,7 +2353,7 @@ static void __devinit cfg_queues(struct adapter *adapter) * any time ... */ init_rspq(&s->intrq, SGE_TIMER_RSTRT_CNTR, 0, MSIX_ENTRIES + 1, - L1_CACHE_BYTES); + iqe_size); } /* From a19faf0250e09b16cac169354126404bc8aa342b Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sun, 5 Dec 2010 18:50:32 +0000 Subject: [PATCH 244/300] net: fix skb_defer_rx_timestamp() After commit c1f19b51d1d8 (net: support time stamping in phy devices.), kernel might crash if CONFIG_NETWORK_PHY_TIMESTAMPING=y and skb_defer_rx_timestamp() handles a packet without an ethernet header. Fixes kernel bugzilla #24102 Reference: https://bugzilla.kernel.org/show_bug.cgi?id=24102 Reported-and-tested-by: Andrew Watts Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/timestamping.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/core/timestamping.c b/net/core/timestamping.c index 0ae6c22da85b..c19bb4ee405e 100644 --- a/net/core/timestamping.c +++ b/net/core/timestamping.c @@ -96,11 +96,13 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb) struct phy_device *phydev; unsigned int type; - skb_push(skb, ETH_HLEN); + if (skb_headroom(skb) < ETH_HLEN) + return false; + __skb_push(skb, ETH_HLEN); type = classify(skb); - skb_pull(skb, ETH_HLEN); + __skb_pull(skb, ETH_HLEN); switch (type) { case PTP_CLASS_V1_IPV4: From c2015dc88a57090bcf67ab7cfcdbc34671598d36 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Mon, 6 Dec 2010 20:52:40 +0000 Subject: [PATCH 245/300] OMAP2: PRCM: fix some SHIFT macros that were actually bitmasks After Charu's GPIO hwmod patches, GPIO initialization on N800 emits the following messages for all GPIO banks: omap_hwmod: gpio1: cannot be enabled (3) This is due to OMAP24XX_ST_GPIOS_SHIFT being defined as a bitmask. Fix this and also fix two other macros that had the same problem. Thanks to Tony Lindgren for originally reporting this bug. Signed-off-by: Paul Walmsley Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/prcm-common.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 298a22a754e2..f81acee4738d 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -243,13 +243,14 @@ #define OMAP24XX_EN_GPT1_MASK (1 << 0) /* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */ -#define OMAP24XX_ST_GPIOS_SHIFT (1 << 2) -#define OMAP24XX_ST_GPIOS_MASK 2 -#define OMAP24XX_ST_GPT1_SHIFT (1 << 0) -#define OMAP24XX_ST_GPT1_MASK 0 +#define OMAP24XX_ST_GPIOS_SHIFT 2 +#define OMAP24XX_ST_GPIOS_MASK (1 << 2) +#define OMAP24XX_ST_GPT1_SHIFT 0 +#define OMAP24XX_ST_GPT1_MASK (1 << 0) /* CM_IDLEST_MDM and PM_WKST_MDM shared bits */ -#define OMAP2430_ST_MDM_SHIFT (1 << 0) +#define OMAP2430_ST_MDM_SHIFT 0 +#define OMAP2430_ST_MDM_MASK (1 << 0) /* 3430 register bits shared between CM & PRM registers */ From d90aa92c0c1625d7f02050e4d2924805840cda3d Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 9 Dec 2010 16:50:52 +0800 Subject: [PATCH 246/300] acpi: fix _OSI string setup regression commit b0ed7a91(ACPICA/ACPI: Add new host interfaces for _OSI suppor) introduced a regression that _OSI string setup fails. There are 2 paths to setup _OSI string. DMI: acpi_dmi_osi_linux -> set_osi_linux -> acpi_osi_setup -> copy _OSI string to osi_setup_string Boot command line: acpi_osi_setup -> copy _OSI string to osi_setup_string Later, acpi_osi_setup_late will be called to handle osi_setup_string. If _OSI string is "Linux" or "!Linux", then the call path is, acpi_osi_setup_late -> acpi_cmdline_osi_linux -> set_osi_linux -> acpi_osi_setup -> copy _OSI string to osi_setup_string This actually never installs _OSI string(acpi_install_interface not called), but just copy the _OSI string to osi_setup_string. This patch fixes the regression. Reported-and-tested-by: Lukas Hejtmanek Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/osl.c | 59 +++++++++++++++++++++++++------------------- include/linux/acpi.h | 2 +- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 966feddf6b1b..6867443c4941 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -152,8 +152,7 @@ static struct osi_linux { unsigned int enable:1; unsigned int dmi:1; unsigned int cmdline:1; - unsigned int known:1; -} osi_linux = { 0, 0, 0, 0}; +} osi_linux = {0, 0, 0}; static u32 acpi_osi_handler(acpi_string interface, u32 supported) { @@ -1055,13 +1054,22 @@ static int __init acpi_os_name_setup(char *str) __setup("acpi_os_name=", acpi_os_name_setup); +void __init acpi_osi_setup(char *str) +{ + if (!acpi_gbl_create_osi_method) + return; + + if (str == NULL || *str == '\0') { + printk(KERN_INFO PREFIX "_OSI method disabled\n"); + acpi_gbl_create_osi_method = FALSE; + } else + strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX); +} + static void __init set_osi_linux(unsigned int enable) { - if (osi_linux.enable != enable) { + if (osi_linux.enable != enable) osi_linux.enable = enable; - printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", - enable ? "Add": "Delet"); - } if (osi_linux.enable) acpi_osi_setup("Linux"); @@ -1073,7 +1081,8 @@ static void __init set_osi_linux(unsigned int enable) static void __init acpi_cmdline_osi_linux(unsigned int enable) { - osi_linux.cmdline = 1; /* cmdline set the default */ + osi_linux.cmdline = 1; /* cmdline set the default and override DMI */ + osi_linux.dmi = 0; set_osi_linux(enable); return; @@ -1081,15 +1090,12 @@ static void __init acpi_cmdline_osi_linux(unsigned int enable) void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) { - osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ - printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); if (enable == -1) return; - osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */ - + osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ set_osi_linux(enable); return; @@ -1105,36 +1111,37 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) static void __init acpi_osi_setup_late(void) { char *str = osi_setup_string; + acpi_status status; if (*str == '\0') return; - if (!strcmp("!Linux", str)) { - acpi_cmdline_osi_linux(0); /* !enable */ - } else if (*str == '!') { - if (acpi_remove_interface(++str) == AE_OK) + if (*str == '!') { + status = acpi_remove_interface(++str); + + if (ACPI_SUCCESS(status)) printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); - } else if (!strcmp("Linux", str)) { - acpi_cmdline_osi_linux(1); /* enable */ } else { - if (acpi_install_interface(str) == AE_OK) + status = acpi_install_interface(str); + + if (ACPI_SUCCESS(status)) printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); } } -int __init acpi_osi_setup(char *str) +static int __init osi_setup(char *str) { - if (str == NULL || *str == '\0') { - printk(KERN_INFO PREFIX "_OSI method disabled\n"); - acpi_gbl_create_osi_method = FALSE; - } else { - strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX); - } + if (str && !strcmp("Linux", str)) + acpi_cmdline_osi_linux(1); + else if (str && !strcmp("!Linux", str)) + acpi_cmdline_osi_linux(0); + else + acpi_osi_setup(str); return 1; } -__setup("acpi_osi=", acpi_osi_setup); +__setup("acpi_osi=", osi_setup); /* enable serialization to combat AE_ALREADY_EXISTS errors */ static int __init acpi_serialize_setup(char *str) diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 050a7bccb836..67c91b4418b0 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -219,7 +219,7 @@ static inline int acpi_video_display_switch_support(void) extern int acpi_blacklisted(void); extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d); -extern int acpi_osi_setup(char *str); +extern void acpi_osi_setup(char *str); #ifdef CONFIG_ACPI_NUMA int acpi_get_pxm(acpi_handle handle); From 12d3206466d2074ef0684aaf7759ae01a0a92560 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 9 Dec 2010 16:51:06 +0800 Subject: [PATCH 247/300] ACPI: fix allowing to add/remove multiple _OSI strings commit b0ed7a91(ACPICA/ACPI: Add new host interfaces for _OSI suppor) introduced another regression that only one _OSI string can be added or removed. Now multiple _OSI strings can be added or removed, for example acpi_osi=Linux acpi_osi=FreeBSD acpi_osi="!Windows 2006" Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/osl.c | 66 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 6867443c4941..d0a1bb54367b 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -110,9 +110,6 @@ struct acpi_ioremap { static LIST_HEAD(acpi_ioremaps); static DEFINE_SPINLOCK(acpi_ioremap_lock); -#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ -static char osi_setup_string[OSI_STRING_LENGTH_MAX]; - static void __init acpi_osi_setup_late(void); /* @@ -1054,16 +1051,47 @@ static int __init acpi_os_name_setup(char *str) __setup("acpi_os_name=", acpi_os_name_setup); +#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ +#define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */ + +struct osi_setup_entry { + char string[OSI_STRING_LENGTH_MAX]; + bool enable; +}; + +static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX]; + void __init acpi_osi_setup(char *str) { + struct osi_setup_entry *osi; + bool enable = true; + int i; + if (!acpi_gbl_create_osi_method) return; if (str == NULL || *str == '\0') { printk(KERN_INFO PREFIX "_OSI method disabled\n"); acpi_gbl_create_osi_method = FALSE; - } else - strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX); + return; + } + + if (*str == '!') { + str++; + enable = false; + } + + for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { + osi = &osi_setup_entries[i]; + if (!strcmp(osi->string, str)) { + osi->enable = enable; + break; + } else if (osi->string[0] == '\0') { + osi->enable = enable; + strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); + break; + } + } } static void __init set_osi_linux(unsigned int enable) @@ -1110,22 +1138,28 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) */ static void __init acpi_osi_setup_late(void) { - char *str = osi_setup_string; + struct osi_setup_entry *osi; + char *str; + int i; acpi_status status; - if (*str == '\0') - return; + for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { + osi = &osi_setup_entries[i]; + str = osi->string; - if (*str == '!') { - status = acpi_remove_interface(++str); + if (*str == '\0') + break; + if (osi->enable) { + status = acpi_install_interface(str); - if (ACPI_SUCCESS(status)) - printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); - } else { - status = acpi_install_interface(str); + if (ACPI_SUCCESS(status)) + printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); + } else { + status = acpi_remove_interface(str); - if (ACPI_SUCCESS(status)) - printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); + if (ACPI_SUCCESS(status)) + printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); + } } } From 3353bebe7c89725ab2f476b9d8d618259402d52e Mon Sep 17 00:00:00 2001 From: Len Brown Date: Tue, 30 Nov 2010 18:21:46 -0500 Subject: [PATCH 248/300] ACPI: video: fix build for VIDEO_OUTPUT_CONTROL=n drivers/built-in.o: In function `acpi_video_bus_put_devices': video.c:(.text+0x79663): undefined reference to `video_output_unregister' drivers/built-in.o: In function `acpi_video_bus_add': video.c:(.text+0x7b0b3): undefined reference to `video_output_register' Signed-off-by: Len Brown --- include/linux/video_output.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/linux/video_output.h b/include/linux/video_output.h index 2fb46bc9340d..ed5cdeb3604d 100644 --- a/include/linux/video_output.h +++ b/include/linux/video_output.h @@ -23,6 +23,7 @@ #ifndef _LINUX_VIDEO_OUTPUT_H #define _LINUX_VIDEO_OUTPUT_H #include +#include struct output_device; struct output_properties { int (*set_state)(struct output_device *); @@ -34,9 +35,23 @@ struct output_device { struct device dev; }; #define to_output_device(obj) container_of(obj, struct output_device, dev) +#if defined(CONFIG_VIDEO_OUTPUT_CONTROL) || defined(CONFIG_VIDEO_OUTPUT_CONTROL_MODULE) struct output_device *video_output_register(const char *name, struct device *dev, void *devdata, struct output_properties *op); void video_output_unregister(struct output_device *dev); +#else +static struct output_device *video_output_register(const char *name, + struct device *dev, + void *devdata, + struct output_properties *op) +{ + return ERR_PTR(-ENODEV); +} +static void video_output_unregister(struct output_device *dev) +{ + return; +} +#endif #endif From b72512ed706efb26087fcbbc5f98ed64ac1230d5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 5 Sep 2010 14:51:49 +0100 Subject: [PATCH 249/300] ACPI: video: fix build for CONFIG_ACPI=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In file included from drivers/gpu/drm/i915/intel_opregion.c:30: include/acpi/video.h:22: warning: ‘struct acpi_device’ declared inside parameter list ... include/acpi/video.h:24: error: ‘ENODEV’ undeclared (first use in this function) Signed-off-by: Chris Wilson Signed-off-by: Len Brown --- include/acpi/video.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/acpi/video.h b/include/acpi/video.h index 551793c9b6e8..0e98e679d3a7 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h @@ -1,6 +1,10 @@ #ifndef __ACPI_VIDEO_H #define __ACPI_VIDEO_H +#include /* for ENODEV */ + +struct acpi_device; + #define ACPI_VIDEO_DISPLAY_CRT 1 #define ACPI_VIDEO_DISPLAY_TV 2 #define ACPI_VIDEO_DISPLAY_DVI 3 @@ -26,4 +30,3 @@ static inline int acpi_video_get_edid(struct acpi_device *device, int type, #endif #endif - From 3b38bb5f7f06356a89bb2cbf92ad346025e95192 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Thu, 2 Dec 2010 10:40:53 +0800 Subject: [PATCH 250/300] ACPI, APEI, use raw spinlock in ERST ERST writing may be used in NMI or Machine Check Exception handler. So it need to use raw spinlock instead of normal spinlock. This patch fixes it. Signed-off-by: Huang Ying Signed-off-by: Len Brown --- drivers/acpi/apei/erst.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 1211c03149e8..5850d320404c 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c @@ -86,7 +86,7 @@ static struct erst_erange { * It is used to provide exclusive accessing for ERST Error Log * Address Range too. */ -static DEFINE_SPINLOCK(erst_lock); +static DEFINE_RAW_SPINLOCK(erst_lock); static inline int erst_errno(int command_status) { @@ -421,9 +421,9 @@ ssize_t erst_get_record_count(void) if (erst_disable) return -ENODEV; - spin_lock_irqsave(&erst_lock, flags); + raw_spin_lock_irqsave(&erst_lock, flags); count = __erst_get_record_count(); - spin_unlock_irqrestore(&erst_lock, flags); + raw_spin_unlock_irqrestore(&erst_lock, flags); return count; } @@ -456,9 +456,9 @@ int erst_get_next_record_id(u64 *record_id) if (erst_disable) return -ENODEV; - spin_lock_irqsave(&erst_lock, flags); + raw_spin_lock_irqsave(&erst_lock, flags); rc = __erst_get_next_record_id(record_id); - spin_unlock_irqrestore(&erst_lock, flags); + raw_spin_unlock_irqrestore(&erst_lock, flags); return rc; } @@ -624,17 +624,17 @@ int erst_write(const struct cper_record_header *record) return -EINVAL; if (erst_erange.attr & ERST_RANGE_NVRAM) { - if (!spin_trylock_irqsave(&erst_lock, flags)) + if (!raw_spin_trylock_irqsave(&erst_lock, flags)) return -EBUSY; rc = __erst_write_to_nvram(record); - spin_unlock_irqrestore(&erst_lock, flags); + raw_spin_unlock_irqrestore(&erst_lock, flags); return rc; } if (record->record_length > erst_erange.size) return -EINVAL; - if (!spin_trylock_irqsave(&erst_lock, flags)) + if (!raw_spin_trylock_irqsave(&erst_lock, flags)) return -EBUSY; memcpy(erst_erange.vaddr, record, record->record_length); rcd_erange = erst_erange.vaddr; @@ -642,7 +642,7 @@ int erst_write(const struct cper_record_header *record) memcpy(&rcd_erange->persistence_information, "ER", 2); rc = __erst_write_to_storage(0); - spin_unlock_irqrestore(&erst_lock, flags); + raw_spin_unlock_irqrestore(&erst_lock, flags); return rc; } @@ -696,9 +696,9 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record, if (erst_disable) return -ENODEV; - spin_lock_irqsave(&erst_lock, flags); + raw_spin_lock_irqsave(&erst_lock, flags); len = __erst_read(record_id, record, buflen); - spin_unlock_irqrestore(&erst_lock, flags); + raw_spin_unlock_irqrestore(&erst_lock, flags); return len; } EXPORT_SYMBOL_GPL(erst_read); @@ -719,20 +719,20 @@ ssize_t erst_read_next(struct cper_record_header *record, size_t buflen) if (erst_disable) return -ENODEV; - spin_lock_irqsave(&erst_lock, flags); + raw_spin_lock_irqsave(&erst_lock, flags); rc = __erst_get_next_record_id(&record_id); if (rc) { - spin_unlock_irqrestore(&erst_lock, flags); + raw_spin_unlock_irqrestore(&erst_lock, flags); return rc; } /* no more record */ if (record_id == APEI_ERST_INVALID_RECORD_ID) { - spin_unlock_irqrestore(&erst_lock, flags); + raw_spin_unlock_irqrestore(&erst_lock, flags); return 0; } len = __erst_read(record_id, record, buflen); - spin_unlock_irqrestore(&erst_lock, flags); + raw_spin_unlock_irqrestore(&erst_lock, flags); return len; } @@ -746,12 +746,12 @@ int erst_clear(u64 record_id) if (erst_disable) return -ENODEV; - spin_lock_irqsave(&erst_lock, flags); + raw_spin_lock_irqsave(&erst_lock, flags); if (erst_erange.attr & ERST_RANGE_NVRAM) rc = __erst_clear_from_nvram(record_id); else rc = __erst_clear_from_storage(record_id); - spin_unlock_irqrestore(&erst_lock, flags); + raw_spin_unlock_irqrestore(&erst_lock, flags); return rc; } From 32d47eeff05981bfb89a95747eb182bc12630d58 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 8 Dec 2010 10:40:36 +0800 Subject: [PATCH 251/300] ACPI: fix a section mismatch WARNING: drivers/acpi/acpi.o(.text+0xeda): Section mismatch in reference from the function acpi_os_initialize1() to the function .init.text:set_osi_linux() The function acpi_os_initialize1() references the function __init set_osi_linux(). Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/osl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 966feddf6b1b..f7227e990b0f 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1530,7 +1530,7 @@ acpi_status __init acpi_os_initialize(void) return AE_OK; } -acpi_status acpi_os_initialize1(void) +acpi_status __init acpi_os_initialize1(void) { kacpid_wq = create_workqueue("kacpid"); kacpi_notify_wq = create_workqueue("kacpi_notify"); From b9047599695ae835252ba3d6a19eada98c19dc89 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 8 Dec 2010 10:40:26 +0800 Subject: [PATCH 252/300] ACPI thermal: remove two unused functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When CONFIG_CPU_FREQ=n ... drivers/acpi/processor_thermal.c:159:12: warning: ‘acpi_thermal_cpufreq_increase’ defined but not used drivers/acpi/processor_thermal.c:163:12: warning: ‘acpi_thermal_cpufreq_decrease’ defined but not used Remove unused declaration of ‘acpi_thermal_cpufreq_increase’ and ‘acpi_thermal_cpufreq_decrease’ Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/processor_thermal.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index fde49b9b1d99..79cb65332894 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -156,15 +156,6 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state) return 0; } -static int acpi_thermal_cpufreq_increase(unsigned int cpu) -{ - return -ENODEV; -} -static int acpi_thermal_cpufreq_decrease(unsigned int cpu) -{ - return -ENODEV; -} - #endif int acpi_processor_get_limit_info(struct acpi_processor *pr) From 66c3ec4f1f70ee87833363166b594855631d7ba6 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 7 Dec 2010 15:05:49 +0000 Subject: [PATCH 253/300] ACPI/PNP: avoid section mismatch warning Signed-off-by: Jan Beulich Signed-off-by: Len Brown --- drivers/pnp/pnpacpi/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 2d73dfcecdbb..57313f4658bc 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -180,7 +180,7 @@ struct pnp_protocol pnpacpi_protocol = { }; EXPORT_SYMBOL(pnpacpi_protocol); -static char *pnpacpi_get_id(struct acpi_device *device) +static char *__init pnpacpi_get_id(struct acpi_device *device) { struct acpi_hardware_id *id; From 091aad6af4ab29af693ced5d6970ceee9d5981c8 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 7 Dec 2010 14:52:25 +0000 Subject: [PATCH 254/300] ACPI: eliminate unused variable warning for !ACPI_SLEEP Signed-off-by: Jan Beulich Signed-off-by: Len Brown --- drivers/acpi/sleep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 721d93b3ceee..2182c5579230 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -27,8 +27,6 @@ static u8 sleep_states[ACPI_S_STATE_COUNT]; -static u32 acpi_target_sleep_state = ACPI_STATE_S0; - static void acpi_sleep_tts_switch(u32 acpi_state) { union acpi_object in_arg = { ACPI_TYPE_INTEGER }; @@ -81,6 +79,8 @@ static int acpi_sleep_prepare(u32 acpi_state) } #ifdef CONFIG_ACPI_SLEEP +static u32 acpi_target_sleep_state = ACPI_STATE_S0; + /* * The ACPI specification wants us to save NVS memory regions during hibernation * and to restore them during the subsequent resume. Windows does that also for From bec4f22a2dbd5a26079cbddbcadf38f8c7e5381f Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 7 Dec 2010 14:58:44 +0000 Subject: [PATCH 255/300] ACPI/HEST: adjust section selection Properly const-, __init-, and __read_mostly-annotate this code. Signed-off-by: Jan Beulich Signed-off-by: Len Brown --- drivers/acpi/apei/hest.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 1a3508a7fe03..daa7bc63f1d4 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c @@ -46,9 +46,9 @@ EXPORT_SYMBOL_GPL(hest_disable); /* HEST table parsing */ -static struct acpi_table_hest *hest_tab; +static struct acpi_table_hest *__read_mostly hest_tab; -static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { +static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi), @@ -126,7 +126,7 @@ struct ghes_arr { unsigned int count; }; -static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) +static int __init hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) { int *count = data; @@ -135,7 +135,7 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) return 0; } -static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) +static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) { struct platform_device *ghes_dev; struct ghes_arr *ghes_arr = data; @@ -165,7 +165,7 @@ err: return rc; } -static int hest_ghes_dev_register(unsigned int ghes_count) +static int __init hest_ghes_dev_register(unsigned int ghes_count) { int rc, i; struct ghes_arr ghes_arr; From af0cdf4947818becfe209610b209315578645ab4 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Tue, 7 Dec 2010 19:16:02 +0100 Subject: [PATCH 256/300] firewire: ohci: fix regression with VIA VT6315, disable MSI "VIA Technologies, Inc. VT6315 Series Firewire Controller [1106:3403]" does not generate any interrupts if Message Signaled Interrupts were enabled. This is a regression since kernel 2.6.36 in which MSI support was added to firewire-ohci. Hence blacklist MSI on all VIA controllers. Reported-by: Robin Cook Signed-off-by: Stefan Richter Cc: # 2.6.36.y --- drivers/firewire/ohci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 84eb607d6c03..5697cf20c924 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -262,7 +262,8 @@ static const struct { {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI}, {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, - {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, + {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER | + QUIRK_NO_MSI}, {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS}, }; From 9993e0fe0f5f29c69e79efcb271ffc9843002985 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Tue, 7 Dec 2010 20:32:40 +0100 Subject: [PATCH 257/300] firewire: ohci: fix regression with Agere FW643 rev 06, disable MSI Agere FW643 rev 06, listed as "11c1:5901 (rev 06) (prog-if 10 [OHCI])", produced SBP-2 I/O errors since kernel 2.6.36. Disabling MSI fixes it. Since MSI work on Agere FW643-E (same vendor and device ID, but rev 07), introduce a device revision field into firewire-ohci's quirks list so that different quirks can be defined for older and newer revisions. Reported-by: Jonathan Isom Signed-off-by: Stefan Richter Cc: # 2.6.36.y --- drivers/firewire/ohci.c | 48 ++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 5697cf20c924..e3c8b60bd86b 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -242,6 +242,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) static char ohci_driver_name[] = KBUILD_MODNAME; +#define PCI_DEVICE_ID_AGERE_FW643 0x5901 #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 @@ -253,19 +254,34 @@ static char ohci_driver_name[] = KBUILD_MODNAME; /* In case of multiple matches in ohci_quirks[], only the first one is used. */ static const struct { - unsigned short vendor, device, flags; + unsigned short vendor, device, revision, flags; } ohci_quirks[] = { - {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER | - QUIRK_RESET_PACKET | - QUIRK_NO_1394A}, - {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, - {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, - {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI}, - {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, - {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER | - QUIRK_NO_MSI}, - {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, - {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS}, + {PCI_VENDOR_ID_AL, PCI_ANY_ID, PCI_ANY_ID, + QUIRK_CYCLE_TIMER}, + + {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, PCI_ANY_ID, + QUIRK_BE_HEADERS}, + + {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6, + QUIRK_NO_MSI}, + + {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID, + QUIRK_NO_MSI}, + + {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID, + QUIRK_CYCLE_TIMER}, + + {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID, + QUIRK_CYCLE_TIMER}, + + {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID, + QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A}, + + {PCI_VENDOR_ID_TI, PCI_ANY_ID, PCI_ANY_ID, + QUIRK_RESET_PACKET}, + + {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID, + QUIRK_CYCLE_TIMER | QUIRK_NO_MSI}, }; /* This overrides anything that was found in ohci_quirks[]. */ @@ -2928,9 +2944,11 @@ static int __devinit pci_probe(struct pci_dev *dev, } for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++) - if (ohci_quirks[i].vendor == dev->vendor && - (ohci_quirks[i].device == dev->device || - ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) { + if ((ohci_quirks[i].vendor == dev->vendor) && + (ohci_quirks[i].device == (unsigned short)PCI_ANY_ID || + ohci_quirks[i].device == dev->device) && + (ohci_quirks[i].revision == (unsigned short)PCI_ANY_ID || + ohci_quirks[i].revision >= dev->revision)) { ohci->quirks = ohci_quirks[i].flags; break; } From 4d7b6b5d247aa71ea27709b9eac1ba6e752fbe87 Mon Sep 17 00:00:00 2001 From: Ron Mercer Date: Sat, 11 Dec 2010 11:06:50 +0000 Subject: [PATCH 258/300] qlge: Fix deadlock when cancelling worker. Removing usage of rtnl_lock() to protect firmware interface registers. These registers are accessed in some worker threads and can create a deadlock if rtnl_lock is taken by upper layers while the worker is still pending. We remove rtnl_lock and use a driver mutex just while mailboxes are accessed. Signed-off-by: Ron Mercer Signed-off-by: David S. Miller --- drivers/net/qlge/qlge.h | 1 + drivers/net/qlge/qlge_main.c | 1 + drivers/net/qlge/qlge_mpi.c | 12 ++++-------- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 22821398fc63..9787dff90d3f 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h @@ -2083,6 +2083,7 @@ struct ql_adapter { u32 mailbox_in; u32 mailbox_out; struct mbox_params idc_mbc; + struct mutex mpi_mutex; int tx_ring_size; int rx_ring_size; diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 528eaef5308f..2555b1d34f34 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -4629,6 +4629,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev, INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work); INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log); init_completion(&qdev->ide_completion); + mutex_init(&qdev->mpi_mutex); if (!cards_found) { dev_info(&pdev->dev, "%s\n", DRV_STRING); diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c index 0e7c7c7ee164..a2e919bcb3c6 100644 --- a/drivers/net/qlge/qlge_mpi.c +++ b/drivers/net/qlge/qlge_mpi.c @@ -534,6 +534,7 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) int status; unsigned long count; + mutex_lock(&qdev->mpi_mutex); /* Begin polled mode for MPI */ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); @@ -603,6 +604,7 @@ done: end: /* End polled mode for MPI */ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); + mutex_unlock(&qdev->mpi_mutex); return status; } @@ -1099,9 +1101,7 @@ int ql_wait_fifo_empty(struct ql_adapter *qdev) static int ql_set_port_cfg(struct ql_adapter *qdev) { int status; - rtnl_lock(); status = ql_mb_set_port_cfg(qdev); - rtnl_unlock(); if (status) return status; status = ql_idc_wait(qdev); @@ -1122,9 +1122,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work) container_of(work, struct ql_adapter, mpi_port_cfg_work.work); int status; - rtnl_lock(); status = ql_mb_get_port_cfg(qdev); - rtnl_unlock(); if (status) { netif_err(qdev, drv, qdev->ndev, "Bug: Failed to get port config data.\n"); @@ -1167,7 +1165,6 @@ void ql_mpi_idc_work(struct work_struct *work) u32 aen; int timeout; - rtnl_lock(); aen = mbcp->mbox_out[1] >> 16; timeout = (mbcp->mbox_out[1] >> 8) & 0xf; @@ -1231,7 +1228,6 @@ void ql_mpi_idc_work(struct work_struct *work) } break; } - rtnl_unlock(); } void ql_mpi_work(struct work_struct *work) @@ -1242,7 +1238,7 @@ void ql_mpi_work(struct work_struct *work) struct mbox_params *mbcp = &mbc; int err = 0; - rtnl_lock(); + mutex_lock(&qdev->mpi_mutex); /* Begin polled mode for MPI */ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); @@ -1259,7 +1255,7 @@ void ql_mpi_work(struct work_struct *work) /* End polled mode for MPI */ ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); - rtnl_unlock(); + mutex_unlock(&qdev->mpi_mutex); ql_enable_completion_interrupt(qdev, 0); } From 099978b434d4924594516db540ccc50652e7cc94 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 12 Dec 2010 04:11:45 +0000 Subject: [PATCH 259/300] bnx2x: LSO code was broken on BE platforms Make the LSO code work on BE platforms: parsing_data field of a parsing BD (PBD) for 57712 was improperly composed which made FW read wrong values for TCP header's length and offset and, as a result, the corresponding PCI device was performing bad DMA reads triggering EEH. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_cmn.c | 42 ++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 94d5f59d5a6f..0af361e4e3d1 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1782,15 +1782,15 @@ exit_lbl: } #endif -static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, - struct eth_tx_parse_bd_e2 *pbd, - u32 xmit_type) +static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data, + u32 xmit_type) { - pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) << - ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT; + *parsing_data |= (skb_shinfo(skb)->gso_size << + ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) & + ETH_TX_PARSE_BD_E2_LSO_MSS; if ((xmit_type & XMIT_GSO_V6) && (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6)) - pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; + *parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; } /** @@ -1835,15 +1835,15 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, * @return header len */ static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, - struct eth_tx_parse_bd_e2 *pbd, - u32 xmit_type) + u32 *parsing_data, u32 xmit_type) { - pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) << - ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT; + *parsing_data |= ((tcp_hdrlen(skb)/4) << + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; - pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) - - skb->data) / 2) << - ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT; + *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) << + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) & + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W; return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; } @@ -1912,6 +1912,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; + u32 pbd_e2_parsing_data = 0; u16 pkt_prod, bd_prod; int nbd, fp_index; dma_addr_t mapping; @@ -2033,8 +2034,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); /* Set PBD in checksum offload case */ if (xmit_type & XMIT_CSUM) - hlen = bnx2x_set_pbd_csum_e2(bp, - skb, pbd_e2, xmit_type); + hlen = bnx2x_set_pbd_csum_e2(bp, skb, + &pbd_e2_parsing_data, + xmit_type); } else { pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); @@ -2076,10 +2078,18 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, hlen, bd_prod, ++nbd); if (CHIP_IS_E2(bp)) - bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type); + bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data, + xmit_type); else bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type); } + + /* Set the PBD's parsing_data field if not zero + * (for the chips newer than 57711). + */ + if (pbd_e2_parsing_data) + pbd_e2->parsing_data = cpu_to_le32(pbd_e2_parsing_data); + tx_data_bd = (struct eth_tx_bd *)tx_start_bd; /* Handle fragmented skb */ From 372e43eb2fc34001250e27d63f99c20e46ea58a7 Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 12 Dec 2010 04:12:12 +0000 Subject: [PATCH 260/300] bnx2x: Fixed a compilation warning bnx2x_src_init_t2() is used only when BCM_CNIC is defined. So, to avoid a compilation warning, we won't define it unless BCM_CNIC is defined. Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x_init_ops.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h index a306b0e46b61..66df29fcf751 100644 --- a/drivers/net/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/bnx2x/bnx2x_init_ops.h @@ -838,7 +838,7 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count, /**************************************************************************** * SRC initializations ****************************************************************************/ - +#ifdef BCM_CNIC /* called during init func stage */ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, dma_addr_t t2_mapping, int src_cid_count) @@ -862,5 +862,5 @@ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, U64_HI((u64)t2_mapping + (src_cid_count-1) * sizeof(struct src_ent))); } - +#endif #endif /* BNX2X_INIT_OPS_H */ From 9f5449611c9d6d7bdcae8020a197d8b4d9b6443c Mon Sep 17 00:00:00 2001 From: Vladislav Zolotarov Date: Sun, 12 Dec 2010 04:12:29 +0000 Subject: [PATCH 261/300] bnx2x: Advance a version number to 1.60.01-0 Signed-off-by: Vladislav Zolotarov Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/bnx2x/bnx2x.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 863e73a85fbe..d255428122fc 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -20,8 +20,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.60.00-4" -#define DRV_MODULE_RELDATE "2010/11/01" +#define DRV_MODULE_VERSION "1.60.01-0" +#define DRV_MODULE_RELDATE "2010/11/12" #define BNX2X_BC_VER 0x040200 #define BNX2X_MULTI_QUEUE From eaff9453d3e2b63969af93e9d42a85e803060121 Mon Sep 17 00:00:00 2001 From: Krzysztof Halasa Date: Sun, 12 Dec 2010 12:06:47 +0000 Subject: [PATCH 262/300] WAN: Fix a TX IRQ causing BUG() in PC300 and PCI200SYN drivers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We must not wake the TX queue without free TX descriptors. sca_xmit() expects at least one free descriptor and BUGs otherwise. Problem reported and fix tested by Bernie Innocenti and Ward Vandewege. Signed-off-by: Krzysztof Hałasa Signed-off-by: David S. Miller --- drivers/net/wan/hd64572.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c index ea476cbd38b5..e305274f83fb 100644 --- a/drivers/net/wan/hd64572.c +++ b/drivers/net/wan/hd64572.c @@ -293,6 +293,7 @@ static inline void sca_tx_done(port_t *port) struct net_device *dev = port->netdev; card_t* card = port->card; u8 stat; + unsigned count = 0; spin_lock(&port->lock); @@ -316,10 +317,12 @@ static inline void sca_tx_done(port_t *port) dev->stats.tx_bytes += readw(&desc->len); } writeb(0, &desc->stat); /* Free descriptor */ + count++; port->txlast = (port->txlast + 1) % card->tx_ring_buffers; } - netif_wake_queue(dev); + if (count) + netif_wake_queue(dev); spin_unlock(&port->lock); } From 2a27a03d3a891e87ca33d27a858b4db734a4cbab Mon Sep 17 00:00:00 2001 From: Andrej Ota Date: Sun, 12 Dec 2010 15:06:16 -0800 Subject: [PATCH 263/300] pppoe.c: Fix kernel panic caused by __pppoe_xmit __pppoe_xmit function return value was invalid resulting in additional call to kfree_skb on already freed skb. This resulted in memory corruption and consequent kernel panic after PPPoE peer terminated the link. This fixes commit 55c95e738da85373965cb03b4f975d0fd559865b. Reported-by: Gorik Van Steenberge Reported-by: Daniel Kenzelmann Reported-by: Denys Fedoryshchenko Reported-by: Pawel Staszewski Diagnosed-by: Andrej Ota Diagnosed-by: Eric Dumazet Tested-by: Denys Fedoryshchenko Tested-by: Pawel Staszewski Signed-off-by: Jarek Poplawski Signed-off-by: Andrej Ota Signed-off-by: David S. Miller --- drivers/net/pppoe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index d72fb0519a2a..78c0e3c9b2b5 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -948,7 +948,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) abort: kfree_skb(skb); - return 0; + return 1; } /************************************************************************ From f91e2c3bd427239c198351f44814dd39db91afe0 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Tue, 7 Dec 2010 16:52:04 +0100 Subject: [PATCH 264/300] ARM: 6527/1: Use CTR instead of CCSIDR for the D-cache line size on ARMv7 The current implementation of the dcache_line_size macro reads the L1 cache size from the CCSIDR register. This, however, is not guaranteed to be the smallest cache line in the cache hierarchy. The patch changes to the macro to use the more architecturally correct CTR register. Reported-by: Kevin Sapp Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/proc-macros.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index 7d63beaf9745..321555b894d1 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S @@ -61,14 +61,14 @@ .endm /* - * cache_line_size - get the cache line size from the CSIDR register - * (available on ARMv7+). It assumes that the CSSR register was configured - * to access the L1 data cache CSIDR. + * dcache_line_size - get the minimum D-cache line size from the CTR register + * on ARMv7. */ .macro dcache_line_size, reg, tmp - mrc p15, 1, \tmp, c0, c0, 0 @ read CSIDR - and \tmp, \tmp, #7 @ cache line size encoding - mov \reg, #16 @ size offset + mrc p15, 0, \tmp, c0, c0, 1 @ read ctr + lsr \tmp, \tmp, #16 + and \tmp, \tmp, #0xf @ cache line size encoding + mov \reg, #4 @ bytes per word mov \reg, \reg, lsl \tmp @ actual cache line size .endm From da30e0ac0f9a521f0cfec8145ddd1ad131f66d61 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Tue, 7 Dec 2010 16:56:29 +0100 Subject: [PATCH 265/300] ARM: 6528/1: Use CTR for the I-cache line size on ARMv7 The current implementation of the v7_coherent_*_range function assumes that the D and I cache lines have the same size, which is incorrect architecturally. This patch adds the icache_line_size macro which reads the CTR register. The main loop in v7_coherent_*_range is split in two independent loops or the D and I caches. This also has the performance advantage that the DSB is moved outside the main loop. Reported-by: Kevin Sapp Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/cache-v7.S | 29 ++++++++++++++++++----------- arch/arm/mm/proc-macros.S | 10 ++++++++++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index a3ebf7a4f49b..6136e68ce953 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S @@ -173,15 +173,22 @@ ENTRY(v7_coherent_user_range) UNWIND(.fnstart ) dcache_line_size r2, r3 sub r3, r2, #1 - bic r0, r0, r3 + bic r12, r0, r3 1: - USER( mcr p15, 0, r0, c7, c11, 1 ) @ clean D line to the point of unification - dsb - USER( mcr p15, 0, r0, c7, c5, 1 ) @ invalidate I line - add r0, r0, r2 -2: - cmp r0, r1 + USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification + add r12, r12, r2 + cmp r12, r1 blo 1b + dsb + icache_line_size r2, r3 + sub r3, r2, #1 + bic r12, r0, r3 +2: + USER( mcr p15, 0, r12, c7, c5, 1 ) @ invalidate I line + add r12, r12, r2 + cmp r12, r1 + blo 2b +3: mov r0, #0 ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB @@ -194,10 +201,10 @@ ENTRY(v7_coherent_user_range) * isn't mapped, just try the next page. */ 9001: - mov r0, r0, lsr #12 - mov r0, r0, lsl #12 - add r0, r0, #4096 - b 2b + mov r12, r12, lsr #12 + mov r12, r12, lsl #12 + add r12, r12, #4096 + b 3b UNWIND(.fnend ) ENDPROC(v7_coherent_kern_range) ENDPROC(v7_coherent_user_range) diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index 321555b894d1..b795afd0a2c6 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S @@ -72,6 +72,16 @@ mov \reg, \reg, lsl \tmp @ actual cache line size .endm +/* + * icache_line_size - get the minimum I-cache line size from the CTR register + * on ARMv7. + */ + .macro icache_line_size, reg, tmp + mrc p15, 0, \tmp, c0, c0, 1 @ read ctr + and \tmp, \tmp, #0xf @ cache line size encoding + mov \reg, #4 @ bytes per word + mov \reg, \reg, lsl \tmp @ actual cache line size + .endm /* * Sanity check the PTE configuration for the code below - which makes From 440e2e4759805437f89f7eda78de72cb46729d04 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 12 Dec 2010 23:24:28 +0000 Subject: [PATCH 266/300] ARM: Update mach-types Signed-off-by: Russell King --- arch/arm/tools/mach-types | 183 +++++++++++++++++++++++++++++++++++++- 1 file changed, 179 insertions(+), 4 deletions(-) diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 55590a4d87c9..2fea897ebeb1 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Thu Sep 9 22:43:01 2010 +# Last update: Sun Dec 12 23:24:27 2010 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -2321,7 +2321,7 @@ mx31txtr MACH_MX31TXTR MX31TXTR 2332 u380 MACH_U380 U380 2333 oamp3_hualu MACH_HUALU_BOARD HUALU_BOARD 2334 npcmx50 MACH_NPCMX50 NPCMX50 2335 -mx51_lange51 MACH_MX51_LANGE51 MX51_LANGE51 2336 +mx51_efikamx MACH_MX51_EFIKAMX MX51_EFIKAMX 2336 mx51_lange52 MACH_MX51_LANGE52 MX51_LANGE52 2337 riom MACH_RIOM RIOM 2338 comcas MACH_COMCAS COMCAS 2339 @@ -2355,7 +2355,7 @@ at91sam9263cs MACH_AT91SAM9263CS AT91SAM9263CS 2366 csb732 MACH_CSB732 CSB732 2367 u8500 MACH_U8500 U8500 2368 huqiu MACH_HUQIU HUQIU 2369 -mx51_kunlun MACH_MX51_KUNLUN MX51_KUNLUN 2370 +mx51_efikasb MACH_MX51_EFIKASB MX51_EFIKASB 2370 pmt1g MACH_PMT1G PMT1G 2371 htcelf MACH_HTCELF HTCELF 2372 armadillo420 MACH_ARMADILLO420 ARMADILLO420 2373 @@ -2971,7 +2971,7 @@ premierwave_en MACH_PREMIERWAVE_EN PREMIERWAVE_EN 2985 wasabi MACH_WASABI WASABI 2986 vivow MACH_VIVOW VIVOW 2987 mx50_rdp MACH_MX50_RDP MX50_RDP 2988 -universal MACH_UNIVERSAL UNIVERSAL 2989 +universal_c210 MACH_UNIVERSAL_C210 UNIVERSAL_C210 2989 real6410 MACH_REAL6410 REAL6410 2990 spx_sakura MACH_SPX_SAKURA SPX_SAKURA 2991 ij3k_2440 MACH_IJ3K_2440 IJ3K_2440 2992 @@ -3044,3 +3044,178 @@ harvest_desoto MACH_HARVEST_DESOTO HARVEST_DESOTO 3059 msm8x60_qrdc MACH_MSM8X60_QRDC MSM8X60_QRDC 3060 spear900 MACH_SPEAR900 SPEAR900 3061 pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062 +rdstor MACH_RDSTOR RDSTOR 3063 +usdloader MACH_USDLOADER USDLOADER 3064 +tsoploader MACH_TSOPLOADER TSOPLOADER 3065 +kronos MACH_KRONOS KRONOS 3066 +ffcore MACH_FFCORE FFCORE 3067 +mone MACH_MONE MONE 3068 +unit2s MACH_UNIT2S UNIT2S 3069 +acer_a5 MACH_ACER_A5 ACER_A5 3070 +etherpro_isp MACH_ETHERPRO_ISP ETHERPRO_ISP 3071 +stretchs7000 MACH_STRETCHS7000 STRETCHS7000 3072 +p87_smartsim MACH_P87_SMARTSIM P87_SMARTSIM 3073 +tulip MACH_TULIP TULIP 3074 +sunflower MACH_SUNFLOWER SUNFLOWER 3075 +rib MACH_RIB RIB 3076 +clod MACH_CLOD CLOD 3077 +rump MACH_RUMP RUMP 3078 +tenderloin MACH_TENDERLOIN TENDERLOIN 3079 +shortloin MACH_SHORTLOIN SHORTLOIN 3080 +crespo MACH_CRESPO CRESPO 3081 +antares MACH_ANTARES ANTARES 3082 +wb40n MACH_WB40N WB40N 3083 +herring MACH_HERRING HERRING 3084 +naxy400 MACH_NAXY400 NAXY400 3085 +naxy1200 MACH_NAXY1200 NAXY1200 3086 +vpr200 MACH_VPR200 VPR200 3087 +bug20 MACH_BUG20 BUG20 3088 +goflexnet MACH_GOFLEXNET GOFLEXNET 3089 +torbreck MACH_TORBRECK TORBRECK 3090 +saarb_mg1 MACH_SAARB_MG1 SAARB_MG1 3091 +callisto MACH_CALLISTO CALLISTO 3092 +multhsu MACH_MULTHSU MULTHSU 3093 +saluda MACH_SALUDA SALUDA 3094 +pemp_omap3_apollo MACH_PEMP_OMAP3_APOLLO PEMP_OMAP3_APOLLO 3095 +vc0718 MACH_VC0718 VC0718 3096 +mvblx MACH_MVBLX MVBLX 3097 +inhand_apeiron MACH_INHAND_APEIRON INHAND_APEIRON 3098 +inhand_fury MACH_INHAND_FURY INHAND_FURY 3099 +inhand_siren MACH_INHAND_SIREN INHAND_SIREN 3100 +hdnvp MACH_HDNVP HDNVP 3101 +softwinner MACH_SOFTWINNER SOFTWINNER 3102 +prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103 +nas6210 MACH_NAS6210 NAS6210 3104 +unisdev MACH_UNISDEV UNISDEV 3105 +sbca11 MACH_SBCA11 SBCA11 3106 +saga MACH_SAGA SAGA 3107 +ns_k330 MACH_NS_K330 NS_K330 3108 +tanna MACH_TANNA TANNA 3109 +imate8502 MACH_IMATE8502 IMATE8502 3110 +aspen MACH_ASPEN ASPEN 3111 +daintree_cwac MACH_DAINTREE_CWAC DAINTREE_CWAC 3112 +zmx25 MACH_ZMX25 ZMX25 3113 +maple1 MACH_MAPLE1 MAPLE1 3114 +qsd8x72_surf MACH_QSD8X72_SURF QSD8X72_SURF 3115 +qsd8x72_ffa MACH_QSD8X72_FFA QSD8X72_FFA 3116 +abilene MACH_ABILENE ABILENE 3117 +eigen_ttr MACH_EIGEN_TTR EIGEN_TTR 3118 +iomega_ix2_200 MACH_IOMEGA_IX2_200 IOMEGA_IX2_200 3119 +coretec_vcx7400 MACH_CORETEC_VCX7400 CORETEC_VCX7400 3120 +santiago MACH_SANTIAGO SANTIAGO 3121 +mx257sol MACH_MX257SOL MX257SOL 3122 +strasbourg MACH_STRASBOURG STRASBOURG 3123 +msm8x60_fluid MACH_MSM8X60_FLUID MSM8X60_FLUID 3124 +smartqv5 MACH_SMARTQV5 SMARTQV5 3125 +smartqv3 MACH_SMARTQV3 SMARTQV3 3126 +smartqv7 MACH_SMARTQV7 SMARTQV7 3127 +paz00 MACH_PAZ00 PAZ00 3128 +acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129 +htcwillow MACH_HTCWILLOW HTCWILLOW 3130 +fwbd_0404 MACH_FWBD_0404 FWBD_0404 3131 +hdgu MACH_HDGU HDGU 3132 +pyramid MACH_PYRAMID PYRAMID 3133 +epiphan MACH_EPIPHAN EPIPHAN 3134 +omap_bender MACH_OMAP_BENDER OMAP_BENDER 3135 +gurnard MACH_GURNARD GURNARD 3136 +gtl_it5100 MACH_GTL_IT5100 GTL_IT5100 3137 +bcm2708 MACH_BCM2708 BCM2708 3138 +mx51_ggc MACH_MX51_GGC MX51_GGC 3139 +sharespace MACH_SHARESPACE SHARESPACE 3140 +haba_knx_explorer MACH_HABA_KNX_EXPLORER HABA_KNX_EXPLORER 3141 +simtec_kirkmod MACH_SIMTEC_KIRKMOD SIMTEC_KIRKMOD 3142 +crux MACH_CRUX CRUX 3143 +mx51_bravo MACH_MX51_BRAVO MX51_BRAVO 3144 +charon MACH_CHARON CHARON 3145 +picocom3 MACH_PICOCOM3 PICOCOM3 3146 +picocom4 MACH_PICOCOM4 PICOCOM4 3147 +serrano MACH_SERRANO SERRANO 3148 +doubleshot MACH_DOUBLESHOT DOUBLESHOT 3149 +evsy MACH_EVSY EVSY 3150 +huashan MACH_HUASHAN HUASHAN 3151 +lausanne MACH_LAUSANNE LAUSANNE 3152 +emerald MACH_EMERALD EMERALD 3153 +tqma35 MACH_TQMA35 TQMA35 3154 +marvel MACH_MARVEL MARVEL 3155 +manuae MACH_MANUAE MANUAE 3156 +chacha MACH_CHACHA CHACHA 3157 +lemon MACH_LEMON LEMON 3158 +csc MACH_CSC CSC 3159 +gira_knxip_router MACH_GIRA_KNXIP_ROUTER GIRA_KNXIP_ROUTER 3160 +t20 MACH_T20 T20 3161 +hdmini MACH_HDMINI HDMINI 3162 +sciphone_g2 MACH_SCIPHONE_G2 SCIPHONE_G2 3163 +express MACH_EXPRESS EXPRESS 3164 +express_kt MACH_EXPRESS_KT EXPRESS_KT 3165 +maximasp MACH_MAXIMASP MAXIMASP 3166 +nitrogen_imx51 MACH_NITROGEN_IMX51 NITROGEN_IMX51 3167 +nitrogen_imx53 MACH_NITROGEN_IMX53 NITROGEN_IMX53 3168 +sunfire MACH_SUNFIRE SUNFIRE 3169 +arowana MACH_AROWANA AROWANA 3170 +tegra_daytona MACH_TEGRA_DAYTONA TEGRA_DAYTONA 3171 +tegra_swordfish MACH_TEGRA_SWORDFISH TEGRA_SWORDFISH 3172 +edison MACH_EDISON EDISON 3173 +svp8500v1 MACH_SVP8500V1 SVP8500V1 3174 +svp8500v2 MACH_SVP8500V2 SVP8500V2 3175 +svp5500 MACH_SVP5500 SVP5500 3176 +b5500 MACH_B5500 B5500 3177 +s5500 MACH_S5500 S5500 3178 +icon MACH_ICON ICON 3179 +elephant MACH_ELEPHANT ELEPHANT 3180 +msm8x60_fusion MACH_MSM8X60_FUSION MSM8X60_FUSION 3181 +shooter MACH_SHOOTER SHOOTER 3182 +spade_lte MACH_SPADE_LTE SPADE_LTE 3183 +philhwani MACH_PHILHWANI PHILHWANI 3184 +gsncomm MACH_GSNCOMM GSNCOMM 3185 +strasbourg_a2 MACH_STRASBOURG_A2 STRASBOURG_A2 3186 +mmm MACH_MMM MMM 3187 +davinci_dm365_bv MACH_DAVINCI_DM365_BV DAVINCI_DM365_BV 3188 +ag5evm MACH_AG5EVM AG5EVM 3189 +sc575plc MACH_SC575PLC SC575PLC 3190 +sc575hmi MACH_SC575IPC SC575IPC 3191 +omap3_tdm3730 MACH_OMAP3_TDM3730 OMAP3_TDM3730 3192 +g7 MACH_G7 G7 3193 +top9000_eval MACH_TOP9000_EVAL TOP9000_EVAL 3194 +top9000_su MACH_TOP9000_SU TOP9000_SU 3195 +utm300 MACH_UTM300 UTM300 3196 +tsunagi MACH_TSUNAGI TSUNAGI 3197 +ts75xx MACH_TS75XX TS75XX 3198 +msm8x60_fusn_ffa MACH_MSM8X60_FUSN_FFA MSM8X60_FUSN_FFA 3199 +ts47xx MACH_TS47XX TS47XX 3200 +da850_k5 MACH_DA850_K5 DA850_K5 3201 +ax502 MACH_AX502 AX502 3202 +igep0032 MACH_IGEP0032 IGEP0032 3203 +antero MACH_ANTERO ANTERO 3204 +synergy MACH_SYNERGY SYNERGY 3205 +ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 +wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 +punica MACH_PUNICA PUNICA 3208 +sbc_nt250 MACH_SBC_NT250 SBC_NT250 3209 +mx27_wmultra MACH_MX27_WMULTRA MX27_WMULTRA 3210 +mackerel MACH_MACKEREL MACKEREL 3211 +fa9x27 MACH_FA9X27 FA9X27 3213 +ns2816tb MACH_NS2816TB NS2816TB 3214 +ns2816_ntpad MACH_NS2816_NTPAD NS2816_NTPAD 3215 +ns2816_ntnb MACH_NS2816_NTNB NS2816_NTNB 3216 +kaen MACH_KAEN KAEN 3217 +nv1000 MACH_NV1000 NV1000 3218 +nuc950ts MACH_NUC950TS NUC950TS 3219 +nokia_rm680 MACH_NOKIA_RM680 NOKIA_RM680 3220 +ast2200 MACH_AST2200 AST2200 3221 +lead MACH_LEAD LEAD 3222 +unino1 MACH_UNINO1 UNINO1 3223 +greeco MACH_GREECO GREECO 3224 +verdi MACH_VERDI VERDI 3225 +dm6446_adbox MACH_DM6446_ADBOX DM6446_ADBOX 3226 +quad_salsa MACH_QUAD_SALSA QUAD_SALSA 3227 +abb_gma_1_1 MACH_ABB_GMA_1_1 ABB_GMA_1_1 3228 +svcid MACH_SVCID SVCID 3229 +msm8960_sim MACH_MSM8960_SIM MSM8960_SIM 3230 +msm8960_rumi3 MACH_MSM8960_RUMI3 MSM8960_RUMI3 3231 +icon_g MACH_ICON_G ICON_G 3232 +mb3 MACH_MB3 MB3 3233 +gsia18s MACH_GSIA18S GSIA18S 3234 +pivicc MACH_PIVICC PIVICC 3235 +pcm048 MACH_PCM048 PCM048 3236 +dds MACH_DDS DDS 3237 +chalten_xa1 MACH_CHALTEN_XA1 CHALTEN_XA1 3238 From 80fbf8382e110656ea67327300f16cfd2488a9bf Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 13 Dec 2010 14:59:51 +0900 Subject: [PATCH 267/300] sh: Enable deprecated IRQ chip APIs for MFD and GPIOLIB drivers. There are still quite a number of MFD and GPIO expander drivers that are using the old irq_chip APIs that haven't had a chance to update during the .37 cycle, resulting in allyes/modconfig errors on some configurations. Mark Brown has done most of the legwork to get these fixed up in .38, so this should just be a .37 stop-gap that we can drop at the end of the .38 merge window. Reported-by: Mark Brown Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 7f217b3a50a8..2e9d78d21fd3 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -22,7 +22,8 @@ config SUPERH select HAVE_SPARSE_IRQ select RTC_LIB select GENERIC_ATOMIC64 - select GENERIC_HARDIRQS_NO_DEPRECATED + # Support the deprecated APIs until MFD and GPIOLIB catch up. + select GENERIC_HARDIRQS_NO_DEPRECATED if !MFD_SUPPORT && !GPIOLIB help The SuperH is a RISC processor targeted for use in embedded systems and consumer electronics; it was also used in the Sega Dreamcast From 0a6bf658c3b9d1d0e520d320b6392c8680c2e381 Mon Sep 17 00:00:00 2001 From: "Ira W. Snyder" Date: Mon, 13 Dec 2010 11:42:30 -0500 Subject: [PATCH 268/300] hwmon: (ltc4215) make sysfs file match the alarm cause The ltc4215 driver used the chip's "power good" status bit to provide the power1_alarm file. This is wrong: the chip is really reporting the status of one of the monitored voltages. Change the sysfs file from power1_alarm to in2_min_alarm instead. This matches the voltage that the chip is raising an alarm for. Signed-off-by: Ira W. Snyder Signed-off-by: Guenter Roeck --- drivers/hwmon/ltc4215.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c index 00d975eb5b83..c7e6d8e81656 100644 --- a/drivers/hwmon/ltc4215.c +++ b/drivers/hwmon/ltc4215.c @@ -205,7 +205,6 @@ LTC4215_ALARM(curr1_max_alarm, (1 << 2), LTC4215_STATUS); /* Power (virtual) */ LTC4215_POWER(power1_input); -LTC4215_ALARM(power1_alarm, (1 << 3), LTC4215_STATUS); /* Input Voltage */ LTC4215_VOLTAGE(in1_input, LTC4215_ADIN); @@ -214,6 +213,7 @@ LTC4215_ALARM(in1_min_alarm, (1 << 1), LTC4215_STATUS); /* Output Voltage */ LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE); +LTC4215_ALARM(in2_min_alarm, (1 << 3), LTC4215_STATUS); /* Finally, construct an array of pointers to members of the above objects, * as required for sysfs_create_group() @@ -223,13 +223,13 @@ static struct attribute *ltc4215_attributes[] = { &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, &sensor_dev_attr_power1_input.dev_attr.attr, - &sensor_dev_attr_power1_alarm.dev_attr.attr, &sensor_dev_attr_in1_input.dev_attr.attr, &sensor_dev_attr_in1_max_alarm.dev_attr.attr, &sensor_dev_attr_in1_min_alarm.dev_attr.attr, &sensor_dev_attr_in2_input.dev_attr.attr, + &sensor_dev_attr_in2_min_alarm.dev_attr.attr, NULL, }; From 68433b73b104bff388aac376631d32abbbd872b0 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Mon, 13 Dec 2010 14:47:58 -0500 Subject: [PATCH 269/300] Btrfs: EIO when we fail to read tree roots If we just get a plain IO error when we read tree roots, the code wasn't properly sending that error up the chain. This allowed mounts to continue when they should failed, and allowed operations on partially setup root structs. The end result was usually oopsen on spinlocks that hadn't been spun up correctly. Signed-off-by: Chris Mason --- fs/btrfs/disk-io.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index b803c2667673..a5d2249e6da5 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1007,7 +1007,10 @@ static int find_and_setup_root(struct btrfs_root *tree_root, blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), blocksize, generation); - BUG_ON(!root->node); + if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) { + free_extent_buffer(root->node); + return -EIO; + } root->commit_root = btrfs_root_node(root); return 0; } From f3c677b997757326e1f29d33060719a6a5091950 Mon Sep 17 00:00:00 2001 From: Forrest Shi Date: Thu, 9 Dec 2010 16:14:04 +0800 Subject: [PATCH 270/300] fsldma: fix issue of slow dma Fixed fsl dma slow issue by initializing dma mode register with bandwidth control. It boosts dma performance and should works with 85xx board. Signed-off-by: Forrest Shi Signed-off-by: Li Yang Signed-off-by: Dan Williams --- drivers/dma/fsldma.c | 6 ++++-- drivers/dma/fsldma.h | 9 ++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 286c3ac6bdcc..e5e172d21692 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -50,9 +50,11 @@ static void dma_init(struct fsldma_chan *chan) * EIE - Error interrupt enable * EOSIE - End of segments interrupt enable (basic mode) * EOLNIE - End of links interrupt enable + * BWC - Bandwidth sharing among channels */ - DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_EIE - | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32); + DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_BWC + | FSL_DMA_MR_EIE | FSL_DMA_MR_EOLNIE + | FSL_DMA_MR_EOSIE, 32); break; case FSL_DMA_IP_83XX: /* Set the channel to below modes: diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h index cb4d6ff51597..ba9f403c0fbe 100644 --- a/drivers/dma/fsldma.h +++ b/drivers/dma/fsldma.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. + * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. All rights reserved. * * Author: * Zhang Wei , Jul 2007 @@ -36,6 +36,13 @@ #define FSL_DMA_MR_DAHE 0x00002000 #define FSL_DMA_MR_SAHE 0x00001000 +/* + * Bandwidth/pause control determines how many bytes a given + * channel is allowed to transfer before the DMA engine pauses + * the current channel and switches to the next channel + */ +#define FSL_DMA_MR_BWC 0x08000000 + /* Special MR definition for MPC8349 */ #define FSL_DMA_MR_EOTIE 0x00000080 #define FSL_DMA_MR_PRC_RM 0x00000800 From cd02dca56442e1504fd6bc5b96f7f1870162b266 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Mon, 13 Dec 2010 14:56:23 -0500 Subject: [PATCH 271/300] Btrfs: account for missing devices in RAID allocation profiles When we mount in RAID degraded mode without adding a new device to replace the failed one, we can end up using the wrong RAID flags for allocations. This results in strange combinations of block groups (raid1 in a raid10 filesystem) and corruptions when we try to allocate blocks from single spindle chunks on drives that are actually missing. The first device has two small 4MB chunks in it that mkfs creates and these are usually unused in a raid1 or raid10 setup. But, in -o degraded, the allocator will fall back to these because the mask of desired raid groups isn't correct. The fix here is to count the missing devices as we build up the list of devices in the system. This count is used when picking the raid level to make sure we continue using the same levels that were in place before we lost a drive. Signed-off-by: Chris Mason --- fs/btrfs/extent-tree.c | 17 +++++++++++++++-- fs/btrfs/volumes.c | 20 +++++++++++++++++++- fs/btrfs/volumes.h | 2 ++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 41133b064d72..4be231e0d2bd 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3044,7 +3044,13 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags) u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) { - u64 num_devices = root->fs_info->fs_devices->rw_devices; + /* + * we add in the count of missing devices because we want + * to make sure that any RAID levels on a degraded FS + * continue to be honored. + */ + u64 num_devices = root->fs_info->fs_devices->rw_devices + + root->fs_info->fs_devices->missing_devices; if (num_devices == 1) flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0); @@ -7891,7 +7897,14 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags) u64 stripped = BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10; - num_devices = root->fs_info->fs_devices->rw_devices; + /* + * we add in the count of missing devices because we want + * to make sure that any RAID levels on a degraded FS + * continue to be honored. + */ + num_devices = root->fs_info->fs_devices->rw_devices + + root->fs_info->fs_devices->missing_devices; + if (num_devices == 1) { stripped |= BTRFS_BLOCK_GROUP_DUP; stripped = flags & ~stripped; diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 91851b555e2e..177b73179590 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -413,12 +413,16 @@ static noinline int device_list_add(const char *path, device->fs_devices = fs_devices; fs_devices->num_devices++; - } else if (strcmp(device->name, path)) { + } else if (!device->name || strcmp(device->name, path)) { name = kstrdup(path, GFP_NOFS); if (!name) return -ENOMEM; kfree(device->name); device->name = name; + if (device->missing) { + fs_devices->missing_devices--; + device->missing = 0; + } } if (found_transid > fs_devices->latest_trans) { @@ -1238,6 +1242,9 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) device->fs_devices->num_devices--; + if (device->missing) + root->fs_info->fs_devices->missing_devices--; + next_device = list_entry(root->fs_info->fs_devices->devices.next, struct btrfs_device, dev_list); if (device->bdev == root->fs_info->sb->s_bdev) @@ -3084,7 +3091,9 @@ static struct btrfs_device *add_missing_dev(struct btrfs_root *root, device->devid = devid; device->work.func = pending_bios_fn; device->fs_devices = fs_devices; + device->missing = 1; fs_devices->num_devices++; + fs_devices->missing_devices++; spin_lock_init(&device->io_lock); INIT_LIST_HEAD(&device->dev_alloc_list); memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE); @@ -3282,6 +3291,15 @@ static int read_one_dev(struct btrfs_root *root, device = add_missing_dev(root, devid, dev_uuid); if (!device) return -ENOMEM; + } else if (!device->missing) { + /* + * this happens when a device that was properly setup + * in the device info lists suddenly goes bad. + * device->bdev is NULL, and so we have to set + * device->missing to one here + */ + root->fs_info->fs_devices->missing_devices++; + device->missing = 1; } } diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 31b0fabdd2ea..a668c0116982 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -45,6 +45,7 @@ struct btrfs_device { int barriers; int writeable; int in_fs_metadata; + int missing; spinlock_t io_lock; @@ -94,6 +95,7 @@ struct btrfs_fs_devices { u64 num_devices; u64 open_devices; u64 rw_devices; + u64 missing_devices; u64 total_rw_bytes; struct block_device *latest_bdev; From 83a50de97fe96aca82389e061862ed760ece2283 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Mon, 13 Dec 2010 15:06:46 -0500 Subject: [PATCH 272/300] Btrfs: prevent RAID level downgrades when space is low The extent allocator has code that allows us to fill allocations from any available block group, even if it doesn't match the raid level we've requested. This was put in because adding a new drive to a filesystem made with the default mkfs options actually upgrades the metadata from single spindle dup to full RAID1. But, the code also allows us to allocate from a raid0 chunk when we really want a raid1 or raid10 chunk. This can cause big trouble because mkfs creates a small (4MB) raid0 chunk for data and metadata which then goes unused for raid1/raid10 installs. The allocator will happily wander in and allocate from that chunk when things get tight, which is not correct. The fix here is to make sure that we provide duplication when the caller has asked for it. It does all the dups to be any raid level, which preserves the dup->raid1 upgrade abilities. Signed-off-by: Chris Mason --- fs/btrfs/extent-tree.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 4be231e0d2bd..7e5162e5c411 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -4943,6 +4943,25 @@ search: btrfs_get_block_group(block_group); search_start = block_group->key.objectid; + /* + * this can happen if we end up cycling through all the + * raid types, but we want to make sure we only allocate + * for the proper type. + */ + if (!block_group_bits(block_group, data)) { + u64 extra = BTRFS_BLOCK_GROUP_DUP | + BTRFS_BLOCK_GROUP_RAID1 | + BTRFS_BLOCK_GROUP_RAID10; + + /* + * if they asked for extra copies and this block group + * doesn't provide them, bail. This does allow us to + * fill raid0 from raid1. + */ + if ((data & extra) && !(block_group->flags & extra)) + goto loop; + } + have_block_group: if (unlikely(block_group->cached == BTRFS_CACHE_NO)) { u64 free_percent; @@ -8273,7 +8292,6 @@ int btrfs_read_block_groups(struct btrfs_root *root) break; if (ret != 0) goto error; - leaf = path->nodes[0]; btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); cache = kzalloc(sizeof(*cache), GFP_NOFS); From 291a73c9be15f12046a7291ec0bf7176a58d4f14 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 12 Dec 2010 21:10:42 +0100 Subject: [PATCH 273/300] ACPI / PM: Do not save/restore NVS on Sony Vaio VGN-NW130D The saving of the NVS memory area during suspend and restoring it during resume causes problems to appear on Sony Vaio VGN-NW130D, so blacklist that machine to avoid those problems. Addresses https://bugzilla.kernel.org/show_bug.cgi?id=23002 Signed-off-by: Rafael J. Wysocki Reported-and-tested-by: Adriano Signed-off-by: Len Brown --- drivers/acpi/sleep.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 721d93b3ceee..d8149424c812 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -427,6 +427,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"), }, }, + { + .callback = init_nvs_nosave, + .ident = "Sony Vaio VGN-NW130D", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"), + }, + }, {}, }; #endif /* CONFIG_SUSPEND */ From 8863ada9c47503bb93eba5e3a9ba88e6311db31f Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Wed, 1 Dec 2010 13:01:01 -0600 Subject: [PATCH 274/300] kgdboc,input: Fix regression with keyboard release key and early debugging The commit 111c182340cd22e238ab1cc6564df336c6ebd7cb (kgdboc: reset input devices (keyboards) when exiting debugger) introduced a regression in early debugging such that you get a kernel oops on continue (with the go command) if you boot a kernel with: earlyprintk=vga ekgdboc=kbd kgdbwait The restore kgdboc_restore_input() routine schedules work for the purpose of sending key release events for any keys that were in the depressed state prior to entering the kernel debugger. A simple fix to the crash is to not invoke the schedule_work() if the kernel system_state is anything other than SYSTEM_RUNNING. Signed-off-by: Jason Wessel Acked-by: Dmitry Torokhov Reviewed-by: Sergei Shtylyov --- drivers/serial/kgdboc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c index 3374618300af..25a8bc565f40 100644 --- a/drivers/serial/kgdboc.c +++ b/drivers/serial/kgdboc.c @@ -90,7 +90,8 @@ static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper); static void kgdboc_restore_input(void) { - schedule_work(&kgdboc_restore_input_work); + if (likely(system_state == SYSTEM_RUNNING)) + schedule_work(&kgdboc_restore_input_work); } static int kgdboc_register_kbd(char **cptr) From 59a609d9b59be9452f168fe228befea53d5962ff Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Mon, 13 Dec 2010 13:48:41 +0100 Subject: [PATCH 275/300] dmaengine: at_hdmac: fix buffer transfer size specification Buffer transfer size is the number of transfers to be performed in relation with the width of the _source_ interface. So in the DMA_FROM_DEVICE case, it should be the register width that should be taken into account. Signed-off-by: Nicolas Ferre Signed-off-by: Dan Williams --- drivers/dma/at_hdmac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index a0f3e6a06e06..ea0ee81cff53 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -722,7 +722,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, desc->lli.daddr = mem; desc->lli.ctrla = ctrla | ATC_DST_WIDTH(mem_width) - | len >> mem_width; + | len >> reg_width; desc->lli.ctrlb = ctrlb; if (!first) { From 21b6e4c7106b2d68a6710506d8706608272fd78b Mon Sep 17 00:00:00 2001 From: Carmelo AMOROSO Date: Mon, 13 Dec 2010 10:20:26 +0000 Subject: [PATCH 276/300] sh: wire up accept4 syscall (non-multiplexed path) Signed-off-by: Carmelo Amoroso Signed-off-by: Paul Mundt --- arch/sh/include/asm/unistd_32.h | 3 ++- arch/sh/kernel/syscalls_32.S | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h index 903cd618eb74..d6741fca89a4 100644 --- a/arch/sh/include/asm/unistd_32.h +++ b/arch/sh/include/asm/unistd_32.h @@ -368,8 +368,9 @@ #define __NR_sendmsg 355 #define __NR_recvmsg 356 #define __NR_recvmmsg 357 +#define __NR_accept4 358 -#define NR_syscalls 358 +#define NR_syscalls 359 #ifdef __KERNEL__ diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index e872e81add8a..6fc347ebe59d 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S @@ -375,3 +375,4 @@ ENTRY(sys_call_table) .long sys_sendmsg /* 355 */ .long sys_recvmsg .long sys_recvmmsg + .long sys_accept4 From e504b84805c574cf18d705c610c9e4a8f6e61017 Mon Sep 17 00:00:00 2001 From: Andrew Kephart Date: Mon, 13 Dec 2010 09:46:34 -0600 Subject: [PATCH 277/300] fbdev: Fix fb_find_nearest_mode refresh comparison Refresh rate nearness is not calculated or reset when nearest resolution changes. This patch resets the refresh rate differential measurement whenever a new nearest resolution is discovered. This fixes two error cases; first, wherein the first mode's refresh rate differential is never calculated and second, when the closest refresh rate from a previous nearest resolution is erroneously preserved. Signed-off-by: Andrew Kephart Signed-off-by: Paul Mundt --- drivers/video/modedb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 0a4dbdc1693a..de450c1fb869 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c @@ -855,6 +855,7 @@ const struct fb_videomode *fb_find_nearest_mode(const struct fb_videomode *mode, abs(cmode->yres - mode->yres); if (diff > d) { diff = d; + diff_refresh = abs(cmode->refresh - mode->refresh); best = cmode; } else if (diff == d) { d = abs(cmode->refresh - mode->refresh); From 3e6cd7a4b6a04cf354a18c9d2e7ecec8fa1772fb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 10 Dec 2010 17:20:23 +0100 Subject: [PATCH 278/300] MAINTAINERS: Add workqueue entry Signed-off-by: Tejun Heo --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index b3be8b3d0437..462e39709c03 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6585,6 +6585,15 @@ F: include/linux/mfd/wm8400* F: include/sound/wm????.h F: sound/soc/codecs/wm* +WORKQUEUE +M: Tejun Heo +L: linux-kernel@vger.kernel.org +T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git +S: Maintained +F: include/linux/workqueue.h +F: kernel/workqueue.c +F: Documentation/workqueue.txt + X.25 NETWORK LAYER M: Andrew Hendry L: linux-x25@vger.kernel.org From 2d64672ed38721b7a3815009d79bfb90a1f34a17 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 3 Dec 2010 23:12:33 -0500 Subject: [PATCH 279/300] workqueue: It is likely that WORKER_NOT_RUNNING is true Running the annotate branch profiler on three boxes, including my main box that runs firefox, evolution, xchat, and is part of the distcc farm, showed this with the likelys in the workqueue code: correct incorrect % Function File Line ------- --------- - -------- ---- ---- 96 996253 99 wq_worker_sleeping workqueue.c 703 96 996247 99 wq_worker_waking_up workqueue.c 677 The likely()s in this case were assuming that WORKER_NOT_RUNNING will most likely be false. But this is not the case. The reason is (and shown by adding trace_printks and testing it) that most of the time WORKER_PREP is set. In worker_thread() we have: worker_clr_flags(worker, WORKER_PREP); [ do work stuff ] worker_set_flags(worker, WORKER_PREP, false); (that 'false' means not to wake up an idle worker) The wq_worker_sleeping() is called from schedule when a worker thread is putting itself to sleep. Which happens most of the time outside of that [ do work stuff ]. The wq_worker_waking_up is called by the wakeup worker code, which is also callod outside that [ do work stuff ]. Thus, the likely and unlikely used by those two functions are actually backwards. Remove the annotation and let gcc figure it out. Acked-by: Tejun Heo Signed-off-by: Steven Rostedt Signed-off-by: Tejun Heo --- kernel/workqueue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index ca017ce8bc6b..e785b0f2aea5 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -661,7 +661,7 @@ void wq_worker_waking_up(struct task_struct *task, unsigned int cpu) { struct worker *worker = kthread_data(task); - if (likely(!(worker->flags & WORKER_NOT_RUNNING))) + if (!(worker->flags & WORKER_NOT_RUNNING)) atomic_inc(get_gcwq_nr_running(cpu)); } @@ -687,7 +687,7 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task, struct global_cwq *gcwq = get_gcwq(cpu); atomic_t *nr_running = get_gcwq_nr_running(cpu); - if (unlikely(worker->flags & WORKER_NOT_RUNNING)) + if (worker->flags & WORKER_NOT_RUNNING) return NULL; /* this can only happen on the local cpu */ From 1449032be17abb69116dbc393f67ceb8bd034f92 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 14 Dec 2010 15:27:50 -0500 Subject: [PATCH 280/300] ext4: Turn off multiple page-io submission by default Jon Nelson has found a test case which causes postgresql to fail with the error: psql:t.sql:4: ERROR: invalid page header in block 38269 of relation base/16384/16581 Under memory pressure, it looks like part of a file can end up getting replaced by zero's. Until we can figure out the cause, we'll roll back the change and use block_write_full_page() instead of ext4_bio_write_page(). The new, more efficient writing function can be used via the mount option mblk_io_submit, so we can test and fix the new page I/O code. To reproduce the problem, install postgres 8.4 or 9.0, and pin enough memory such that the system just at the end of triggering writeback before running the following sql script: begin; create temporary table foo as select x as a, ARRAY[x] as b FROM generate_series(1, 10000000 ) AS x; create index foo_a_idx on foo (a); create index foo_b_idx on foo USING GIN (b); rollback; If the temporary table is created on a hard drive partition which is encrypted using dm_crypt, then under memory pressure, approximately 30-40% of the time, pgsql will issue the above failure. This patch should fix this problem, and the problem will come back if the file system is mounted with the mblk_io_submit mount option. Reported-by: Jon Nelson Signed-off-by: "Theodore Ts'o" --- fs/ext4/ext4.h | 1 + fs/ext4/inode.c | 5 ++++- fs/ext4/super.c | 14 ++++++++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 6a5edea2d70b..94ce3d7a1c4b 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -910,6 +910,7 @@ struct ext4_inode_info { #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ +#define EXT4_MOUNT_MBLK_IO_SUBMIT 0x4000000 /* multi-block io submits */ #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index bdbe69902207..e659597b690b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2125,9 +2125,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, */ if (unlikely(journal_data && PageChecked(page))) err = __ext4_journalled_writepage(page, len); - else + else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT)) err = ext4_bio_write_page(&io_submit, page, len, mpd->wbc); + else + err = block_write_full_page(page, + noalloc_get_block_write, mpd->wbc); if (!err) mpd->pages_written++; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e32195d6aac3..fb15c9c0be74 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1026,6 +1026,8 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) !(def_mount_opts & EXT4_DEFM_NODELALLOC)) seq_puts(seq, ",nodelalloc"); + if (test_opt(sb, MBLK_IO_SUBMIT)) + seq_puts(seq, ",mblk_io_submit"); if (sbi->s_stripe) seq_printf(seq, ",stripe=%lu", sbi->s_stripe); /* @@ -1239,8 +1241,8 @@ enum { Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version, - Opt_stripe, Opt_delalloc, Opt_nodelalloc, - Opt_block_validity, Opt_noblock_validity, + Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit, + Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, Opt_inode_readahead_blks, Opt_journal_ioprio, Opt_dioread_nolock, Opt_dioread_lock, Opt_discard, Opt_nodiscard, @@ -1304,6 +1306,8 @@ static const match_table_t tokens = { {Opt_resize, "resize"}, {Opt_delalloc, "delalloc"}, {Opt_nodelalloc, "nodelalloc"}, + {Opt_mblk_io_submit, "mblk_io_submit"}, + {Opt_nomblk_io_submit, "nomblk_io_submit"}, {Opt_block_validity, "block_validity"}, {Opt_noblock_validity, "noblock_validity"}, {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, @@ -1725,6 +1729,12 @@ set_qf_format: case Opt_nodelalloc: clear_opt(sbi->s_mount_opt, DELALLOC); break; + case Opt_mblk_io_submit: + set_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT); + break; + case Opt_nomblk_io_submit: + clear_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT); + break; case Opt_stripe: if (match_int(&args[0], &option)) return 0; From d6db46675dba21203378b6993068ec04bb53389c Mon Sep 17 00:00:00 2001 From: Jiandong Zheng Date: Tue, 14 Dec 2010 21:55:49 +0000 Subject: [PATCH 281/300] Change bcmring Maintainer list. I am Jiandong Zheng working on BCMRING in Broadcom Canada Ltd. I am replacing Leo Chen (leochen@broadcom.com) as "ARM/BCMRING ARM ARCHITECTURE" and "ARM/BCMRING MTD NAND DRIVER" maintainer from Broadcom as he is no longer the maintainer of these components. Signed-off-by: Jiandong Zheng Acked-by: Scott Branden Signed-off-by: Russell King --- MAINTAINERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1a1c27b9c557..5202dc3ad5c4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -559,14 +559,14 @@ W: http://maxim.org.za/at91_26.html S: Maintained ARM/BCMRING ARM ARCHITECTURE -M: Leo Chen +M: Jiandong Zheng M: Scott Branden L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained F: arch/arm/mach-bcmring ARM/BCMRING MTD NAND DRIVER -M: Leo Chen +M: Jiandong Zheng M: Scott Branden L: linux-mtd@lists.infradead.org S: Maintained From 6e6fc998b8c127fe06b9350a1f16e41bfe4f109d Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Mon, 13 Dec 2010 21:53:53 +0100 Subject: [PATCH 282/300] ARM: 6533/1: Thumb-2: Make CONFIG_THUMB2_KERNEL depend on !CPU_V6 This makes sense, because Thumb-2 code can't execute on plain ARMv6 processors. This will avoid accidentally configuring a broken kernel where the config otherwise would allow multiple architecture versions to coexist in the same kernel. Not adding !CPU_V5 etc., because the chance of anyone trying to put v5 and v7 in the same kernel is low, and I'm not aware of any mach which can do this. These could be added later if it matters. Note that the rules may need to be refined if support for the ARM1156J(F)-S processor is later added to the kernel, since this processor supports the rare ARMv6T2 extensions, which add support for Thumb-2 and a few other ARMv7 features. Signed-off-by: Dave Martin Acked-by: Catalin Marinas Acked-by: Nicolas Pitre Acked-by: Santosh Shilimkar Signed-off-by: Russell King --- arch/arm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f1d9297b1050..bf1f8dba02f3 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1311,7 +1311,7 @@ config HZ config THUMB2_KERNEL bool "Compile the kernel in Thumb-2 mode" - depends on CPU_V7 && EXPERIMENTAL + depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL select AEABI select ARM_ASM_UNIFIED help From 593c252a731389ffdd00d4cb2d20192c47aa18c1 Mon Sep 17 00:00:00 2001 From: Dave Martin Date: Mon, 13 Dec 2010 21:56:03 +0100 Subject: [PATCH 283/300] ARM: 6534/1: Make CONFIG_FPE_NWFPE depend on !CONFIG_THUMB2_KERNEL Because the nwfpe support is unlikely to be used on new platforms and requires CONFIG_OABI_COMPAT, which is not generally used with ARMv7+, we shouldn't expect to build nwfpe support into a Thumb-2 kernel. At present, nwfpe contains assembly code which isn't Thumb-2 compatible, and for now it doesn't appear useful to port this code. All ARMv7-A/R platforms necessarily have VFPv3 hardware floating- point natively, making emulation unnecessary. Signed-off-by: Dave Martin Acked-by: Catalin Marinas Acked-by: Nicolas Pitre Acked-by: Santosh Shilimkar Signed-off-by: Russell King --- arch/arm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index bf1f8dba02f3..d56d21c0573b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1759,7 +1759,7 @@ comment "At least one emulation must be selected" config FPE_NWFPE bool "NWFPE math emulation" - depends on !AEABI || OABI_COMPAT + depends on (!AEABI || OABI_COMPAT) && !THUMB2_KERNEL ---help--- Say Y to include the NWFPE floating point emulator in the kernel. This is necessary to run most binaries. Linux does not currently From 85b093bcc5322baa811a03ec73de0909c157f181 Mon Sep 17 00:00:00 2001 From: Valentine Barshak Date: Tue, 14 Dec 2010 00:03:16 +0100 Subject: [PATCH 284/300] ARM: 6535/1: V6 MPCore v6_dma_inv_range and v6_dma_flush_range RWFO fix Cache ownership must be acquired by reading/writing data from the cache line to make cache operation have the desired effect on the SMP MPCore CPU. However, the ownership is never acquired in the v6_dma_inv_range function when cleaning the first line and flushing the last one, in case the address is not aligned to D_CACHE_LINE_SIZE boundary. Fix this by reading/writing data if needed, before performing cache operations. While at it, fix v6_dma_flush_range to prevent RWFO outside the buffer. Cc: stable@kernel.org Signed-off-by: Valentine Barshak Signed-off-by: George G. Davis Acked-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/cache-v6.S | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 99fa688dfadd..c96fa1b3f49f 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S @@ -203,6 +203,10 @@ ENTRY(v6_flush_kern_dcache_area) * - end - virtual end address of region */ v6_dma_inv_range: +#ifdef CONFIG_DMA_CACHE_RWFO + ldrb r2, [r0] @ read for ownership + strb r2, [r0] @ write for ownership +#endif tst r0, #D_CACHE_LINE_SIZE - 1 bic r0, r0, #D_CACHE_LINE_SIZE - 1 #ifdef HARVARD_CACHE @@ -211,6 +215,10 @@ v6_dma_inv_range: mcrne p15, 0, r0, c7, c11, 1 @ clean unified line #endif tst r1, #D_CACHE_LINE_SIZE - 1 +#ifdef CONFIG_DMA_CACHE_RWFO + ldrneb r2, [r1, #-1] @ read for ownership + strneb r2, [r1, #-1] @ write for ownership +#endif bic r1, r1, #D_CACHE_LINE_SIZE - 1 #ifdef HARVARD_CACHE mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line @@ -218,10 +226,6 @@ v6_dma_inv_range: mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line #endif 1: -#ifdef CONFIG_DMA_CACHE_RWFO - ldr r2, [r0] @ read for ownership - str r2, [r0] @ write for ownership -#endif #ifdef HARVARD_CACHE mcr p15, 0, r0, c7, c6, 1 @ invalidate D line #else @@ -229,6 +233,10 @@ v6_dma_inv_range: #endif add r0, r0, #D_CACHE_LINE_SIZE cmp r0, r1 +#ifdef CONFIG_DMA_CACHE_RWFO + ldrlo r2, [r0] @ read for ownership + strlo r2, [r0] @ write for ownership +#endif blo 1b mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer @@ -263,12 +271,12 @@ v6_dma_clean_range: * - end - virtual end address of region */ ENTRY(v6_dma_flush_range) +#ifdef CONFIG_DMA_CACHE_RWFO + ldrb r2, [r0] @ read for ownership + strb r2, [r0] @ write for ownership +#endif bic r0, r0, #D_CACHE_LINE_SIZE - 1 1: -#ifdef CONFIG_DMA_CACHE_RWFO - ldr r2, [r0] @ read for ownership - str r2, [r0] @ write for ownership -#endif #ifdef HARVARD_CACHE mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line #else @@ -276,6 +284,10 @@ ENTRY(v6_dma_flush_range) #endif add r0, r0, #D_CACHE_LINE_SIZE cmp r0, r1 +#ifdef CONFIG_DMA_CACHE_RWFO + ldrlob r2, [r0] @ read for ownership + strlob r2, [r0] @ write for ownership +#endif blo 1b mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer From 6d5c3aa84b3e431f2d0fc39c73c867d1a4dd8cff Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 14 Dec 2010 21:45:31 -0500 Subject: [PATCH 285/300] ext4: fix typo which broke '..' detection in ext4_find_entry() There should be a check for the NUL character instead of '0'. Fortunately the only thing that cares about this is NFS serving, which is why we didn't notice this in the merge window testing. Reported-by: Phil Carmody Signed-off-by: Aaro Koskinen Signed-off-by: "Theodore Ts'o" --- fs/ext4/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 92203b8a099f..dc40e75cba88 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -872,7 +872,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir, if (namelen > EXT4_NAME_LEN) return NULL; if ((namelen <= 2) && (name[0] == '.') && - (name[1] == '.' || name[1] == '0')) { + (name[1] == '.' || name[1] == '\0')) { /* * "." or ".." will only be in the first block * NFS may look up ".."; "." should be handled by the VFS From 54efdfeb49f03adfd0196935335890469ed314b9 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 14 Dec 2010 15:29:08 +0000 Subject: [PATCH 286/300] i2c_intel_mid: Fix slash in sysfs name This gets caught by the new sanity check code. Instead of the slash use a different symbol. This was originally found by Major Lee who proposed a rather more complex patch which changed the name according to the chip type. On the basis that we are in a late -rc and making Linus grumpy isn't always a good idea (however fun) this is a simple alternative. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/i2c/busses/i2c-intel-mid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-intel-mid.c b/drivers/i2c/busses/i2c-intel-mid.c index 80f70d3a744d..c71492782bbd 100644 --- a/drivers/i2c/busses/i2c-intel-mid.c +++ b/drivers/i2c/busses/i2c-intel-mid.c @@ -999,7 +999,7 @@ static int __devinit intel_mid_i2c_probe(struct pci_dev *dev, /* Initialize struct members */ snprintf(mrst->adap.name, sizeof(mrst->adap.name), - "MRST/Medfield I2C at %lx", start); + "Intel MID I2C at %lx", start); mrst->adap.owner = THIS_MODULE; mrst->adap.algo = &intel_mid_i2c_algorithm; mrst->adap.dev.parent = &dev->dev; From 3d0b6087f3f2c88caef25e1455ff8db0816d4e11 Mon Sep 17 00:00:00 2001 From: Major Lee Date: Fri, 10 Dec 2010 10:13:49 +0000 Subject: [PATCH 287/300] dw_spi: Fix missing final read in some polling situations There is a possibility that the last word of a transaction will be lost if data is not ready. Re-read in poll_transfer() to solve this issue when poll_mode is enabled. Verified on SPI touch screen device. Signed-off-by: Major Lee Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/spi/dw_spi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c index 90439314cf67..0838c79861e4 100644 --- a/drivers/spi/dw_spi.c +++ b/drivers/spi/dw_spi.c @@ -413,6 +413,11 @@ static void poll_transfer(struct dw_spi *dws) { while (dws->write(dws)) dws->read(dws); + /* + * There is a possibility that the last word of a transaction + * will be lost if data is not ready. Re-read to solve this issue. + */ + dws->read(dws); transfer_complete(dws); } From 52f6c5ad430e41736133acac179607b224eaaa11 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 15 Dec 2010 17:58:57 +0800 Subject: [PATCH 288/300] crypto: ghash-intel - ghash-clmulni-intel_glue needs err.h Add missing header file: arch/x86/crypto/ghash-clmulni-intel_glue.c:256: error: implicit declaration of function 'IS_ERR' arch/x86/crypto/ghash-clmulni-intel_glue.c:257: error: implicit declaration of function 'PTR_ERR' Signed-off-by: Randy Dunlap Signed-off-by: Herbert Xu --- arch/x86/crypto/ghash-clmulni-intel_glue.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c index cbcc8d8ea93a..7a6e68e4f748 100644 --- a/arch/x86/crypto/ghash-clmulni-intel_glue.c +++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c @@ -10,6 +10,7 @@ * by the Free Software Foundation. */ +#include #include #include #include From 462e635e5b73ba9a4c03913b77138cd57ce4b050 Mon Sep 17 00:00:00 2001 From: Tavis Ormandy Date: Thu, 9 Dec 2010 15:29:42 +0100 Subject: [PATCH 289/300] install_special_mapping skips security_file_mmap check. The install_special_mapping routine (used, for example, to setup the vdso) skips the security check before insert_vm_struct, allowing a local attacker to bypass the mmap_min_addr security restriction by limiting the available pages for special mappings. bprm_mm_init() also skips the check, and although I don't think this can be used to bypass any restrictions, I don't see any reason not to have the security check. $ uname -m x86_64 $ cat /proc/sys/vm/mmap_min_addr 65536 $ cat install_special_mapping.s section .bss resb BSS_SIZE section .text global _start _start: mov eax, __NR_pause int 0x80 $ nasm -D__NR_pause=29 -DBSS_SIZE=0xfffed000 -f elf -o install_special_mapping.o install_special_mapping.s $ ld -m elf_i386 -Ttext=0x10000 -Tbss=0x11000 -o install_special_mapping install_special_mapping.o $ ./install_special_mapping & [1] 14303 $ cat /proc/14303/maps 0000f000-00010000 r-xp 00000000 00:00 0 [vdso] 00010000-00011000 r-xp 00001000 00:19 2453665 /home/taviso/install_special_mapping 00011000-ffffe000 rwxp 00000000 00:00 0 [stack] It's worth noting that Red Hat are shipping with mmap_min_addr set to 4096. Signed-off-by: Tavis Ormandy Acked-by: Kees Cook Acked-by: Robert Swiecki [ Changed to not drop the error code - akpm ] Reviewed-by: James Morris Signed-off-by: Linus Torvalds --- fs/exec.c | 5 +++++ mm/mmap.c | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index d68c378a3137..c62efcb959c7 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -275,6 +275,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm) vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP; vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); INIT_LIST_HEAD(&vma->anon_vma_chain); + + err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1); + if (err) + goto err; + err = insert_vm_struct(mm, vma); if (err) goto err; diff --git a/mm/mmap.c b/mm/mmap.c index b179abb1474a..50a4aa0255a0 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2462,6 +2462,7 @@ int install_special_mapping(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long vm_flags, struct page **pages) { + int ret; struct vm_area_struct *vma; vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); @@ -2479,16 +2480,23 @@ int install_special_mapping(struct mm_struct *mm, vma->vm_ops = &special_mapping_vmops; vma->vm_private_data = pages; - if (unlikely(insert_vm_struct(mm, vma))) { - kmem_cache_free(vm_area_cachep, vma); - return -ENOMEM; - } + ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1); + if (ret) + goto out; + + ret = insert_vm_struct(mm, vma); + if (ret) + goto out; mm->total_vm += len >> PAGE_SHIFT; perf_event_mmap(vma); return 0; + +out: + kmem_cache_free(vm_area_cachep, vma); + return ret; } static DEFINE_MUTEX(mm_all_locks_mutex); From 6c965ff5e7ca844494f1dcf0ec0440146db01294 Mon Sep 17 00:00:00 2001 From: Daniel Walker Date: Thu, 9 Dec 2010 15:45:27 -0800 Subject: [PATCH 290/300] MAINTAINERS: update MSM git tree The MSM main git tree has changed over to this new address. Signed-off-by: Daniel Walker Signed-off-by: Linus Torvalds --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 0b0d2ba69a8e..6a588873cf8d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -815,7 +815,7 @@ F: drivers/mmc/host/msm_sdcc.c F: drivers/mmc/host/msm_sdcc.h F: drivers/serial/msm_serial.h F: drivers/serial/msm_serial.c -T: git git://codeaurora.org/quic/kernel/dwalker/linux-msm.git +T: git git://codeaurora.org/quic/kernel/davidb/linux-msm.git S: Maintained ARM/TOSA MACHINE SUPPORT From 667c78afaec0ac500908e191e8f236e9578d7b1f Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 8 Dec 2010 12:39:12 -0800 Subject: [PATCH 291/300] xen: Provide a variant of __RING_SIZE() that is an integer constant expression Without this, gcc 4.5 won't compile xen-netfront and xen-blkfront, where this is being used to specify array sizes. Signed-off-by: Jan Beulich Signed-off-by: Jeremy Fitzhardinge Cc: Jens Axboe Cc: David Miller Cc: Stable Kernel Signed-off-by: Linus Torvalds --- drivers/block/xen-blkfront.c | 2 +- drivers/net/xen-netfront.c | 4 ++-- include/xen/interface/io/ring.h | 11 +++++++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 4f9e22f29138..657873e4328d 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -72,7 +72,7 @@ struct blk_shadow { static DEFINE_MUTEX(blkfront_mutex); static const struct block_device_operations xlvbd_block_fops; -#define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE) +#define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE) /* * We have one of these per vbd, whether ide, scsi or 'other'. They diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 458bb57914a3..cdbeec9f83ea 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -66,8 +66,8 @@ struct netfront_cb { #define GRANT_INVALID_REF 0 -#define NET_TX_RING_SIZE __RING_SIZE((struct xen_netif_tx_sring *)0, PAGE_SIZE) -#define NET_RX_RING_SIZE __RING_SIZE((struct xen_netif_rx_sring *)0, PAGE_SIZE) +#define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE) +#define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE) #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) struct netfront_info { diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h index e8cbf431c8cc..75271b9a8f61 100644 --- a/include/xen/interface/io/ring.h +++ b/include/xen/interface/io/ring.h @@ -24,8 +24,15 @@ typedef unsigned int RING_IDX; * A ring contains as many entries as will fit, rounded down to the nearest * power of two (so we can mask with (size-1) to loop around). */ -#define __RING_SIZE(_s, _sz) \ - (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0]))) +#define __CONST_RING_SIZE(_s, _sz) \ + (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \ + sizeof(((struct _s##_sring *)0)->ring[0]))) + +/* + * The same for passing in an actual pointer instead of a name tag. + */ +#define __RING_SIZE(_s, _sz) \ + (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0]))) /* * Macros to make the correct C datatypes for a new kind of ring. From b0c3844d8af6b9f3f18f31e1b0502fbefa2166be Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 15 Dec 2010 17:24:48 -0800 Subject: [PATCH 292/300] Linux 2.6.37-rc6 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3d94974542ea..5aa44278d956 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 37 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc6 NAME = Flesh-Eating Bats with Fangs # *DOCUMENTATION* From 6c3bc4eb5608665b7330b3d2044fca976cbd1a50 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 17 Dec 2010 15:13:44 -0800 Subject: [PATCH 293/300] arm: omap: rename board-rx51-sdram.c to sdram-nokia.c Rename the file and functions so that it can be reused by future Nokia boards. Based on patches by Juha Keski-Saari. Signed-off-by: Aaro Koskinen Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/board-rx51.c | 4 +-- .../{board-rx51-sdram.c => sdram-nokia.c} | 34 +++++++++---------- 3 files changed, 20 insertions(+), 20 deletions(-) rename arch/arm/mach-omap2/{board-rx51-sdram.c => sdram-nokia.c} (85%) diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 60e51bcf53bd..e72ccf79b791 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -140,7 +140,7 @@ obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \ board-flash.o obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \ - board-rx51-sdram.o \ + sdram-nokia.o \ board-rx51-peripherals.o \ board-rx51-video.o \ hsmmc.o diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c index 36f2cf4efd57..904b83a62be7 100644 --- a/arch/arm/mach-omap2/board-rx51.c +++ b/arch/arm/mach-omap2/board-rx51.c @@ -35,7 +35,7 @@ #define RX51_GPIO_SLEEP_IND 162 -struct omap_sdrc_params *rx51_get_sdram_timings(void); +struct omap_sdrc_params *nokia_get_sdram_timings(void); extern void rx51_video_mem_init(void); static struct gpio_led gpio_leds[] = { @@ -105,7 +105,7 @@ static void __init rx51_init_irq(void) omap_board_config = rx51_config; omap_board_config_size = ARRAY_SIZE(rx51_config); omap3_pm_init_cpuidle(rx51_cpuidle_params); - sdrc_params = rx51_get_sdram_timings(); + sdrc_params = nokia_get_sdram_timings(); omap2_init_common_hw(sdrc_params, sdrc_params); omap_init_irq(); omap_gpio_init(); diff --git a/arch/arm/mach-omap2/board-rx51-sdram.c b/arch/arm/mach-omap2/sdram-nokia.c similarity index 85% rename from arch/arm/mach-omap2/board-rx51-sdram.c rename to arch/arm/mach-omap2/sdram-nokia.c index a43b2c5c838b..690202b996c1 100644 --- a/arch/arm/mach-omap2/board-rx51-sdram.c +++ b/arch/arm/mach-omap2/sdram-nokia.c @@ -1,7 +1,7 @@ /* - * SDRC register values for RX51 + * SDRC register values for Nokia boards * - * Copyright (C) 2008 Nokia Corporation + * Copyright (C) 2008, 2010 Nokia Corporation * * Lauri Leukkunen * @@ -43,9 +43,9 @@ struct sdram_timings { u32 tWTR; }; -static struct omap_sdrc_params rx51_sdrc_params[4]; +static struct omap_sdrc_params nokia_sdrc_params[4]; -static const struct sdram_timings rx51_timings[] = { +static const struct sdram_timings memory_timings[] = { { .casl = 3, .tDAL = 33000, @@ -110,12 +110,12 @@ static int set_sdrc_timing_regval(u32 *regval, int st_bit, int end_bit, #ifdef DEBUG #define SDRC_SET_ONE(reg, st, end, field, rate) \ if (set_sdrc_timing_regval((reg), (st), (end), \ - rx51_timings->field, (rate), #field) < 0) \ + memory_timings->field, (rate), #field) < 0) \ err = -1; #else #define SDRC_SET_ONE(reg, st, end, field, rate) \ if (set_sdrc_timing_regval((reg), (st), (end), \ - rx51_timings->field) < 0) \ + memory_timings->field) < 0) \ err = -1; #endif @@ -148,14 +148,14 @@ static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit, #ifdef DEBUG #define SDRC_SET_ONE_PS(reg, st, end, field, rate) \ if (set_sdrc_timing_regval_ps((reg), (st), (end), \ - rx51_timings->field, \ + memory_timings->field, \ (rate), #field) < 0) \ err = -1; #else #define SDRC_SET_ONE_PS(reg, st, end, field, rate) \ if (set_sdrc_timing_regval_ps((reg), (st), (end), \ - rx51_timings->field, (rate)) < 0) \ + memory_timings->field, (rate)) < 0) \ err = -1; #endif @@ -184,7 +184,7 @@ static int sdrc_timings(int id, long rate) SDRC_SET_ONE(&actim_ctrlb, 16, 17, tWTR, l3_rate); ticks_per_ms = l3_rate; - rfr = rx51_timings[0].tREF * ticks_per_ms / 1000000; + rfr = memory_timings[0].tREF * ticks_per_ms / 1000000; if (rfr > 65535 + 50) rfr = 65535; else @@ -197,18 +197,18 @@ static int sdrc_timings(int id, long rate) l = rfr << 8; rfr_ctrl = l | 0x1; /* autorefresh, reload counter with 1xARCV */ - rx51_sdrc_params[id].rate = rate; - rx51_sdrc_params[id].actim_ctrla = actim_ctrla; - rx51_sdrc_params[id].actim_ctrlb = actim_ctrlb; - rx51_sdrc_params[id].rfr_ctrl = rfr_ctrl; - rx51_sdrc_params[id].mr = 0x32; + nokia_sdrc_params[id].rate = rate; + nokia_sdrc_params[id].actim_ctrla = actim_ctrla; + nokia_sdrc_params[id].actim_ctrlb = actim_ctrlb; + nokia_sdrc_params[id].rfr_ctrl = rfr_ctrl; + nokia_sdrc_params[id].mr = 0x32; - rx51_sdrc_params[id + 1].rate = 0; + nokia_sdrc_params[id + 1].rate = 0; return err; } -struct omap_sdrc_params *rx51_get_sdram_timings(void) +struct omap_sdrc_params *nokia_get_sdram_timings(void) { int err; @@ -216,6 +216,6 @@ struct omap_sdrc_params *rx51_get_sdram_timings(void) err |= sdrc_timings(1, 83000000); err |= sdrc_timings(2, 166000000); - return &rx51_sdrc_params[0]; + return &nokia_sdrc_params[0]; } From fcd8d84633902fd1717d80f36a38b8a4305ca3d4 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 17 Dec 2010 15:13:44 -0800 Subject: [PATCH 294/300] arm: omap: add sdram-nokia.h Add a header file for Nokia SDRAM functions. Based on patches by Juha Keski-Saari. Signed-off-by: Aaro Koskinen Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-rx51.c | 2 +- arch/arm/mach-omap2/sdram-nokia.c | 1 + arch/arm/mach-omap2/sdram-nokia.h | 12 ++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-omap2/sdram-nokia.h diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c index 904b83a62be7..215ea0efed89 100644 --- a/arch/arm/mach-omap2/board-rx51.c +++ b/arch/arm/mach-omap2/board-rx51.c @@ -32,10 +32,10 @@ #include "mux.h" #include "pm.h" +#include "sdram-nokia.h" #define RX51_GPIO_SLEEP_IND 162 -struct omap_sdrc_params *nokia_get_sdram_timings(void); extern void rx51_video_mem_init(void); static struct gpio_led gpio_leds[] = { diff --git a/arch/arm/mach-omap2/sdram-nokia.c b/arch/arm/mach-omap2/sdram-nokia.c index 690202b996c1..261efc8a533e 100644 --- a/arch/arm/mach-omap2/sdram-nokia.c +++ b/arch/arm/mach-omap2/sdram-nokia.c @@ -22,6 +22,7 @@ #include #include +#include "sdram-nokia.h" /* In picoseconds, except for tREF (ns), tXP, tCKE, tWTR (clks) */ struct sdram_timings { diff --git a/arch/arm/mach-omap2/sdram-nokia.h b/arch/arm/mach-omap2/sdram-nokia.h new file mode 100644 index 000000000000..ee63da5f8df0 --- /dev/null +++ b/arch/arm/mach-omap2/sdram-nokia.h @@ -0,0 +1,12 @@ +/* + * SDRC register values for Nokia boards + * + * Copyright (C) 2010 Nokia + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +struct omap_sdrc_params *nokia_get_sdram_timings(void); + From fbd208e9772005c193459d1a0575c0787ad52f69 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 17 Dec 2010 15:13:45 -0800 Subject: [PATCH 295/300] arm: omap: sdram-nokia: prepare for new memory timings Rename the current timings to indicate they're for 166 MHz. Based on patches by Eduardo Valentin and Juha Keski-Saari. Signed-off-by: Aaro Koskinen Cc: Eduardo Valentin Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/sdram-nokia.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/sdram-nokia.c b/arch/arm/mach-omap2/sdram-nokia.c index 261efc8a533e..97d16732c54d 100644 --- a/arch/arm/mach-omap2/sdram-nokia.c +++ b/arch/arm/mach-omap2/sdram-nokia.c @@ -46,7 +46,7 @@ struct sdram_timings { static struct omap_sdrc_params nokia_sdrc_params[4]; -static const struct sdram_timings memory_timings[] = { +static const struct sdram_timings nokia_166mhz_timings[] = { { .casl = 3, .tDAL = 33000, @@ -160,7 +160,8 @@ static int set_sdrc_timing_regval_ps(u32 *regval, int st_bit, int end_bit, err = -1; #endif -static int sdrc_timings(int id, long rate) +static int sdrc_timings(int id, long rate, + const struct sdram_timings *memory_timings) { u32 ticks_per_ms; u32 rfr, l; @@ -213,9 +214,9 @@ struct omap_sdrc_params *nokia_get_sdram_timings(void) { int err; - err = sdrc_timings(0, 41500000); - err |= sdrc_timings(1, 83000000); - err |= sdrc_timings(2, 166000000); + err = sdrc_timings(0, 41500000, nokia_166mhz_timings); + err |= sdrc_timings(1, 83000000, nokia_166mhz_timings); + err |= sdrc_timings(2, 166000000, nokia_166mhz_timings); return &nokia_sdrc_params[0]; } From e5f5b5422d064b7a393e39332da31af68e975f91 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 17 Dec 2010 15:13:45 -0800 Subject: [PATCH 296/300] arm: omap: sdram-nokia: use array to list timings Use an array to make it easier to add new values. Signed-off-by: Aaro Koskinen Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/sdram-nokia.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/sdram-nokia.c b/arch/arm/mach-omap2/sdram-nokia.c index 97d16732c54d..1171451ef7f2 100644 --- a/arch/arm/mach-omap2/sdram-nokia.c +++ b/arch/arm/mach-omap2/sdram-nokia.c @@ -44,8 +44,6 @@ struct sdram_timings { u32 tWTR; }; -static struct omap_sdrc_params nokia_sdrc_params[4]; - static const struct sdram_timings nokia_166mhz_timings[] = { { .casl = 3, @@ -67,6 +65,16 @@ static const struct sdram_timings nokia_166mhz_timings[] = { }, }; +static const struct { + long rate; + struct sdram_timings const *data; +} nokia_timings[] = { + { 41500000, nokia_166mhz_timings }, + { 83000000, nokia_166mhz_timings }, + { 166000000, nokia_166mhz_timings }, +}; +static struct omap_sdrc_params nokia_sdrc_params[ARRAY_SIZE(nokia_timings) + 1]; + static unsigned long sdrc_get_fclk_period(long rate) { /* In picoseconds */ @@ -212,11 +220,12 @@ static int sdrc_timings(int id, long rate, struct omap_sdrc_params *nokia_get_sdram_timings(void) { - int err; + int err = 0; + int i; - err = sdrc_timings(0, 41500000, nokia_166mhz_timings); - err |= sdrc_timings(1, 83000000, nokia_166mhz_timings); - err |= sdrc_timings(2, 166000000, nokia_166mhz_timings); + for (i = 0; i < ARRAY_SIZE(nokia_timings); i++) + err |= sdrc_timings(i, nokia_timings[i].rate, + nokia_timings[i].data); return &nokia_sdrc_params[0]; } From 2b1af87ace4776f0d0c3513923a79529fc1b5a00 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 17 Dec 2010 15:13:46 -0800 Subject: [PATCH 297/300] arm: omap: sdram-nokia: improve error handling Actually check for errors: print an error log and return NULL. Signed-off-by: Aaro Koskinen Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/sdram-nokia.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/sdram-nokia.c b/arch/arm/mach-omap2/sdram-nokia.c index 1171451ef7f2..863586bdb98a 100644 --- a/arch/arm/mach-omap2/sdram-nokia.c +++ b/arch/arm/mach-omap2/sdram-nokia.c @@ -223,10 +223,14 @@ struct omap_sdrc_params *nokia_get_sdram_timings(void) int err = 0; int i; - for (i = 0; i < ARRAY_SIZE(nokia_timings); i++) + for (i = 0; i < ARRAY_SIZE(nokia_timings); i++) { err |= sdrc_timings(i, nokia_timings[i].rate, nokia_timings[i].data); + if (err) + pr_err("%s: error with rate %ld: %d\n", __func__, + nokia_timings[i].rate, err); + } - return &nokia_sdrc_params[0]; + return err ? NULL : nokia_sdrc_params; } From 15d24e118d51601a5cc2f021005aa7354b03b1c8 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 17 Dec 2010 15:13:46 -0800 Subject: [PATCH 298/300] arm: omap: sdram-nokia: delete redundant timing data 41.5 MHz SDRAM clock is not usable. Signed-off-by: Aaro Koskinen Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/sdram-nokia.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-omap2/sdram-nokia.c b/arch/arm/mach-omap2/sdram-nokia.c index 863586bdb98a..baf83ecdada1 100644 --- a/arch/arm/mach-omap2/sdram-nokia.c +++ b/arch/arm/mach-omap2/sdram-nokia.c @@ -69,7 +69,6 @@ static const struct { long rate; struct sdram_timings const *data; } nokia_timings[] = { - { 41500000, nokia_166mhz_timings }, { 83000000, nokia_166mhz_timings }, { 166000000, nokia_166mhz_timings }, }; From 20dbeb1081327aefaac7044d9908c97bf445858c Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 17 Dec 2010 15:13:46 -0800 Subject: [PATCH 299/300] arm: omap: sdram-nokia: add 97.6/195.2 MHz timing data Introduce 97.6/195.2 MHz memory timing data. Based on patches by Eduardo Valentin, Igor Dmitriev and Juha Keski-Saari. Signed-off-by: Aaro Koskinen Cc: Eduardo Valentin Cc: Igor Dmitriev Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/sdram-nokia.c | 44 +++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/arch/arm/mach-omap2/sdram-nokia.c b/arch/arm/mach-omap2/sdram-nokia.c index baf83ecdada1..14caa228bc0d 100644 --- a/arch/arm/mach-omap2/sdram-nokia.c +++ b/arch/arm/mach-omap2/sdram-nokia.c @@ -44,6 +44,27 @@ struct sdram_timings { u32 tWTR; }; +static const struct sdram_timings nokia_97dot6mhz_timings[] = { + { + .casl = 3, + .tDAL = 30725, + .tDPL = 15362, + .tRRD = 10241, + .tRCD = 20483, + .tRP = 15362, + .tRAS = 40967, + .tRC = 56330, + .tRFC = 138266, + .tXSR = 204839, + + .tREF = 7798, + + .tXP = 2, + .tCKE = 4, + .tWTR = 2, + }, +}; + static const struct sdram_timings nokia_166mhz_timings[] = { { .casl = 3, @@ -65,12 +86,35 @@ static const struct sdram_timings nokia_166mhz_timings[] = { }, }; +static const struct sdram_timings nokia_195dot2mhz_timings[] = { + { + .casl = 3, + .tDAL = 30725, + .tDPL = 15362, + .tRRD = 10241, + .tRCD = 20483, + .tRP = 15362, + .tRAS = 40967, + .tRC = 56330, + .tRFC = 138266, + .tXSR = 204839, + + .tREF = 7752, + + .tXP = 2, + .tCKE = 4, + .tWTR = 2, + }, +}; + static const struct { long rate; struct sdram_timings const *data; } nokia_timings[] = { { 83000000, nokia_166mhz_timings }, + { 97600000, nokia_97dot6mhz_timings }, { 166000000, nokia_166mhz_timings }, + { 195200000, nokia_195dot2mhz_timings }, }; static struct omap_sdrc_params nokia_sdrc_params[ARRAY_SIZE(nokia_timings) + 1]; From 2d200665c37f544f648d77a05a06ab63328f0d3a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 17 Dec 2010 15:13:47 -0800 Subject: [PATCH 300/300] arm: omap: add minimal support for RM-680 Add minimal support for Nokia RM-680 board. Tested with omap2plus_defconfig. Signed-off-by: Aaro Koskinen [tony@atomide.com: updated to remove omap_gpio_init Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/Kconfig | 6 + arch/arm/mach-omap2/Makefile | 3 + arch/arm/mach-omap2/board-rm680.c | 186 +++++++++++++++++++ arch/arm/plat-omap/include/plat/uncompress.h | 1 + 4 files changed, 196 insertions(+) create mode 100644 arch/arm/mach-omap2/board-rm680.c diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index ab784bfde908..fe92f4c5f397 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -210,6 +210,12 @@ config MACH_NOKIA_N8X0 select MACH_NOKIA_N810 select MACH_NOKIA_N810_WIMAX +config MACH_NOKIA_RM680 + bool "Nokia RM-680 board" + depends on ARCH_OMAP3 + default y + select OMAP_PACKAGE_CBB + config MACH_NOKIA_RX51 bool "Nokia RX-51 board" depends on ARCH_OMAP3 diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index e72ccf79b791..4e23ed6d2ec4 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -139,6 +139,9 @@ obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \ hsmmc.o \ board-flash.o obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o +obj-$(CONFIG_MACH_NOKIA_RM680) += board-rm680.o \ + sdram-nokia.o \ + hsmmc.o obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \ sdram-nokia.o \ board-rx51-peripherals.o \ diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c new file mode 100644 index 000000000000..8da65bd6ff8d --- /dev/null +++ b/arch/arm/mach-omap2/board-rm680.c @@ -0,0 +1,186 @@ +/* + * Board support file for Nokia RM-680. + * + * Copyright (C) 2010 Nokia + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "mux.h" +#include "hsmmc.h" +#include "sdram-nokia.h" + +static struct regulator_consumer_supply rm680_vemmc_consumers[] = { + REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1"), +}; + +/* Fixed regulator for internal eMMC */ +static struct regulator_init_data rm680_vemmc = { + .constraints = { + .name = "rm680_vemmc", + .min_uV = 2900000, + .max_uV = 2900000, + .apply_uV = 1, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_STATUS + | REGULATOR_CHANGE_MODE, + }, + .num_consumer_supplies = ARRAY_SIZE(rm680_vemmc_consumers), + .consumer_supplies = rm680_vemmc_consumers, +}; + +static struct fixed_voltage_config rm680_vemmc_config = { + .supply_name = "VEMMC", + .microvolts = 2900000, + .gpio = 157, + .startup_delay = 150, + .enable_high = 1, + .init_data = &rm680_vemmc, +}; + +static struct platform_device rm680_vemmc_device = { + .name = "reg-fixed-voltage", + .dev = { + .platform_data = &rm680_vemmc_config, + }, +}; + +static struct platform_device *rm680_peripherals_devices[] __initdata = { + &rm680_vemmc_device, +}; + +/* TWL */ +static struct twl4030_gpio_platform_data rm680_gpio_data = { + .gpio_base = OMAP_MAX_GPIO_LINES, + .irq_base = TWL4030_GPIO_IRQ_BASE, + .irq_end = TWL4030_GPIO_IRQ_END, + .pullups = BIT(0), + .pulldowns = BIT(1) | BIT(2) | BIT(8) | BIT(15), +}; + +static struct twl4030_usb_data rm680_usb_data = { + .usb_mode = T2_USB_MODE_ULPI, +}; + +static struct twl4030_platform_data rm680_twl_data = { + .irq_base = TWL4030_IRQ_BASE, + .irq_end = TWL4030_IRQ_END, + .gpio = &rm680_gpio_data, + .usb = &rm680_usb_data, + /* add rest of the children here */ +}; + +static struct i2c_board_info __initdata rm680_twl_i2c_board_info[] = { + { + I2C_BOARD_INFO("twl5031", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &rm680_twl_data, + }, +}; + +static void __init rm680_i2c_init(void) +{ + omap_register_i2c_bus(1, 2900, rm680_twl_i2c_board_info, + ARRAY_SIZE(rm680_twl_i2c_board_info)); + omap_register_i2c_bus(2, 400, NULL, 0); + omap_register_i2c_bus(3, 400, NULL, 0); +} + +#if defined(CONFIG_MTD_ONENAND_OMAP2) || \ + defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) +static struct omap_onenand_platform_data board_onenand_data[] = { + { + .gpio_irq = 65, + .flags = ONENAND_SYNC_READWRITE, + } +}; +#endif + +/* eMMC */ +static struct omap2_hsmmc_info mmc[] __initdata = { + { + .name = "internal", + .mmc = 2, + .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + }, + { /* Terminator */ } +}; + +static void __init rm680_peripherals_init(void) +{ + platform_add_devices(rm680_peripherals_devices, + ARRAY_SIZE(rm680_peripherals_devices)); + rm680_i2c_init(); + gpmc_onenand_init(board_onenand_data); + omap2_hsmmc_init(mmc); +} + +static void __init rm680_init_irq(void) +{ + struct omap_sdrc_params *sdrc_params; + + sdrc_params = nokia_get_sdram_timings(); + omap2_init_common_hw(sdrc_params, sdrc_params); + omap_init_irq(); +} + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#endif + +static struct omap_musb_board_data rm680_musb_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_PERIPHERAL, + .power = 100, +}; + +static void __init rm680_init(void) +{ + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + omap_serial_init(); + usb_musb_init(&rm680_musb_data); + rm680_peripherals_init(); +} + +static void __init rm680_map_io(void) +{ + omap2_set_globals_3xxx(); + omap34xx_map_common_io(); +} + +MACHINE_START(NOKIA_RM680, "Nokia RM-680 board") + .boot_params = 0x80000100, + .map_io = rm680_map_io, + .reserve = omap_reserve, + .init_irq = rm680_init_irq, + .init_machine = rm680_init, + .timer = &omap_timer, +MACHINE_END diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h index 9036e374e0ac..d02adb5cc4d9 100644 --- a/arch/arm/plat-omap/include/plat/uncompress.h +++ b/arch/arm/plat-omap/include/plat/uncompress.h @@ -147,6 +147,7 @@ static inline void __arch_decomp_setup(unsigned long arch_id) DEBUG_LL_OMAP3(3, cm_t3517); DEBUG_LL_OMAP3(3, igep0020); DEBUG_LL_OMAP3(3, igep0030); + DEBUG_LL_OMAP3(3, nokia_rm680); DEBUG_LL_OMAP3(3, nokia_rx51); DEBUG_LL_OMAP3(3, omap3517evm); DEBUG_LL_OMAP3(3, omap3_beagle);