diff options
64 files changed, 572 insertions, 438 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 6c73b3bc7f34..7642365ed6d2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -896,11 +896,13 @@ S: Maintained ARM/SAMSUNG ARM ARCHITECTURES M: Ben Dooks <ben-linux@fluff.org> +M: Kukjin Kim <kgene.kim@samsung.com> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.fluff.org/ben/linux/ S: Maintained -F: arch/arm/plat-s3c/ +F: arch/arm/plat-samsung/ F: arch/arm/plat-s3c24xx/ +F: arch/arm/plat-s5p/ ARM/S3C2410 ARM ARCHITECTURE M: Ben Dooks <ben-linux@fluff.org> @@ -1148,7 +1150,7 @@ F: drivers/mmc/host/atmel-mci.c F: drivers/mmc/host/atmel-mci-regs.h ATMEL AT91 / AT32 SERIAL DRIVER -M: Haavard Skinnemoen <hskinnemoen@atmel.com> +M: Nicolas Ferre <nicolas.ferre@atmel.com> S: Supported F: drivers/serial/atmel_serial.c @@ -1160,18 +1162,18 @@ F: drivers/video/atmel_lcdfb.c F: include/video/atmel_lcdc.h ATMEL MACB ETHERNET DRIVER -M: Haavard Skinnemoen <hskinnemoen@atmel.com> +M: Nicolas Ferre <nicolas.ferre@atmel.com> S: Supported F: drivers/net/macb.* ATMEL SPI DRIVER -M: Haavard Skinnemoen <hskinnemoen@atmel.com> +M: Nicolas Ferre <nicolas.ferre@atmel.com> S: Supported F: drivers/spi/atmel_spi.* ATMEL USBA UDC DRIVER -M: Haavard Skinnemoen <hskinnemoen@atmel.com> -L: kernel@avr32linux.org +M: Nicolas Ferre <nicolas.ferre@atmel.com> +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://avr32linux.org/twiki/bin/view/Main/AtmelUsbDeviceDriver S: Supported F: drivers/usb/gadget/atmel_usba_udc.* @@ -3380,7 +3382,7 @@ KPROBES M: Ananth N Mavinakayanahalli <ananth@in.ibm.com> M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> M: "David S. Miller" <davem@davemloft.net> -M: Masami Hiramatsu <mhiramat@redhat.com> +M: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> S: Maintained F: Documentation/kprobes.txt F: include/linux/kprobes.h @@ -4628,6 +4630,12 @@ M: Robert Jarzmik <robert.jarzmik@free.fr> L: rtc-linux@googlegroups.com S: Maintained +QLOGIC QLA1280 SCSI DRIVER +M: Michael Reed <mdr@sgi.com> +L: linux-scsi@vger.kernel.org +S: Maintained +F: drivers/scsi/qla1280.[ch] + QLOGIC QLA2XXX FC-SCSI DRIVER M: Andrew Vasquez <andrew.vasquez@qlogic.com> M: linux-driver@qlogic.com diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c index f848ba8dbc16..a04cffd691c5 100644 --- a/arch/arm/mach-omap2/board-omap3stalker.c +++ b/arch/arm/mach-omap2/board-omap3stalker.c @@ -538,9 +538,7 @@ static void ads7846_dev_init(void) printk(KERN_ERR "can't get ads7846 pen down GPIO\n"); gpio_direction_input(OMAP3_STALKER_TS_GPIO); - - omap_set_gpio_debounce(OMAP3_STALKER_TS_GPIO, 1); - omap_set_gpio_debounce_time(OMAP3_STALKER_TS_GPIO, 0xa); + gpio_set_debounce(OMAP3_STALKER_TS_GPIO, 310); } static int ads7846_get_pendown_state(void) diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index 02804224517b..e10db7a90cb2 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -1369,6 +1369,7 @@ static struct clk emif1_ick = { .ops = &clkops_omap2_dflt, .enable_reg = OMAP4430_CM_MEMIF_EMIF_1_CLKCTRL, .enable_bit = OMAP4430_MODULEMODE_HWCTRL, + .flags = ENABLE_ON_INIT, .clkdm_name = "l3_emif_clkdm", .parent = &ddrphy_ck, .recalc = &followparent_recalc, @@ -1379,6 +1380,7 @@ static struct clk emif2_ick = { .ops = &clkops_omap2_dflt, .enable_reg = OMAP4430_CM_MEMIF_EMIF_2_CLKCTRL, .enable_bit = OMAP4430_MODULEMODE_HWCTRL, + .flags = ENABLE_ON_INIT, .clkdm_name = "l3_emif_clkdm", .parent = &ddrphy_ck, .recalc = &followparent_recalc, diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 95c9a5f774e1..b7a4133267d8 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -409,10 +409,11 @@ static int _init_main_clk(struct omap_hwmod *oh) return 0; oh->_clk = omap_clk_get_by_name(oh->main_clk); - if (!oh->_clk) + if (!oh->_clk) { pr_warning("omap_hwmod: %s: cannot clk_get main_clk %s\n", oh->name, oh->main_clk); return -EINVAL; + } if (!oh->_clk->clkdm) pr_warning("omap_hwmod: %s: missing clockdomain for %s.\n", @@ -444,10 +445,11 @@ static int _init_interface_clks(struct omap_hwmod *oh) continue; c = omap_clk_get_by_name(os->clk); - if (!c) + if (!c) { pr_warning("omap_hwmod: %s: cannot clk_get interface_clk %s\n", oh->name, os->clk); ret = -EINVAL; + } os->_clk = c; } @@ -470,10 +472,11 @@ static int _init_opt_clks(struct omap_hwmod *oh) for (i = oh->opt_clks_cnt, oc = oh->opt_clks; i > 0; i--, oc++) { c = omap_clk_get_by_name(oc->clk); - if (!c) + if (!c) { pr_warning("omap_hwmod: %s: cannot clk_get opt_clk %s\n", oh->name, oc->clk); ret = -EINVAL; + } oc->_clk = c; } diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 2e967716cc3f..b88737fd6cfe 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -99,7 +99,7 @@ static void omap3_enable_io_chain(void) /* Do a readback to assure write has been done */ prm_read_mod_reg(WKUP_MOD, PM_WKEN); - while (!(prm_read_mod_reg(WKUP_MOD, PM_WKST) & + while (!(prm_read_mod_reg(WKUP_MOD, PM_WKEN) & OMAP3430_ST_IO_CHAIN_MASK)) { timeout++; if (timeout > 1000) { @@ -108,7 +108,7 @@ static void omap3_enable_io_chain(void) return; } prm_set_mod_reg_bits(OMAP3430_ST_IO_CHAIN_MASK, - WKUP_MOD, PM_WKST); + WKUP_MOD, PM_WKEN); } } } diff --git a/arch/arm/mach-omap2/usb-ehci.c b/arch/arm/mach-omap2/usb-ehci.c index c68f799e83c5..d72d1ac30333 100644 --- a/arch/arm/mach-omap2/usb-ehci.c +++ b/arch/arm/mach-omap2/usb-ehci.c @@ -20,6 +20,8 @@ #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/clk.h> +#include <linux/dma-mapping.h> + #include <asm/io.h> #include <plat/mux.h> diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index c64875f11fac..44bafdab2dce 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -541,11 +541,11 @@ void omap_dm_timer_stop(struct omap_dm_timer *timer) * timer is stopped */ udelay(3500000 / clk_get_rate(timer->fclk) + 1); - /* Ack possibly pending interrupt */ - omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, - OMAP_TIMER_INT_OVERFLOW); #endif } + /* Ack possibly pending interrupt */ + omap_dm_timer_write_reg(timer, OMAP_TIMER_STAT_REG, + OMAP_TIMER_INT_OVERFLOW); } EXPORT_SYMBOL_GPL(omap_dm_timer_stop); diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 393e9219a5b6..9b7e3545f325 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -673,6 +673,7 @@ static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio, if (cpu_is_omap34xx() || cpu_is_omap44xx()) clk_disable(bank->dbck); } + bank->dbck_enable_mask = val; __raw_writel(val, reg); } diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c index e43983ba59c5..8ce0de247c71 100644 --- a/arch/arm/plat-omap/iovmm.c +++ b/arch/arm/plat-omap/iovmm.c @@ -140,8 +140,10 @@ static struct sg_table *sgtable_alloc(const size_t bytes, u32 flags) return ERR_PTR(-ENOMEM); err = sg_alloc_table(sgt, nr_entries, GFP_KERNEL); - if (err) + if (err) { + kfree(sgt); return ERR_PTR(err); + } pr_debug("%s: sgt:%p(%d entries)\n", __func__, sgt, nr_entries); diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index 93a11d7edfa0..e696144d2be3 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -10,6 +10,7 @@ #include <errno.h> #include <fcntl.h> #include <string.h> +#include <sys/stat.h> #include <sys/mman.h> #include <sys/param.h> #include "init.h" diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 35603dd4e6c5..094bdc355b1f 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -302,6 +302,12 @@ struct smi_info { static int force_kipmid[SI_MAX_PARMS]; static int num_force_kipmid; +#ifdef CONFIG_PCI +static int pci_registered; +#endif +#ifdef CONFIG_PPC_OF +static int of_registered; +#endif static unsigned int kipmid_max_busy_us[SI_MAX_PARMS]; static int num_max_busy_us; @@ -1018,7 +1024,7 @@ static int ipmi_thread(void *data) else if (smi_result == SI_SM_IDLE) schedule_timeout_interruptible(100); else - schedule_timeout_interruptible(0); + schedule_timeout_interruptible(1); } return 0; } @@ -3314,6 +3320,8 @@ static __devinit int init_ipmi_si(void) rv = pci_register_driver(&ipmi_pci_driver); if (rv) printk(KERN_ERR PFX "Unable to register PCI driver: %d\n", rv); + else + pci_registered = 1; #endif #ifdef CONFIG_ACPI @@ -3330,6 +3338,7 @@ static __devinit int init_ipmi_si(void) #ifdef CONFIG_PPC_OF of_register_platform_driver(&ipmi_of_platform_driver); + of_registered = 1; #endif /* We prefer devices with interrupts, but in the case of a machine @@ -3383,11 +3392,13 @@ static __devinit int init_ipmi_si(void) if (unload_when_empty && list_empty(&smi_infos)) { mutex_unlock(&smi_infos_lock); #ifdef CONFIG_PCI - pci_unregister_driver(&ipmi_pci_driver); + if (pci_registered) + pci_unregister_driver(&ipmi_pci_driver); #endif #ifdef CONFIG_PPC_OF - of_unregister_platform_driver(&ipmi_of_platform_driver); + if (of_registered) + of_unregister_platform_driver(&ipmi_of_platform_driver); #endif driver_unregister(&ipmi_driver.driver); printk(KERN_WARNING PFX @@ -3478,14 +3489,16 @@ static __exit void cleanup_ipmi_si(void) return; #ifdef CONFIG_PCI - pci_unregister_driver(&ipmi_pci_driver); + if (pci_registered) + pci_unregister_driver(&ipmi_pci_driver); #endif #ifdef CONFIG_ACPI pnp_unregister_driver(&ipmi_pnp_driver); #endif #ifdef CONFIG_PPC_OF - of_unregister_platform_driver(&ipmi_of_platform_driver); + if (of_registered) + of_unregister_platform_driver(&ipmi_of_platform_driver); #endif mutex_lock(&smi_infos_lock); diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 724038dab4ca..7face915b963 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1,5 +1,5 @@ # -# GPIO infrastructure and expanders +# platform-neutral GPIO infrastructure and expanders # config ARCH_WANT_OPTIONAL_GPIOLIB diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 51c3cdd41b5a..e53dcff49b4f 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -1,4 +1,8 @@ -# gpio support: dedicated expander chips, etc +# generic gpio support: dedicated expander chips, etc +# +# NOTE: platform-specific GPIO drivers don't belong in the +# drivers/gpio directory; put them with other platform setup +# code, IRQ controllers, board init, etc. ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index de033b7ac21f..d827ce570a8c 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -777,7 +777,7 @@ static int __devinit ds1307_probe(struct i2c_client *client, read_rtc: /* read RTC registers */ - tmp = ds1307->read_block_data(ds1307->client, 0, 8, buf); + tmp = ds1307->read_block_data(ds1307->client, ds1307->offset, 8, buf); if (tmp != 8) { pr_debug("read error %d\n", tmp); err = -EIO; @@ -862,7 +862,7 @@ read_rtc: if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM) tmp += 12; i2c_smbus_write_byte_data(client, - DS1307_REG_HOUR, + ds1307->offset + DS1307_REG_HOUR, bin2bcd(tmp)); } diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 9eb62a256e9a..cd6cf575902e 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -930,6 +930,83 @@ static void cpm_uart_config_port(struct uart_port *port, int flags) } } +#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_CPM_CONSOLE) +/* + * Write a string to the serial port + * Note that this is called with interrupts already disabled + */ +static void cpm_uart_early_write(struct uart_cpm_port *pinfo, + const char *string, u_int count) +{ + unsigned int i; + cbd_t __iomem *bdp, *bdbase; + unsigned char *cpm_outp_addr; + + /* Get the address of the host memory buffer. + */ + bdp = pinfo->tx_cur; + bdbase = pinfo->tx_bd_base; + + /* + * Now, do each character. This is not as bad as it looks + * since this is a holding FIFO and not a transmitting FIFO. + * We could add the complexity of filling the entire transmit + * buffer, but we would just wait longer between accesses...... + */ + for (i = 0; i < count; i++, string++) { + /* Wait for transmitter fifo to empty. + * Ready indicates output is ready, and xmt is doing + * that, not that it is ready for us to send. + */ + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) + ; + + /* Send the character out. + * If the buffer address is in the CPM DPRAM, don't + * convert it. + */ + cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), + pinfo); + *cpm_outp_addr = *string; + + out_be16(&bdp->cbd_datlen, 1); + setbits16(&bdp->cbd_sc, BD_SC_READY); + + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) + bdp = bdbase; + else + bdp++; + + /* if a LF, also do CR... */ + if (*string == 10) { + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) + ; + + cpm_outp_addr = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), + pinfo); + *cpm_outp_addr = 13; + + out_be16(&bdp->cbd_datlen, 1); + setbits16(&bdp->cbd_sc, BD_SC_READY); + + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) + bdp = bdbase; + else + bdp++; + } + } + + /* + * Finally, Wait for transmitter & holding register to empty + * and restore the IER + */ + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) + ; + + pinfo->tx_cur = bdp; +} +#endif + #ifdef CONFIG_CONSOLE_POLL /* Serial polling routines for writing and reading from the uart while * in an interrupt or debug context. @@ -999,7 +1076,7 @@ static void cpm_put_poll_char(struct uart_port *port, static char ch[2]; ch[0] = (char)c; - cpm_uart_early_write(pinfo->port.line, ch, 1); + cpm_uart_early_write(pinfo, ch, 1); } #endif /* CONFIG_CONSOLE_POLL */ @@ -1130,9 +1207,6 @@ static void cpm_uart_console_write(struct console *co, const char *s, u_int count) { struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; - unsigned int i; - cbd_t __iomem *bdp, *bdbase; - unsigned char *cp; unsigned long flags; int nolock = oops_in_progress; @@ -1142,66 +1216,7 @@ static void cpm_uart_console_write(struct console *co, const char *s, spin_lock_irqsave(&pinfo->port.lock, flags); } - /* Get the address of the host memory buffer. - */ - bdp = pinfo->tx_cur; - bdbase = pinfo->tx_bd_base; - - /* - * Now, do each character. This is not as bad as it looks - * since this is a holding FIFO and not a transmitting FIFO. - * We could add the complexity of filling the entire transmit - * buffer, but we would just wait longer between accesses...... - */ - for (i = 0; i < count; i++, s++) { - /* Wait for transmitter fifo to empty. - * Ready indicates output is ready, and xmt is doing - * that, not that it is ready for us to send. - */ - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) - ; - - /* Send the character out. - * If the buffer address is in the CPM DPRAM, don't - * convert it. - */ - cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); - *cp = *s; - - out_be16(&bdp->cbd_datlen, 1); - setbits16(&bdp->cbd_sc, BD_SC_READY); - - if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) - bdp = bdbase; - else - bdp++; - - /* if a LF, also do CR... */ - if (*s == 10) { - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) - ; - - cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); - *cp = 13; - - out_be16(&bdp->cbd_datlen, 1); - setbits16(&bdp->cbd_sc, BD_SC_READY); - - if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) - bdp = bdbase; - else - bdp++; - } - } - - /* - * Finally, Wait for transmitter & holding register to empty - * and restore the IER - */ - while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) - ; - - pinfo->tx_cur = bdp; + cpm_uart_early_write(pinfo, s, count); if (unlikely(nolock)) { local_irq_restore(flags); diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index e2c000b80ca0..212bc21e6d68 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -225,9 +225,9 @@ static struct bat_attribute *mesh_attrs[] = { NULL, }; -static ssize_t transtable_local_read(struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buff, loff_t off, size_t count) +static ssize_t transtable_local_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) { struct device *dev = to_dev(kobj->parent); struct net_device *net_dev = to_net_dev(dev); @@ -235,9 +235,9 @@ static ssize_t transtable_local_read(struct kobject *kobj, return hna_local_fill_buffer_text(net_dev, buff, count, off); } -static ssize_t transtable_global_read(struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buff, loff_t off, size_t count) +static ssize_t transtable_global_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) { struct device *dev = to_dev(kobj->parent); struct net_device *net_dev = to_net_dev(dev); @@ -245,9 +245,9 @@ static ssize_t transtable_global_read(struct kobject *kobj, return hna_global_fill_buffer_text(net_dev, buff, count, off); } -static ssize_t originators_read(struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buff, loff_t off, size_t count) +static ssize_t originators_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) { struct device *dev = to_dev(kobj->parent); struct net_device *net_dev = to_net_dev(dev); @@ -255,9 +255,9 @@ static ssize_t originators_read(struct kobject *kobj, return orig_fill_buffer_text(net_dev, buff, count, off); } -static ssize_t vis_data_read(struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buff, loff_t off, size_t count) +static ssize_t vis_data_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buff, loff_t off, size_t count) { struct device *dev = to_dev(kobj->parent); struct net_device *net_dev = to_net_dev(dev); diff --git a/drivers/staging/batman-adv/device.c b/drivers/staging/batman-adv/device.c index 7eb6559e0315..32204b5572d0 100644 --- a/drivers/staging/batman-adv/device.c +++ b/drivers/staging/batman-adv/device.c @@ -196,7 +196,7 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count, kfree(device_packet); if (error) - return error; + return -EFAULT; return sizeof(struct icmp_packet); } diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c index 36a254cd4413..39d112b708e3 100644 --- a/drivers/staging/comedi/drivers/adl_pci9111.c +++ b/drivers/staging/comedi/drivers/adl_pci9111.c @@ -824,9 +824,12 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev, plx9050_interrupt_control(dev_private->lcr_io_base, true, true, false, true, true); - dev_private->scan_delay = - (async_cmd->scan_begin_arg / (async_cmd->convert_arg * - async_cmd->chanlist_len)) - 1; + if (async_cmd->scan_begin_src == TRIG_TIMER) { + dev_private->scan_delay = + (async_cmd->scan_begin_arg / + (async_cmd->convert_arg * + async_cmd->chanlist_len)) - 1; + } break; diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 81829d6fd287..c374bee25068 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -52,7 +52,6 @@ Please report success/failure with other different cards to #include "8255.h" #define PCI_VENDOR_ID_CB 0x1307 /* PCI vendor number of ComputerBoards */ -#define N_BOARDS 10 /* Number of boards in cb_pcidda_boards */ #define EEPROM_SIZE 128 /* number of entries in eeprom */ #define MAX_AO_CHANNELS 8 /* maximum number of ao channels for supported boards */ @@ -307,7 +306,7 @@ static int cb_pcidda_attach(struct comedi_device *dev, continue; } } - for (index = 0; index < N_BOARDS; index++) { + for (index = 0; index < ARRAY_SIZE(cb_pcidda_boards); index++) { if (cb_pcidda_boards[index].device_id == pcidev->device) { goto found; diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 3f53b4d1e4cf..12db555a3a5d 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -23,6 +23,7 @@ #include <linux/slab.h> #include <linux/list.h> #include <linux/module.h> +#include <linux/completion.h> #include "osd.h" #include "logging.h" #include "vmbus_private.h" @@ -293,6 +294,25 @@ void FreeVmbusChannel(struct vmbus_channel *Channel) Channel); } + +DECLARE_COMPLETION(hv_channel_ready); + +/* + * Count initialized channels, and ensure all channels are ready when hv_vmbus + * module loading completes. + */ +static void count_hv_channel(void) +{ + static int counter; + unsigned long flags; + + spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + if (++counter == MAX_MSG_TYPES) + complete(&hv_channel_ready); + spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); +} + + /* * VmbusChannelProcessOffer - Process the offer by creating a channel/device * associated with this offer @@ -373,22 +393,21 @@ static void VmbusChannelProcessOffer(void *context) * can cleanup properly */ newChannel->State = CHANNEL_OPEN_STATE; - cnt = 0; - while (cnt != MAX_MSG_TYPES) { + /* Open IC channels */ + for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) { if (memcmp(&newChannel->OfferMsg.Offer.InterfaceType, &hv_cb_utils[cnt].data, - sizeof(struct hv_guid)) == 0) { + sizeof(struct hv_guid)) == 0 && + VmbusChannelOpen(newChannel, 2 * PAGE_SIZE, + 2 * PAGE_SIZE, NULL, 0, + hv_cb_utils[cnt].callback, + newChannel) == 0) { + hv_cb_utils[cnt].channel = newChannel; DPRINT_INFO(VMBUS, "%s", - hv_cb_utils[cnt].log_msg); - - if (VmbusChannelOpen(newChannel, 2 * PAGE_SIZE, - 2 * PAGE_SIZE, NULL, 0, - hv_cb_utils[cnt].callback, - newChannel) == 0) - hv_cb_utils[cnt].channel = newChannel; + hv_cb_utils[cnt].log_msg); + count_hv_channel(); } - cnt++; } } DPRINT_EXIT(VMBUS); diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c index 8a49aafea37a..2adc9b48ca9c 100644 --- a/drivers/staging/hv/hv_utils.c +++ b/drivers/staging/hv/hv_utils.c @@ -24,6 +24,8 @@ #include <linux/slab.h> #include <linux/sysctl.h> #include <linux/reboot.h> +#include <linux/dmi.h> +#include <linux/pci.h> #include "logging.h" #include "osd.h" @@ -251,10 +253,36 @@ static void heartbeat_onchannelcallback(void *context) DPRINT_EXIT(VMBUS); } +static const struct pci_device_id __initconst +hv_utils_pci_table[] __maybe_unused = { + { PCI_DEVICE(0x1414, 0x5353) }, /* Hyper-V emulated VGA controller */ + { 0 } +}; +MODULE_DEVICE_TABLE(pci, hv_utils_pci_table); + + +static const struct dmi_system_id __initconst +hv_utils_dmi_table[] __maybe_unused = { + { + .ident = "Hyper-V", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), + DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"), + }, + }, + { }, +}; +MODULE_DEVICE_TABLE(dmi, hv_utils_dmi_table); + + static int __init init_hyperv_utils(void) { printk(KERN_INFO "Registering HyperV Utility Driver\n"); + if (!dmi_check_system(hv_utils_dmi_table)) + return -ENODEV; + hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback = &shutdown_onchannelcallback; hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback; diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h index 0c6ee0f487f3..3c14b2926e00 100644 --- a/drivers/staging/hv/vmbus.h +++ b/drivers/staging/hv/vmbus.h @@ -74,4 +74,6 @@ int vmbus_child_driver_register(struct driver_context *driver_ctx); void vmbus_child_driver_unregister(struct driver_context *driver_ctx); void vmbus_get_interface(struct vmbus_channel_interface *interface); +extern struct completion hv_channel_ready; + #endif /* _VMBUS_H_ */ diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index c21731a12ca7..22c80ece6388 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -27,6 +27,7 @@ #include <linux/pci.h> #include <linux/dmi.h> #include <linux/slab.h> +#include <linux/completion.h> #include "version_info.h" #include "osd.h" #include "logging.h" @@ -356,6 +357,8 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) vmbus_drv_obj->GetChannelOffers(); + wait_for_completion(&hv_channel_ready); + cleanup: DPRINT_EXIT(VMBUS_DRV); diff --git a/drivers/staging/mrst-touchscreen/intel-mid-touch.c b/drivers/staging/mrst-touchscreen/intel-mid-touch.c index 1db00975a594..abba22f921be 100644 --- a/drivers/staging/mrst-touchscreen/intel-mid-touch.c +++ b/drivers/staging/mrst-touchscreen/intel-mid-touch.c @@ -817,9 +817,9 @@ static int mrstouch_remove(struct spi_device *spi) free_irq(mrstouchdevp->irq, mrstouchdevp); input_unregister_device(mrstouchdevp->input); input_free_device(mrstouchdevp->input); - kfree(mrstouchdevp); if (mrstouchdevp->pendet_thrd) kthread_stop(mrstouchdevp->pendet_thrd); + kfree(mrstouchdevp); return 0; } diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c index b740662d095a..674769d2b59b 100644 --- a/drivers/staging/rt2860/usb_main_dev.c +++ b/drivers/staging/rt2860/usb_main_dev.c @@ -77,6 +77,7 @@ struct usb_device_id rtusb_usb_id[] = { {USB_DEVICE(0x083A, 0x7522)}, /* Arcadyan */ {USB_DEVICE(0x0CDE, 0x0022)}, /* ZCOM */ {USB_DEVICE(0x0586, 0x3416)}, /* Zyxel */ + {USB_DEVICE(0x0586, 0x341a)}, /* Zyxel NWD-270N */ {USB_DEVICE(0x0CDE, 0x0025)}, /* Zyxel */ {USB_DEVICE(0x1740, 0x9701)}, /* EnGenius */ {USB_DEVICE(0x1740, 0x9702)}, /* EnGenius */ diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c index dacefea78113..49ab9fa9ffa7 100644 --- a/drivers/staging/rtl8187se/r8180_core.c +++ b/drivers/staging/rtl8187se/r8180_core.c @@ -66,8 +66,6 @@ static int hwseqnum = 0; static int hwwep = 0; static int channels = 0x3fff; -#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1 : 0) -#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5]) MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(pci, rtl8180_pci_id_tbl); MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>"); diff --git a/drivers/staging/rtl8192su/r8192U_core.c b/drivers/staging/rtl8192su/r8192U_core.c index 447d6474a70c..1b6890611fb6 100644 --- a/drivers/staging/rtl8192su/r8192U_core.c +++ b/drivers/staging/rtl8192su/r8192U_core.c @@ -112,28 +112,29 @@ u32 rt_global_debug_component = \ #define CAM_CONTENT_COUNT 8 static const struct usb_device_id rtl8192_usb_id_tbl[] = { - /* Realtek */ - {USB_DEVICE(0x0bda, 0x8171)}, - {USB_DEVICE(0x0bda, 0x8192)}, - {USB_DEVICE(0x0bda, 0x8709)}, - /* Corega */ - {USB_DEVICE(0x07aa, 0x0043)}, - /* Belkin */ - {USB_DEVICE(0x050d, 0x805E)}, - {USB_DEVICE(0x050d, 0x815F)}, /* Belkin F5D8053 v6 */ - /* Sitecom */ - {USB_DEVICE(0x0df6, 0x0031)}, - {USB_DEVICE(0x0df6, 0x004b)}, /* WL-349 */ - /* EnGenius */ - {USB_DEVICE(0x1740, 0x9201)}, - /* Dlink */ - {USB_DEVICE(0x2001, 0x3301)}, - /* Zinwell */ - {USB_DEVICE(0x5a57, 0x0290)}, - /* Guillemot */ - {USB_DEVICE(0x06f8, 0xe031)}, - //92SU + {USB_DEVICE(0x0bda, 0x8171)}, /* Realtek */ {USB_DEVICE(0x0bda, 0x8172)}, + {USB_DEVICE(0x0bda, 0x8173)}, + {USB_DEVICE(0x0bda, 0x8174)}, + {USB_DEVICE(0x0bda, 0x8712)}, + {USB_DEVICE(0x0bda, 0x8713)}, + {USB_DEVICE(0x07aa, 0x0047)}, + {USB_DEVICE(0x07d1, 0x3303)}, + {USB_DEVICE(0x07d1, 0x3302)}, + {USB_DEVICE(0x07d1, 0x3300)}, + {USB_DEVICE(0x1740, 0x9603)}, + {USB_DEVICE(0x1740, 0x9605)}, + {USB_DEVICE(0x050d, 0x815F)}, + {USB_DEVICE(0x06f8, 0xe031)}, + {USB_DEVICE(0x7392, 0x7611)}, + {USB_DEVICE(0x7392, 0x7612)}, + {USB_DEVICE(0x7392, 0x7622)}, + {USB_DEVICE(0x0DF6, 0x0045)}, + {USB_DEVICE(0x0E66, 0x0015)}, + {USB_DEVICE(0x0E66, 0x0016)}, + {USB_DEVICE(0x0b05, 0x1786)}, + /* these are not in the official list */ + {USB_DEVICE(0x0df6, 0x004b)}, /* WL-349 */ {} }; diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 2bede271a2f0..f38472c2e75c 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -121,6 +121,8 @@ static const struct usb_device_id rtl8192_usb_id_tbl[] = { {USB_DEVICE(0x2001, 0x3301)}, /* Zinwell */ {USB_DEVICE(0x5a57, 0x0290)}, + /* LG */ + {USB_DEVICE(0x043e, 0x7a01)}, {} }; diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c index 52408164036f..6a499f0eb594 100644 --- a/drivers/staging/usbip/usbip_common.c +++ b/drivers/staging/usbip/usbip_common.c @@ -378,47 +378,67 @@ int usbip_thread(void *param) complete_and_exit(&ut->thread_done, 0); } +static void stop_rx_thread(struct usbip_device *ud) +{ + if (ud->tcp_rx.thread != NULL) { + send_sig(SIGKILL, ud->tcp_rx.thread, 1); + wait_for_completion(&ud->tcp_rx.thread_done); + usbip_udbg("rx_thread for ud %p has finished\n", ud); + } +} + +static void stop_tx_thread(struct usbip_device *ud) +{ + if (ud->tcp_tx.thread != NULL) { + send_sig(SIGKILL, ud->tcp_tx.thread, 1); + wait_for_completion(&ud->tcp_tx.thread_done); + usbip_udbg("tx_thread for ud %p has finished\n", ud); + } +} + int usbip_start_threads(struct usbip_device *ud) { /* * threads are invoked per one device (per one connection). */ struct task_struct *th; + int err = 0; th = kthread_run(usbip_thread, (void *)&ud->tcp_rx, "usbip"); if (IS_ERR(th)) { printk(KERN_WARNING "Unable to start control thread\n"); - return PTR_ERR(th); + err = PTR_ERR(th); + goto ust_exit; } + th = kthread_run(usbip_thread, (void *)&ud->tcp_tx, "usbip"); if (IS_ERR(th)) { printk(KERN_WARNING "Unable to start control thread\n"); - return PTR_ERR(th); + err = PTR_ERR(th); + goto tx_thread_err; } /* confirm threads are starting */ wait_for_completion(&ud->tcp_rx.thread_done); wait_for_completion(&ud->tcp_tx.thread_done); + return 0; + +tx_thread_err: + stop_rx_thread(ud); + +ust_exit: + return err; } EXPORT_SYMBOL_GPL(usbip_start_threads); void usbip_stop_threads(struct usbip_device *ud) { /* kill threads related to this sdev, if v.c. exists */ - if (ud->tcp_rx.thread != NULL) { - send_sig(SIGKILL, ud->tcp_rx.thread, 1); - wait_for_completion(&ud->tcp_rx.thread_done); - usbip_udbg("rx_thread for ud %p has finished\n", ud); - } - - if (ud->tcp_tx.thread != NULL) { - send_sig(SIGKILL, ud->tcp_tx.thread, 1); - wait_for_completion(&ud->tcp_tx.thread_done); - usbip_udbg("tx_thread for ud %p has finished\n", ud); - } + stop_rx_thread(ud); + stop_tx_thread(ud); } EXPORT_SYMBOL_GPL(usbip_stop_threads); diff --git a/drivers/staging/wlags49_h2/wl_enc.c b/drivers/staging/wlags49_h2/wl_enc.c index 48c44c8fdb28..26cf5486edd6 100644 --- a/drivers/staging/wlags49_h2/wl_enc.c +++ b/drivers/staging/wlags49_h2/wl_enc.c @@ -62,6 +62,7 @@ /******************************************************************************* * include files ******************************************************************************/ +#include <linux/string.h> #include <wl_version.h> #include <debug.h> diff --git a/drivers/staging/wlags49_h2/wl_sysfs.h b/drivers/staging/wlags49_h2/wl_sysfs.h index 6d96d03cf490..fa658c38001e 100644 --- a/drivers/staging/wlags49_h2/wl_sysfs.h +++ b/drivers/staging/wlags49_h2/wl_sysfs.h @@ -2,6 +2,6 @@ extern void register_wlags_sysfs(struct net_device *); extern void unregister_wlags_sysfs(struct net_device *); #else -static void register_wlags_sysfs(struct net_device *) { return; }; -static void unregister_wlags_sysfs(struct net_device *) { return; }; +static inline void register_wlags_sysfs(struct net_device *net) { } +static inline void unregister_wlags_sysfs(struct net_device *net) { } #endif diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index de98a94d1853..a6bd53ace035 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1272,8 +1272,7 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) static void choose_wakeup(struct usb_device *udev, pm_message_t msg) { - int w, i; - struct usb_interface *intf; + int w; /* Remote wakeup is needed only when we actually go to sleep. * For things like FREEZE and QUIESCE, if the device is already @@ -1285,16 +1284,10 @@ static void choose_wakeup(struct usb_device *udev, pm_message_t msg) return; } - /* If remote wakeup is permitted, see whether any interface drivers + /* Enable remote wakeup if it is allowed, even if no interface drivers * actually want it. */ - w = 0; - if (device_may_wakeup(&udev->dev) && udev->actconfig) { - for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { - intf = udev->actconfig->interface[i]; - w |= intf->needs_remote_wakeup; - } - } + w = device_may_wakeup(&udev->dev); /* If the device is autosuspended with the wrong wakeup setting, * autoresume now so the setting can be changed. diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index a73e08fdab36..fd4c36ea5e46 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -416,8 +416,11 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, /* A length of zero means transfer the whole sg list */ len = length; if (len == 0) { - for_each_sg(sg, sg, nents, i) - len += sg->length; + struct scatterlist *sg2; + int j; + + for_each_sg(sg, sg2, nents, j) + len += sg2->length; } } else { /* diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c index 38226e9a371d..95dd4662d6a8 100644 --- a/drivers/usb/gadget/f_eem.c +++ b/drivers/usb/gadget/f_eem.c @@ -469,8 +469,7 @@ static int eem_unwrap(struct gether *port, crc = get_unaligned_le32(skb->data + len - ETH_FCS_LEN); crc2 = ~crc32_le(~0, - skb->data, - skb->len - ETH_FCS_LEN); + skb->data, len - ETH_FCS_LEN); } else { crc = get_unaligned_be32(skb->data + len - ETH_FCS_LEN); diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 7d05a0be5c60..4ce899c9b165 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -321,8 +321,8 @@ struct fsg_dev; /* Data shared by all the FSG instances. */ struct fsg_common { struct usb_gadget *gadget; - struct fsg_dev *fsg; - struct fsg_dev *prev_fsg; + struct fsg_dev *fsg, *new_fsg; + wait_queue_head_t fsg_wait; /* filesem protects: backing files in use */ struct rw_semaphore filesem; @@ -351,7 +351,6 @@ struct fsg_common { enum fsg_state state; /* For exception handling */ unsigned int exception_req_tag; - u8 config, new_config; enum data_direction data_dir; u32 data_size; u32 data_size_from_cmnd; @@ -595,7 +594,7 @@ static int fsg_setup(struct usb_function *f, u16 w_value = le16_to_cpu(ctrl->wValue); u16 w_length = le16_to_cpu(ctrl->wLength); - if (!fsg->common->config) + if (!fsg_is_set(fsg->common)) return -EOPNOTSUPP; switch (ctrl->bRequest) { @@ -2303,24 +2302,20 @@ static int alloc_request(struct fsg_common *common, struct usb_ep *ep, return -ENOMEM; } -/* - * Reset interface setting and re-init endpoint state (toggle etc). - * Call with altsetting < 0 to disable the interface. The only other - * available altsetting is 0, which enables the interface. - */ -static int do_set_interface(struct fsg_common *common, int altsetting) +/* Reset interface setting and re-init endpoint state (toggle etc). */ +static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg) { - int rc = 0; - int i; - const struct usb_endpoint_descriptor *d; + const struct usb_endpoint_descriptor *d; + struct fsg_dev *fsg; + int i, rc = 0; if (common->running) DBG(common, "reset interface\n"); reset: /* Deallocate the requests */ - if (common->prev_fsg) { - struct fsg_dev *fsg = common->prev_fsg; + if (common->fsg) { + fsg = common->fsg; for (i = 0; i < FSG_NUM_BUFFERS; ++i) { struct fsg_buffhd *bh = &common->buffhds[i]; @@ -2345,88 +2340,53 @@ reset: fsg->bulk_out_enabled = 0; } - common->prev_fsg = 0; + common->fsg = NULL; + wake_up(&common->fsg_wait); } common->running = 0; - if (altsetting < 0 || rc != 0) + if (!new_fsg || rc) return rc; - DBG(common, "set interface %d\n", altsetting); + common->fsg = new_fsg; + fsg = common->fsg; - if (fsg_is_set(common)) { - struct fsg_dev *fsg = common->fsg; - common->prev_fsg = common->fsg; + /* Enable the endpoints */ + d = fsg_ep_desc(common->gadget, + &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc); + rc = enable_endpoint(common, fsg->bulk_in, d); + if (rc) + goto reset; + fsg->bulk_in_enabled = 1; + + d = fsg_ep_desc(common->gadget, + &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc); + rc = enable_endpoint(common, fsg->bulk_out, d); + if (rc) + goto reset; + fsg->bulk_out_enabled = 1; + common->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize); + clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); - /* Enable the endpoints */ - d = fsg_ep_desc(common->gadget, - &fsg_fs_bulk_in_desc, &fsg_hs_bulk_in_desc); - rc = enable_endpoint(common, fsg->bulk_in, d); + /* Allocate the requests */ + for (i = 0; i < FSG_NUM_BUFFERS; ++i) { + struct fsg_buffhd *bh = &common->buffhds[i]; + + rc = alloc_request(common, fsg->bulk_in, &bh->inreq); if (rc) goto reset; - fsg->bulk_in_enabled = 1; - - d = fsg_ep_desc(common->gadget, - &fsg_fs_bulk_out_desc, &fsg_hs_bulk_out_desc); - rc = enable_endpoint(common, fsg->bulk_out, d); + rc = alloc_request(common, fsg->bulk_out, &bh->outreq); if (rc) goto reset; - fsg->bulk_out_enabled = 1; - common->bulk_out_maxpacket = le16_to_cpu(d->wMaxPacketSize); - clear_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags); - - /* Allocate the requests */ - for (i = 0; i < FSG_NUM_BUFFERS; ++i) { - struct fsg_buffhd *bh = &common->buffhds[i]; - - rc = alloc_request(common, fsg->bulk_in, &bh->inreq); - if (rc) - goto reset; - rc = alloc_request(common, fsg->bulk_out, &bh->outreq); - if (rc) - goto reset; - bh->inreq->buf = bh->outreq->buf = bh->buf; - bh->inreq->context = bh->outreq->context = bh; - bh->inreq->complete = bulk_in_complete; - bh->outreq->complete = bulk_out_complete; - } - - common->running = 1; - for (i = 0; i < common->nluns; ++i) - common->luns[i].unit_attention_data = SS_RESET_OCCURRED; - return rc; - } else { - return -EIO; - } -} - - -/* - * Change our operational configuration. This code must agree with the code - * that returns config descriptors, and with interface altsetting code. - * - * It's also responsible for power management interactions. Some - * configurations might not work with our current power sources. - * For now we just assume the gadget is always self-powered. - */ -static int do_set_config(struct fsg_common *common, u8 new_config) -{ - int rc = 0; - - /* Disable the single interface */ - if (common->config != 0) { - DBG(common, "reset config\n"); - common->config = 0; - rc = do_set_interface(common, -1); + bh->inreq->buf = bh->outreq->buf = bh->buf; + bh->inreq->context = bh->outreq->context = bh; + bh->inreq->complete = bulk_in_complete; + bh->outreq->complete = bulk_out_complete; } - /* Enable the interface */ - if (new_config != 0) { - common->config = new_config; - rc = do_set_interface(common, 0); - if (rc != 0) - common->config = 0; /* Reset on errors */ - } + common->running = 1; + for (i = 0; i < common->nluns; ++i) + common->luns[i].unit_attention_data = SS_RESET_OCCURRED; return rc; } @@ -2437,9 +2397,7 @@ static int do_set_config(struct fsg_common *common, u8 new_config) static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct fsg_dev *fsg = fsg_from_func(f); - fsg->common->prev_fsg = fsg->common->fsg; - fsg->common->fsg = fsg; - fsg->common->new_config = 1; + fsg->common->new_fsg = fsg; raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); return 0; } @@ -2447,9 +2405,7 @@ static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) static void fsg_disable(struct usb_function *f) { struct fsg_dev *fsg = fsg_from_func(f); - fsg->common->prev_fsg = fsg->common->fsg; - fsg->common->fsg = fsg; - fsg->common->new_config = 0; + fsg->common->new_fsg = NULL; raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); } @@ -2459,19 +2415,17 @@ static void fsg_disable(struct usb_function *f) static void handle_exception(struct fsg_common *common) { siginfo_t info; - int sig; int i; struct fsg_buffhd *bh; enum fsg_state old_state; - u8 new_config; struct fsg_lun *curlun; unsigned int exception_req_tag; - int rc; /* Clear the existing signals. Anything but SIGUSR1 is converted * into a high-priority EXIT exception. */ for (;;) { - sig = dequeue_signal_lock(current, ¤t->blocked, &info); + int sig = + dequeue_signal_lock(current, ¤t->blocked, &info); if (!sig) break; if (sig != SIGUSR1) { @@ -2482,7 +2436,7 @@ static void handle_exception(struct fsg_common *common) } /* Cancel all the pending transfers */ - if (fsg_is_set(common)) { + if (likely(common->fsg)) { for (i = 0; i < FSG_NUM_BUFFERS; ++i) { bh = &common->buffhds[i]; if (bh->inreq_busy) @@ -2523,7 +2477,6 @@ static void handle_exception(struct fsg_common *common) common->next_buffhd_to_fill = &common->buffhds[0]; common->next_buffhd_to_drain = &common->buffhds[0]; exception_req_tag = common->exception_req_tag; - new_config = common->new_config; old_state = common->state; if (old_state == FSG_STATE_ABORT_BULK_OUT) @@ -2573,12 +2526,12 @@ static void handle_exception(struct fsg_common *common) break; case FSG_STATE_CONFIG_CHANGE: - rc = do_set_config(common, new_config); + do_set_interface(common, common->new_fsg); break; case FSG_STATE_EXIT: case FSG_STATE_TERMINATED: - do_set_config(common, 0); /* Free resources */ + do_set_interface(common, NULL); /* Free resources */ spin_lock_irq(&common->lock); common->state = FSG_STATE_TERMINATED; /* Stop the thread */ spin_unlock_irq(&common->lock); @@ -2863,6 +2816,7 @@ buffhds_first_it: goto error_release; } init_completion(&common->thread_notifier); + init_waitqueue_head(&common->fsg_wait); #undef OR @@ -2957,9 +2911,17 @@ static void fsg_common_release(struct kref *ref) static void fsg_unbind(struct usb_configuration *c, struct usb_function *f) { struct fsg_dev *fsg = fsg_from_func(f); + struct fsg_common *common = fsg->common; DBG(fsg, "unbind\n"); - fsg_common_put(fsg->common); + if (fsg->common->fsg == fsg) { + fsg->common->new_fsg = NULL; + raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); + /* FIXME: make interruptible or killable somehow? */ + wait_event(common->fsg_wait, common->fsg != fsg); + } + + fsg_common_put(common); usb_free_descriptors(fsg->function.descriptors); usb_free_descriptors(fsg->function.hs_descriptors); kfree(fsg); @@ -2970,7 +2932,6 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) { struct fsg_dev *fsg = fsg_from_func(f); struct usb_gadget *gadget = c->cdev->gadget; - int rc; int i; struct usb_ep *ep; @@ -2996,6 +2957,11 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) ep->driver_data = fsg->common; /* claim the endpoint */ fsg->bulk_out = ep; + /* Copy descriptors */ + f->descriptors = usb_copy_descriptors(fsg_fs_function); + if (unlikely(!f->descriptors)) + return -ENOMEM; + if (gadget_is_dualspeed(gadget)) { /* Assume endpoint addresses are the same for both speeds */ fsg_hs_bulk_in_desc.bEndpointAddress = @@ -3003,16 +2969,17 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) fsg_hs_bulk_out_desc.bEndpointAddress = fsg_fs_bulk_out_desc.bEndpointAddress; f->hs_descriptors = usb_copy_descriptors(fsg_hs_function); - if (unlikely(!f->hs_descriptors)) + if (unlikely(!f->hs_descriptors)) { + usb_free_descriptors(f->descriptors); return -ENOMEM; + } } return 0; autoconf_fail: ERROR(fsg, "unable to autoconfigure all endpoints\n"); - rc = -ENOTSUPP; - return rc; + return -ENOTSUPP; } @@ -3036,11 +3003,6 @@ static int fsg_add(struct usb_composite_dev *cdev, fsg->function.name = FSG_DRIVER_DESC; fsg->function.strings = fsg_strings_array; - fsg->function.descriptors = usb_copy_descriptors(fsg_fs_function); - if (unlikely(!fsg->function.descriptors)) { - rc = -ENOMEM; - goto error_free_fsg; - } fsg->function.bind = fsg_bind; fsg->function.unbind = fsg_unbind; fsg->function.setup = fsg_setup; @@ -3056,19 +3018,9 @@ static int fsg_add(struct usb_composite_dev *cdev, rc = usb_add_function(c, &fsg->function); if (unlikely(rc)) - goto error_free_all; - - fsg_common_get(fsg->common); - return 0; - -error_free_all: - usb_free_descriptors(fsg->function.descriptors); - /* fsg_bind() might have copied those; or maybe not? who cares - * -- free it just in case. */ - usb_free_descriptors(fsg->function.hs_descriptors); -error_free_fsg: - kfree(fsg); - + kfree(fsg); + else + fsg_common_get(fsg->common); return rc; } diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 4b0e4a040d6f..d1af253a9105 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -392,6 +392,17 @@ static int __gfs_do_config(struct usb_configuration *c, if (unlikely(ret < 0)) return ret; + /* After previous do_configs there may be some invalid + * pointers in c->interface array. This happens every time + * a user space function with fewer interfaces than a user + * space function that was run before the new one is run. The + * compasit's set_config() assumes that if there is no more + * then MAX_CONFIG_INTERFACES interfaces in a configuration + * then there is a NULL pointer after the last interface in + * c->interface array. We need to make sure this is true. */ + if (c->next_interface_id < ARRAY_SIZE(c->interface)) + c->interface[c->next_interface_id] = NULL; + return 0; } diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 43abf55d8c60..4c3ac5c42237 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -82,7 +82,7 @@ static struct class *usb_gadget_class; struct printer_dev { spinlock_t lock; /* lock this structure */ /* lock buffer lists during read/write calls */ - spinlock_t lock_printer_io; + struct mutex lock_printer_io; struct usb_gadget *gadget; struct usb_request *req; /* for control responses */ u8 config; @@ -567,7 +567,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) DBG(dev, "printer_read trying to read %d bytes\n", (int)len); - spin_lock(&dev->lock_printer_io); + mutex_lock(&dev->lock_printer_io); spin_lock_irqsave(&dev->lock, flags); /* We will use this flag later to check if a printer reset happened @@ -601,7 +601,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) * call or not. */ if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { - spin_unlock(&dev->lock_printer_io); + mutex_unlock(&dev->lock_printer_io); return -EAGAIN; } @@ -648,7 +648,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) if (dev->reset_printer) { list_add(¤t_rx_req->list, &dev->rx_reqs); spin_unlock_irqrestore(&dev->lock, flags); - spin_unlock(&dev->lock_printer_io); + mutex_unlock(&dev->lock_printer_io); return -EAGAIN; } @@ -673,7 +673,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr) dev->current_rx_buf = current_rx_buf; spin_unlock_irqrestore(&dev->lock, flags); - spin_unlock(&dev->lock_printer_io); + mutex_unlock(&dev->lock_printer_io); DBG(dev, "printer_read returned %d bytes\n", (int)bytes_copied); @@ -697,7 +697,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) if (len == 0) return -EINVAL; - spin_lock(&dev->lock_printer_io); + mutex_lock(&dev->lock_printer_io); spin_lock_irqsave(&dev->lock, flags); /* Check if a printer reset happens while we have interrupts on */ @@ -713,7 +713,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) * a NON-Blocking call or not. */ if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) { - spin_unlock(&dev->lock_printer_io); + mutex_unlock(&dev->lock_printer_io); return -EAGAIN; } @@ -752,7 +752,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) if (copy_from_user(req->buf, buf, size)) { list_add(&req->list, &dev->tx_reqs); - spin_unlock(&dev->lock_printer_io); + mutex_unlock(&dev->lock_printer_io); return bytes_copied; } @@ -766,14 +766,14 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) if (dev->reset_printer) { list_add(&req->list, &dev->tx_reqs); spin_unlock_irqrestore(&dev->lock, flags); - spin_unlock(&dev->lock_printer_io); + mutex_unlock(&dev->lock_printer_io); return -EAGAIN; } if (usb_ep_queue(dev->in_ep, req, GFP_ATOMIC)) { list_add(&req->list, &dev->tx_reqs); spin_unlock_irqrestore(&dev->lock, flags); - spin_unlock(&dev->lock_printer_io); + mutex_unlock(&dev->lock_printer_io); return -EAGAIN; } @@ -782,7 +782,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr) } spin_unlock_irqrestore(&dev->lock, flags); - spin_unlock(&dev->lock_printer_io); + mutex_unlock(&dev->lock_printer_io); DBG(dev, "printer_write sent %d bytes\n", (int)bytes_copied); @@ -820,11 +820,11 @@ printer_poll(struct file *fd, poll_table *wait) unsigned long flags; int status = 0; - spin_lock(&dev->lock_printer_io); + mutex_lock(&dev->lock_printer_io); spin_lock_irqsave(&dev->lock, flags); setup_rx_reqs(dev); spin_unlock_irqrestore(&dev->lock, flags); - spin_unlock(&dev->lock_printer_io); + mutex_unlock(&dev->lock_printer_io); poll_wait(fd, &dev->rx_wait, wait); poll_wait(fd, &dev->tx_wait, wait); @@ -1461,7 +1461,7 @@ autoconf_fail: } spin_lock_init(&dev->lock); - spin_lock_init(&dev->lock_printer_io); + mutex_init(&dev->lock_printer_io); INIT_LIST_HEAD(&dev->tx_reqs); INIT_LIST_HEAD(&dev->tx_reqs_active); INIT_LIST_HEAD(&dev->rx_reqs); @@ -1594,7 +1594,7 @@ cleanup(void) { int status; - spin_lock(&usb_printer_gadget.lock_printer_io); + mutex_lock(&usb_printer_gadget.lock_printer_io); class_destroy(usb_gadget_class); unregister_chrdev_region(g_printer_devno, 2); @@ -1602,6 +1602,6 @@ cleanup(void) if (status) ERROR(dev, "usb_gadget_unregister_driver %x\n", status); - spin_unlock(&usb_printer_gadget.lock_printer_io); + mutex_unlock(&usb_printer_gadget.lock_printer_io); } module_exit(cleanup); diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index d5f4c1d45c97..e724a051bfdd 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1700,9 +1700,13 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) if (!driver || driver != udc->driver || !driver->unbind) return -EINVAL; - dprintk(DEBUG_NORMAL,"usb_gadget_register_driver() '%s'\n", + dprintk(DEBUG_NORMAL, "usb_gadget_unregister_driver() '%s'\n", driver->driver.name); + /* report disconnect */ + if (driver->disconnect) + driver->disconnect(&udc->gadget); + driver->unbind(&udc->gadget); device_del(&udc->gadget.dev); diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 16bdf77f582a..3e8dcb5455e3 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -536,17 +536,11 @@ recycle: list_move(&req->list, &port->read_pool); } - /* Push from tty to ldisc; this is immediate with low_latency, and - * may trigger callbacks to this driver ... so drop the spinlock. + /* Push from tty to ldisc; without low_latency set this is handled by + * a workqueue, so we won't get callbacks and can hold port_lock */ if (tty && do_push) { - spin_unlock_irq(&port->port_lock); tty_flip_buffer_push(tty); - wake_up_interruptible(&tty->read_wait); - spin_lock_irq(&port->port_lock); - - /* tty may have been closed */ - tty = port->port_tty; } @@ -784,11 +778,6 @@ static int gs_open(struct tty_struct *tty, struct file *file) port->open_count = 1; port->openclose = false; - /* low_latency means ldiscs work in tasklet context, without - * needing a workqueue schedule ... easier to keep up. - */ - tty->low_latency = 1; - /* if connected, start the I/O stream */ if (port->port_usb) { struct gserial *gser = port->port_usb; @@ -1195,6 +1184,7 @@ void gserial_cleanup(void) n_ports = 0; tty_unregister_driver(gs_tty_driver); + put_tty_driver(gs_tty_driver); gs_tty_driver = NULL; pr_debug("%s: cleaned up ttyGS* support\n", __func__); diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index 544ccfd7056e..bd4027745aa7 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -207,10 +207,17 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) /* Initialize the transceiver */ if (pdata->otg) { pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET; - if (otg_init(pdata->otg) != 0) - dev_err(dev, "unable to init transceiver\n"); - else if (otg_set_vbus(pdata->otg, 1) != 0) + ret = otg_init(pdata->otg); + if (ret) { + dev_err(dev, "unable to init transceiver, probably missing\n"); + ret = -ENODEV; + goto err_add; + } + ret = otg_set_vbus(pdata->otg, 1); + if (ret) { dev_err(dev, "unable to enable vbus on transceiver\n"); + goto err_add; + } } priv->hcd = hcd; diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 20a0dfe0fe36..0587ad4ce5c2 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -2224,12 +2224,9 @@ static void remove_debug_file(struct isp1362_hcd *isp1362_hcd) /*-------------------------------------------------------------------------*/ -static void isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd) +static void __isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd) { int tmp = 20; - unsigned long flags; - - spin_lock_irqsave(&isp1362_hcd->lock, flags); isp1362_write_reg16(isp1362_hcd, HCSWRES, HCSWRES_MAGIC); isp1362_write_reg32(isp1362_hcd, HCCMDSTAT, OHCI_HCR); @@ -2240,6 +2237,14 @@ static void isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd) } if (!tmp) pr_err("Software reset timeout\n"); +} + +static void isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd) +{ + unsigned long flags; + + spin_lock_irqsave(&isp1362_hcd->lock, flags); + __isp1362_sw_reset(isp1362_hcd); spin_unlock_irqrestore(&isp1362_hcd->lock, flags); } @@ -2418,7 +2423,7 @@ static void isp1362_hc_stop(struct usb_hcd *hcd) if (isp1362_hcd->board && isp1362_hcd->board->reset) isp1362_hcd->board->reset(hcd->self.controller, 1); else - isp1362_sw_reset(isp1362_hcd); + __isp1362_sw_reset(isp1362_hcd); if (isp1362_hcd->board && isp1362_hcd->board->clock) isp1362_hcd->board->clock(hcd->self.controller, 0); diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 1a2bb4ce638f..77be3c24a427 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -1065,7 +1065,7 @@ static void r8a66597_usb_connect(struct r8a66597 *r8a66597, int port) else if (speed == LSMODE) rh->port |= USB_PORT_STAT_LOW_SPEED; - rh->port &= USB_PORT_STAT_RESET; + rh->port &= ~USB_PORT_STAT_RESET; rh->port |= USB_PORT_STAT_ENABLE; } diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 9012098add6b..94e6934edb09 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -182,8 +182,12 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer * set, but other sections talk about dealing with the chain bit set. This was * fixed in the 0.96 specification errata, but we have to assume that all 0.95 * xHCI hardware can't handle the chain bit being cleared on a link TRB. + * + * @more_trbs_coming: Will you enqueue more TRBs before calling + * prepare_transfer()? */ -static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer) +static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, + bool consumer, bool more_trbs_coming) { u32 chain; union xhci_trb *next; @@ -199,15 +203,28 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer while (last_trb(xhci, ring, ring->enq_seg, next)) { if (!consumer) { if (ring != xhci->event_ring) { - if (chain) { - next->link.control |= TRB_CHAIN; - - /* Give this link TRB to the hardware */ - wmb(); - next->link.control ^= TRB_CYCLE; - } else { + /* + * If the caller doesn't plan on enqueueing more + * TDs before ringing the doorbell, then we + * don't want to give the link TRB to the + * hardware just yet. We'll give the link TRB + * back in prepare_ring() just before we enqueue + * the TD at the top of the ring. + */ + if (!chain && !more_trbs_coming) break; + + /* If we're not dealing with 0.95 hardware, + * carry over the chain bit of the previous TRB + * (which may mean the chain bit is cleared). + */ + if (!xhci_link_trb_quirk(xhci)) { + next->link.control &= ~TRB_CHAIN; + next->link.control |= chain; } + /* Give this link TRB to the hardware */ + wmb(); + next->link.control ^= TRB_CYCLE; } /* Toggle the cycle bit after the last ring segment. */ if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) { @@ -1707,9 +1724,12 @@ void xhci_handle_event(struct xhci_hcd *xhci) /* * Generic function for queueing a TRB on a ring. * The caller must have checked to make sure there's room on the ring. + * + * @more_trbs_coming: Will you enqueue more TRBs before calling + * prepare_transfer()? */ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring, - bool consumer, + bool consumer, bool more_trbs_coming, u32 field1, u32 field2, u32 field3, u32 field4) { struct xhci_generic_trb *trb; @@ -1719,7 +1739,7 @@ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring, trb->field[1] = field2; trb->field[2] = field3; trb->field[3] = field4; - inc_enq(xhci, ring, consumer); + inc_enq(xhci, ring, consumer, more_trbs_coming); } /* @@ -1988,6 +2008,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, int trb_buff_len, this_sg_len, running_total; bool first_trb; u64 addr; + bool more_trbs_coming; struct xhci_generic_trb *start_trb; int start_cycle; @@ -2073,7 +2094,11 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, length_field = TRB_LEN(trb_buff_len) | remainder | TRB_INTR_TARGET(0); - queue_trb(xhci, ep_ring, false, + if (num_trbs > 1) + more_trbs_coming = true; + else + more_trbs_coming = false; + queue_trb(xhci, ep_ring, false, more_trbs_coming, lower_32_bits(addr), upper_32_bits(addr), length_field, @@ -2124,6 +2149,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, int num_trbs; struct xhci_generic_trb *start_trb; bool first_trb; + bool more_trbs_coming; int start_cycle; u32 field, length_field; @@ -2212,7 +2238,11 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, length_field = TRB_LEN(trb_buff_len) | remainder | TRB_INTR_TARGET(0); - queue_trb(xhci, ep_ring, false, + if (num_trbs > 1) + more_trbs_coming = true; + else + more_trbs_coming = false; + queue_trb(xhci, ep_ring, false, more_trbs_coming, lower_32_bits(addr), upper_32_bits(addr), length_field, @@ -2291,7 +2321,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, /* Queue setup TRB - see section 6.4.1.2.1 */ /* FIXME better way to translate setup_packet into two u32 fields? */ setup = (struct usb_ctrlrequest *) urb->setup_packet; - queue_trb(xhci, ep_ring, false, + queue_trb(xhci, ep_ring, false, true, /* FIXME endianness is probably going to bite my ass here. */ setup->bRequestType | setup->bRequest << 8 | setup->wValue << 16, setup->wIndex | setup->wLength << 16, @@ -2307,7 +2337,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, if (urb->transfer_buffer_length > 0) { if (setup->bRequestType & USB_DIR_IN) field |= TRB_DIR_IN; - queue_trb(xhci, ep_ring, false, + queue_trb(xhci, ep_ring, false, true, lower_32_bits(urb->transfer_dma), upper_32_bits(urb->transfer_dma), length_field, @@ -2324,7 +2354,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, field = 0; else field = TRB_DIR_IN; - queue_trb(xhci, ep_ring, false, + queue_trb(xhci, ep_ring, false, false, 0, 0, TRB_INTR_TARGET(0), @@ -2361,7 +2391,7 @@ static int queue_command(struct xhci_hcd *xhci, u32 field1, u32 field2, "unfailable commands failed.\n"); return -ENOMEM; } - queue_trb(xhci, xhci->cmd_ring, false, field1, field2, field3, + queue_trb(xhci, xhci->cmd_ring, false, false, field1, field2, field3, field4 | xhci->cmd_ring->cycle_state); return 0; } diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index fad70bc83555..3b795c56221f 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -219,8 +219,8 @@ static int musb_ulpi_write(struct otg_transceiver *otg, return 0; } #else -#define musb_ulpi_read(a, b) NULL -#define musb_ulpi_write(a, b, c) NULL +#define musb_ulpi_read NULL +#define musb_ulpi_write NULL #endif static struct otg_io_access_ops musb_ulpi_access = { @@ -451,10 +451,6 @@ void musb_hnp_stop(struct musb *musb) * @param power */ -#define STAGE0_MASK (MUSB_INTR_RESUME | MUSB_INTR_SESSREQ \ - | MUSB_INTR_VBUSERROR | MUSB_INTR_CONNECT \ - | MUSB_INTR_RESET) - static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, u8 devctl, u8 power) { @@ -642,7 +638,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, handled = IRQ_HANDLED; } - +#endif if (int_usb & MUSB_INTR_SUSPEND) { DBG(1, "SUSPEND (%s) devctl %02x power %02x\n", otg_state_string(musb), devctl, power); @@ -705,6 +701,7 @@ static irqreturn_t musb_stage0_irq(struct musb *musb, u8 int_usb, } } +#ifdef CONFIG_USB_MUSB_HDRC_HCD if (int_usb & MUSB_INTR_CONNECT) { struct usb_hcd *hcd = musb_to_hcd(musb); void __iomem *mbase = musb->mregs; @@ -1597,7 +1594,7 @@ irqreturn_t musb_interrupt(struct musb *musb) /* the core can interrupt us for multiple reasons; docs have * a generic interrupt flowchart to follow */ - if (musb->int_usb & STAGE0_MASK) + if (musb->int_usb) retval |= musb_stage0_irq(musb, musb->int_usb, devctl, power); diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index b22d02dea7d3..91d67794e350 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h @@ -470,7 +470,8 @@ struct musb_csr_regs { struct musb_context_registers { -#ifdef CONFIG_PM +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ + defined(CONFIG_ARCH_OMAP4) u32 otg_sysconfig, otg_forcestandby; #endif u8 power; @@ -484,7 +485,8 @@ struct musb_context_registers { struct musb_csr_regs index_regs[MUSB_C_NUM_EPS]; }; -#ifdef CONFIG_PM +#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) || \ + defined(CONFIG_ARCH_OMAP4) extern void musb_platform_save_context(struct musb *musb, struct musb_context_registers *musb_context); extern void musb_platform_restore_context(struct musb *musb, diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 1008044a3bbc..dc66e4376d49 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c @@ -132,18 +132,9 @@ static void configure_channel(struct dma_channel *channel, if (mode) { csr |= 1 << MUSB_HSDMA_MODE1_SHIFT; BUG_ON(len < packet_sz); - - if (packet_sz >= 64) { - csr |= MUSB_HSDMA_BURSTMODE_INCR16 - << MUSB_HSDMA_BURSTMODE_SHIFT; - } else if (packet_sz >= 32) { - csr |= MUSB_HSDMA_BURSTMODE_INCR8 - << MUSB_HSDMA_BURSTMODE_SHIFT; - } else if (packet_sz >= 16) { - csr |= MUSB_HSDMA_BURSTMODE_INCR4 - << MUSB_HSDMA_BURSTMODE_SHIFT; - } } + csr |= MUSB_HSDMA_BURSTMODE_INCR16 + << MUSB_HSDMA_BURSTMODE_SHIFT; csr |= (musb_channel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT) | (1 << MUSB_HSDMA_ENABLE_SHIFT) diff --git a/drivers/usb/otg/ulpi.c b/drivers/usb/otg/ulpi.c index b1b346932946..d331b222ad21 100644 --- a/drivers/usb/otg/ulpi.c +++ b/drivers/usb/otg/ulpi.c @@ -59,12 +59,17 @@ static int ulpi_set_flags(struct otg_transceiver *otg) static int ulpi_init(struct otg_transceiver *otg) { - int i, vid, pid; - - vid = (otg_io_read(otg, ULPI_VENDOR_ID_HIGH) << 8) | - otg_io_read(otg, ULPI_VENDOR_ID_LOW); - pid = (otg_io_read(otg, ULPI_PRODUCT_ID_HIGH) << 8) | - otg_io_read(otg, ULPI_PRODUCT_ID_LOW); + int i, vid, pid, ret; + u32 ulpi_id = 0; + + for (i = 0; i < 4; i++) { + ret = otg_io_read(otg, ULPI_PRODUCT_ID_HIGH - i); + if (ret < 0) + return ret; + ulpi_id = (ulpi_id << 8) | ret; + } + vid = ulpi_id & 0xffff; + pid = ulpi_id >> 16; pr_info("ULPI transceiver vendor/product ID 0x%04x/0x%04x\n", vid, pid); diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 79dd1ae195e5..da7e334b0407 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -653,7 +653,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, - { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 94d86c3febcb..bbc159a1df45 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -501,13 +501,6 @@ #define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ /* - * Contec products (http://www.contec.com) - * Submitted by Daniel Sangorrin - */ -#define CONTEC_VID 0x06CE /* Vendor ID */ -#define CONTEC_COM1USBH_PID 0x8311 /* COM-1(USB)H */ - -/* * Definitions for B&B Electronics products. */ #define BANDB_VID 0x0856 /* B&B Electronics Vendor ID */ diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 04bb759536bb..93d72eb8cafc 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -139,6 +139,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) "Could not set interface, error %d\n", retval); retval = -ENODEV; + kfree(data); } return retval; } @@ -155,6 +156,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) "Could not set interface, error %d\n", retval); retval = -ENODEV; + kfree(data); } return retval; } @@ -163,6 +165,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) default: dev_err(&serial->dev->dev, "unknown number of interfaces: %d\n", nintf); + kfree(data); return -ENODEV; } diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c index 76e7dac6f259..70b1d9d51c96 100644 --- a/drivers/video/geode/gxfb_core.c +++ b/drivers/video/geode/gxfb_core.c @@ -40,7 +40,7 @@ static int vram; static int vt_switch; /* Modes relevant to the GX (taken from modedb.c) */ -static struct fb_videomode gx_modedb[] __initdata = { +static struct fb_videomode gx_modedb[] __devinitdata = { /* 640x480-60 VESA */ { NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2, 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, @@ -110,14 +110,15 @@ static struct fb_videomode gx_modedb[] __initdata = { #ifdef CONFIG_OLPC #include <asm/olpc.h> -static struct fb_videomode gx_dcon_modedb[] __initdata = { +static struct fb_videomode gx_dcon_modedb[] __devinitdata = { /* The only mode the DCON has is 1200x900 */ { NULL, 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0 } }; -static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size) +static void __devinit get_modedb(struct fb_videomode **modedb, + unsigned int *size) { if (olpc_has_dcon()) { *modedb = (struct fb_videomode *) gx_dcon_modedb; @@ -129,7 +130,8 @@ static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size) } #else -static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size) +static void __devinit get_modedb(struct fb_videomode **modedb, + unsigned int *size) { *modedb = (struct fb_videomode *) gx_modedb; *size = ARRAY_SIZE(gx_modedb); @@ -226,7 +228,8 @@ static int gxfb_blank(int blank_mode, struct fb_info *info) return gx_blank_display(info, blank_mode); } -static int __init gxfb_map_video_memory(struct fb_info *info, struct pci_dev *dev) +static int __devinit gxfb_map_video_memory(struct fb_info *info, + struct pci_dev *dev) { struct gxfb_par *par = info->par; int ret; @@ -290,7 +293,7 @@ static struct fb_ops gxfb_ops = { .fb_imageblit = cfb_imageblit, }; -static struct fb_info * __init gxfb_init_fbinfo(struct device *dev) +static struct fb_info *__devinit gxfb_init_fbinfo(struct device *dev) { struct gxfb_par *par; struct fb_info *info; @@ -371,7 +374,8 @@ static int gxfb_resume(struct pci_dev *pdev) } #endif -static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id) +static int __devinit gxfb_probe(struct pci_dev *pdev, + const struct pci_device_id *id) { struct gxfb_par *par; struct fb_info *info; @@ -451,7 +455,7 @@ static int __init gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *i return ret; } -static void gxfb_remove(struct pci_dev *pdev) +static void __devexit gxfb_remove(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); struct gxfb_par *par = info->par; diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/geode/lxfb_core.c index 1a18da86d3fa..39bdbedf43b4 100644 --- a/drivers/video/geode/lxfb_core.c +++ b/drivers/video/geode/lxfb_core.c @@ -35,7 +35,7 @@ static int vt_switch; * we try to make it something sane - 640x480-60 is sane */ -static struct fb_videomode geode_modedb[] __initdata = { +static struct fb_videomode geode_modedb[] __devinitdata = { /* 640x480-60 */ { NULL, 60, 640, 480, 39682, 48, 8, 25, 2, 88, 2, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, @@ -219,14 +219,15 @@ static struct fb_videomode geode_modedb[] __initdata = { #ifdef CONFIG_OLPC #include <asm/olpc.h> -static struct fb_videomode olpc_dcon_modedb[] __initdata = { +static struct fb_videomode olpc_dcon_modedb[] __devinitdata = { /* The only mode the DCON has is 1200x900 */ { NULL, 50, 1200, 900, 17460, 24, 8, 4, 5, 8, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 0 } }; -static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size) +static void __devinit get_modedb(struct fb_videomode **modedb, + unsigned int *size) { if (olpc_has_dcon()) { *modedb = (struct fb_videomode *) olpc_dcon_modedb; @@ -238,7 +239,8 @@ static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size) } #else -static void __init get_modedb(struct fb_videomode **modedb, unsigned int *size) +static void __devinit get_modedb(struct fb_videomode **modedb, + unsigned int *size) { *modedb = (struct fb_videomode *) geode_modedb; *size = ARRAY_SIZE(geode_modedb); @@ -334,7 +336,7 @@ static int lxfb_blank(int blank_mode, struct fb_info *info) } -static int __init lxfb_map_video_memory(struct fb_info *info, +static int __devinit lxfb_map_video_memory(struct fb_info *info, struct pci_dev *dev) { struct lxfb_par *par = info->par; @@ -412,7 +414,7 @@ static struct fb_ops lxfb_ops = { .fb_imageblit = cfb_imageblit, }; -static struct fb_info * __init lxfb_init_fbinfo(struct device *dev) +static struct fb_info * __devinit lxfb_init_fbinfo(struct device *dev) { struct lxfb_par *par; struct fb_info *info; @@ -496,7 +498,7 @@ static int lxfb_resume(struct pci_dev *pdev) #define lxfb_resume NULL #endif -static int __init lxfb_probe(struct pci_dev *pdev, +static int __devinit lxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct lxfb_par *par; @@ -588,7 +590,7 @@ err: return ret; } -static void lxfb_remove(struct pci_dev *pdev) +static void __devexit lxfb_remove(struct pci_dev *pdev) { struct fb_info *info = pci_get_drvdata(pdev); struct lxfb_par *par = info->par; diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c index d4cde79ea15e..81687ed26ba9 100644 --- a/drivers/video/nuc900fb.c +++ b/drivers/video/nuc900fb.c @@ -596,8 +596,6 @@ static int __devinit nuc900fb_probe(struct platform_device *pdev) goto release_regs; } - nuc900_driver_clksrc_div(&pdev->dev, "ext", 0x2); - fbi->clk = clk_get(&pdev->dev, NULL); if (!fbi->clk || IS_ERR(fbi->clk)) { printk(KERN_ERR "nuc900-lcd:failed to get lcd clock source\n"); diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index b6ab27ccf214..811384bec8de 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c @@ -68,11 +68,7 @@ * Here we can be a bit looser than the data sections since this * needs to only meet arch ABI requirements. */ -#ifdef ARCH_SLAB_MINALIGN -#define FLAT_STACK_ALIGN (ARCH_SLAB_MINALIGN) -#else -#define FLAT_STACK_ALIGN (sizeof(void *)) -#endif +#define FLAT_STACK_ALIGN max_t(unsigned long, sizeof(void *), ARCH_SLAB_MINALIGN) #define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */ #define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */ diff --git a/fs/fcntl.c b/fs/fcntl.c index 51e11bf5708f..9d175d623aab 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -733,12 +733,14 @@ static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band) { while (fa) { struct fown_struct *fown; + unsigned long flags; + if (fa->magic != FASYNC_MAGIC) { printk(KERN_ERR "kill_fasync: bad magic number in " "fasync_struct!\n"); return; } - spin_lock(&fa->fa_lock); + spin_lock_irqsave(&fa->fa_lock, flags); if (fa->fa_file) { fown = &fa->fa_file->f_owner; /* Don't send SIGURG to processes which have not set a @@ -747,7 +749,7 @@ static void kill_fasync_rcu(struct fasync_struct *fa, int sig, int band) if (!(sig == SIGURG && fown->signum == 0)) send_sigio(fown, fa->fa_fd, band); } - spin_unlock(&fa->fa_lock); + spin_unlock_irqrestore(&fa->fa_lock, flags); fa = rcu_dereference(fa->fa_next); } } diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index 46d4b5d72bd3..cb6306e63843 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c @@ -122,11 +122,20 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, return size; } +static void pad_len_spaces(struct seq_file *m, int len) +{ + len = 25 + sizeof(void*) * 6 - len; + if (len < 1) + len = 1; + seq_printf(m, "%*c", len, ' '); +} + /* * display a single VMA to a sequenced file */ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) { + struct mm_struct *mm = vma->vm_mm; unsigned long ino = 0; struct file *file; dev_t dev = 0; @@ -155,11 +164,14 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) MAJOR(dev), MINOR(dev), ino, &len); if (file) { - len = 25 + sizeof(void *) * 6 - len; - if (len < 1) - len = 1; - seq_printf(m, "%*c", len, ' '); + pad_len_spaces(m, len); seq_path(m, &file->f_path, ""); + } else if (mm) { + if (vma->vm_start <= mm->start_stack && + vma->vm_end >= mm->start_stack) { + pad_len_spaces(m, len); + seq_puts(m, "[stack]"); + } } seq_putc(m, '\n'); diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c index bbd69bdb0fa8..fcc498ec9b33 100644 --- a/fs/sysv/ialloc.c +++ b/fs/sysv/ialloc.c @@ -25,6 +25,7 @@ #include <linux/stat.h> #include <linux/string.h> #include <linux/buffer_head.h> +#include <linux/writeback.h> #include "sysv.h" /* We don't trust the value of @@ -139,6 +140,9 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode) struct inode *inode; sysv_ino_t ino; unsigned count; + struct writeback_control wbc = { + .sync_mode = WB_SYNC_NONE + }; inode = new_inode(sb); if (!inode) @@ -168,7 +172,7 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode) insert_inode_hash(inode); mark_inode_dirty(inode); - sysv_write_inode(inode, 0); /* ensure inode not allocated again */ + sysv_write_inode(inode, &wbc); /* ensure inode not allocated again */ mark_inode_dirty(inode); /* cleared by sysv_write_inode() */ /* That's it. */ unlock_super(sb); diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 73dcf804bc94..0da5b187f124 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -58,8 +58,12 @@ * naked functions because then mcount is called without stack and frame pointer * being set up and there is no chance to restore the lr register to the value * before mcount was called. + * + * The asm() bodies of naked functions often depend on standard calling conventions, + * therefore they must be noinline and noclone. GCC 4.[56] currently fail to enforce + * this, so we must do so ourselves. See GCC PR44290. */ -#define __naked __attribute__((naked)) notrace +#define __naked __attribute__((naked)) noinline __noclone notrace #define __noreturn __attribute__((noreturn)) @@ -85,3 +89,7 @@ #define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h) #define gcc_header(x) _gcc_header(x) #include gcc_header(__GNUC__) + +#if !defined(__noclone) +#define __noclone /* not needed */ +#endif diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h index 94dea3ffbfa1..fcfa5b9a4317 100644 --- a/include/linux/compiler-gcc4.h +++ b/include/linux/compiler-gcc4.h @@ -48,6 +48,10 @@ * unreleased. Really, we need to have autoconf for the kernel. */ #define unreachable() __builtin_unreachable() + +/* Mark a function definition as prohibited from being cloned. */ +#define __noclone __attribute__((__noclone__)) + #endif #endif diff --git a/kernel/futex.c b/kernel/futex.c index e7a35f1039e7..6a3a5fa1526d 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -429,20 +429,11 @@ static void free_pi_state(struct futex_pi_state *pi_state) static struct task_struct * futex_find_get_task(pid_t pid) { struct task_struct *p; - const struct cred *cred = current_cred(), *pcred; rcu_read_lock(); p = find_task_by_vpid(pid); - if (!p) { - p = ERR_PTR(-ESRCH); - } else { - pcred = __task_cred(p); - if (cred->euid != pcred->euid && - cred->euid != pcred->uid) - p = ERR_PTR(-ESRCH); - else - get_task_struct(p); - } + if (p) + get_task_struct(p); rcu_read_unlock(); @@ -564,8 +555,8 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, if (!pid) return -ESRCH; p = futex_find_get_task(pid); - if (IS_ERR(p)) - return PTR_ERR(p); + if (!p) + return -ESRCH; /* * We need to look at the task state flags to figure out, diff --git a/kernel/kexec.c b/kernel/kexec.c index 474a84715eac..131b1703936f 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -1089,9 +1089,10 @@ void crash_kexec(struct pt_regs *regs) size_t crash_get_memory_size(void) { - size_t size; + size_t size = 0; mutex_lock(&kexec_mutex); - size = crashk_res.end - crashk_res.start + 1; + if (crashk_res.end != crashk_res.start) + size = crashk_res.end - crashk_res.start + 1; mutex_unlock(&kexec_mutex); return size; } @@ -1134,7 +1135,7 @@ int crash_shrink_memory(unsigned long new_size) free_reserved_phys_range(end, crashk_res.end); - if (start == end) + if ((start == end) && (crashk_res.parent != NULL)) release_resource(&crashk_res); crashk_res.end = end - 1; diff --git a/lib/genalloc.c b/lib/genalloc.c index 736c3b06398e..1923f1490e72 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -128,7 +128,6 @@ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); end_bit = (chunk->end_addr - chunk->start_addr) >> order; - end_bit -= nbits + 1; spin_lock_irqsave(&chunk->lock, flags); start_bit = bitmap_find_next_zero_area(chunk->bits, end_bit, 0, diff --git a/mm/memcontrol.c b/mm/memcontrol.c index c6ece0a57595..20a8193a7af8 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1370,7 +1370,7 @@ static void memcg_wakeup_oom(struct mem_cgroup *mem) static void memcg_oom_recover(struct mem_cgroup *mem) { - if (mem->oom_kill_disable && atomic_read(&mem->oom_lock)) + if (atomic_read(&mem->oom_lock)) memcg_wakeup_oom(mem); } @@ -3781,6 +3781,8 @@ static int mem_cgroup_oom_control_write(struct cgroup *cgrp, return -EINVAL; } mem->oom_kill_disable = val; + if (!val) + memcg_oom_recover(mem); cgroup_unlock(); return 0; } diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 5d6fb339de03..5bc0a96beb51 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -2094,7 +2094,7 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol) NODEMASK_SCRATCH(scratch); if (!scratch) - return; + goto put_mpol; /* contextualize the tmpfs mount point mempolicy */ new = mpol_new(mpol->mode, mpol->flags, &mpol->w.user_nodemask); if (IS_ERR(new)) @@ -2103,19 +2103,20 @@ void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol) task_lock(current); ret = mpol_set_nodemask(new, &mpol->w.user_nodemask, scratch); task_unlock(current); - mpol_put(mpol); /* drop our ref on sb mpol */ if (ret) - goto put_free; + goto put_new; /* Create pseudo-vma that contains just the policy */ memset(&pvma, 0, sizeof(struct vm_area_struct)); pvma.vm_end = TASK_SIZE; /* policy covers entire file */ mpol_set_shared_policy(sp, &pvma, new); /* adds ref */ -put_free: +put_new: mpol_put(new); /* drop initial ref */ free_scratch: NODEMASK_SCRATCH_FREE(scratch); +put_mpol: + mpol_put(mpol); /* drop our incoming ref on sb mpol */ } } |