diff options
119 files changed, 1164 insertions, 543 deletions
diff --git a/Documentation/fb/imacfb.txt b/Documentation/fb/imacfb.txt new file mode 100644 index 00000000000..759028545a7 --- /dev/null +++ b/Documentation/fb/imacfb.txt @@ -0,0 +1,31 @@ + +What is imacfb? +=============== + +This is a generic EFI platform driver for Intel based Apple computers. +Imacfb is only for EFI booted Intel Macs. + +Supported Hardware +================== + +iMac 17"/20" +Macbook +Macbook Pro 15"/17" +MacMini + +How to use it? +============== + +Imacfb does not have any kind of autodetection of your machine. +You have to add the fillowing kernel parameters in your elilo.conf: + Macbook : + video=imacfb:macbook + MacMini : + video=imacfb:mini + Macbook Pro 15", iMac 17" : + video=imacfb:i17 + Macbook Pro 17", iMac 20" : + video=imacfb:i20 + +-- +Edgar Hucek <gimli@dark-green.com> diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt index 8d9bffbd192..949f7b5a205 100644 --- a/Documentation/kobject.txt +++ b/Documentation/kobject.txt @@ -247,7 +247,7 @@ the object-specific fields, which include: - default_attrs: Default attributes to be exported via sysfs when the object is registered.Note that the last attribute has to be initialized to NULL ! You can find a complete implementation - in drivers/block/genhd.c + in block/genhd.c Instances of struct kobj_type are not registered; only referenced by diff --git a/MAINTAINERS b/MAINTAINERS index e3e1515ba5a..21116cc3b4a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2656,6 +2656,14 @@ M: chrisw@sous-sol.org L: stable@kernel.org S: Maintained +STABLE BRANCH: +P: Greg Kroah-Hartman +M: greg@kroah.com +P: Chris Wright +M: chrisw@sous-sol.org +L: stable@kernel.org +S: Maintained + TPM DEVICE DRIVER P: Kylene Hall M: kjhall@us.ibm.com @@ -309,9 +309,6 @@ CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE) CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common -# Force gcc to behave correct even for buggy distributions -CFLAGS += $(call cc-option, -fno-stack-protector) - AFLAGS := -D__ASSEMBLY__ # Read KERNELRELEASE from include/config/kernel.release (if it exists) @@ -436,12 +433,13 @@ core-y := usr/ endif # KBUILD_EXTMOD ifeq ($(dot-config),1) -# In this section, we need .config +# Read in config +-include include/config/auto.conf +ifeq ($(KBUILD_EXTMOD),) # Read in dependencies to all Kconfig* files, make sure to run # oldconfig if changes are detected. -include include/config/auto.conf.cmd --include include/config/auto.conf # To avoid any implicit rule to kick in, define an empty command $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; @@ -451,16 +449,27 @@ $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; # if auto.conf.cmd is missing then we are probably in a cleaned tree so # we execute the config step to be sure to catch updated Kconfig files include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd -ifeq ($(KBUILD_EXTMOD),) $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig else - $(error kernel configuration not valid - run 'make prepare' in $(srctree) to update it) -endif +# external modules needs include/linux/autoconf.h and include/config/auto.conf +# but do not care if they are up-to-date. Use auto.conf to trigger the test +PHONY += include/config/auto.conf + +include/config/auto.conf: + $(Q)test -e include/linux/autoconf.h -a -e $@ || ( \ + echo; \ + echo " ERROR: Kernel configuration is invalid."; \ + echo " include/linux/autoconf.h or $@ are missing."; \ + echo " Run 'make oldconfig && make prepare' on kernel src to fix it."; \ + echo; \ + /bin/false) + +endif # KBUILD_EXTMOD else # Dummy target needed, because used as prerequisite include/config/auto.conf: ; -endif +endif # $(dot-config) # The all: target is the default when no target is given on the # command line. @@ -474,6 +483,8 @@ else CFLAGS += -O2 endif +include $(srctree)/arch/$(ARCH)/Makefile + ifdef CONFIG_FRAME_POINTER CFLAGS += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,) else @@ -488,7 +499,8 @@ ifdef CONFIG_DEBUG_INFO CFLAGS += -g endif -include $(srctree)/arch/$(ARCH)/Makefile +# Force gcc to behave correct even for buggy distributions +CFLAGS += $(call cc-option, -fno-stack-protector) # arch Makefile may override CC so keep this after arch Makefile is included NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) diff --git a/arch/arm/common/rtctime.c b/arch/arm/common/rtctime.c index 35c9a64ac14..4e5445cfb0e 100644 --- a/arch/arm/common/rtctime.c +++ b/arch/arm/common/rtctime.c @@ -68,6 +68,7 @@ void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc rtc_time_to_tm(next_time, next); } } +EXPORT_SYMBOL(rtc_next_alarm_time); static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm) { diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 4e29dd03e58..aeeed806f99 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -233,7 +233,7 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) spin_unlock_irq(&die_lock); if (panic_on_oops) - panic("Fatal exception: panic_on_oops"); + panic("Fatal exception"); do_exit(SIGSEGV); } diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 2d40fe1145f..9562177b5fe 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -532,8 +532,6 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) return -EIO; } -EXPORT_SYMBOL(pci_set_dma_mask); -EXPORT_SYMBOL(pci_set_consistent_dma_mask); EXPORT_SYMBOL(ixp4xx_pci_read); EXPORT_SYMBOL(ixp4xx_pci_write); diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c index 654e2eed81f..30f1300e0e2 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c @@ -107,9 +107,9 @@ static struct flash_platform_data gtwx5715_flash_data = { .width = 2, }; -static struct gtw5715_flash_resource = { +static struct resource gtwx5715_flash_resource = { .flags = IORESOURCE_MEM, -} +}; static struct platform_device gtwx5715_flash = { .name = "IXP4XX-Flash", @@ -130,9 +130,6 @@ static void __init gtwx5715_init(void) { ixp4xx_sys_init(); - if (!flash_resource) - printk(KERN_ERR "Could not allocate flash resource\n"); - gtwx5715_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); gtwx5715_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_8M - 1; diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 0d4005dc06c..82e0fd02af1 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -454,7 +454,7 @@ void die(const char * str, struct pt_regs * regs, long err) panic("Fatal exception in interrupt"); if (panic_on_oops) - panic("Fatal exception: panic_on_oops"); + panic("Fatal exception"); oops_exit(); do_exit(SIGSEGV); diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index 5a0420464c6..fffa9e0826b 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -118,7 +118,7 @@ die (const char *str, struct pt_regs *regs, long err) spin_unlock_irq(&die.lock); if (panic_on_oops) - panic("Fatal exception: panic_on_oops"); + panic("Fatal exception"); do_exit(SIGSEGV); } diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 125761aaa40..e4d1713e8ae 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -148,7 +148,7 @@ int die(const char *str, struct pt_regs *regs, long err) panic("Fatal exception in interrupt"); if (panic_on_oops) - panic("Fatal exception: panic_on_oops"); + panic("Fatal exception"); do_exit(err); diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 6a4b5f9715c..a0a94e0ef8d 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -618,7 +618,7 @@ appldata_offline_cpu(int cpu) } #ifdef CONFIG_HOTPLUG_CPU -static int +static int __cpuinit appldata_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index eb6ebfef134..6e6b6de7777 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -129,7 +129,7 @@ void __init paging_init(void) /* * pg_table is physical at this point */ - pg_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); + pg_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE); pg_dir->pgd0 = (_PAGE_TABLE | __pa(pg_table)); pg_dir->pgd1 = (_PAGE_TABLE | (__pa(pg_table)+1024)); @@ -219,7 +219,7 @@ void __init paging_init(void) continue; } - pm_dir = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE*4); + pm_dir = (pmd_t *) alloc_bootmem_pages(PAGE_SIZE * 4); pgd_populate(&init_mm, pg_dir, pm_dir); for (j = 0 ; j < PTRS_PER_PMD ; j++,pm_dir++) { @@ -228,7 +228,7 @@ void __init paging_init(void) continue; } - pt_dir = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); + pt_dir = (pte_t *) alloc_bootmem_pages(PAGE_SIZE); pmd_populate_kernel(&init_mm, pm_dir, pt_dir); for (k = 0 ; k < PTRS_PER_PTE ; k++,pt_dir++) { diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 4e9938dee06..14052f08981 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -529,7 +529,7 @@ void __kprobes oops_end(unsigned long flags) /* Nest count reaches zero, release the lock. */ spin_unlock_irqrestore(&die_lock, flags); if (panic_on_oops) - panic("Fatal exception: panic_on_oops"); + panic("Fatal exception"); } void __kprobes __die(const char * str, struct pt_regs * regs, long err) diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 9734960a245..ce077d6bf3a 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -488,7 +488,7 @@ void die(const char * str, struct pt_regs * regs, long err) panic("Fatal exception in interrupt"); if (panic_on_oops) - panic("Fatal exception: panic_on_oops"); + panic("Fatal exception"); do_exit(err); } diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index d53f664a4dd..fff89c2d88f 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig @@ -45,7 +45,7 @@ config WATCHDOG_NOWAYOUT comment "Watchdog Device Drivers" depends on WATCHDOG -# Architecture Independant +# Architecture Independent config SOFT_WATCHDOG tristate "Software watchdog" @@ -127,7 +127,7 @@ config S3C2410_WATCHDOG enabled. The driver is limited by the speed of the system's PCLK - signal, so with reasonbaly fast systems (PCLK around 50-66MHz) + signal, so with reasonably fast systems (PCLK around 50-66MHz) then watchdog intervals of over approximately 20seconds are unavailable. @@ -423,7 +423,7 @@ config SBC_EPX_C3_WATCHDOG is no way to know if writing to its IO address will corrupt your system or have any real effect. The only way to be sure that this driver does what you want is to make sure you - are runnning it on an EPX-C3 from Winsystems with the watchdog + are running it on an EPX-C3 from Winsystems with the watchdog timer at IO address 0x1ee and 0x1ef. It will write to both those IO ports. Basically, the assumption is made that if you compile this driver into your kernel and/or load it as a module, that you @@ -472,7 +472,7 @@ config INDYDOG tristate "Indy/I2 Hardware Watchdog" depends on WATCHDOG && SGI_IP22 help - Hardwaredriver for the Indy's/I2's watchdog. This is a + Hardware driver for the Indy's/I2's watchdog. This is a watchdog timer that will reboot the machine after a 60 second timer expired and no process has written to /dev/watchdog during that time. diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index 2f962cfa3f7..78810ba982e 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c @@ -180,6 +180,36 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { .channels = 2, .autodma = AUTODMA, .bootable = OFF_BOARD, + },{ /* 15 */ + .name = "JMB361", + .init_hwif = init_hwif_generic, + .channels = 2, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + },{ /* 16 */ + .name = "JMB363", + .init_hwif = init_hwif_generic, + .channels = 2, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + },{ /* 17 */ + .name = "JMB365", + .init_hwif = init_hwif_generic, + .channels = 2, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + },{ /* 18 */ + .name = "JMB366", + .init_hwif = init_hwif_generic, + .channels = 2, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + },{ /* 19 */ + .name = "JMB368", + .init_hwif = init_hwif_generic, + .channels = 2, + .autodma = AUTODMA, + .bootable = OFF_BOARD, } }; diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 217615b3322..93f701ea87b 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -710,6 +710,8 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, return -EINVAL; } + m->ti = ti; + r = parse_features(&as, m, ti); if (r) goto bad; @@ -751,7 +753,6 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, } ti->private = m; - m->ti = ti; return 0; diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index d687a14ec0a..06ac899a9a2 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -393,7 +393,7 @@ static int dst_set_bandwidth(struct dst_state *state, fe_bandwidth_t bandwidth) state->bandwidth = bandwidth; if (state->dst_type != DST_TYPE_IS_TERR) - return 0; + return -EOPNOTSUPP; switch (bandwidth) { case BANDWIDTH_6_MHZ: @@ -462,7 +462,7 @@ static int dst_set_symbolrate(struct dst_state *state, u32 srate) state->symbol_rate = srate; if (state->dst_type == DST_TYPE_IS_TERR) { - return 0; + return -EOPNOTSUPP; } dprintk(verbose, DST_INFO, 1, "set symrate %u", srate); srate /= 1000; @@ -504,7 +504,7 @@ static int dst_set_symbolrate(struct dst_state *state, u32 srate) static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation) { if (state->dst_type != DST_TYPE_IS_CABLE) - return 0; + return -EOPNOTSUPP; state->modulation = modulation; switch (modulation) { @@ -1234,7 +1234,7 @@ int dst_command(struct dst_state *state, u8 *data, u8 len) goto error; } if (write_dst(state, data, len)) { - dprintk(verbose, DST_INFO, 1, "Tring to recover.. "); + dprintk(verbose, DST_INFO, 1, "Trying to recover.. "); if ((dst_error_recovery(state)) < 0) { dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); goto error; @@ -1328,15 +1328,13 @@ static int dst_tone_power_cmd(struct dst_state *state) { u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 }; - if (state->dst_type == DST_TYPE_IS_TERR) - return 0; + if (state->dst_type != DST_TYPE_IS_SAT) + return -EOPNOTSUPP; paket[4] = state->tx_tuna[4]; paket[2] = state->tx_tuna[2]; paket[3] = state->tx_tuna[3]; paket[7] = dst_check_sum (paket, 7); - dst_command(state, paket, 8); - - return 0; + return dst_command(state, paket, 8); } static int dst_get_tuna(struct dst_state *state) @@ -1465,7 +1463,7 @@ static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec }; if (state->dst_type != DST_TYPE_IS_SAT) - return 0; + return -EOPNOTSUPP; if (cmd->msg_len > 0 && cmd->msg_len < 5) memcpy(&paket[3], cmd->msg, cmd->msg_len); else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5) @@ -1473,18 +1471,17 @@ static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd else return -EINVAL; paket[7] = dst_check_sum(&paket[0], 7); - dst_command(state, paket, 8); - return 0; + return dst_command(state, paket, 8); } static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) { - int need_cmd; + int need_cmd, retval = 0; struct dst_state *state = fe->demodulator_priv; state->voltage = voltage; if (state->dst_type != DST_TYPE_IS_SAT) - return 0; + return -EOPNOTSUPP; need_cmd = 0; @@ -1506,9 +1503,9 @@ static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) } if (need_cmd) - dst_tone_power_cmd(state); + retval = dst_tone_power_cmd(state); - return 0; + return retval; } static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) @@ -1517,7 +1514,7 @@ static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) state->tone = tone; if (state->dst_type != DST_TYPE_IS_SAT) - return 0; + return -EOPNOTSUPP; switch (tone) { case SEC_TONE_OFF: @@ -1533,9 +1530,7 @@ static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) default: return -EINVAL; } - dst_tone_power_cmd(state); - - return 0; + return dst_tone_power_cmd(state); } static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) @@ -1543,7 +1538,7 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) struct dst_state *state = fe->demodulator_priv; if (state->dst_type != DST_TYPE_IS_SAT) - return 0; + return -EOPNOTSUPP; state->minicmd = minicmd; switch (minicmd) { case SEC_MINI_A: @@ -1553,9 +1548,7 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) state->tx_tuna[3] = 0xff; break; } - dst_tone_power_cmd(state); - - return 0; + return dst_tone_power_cmd(state); } @@ -1608,28 +1601,31 @@ static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { struct dst_state *state = fe->demodulator_priv; - dst_get_signal(state); + int retval = dst_get_signal(state); *strength = state->decode_strength; - return 0; + return retval; } static int dst_read_snr(struct dvb_frontend *fe, u16 *snr) { struct dst_state *state = fe->demodulator_priv; - dst_get_signal(state); + int retval = dst_get_signal(state); *snr = state->decode_snr; - return 0; + return retval; } static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { + int retval = -EINVAL; struct dst_state *state = fe->demodulator_priv; if (p != NULL) { - dst_set_freq(state, p->frequency); + retval = dst_set_freq(state, p->frequency); + if(retval != 0) + return retval; dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); if (state->dst_type == DST_TYPE_IS_SAT) { @@ -1647,10 +1643,10 @@ static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_paramet dst_set_symbolrate(state, p->u.qam.symbol_rate); dst_set_modulation(state, p->u.qam.modulation); } - dst_write_tuna(fe); + retval = dst_write_tuna(fe); } - return 0; + return retval; } static int dst_tune_frontend(struct dvb_frontend* fe, diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile index 11054657fdb..0b5182835cc 100644 --- a/drivers/media/dvb/dvb-core/Makefile +++ b/drivers/media/dvb/dvb-core/Makefile @@ -2,8 +2,8 @@ # Makefile for the kernel DVB device drivers. # -dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ - dvb_ca_en50221.o dvb_frontend.o \ - dvb_net.o dvb_ringbuffer.o dvb_math.o +dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ + dvb_ca_en50221.o dvb_frontend.o \ + dvb_net.o dvb_ringbuffer.o dvb_math.o obj-$(CONFIG_DVB_CORE) += dvb-core.o diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index de3128a31de..220076b1b95 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -350,5 +350,15 @@ config RADIO_ZOLTRIX_PORT help Enter the I/O port of your Zoltrix radio card. -endmenu +config USB_DSBR + tristate "D-Link USB FM radio support (EXPERIMENTAL)" + depends on USB && VIDEO_V4L1 && EXPERIMENTAL + ---help--- + Say Y here if you want to connect this type of radio to your + computer's USB port. Note that the audio is not digital, and + you must connect the line out connector to a sound card or a + set of speakers. + To compile this driver as a module, choose M here: the + module will be called dsbr100. +endmenu diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile index e95b6805e00..cf55a18e3dd 100644 --- a/drivers/media/radio/Makefile +++ b/drivers/media/radio/Makefile @@ -20,5 +20,6 @@ obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o obj-$(CONFIG_RADIO_TRUST) += radio-trust.o obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o +obj-$(CONFIG_USB_DSBR) += dsbr100.o EXTRA_CFLAGS += -Isound diff --git a/drivers/media/video/dsbr100.c b/drivers/media/radio/dsbr100.c index f7e33f9ee8e..f7e33f9ee8e 100644 --- a/drivers/media/video/dsbr100.c +++ b/drivers/media/radio/dsbr100.c diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index fe56862d51e..732bf1e7c32 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -449,18 +449,6 @@ source "drivers/media/video/pvrusb2/Kconfig" source "drivers/media/video/em28xx/Kconfig" -config USB_DSBR - tristate "D-Link USB FM radio support (EXPERIMENTAL)" - depends on USB && VIDEO_V4L1 && EXPERIMENTAL - ---help--- - Say Y here if you want to connect this type of radio to your - computer's USB port. Note that the audio is not digital, and - you must connect the line out connector to a sound card or a - set of speakers. - - To compile this driver as a module, choose M here: the - module will be called dsbr100. - source "drivers/media/video/usbvideo/Kconfig" source "drivers/media/video/et61x251/Kconfig" diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 353d61cfac1..e82e511f2a7 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -77,7 +77,6 @@ obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o obj-$(CONFIG_USB_DABUSB) += dabusb.o -obj-$(CONFIG_USB_DSBR) += dsbr100.o obj-$(CONFIG_USB_OV511) += ov511.o obj-$(CONFIG_USB_SE401) += se401.o obj-$(CONFIG_USB_STV680) += stv680.o @@ -91,6 +90,7 @@ obj-$(CONFIG_USB_ZC0301) += zc0301/ obj-$(CONFIG_USB_IBMCAM) += usbvideo/ obj-$(CONFIG_USB_KONICAWC) += usbvideo/ obj-$(CONFIG_USB_VICAM) += usbvideo/ +obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/ obj-$(CONFIG_VIDEO_VIVI) += vivi.o diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c index 9dddff42ec1..b69ee119481 100644 --- a/drivers/media/video/compat_ioctl32.c +++ b/drivers/media/video/compat_ioctl32.c @@ -21,7 +21,7 @@ #ifdef CONFIG_COMPAT - +#ifdef CONFIG_VIDEO_V4L1_COMPAT struct video_tuner32 { compat_int_t tuner; char name[32]; @@ -107,6 +107,7 @@ struct video_window32 { compat_caddr_t clips; compat_int_t clipcount; }; +#endif static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -124,6 +125,7 @@ static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } +#ifdef CONFIG_VIDEO_V4L1_COMPAT /* You get back everything except the clips... */ static int put_video_window32(struct video_window *kp, struct video_window32 __user *up) { @@ -138,6 +140,7 @@ static int put_video_window32(struct video_window *kp, struct video_window32 __u return -EFAULT; return 0; } +#endif struct v4l2_clip32 { @@ -490,6 +493,7 @@ static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user return 0; } +#ifdef CONFIG_VIDEO_V4L1_COMPAT struct video_code32 { char loadwhat[16]; /* name or tag of file being passed */ @@ -517,6 +521,8 @@ static inline int microcode32(struct video_code *kp, struct video_code32 __user #define VIDIOCSFREQ32 _IOW('v',15, u32) #define VIDIOCSMICROCODE32 _IOW('v',27, struct video_code32) +#endif + /* VIDIOC_ENUMINPUT32 is VIDIOC_ENUMINPUT minus 4 bytes of padding alignement */ #define VIDIOC_ENUMINPUT32 VIDIOC_ENUMINPUT - _IOC(0, 0, 0, 4) #define VIDIOC_G_FMT32 _IOWR ('V', 4, struct v4l2_format32) @@ -537,6 +543,7 @@ static inline int microcode32(struct video_code *kp, struct video_code32 __user #define VIDIOC_S_INPUT32 _IOWR ('V', 39, compat_int_t) #define VIDIOC_TRY_FMT32 _IOWR ('V', 64, struct v4l2_format32) +#ifdef CONFIG_VIDEO_V4L1_COMPAT enum { MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip) }; @@ -601,14 +608,17 @@ static int do_set_window(struct file *file, unsigned int cmd, unsigned long arg) return native_ioctl(file, VIDIOCSWIN, (unsigned long)vw); } +#endif static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { union { +#ifdef CONFIG_VIDEO_V4L1_COMPAT struct video_tuner vt; struct video_buffer vb; struct video_window vw; struct video_code vc; +#endif struct v4l2_format v2f; struct v4l2_buffer v2b; struct v4l2_framebuffer v2fb; @@ -624,6 +634,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg /* First, convert the command. */ switch(cmd) { +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break; case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break; case VIDIOCGWIN32: cmd = VIDIOCGWIN; break; @@ -631,6 +642,8 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break; case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break; case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break; + case VIDIOCSMICROCODE32: cmd = VIDIOCSMICROCODE; break; +#endif case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break; case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break; case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break; @@ -647,10 +660,10 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break; - case VIDIOCSMICROCODE32: cmd = VIDIOCSMICROCODE; break; }; switch(cmd) { +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCSTUNER: case VIDIOCGTUNER: err = get_video_tuner32(&karg.vt, up); @@ -664,6 +677,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg break; case VIDIOCSFREQ: +#endif case VIDIOC_S_INPUT: case VIDIOC_OVERLAY: case VIDIOC_STREAMON: @@ -717,18 +731,21 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg compatible_arg = 0; break; +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCGWIN: case VIDIOCGFBUF: case VIDIOCGFREQ: +#endif case VIDIOC_G_FBUF: case VIDIOC_G_INPUT: compatible_arg = 0; +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCSMICROCODE: err = microcode32(&karg.vc, up); compatible_arg = 0; break; +#endif }; - if(err) goto out; @@ -743,6 +760,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg } if(err == 0) { switch(cmd) { +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCGTUNER: err = put_video_tuner32(&karg.vt, up); break; @@ -754,7 +772,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg case VIDIOCGFBUF: err = put_video_buffer32(&karg.vb, up); break; - +#endif case VIDIOC_G_FBUF: err = put_v4l2_framebuffer32(&karg.v2fb, up); break; @@ -792,7 +810,9 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg err = put_v4l2_input32(&karg.v2i, up); break; +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCGFREQ: +#endif case VIDIOC_G_INPUT: err = put_user(((u32)karg.vx), (u32 __user *)up); break; @@ -810,6 +830,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) return ret; switch (cmd) { +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCSWIN32: ret = do_set_window(file, cmd, arg); break; @@ -820,6 +841,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case VIDIOCSFBUF32: case VIDIOCGFREQ32: case VIDIOCSFREQ32: +#endif case VIDIOC_QUERYCAP: case VIDIOC_ENUM_FMT: case VIDIOC_G_FMT32: @@ -851,6 +873,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) ret = do_video_ioctl(file, cmd, arg); break; +#ifdef CONFIG_VIDEO_V4L1_COMPAT /* Little v, the video4linux ioctls (conflict?) */ case VIDIOCGCAP: case VIDIOCGCHAN: @@ -879,6 +902,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case _IOR('v' , BASE_VIDIOCPRIVATE+7, int): ret = native_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); break; +#endif default: v4l_print_ioctl("compat_ioctl32", cmd); } diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 5c2036b40ea..7bb7589a07c 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -104,8 +104,8 @@ u32 cx25840_read4(struct i2c_client * client, u16 addr) if (i2c_master_recv(client, buffer, 4) < 4) return 0; - return (buffer[0] << 24) | (buffer[1] << 16) | - (buffer[2] << 8) | buffer[3]; + return (buffer[3] << 24) | (buffer[2] << 16) | + (buffer[1] << 8) | buffer[0]; } int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned and_mask, diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 547cdbdb644..94c92bacc34 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -1225,7 +1225,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_format *f = arg; return cx8800_try_fmt(dev,fh,f); } -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT /* --- streaming capture ------------------------------------- */ case VIDIOCGMBUF: { @@ -1584,7 +1584,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, *id = 0; return 0; } -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCSTUNER: { struct video_tuner *v = arg; diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c index f2fd9195b3a..ed02ff81138 100644 --- a/drivers/media/video/msp3400-kthreads.c +++ b/drivers/media/video/msp3400-kthreads.c @@ -961,10 +961,10 @@ int msp34xxg_thread(void *data) /* setup the chip*/ msp34xxg_reset(client); state->std = state->radio ? 0x40 : msp_standard; - if (state->std != 1) - goto unmute; /* start autodetect */ msp_write_dem(client, 0x20, state->std); + if (state->std != 1) + goto unmute; /* watch autodetect */ v4l_dbg(1, msp_debug, client, "started autodetect, waiting for result\n"); diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig index 697145e0bf1..8fdf7101d3b 100644 --- a/drivers/media/video/pwc/Kconfig +++ b/drivers/media/video/pwc/Kconfig @@ -30,7 +30,7 @@ config USB_PWC config USB_PWC_DEBUG bool "USB Philips Cameras verbose debug" - depends USB_PWC + depends on USB_PWC help Say Y here in order to have the pwc driver generate verbose debugging messages. diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 47d0d83a026..d4703944df9 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -160,6 +160,7 @@ static struct file_operations pwc_fops = { .poll = pwc_video_poll, .mmap = pwc_video_mmap, .ioctl = pwc_video_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; static struct video_device pwc_template = { diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 8656f2400e1..2c171af9a9f 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -2087,7 +2087,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_format *f = arg; return saa7134_try_fmt(dev,fh,f); } -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCGMBUF: { struct video_mbuf *mbuf = arg; diff --git a/drivers/media/video/tuner-types.c b/drivers/media/video/tuner-types.c index a167e17c6dc..d7eadc2c298 100644 --- a/drivers/media/video/tuner-types.c +++ b/drivers/media/video/tuner-types.c @@ -1027,10 +1027,11 @@ static struct tuner_params tuner_tnf_5335mf_params[] = { /* 70-79 */ /* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */ +/* '+ 4' turns on the Low Noise Amplifier */ static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = { - { 16 * 130.00 /*MHz*/, 0xce, 0x01, }, - { 16 * 364.50 /*MHz*/, 0xce, 0x02, }, - { 16 * 999.99 , 0xce, 0x08, }, + { 16 * 130.00 /*MHz*/, 0xce, 0x01 + 4, }, + { 16 * 364.50 /*MHz*/, 0xce, 0x02 + 4, }, + { 16 * 999.99 , 0xce, 0x08 + 4, }, }; static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = { @@ -1060,10 +1061,11 @@ static struct tuner_params tuner_thomson_fe6600_params[] = { /* ------------ TUNER_SAMSUNG_TCPG_6121P30A - Samsung PAL ------------ */ +/* '+ 4' turns on the Low Noise Amplifier */ static struct tuner_range tuner_samsung_tcpg_6121p30a_pal_ranges[] = { - { 16 * 146.25 /*MHz*/, 0xce, 0x01, }, - { 16 * 428.50 /*MHz*/, 0xce, 0x02, }, - { 16 * 999.99 , 0xce, 0x08, }, + { 16 * 146.25 /*MHz*/, 0xce, 0x01 + 4, }, + { 16 * 428.50 /*MHz*/, 0xce, 0x02 + 4, }, + { 16 * 999.99 , 0xce, 0x08 + 4, }, }; static struct tuner_params tuner_samsung_tcpg_6121p30a_params[] = { diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index d83a2c84d23..d7c3fcbc80f 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c @@ -599,6 +599,10 @@ v4l_compat_translate_ioctl(struct inode *inode, dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n",err); break; } + + pict->depth = ((fmt2->fmt.pix.bytesperline<<3) + + (fmt2->fmt.pix.width-1) ) + /fmt2->fmt.pix.width; pict->palette = pixelformat_to_palette( fmt2->fmt.pix.pixelformat); break; diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index 2ecbeffb559..8d972ffdaf9 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -202,7 +202,7 @@ static char *v4l2_memory_names[] = { /* ------------------------------------------------------------------ */ /* debug help functions */ -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT static const char *v4l1_ioctls[] = { [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", @@ -301,7 +301,7 @@ static const char *v4l2_ioctls[] = { #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) static const char *v4l2_int_ioctls[] = { -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", @@ -367,7 +367,7 @@ void v4l_printk_ioctl(unsigned int cmd) (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ? v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); break; -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT case 'v': printk("v4l1 ioctl %s, dir=%s (0x%08x)\n", (_IOC_NR(cmd) < V4L1_IOCTLS) ? diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 0fc90cd393f..88bf2af2a0e 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -760,7 +760,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret=vfd->vidioc_overlay(file, fh, *i); break; } -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT /* --- streaming capture ------------------------------------- */ case VIDIOCGMBUF: { diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 38bd0c1018c..841884af0cc 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -986,7 +986,7 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p) file->f_flags & O_NONBLOCK)); } -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf) { struct vivi_fh *fh=priv; @@ -1328,7 +1328,7 @@ static struct video_device vivi = { .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT .vidiocgmbuf = vidiocgmbuf, #endif .tvnorms = tvnorms, diff --git a/drivers/mmc/mmc_queue.c b/drivers/mmc/mmc_queue.c index 0b9682e9a35..74f8cdeeff0 100644 --- a/drivers/mmc/mmc_queue.c +++ b/drivers/mmc/mmc_queue.c @@ -79,7 +79,8 @@ static int mmc_queue_thread(void *d) spin_lock_irq(q->queue_lock); set_current_state(TASK_INTERRUPTIBLE); if (!blk_queue_plugged(q)) - mq->req = req = elv_next_request(q); + req = elv_next_request(q); + mq->req = req; spin_unlock_irq(q->queue_lock); if (!req) { diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index 8a30ef3ae41..c351c6d1a18 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c @@ -41,7 +41,7 @@ #include "wbsd.h" #define DRIVER_NAME "wbsd" -#define DRIVER_VERSION "1.5" +#define DRIVER_VERSION "1.6" #define DBG(x...) \ pr_debug(DRIVER_NAME ": " x) @@ -1439,13 +1439,13 @@ static int __devinit wbsd_scan(struct wbsd_host *host) static int __devinit wbsd_request_region(struct wbsd_host *host, int base) { - if (io & 0x7) + if (base & 0x7) return -EINVAL; if (!request_region(base, 8, DRIVER_NAME)) return -EIO; - host->base = io; + host->base = base; return 0; } @@ -1773,7 +1773,7 @@ static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma, /* * Request resources. */ - ret = wbsd_request_resources(host, io, irq, dma); + ret = wbsd_request_resources(host, base, irq, dma); if (ret) { wbsd_release_resources(host); wbsd_free_mmc(dev); @@ -1861,6 +1861,7 @@ static void __devexit wbsd_shutdown(struct device *dev, int pnp) static int __devinit wbsd_probe(struct platform_device *dev) { + /* Use the module parameters for resources */ return wbsd_init(&dev->dev, io, irq, dma, 0); } diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 06440a86bae..9bdd43ab357 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -2425,7 +2425,7 @@ static int myri10ge_resume(struct pci_dev *pdev) } myri10ge_reset(mgp); - myri10ge_dummy_rdma(mgp, mgp->tx.boundary != 4096); + myri10ge_dummy_rdma(mgp, 1); /* Save configuration space to be restored if the * nic resets due to a parity error */ diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 6f97962dd06..eafabb253f0 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -68,8 +68,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.64" -#define DRV_MODULE_RELDATE "July 31, 2006" +#define DRV_MODULE_VERSION "3.65" +#define DRV_MODULE_RELDATE "August 07, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -123,9 +123,6 @@ TG3_RX_RCB_RING_SIZE(tp)) #define TG3_TX_RING_BYTES (sizeof(struct tg3_tx_buffer_desc) * \ TG3_TX_RING_SIZE) -#define TX_BUFFS_AVAIL(TP) \ - ((TP)->tx_pending - \ - (((TP)->tx_prod - (TP)->tx_cons) & (TG3_TX_RING_SIZE - 1))) #define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1)) #define RX_PKT_BUF_SZ (1536 + tp->rx_offset + 64) @@ -2987,6 +2984,13 @@ static void tg3_tx_recover(struct tg3 *tp) spin_unlock(&tp->lock); } +static inline u32 tg3_tx_avail(struct tg3 *tp) +{ + smp_mb(); + return (tp->tx_pending - + ((tp->tx_prod - tp->tx_cons) & (TG3_TX_RING_SIZE - 1))); +} + /* Tigon3 never reports partial packet sends. So we do not * need special logic to handle SKBs that have not had all * of their frags sent yet, like SunGEM does. @@ -3038,12 +3042,20 @@ static void tg3_tx(struct tg3 *tp) tp->tx_cons = sw_idx; - if (unlikely(netif_queue_stopped(tp->dev))) { - spin_lock(&tp->tx_lock); + /* Need to make the tx_cons update visible to tg3_start_xmit() + * before checking for netif_queue_stopped(). Without the + * memory barrier, there is a small possibility that tg3_start_xmit() + * will miss it and cause the queue to be stopped forever. + */ + smp_mb(); + + if (unlikely(netif_queue_stopped(tp->dev) && + (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH))) { + netif_tx_lock(tp->dev); if (netif_queue_stopped(tp->dev) && - (TX_BUFFS_AVAIL(tp) > TG3_TX_WAKEUP_THRESH)) + (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH)) netif_wake_queue(tp->dev); - spin_unlock(&tp->tx_lock); + netif_tx_unlock(tp->dev); } } @@ -3101,7 +3113,6 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key, if (skb == NULL) return -ENOMEM; - skb->dev = tp->dev; skb_reserve(skb, tp->rx_offset); mapping = pci_map_single(tp->pdev, skb->data, @@ -3274,7 +3285,6 @@ static int tg3_rx(struct tg3 *tp, int budget) if (copy_skb == NULL) goto drop_it_no_recycle; - copy_skb->dev = tp->dev; skb_reserve(copy_skb, 2); skb_put(copy_skb, len); pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE); @@ -3797,7 +3807,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) * interrupt. Furthermore, IRQ processing runs lockless so we have * no IRQ context deadlocks to worry about either. Rejoice! */ - if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) { + if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->nr_frags + 1))) { if (!netif_queue_stopped(dev)) { netif_stop_queue(dev); @@ -3893,12 +3903,10 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry); tp->tx_prod = entry; - if (unlikely(TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1))) { - spin_lock(&tp->tx_lock); + if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) { netif_stop_queue(dev); - if (TX_BUFFS_AVAIL(tp) > TG3_TX_WAKEUP_THRESH) + if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH) netif_wake_queue(tp->dev); - spin_unlock(&tp->tx_lock); } out_unlock: @@ -3920,7 +3928,7 @@ static int tg3_tso_bug(struct tg3 *tp, struct sk_buff *skb) struct sk_buff *segs, *nskb; /* Estimate the number of fragments in the worst case */ - if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->gso_segs * 3))) { + if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->gso_segs * 3))) { netif_stop_queue(tp->dev); return NETDEV_TX_BUSY; } @@ -3960,7 +3968,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) * interrupt. Furthermore, IRQ processing runs lockless so we have * no IRQ context deadlocks to worry about either. Rejoice! */ - if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) { + if (unlikely(tg3_tx_avail(tp) <= (skb_shinfo(skb)->nr_frags + 1))) { if (!netif_queue_stopped(dev)) { netif_stop_queue(dev); @@ -4110,12 +4118,10 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev) tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry); tp->tx_prod = entry; - if (unlikely(TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1))) { - spin_lock(&tp->tx_lock); + if (unlikely(tg3_tx_avail(tp) <= (MAX_SKB_FRAGS + 1))) { netif_stop_queue(dev); - if (TX_BUFFS_AVAIL(tp) > TG3_TX_WAKEUP_THRESH) + if (tg3_tx_avail(tp) > TG3_TX_WAKEUP_THRESH) netif_wake_queue(tp->dev); - spin_unlock(&tp->tx_lock); } out_unlock: @@ -11474,7 +11480,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tp->grc_mode |= GRC_MODE_BSWAP_NONFRM_DATA; #endif spin_lock_init(&tp->lock); - spin_lock_init(&tp->tx_lock); spin_lock_init(&tp->indirect_lock); INIT_WORK(&tp->reset_task, tg3_reset_task, tp); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index ba2c98711c8..3ecf356cfb0 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2079,9 +2079,9 @@ struct tg3 { * lock: Held during reset, PHY access, timer, and when * updating tg3_flags and tg3_flags2. * - * tx_lock: Held during tg3_start_xmit and tg3_tx only - * when calling netif_[start|stop]_queue. - * tg3_start_xmit is protected by netif_tx_lock. + * netif_tx_lock: Held during tg3_start_xmit. tg3_tx holds + * netif_tx_lock when it needs to call + * netif_wake_queue. * * Both of these locks are to be held with BH safety. * @@ -2118,8 +2118,6 @@ struct tg3 { u32 tx_cons; u32 tx_pending; - spinlock_t tx_lock; - struct tg3_tx_buffer_desc *tx_ring; struct tx_ring_info *tx_buffers; dma_addr_t tx_desc_mapping; diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index 3fae77ffb2f..3c148eaf2f4 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig @@ -153,13 +153,6 @@ config HOTPLUG_PCI_SHPC_POLL_EVENT_MODE When in doubt, say N. -config HOTPLUG_PCI_SHPC_PHPRM_LEGACY - bool "For AMD SHPC only: Use $HRT for resource/configuration" - depends on HOTPLUG_PCI_SHPC && !ACPI - help - Say Y here for AMD SHPC. You have to select this option if you are - using this driver on platform with AMD SHPC. - config HOTPLUG_PCI_RPA tristate "RPA PCI Hotplug driver" depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index ce89f581586..eaea9d36a1b 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -279,6 +279,11 @@ struct hpc_ops { #ifdef CONFIG_ACPI +#include <acpi/acpi.h> +#include <acpi/acpi_bus.h> +#include <acpi/actypes.h> +#include <linux/pci-acpi.h> + #define pciehp_get_hp_hw_control_from_firmware(dev) \ pciehp_acpi_get_hp_hw_control_from_firmware(dev) static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 0d8fb6e607a..6ab3b6cd2b5 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -38,10 +38,6 @@ #include "../pci.h" #include "pciehp.h" -#include <acpi/acpi.h> -#include <acpi/acpi_bus.h> -#include <acpi/actypes.h> -#include <linux/pci-acpi.h> #ifdef DEBUG #define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */ #define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */ diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 4bf03fb67f8..d8e9b95f0a1 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -1730,8 +1730,8 @@ dasd_flush_request_queue(struct dasd_device * device) req = elv_next_request(device->request_queue); if (req == NULL) break; - dasd_end_request(req, 0); blkdev_dequeue_request(req); + dasd_end_request(req, 0); } spin_unlock_irq(&device->request_queue_lock); } diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 7f6fdac7470..9d0c6e1a0e6 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c @@ -48,18 +48,20 @@ struct dasd_devmap { }; /* - * dasd_servermap is used to store the server_id of all storage servers - * accessed by DASD device driver. + * dasd_server_ssid_map contains a globally unique storage server subsystem ID. + * dasd_server_ssid_list contains the list of all subsystem IDs accessed by + * the DASD device driver. */ -struct dasd_servermap { +struct dasd_server_ssid_map { struct list_head list; struct server_id { char vendor[4]; char serial[15]; } sid; + __u16 ssid; }; -static struct list_head dasd_serverlist; +static struct list_head dasd_server_ssid_list; /* * Parameter parsing functions for dasd= parameter. The syntax is: @@ -89,7 +91,7 @@ static char *dasd[256]; module_param_array(dasd, charp, NULL, 0); /* - * Single spinlock to protect devmap structures and lists. + * Single spinlock to protect devmap and servermap structures and lists. */ static DEFINE_SPINLOCK(dasd_devmap_lock); @@ -264,8 +266,9 @@ dasd_parse_keyword( char *parsestring ) { if (dasd_page_cache) return residual_str; dasd_page_cache = - kmem_cache_create("dasd_page_cache", PAGE_SIZE, 0, - SLAB_CACHE_DMA, NULL, NULL ); + kmem_cache_create("dasd_page_cache", PAGE_SIZE, + PAGE_SIZE, SLAB_CACHE_DMA, + NULL, NULL ); if (!dasd_page_cache) MESSAGE(KERN_WARNING, "%s", "Failed to create slab, " "fixed buffer mode disabled."); @@ -859,39 +862,6 @@ static struct attribute_group dasd_attr_group = { }; /* - * Check if the related storage server is already contained in the - * dasd_serverlist. If server is not contained, create new entry. - * Return 0 if server was already in serverlist, - * 1 if the server was added successfully - * <0 in case of error. - */ -static int -dasd_add_server(struct dasd_uid *uid) -{ - struct dasd_servermap *new, *tmp; - - /* check if server is already contained */ - list_for_each_entry(tmp, &dasd_serverlist, list) - // normale cmp? - if (strncmp(tmp->sid.vendor, uid->vendor, - sizeof(tmp->sid.vendor)) == 0 - && strncmp(tmp->sid.serial, uid->serial, - sizeof(tmp->sid.serial)) == 0) - return 0; - - new = (struct dasd_servermap *) - kzalloc(sizeof(struct dasd_servermap), GFP_KERNEL); - if (!new) - return -ENOMEM; - - strncpy(new->sid.vendor, uid->vendor, sizeof(new->sid.vendor)); - strncpy(new->sid.serial, uid->serial, sizeof(new->sid.serial)); - list_add(&new->list, &dasd_serverlist); - return 1; -} - - -/* * Return copy of the device unique identifier. */ int @@ -910,6 +880,9 @@ dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid) /* * Register the given device unique identifier into devmap struct. + * In addition check if the related storage server subsystem ID is already + * contained in the dasd_server_ssid_list. If subsystem ID is not contained, + * create new entry. * Return 0 if server was already in serverlist, * 1 if the server was added successful * <0 in case of error. @@ -918,16 +891,39 @@ int dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) { struct dasd_devmap *devmap; - int rc; + struct dasd_server_ssid_map *srv, *tmp; devmap = dasd_find_busid(cdev->dev.bus_id); if (IS_ERR(devmap)) return PTR_ERR(devmap); + + /* generate entry for server_ssid_map */ + srv = (struct dasd_server_ssid_map *) + kzalloc(sizeof(struct dasd_server_ssid_map), GFP_KERNEL); + if (!srv) + return -ENOMEM; + strncpy(srv->sid.vendor, uid->vendor, sizeof(srv->sid.vendor) - 1); + strncpy(srv->sid.serial, uid->serial, sizeof(srv->sid.serial) - 1); + srv->ssid = uid->ssid; + + /* server is already contained ? */ spin_lock(&dasd_devmap_lock); devmap->uid = *uid; - rc = dasd_add_server(uid); + list_for_each_entry(tmp, &dasd_server_ssid_list, list) { + if (!memcmp(&srv->sid, &tmp->sid, + sizeof(struct dasd_server_ssid_map))) { + kfree(srv); + srv = NULL; + break; + } + } + + /* add servermap to serverlist */ + if (srv) + list_add(&srv->list, &dasd_server_ssid_list); spin_unlock(&dasd_devmap_lock); - return rc; + + return (srv ? 1 : 0); } EXPORT_SYMBOL_GPL(dasd_set_uid); @@ -995,7 +991,7 @@ dasd_devmap_init(void) INIT_LIST_HEAD(&dasd_hashlists[i]); /* Initialize servermap structure. */ - INIT_LIST_HEAD(&dasd_serverlist); + INIT_LIST_HEAD(&dasd_server_ssid_list); return 0; } diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 39c2281371b..957ed5db98e 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -468,11 +468,11 @@ dasd_eckd_generate_uid(struct dasd_device *device, struct dasd_uid *uid) return -ENODEV; memset(uid, 0, sizeof(struct dasd_uid)); - strncpy(uid->vendor, confdata->ned1.HDA_manufacturer, - sizeof(uid->vendor) - 1); + memcpy(uid->vendor, confdata->ned1.HDA_manufacturer, + sizeof(uid->vendor) - 1); EBCASC(uid->vendor, sizeof(uid->vendor) - 1); - strncpy(uid->serial, confdata->ned1.HDA_location, - sizeof(uid->serial) - 1); + memcpy(uid->serial, confdata->ned1.HDA_location, + sizeof(uid->serial) - 1); EBCASC(uid->serial, sizeof(uid->serial) - 1); uid->ssid = confdata->neq.subsystemID; if (confdata->ned2.sneq.flags == 0x40) { diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index 1140302ff11..ca7d51f7ecc 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c @@ -48,15 +48,6 @@ #define PRINT_ERR(x...) printk(KERN_ERR XPRAM_NAME " error:" x) -static struct sysdev_class xpram_sysclass = { - set_kset_name("xpram"), -}; - -static struct sys_device xpram_sys_device = { - .id = 0, - .cls = &xpram_sysclass, -}; - typedef struct { unsigned int size; /* size of xpram segment in pages */ unsigned int offset; /* start page of xpram segment */ @@ -451,8 +442,6 @@ static void __exit xpram_exit(void) } unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME); blk_cleanup_queue(xpram_queue); - sysdev_unregister(&xpram_sys_device); - sysdev_class_unregister(&xpram_sysclass); } static int __init xpram_init(void) @@ -470,19 +459,7 @@ static int __init xpram_init(void) rc = xpram_setup_sizes(xpram_pages); if (rc) return rc; - rc = sysdev_class_register(&xpram_sysclass); - if (rc) - return rc; - - rc = sysdev_register(&xpram_sys_device); - if (rc) { - sysdev_class_unregister(&xpram_sysclass); - return rc; - } - rc = xpram_setup_blkdev(); - if (rc) - sysdev_unregister(&xpram_sys_device); - return rc; + return xpram_setup_blkdev(); } module_init(xpram_init); diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c index 643b6d07856..56b87618b10 100644 --- a/drivers/s390/char/tape_class.c +++ b/drivers/s390/char/tape_class.c @@ -76,7 +76,7 @@ struct tape_class_device *register_tape_dev( device, "%s", tcd->device_name ); - rc = PTR_ERR(tcd->class_device); + rc = IS_ERR(tcd->class_device) ? PTR_ERR(tcd->class_device) : 0; if (rc) goto fail_with_cdev; rc = sysfs_create_link( diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 7a39e0b0386..6d91c2eb205 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -772,6 +772,7 @@ ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event) stsch(sch->schid, &sch->schib); if (sch->schib.scsw.actl != 0 || + (sch->schib.scsw.stctl & SCSW_STCTL_STATUS_PEND) || (cdev->private->irb.scsw.stctl & SCSW_STCTL_STATUS_PEND)) { /* * No final status yet or final status not yet delivered diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c index a60124264be..9e3de0bd59b 100644 --- a/drivers/s390/cio/device_ops.c +++ b/drivers/s390/cio/device_ops.c @@ -263,6 +263,9 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb) /* Abuse intparm for error reporting. */ if (IS_ERR(irb)) cdev->private->intparm = -EIO; + else if (irb->scsw.cc == 1) + /* Retry for deferred condition code. */ + cdev->private->intparm = -EAGAIN; else if ((irb->scsw.dstat != (DEV_STAT_CHN_END|DEV_STAT_DEV_END)) || (irb->scsw.cstat != 0)) { diff --git a/drivers/scsi/arm/Kconfig b/drivers/scsi/arm/Kconfig index 06d7601cdf5..d006a8cb4a7 100644 --- a/drivers/scsi/arm/Kconfig +++ b/drivers/scsi/arm/Kconfig @@ -69,6 +69,7 @@ comment "The following drivers are not fully supported" config SCSI_CUMANA_1 tristate "CumanaSCSI I support (EXPERIMENTAL)" depends on ARCH_ACORN && EXPERIMENTAL && SCSI + select SCSI_SPI_ATTRS help This enables support for the Cumana SCSI I card. If you have an Acorn system with one of these, say Y. If unsure, say N. @@ -76,6 +77,7 @@ config SCSI_CUMANA_1 config SCSI_ECOSCSI tristate "EcoScsi support (EXPERIMENTAL)" depends on ARCH_ACORN && EXPERIMENTAL && (ARCH_ARC || ARCH_A5K) && SCSI + select SCSI_SPI_ATTRS help This enables support for the EcoSCSI card -- a small card that sits in the Econet socket. If you have an Acorn system with one of these, @@ -84,6 +86,7 @@ config SCSI_ECOSCSI config SCSI_OAK1 tristate "Oak SCSI support (EXPERIMENTAL)" depends on ARCH_ACORN && EXPERIMENTAL && SCSI + select SCSI_SPI_ATTRS help This enables support for the Oak SCSI card. If you have an Acorn system with one of these, say Y. If unsure, say N. diff --git a/drivers/scsi/arm/scsi.h b/drivers/scsi/arm/scsi.h index 6dd544a5eb5..8c2600ffc6a 100644 --- a/drivers/scsi/arm/scsi.h +++ b/drivers/scsi/arm/scsi.h @@ -74,7 +74,7 @@ static inline void init_SCp(Scsi_Cmnd *SCpnt) unsigned long len = 0; int buf; - SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->buffer; + SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer; SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1; SCpnt->SCp.ptr = (char *) (page_address(SCpnt->SCp.buffer->page) + diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 19745a31072..5e8afc87698 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c @@ -567,8 +567,8 @@ static int piix_sata_prereset(struct ata_port *ap) present = 1; } - DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n", - ap->id, pcs, present_mask); + DPRINTK("ata%u: LEAVE, pcs=0x%x present=0x%x\n", + ap->id, pcs, present); if (!present) { ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n"); @@ -828,6 +828,7 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev, case IDE: WARN_ON((i & 1) || map[i + 1] != IDE); pinfo[i / 2] = piix_port_info[ich5_pata]; + pinfo[i / 2].private_data = hpriv; i++; printk(" IDE IDE"); break; diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 386e5f21e19..16fc2dd8f2f 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -5185,28 +5185,6 @@ void ata_host_stop (struct ata_host_set *host_set) iounmap(host_set->mmio_base); } - -/** - * ata_host_remove - Unregister SCSI host structure with upper layers - * @ap: Port to unregister - * @do_unregister: 1 if we fully unregister, 0 to just stop the port - * - * LOCKING: - * Inherited from caller. - */ - -static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister) -{ - struct Scsi_Host *sh = ap->host; - - DPRINTK("ENTER\n"); - - if (do_unregister) - scsi_remove_host(sh); - - ap->ops->port_stop(ap); -} - /** * ata_dev_init - Initialize an ata_device structure * @dev: Device structure to initialize @@ -5532,8 +5510,11 @@ int ata_device_add(const struct ata_probe_ent *ent) err_out: for (i = 0; i < count; i++) { - ata_host_remove(host_set->ports[i], 1); - scsi_host_put(host_set->ports[i]->host); + struct ata_port *ap = host_set->ports[i]; + if (ap) { + ap->ops->port_stop(ap); + scsi_host_put(ap->host); + } } err_free_ret: kfree(host_set); @@ -5558,7 +5539,7 @@ void ata_port_detach(struct ata_port *ap) int i; if (!ap->ops->error_handler) - return; + goto skip_eh; /* tell EH we're leaving & flush EH */ spin_lock_irqsave(ap->lock, flags); @@ -5594,6 +5575,7 @@ void ata_port_detach(struct ata_port *ap) cancel_delayed_work(&ap->hotplug_task); flush_workqueue(ata_aux_wq); + skip_eh: /* remove the associated SCSI host */ scsi_remove_host(ap->host); } @@ -5662,7 +5644,7 @@ int ata_scsi_release(struct Scsi_Host *host) DPRINTK("ENTER\n"); ap->ops->port_disable(ap); - ata_host_remove(ap, 0); + ap->ops->port_stop(ap); DPRINTK("EXIT\n"); return 1; diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 7ced41ecde8..e92c31d698f 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -2353,6 +2353,19 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) ata_gen_ata_desc_sense(qc); } + /* SCSI EH automatically locks door if sdev->locked is + * set. Sometimes door lock request continues to + * fail, for example, when no media is present. This + * creates a loop - SCSI EH issues door lock which + * fails and gets invoked again to acquire sense data + * for the failed command. + * + * If door lock fails, always clear sdev->locked to + * avoid this infinite loop. + */ + if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL) + qc->dev->sdev->locked = 0; + qc->scsicmd->result = SAM_STAT_CHECK_CONDITION; qc->scsidone(cmd); ata_qc_free(qc); diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index 2e0f4a4076a..3f368c7d3ef 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c @@ -1106,7 +1106,6 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) probe_ent->irq = pdev->irq; probe_ent->irq_flags = IRQF_SHARED; - probe_ent->mmio_base = port_base; probe_ent->private_data = hpriv; hpriv->host_base = host_base; diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 822914e2f43..f7a975d5db0 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c @@ -110,7 +110,6 @@ static void au1xxx_start_ohc(struct platform_device *dev) printk(KERN_DEBUG __FILE__ ": Clock to USB host has been enabled \n"); -#endif } static void au1xxx_stop_ohc(struct platform_device *dev) diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c index 9e3f1390337..044faa07e29 100644 --- a/drivers/usb/input/appletouch.c +++ b/drivers/usb/input/appletouch.c @@ -597,9 +597,9 @@ static void atp_disconnect(struct usb_interface *iface) if (dev) { usb_kill_urb(dev->urb); input_unregister_device(dev->input); - usb_free_urb(dev->urb); usb_buffer_free(dev->udev, dev->datalen, dev->data, dev->urb->transfer_dma); + usb_free_urb(dev->urb); kfree(dev); } printk(KERN_INFO "input: appletouch disconnected\n"); diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 786e1dbe88e..983e104dd45 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -1242,11 +1242,12 @@ done: static int ctrl_out (struct usbtest_dev *dev, unsigned count, unsigned length, unsigned vary) { - unsigned i, j, len, retval; + unsigned i, j, len; + int retval; u8 *buf; char *what = "?"; struct usb_device *udev; - + if (length < 1 || length > 0xffff || vary >= length) return -EINVAL; diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index a20da8528a5..15945e806f0 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -306,6 +306,8 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { static struct usb_device_id id_table_combined [] = { + { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ACTZWAVE_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_IPLUS_PID) }, diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 9f7343a4542..8888cd80a49 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -32,6 +32,12 @@ #define FTDI_NF_RIC_PID 0x0001 /* Product Id */ +/* www.canusb.com Lawicel CANUSB device */ +#define FTDI_CANUSB_PID 0xFFA8 /* Product Id */ + +/* AlphaMicro Components AMC-232USB01 device */ +#define FTDI_AMC232_PID 0xFF00 /* Product Id */ + /* ACT Solutions HomePro ZWave interface (http://www.act-solutions.com/HomePro.htm) */ #define FTDI_ACTZWAVE_PID 0xF2D0 diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 7e1bd5d6dfa..9840bade79f 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -251,6 +251,8 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */ { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */ { USB_DEVICE(0x04DD, 0x9102) }, /* SHARP WS003SH USB Modem */ + { USB_DEVICE(0x04DD, 0x9121) }, /* SHARP WS004SH USB Modem */ + { USB_DEVICE(0x04DD, 0x9123) }, /* SHARP WS007SH USB Modem */ { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 2793f9a912b..fd158e063c0 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1240,6 +1240,16 @@ UNUSUAL_DEV( 0x0ed1, 0x7636, 0x0103, 0x0103, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64), +/* David Kuehling <dvdkhlng@gmx.de>: + * for MP3-Player AVOX WSX-300ER (bought in Japan). Reports lots of SCSI + * errors when trying to write. + */ +UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x0100, + "C-MEX", + "A-VOX", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + /* Reported by Michael Stattmann <michael@stattmann.com> */ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, "Sony Ericsson", diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index c40b9b8b1e7..702eb933cf8 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -554,7 +554,7 @@ config FB_VESA config FB_IMAC bool "Intel-based Macintosh Framebuffer Support" - depends on (FB = y) && X86 + depends on (FB = y) && X86 && EFI select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT diff --git a/drivers/video/imacfb.c b/drivers/video/imacfb.c index ff233b84dec..b485bece5fc 100644 --- a/drivers/video/imacfb.c +++ b/drivers/video/imacfb.c @@ -18,6 +18,8 @@ #include <linux/screen_info.h> #include <linux/slab.h> #include <linux/string.h> +#include <linux/dmi.h> +#include <linux/efi.h> #include <asm/io.h> @@ -28,7 +30,7 @@ typedef enum _MAC_TYPE { M_I20, M_MINI, M_MACBOOK, - M_NEW + M_UNKNOWN } MAC_TYPE; /* --------------------------------------------------------------------- */ @@ -52,10 +54,36 @@ static struct fb_fix_screeninfo imacfb_fix __initdata = { }; static int inverse; -static int model = M_NEW; +static int model = M_UNKNOWN; static int manual_height; static int manual_width; +static int set_system(struct dmi_system_id *id) +{ + printk(KERN_INFO "imacfb: %s detected - set system to %ld\n", + id->ident, (long)id->driver_data); + + model = (long)id->driver_data; + + return 0; +} + +static struct dmi_system_id __initdata dmi_system_table[] = { + { set_system, "iMac4,1", { + DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."), + DMI_MATCH(DMI_BIOS_VERSION,"iMac4,1") }, (void*)M_I17}, + { set_system, "MacBookPro1,1", { + DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."), + DMI_MATCH(DMI_BIOS_VERSION,"MacBookPro1,1") }, (void*)M_I17}, + { set_system, "MacBook1,1", { + DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."), + DMI_MATCH(DMI_PRODUCT_NAME,"MacBook1,1")}, (void *)M_MACBOOK}, + { set_system, "Macmini1,1", { + DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."), + DMI_MATCH(DMI_PRODUCT_NAME,"Macmini1,1")}, (void *)M_MINI}, + {}, +}; + #define DEFAULT_FB_MEM 1024*1024*16 /* --------------------------------------------------------------------- */ @@ -149,7 +177,6 @@ static int __init imacfb_probe(struct platform_device *dev) screen_info.lfb_linelength = 1472 * 4; screen_info.lfb_base = 0x80010000; break; - case M_NEW: case M_I20: screen_info.lfb_width = 1680; screen_info.lfb_height = 1050; @@ -207,6 +234,10 @@ static int __init imacfb_probe(struct platform_device *dev) size_remap = size_total; imacfb_fix.smem_len = size_remap; +#ifndef __i386__ + screen_info.imacpm_seg = 0; +#endif + if (!request_mem_region(imacfb_fix.smem_start, size_total, "imacfb")) { printk(KERN_WARNING "imacfb: cannot reserve video memory at 0x%lx\n", @@ -324,8 +355,16 @@ static int __init imacfb_init(void) int ret; char *option = NULL; - /* ignore error return of fb_get_options */ - fb_get_options("imacfb", &option); + if (!efi_enabled) + return -ENODEV; + if (!dmi_check_system(dmi_system_table)) + return -ENODEV; + if (model == M_UNKNOWN) + return -ENODEV; + + if (fb_get_options("imacfb", &option)) + return -ENODEV; + imacfb_setup(option); ret = platform_driver_register(&imacfb_driver); diff --git a/fs/adfs/super.c b/fs/adfs/super.c index ba1c88af49f..82011019494 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -308,7 +308,7 @@ static struct adfs_discmap *adfs_read_map(struct super_block *sb, struct adfs_di if (adfs_checkmap(sb, dm)) return dm; - adfs_error(sb, NULL, "map corrupted"); + adfs_error(sb, "map corrupted"); error_free: while (--zone >= 0) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 63614ed1633..5c4fcd1dbf5 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -395,14 +395,16 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, struct fuse_readpages_data data; int err; + err = -EIO; if (is_bad_inode(inode)) - return -EIO; + goto clean_pages_up; data.file = file; data.inode = inode; data.req = fuse_get_req(fc); + err = PTR_ERR(data.req); if (IS_ERR(data.req)) - return PTR_ERR(data.req); + goto clean_pages_up; err = read_cache_pages(mapping, pages, fuse_readpages_fill, &data); if (!err) { @@ -412,6 +414,10 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, fuse_put_request(fc, data.req); } return err; + +clean_pages_up: + put_pages_list(pages); + return err; } static size_t fuse_send_write(struct fuse_req *req, struct file *file, diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c index 43e3f566aad..a223cf4faa9 100644 --- a/fs/jfs/inode.c +++ b/fs/jfs/inode.c @@ -168,16 +168,15 @@ void jfs_dirty_inode(struct inode *inode) set_cflag(COMMIT_Dirty, inode); } -static int -jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, - struct buffer_head *bh_result, int create) +int jfs_get_block(struct inode *ip, sector_t lblock, + struct buffer_head *bh_result, int create) { s64 lblock64 = lblock; int rc = 0; xad_t xad; s64 xaddr; int xflag; - s32 xlen = max_blocks; + s32 xlen = bh_result->b_size >> ip->i_blkbits; /* * Take appropriate lock on inode @@ -188,7 +187,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, IREAD_LOCK(ip); if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) && - (!xtLookup(ip, lblock64, max_blocks, &xflag, &xaddr, &xlen, 0)) && + (!xtLookup(ip, lblock64, xlen, &xflag, &xaddr, &xlen, 0)) && xaddr) { if (xflag & XAD_NOTRECORDED) { if (!create) @@ -255,13 +254,6 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks, return rc; } -static int jfs_get_block(struct inode *ip, sector_t lblock, - struct buffer_head *bh_result, int create) -{ - return jfs_get_blocks(ip, lblock, bh_result->b_size >> ip->i_blkbits, - bh_result, create); -} - static int jfs_writepage(struct page *page, struct writeback_control *wbc) { return nobh_writepage(page, jfs_get_block, wbc); diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index b5c7da6190d..1fc48df670c 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h @@ -32,6 +32,7 @@ extern void jfs_truncate_nolock(struct inode *, loff_t); extern void jfs_free_zero_link(struct inode *); extern struct dentry *jfs_get_parent(struct dentry *dentry); extern void jfs_set_inode_flags(struct inode *); +extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int); extern const struct address_space_operations jfs_aops; extern struct inode_operations jfs_dir_inode_operations; diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 4f6cfebc82d..143bcd1d5ea 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -26,6 +26,7 @@ #include <linux/moduleparam.h> #include <linux/kthread.h> #include <linux/posix_acl.h> +#include <linux/buffer_head.h> #include <asm/uaccess.h> #include <linux/seq_file.h> @@ -298,7 +299,7 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, break; } -#if defined(CONFIG_QUOTA) +#ifdef CONFIG_QUOTA case Opt_quota: case Opt_usrquota: *flag |= JFS_USRQUOTA; @@ -597,7 +598,7 @@ static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs) if (sbi->flag & JFS_NOINTEGRITY) seq_puts(seq, ",nointegrity"); -#if defined(CONFIG_QUOTA) +#ifdef CONFIG_QUOTA if (sbi->flag & JFS_USRQUOTA) seq_puts(seq, ",usrquota"); @@ -608,6 +609,113 @@ static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs) return 0; } +#ifdef CONFIG_QUOTA + +/* Read data from quotafile - avoid pagecache and such because we cannot afford + * acquiring the locks... As quota files are never truncated and quota code + * itself serializes the operations (and noone else should touch the files) + * we don't have to be afraid of races */ +static ssize_t jfs_quota_read(struct super_block *sb, int type, char *data, + size_t len, loff_t off) +{ + struct inode *inode = sb_dqopt(sb)->files[type]; + sector_t blk = off >> sb->s_blocksize_bits; + int err = 0; + int offset = off & (sb->s_blocksize - 1); + int tocopy; + size_t toread; + struct buffer_head tmp_bh; + struct buffer_head *bh; + loff_t i_size = i_size_read(inode); + + if (off > i_size) + return 0; + if (off+len > i_size) + len = i_size-off; + toread = len; + while (toread > 0) { + tocopy = sb->s_blocksize - offset < toread ? + sb->s_blocksize - offset : toread; + + tmp_bh.b_state = 0; + tmp_bh.b_size = 1 << inode->i_blkbits; + err = jfs_get_block(inode, blk, &tmp_bh, 0); + if (err) + return err; + if (!buffer_mapped(&tmp_bh)) /* A hole? */ + memset(data, 0, tocopy); + else { + bh = sb_bread(sb, tmp_bh.b_blocknr); + if (!bh) + return -EIO; + memcpy(data, bh->b_data+offset, tocopy); + brelse(bh); + } + offset = 0; + toread -= tocopy; + data += tocopy; + blk++; + } + return len; +} + +/* Write to quotafile */ +static ssize_t jfs_quota_write(struct super_block *sb, int type, + const char *data, size_t len, loff_t off) +{ + struct inode *inode = sb_dqopt(sb)->files[type]; + sector_t blk = off >> sb->s_blocksize_bits; + int err = 0; + int offset = off & (sb->s_blocksize - 1); + int tocopy; + size_t towrite = len; + struct buffer_head tmp_bh; + struct buffer_head *bh; + + mutex_lock(&inode->i_mutex); + while (towrite > 0) { + tocopy = sb->s_blocksize - offset < towrite ? + sb->s_blocksize - offset : towrite; + + tmp_bh.b_state = 0; + tmp_bh.b_size = 1 << inode->i_blkbits; + err = jfs_get_block(inode, blk, &tmp_bh, 1); + if (err) + goto out; + if (offset || tocopy != sb->s_blocksize) + bh = sb_bread(sb, tmp_bh.b_blocknr); + else + bh = sb_getblk(sb, tmp_bh.b_blocknr); + if (!bh) { + err = -EIO; + goto out; + } + lock_buffer(bh); + memcpy(bh->b_data+offset, data, tocopy); + flush_dcache_page(bh->b_page); + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + unlock_buffer(bh); + brelse(bh); + offset = 0; + towrite -= tocopy; + data += tocopy; + blk++; + } +out: + if (len == towrite) + return err; + if (inode->i_size < off+len-towrite) + i_size_write(inode, off+len-towrite); + inode->i_version++; + inode->i_mtime = inode->i_ctime = CURRENT_TIME; + mark_inode_dirty(inode); + mutex_unlock(&inode->i_mutex); + return len - towrite; +} + +#endif + static struct super_operations jfs_super_operations = { .alloc_inode = jfs_alloc_inode, .destroy_inode = jfs_destroy_inode, @@ -621,7 +729,11 @@ static struct super_operations jfs_super_operations = { .unlockfs = jfs_unlockfs, .statfs = jfs_statfs, .remount_fs = jfs_remount, - .show_options = jfs_show_options + .show_options = jfs_show_options, +#ifdef CONFIG_QUOTA + .quota_read = jfs_quota_read, + .quota_write = jfs_quota_write, +#endif }; static struct export_operations jfs_export_operations = { diff --git a/fs/locks.c b/fs/locks.c index b0b41a64e10..d7c53392cac 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1421,8 +1421,9 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp) if (!leases_enable) goto out; - error = lease_alloc(filp, arg, &fl); - if (error) + error = -ENOMEM; + fl = locks_alloc_lock(); + if (fl == NULL) goto out; locks_copy_lock(fl, lease); @@ -1430,6 +1431,7 @@ static int __setlease(struct file *filp, long arg, struct file_lock **flp) locks_insert_lock(before, fl); *flp = fl; + error = 0; out: return error; } diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 1b8346dd057..9503240ef0e 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -2375,7 +2375,6 @@ leave: mlog(0, "returning %d\n", ret); return ret; } -EXPORT_SYMBOL_GPL(dlm_migrate_lockres); int dlm_lock_basts_flushed(struct dlm_ctxt *dlm, struct dlm_lock *lock) { diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c index b0c3134f4f7..37be4b2e0d4 100644 --- a/fs/ocfs2/dlm/dlmunlock.c +++ b/fs/ocfs2/dlm/dlmunlock.c @@ -155,7 +155,7 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, else status = dlm_get_unlock_actions(dlm, res, lock, lksb, &actions); - if (status != DLM_NORMAL) + if (status != DLM_NORMAL && (status != DLM_CANCELGRANT || !master_node)) goto leave; /* By now this has been masked out of cancel requests. */ @@ -183,8 +183,7 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, spin_lock(&lock->spinlock); /* if the master told us the lock was already granted, * let the ast handle all of these actions */ - if (status == DLM_NORMAL && - lksb->status == DLM_CANCELGRANT) { + if (status == DLM_CANCELGRANT) { actions &= ~(DLM_UNLOCK_REMOVE_LOCK| DLM_UNLOCK_REGRANT_LOCK| DLM_UNLOCK_CLEAR_CONVERT_TYPE); @@ -349,14 +348,9 @@ static enum dlm_status dlm_send_remote_unlock_request(struct dlm_ctxt *dlm, vec, veclen, owner, &status); if (tmpret >= 0) { // successfully sent and received - if (status == DLM_CANCELGRANT) - ret = DLM_NORMAL; - else if (status == DLM_FORWARD) { + if (status == DLM_FORWARD) mlog(0, "master was in-progress. retry\n"); - ret = DLM_FORWARD; - } else - ret = status; - lksb->status = status; + ret = status; } else { mlog_errno(tmpret); if (dlm_is_host_down(tmpret)) { @@ -372,7 +366,6 @@ static enum dlm_status dlm_send_remote_unlock_request(struct dlm_ctxt *dlm, /* something bad. this will BUG in ocfs2 */ ret = dlm_err_to_dlm_status(tmpret); } - lksb->status = ret; } return ret; @@ -483,6 +476,10 @@ int dlm_unlock_lock_handler(struct o2net_msg *msg, u32 len, void *data) /* lock was found on queue */ lksb = lock->lksb; + if (flags & (LKM_VALBLK|LKM_PUT_LVB) && + lock->ml.type != LKM_EXMODE) + flags &= ~(LKM_VALBLK|LKM_PUT_LVB); + /* unlockast only called on originating node */ if (flags & LKM_PUT_LVB) { lksb->flags |= DLM_LKSB_PUT_LVB; @@ -507,11 +504,8 @@ not_found: "cookie=%u:%llu\n", dlm_get_lock_cookie_node(unlock->cookie), dlm_get_lock_cookie_seq(unlock->cookie)); - else { - /* send the lksb->status back to the other node */ - status = lksb->status; + else dlm_lock_put(lock); - } leave: if (res) @@ -533,26 +527,22 @@ static enum dlm_status dlm_get_cancel_actions(struct dlm_ctxt *dlm, if (dlm_lock_on_list(&res->blocked, lock)) { /* cancel this outright */ - lksb->status = DLM_NORMAL; status = DLM_NORMAL; *actions = (DLM_UNLOCK_CALL_AST | DLM_UNLOCK_REMOVE_LOCK); } else if (dlm_lock_on_list(&res->converting, lock)) { /* cancel the request, put back on granted */ - lksb->status = DLM_NORMAL; status = DLM_NORMAL; *actions = (DLM_UNLOCK_CALL_AST | DLM_UNLOCK_REMOVE_LOCK | DLM_UNLOCK_REGRANT_LOCK | DLM_UNLOCK_CLEAR_CONVERT_TYPE); } else if (dlm_lock_on_list(&res->granted, lock)) { - /* too late, already granted. DLM_CANCELGRANT */ - lksb->status = DLM_CANCELGRANT; - status = DLM_NORMAL; + /* too late, already granted. */ + status = DLM_CANCELGRANT; *actions = DLM_UNLOCK_CALL_AST; } else { mlog(ML_ERROR, "lock to cancel is not on any list!\n"); - lksb->status = DLM_IVLOCKID; status = DLM_IVLOCKID; *actions = 0; } @@ -569,13 +559,11 @@ static enum dlm_status dlm_get_unlock_actions(struct dlm_ctxt *dlm, /* unlock request */ if (!dlm_lock_on_list(&res->granted, lock)) { - lksb->status = DLM_DENIED; status = DLM_DENIED; dlm_error(status); *actions = 0; } else { /* unlock granted lock */ - lksb->status = DLM_NORMAL; status = DLM_NORMAL; *actions = (DLM_UNLOCK_FREE_LOCK | DLM_UNLOCK_CALL_AST | @@ -632,6 +620,8 @@ retry: spin_lock(&res->spinlock); is_master = (res->owner == dlm->node_num); + if (flags & LKM_VALBLK && lock->ml.type != LKM_EXMODE) + flags &= ~LKM_VALBLK; spin_unlock(&res->spinlock); if (is_master) { @@ -665,7 +655,7 @@ retry: } if (call_ast) { - mlog(0, "calling unlockast(%p, %d)\n", data, lksb->status); + mlog(0, "calling unlockast(%p, %d)\n", data, status); if (is_master) { /* it is possible that there is one last bast * pending. make sure it is flushed, then @@ -677,9 +667,12 @@ retry: wait_event(dlm->ast_wq, dlm_lock_basts_flushed(dlm, lock)); } - (*unlockast)(data, lksb->status); + (*unlockast)(data, status); } + if (status == DLM_CANCELGRANT) + status = DLM_NORMAL; + if (status == DLM_NORMAL) { mlog(0, "kicking the thread\n"); dlm_kick_thread(dlm, res); diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index 0d1973ea32b..1f17a4d0828 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c @@ -840,6 +840,12 @@ static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, mlog(0, "Allocating %u clusters for a new window.\n", ocfs2_local_alloc_window_bits(osb)); + + /* Instruct the allocation code to try the most recently used + * cluster group. We'll re-record the group used this pass + * below. */ + ac->ac_last_group = osb->la_last_gd; + /* we used the generic suballoc reserve function, but we set * everything up nicely, so there's no reason why we can't use * the more specific cluster api to claim bits. */ @@ -852,6 +858,8 @@ static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, goto bail; } + osb->la_last_gd = ac->ac_last_group; + la->la_bm_off = cpu_to_le32(cluster_off); alloc->id1.bitmap1.i_total = cpu_to_le32(cluster_count); /* just in case... In the future when we find space ourselves, diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index cd4a6f253d1..0462a7f4e21 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -197,7 +197,6 @@ struct ocfs2_super struct ocfs2_node_map recovery_map; struct ocfs2_node_map umount_map; - u32 num_clusters; u64 root_blkno; u64 system_dir_blkno; u64 bitmap_blkno; @@ -237,6 +236,7 @@ struct ocfs2_super enum ocfs2_local_alloc_state local_alloc_state; struct buffer_head *local_alloc_bh; + u64 la_last_gd; /* Next two fields are for local node slot recovery during * mount. */ diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 195523090c8..9d91e66f51a 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c @@ -70,12 +70,6 @@ static int ocfs2_block_group_search(struct inode *inode, struct buffer_head *group_bh, u32 bits_wanted, u32 min_bits, u16 *bit_off, u16 *bits_found); -static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, - u32 bits_wanted, - u32 min_bits, - u16 *bit_off, - unsigned int *num_bits, - u64 *bg_blkno); static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, struct ocfs2_alloc_context *ac, u32 bits_wanted, @@ -85,11 +79,6 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, u64 *bg_blkno); static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh, int nr); -static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, - struct buffer_head *bg_bh, - unsigned int bits_wanted, - u16 *bit_off, - u16 *bits_found); static inline int ocfs2_block_group_set_bits(struct ocfs2_journal_handle *handle, struct inode *alloc_inode, struct ocfs2_group_desc *bg, @@ -143,6 +132,64 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl) return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc); } +/* somewhat more expensive than our other checks, so use sparingly. */ +static int ocfs2_check_group_descriptor(struct super_block *sb, + struct ocfs2_dinode *di, + struct ocfs2_group_desc *gd) +{ + unsigned int max_bits; + + if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { + OCFS2_RO_ON_INVALID_GROUP_DESC(sb, gd); + return -EIO; + } + + if (di->i_blkno != gd->bg_parent_dinode) { + ocfs2_error(sb, "Group descriptor # %llu has bad parent " + "pointer (%llu, expected %llu)", + (unsigned long long)le64_to_cpu(gd->bg_blkno), + (unsigned long long)le64_to_cpu(gd->bg_parent_dinode), + (unsigned long long)le64_to_cpu(di->i_blkno)); + return -EIO; + } + + max_bits = le16_to_cpu(di->id2.i_chain.cl_cpg) * le16_to_cpu(di->id2.i_chain.cl_bpc); + if (le16_to_cpu(gd->bg_bits) > max_bits) { + ocfs2_error(sb, "Group descriptor # %llu has bit count of %u", + (unsigned long long)le64_to_cpu(gd->bg_blkno), + le16_to_cpu(gd->bg_bits)); + return -EIO; + } + + if (le16_to_cpu(gd->bg_chain) >= + le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) { + ocfs2_error(sb, "Group descriptor # %llu has bad chain %u", + (unsigned long long)le64_to_cpu(gd->bg_blkno), + le16_to_cpu(gd->bg_chain)); + return -EIO; + } + + if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) { + ocfs2_error(sb, "Group descriptor # %llu has bit count %u but " + "claims that %u are free", + (unsigned long long)le64_to_cpu(gd->bg_blkno), + le16_to_cpu(gd->bg_bits), + le16_to_cpu(gd->bg_free_bits_count)); + return -EIO; + } + + if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) { + ocfs2_error(sb, "Group descriptor # %llu has bit count %u but " + "max bitmap bits of %u", + (unsigned long long)le64_to_cpu(gd->bg_blkno), + le16_to_cpu(gd->bg_bits), + 8 * le16_to_cpu(gd->bg_size)); + return -EIO; + } + + return 0; +} + static int ocfs2_block_group_fill(struct ocfs2_journal_handle *handle, struct inode *alloc_inode, struct buffer_head *bg_bh, @@ -663,6 +710,7 @@ static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh, static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, struct buffer_head *bg_bh, unsigned int bits_wanted, + unsigned int total_bits, u16 *bit_off, u16 *bits_found) { @@ -679,10 +727,8 @@ static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, found = start = best_offset = best_size = 0; bitmap = bg->bg_bitmap; - while((offset = ocfs2_find_next_zero_bit(bitmap, - le16_to_cpu(bg->bg_bits), - start)) != -1) { - if (offset == le16_to_cpu(bg->bg_bits)) + while((offset = ocfs2_find_next_zero_bit(bitmap, total_bits, start)) != -1) { + if (offset == total_bits) break; if (!ocfs2_test_bg_bit_allocatable(bg_bh, offset)) { @@ -911,14 +957,35 @@ static int ocfs2_cluster_group_search(struct inode *inode, { int search = -ENOSPC; int ret; - struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) group_bh->b_data; + struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *) group_bh->b_data; u16 tmp_off, tmp_found; + unsigned int max_bits, gd_cluster_off; BUG_ON(!ocfs2_is_cluster_bitmap(inode)); - if (bg->bg_free_bits_count) { + if (gd->bg_free_bits_count) { + max_bits = le16_to_cpu(gd->bg_bits); + + /* Tail groups in cluster bitmaps which aren't cpg + * aligned are prone to partial extention by a failed + * fs resize. If the file system resize never got to + * update the dinode cluster count, then we don't want + * to trust any clusters past it, regardless of what + * the group descriptor says. */ + gd_cluster_off = ocfs2_blocks_to_clusters(inode->i_sb, + le64_to_cpu(gd->bg_blkno)); + if ((gd_cluster_off + max_bits) > + OCFS2_I(inode)->ip_clusters) { + max_bits = OCFS2_I(inode)->ip_clusters - gd_cluster_off; + mlog(0, "Desc %llu, bg_bits %u, clusters %u, use %u\n", + (unsigned long long)le64_to_cpu(gd->bg_blkno), + le16_to_cpu(gd->bg_bits), + OCFS2_I(inode)->ip_clusters, max_bits); + } + ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb), group_bh, bits_wanted, + max_bits, &tmp_off, &tmp_found); if (ret) return ret; @@ -951,17 +1018,109 @@ static int ocfs2_block_group_search(struct inode *inode, if (bg->bg_free_bits_count) ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb), group_bh, bits_wanted, + le16_to_cpu(bg->bg_bits), bit_off, bits_found); return ret; } +static int ocfs2_alloc_dinode_update_counts(struct inode *inode, + struct ocfs2_journal_handle *handle, + struct buffer_head *di_bh, + u32 num_bits, + u16 chain) +{ + int ret; + u32 tmp_used; + struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; + struct ocfs2_chain_list *cl = (struct ocfs2_chain_list *) &di->id2.i_chain; + + ret = ocfs2_journal_access(handle, inode, di_bh, + OCFS2_JOURNAL_ACCESS_WRITE); + if (ret < 0) { + mlog_errno(ret); + goto out; + } + + tmp_used = le32_to_cpu(di->id1.bitmap1.i_used); + di->id1.bitmap1.i_used = cpu_to_le32(num_bits + tmp_used); + le32_add_cpu(&cl->cl_recs[chain].c_free, -num_bits); + + ret = ocfs2_journal_dirty(handle, di_bh); + if (ret < 0) + mlog_errno(ret); + +out: + return ret; +} + +static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, + u32 bits_wanted, + u32 min_bits, + u16 *bit_off, + unsigned int *num_bits, + u64 gd_blkno, + u16 *bits_left) +{ + int ret; + u16 found; + struct buffer_head *group_bh = NULL; + struct ocfs2_group_desc *gd; + struct inode *alloc_inode = ac->ac_inode; + struct ocfs2_journal_handle *handle = ac->ac_handle; + + ret = ocfs2_read_block(OCFS2_SB(alloc_inode->i_sb), gd_blkno, + &group_bh, OCFS2_BH_CACHED, alloc_inode); + if (ret < 0) { + mlog_errno(ret); + return ret; + } + + gd = (struct ocfs2_group_desc *) group_bh->b_data; + if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { + OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, gd); + ret = -EIO; + goto out; + } + + ret = ac->ac_group_search(alloc_inode, group_bh, bits_wanted, min_bits, + bit_off, &found); + if (ret < 0) { + if (ret != -ENOSPC) + mlog_errno(ret); + goto out; + } + + *num_bits = found; + + ret = ocfs2_alloc_dinode_update_counts(alloc_inode, handle, ac->ac_bh, + *num_bits, + le16_to_cpu(gd->bg_chain)); + if (ret < 0) { + mlog_errno(ret); + goto out; + } + + ret = ocfs2_block_group_set_bits(handle, alloc_inode, gd, group_bh, + *bit_off, *num_bits); + if (ret < 0) + mlog_errno(ret); + + *bits_left = le16_to_cpu(gd->bg_free_bits_count); + +out: + brelse(group_bh); + + return ret; +} + static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, u32 bits_wanted, u32 min_bits, u16 *bit_off, unsigned int *num_bits, - u64 *bg_blkno) + u64 *bg_blkno, + u16 *bits_left) { int status; u16 chain, tmp_bits; @@ -988,9 +1147,9 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, goto bail; } bg = (struct ocfs2_group_desc *) group_bh->b_data; - if (!OCFS2_IS_VALID_GROUP_DESC(bg)) { - OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg); - status = -EIO; + status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, bg); + if (status) { + mlog_errno(status); goto bail; } @@ -1018,9 +1177,9 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, goto bail; } bg = (struct ocfs2_group_desc *) group_bh->b_data; - if (!OCFS2_IS_VALID_GROUP_DESC(bg)) { - OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, bg); - status = -EIO; + status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, bg); + if (status) { + mlog_errno(status); goto bail; } } @@ -1099,6 +1258,7 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, (unsigned long long)fe->i_blkno); *bg_blkno = le64_to_cpu(bg->bg_blkno); + *bits_left = le16_to_cpu(bg->bg_free_bits_count); bail: if (group_bh) brelse(group_bh); @@ -1120,6 +1280,8 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, { int status; u16 victim, i; + u16 bits_left = 0; + u64 hint_blkno = ac->ac_last_group; struct ocfs2_chain_list *cl; struct ocfs2_dinode *fe; @@ -1146,6 +1308,28 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, goto bail; } + if (hint_blkno) { + /* Attempt to short-circuit the usual search mechanism + * by jumping straight to the most recently used + * allocation group. This helps us mantain some + * contiguousness across allocations. */ + status = ocfs2_search_one_group(ac, bits_wanted, min_bits, + bit_off, num_bits, + hint_blkno, &bits_left); + if (!status) { + /* Be careful to update *bg_blkno here as the + * caller is expecting it to be filled in, and + * ocfs2_search_one_group() won't do that for + * us. */ + *bg_blkno = hint_blkno; + goto set_hint; + } + if (status < 0 && status != -ENOSPC) { + mlog_errno(status); + goto bail; + } + } + cl = (struct ocfs2_chain_list *) &fe->id2.i_chain; victim = ocfs2_find_victim_chain(cl); @@ -1153,9 +1337,9 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, ac->ac_allow_chain_relink = 1; status = ocfs2_search_chain(ac, bits_wanted, min_bits, bit_off, - num_bits, bg_blkno); + num_bits, bg_blkno, &bits_left); if (!status) - goto bail; + goto set_hint; if (status < 0 && status != -ENOSPC) { mlog_errno(status); goto bail; @@ -1177,8 +1361,8 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, ac->ac_chain = i; status = ocfs2_search_chain(ac, bits_wanted, min_bits, - bit_off, num_bits, - bg_blkno); + bit_off, num_bits, bg_blkno, + &bits_left); if (!status) break; if (status < 0 && status != -ENOSPC) { @@ -1186,8 +1370,19 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, goto bail; } } -bail: +set_hint: + if (status != -ENOSPC) { + /* If the next search of this group is not likely to + * yield a suitable extent, then we reset the last + * group hint so as to not waste a disk read */ + if (bits_left < min_bits) + ac->ac_last_group = 0; + else + ac->ac_last_group = *bg_blkno; + } + +bail: mlog_exit(status); return status; } @@ -1341,7 +1536,7 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb, { int status; unsigned int bits_wanted = ac->ac_bits_wanted - ac->ac_bits_given; - u64 bg_blkno; + u64 bg_blkno = 0; u16 bg_bit_off; mlog_entry_void(); @@ -1494,9 +1689,9 @@ static int ocfs2_free_suballoc_bits(struct ocfs2_journal_handle *handle, } group = (struct ocfs2_group_desc *) group_bh->b_data; - if (!OCFS2_IS_VALID_GROUP_DESC(group)) { - OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, group); - status = -EIO; + status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, group); + if (status) { + mlog_errno(status); goto bail; } BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits)); diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h index a76c82a7cea..c787838d105 100644 --- a/fs/ocfs2/suballoc.h +++ b/fs/ocfs2/suballoc.h @@ -49,6 +49,8 @@ struct ocfs2_alloc_context { u16 ac_chain; int ac_allow_chain_relink; group_search_t *ac_group_search; + + u64 ac_last_group; }; void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac); diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 382706a67ff..d17e33e66a1 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1442,8 +1442,13 @@ static int ocfs2_initialize_super(struct super_block *sb, osb->bitmap_blkno = OCFS2_I(inode)->ip_blkno; + /* We don't have a cluster lock on the bitmap here because + * we're only interested in static information and the extra + * complexity at mount time isn't worht it. Don't pass the + * inode in to the read function though as we don't want it to + * be put in the cache. */ status = ocfs2_read_block(osb, osb->bitmap_blkno, &bitmap_bh, 0, - inode); + NULL); iput(inode); if (status < 0) { mlog_errno(status); @@ -1452,7 +1457,6 @@ static int ocfs2_initialize_super(struct super_block *sb, di = (struct ocfs2_dinode *) bitmap_bh->b_data; osb->bitmap_cpg = le16_to_cpu(di->id2.i_chain.cl_cpg); - osb->num_clusters = le32_to_cpu(di->id1.bitmap1.i_total); brelse(bitmap_bh); mlog(0, "cluster bitmap inode: %llu, clusters per group: %u\n", (unsigned long long)osb->bitmap_blkno, osb->bitmap_cpg); diff --git a/fs/udf/super.c b/fs/udf/super.c index 4df822c881b..7de172efa08 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -115,6 +115,13 @@ static struct inode *udf_alloc_inode(struct super_block *sb) ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, SLAB_KERNEL); if (!ei) return NULL; + + ei->i_unique = 0; + ei->i_lenExtents = 0; + ei->i_next_alloc_block = 0; + ei->i_next_alloc_goal = 0; + ei->i_strat4096 = 0; + return &ei->vfs_inode; } diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index eef6763f3a6..d2bbcd882a6 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c @@ -1835,40 +1835,47 @@ xfs_alloc_fix_freelist( &agbp))) return error; if (!pag->pagf_init) { + ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK); + ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); args->agbp = NULL; return 0; } } else agbp = NULL; - /* If this is a metadata preferred pag and we are user data + /* + * If this is a metadata preferred pag and we are user data * then try somewhere else if we are not being asked to * try harder at this point */ - if (pag->pagf_metadata && args->userdata && flags) { + if (pag->pagf_metadata && args->userdata && + (flags & XFS_ALLOC_FLAG_TRYLOCK)) { + ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); args->agbp = NULL; return 0; } - need = XFS_MIN_FREELIST_PAG(pag, mp); - delta = need > pag->pagf_flcount ? need - pag->pagf_flcount : 0; - /* - * If it looks like there isn't a long enough extent, or enough - * total blocks, reject it. - */ - longest = (pag->pagf_longest > delta) ? - (pag->pagf_longest - delta) : - (pag->pagf_flcount > 0 || pag->pagf_longest > 0); - if (args->minlen + args->alignment + args->minalignslop - 1 > longest || - (!(flags & XFS_ALLOC_FLAG_FREEING) && - (int)(pag->pagf_freeblks + pag->pagf_flcount - - need - args->total) < - (int)args->minleft)) { - if (agbp) - xfs_trans_brelse(tp, agbp); - args->agbp = NULL; - return 0; + if (!(flags & XFS_ALLOC_FLAG_FREEING)) { + need = XFS_MIN_FREELIST_PAG(pag, mp); + delta = need > pag->pagf_flcount ? need - pag->pagf_flcount : 0; + /* + * If it looks like there isn't a long enough extent, or enough + * total blocks, reject it. + */ + longest = (pag->pagf_longest > delta) ? + (pag->pagf_longest - delta) : + (pag->pagf_flcount > 0 || pag->pagf_longest > 0); + if ((args->minlen + args->alignment + args->minalignslop - 1) > + longest || + ((int)(pag->pagf_freeblks + pag->pagf_flcount - + need - args->total) < (int)args->minleft)) { + if (agbp) + xfs_trans_brelse(tp, agbp); + args->agbp = NULL; + return 0; + } } + /* * Get the a.g. freespace buffer. * Can fail if we're not blocking on locks, and it's held. @@ -1878,6 +1885,8 @@ xfs_alloc_fix_freelist( &agbp))) return error; if (agbp == NULL) { + ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK); + ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING)); args->agbp = NULL; return 0; } @@ -1887,22 +1896,24 @@ xfs_alloc_fix_freelist( */ agf = XFS_BUF_TO_AGF(agbp); need = XFS_MIN_FREELIST(agf, mp); - delta = need > be32_to_cpu(agf->agf_flcount) ? - (need - be32_to_cpu(agf->agf_flcount)) : 0; /* * If there isn't enough total or single-extent, reject it. */ - longest = be32_to_cpu(agf->agf_longest); - longest = (longest > delta) ? (longest - delta) : - (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); - if (args->minlen + args->alignment + args->minalignslop - 1 > longest || - (!(flags & XFS_ALLOC_FLAG_FREEING) && - (int)(be32_to_cpu(agf->agf_freeblks) + - be32_to_cpu(agf->agf_flcount) - need - args->total) < - (int)args->minleft)) { - xfs_trans_brelse(tp, agbp); - args->agbp = NULL; - return 0; + if (!(flags & XFS_ALLOC_FLAG_FREEING)) { + delta = need > be32_to_cpu(agf->agf_flcount) ? + (need - be32_to_cpu(agf->agf_flcount)) : 0; + longest = be32_to_cpu(agf->agf_longest); + longest = (longest > delta) ? (longest - delta) : + (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0); + if ((args->minlen + args->alignment + args->minalignslop - 1) > + longest || + ((int)(be32_to_cpu(agf->agf_freeblks) + + be32_to_cpu(agf->agf_flcount) - need - args->total) < + (int)args->minleft)) { + xfs_trans_brelse(tp, agbp); + args->agbp = NULL; + return 0; + } } /* * Make the freelist shorter if it's too long. @@ -1950,12 +1961,11 @@ xfs_alloc_fix_freelist( * on a completely full ag. */ if (targs.agbno == NULLAGBLOCK) { - if (!(flags & XFS_ALLOC_FLAG_FREEING)) { - xfs_trans_brelse(tp, agflbp); - args->agbp = NULL; - return 0; - } - break; + if (flags & XFS_ALLOC_FLAG_FREEING) + break; + xfs_trans_brelse(tp, agflbp); + args->agbp = NULL; + return 0; } /* * Put each allocated block on the list. @@ -2442,31 +2452,26 @@ xfs_free_extent( xfs_fsblock_t bno, /* starting block number of extent */ xfs_extlen_t len) /* length of extent */ { -#ifdef DEBUG - xfs_agf_t *agf; /* a.g. freespace header */ -#endif - xfs_alloc_arg_t args; /* allocation argument structure */ + xfs_alloc_arg_t args; int error; ASSERT(len != 0); + memset(&args, 0, sizeof(xfs_alloc_arg_t)); args.tp = tp; args.mp = tp->t_mountp; args.agno = XFS_FSB_TO_AGNO(args.mp, bno); ASSERT(args.agno < args.mp->m_sb.sb_agcount); args.agbno = XFS_FSB_TO_AGBNO(args.mp, bno); - args.alignment = 1; - args.minlen = args.minleft = args.minalignslop = 0; down_read(&args.mp->m_peraglock); args.pag = &args.mp->m_perag[args.agno]; if ((error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING))) goto error0; #ifdef DEBUG ASSERT(args.agbp != NULL); - agf = XFS_BUF_TO_AGF(args.agbp); - ASSERT(args.agbno + len <= be32_to_cpu(agf->agf_length)); + ASSERT((args.agbno + len) <= + be32_to_cpu(XFS_BUF_TO_AGF(args.agbp)->agf_length)); #endif - error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, - len, 0); + error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); error0: up_read(&args.mp->m_peraglock); return error; diff --git a/include/linux/fb.h b/include/linux/fb.h index 4ad0673b199..2f335e96601 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -1,7 +1,6 @@ #ifndef _LINUX_FB_H #define _LINUX_FB_H -#include <linux/backlight.h> #include <asm/types.h> /* Definitions of frame buffers */ @@ -381,6 +380,7 @@ struct fb_cursor { #include <linux/workqueue.h> #include <linux/notifier.h> #include <linux/list.h> +#include <linux/backlight.h> #include <asm/io.h> struct vm_area_struct; diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 181c69cad4e..851aa1bcfc1 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -210,6 +210,7 @@ extern enum system_states { extern void dump_stack(void); #ifdef DEBUG +/* If you are writing a driver, please use dev_dbg instead */ #define pr_debug(fmt,arg...) \ printk(KERN_DEBUG fmt,##arg) #else diff --git a/include/linux/mm.h b/include/linux/mm.h index 990957e0929..f0b135cd86d 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -336,6 +336,7 @@ static inline void init_page_count(struct page *page) } void put_page(struct page *page); +void put_pages_list(struct list_head *pages); void split_page(struct page *page, unsigned int order); diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 19c96d498e2..755e9cddac4 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1040,6 +1040,21 @@ static inline int pskb_trim(struct sk_buff *skb, unsigned int len) } /** + * pskb_trim_unique - remove end from a paged unique (not cloned) buffer + * @skb: buffer to alter + * @len: new length + * + * This is identical to pskb_trim except that the caller knows that + * the skb is not cloned so we should never get an error due to out- + * of-memory. + */ +static inline void pskb_trim_unique(struct sk_buff *skb, unsigned int len) +{ + int err = pskb_trim(skb, len); + BUG_ON(err); +} + +/** * skb_orphan - orphan a buffer * @skb: buffer to orphan * @@ -1081,7 +1096,7 @@ static inline void __skb_queue_purge(struct sk_buff_head *list) * the headroom they think they need without accounting for the * built in space. The built in space is used for optimisations. * - * %NULL is returned in there is no free memory. + * %NULL is returned if there is no free memory. */ static inline struct sk_buff *__dev_alloc_skb(unsigned int length, gfp_t gfp_mask) @@ -1101,7 +1116,7 @@ static inline struct sk_buff *__dev_alloc_skb(unsigned int length, * the headroom they think they need without accounting for the * built in space. The built in space is used for optimisations. * - * %NULL is returned in there is no free memory. Although this function + * %NULL is returned if there is no free memory. Although this function * allocates memory it can be called from an interrupt. */ static inline struct sk_buff *dev_alloc_skb(unsigned int length) diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index f8665326ed9..600d61d7d2a 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -16,7 +16,7 @@ #include <linux/device.h> #include <linux/mutex.h> #include <linux/compiler.h> /* need __user */ -#ifdef CONFIG_VIDEO_V4L1 +#ifdef CONFIG_VIDEO_V4L1_COMPAT #include <linux/videodev.h> #else #include <linux/videodev2.h> diff --git a/kernel/futex.c b/kernel/futex.c index c2b2e0b83ab..d4633c588f3 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -297,7 +297,7 @@ static int futex_handle_fault(unsigned long address, int attempt) struct vm_area_struct * vma; struct mm_struct *mm = current->mm; - if (attempt >= 2 || !(vma = find_vma(mm, address)) || + if (attempt > 2 || !(vma = find_vma(mm, address)) || vma->vm_start > address || !(vma->vm_flags & VM_WRITE)) return -EFAULT; @@ -747,8 +747,10 @@ retry: */ if (attempt++) { if (futex_handle_fault((unsigned long)uaddr2, - attempt)) + attempt)) { + ret = -EFAULT; goto out; + } goto retry; } @@ -1322,9 +1324,10 @@ static int do_futex_lock_pi(u32 __user *uaddr, int detect, int trylock, * still holding the mmap_sem. */ if (attempt++) { - if (futex_handle_fault((unsigned long)uaddr, attempt)) + if (futex_handle_fault((unsigned long)uaddr, attempt)) { + ret = -EFAULT; goto out_unlock_release_sem; - + } goto retry_locked; } @@ -1506,9 +1509,10 @@ pi_faulted: * still holding the mmap_sem. */ if (attempt++) { - if (futex_handle_fault((unsigned long)uaddr, attempt)) + if (futex_handle_fault((unsigned long)uaddr, attempt)) { + ret = -EFAULT; goto out_unlock; - + } goto retry_locked; } diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index be989efc785..21c38a7e666 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -187,7 +187,7 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_base *base) { struct hrtimer_base *new_base; - new_base = &__get_cpu_var(hrtimer_bases[base->index]); + new_base = &__get_cpu_var(hrtimer_bases)[base->index]; if (base != new_base) { /* diff --git a/kernel/panic.c b/kernel/panic.c index d8a0bca2123..9b8dcfd1ca9 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -18,6 +18,7 @@ #include <linux/interrupt.h> #include <linux/nmi.h> #include <linux/kexec.h> +#include <linux/debug_locks.h> int panic_on_oops; int tainted; diff --git a/kernel/timer.c b/kernel/timer.c index b650f04888e..1d7dd6267c2 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1324,46 +1324,19 @@ asmlinkage long sys_getpid(void) } /* - * Accessing ->group_leader->real_parent is not SMP-safe, it could - * change from under us. However, rather than getting any lock - * we can use an optimistic algorithm: get the parent - * pid, and go back and check that the parent is still - * the same. If it has changed (which is extremely unlikely - * indeed), we just try again.. - * - * NOTE! This depends on the fact that even if we _do_ - * get an old value of "parent", we can happily dereference - * the pointer (it was and remains a dereferencable kernel pointer - * no matter what): we just can't necessarily trust the result - * until we know that the parent pointer is valid. - * - * NOTE2: ->group_leader never changes from under us. + * Accessing ->real_parent is not SMP-safe, it could + * change from under us. However, we can use a stale + * value of ->real_parent under rcu_read_lock(), see + * release_task()->call_rcu(delayed_put_task_struct). */ asmlinkage long sys_getppid(void) { int pid; - struct task_struct *me = current; - struct task_struct *parent; - parent = me->group_leader->real_parent; - for (;;) { - pid = parent->tgid; -#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) -{ - struct task_struct *old = parent; + rcu_read_lock(); + pid = rcu_dereference(current->real_parent)->tgid; + rcu_read_unlock(); - /* - * Make sure we read the pid before re-reading the - * parent pointer: - */ - smp_rmb(); - parent = me->group_leader->real_parent; - if (old != parent) - continue; -} -#endif - break; - } return pid; } diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 448e8f7b342..835fe28b87a 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -68,7 +68,7 @@ struct workqueue_struct { /* All the per-cpu workqueues on the system, for hotplug cpu to add/remove threads to each one as cpus come/go. */ -static DEFINE_SPINLOCK(workqueue_lock); +static DEFINE_MUTEX(workqueue_mutex); static LIST_HEAD(workqueues); static int singlethread_cpu; @@ -320,10 +320,10 @@ void fastcall flush_workqueue(struct workqueue_struct *wq) } else { int cpu; - lock_cpu_hotplug(); + mutex_lock(&workqueue_mutex); for_each_online_cpu(cpu) flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, cpu)); - unlock_cpu_hotplug(); + mutex_unlock(&workqueue_mutex); } } EXPORT_SYMBOL_GPL(flush_workqueue); @@ -371,8 +371,7 @@ struct workqueue_struct *__create_workqueue(const char *name, } wq->name = name; - /* We don't need the distraction of CPUs appearing and vanishing. */ - lock_cpu_hotplug(); + mutex_lock(&workqueue_mutex); if (singlethread) { INIT_LIST_HEAD(&wq->list); p = create_workqueue_thread(wq, singlethread_cpu); @@ -381,9 +380,7 @@ struct workqueue_struct *__create_workqueue(const char *name, else wake_up_process(p); } else { - spin_lock(&workqueue_lock); list_add(&wq->list, &workqueues); - spin_unlock(&workqueue_lock); for_each_online_cpu(cpu) { p = create_workqueue_thread(wq, cpu); if (p) { @@ -393,7 +390,7 @@ struct workqueue_struct *__create_workqueue(const char *name, destroy = 1; } } - unlock_cpu_hotplug(); + mutex_unlock(&workqueue_mutex); /* * Was there any error during startup? If yes then clean up: @@ -434,17 +431,15 @@ void destroy_workqueue(struct workqueue_struct *wq) flush_workqueue(wq); /* We don't need the distraction of CPUs appearing and vanishing. */ - lock_cpu_hotplug(); + mutex_lock(&workqueue_mutex); if (is_single_threaded(wq)) cleanup_workqueue_thread(wq, singlethread_cpu); else { for_each_online_cpu(cpu) cleanup_workqueue_thread(wq, cpu); - spin_lock(&workqueue_lock); list_del(&wq->list); - spin_unlock(&workqueue_lock); } - unlock_cpu_hotplug(); + mutex_unlock(&workqueue_mutex); free_percpu(wq->cpu_wq); kfree(wq); } @@ -515,11 +510,13 @@ int schedule_on_each_cpu(void (*func)(void *info), void *info) if (!works) return -ENOMEM; + mutex_lock(&workqueue_mutex); for_each_online_cpu(cpu) { INIT_WORK(per_cpu_ptr(works, cpu), func, info); __queue_work(per_cpu_ptr(keventd_wq->cpu_wq, cpu), per_cpu_ptr(works, cpu)); } + mutex_unlock(&workqueue_mutex); flush_workqueue(keventd_wq); free_percpu(works); return 0; @@ -635,6 +632,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, switch (action) { case CPU_UP_PREPARE: + mutex_lock(&workqueue_mutex); /* Create a new workqueue thread for it. */ list_for_each_entry(wq, &workqueues, list) { if (!create_workqueue_thread(wq, hotcpu)) { @@ -653,6 +651,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, kthread_bind(cwq->thread, hotcpu); wake_up_process(cwq->thread); } + mutex_unlock(&workqueue_mutex); break; case CPU_UP_CANCELED: @@ -664,6 +663,15 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, any_online_cpu(cpu_online_map)); cleanup_workqueue_thread(wq, hotcpu); } + mutex_unlock(&workqueue_mutex); + break; + + case CPU_DOWN_PREPARE: + mutex_lock(&workqueue_mutex); + break; + + case CPU_DOWN_FAILED: + mutex_unlock(&workqueue_mutex); break; case CPU_DEAD: @@ -671,6 +679,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, cleanup_workqueue_thread(wq, hotcpu); list_for_each_entry(wq, &workqueues, list) take_over_work(wq, hotcpu); + mutex_unlock(&workqueue_mutex); break; } diff --git a/mm/swap.c b/mm/swap.c index 8fd095c4ae5..687686a61f7 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -54,6 +54,26 @@ void put_page(struct page *page) } EXPORT_SYMBOL(put_page); +/** + * put_pages_list(): release a list of pages + * + * Release a list of pages which are strung together on page.lru. Currently + * used by read_cache_pages() and related error recovery code. + * + * @pages: list of pages threaded on page->lru + */ +void put_pages_list(struct list_head *pages) +{ + while (!list_empty(pages)) { + struct page *victim; + + victim = list_entry(pages->prev, struct page, lru); + list_del(&victim->lru); + page_cache_release(victim); + } +} +EXPORT_SYMBOL(put_pages_list); + /* * Writeback is about to end against a page which has been marked for immediate * reclaim. If it still appears to be reclaimable, move it to the tail of the diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index 02693a230dc..9f950db3b76 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c @@ -74,6 +74,9 @@ static void ulog_send(unsigned int nlgroup) if (timer_pending(&ub->timer)) del_timer(&ub->timer); + if (!ub->skb) + return; + /* last nlmsg needs NLMSG_DONE */ if (ub->qlen > 1) ub->lastnlh->nlmsg_type = NLMSG_DONE; diff --git a/net/core/dst.c b/net/core/dst.c index 470c05bc4cb..1a5e49da0e7 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -95,12 +95,11 @@ static void dst_run_gc(unsigned long dummy) dst_gc_timer_inc = DST_GC_INC; dst_gc_timer_expires = DST_GC_MIN; } - dst_gc_timer.expires = jiffies + dst_gc_timer_expires; #if RT_CACHE_DEBUG >= 2 printk("dst_total: %d/%d %ld\n", atomic_read(&dst_total), delayed, dst_gc_timer_expires); #endif - add_timer(&dst_gc_timer); + mod_timer(&dst_gc_timer, jiffies + dst_gc_timer_expires); out: spin_unlock(&dst_lock); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 67ed14ddabd..6a7320b39ed 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2149,6 +2149,8 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, skb->mac.raw = ((u8 *) iph) - 14 - pkt_dev->nr_labels*sizeof(u32); skb->dev = odev; skb->pkt_type = PACKET_HOST; + skb->nh.iph = iph; + skb->h.uh = udph; if (pkt_dev->nfrags <= 0) pgh = (struct pktgen_hdr *)skb_put(skb, datalen); @@ -2460,6 +2462,8 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, skb->protocol = protocol; skb->dev = odev; skb->pkt_type = PACKET_HOST; + skb->nh.ipv6h = iph; + skb->h.uh = udph; if (pkt_dev->nfrags <= 0) pgh = (struct pktgen_hdr *)skb_put(skb, datalen); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 20e5bb73f14..30cc1ba6ed5 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -394,6 +394,9 @@ static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) } if (ida[IFLA_ADDRESS - 1]) { + struct sockaddr *sa; + int len; + if (!dev->set_mac_address) { err = -EOPNOTSUPP; goto out; @@ -405,7 +408,17 @@ static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) if (ida[IFLA_ADDRESS - 1]->rta_len != RTA_LENGTH(dev->addr_len)) goto out; - err = dev->set_mac_address(dev, RTA_DATA(ida[IFLA_ADDRESS - 1])); + len = sizeof(sa_family_t) + dev->addr_len; + sa = kmalloc(len, GFP_KERNEL); + if (!sa) { + err = -ENOMEM; + goto out; + } + sa->sa_family = dev->type; + memcpy(sa->sa_data, RTA_DATA(ida[IFLA_ADDRESS - 1]), + dev->addr_len); + err = dev->set_mac_address(dev, sa); + kfree(sa); if (err) goto out; send_addr_notify = 1; diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 022d8894c11..c54f3664bce 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -268,8 +268,10 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, struct sk_buff *skb; skb = alloc_skb(length + NET_SKB_PAD, gfp_mask); - if (likely(skb)) + if (likely(skb)) { skb_reserve(skb, NET_SKB_PAD); + skb->dev = dev; + } return skb; } diff --git a/net/core/wireless.c b/net/core/wireless.c index d2bc72d318f..de0bde4b51d 100644 --- a/net/core/wireless.c +++ b/net/core/wireless.c @@ -82,6 +82,7 @@ #include <linux/init.h> /* for __init */ #include <linux/if_arp.h> /* ARPHRD_ETHER */ #include <linux/etherdevice.h> /* compare_ether_addr */ +#include <linux/interrupt.h> #include <linux/wireless.h> /* Pretty obvious */ #include <net/iw_handler.h> /* New driver API */ @@ -1842,6 +1843,18 @@ int wireless_rtnetlink_set(struct net_device * dev, */ #ifdef WE_EVENT_RTNETLINK +static struct sk_buff_head wireless_nlevent_queue; + +static void wireless_nlevent_process(unsigned long data) +{ + struct sk_buff *skb; + + while ((skb = skb_dequeue(&wireless_nlevent_queue))) + netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_ATOMIC); +} + +static DECLARE_TASKLET(wireless_nlevent_tasklet, wireless_nlevent_process, 0); + /* ---------------------------------------------------------------- */ /* * Fill a rtnetlink message with our event data. @@ -1904,8 +1917,17 @@ static inline void rtmsg_iwinfo(struct net_device * dev, return; } NETLINK_CB(skb).dst_group = RTNLGRP_LINK; - netlink_broadcast(rtnl, skb, 0, RTNLGRP_LINK, GFP_ATOMIC); + skb_queue_tail(&wireless_nlevent_queue, skb); + tasklet_schedule(&wireless_nlevent_tasklet); +} + +static int __init wireless_nlevent_init(void) +{ + skb_queue_head_init(&wireless_nlevent_queue); + return 0; } + +subsys_initcall(wireless_nlevent_init); #endif /* WE_EVENT_RTNETLINK */ /* ---------------------------------------------------------------- */ diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 9bf307a2978..4c20f554689 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -947,7 +947,7 @@ alloc_new_skb: skb_prev->csum = csum_sub(skb_prev->csum, skb->csum); data += fraggap; - skb_trim(skb_prev, maxfraglen); + pskb_trim_unique(skb_prev, maxfraglen); } copy = datalen - transhdrlen - fraggap; @@ -1142,7 +1142,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page, data, fraggap, 0); skb_prev->csum = csum_sub(skb_prev->csum, skb->csum); - skb_trim(skb_prev, maxfraglen); + pskb_trim_unique(skb_prev, maxfraglen); } /* diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 80c73ca9011..df4854cf598 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -1170,21 +1170,34 @@ static int __init arp_tables_init(void) { int ret; - xt_proto_init(NF_ARP); + ret = xt_proto_init(NF_ARP); + if (ret < 0) + goto err1; /* Noone else will be downing sem now, so we won't sleep */ - xt_register_target(&arpt_standard_target); - xt_register_target(&arpt_error_target); + ret = xt_register_target(&arpt_standard_target); + if (ret < 0) + goto err2; + ret = xt_register_target(&arpt_error_target); + if (ret < 0) + goto err3; /* Register setsockopt */ ret = nf_register_sockopt(&arpt_sockopts); - if (ret < 0) { - duprintf("Unable to register sockopts.\n"); - return ret; - } + if (ret < 0) + goto err4; printk("arp_tables: (C) 2002 David S. Miller\n"); return 0; + +err4: + xt_unregister_target(&arpt_error_target); +err3: + xt_unregister_target(&arpt_standard_target); +err2: + xt_proto_fini(NF_ARP); +err1: + return ret; } static void __exit arp_tables_fini(void) diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index fc5bdd5eb7d..f316ff5fd8a 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -2239,22 +2239,39 @@ static int __init ip_tables_init(void) { int ret; - xt_proto_init(AF_INET); + ret = xt_proto_init(AF_INET); + if (ret < 0) + goto err1; /* Noone else will be downing sem now, so we won't sleep */ - xt_register_target(&ipt_standard_target); - xt_register_target(&ipt_error_target); - xt_register_match(&icmp_matchstruct); + ret = xt_register_target(&ipt_standard_target); + if (ret < 0) + goto err2; + ret = xt_register_target(&ipt_error_target); + if (ret < 0) + goto err3; + ret = xt_register_match(&icmp_matchstruct); + if (ret < 0) + goto err4; /* Register setsockopt */ ret = nf_register_sockopt(&ipt_sockopts); - if (ret < 0) { - duprintf("Unable to register sockopts.\n"); - return ret; - } + if (ret < 0) + goto err5; printk("ip_tables: (C) 2000-2006 Netfilter Core Team\n"); return 0; + +err5: + xt_unregister_match(&icmp_matchstruct); +err4: + xt_unregister_target(&ipt_error_target); +err3: + xt_unregister_target(&ipt_standard_target); +err2: + xt_proto_fini(AF_INET); +err1: + return ret; } static void __exit ip_tables_fini(void) diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index d7dd7fe7051..d46fd677fa1 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c @@ -115,6 +115,11 @@ static void ulog_send(unsigned int nlgroupnum) del_timer(&ub->timer); } + if (!ub->skb) { + DEBUGP("ipt_ULOG: ulog_send: nothing to send\n"); + return; + } + /* last nlmsg needs NLMSG_DONE */ if (ub->qlen > 1) ub->lastnlh->nlmsg_type = NLMSG_DONE; diff --git a/net/ipv4/netfilter/ipt_hashlimit.c b/net/ipv4/netfilter/ipt_hashlimit.c index 6b662449e82..3bd2368e1fc 100644 --- a/net/ipv4/netfilter/ipt_hashlimit.c +++ b/net/ipv4/netfilter/ipt_hashlimit.c @@ -454,15 +454,12 @@ hashlimit_match(const struct sk_buff *skb, dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg * hinfo->cfg.burst); dh->rateinfo.cost = user2credits(hinfo->cfg.avg); - - spin_unlock_bh(&hinfo->lock); - return 1; + } else { + /* update expiration timeout */ + dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire); + rateinfo_recalc(dh, now); } - /* update expiration timeout */ - dh->expires = now + msecs_to_jiffies(hinfo->cfg.expire); - - rateinfo_recalc(dh, now); if (dh->rateinfo.credit >= dh->rateinfo.cost) { /* We're underlimit. */ dh->rateinfo.credit -= dh->rateinfo.cost; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 19bd49d69d9..b873cbcdd0b 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -3157,7 +3157,7 @@ int __init ip_rt_init(void) rhash_entries, (num_physpages >= 128 * 1024) ? 15 : 17, - HASH_HIGHMEM, + 0, &rt_hash_log, &rt_hash_mask, 0); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 5c08ea20a18..507adefbc17 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -466,7 +466,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, if (skb->len != tcp_header_size) tcp_event_data_sent(tp, skb, sk); - TCP_INC_STATS(TCP_MIB_OUTSEGS); + if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq) + TCP_INC_STATS(TCP_MIB_OUTSEGS); err = icsk->icsk_af_ops->queue_xmit(skb, 0); if (likely(err <= 0)) @@ -2157,10 +2158,9 @@ int tcp_connect(struct sock *sk) skb_shinfo(buff)->gso_size = 0; skb_shinfo(buff)->gso_type = 0; buff->csum = 0; + tp->snd_nxt = tp->write_seq; TCP_SKB_CB(buff)->seq = tp->write_seq++; TCP_SKB_CB(buff)->end_seq = tp->write_seq; - tp->snd_nxt = tp->write_seq; - tp->pushed_seq = tp->write_seq; /* Send it off. */ TCP_SKB_CB(buff)->when = tcp_time_stamp; @@ -2170,6 +2170,12 @@ int tcp_connect(struct sock *sk) sk_charge_skb(sk, buff); tp->packets_out += tcp_skb_pcount(buff); tcp_transmit_skb(sk, buff, 1, GFP_KERNEL); + + /* We change tp->snd_nxt after the tcp_transmit_skb() call + * in order to make this packet get counted in tcpOutSegs. + */ + tp->snd_nxt = tp->write_seq; + tp->pushed_seq = tp->write_seq; TCP_INC_STATS(TCP_MIB_ACTIVEOPENS); /* Timer for repeating the SYN until an answer. */ diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c index b3435324b57..dab37d2f65f 100644 --- a/net/ipv4/tcp_probe.c +++ b/net/ipv4/tcp_probe.c @@ -130,11 +130,12 @@ static ssize_t tcpprobe_read(struct file *file, char __user *buf, error = wait_event_interruptible(tcpw.wait, __kfifo_len(tcpw.fifo) != 0); if (error) - return error; + goto out_free; cnt = kfifo_get(tcpw.fifo, tbuf, len); error = copy_to_user(buf, tbuf, cnt); +out_free: vfree(tbuf); return error ? error : cnt; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 8ea1e36bf8e..0c5042e7380 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -1909,11 +1909,11 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, ifp = ipv6_add_addr(idev, pfx, plen, scope, ifa_flags); if (!IS_ERR(ifp)) { - spin_lock(&ifp->lock); + spin_lock_bh(&ifp->lock); ifp->valid_lft = valid_lft; ifp->prefered_lft = prefered_lft; ifp->tstamp = jiffies; - spin_unlock(&ifp->lock); + spin_unlock_bh(&ifp->lock); addrconf_dad_start(ifp, 0); in6_ifa_put(ifp); diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 69451af6abe..4fb47a25291 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1095,7 +1095,7 @@ alloc_new_skb: skb_prev->csum = csum_sub(skb_prev->csum, skb->csum); data += fraggap; - skb_trim(skb_prev, maxfraglen); + pskb_trim_unique(skb_prev, maxfraglen); } copy = datalen - transhdrlen - fraggap; if (copy < 0) { diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index f26898b0034..c9d6b23cd3f 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1398,23 +1398,39 @@ static int __init ip6_tables_init(void) { int ret; - xt_proto_init(AF_INET6); + ret = xt_proto_init(AF_INET6); + if (ret < 0) + goto err1; /* Noone else will be downing sem now, so we won't sleep */ - xt_register_target(&ip6t_standard_target); - xt_register_target(&ip6t_error_target); - xt_register_match(&icmp6_matchstruct); + ret = xt_register_target(&ip6t_standard_target); + if (ret < 0) + goto err2; + ret = xt_register_target(&ip6t_error_target); + if (ret < 0) + goto err3; + ret = xt_register_match(&icmp6_matchstruct); + if (ret < 0) + goto err4; /* Register setsockopt */ ret = nf_register_sockopt(&ip6t_sockopts); - if (ret < 0) { - duprintf("Unable to register sockopts.\n"); - xt_proto_fini(AF_INET6); - return ret; - } + if (ret < 0) + goto err5; printk("ip6_tables: (C) 2000-2006 Netfilter Core Team\n"); return 0; + +err5: + xt_unregister_match(&icmp6_matchstruct); +err4: + xt_unregister_target(&ip6t_error_target); +err3: + xt_unregister_target(&ip6t_standard_target); +err2: + xt_proto_fini(AF_INET6); +err1: + return ret; } static void __exit ip6_tables_fini(void) diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index aa34ff4b707..bef3f61569f 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -1642,13 +1642,17 @@ static int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ty if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) goto out; - ipx = ipx_hdr(skb); - ipx_pktsize = ntohs(ipx->ipx_pktsize); + if (!pskb_may_pull(skb, sizeof(struct ipxhdr))) + goto drop; + + ipx_pktsize = ntohs(ipx_hdr(skb)->ipx_pktsize); /* Too small or invalid header? */ - if (ipx_pktsize < sizeof(struct ipxhdr) || ipx_pktsize > skb->len) + if (ipx_pktsize < sizeof(struct ipxhdr) || + !pskb_may_pull(skb, ipx_pktsize)) goto drop; + ipx = ipx_hdr(skb); if (ipx->ipx_checksum != IPX_NO_CHECKSUM && ipx->ipx_checksum != ipx_cksum(ipx, ipx_pktsize)) goto drop; diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index 42eb0c3a978..61cb8cf7d15 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c @@ -330,6 +330,9 @@ static void llc_sap_mcast(struct llc_sap *sap, if (llc->laddr.lsap != laddr->lsap) continue; + if (llc->dev != skb->dev) + continue; + skb1 = skb_clone(skb, GFP_ATOMIC); if (!skb1) break; diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 61cdda4e5d3..b59d3b2bde2 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -366,6 +366,9 @@ __nfulnl_send(struct nfulnl_instance *inst) if (timer_pending(&inst->timer)) del_timer(&inst->timer); + if (!inst->skb) + return 0; + if (inst->qlen > 1) inst->lastnlh->nlmsg_type = NLMSG_DONE; diff --git a/net/netfilter/xt_string.c b/net/netfilter/xt_string.c index d8e3891b5f8..275330fcdaa 100644 --- a/net/netfilter/xt_string.c +++ b/net/netfilter/xt_string.c @@ -37,7 +37,7 @@ static int match(const struct sk_buff *skb, return (skb_find_text((struct sk_buff *)skb, conf->from_offset, conf->to_offset, conf->config, &state) - != UINT_MAX) && !conf->invert; + != UINT_MAX) ^ conf->invert; } #define STRING_TEXT_PRIV(m) ((struct xt_string_info *) m) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index f35bc676128..3da67ca2c3c 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1134,12 +1134,33 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family) } EXPORT_SYMBOL(__xfrm_route_forward); +/* Optimize later using cookies and generation ids. */ + static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie) { - /* If it is marked obsolete, which is how we even get here, - * then we have purged it from the policy bundle list and we - * did that for a good reason. + /* Code (such as __xfrm4_bundle_create()) sets dst->obsolete + * to "-1" to force all XFRM destinations to get validated by + * dst_ops->check on every use. We do this because when a + * normal route referenced by an XFRM dst is obsoleted we do + * not go looking around for all parent referencing XFRM dsts + * so that we can invalidate them. It is just too much work. + * Instead we make the checks here on every use. For example: + * + * XFRM dst A --> IPv4 dst X + * + * X is the "xdst->route" of A (X is also the "dst->path" of A + * in this example). If X is marked obsolete, "A" will not + * notice. That's what we are validating here via the + * stale_bundle() check. + * + * When a policy's bundle is pruned, we dst_free() the XFRM + * dst which causes it's ->obsolete field to be set to a + * positive non-zero integer. If an XFRM dst has been pruned + * like this, we want to force a new route lookup. */ + if (dst->obsolete < 0 && !stale_bundle(dst)) + return dst; + return NULL; } diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 44312926b84..e2de650d3db 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -391,7 +391,7 @@ static void do_input(char *alias, unsigned int i; for (i = min; i < max; i++) - if (arr[i / BITS_PER_LONG] & (1 << (i%BITS_PER_LONG))) + if (arr[i / BITS_PER_LONG] & (1L << (i%BITS_PER_LONG))) sprintf(alias + strlen(alias), "%X,*", i); } diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index f4980ca5c05..1b7c3dfc2b4 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig @@ -31,7 +31,7 @@ config SOUND_EMU10K1 For more information on this driver and the degree of support for the different card models please check: - <http://sourceforge.net/projects/emu10k1/> + <http://sourceforge.net/projects/emu10k1/> It is now possible to load dsp microcode patches into the EMU10K1 chip. These patches are used to implement real time sound @@ -140,7 +140,7 @@ config SOUND_TRIDENT system support" and "Sysctl support", and after the /proc file system has been mounted, executing the command - command what is enabled + command what is enabled echo 0>/proc/ALi5451 pcm out is also set to S/PDIF out. (Default). @@ -838,7 +838,7 @@ config SOUND_WAVEARTIST config SOUND_TVMIXER tristate "TV card (bt848) mixer support" - depends on SOUND_PRIME && I2C + depends on SOUND_PRIME && I2C && VIDEO_V4L1 help Support for audio mixer facilities on the BT848 TV frame-grabber card. diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index d7ad32f514d..e49c0fe21b0 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -16,16 +16,16 @@ config SND_AD1889 will be called snd-ad1889. config SND_ALS300 - tristate "Avance Logic ALS300/ALS300+" - depends on SND - select SND_PCM - select SND_AC97_CODEC - select SND_OPL3_LIB - help - Say 'Y' or 'M' to include support for Avance Logic ALS300/ALS300+ + tristate "Avance Logic ALS300/ALS300+" + depends on SND + select SND_PCM + select SND_AC97_CODEC + select SND_OPL3_LIB + help + Say 'Y' or 'M' to include support for Avance Logic ALS300/ALS300+ - To compile this driver as a module, choose M here: the module - will be called snd-als300 + To compile this driver as a module, choose M here: the module + will be called snd-als300 config SND_ALS4000 tristate "Avance Logic ALS4000" @@ -78,49 +78,49 @@ config SND_ATIIXP_MODEM will be called snd-atiixp-modem. config SND_AU8810 - tristate "Aureal Advantage" - depends on SND + tristate "Aureal Advantage" + depends on SND select SND_MPU401_UART select SND_AC97_CODEC - help + help Say Y here to include support for Aureal Advantage soundcards. Supported features: Hardware Mixer, SRC, EQ and SPDIF output. - 3D support code is in place, but not yet useable. For more info, - email the ALSA developer list, or <mjander@users.sourceforge.net>. + 3D support code is in place, but not yet useable. For more info, + email the ALSA developer list, or <mjander@users.sourceforge.net>. To compile this driver as a module, choose M here: the module will be called snd-au8810. - + config SND_AU8820 - tristate "Aureal Vortex" - depends on SND + tristate "Aureal Vortex" + depends on SND select SND_MPU401_UART select SND_AC97_CODEC - help + help Say Y here to include support for Aureal Vortex soundcards. - Supported features: Hardware Mixer and SRC. For more info, email - the ALSA developer list, or <mjander@users.sourceforge.net>. + Supported features: Hardware Mixer and SRC. For more info, email + the ALSA developer list, or <mjander@users.sourceforge.net>. To compile this driver as a module, choose M here: the module will be called snd-au8820. - + config SND_AU8830 - tristate "Aureal Vortex 2" - depends on SND + tristate "Aureal Vortex 2" + depends on SND select SND_MPU401_UART select SND_AC97_CODEC - help + help Say Y here to include support for Aureal Vortex 2 soundcards. - Supported features: Hardware Mixer, SRC, EQ and SPDIF output. - 3D support code is in place, but not yet useable. For more info, - email the ALSA developer list, or <mjander@users.sourceforge.net>. + Supported features: Hardware Mixer, SRC, EQ and SPDIF output. + 3D support code is in place, but not yet useable. For more info, + email the ALSA developer list, or <mjander@users.sourceforge.net>. To compile this driver as a module, choose M here: the module will be called snd-au8830. - + config SND_AZT3328 tristate "Aztech AZF3328 / PCI168 (EXPERIMENTAL)" depends on SND && EXPERIMENTAL @@ -135,10 +135,10 @@ config SND_AZT3328 will be called snd-azt3328. config SND_BT87X - tristate "Bt87x Audio Capture" - depends on SND + tristate "Bt87x Audio Capture" + depends on SND select SND_PCM - help + help If you want to record audio from TV cards based on Brooktree Bt878/Bt879 chips, say Y here and read <file:Documentation/sound/alsa/Bt87x.txt>. @@ -209,7 +209,7 @@ config SND_CS46XX config SND_CS46XX_NEW_DSP bool "Cirrus Logic (Sound Fusion) New DSP support" depends on SND_CS46XX - default y + default y help Say Y here to use a new DSP image for SPDIF and dual codecs. @@ -225,7 +225,7 @@ config SND_CS5535AUDIO referred to as NS CS5535 IO or AMD CS5535 IO companion in various literature. This driver also supports the CS5536 audio device. However, for both chips, on certain boards, you may - need to use ac97_quirk=hp_only if your board has physically + need to use ac97_quirk=hp_only if your board has physically mapped headphone out to master output. If that works for you, send lspci -vvv output to the mailing list so that your board can be identified in the quirks list. @@ -468,11 +468,13 @@ config SND_FM801_TEA575X_BOOL FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media Forte SF256-PCS-02) into the snd-fm801 driver. + This will enable support for the old V4L1 API. + config SND_FM801_TEA575X tristate depends on SND_FM801_TEA575X_BOOL default SND_FM801 - select VIDEO_DEV + select VIDEO_V4L1 config SND_HDA_INTEL tristate "Intel HD Audio" diff --git a/usr/Makefile b/usr/Makefile index e93824269da..5b31c0b61c7 100644 --- a/usr/Makefile +++ b/usr/Makefile @@ -35,6 +35,9 @@ quiet_cmd_initfs = GEN $@ cmd_initfs = $(initramfs) -o $@ $(ramfs-args) $(ramfs-input) targets := initramfs_data.cpio.gz +# do not try to update files included in initramfs +$(deps_initramfs): ; + $(deps_initramfs): klibcdirs # We rebuild initramfs_data.cpio.gz if: # 1) Any included file is newer then initramfs_data.cpio.gz |