diff options
113 files changed, 887 insertions, 865 deletions
diff --git a/Documentation/networking/ax25.txt b/Documentation/networking/ax25.txt index 37c25b0925f0..8257dbf9be57 100644 --- a/Documentation/networking/ax25.txt +++ b/Documentation/networking/ax25.txt @@ -1,16 +1,10 @@ To use the amateur radio protocols within Linux you will need to get a -suitable copy of the AX.25 Utilities. More detailed information about these -and associated programs can be found on http://zone.pspt.fi/~jsn/. - -For more information about the AX.25, NET/ROM and ROSE protocol stacks, see -the AX25-HOWTO written by Terry Dawson <terry@perf.no.itg.telstra.com.au> -who is also the AX.25 Utilities maintainer. +suitable copy of the AX.25 Utilities. More detailed information about +AX.25, NET/ROM and ROSE, associated programs and and utilities can be +found on http://www.linux-ax25.org. There is an active mailing list for discussing Linux amateur radio matters -called linux-hams. To subscribe to it, send a message to +called linux-hams@vger.kernel.org. To subscribe to it, send a message to majordomo@vger.kernel.org with the words "subscribe linux-hams" in the body -of the message, the subject field is ignored. - -Jonathan G4KLX - -g4klx@g4klx.demon.co.uk +of the message, the subject field is ignored. You don't need to be +subscribed to post but of course that means you might miss an answer. diff --git a/Documentation/power/pci.txt b/Documentation/power/pci.txt index c750f9f2e76e..b6a3cbf7e846 100644 --- a/Documentation/power/pci.txt +++ b/Documentation/power/pci.txt @@ -102,31 +102,28 @@ pci_save_state -------------- Usage: - pci_save_state(dev, buffer); + pci_save_state(struct pci_dev *dev); Description: - Save first 64 bytes of PCI config space. Buffer must be allocated by - caller. + Save first 64 bytes of PCI config space, along with any additional + PCI-Express or PCI-X information. pci_restore_state ----------------- Usage: - pci_restore_state(dev, buffer); + pci_restore_state(struct pci_dev *dev); Description: - Restore previously saved config space. (First 64 bytes only); - - If buffer is NULL, then restore what information we know about the - device from bootup: BARs and interrupt line. + Restore previously saved config space. pci_set_power_state ------------------- Usage: - pci_set_power_state(dev, state); + pci_set_power_state(struct pci_dev *dev, pci_power_t state); Description: Transition device to low power state using PCI PM Capabilities @@ -142,7 +139,7 @@ pci_enable_wake --------------- Usage: - pci_enable_wake(dev, state, enable); + pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); Description: Enable device to generate PME# during low power state using PCI PM diff --git a/MAINTAINERS b/MAINTAINERS index dd6978b1e8fb..8c8090e02d8e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1585,12 +1585,6 @@ L: i2c@lm-sensors.org T: quilt http://khali.linux-fr.org/devel/linux-2.6/jdelvare-i2c/ S: Maintained -I2O -P: Markus Lidel -M: markus.lidel@shadowconnect.com -W: http://i2o.shadowconnect.com/ -S: Maintained - i386 BOOT CODE P: Riley H. Williams M: Riley@Williams.Name @@ -2928,9 +2922,12 @@ L: linux-scsi@vger.kernel.org S: Maintained SCTP PROTOCOL +P: Vlad Yasevich +M: vladislav.yasevich@hp.com P: Sridhar Samudrala M: sri@us.ibm.com L: lksctp-developers@lists.sourceforge.net +W: http://lksctp.sourceforge.net S: Supported SCx200 CPU SUPPORT diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c index f3ab61ee7498..76afea67f691 100644 --- a/arch/i386/kernel/hpet.c +++ b/arch/i386/kernel/hpet.c @@ -197,7 +197,7 @@ static int hpet_next_event(unsigned long delta, cnt += delta; hpet_writel(cnt, HPET_T0_CMP); - return ((long)(hpet_readl(HPET_COUNTER) - cnt ) > 0); + return ((long)(hpet_readl(HPET_COUNTER) - cnt ) > 0) ? -ETIME : 0; } /* diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 1bb069372143..948436665385 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c @@ -193,6 +193,14 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { }, { .callback = set_bf_sort, + .ident = "Dell PowerEdge R900", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell"), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R900"), + }, + }, + { + .callback = set_bf_sort, .ident = "HP ProLiant BL20p G3", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "HP"), diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 8af549e95730..993f35381496 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -167,7 +167,7 @@ static int __kprobes swap_instruction(void *aref) * shall not cross any page boundaries (vmalloc area!) when writing * the new instruction. */ - addr = (u32 *)ALIGN((unsigned long)args->ptr, 4); + addr = (u32 *)((unsigned long)args->ptr & -4UL); if ((unsigned long)args->ptr & 2) instr = ((*addr) & 0xffff0000) | args->new; else diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h index 66cb400c2c92..62403bd99661 100644 --- a/arch/um/include/sysdep-x86_64/ptrace.h +++ b/arch/um/include/sysdep-x86_64/ptrace.h @@ -104,10 +104,6 @@ union uml_pt_regs { #endif #ifdef UML_CONFIG_MODE_SKAS struct skas_regs { - /* x86_64 ptrace uses sizeof(user_regs_struct) as its register - * file size, while i386 uses FRAME_SIZE. Therefore, we need - * to use UM_FRAME_SIZE here instead of HOST_FRAME_SIZE. - */ unsigned long regs[MAX_REG_NR]; unsigned long fp[HOST_FP_SIZE]; struct faultinfo faultinfo; diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index b3c11cfa995a..9383e8751ae7 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -48,7 +48,7 @@ int multi_op_count = 0; static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) { unsigned long regs[MAX_REG_NR]; - int n; + int n, i; long ret, offset; unsigned long * data; unsigned long * syscall; @@ -66,9 +66,13 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) (unsigned long) &__syscall_stub_start); n = ptrace_setregs(pid, regs); - if(n < 0) + if(n < 0){ + printk("Registers - \n"); + for(i = 0; i < MAX_REG_NR; i++) + printk("\t%d\t0x%lx\n", i, regs[i]); panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n", - n); + -n); + } wait_stub_done(pid, 0, "do_syscall_stub"); diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index dda06789bcb0..0564422c155f 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -67,7 +67,7 @@ void wait_stub_done(int pid, int sig, char * fname) if((n < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ - unsigned long regs[HOST_FRAME_SIZE]; + unsigned long regs[MAX_REG_NR]; if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) printk("Failed to get registers from stub, " @@ -76,7 +76,7 @@ void wait_stub_done(int pid, int sig, char * fname) int i; printk("Stub registers -\n"); - for(i = 0; i < HOST_FRAME_SIZE; i++) + for(i = 0; i < ARRAY_SIZE(regs); i++) printk("\t%d - %lx\n", i, regs[i]); } panic("%s : failed to wait for SIGUSR1/SIGTRAP, " @@ -328,7 +328,7 @@ void userspace(union uml_pt_regs *regs) int copy_context_skas0(unsigned long new_stack, int pid) { int err; - unsigned long regs[HOST_FRAME_SIZE]; + unsigned long regs[MAX_REG_NR]; unsigned long fp_regs[HOST_FP_SIZE]; unsigned long current_stack = current_stub_stack(); struct stub_data *data = (struct stub_data *) current_stack; diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c index 79cd93c8c5ed..84b44f9cd42a 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/um/os-Linux/sys-i386/registers.c @@ -15,7 +15,7 @@ /* These are set once at boot time and not changed thereafter */ -static unsigned long exec_regs[HOST_FRAME_SIZE]; +static unsigned long exec_regs[MAX_REG_NR]; static unsigned long exec_fp_regs[HOST_FP_SIZE]; static unsigned long exec_fpx_regs[HOST_XFP_SIZE]; static int have_fpx_regs = 1; @@ -101,6 +101,7 @@ void init_registers(int pid) { int err; + memset(exec_regs, 0, sizeof(exec_regs)); err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); if(err) panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", @@ -124,7 +125,7 @@ void init_registers(int pid) void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) { - memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); + memcpy(regs, exec_regs, sizeof(exec_regs)); if(fp_regs != NULL) memcpy(fp_regs, exec_fp_regs, HOST_FP_SIZE * sizeof(unsigned long)); diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c index a2d7e0c603f7..e6fc2179d1bc 100644 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ b/arch/um/os-Linux/sys-x86_64/registers.c @@ -14,7 +14,7 @@ /* These are set once at boot time and not changed thereafter */ -static unsigned long exec_regs[HOST_FRAME_SIZE]; +static unsigned long exec_regs[MAX_REG_NR]; static unsigned long exec_fp_regs[HOST_FP_SIZE]; void init_thread_registers(union uml_pt_regs *to) @@ -72,7 +72,7 @@ void init_registers(int pid) void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) { - memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); + memcpy(regs, exec_regs, sizeof(exec_regs)); if(fp_regs != NULL) memcpy(fp_regs, exec_fp_regs, HOST_FP_SIZE * sizeof(unsigned long)); diff --git a/arch/x86_64/kernel/acpi/sleep.c b/arch/x86_64/kernel/acpi/sleep.c index 23178ce6c783..e1548fbe95ae 100644 --- a/arch/x86_64/kernel/acpi/sleep.c +++ b/arch/x86_64/kernel/acpi/sleep.c @@ -66,8 +66,10 @@ static void init_low_mapping(void) { pgd_t *slot0 = pgd_offset(current->mm, 0UL); low_ptr = *slot0; + /* FIXME: We're playing with the current task's page tables here, which + * is potentially dangerous on SMP systems. + */ set_pgd(slot0, *pgd_offset(current->mm, PAGE_OFFSET)); - WARN_ON(num_online_cpus() != 1); local_flush_tlb(); } diff --git a/block/elevator.c b/block/elevator.c index 25f6ef28e3bb..96a00c822748 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -964,17 +964,18 @@ void elv_unregister_queue(struct request_queue *q) int elv_register(struct elevator_type *e) { + char *def = ""; spin_lock_irq(&elv_list_lock); BUG_ON(elevator_find(e->elevator_name)); list_add_tail(&e->list, &elv_list); spin_unlock_irq(&elv_list_lock); - printk(KERN_INFO "io scheduler %s registered", e->elevator_name); if (!strcmp(e->elevator_name, chosen_elevator) || (!*chosen_elevator && !strcmp(e->elevator_name, CONFIG_DEFAULT_IOSCHED))) - printk(" (default)"); - printk("\n"); + def = " (default)"; + + printk(KERN_INFO "io scheduler %s registered%s\n", e->elevator_name, def); return 0; } EXPORT_SYMBOL_GPL(elv_register); diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 38c293b987b7..3de06953ac33 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -1221,7 +1221,7 @@ void blk_recount_segments(request_queue_t *q, struct bio *bio) * considered part of another segment, since that might * change with the bounce page. */ - high = page_to_pfn(bv->bv_page) >= q->bounce_pfn; + high = page_to_pfn(bv->bv_page) > q->bounce_pfn; if (high || highprv) goto new_hw_segment; if (cluster) { @@ -3658,8 +3658,8 @@ int __init blk_dev_init(void) open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL); register_hotcpu_notifier(&blk_cpu_notifier); - blk_max_low_pfn = max_low_pfn; - blk_max_pfn = max_pfn; + blk_max_low_pfn = max_low_pfn - 1; + blk_max_pfn = max_pfn - 1; return 0; } diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c index 337bbcdcf13d..8ea02755b1c9 100644 --- a/drivers/char/generic_serial.c +++ b/drivers/char/generic_serial.c @@ -710,12 +710,6 @@ void gs_close(struct tty_struct * tty, struct file * filp) } -static unsigned int gs_baudrates[] = { - 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, - 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 -}; - - void gs_set_termios (struct tty_struct * tty, struct ktermios * old_termios) { @@ -771,7 +765,6 @@ void gs_set_termios (struct tty_struct * tty, baudrate = tty_get_baud_rate(tty); - baudrate = gs_baudrates[baudrate]; if ((tiosp->c_cflag & CBAUD) == B38400) { if ( (port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) baudrate = 57600; diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index d42060ede930..5ac309ee7f05 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c @@ -90,7 +90,7 @@ __setup("acpi_pm_good", acpi_pm_good_setup); static inline void acpi_pm_need_workaround(void) { clocksource_acpi_pm.read = acpi_pm_read_slow; - clocksource_acpi_pm.rating = 110; + clocksource_acpi_pm.rating = 120; } /* diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index f52facc570f5..3162010900c9 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1015,6 +1015,10 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev) { unsigned int cpu = sys_dev->id; int retval; + + if (cpu_is_offline(cpu)) + return 0; + if (unlikely(lock_policy_rwsem_write(cpu))) BUG(); diff --git a/drivers/eisa/pci_eisa.c b/drivers/eisa/pci_eisa.c index 9e913629ef39..74edb1d0110f 100644 --- a/drivers/eisa/pci_eisa.c +++ b/drivers/eisa/pci_eisa.c @@ -19,8 +19,8 @@ /* There is only *one* pci_eisa device per machine, right ? */ static struct eisa_root_device pci_eisa_root; -static int __devinit pci_eisa_init (struct pci_dev *pdev, - const struct pci_device_id *ent) +static int __init pci_eisa_init(struct pci_dev *pdev, + const struct pci_device_id *ent) { int rc; diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 8f1fd017679b..ca2e4f830c39 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -103,8 +103,10 @@ config BLK_DEV_IDE_SATA ---help--- There are two drivers for Serial ATA controllers. - The main driver, "libata", exists inside the SCSI subsystem - and supports most modern SATA controllers. + The main driver, "libata", uses the SCSI subsystem + and supports most modern SATA controllers. In order to use it + you may take a look at "Serial ATA (prod) and Parallel ATA + (experimental) drivers". The IDE driver (which you are currently configuring) supports a few first-generation SATA controllers. diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index c193553f6fe7..0e0280076fcd 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -519,21 +519,24 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0) try_to_flush_leftover_data(drive); + if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) { + ide_kill_rq(drive, rq); + return ide_stopped; + } + if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) - /* force an abort */ - hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG); + rq->errors |= ERROR_RESET; - if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) - ide_kill_rq(drive, rq); - else { - if ((rq->errors & ERROR_RESET) == ERROR_RESET) { - ++rq->errors; - return ide_do_reset(drive); - } - if ((rq->errors & ERROR_RECAL) == ERROR_RECAL) - drive->special.b.recalibrate = 1; + if ((rq->errors & ERROR_RESET) == ERROR_RESET) { ++rq->errors; + return ide_do_reset(drive); } + + if ((rq->errors & ERROR_RECAL) == ERROR_RECAL) + drive->special.b.recalibrate = 1; + + ++rq->errors; + return ide_stopped; } @@ -1025,6 +1028,13 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) if (!drive->special.all) { ide_driver_t *drv; + /* + * We reset the drive so we need to issue a SETFEATURES. + * Do it _after_ do_special() restored device parameters. + */ + if (drive->current_speed == 0xff) + ide_config_drive_speed(drive, drive->desired_speed); + if (rq->cmd_type == REQ_TYPE_ATA_CMD || rq->cmd_type == REQ_TYPE_ATA_TASK || rq->cmd_type == REQ_TYPE_ATA_TASKFILE) diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index bd513f5a2323..1ee53a551c3a 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -583,8 +583,12 @@ u8 eighty_ninty_three (ide_drive_t *drive) if(!(drive->id->hw_config & 0x4000)) return 0; #endif /* CONFIG_IDEDMA_IVB */ - if (!(drive->id->hw_config & 0x2000)) - return 0; + /* + * FIXME: + * - change master/slave IDENTIFY order + * - force bit13 (80c cable present) check + * (unless the slave device is pre-ATA3) + */ return 1; } @@ -1090,6 +1094,9 @@ static void pre_reset(ide_drive_t *drive) if (HWIF(drive)->pre_reset != NULL) HWIF(drive)->pre_reset(drive); + if (drive->current_speed != 0xff) + drive->desired_speed = drive->current_speed; + drive->current_speed = 0xff; } /* diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 695610f0e3e4..a6f098fda884 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1124,17 +1124,40 @@ static int set_io_32bit(ide_drive_t *drive, int arg) static int set_using_dma (ide_drive_t *drive, int arg) { #ifdef CONFIG_BLK_DEV_IDEDMA + ide_hwif_t *hwif = drive->hwif; + int err = -EPERM; + if (!drive->id || !(drive->id->capability & 1)) - return -EPERM; - if (HWIF(drive)->ide_dma_check == NULL) - return -EPERM; + goto out; + + if (hwif->ide_dma_check == NULL) + goto out; + + err = -EBUSY; + if (ide_spin_wait_hwgroup(drive)) + goto out; + /* + * set ->busy flag, unlock and let it ride + */ + hwif->hwgroup->busy = 1; + spin_unlock_irq(&ide_lock); + + err = 0; + if (arg) { - if (ide_set_dma(drive)) - return -EIO; - if (HWIF(drive)->ide_dma_on(drive)) return -EIO; + if (ide_set_dma(drive) || hwif->ide_dma_on(drive)) + err = -EIO; } else ide_dma_off(drive); - return 0; + + /* + * lock, clear ->busy flag and unlock before leaving + */ + spin_lock_irq(&ide_lock); + hwif->hwgroup->busy = 0; + spin_unlock_irq(&ide_lock); +out: + return err; #else return -EPERM; #endif diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 6ceb25bc5a7b..ace98929cc3d 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -255,7 +255,7 @@ static int config_chipset_for_dma(ide_drive_t *drive) printk(KERN_WARNING "%s reduced to Ultra33 mode.\n", drive->name); } - if (drive->media != ide_disk) + if (drive->media != ide_disk && drive->media != ide_cdrom) return 0; if (id->capability & 4) { @@ -545,6 +545,7 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + hwif->atapi_dma = 1; hwif->ultra_mask = 0x7f; hwif->mwdma_mask = 0x07; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 0741c6d1337c..f2a40ae8e7d0 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -814,7 +814,7 @@ static void ipoib_set_mcast_list(struct net_device *dev) queue_work(ipoib_workqueue, &priv->restart_task); } -static void ipoib_neigh_destructor(struct neighbour *n) +static void ipoib_neigh_cleanup(struct neighbour *n) { struct ipoib_neigh *neigh; struct ipoib_dev_priv *priv = netdev_priv(n->dev); @@ -822,7 +822,7 @@ static void ipoib_neigh_destructor(struct neighbour *n) struct ipoib_ah *ah = NULL; ipoib_dbg(priv, - "neigh_destructor for %06x " IPOIB_GID_FMT "\n", + "neigh_cleanup for %06x " IPOIB_GID_FMT "\n", IPOIB_QPN(n->ha), IPOIB_GID_RAW_ARG(n->ha + 4)); @@ -874,7 +874,7 @@ void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh) static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms) { - parms->neigh_destructor = ipoib_neigh_destructor; + parms->neigh_cleanup = ipoib_neigh_cleanup; return 0; } diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index 9df9e3548cf1..c547a6665052 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c @@ -440,7 +440,7 @@ isar_bh(struct work_struct *work) { struct BCState *bcs = container_of(work, struct BCState, tqueue); - BChannel_bh(bcs); + BChannel_bh(work); if (test_and_clear_bit(B_LL_NOCARRIER, &bcs->event)) ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_NOCARR); if (test_and_clear_bit(B_LL_CONNECT, &bcs->event)) diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index bfa0ce42ea92..fbbf9d6b299f 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c @@ -618,7 +618,7 @@ static void fix_pmode_dataseg(int seg, struct kvm_save_segment *save) { struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; - if (vmcs_readl(sf->base) == save->base) { + if (vmcs_readl(sf->base) == save->base && (save->base & AR_S_MASK)) { vmcs_write16(sf->selector, save->selector); vmcs_writel(sf->base, save->base); vmcs_write32(sf->limit, save->limit); @@ -1888,6 +1888,27 @@ again: [cr2]"i"(offsetof(struct kvm_vcpu, cr2)) : "cc", "memory" ); + /* + * Reload segment selectors ASAP. (it's needed for a functional + * kernel: x86 relies on having __KERNEL_PDA in %fs and x86_64 + * relies on having 0 in %gs for the CPU PDA to work.) + */ + if (fs_gs_ldt_reload_needed) { + load_ldt(ldt_sel); + load_fs(fs_sel); + /* + * If we have to reload gs, we must take care to + * preserve our gs base. + */ + local_irq_disable(); + load_gs(gs_sel); +#ifdef CONFIG_X86_64 + wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE)); +#endif + local_irq_enable(); + + reload_tss(); + } ++kvm_stat.exits; save_msrs(vcpu->guest_msrs, NR_BAD_MSRS); @@ -1905,22 +1926,6 @@ again: kvm_run->exit_reason = vmcs_read32(VM_INSTRUCTION_ERROR); r = 0; } else { - if (fs_gs_ldt_reload_needed) { - load_ldt(ldt_sel); - load_fs(fs_sel); - /* - * If we have to reload gs, we must take care to - * preserve our gs base. - */ - local_irq_disable(); - load_gs(gs_sel); -#ifdef CONFIG_X86_64 - wrmsrl(MSR_GS_BASE, vmcs_readl(HOST_GS_BASE)); -#endif - local_irq_enable(); - - reload_tss(); - } /* * Profile KVM exit RIPs: */ diff --git a/drivers/md/md.c b/drivers/md/md.c index 6c06e825cff5..2a9b6a07e3a2 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1318,6 +1318,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) char b[BDEVNAME_SIZE]; struct kobject *ko; char *s; + int err; if (rdev->mddev) { MD_BUG(); @@ -1352,20 +1353,29 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) while ( (s=strchr(rdev->kobj.k_name, '/')) != NULL) *s = '!'; - list_add(&rdev->same_set, &mddev->disks); rdev->mddev = mddev; printk(KERN_INFO "md: bind<%s>\n", b); rdev->kobj.parent = &mddev->kobj; - kobject_add(&rdev->kobj); + if ((err = kobject_add(&rdev->kobj))) + goto fail; if (rdev->bdev->bd_part) ko = &rdev->bdev->bd_part->kobj; else ko = &rdev->bdev->bd_disk->kobj; - sysfs_create_link(&rdev->kobj, ko, "block"); + if ((err = sysfs_create_link(&rdev->kobj, ko, "block"))) { + kobject_del(&rdev->kobj); + goto fail; + } + list_add(&rdev->same_set, &mddev->disks); bd_claim_by_disk(rdev->bdev, rdev, mddev->gendisk); return 0; + + fail: + printk(KERN_WARNING "md: failed to register dev-%s for %s\n", + b, mdname(mddev)); + return err; } static void unbind_rdev_from_array(mdk_rdev_t * rdev) @@ -2966,7 +2976,9 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data) mddev->kobj.k_name = NULL; snprintf(mddev->kobj.name, KOBJ_NAME_LEN, "%s", "md"); mddev->kobj.ktype = &md_ktype; - kobject_register(&mddev->kobj); + if (kobject_register(&mddev->kobj)) + printk(KERN_WARNING "md: cannot register %s/md - name in use\n", + disk->disk_name); return NULL; } @@ -3144,9 +3156,12 @@ static int do_md_run(mddev_t * mddev) bitmap_destroy(mddev); return err; } - if (mddev->pers->sync_request) - sysfs_create_group(&mddev->kobj, &md_redundancy_group); - else if (mddev->ro == 2) /* auto-readonly not meaningful */ + if (mddev->pers->sync_request) { + if (sysfs_create_group(&mddev->kobj, &md_redundancy_group)) + printk(KERN_WARNING + "md: cannot register extra attributes for %s\n", + mdname(mddev)); + } else if (mddev->ro == 2) /* auto-readonly not meaningful */ mddev->ro = 0; atomic_set(&mddev->writes_pending,0); @@ -3160,7 +3175,9 @@ static int do_md_run(mddev_t * mddev) if (rdev->raid_disk >= 0) { char nm[20]; sprintf(nm, "rd%d", rdev->raid_disk); - sysfs_create_link(&mddev->kobj, &rdev->kobj, nm); + if (sysfs_create_link(&mddev->kobj, &rdev->kobj, nm)) + printk("md: cannot register %s for %s\n", + nm, mdname(mddev)); } set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); @@ -3325,6 +3342,7 @@ static int do_md_stop(mddev_t * mddev, int mode) mddev->queue->merge_bvec_fn = NULL; mddev->queue->unplug_fn = NULL; mddev->queue->issue_flush_fn = NULL; + mddev->queue->backing_dev_info.congested_fn = NULL; if (mddev->pers->sync_request) sysfs_remove_group(&mddev->kobj, &md_redundancy_group); @@ -5385,8 +5403,12 @@ static int remove_and_add_spares(mddev_t *mddev) if (mddev->pers->hot_add_disk(mddev,rdev)) { char nm[20]; sprintf(nm, "rd%d", rdev->raid_disk); - sysfs_create_link(&mddev->kobj, - &rdev->kobj, nm); + if (sysfs_create_link(&mddev->kobj, + &rdev->kobj, nm)) + printk(KERN_WARNING + "md: cannot register " + "%s for %s\n", + nm, mdname(mddev)); spares++; md_new_event(mddev); } else diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 54a1ad5eef42..8d59914f2057 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -3642,12 +3642,15 @@ static int run(mddev_t *mddev) } /* Ok, everything is just fine now */ - sysfs_create_group(&mddev->kobj, &raid5_attrs_group); + if (sysfs_create_group(&mddev->kobj, &raid5_attrs_group)) + printk(KERN_WARNING + "raid5: failed to create sysfs attributes for %s\n", + mdname(mddev)); mddev->queue->unplug_fn = raid5_unplug_device; mddev->queue->issue_flush_fn = raid5_issue_flush; - mddev->queue->backing_dev_info.congested_fn = raid5_congested; mddev->queue->backing_dev_info.congested_data = mddev; + mddev->queue->backing_dev_info.congested_fn = raid5_congested; mddev->array_size = mddev->size * (conf->previous_raid_disks - conf->max_degraded); @@ -3678,6 +3681,7 @@ static int stop(mddev_t *mddev) mddev->thread = NULL; shrink_stripes(conf); kfree(conf->stripe_hashtbl); + mddev->queue->backing_dev_info.congested_fn = NULL; blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ sysfs_remove_group(&mddev->kobj, &raid5_attrs_group); kfree(conf->disks); @@ -3950,7 +3954,12 @@ static int raid5_start_reshape(mddev_t *mddev) added_devices++; rdev->recovery_offset = 0; sprintf(nm, "rd%d", rdev->raid_disk); - sysfs_create_link(&mddev->kobj, &rdev->kobj, nm); + if (sysfs_create_link(&mddev->kobj, + &rdev->kobj, nm)) + printk(KERN_WARNING + "raid5: failed to create " + " link %s for %s\n", + nm, mdname(mddev)); } else break; } @@ -4104,6 +4113,10 @@ static struct mdk_personality raid4_personality = .spare_active = raid5_spare_active, .sync_request = sync_request, .resize = raid5_resize, +#ifdef CONFIG_MD_RAID5_RESHAPE + .check_reshape = raid5_check_reshape, + .start_reshape = raid5_start_reshape, +#endif .quiesce = raid5_quiesce, }; diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index cbf7c0564889..fcb194135627 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c @@ -310,13 +310,15 @@ void ir_rc5_timer_end(unsigned long data) tv.tv_usec - ir->base_time.tv_usec; } - /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */ + /* signal we're ready to start a new code */ + ir->active = 0; + + /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */ if (gap < 28000) { dprintk(1, "ir-common: spurious timer_end\n"); return; } - ir->active = 0; if (ir->last_bit < 20) { /* ignore spurious codes (caused by light/other remotes) */ dprintk(1, "ir-common: short code: %x\n", ir->code); diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index fc77de45ca4d..a5c0e1a3e6d1 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c @@ -180,8 +180,7 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) struct dvb_device *dvbdev = file->private_data; struct dmxdev *dmxdev = dvbdev->priv; - if (mutex_lock_interruptible(&dmxdev->mutex)) - return -ERESTARTSYS; + mutex_lock(&dmxdev->mutex); if ((file->f_flags & O_ACCMODE) == O_WRONLY) { dmxdev->demux->disconnect_frontend(dmxdev->demux); @@ -673,13 +672,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file) static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, struct dmxdev_filter *dmxdevfilter) { - if (mutex_lock_interruptible(&dmxdev->mutex)) - return -ERESTARTSYS; - - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { - mutex_unlock(&dmxdev->mutex); - return -ERESTARTSYS; - } + mutex_lock(&dmxdev->mutex); + mutex_lock(&dmxdevfilter->mutex); dvb_dmxdev_filter_stop(dmxdevfilter); dvb_dmxdev_filter_reset(dmxdevfilter); diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index fcff5eab21a3..6d8d1c3df863 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c @@ -673,8 +673,7 @@ static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed) struct dvb_demux *demux = feed->demux; int ret; - if (mutex_lock_interruptible(&demux->mutex)) - return -ERESTARTSYS; + mutex_lock(&demux->mutex); if (feed->state < DMX_STATE_GO) { mutex_unlock(&demux->mutex); @@ -748,8 +747,7 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dvb_demux *demux = (struct dvb_demux *)dmx; struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; - if (mutex_lock_interruptible(&demux->mutex)) - return -ERESTARTSYS; + mutex_lock(&demux->mutex); if (feed->state == DMX_STATE_FREE) { mutex_unlock(&demux->mutex); @@ -916,8 +914,7 @@ static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed) struct dvb_demux *dvbdmx = dvbdmxfeed->demux; int ret; - if (mutex_lock_interruptible(&dvbdmx->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdmx->mutex); if (!dvbdmx->stop_feed) { mutex_unlock(&dvbdmx->mutex); @@ -942,8 +939,7 @@ static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - if (mutex_lock_interruptible(&dvbdmx->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdmx->mutex); if (dvbdmxfilter->feed != dvbdmxfeed) { mutex_unlock(&dvbdmx->mutex); @@ -1016,8 +1012,7 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux, struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; struct dvb_demux *dvbdmx = (struct dvb_demux *)demux; - if (mutex_lock_interruptible(&dvbdmx->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdmx->mutex); if (dvbdmxfeed->state == DMX_STATE_FREE) { mutex_unlock(&dvbdmx->mutex); @@ -1126,8 +1121,7 @@ static int dvbdmx_connect_frontend(struct dmx_demux *demux, if (demux->frontend) return -EINVAL; - if (mutex_lock_interruptible(&dvbdemux->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdemux->mutex); demux->frontend = frontend; mutex_unlock(&dvbdemux->mutex); @@ -1138,8 +1132,7 @@ static int dvbdmx_disconnect_frontend(struct dmx_demux *demux) { struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; - if (mutex_lock_interruptible(&dvbdemux->mutex)) - return -ERESTARTSYS; + mutex_lock(&dvbdemux->mutex); demux->frontend = NULL; mutex_unlock(&dvbdemux->mutex); diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 490337b5ee3e..14a372a0fe8b 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -203,8 +203,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, int id; - if (mutex_lock_interruptible(&dvbdev_register_lock)) - return -ERESTARTSYS; + mutex_lock(&dvbdev_register_lock); if ((id = dvbdev_get_free_id (adap, type)) < 0){ mutex_unlock(&dvbdev_register_lock); @@ -294,8 +293,7 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct modu { int num; - if (mutex_lock_interruptible(&dvbdev_register_lock)) - return -ERESTARTSYS; + mutex_lock(&dvbdev_register_lock); if ((num = dvbdev_get_free_adapter_num ()) < 0) { mutex_unlock(&dvbdev_register_lock); @@ -323,8 +321,7 @@ EXPORT_SYMBOL(dvb_register_adapter); int dvb_unregister_adapter(struct dvb_adapter *adap) { - if (mutex_lock_interruptible(&dvbdev_register_lock)) - return -ERESTARTSYS; + mutex_lock(&dvbdev_register_lock); list_del (&adap->list_head); mutex_unlock(&dvbdev_register_lock); return 0; diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c index ef319369ec26..c967148a5945 100644 --- a/drivers/media/dvb/frontends/isl6421.c +++ b/drivers/media/dvb/frontends/isl6421.c @@ -122,6 +122,7 @@ struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter /* detect if it is present or not */ if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) { kfree(isl6421); + fe->sec_priv = NULL; return NULL; } diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 920b63f8cf05..af66a5d5ecd8 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -3,7 +3,7 @@ # menu "Radio Adapters" - depends on VIDEO_DEV!=n + depends on VIDEO_DEV config RADIO_CADET tristate "ADS Cadet AM/FM Tuner" diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index 2fb9fe6a1ae7..ba1af3c8525e 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c @@ -780,18 +780,16 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; } -static int msp_suspend(struct device * dev, pm_message_t state) +static int msp_suspend(struct i2c_client *client, pm_message_t state) { - struct i2c_client *client = container_of(dev, struct i2c_client, dev); v4l_dbg(1, msp_debug, client, "suspend\n"); msp_reset(client); return 0; } -static int msp_resume(struct device * dev) +static int msp_resume(struct i2c_client *client) { - struct i2c_client *client = container_of(dev, struct i2c_client, dev); v4l_dbg(1, msp_debug, client, "resume\n"); msp_wake_thread(client); @@ -825,7 +823,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) if (msp_reset(client) == -1) { v4l_dbg(1, msp_debug, client, "msp3400 not found\n"); kfree(client); - return -1; + return 0; } state = kmalloc(sizeof(*state), GFP_KERNEL); @@ -859,7 +857,7 @@ static int msp_attach(struct i2c_adapter *adapter, int address, int kind) v4l_dbg(1, msp_debug, client, "not an msp3400 (cannot read chip version)\n"); kfree(state); kfree(client); - return -1; + return 0; } msp_set_audio(client); @@ -996,11 +994,11 @@ static struct i2c_driver i2c_driver = { .id = I2C_DRIVERID_MSP3400, .attach_adapter = msp_probe, .detach_client = msp_detach, + .suspend = msp_suspend, + .resume = msp_resume, .command = msp_command, .driver = { .name = "msp3400", - .suspend = msp_suspend, - .resume = msp_resume, }, }; diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index 7735b6758921..4d5bbd859de1 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c @@ -961,7 +961,7 @@ static void saa711x_set_v4lstd(struct i2c_client *client, v4l2_std_id std) reg |= 0x10; } else if (std == V4L2_STD_NTSC_M_JP) { reg |= 0x40; - } else if (std == V4L2_STD_SECAM) { + } else if (std & V4L2_STD_SECAM) { reg |= 0x50; } saa711x_write(client, R_0E_CHROMA_CNTL_1, reg); diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 7be73e3763de..15dbc6bf42a7 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -804,9 +804,8 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; } -static int tuner_suspend(struct device *dev, pm_message_t state) +static int tuner_suspend(struct i2c_client *c, pm_message_t state) { - struct i2c_client *c = container_of (dev, struct i2c_client, dev); struct tuner *t = i2c_get_clientdata (c); tuner_dbg ("suspend\n"); @@ -814,9 +813,8 @@ static int tuner_suspend(struct device *dev, pm_message_t state) return 0; } -static int tuner_resume(struct device *dev) +static int tuner_resume(struct i2c_client *c) { - struct i2c_client *c = container_of (dev, struct i2c_client, dev); struct tuner *t = i2c_get_clientdata (c); tuner_dbg ("resume\n"); @@ -837,10 +835,10 @@ static struct i2c_driver driver = { .attach_adapter = tuner_probe, .detach_client = tuner_detach, .command = tuner_command, + .suspend = tuner_suspend, + .resume = tuner_resume, .driver = { .name = "tuner", - .suspend = tuner_suspend, - .resume = tuner_resume, }, }; static struct i2c_client client_template = { diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 404c014db1bd..1d2d03f77894 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -815,7 +815,7 @@ mptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) static int mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) { - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; + MPT_SCSI_HOST *hd; struct mptsas_target_reset_event *target_reset_list, *n; int rc; @@ -827,7 +827,10 @@ mptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) if (reset_phase != MPT_IOC_POST_RESET) goto out; - if (!hd || !hd->ioc) + if (!ioc->sh || !ioc->sh->hostdata) + goto out; + hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; + if (!hd->ioc) goto out; if (list_empty(&hd->target_reset_list)) diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index da9859f2caf2..b17c4b2bc9ef 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -390,13 +390,6 @@ static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req) return BLKPREP_KILL; } - /* request is already processed by us, so return */ - if (blk_special_request(req)) { - osm_debug("REQ_SPECIAL already set!\n"); - req->cmd_flags |= REQ_DONTPREP; - return BLKPREP_OK; - } - /* connect the i2o_block_request to the request */ if (!req->special) { ireq = i2o_block_request_alloc(); @@ -408,11 +401,8 @@ static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req) ireq->i2o_blk_dev = i2o_blk_dev; req->special = ireq; ireq->req = req; - } else - ireq = req->special; - + } /* do not come back here */ - req->cmd_type = REQ_TYPE_SPECIAL; req->cmd_flags |= REQ_DONTPREP; return BLKPREP_OK; diff --git a/drivers/net/atl1/atl1_hw.c b/drivers/net/atl1/atl1_hw.c index 314dbaabb642..69482e0d849b 100644 --- a/drivers/net/atl1/atl1_hw.c +++ b/drivers/net/atl1/atl1_hw.c @@ -334,7 +334,6 @@ u32 atl1_hash_mc_addr(struct atl1_hw *hw, u8 *mc_addr) int i; crc32 = ether_crc_le(6, mc_addr); - crc32 = ~crc32; for (i = 0; i < 32; i++) value |= (((crc32 >> i) & 1) << (31 - i)); diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 46e1697d9cfd..d04214e4e581 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -2050,9 +2050,10 @@ static void nv_tx_timeout(struct net_device *dev) nv_drain_tx(dev); nv_init_tx(dev); setup_hw_rings(dev, NV_SETUP_TX_RING); - netif_wake_queue(dev); } + netif_wake_queue(dev); + /* 4) restart tx engine */ nv_start_tx(dev); spin_unlock_irq(&np->lock); @@ -3536,7 +3537,10 @@ static void nv_do_nic_poll(unsigned long data) pci_push(base); if (!using_multi_irqs(dev)) { - nv_nic_irq(0, dev); + if (np->desc_ver == DESC_VER_3) + nv_nic_irq_optimized(0, dev); + else + nv_nic_irq(0, dev); if (np->msi_flags & NV_MSI_X_ENABLED) enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index c9f55bc57edb..8015a7c5b0c9 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -1379,7 +1379,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev) spin_lock_init(&mp->lock); - port_num = pd->port_number; + port_num = mp->port_num = pd->port_number; /* set default config values */ eth_port_uc_addr_get(dev, dev->dev_addr); @@ -1411,8 +1411,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev) duplex = pd->duplex; speed = pd->speed; - mp->port_num = port_num; - /* Hook up MII support for ethtool */ mp->mii.dev = dev; mp->mii.mdio_read = mv643xx_mdio_read; diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index b05b20ef8c0a..c216e6a5d235 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -71,7 +71,7 @@ #include "myri10ge_mcp.h" #include "myri10ge_mcp_gen_header.h" -#define MYRI10GE_VERSION_STR "1.3.0-1.226" +#define MYRI10GE_VERSION_STR "1.3.0-1.227" MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_AUTHOR("Maintainer: help@myri.com"); @@ -2015,10 +2015,9 @@ again: mss = 0; max_segments = MXGEFW_MAX_SEND_DESC; - if (skb->len > (dev->mtu + ETH_HLEN)) { + if (skb_is_gso(skb)) { mss = skb_shinfo(skb)->gso_size; - if (mss != 0) - max_segments = MYRI10GE_MAX_SEND_DESC_TSO; + max_segments = MYRI10GE_MAX_SEND_DESC_TSO; } if ((unlikely(avail < max_segments))) { diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 11b575f89856..ef58e4128782 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -2544,6 +2544,9 @@ static void ppp_destroy_interface(struct ppp *ppp) ppp->active_filter = NULL; #endif /* CONFIG_PPP_FILTER */ + if (ppp->xmit_pending) + kfree_skb(ppp->xmit_pending); + kfree(ppp); } diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index d3f65dab306c..a8246eb2f8d9 100755 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -1691,6 +1691,27 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev) /* * Caller holds hw_lock. */ +static void ql_update_small_bufq_prod_index(struct ql3_adapter *qdev) +{ + struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; + if (qdev->small_buf_release_cnt >= 16) { + while (qdev->small_buf_release_cnt >= 16) { + qdev->small_buf_q_producer_index++; + + if (qdev->small_buf_q_producer_index == + NUM_SBUFQ_ENTRIES) + qdev->small_buf_q_producer_index = 0; + qdev->small_buf_release_cnt -= 8; + } + wmb(); + writel(qdev->small_buf_q_producer_index, + &port_regs->CommonRegs.rxSmallQProducerIndex); + } +} + +/* + * Caller holds hw_lock. + */ static void ql_update_lrg_bufq_prod_index(struct ql3_adapter *qdev) { struct bufq_addr_element *lrg_buf_q_ele; @@ -1732,13 +1753,10 @@ static void ql_update_lrg_bufq_prod_index(struct ql3_adapter *qdev) lrg_buf_q_ele = qdev->lrg_buf_q_virt_addr; } } - + wmb(); qdev->lrg_buf_next_free = lrg_buf_q_ele; - - ql_write_common_reg(qdev, - &port_regs->CommonRegs. - rxLargeQProducerIndex, - qdev->lrg_buf_q_producer_index); + writel(qdev->lrg_buf_q_producer_index, + &port_regs->CommonRegs.rxLargeQProducerIndex); } } @@ -1915,17 +1933,18 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, u16 checksum = le16_to_cpu(ib_ip_rsp_ptr->checksum); if (checksum & (IB_IP_IOCB_RSP_3032_ICE | - IB_IP_IOCB_RSP_3032_CE | - IB_IP_IOCB_RSP_3032_NUC)) { + IB_IP_IOCB_RSP_3032_CE)) { printk(KERN_ERR "%s: Bad checksum for this %s packet, checksum = %x.\n", __func__, ((checksum & IB_IP_IOCB_RSP_3032_TCP) ? "TCP" : "UDP"),checksum); - } else if (checksum & IB_IP_IOCB_RSP_3032_TCP) { + } else if ((checksum & IB_IP_IOCB_RSP_3032_TCP) || + (checksum & IB_IP_IOCB_RSP_3032_UDP && + !(checksum & IB_IP_IOCB_RSP_3032_NUC))) { skb2->ip_summed = CHECKSUM_UNNECESSARY; - } + } } skb2->dev = qdev->ndev; skb2->protocol = eth_type_trans(skb2, qdev->ndev); @@ -1944,16 +1963,12 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, static int ql_tx_rx_clean(struct ql3_adapter *qdev, int *tx_cleaned, int *rx_cleaned, int work_to_do) { - struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; struct net_rsp_iocb *net_rsp; struct net_device *ndev = qdev->ndev; - unsigned long hw_flags; int work_done = 0; - u32 rsp_producer_index = le32_to_cpu(*(qdev->prsp_producer_index)); - /* While there are entries in the completion queue. */ - while ((rsp_producer_index != + while ((le32_to_cpu(*(qdev->prsp_producer_index)) != qdev->rsp_consumer_index) && (work_done < work_to_do)) { net_rsp = qdev->rsp_current; @@ -2009,33 +2024,7 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev, work_done = *tx_cleaned + *rx_cleaned; } - if(work_done) { - spin_lock_irqsave(&qdev->hw_lock, hw_flags); - - ql_update_lrg_bufq_prod_index(qdev); - - if (qdev->small_buf_release_cnt >= 16) { - while (qdev->small_buf_release_cnt >= 16) { - qdev->small_buf_q_producer_index++; - - if (qdev->small_buf_q_producer_index == - NUM_SBUFQ_ENTRIES) - qdev->small_buf_q_producer_index = 0; - qdev->small_buf_release_cnt -= 8; - } - - wmb(); - ql_write_common_reg(qdev, - &port_regs->CommonRegs. - rxSmallQProducerIndex, - qdev->small_buf_q_producer_index); - - } - - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); - } - - return *tx_cleaned + *rx_cleaned; + return work_done; } static int ql_poll(struct net_device *ndev, int *budget) @@ -2059,9 +2048,10 @@ quit_polling: netif_rx_complete(ndev); spin_lock_irqsave(&qdev->hw_lock, hw_flags); - ql_write_common_reg(qdev, - &port_regs->CommonRegs.rspQConsumerIndex, - qdev->rsp_consumer_index); + ql_update_small_bufq_prod_index(qdev); + ql_update_lrg_bufq_prod_index(qdev); + writel(qdev->rsp_consumer_index, + &port_regs->CommonRegs.rspQConsumerIndex); spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); ql_enable_interrupts(qdev); @@ -2217,12 +2207,7 @@ static int ql_send_map(struct ql3_adapter *qdev, int seg_cnt, seg = 0; int frag_cnt = (int)skb_shinfo(skb)->nr_frags; - seg_cnt = tx_cb->seg_count = ql_get_seg_count(qdev, - (skb_shinfo(skb)->nr_frags)); - if(seg_cnt == -1) { - printk(KERN_ERR PFX"%s: invalid segment count!\n",__func__); - return NETDEV_TX_BUSY; - } + seg_cnt = tx_cb->seg_count; /* * Map the skb buffer first. */ @@ -2278,7 +2263,7 @@ static int ql_send_map(struct ql3_adapter *qdev, pci_unmap_addr_set(&tx_cb->map[seg], mapaddr, map); pci_unmap_len_set(&tx_cb->map[seg], maplen, - len); + sizeof(struct oal)); oal_entry = (struct oal_entry *)oal; oal++; seg++; @@ -2380,6 +2365,7 @@ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev) } mac_iocb_ptr = tx_cb->queue_entry; + memset((void *)mac_iocb_ptr, 0, sizeof(struct ob_mac_iocb_req)); mac_iocb_ptr->opcode = qdev->mac_ob_opcode; mac_iocb_ptr->flags = OB_MAC_IOCB_REQ_X; mac_iocb_ptr->flags |= qdev->mb_bit_mask; @@ -3054,15 +3040,6 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) goto out; } - if (qdev->mac_index) - ql_write_page0_reg(qdev, - &port_regs->mac1MaxFrameLengthReg, - qdev->max_frame_size); - else - ql_write_page0_reg(qdev, - &port_regs->mac0MaxFrameLengthReg, - qdev->max_frame_size); - value = qdev->nvram_data.tcpMaxWindowSize; ql_write_page0_reg(qdev, &port_regs->tcpMaxWindow, value); @@ -3082,6 +3059,14 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) ql_sem_unlock(qdev, QL_FLASH_SEM_MASK); } + if (qdev->mac_index) + ql_write_page0_reg(qdev, + &port_regs->mac1MaxFrameLengthReg, + qdev->max_frame_size); + else + ql_write_page0_reg(qdev, + &port_regs->mac0MaxFrameLengthReg, + qdev->max_frame_size); if(ql_sem_spinlock(qdev, QL_PHY_GIO_SEM_MASK, (QL_RESOURCE_BITS_BASE_CODE | (qdev->mac_index) * @@ -3152,7 +3137,8 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) if (qdev->device_id == QL3032_DEVICE_ID) { value = (QL3032_PORT_CONTROL_EF | QL3032_PORT_CONTROL_KIE | - QL3032_PORT_CONTROL_EIv6 | QL3032_PORT_CONTROL_EIv4); + QL3032_PORT_CONTROL_EIv6 | QL3032_PORT_CONTROL_EIv4 | + QL3032_PORT_CONTROL_ET); ql_write_page0_reg(qdev, &port_regs->functionControl, ((value << 16) | value)); } else { diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h index 34cd6580fd07..0203f88f0544 100755 --- a/drivers/net/qla3xxx.h +++ b/drivers/net/qla3xxx.h @@ -1014,8 +1014,7 @@ struct eeprom_data { /* Transmit and Receive Buffers */ #define NUM_LBUFQ_ENTRIES 128 -#define JUMBO_NUM_LBUFQ_ENTRIES \ -(NUM_LBUFQ_ENTRIES/(JUMBO_MTU_SIZE/NORMAL_MTU_SIZE)) +#define JUMBO_NUM_LBUFQ_ENTRIES 32 #define NUM_SBUFQ_ENTRIES 64 #define QL_SMALL_BUFFER_SIZE 32 #define QL_ADDR_ELE_PER_BUFQ_ENTRY \ diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index c62e85d89f41..7bee45b42a2c 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c @@ -336,13 +336,27 @@ static int __init lance_probe( struct net_device *dev) /* XXX - leak? */ MEM = dvma_malloc_align(sizeof(struct lance_memory), 0x10000); + if (MEM == NULL) { +#ifdef CONFIG_SUN3 + iounmap((void __iomem *)ioaddr); +#endif + printk(KERN_WARNING "SUN3 Lance couldn't allocate DVMA memory\n"); + return 0; + } lp->iobase = (volatile unsigned short *)ioaddr; dev->base_addr = (unsigned long)ioaddr; /* informational only */ REGA(CSR0) = CSR0_STOP; - request_irq(LANCE_IRQ, lance_interrupt, IRQF_DISABLED, "SUN3 Lance", dev); + if (request_irq(LANCE_IRQ, lance_interrupt, IRQF_DISABLED, "SUN3 Lance", dev) < 0) { +#ifdef CONFIG_SUN3 + iounmap((void __iomem *)ioaddr); +#endif + dvma_free((void *)MEM); + printk(KERN_WARNING "SUN3 Lance unable to allocate IRQ\n"); + return 0; + } dev->irq = (unsigned short)LANCE_IRQ; diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 616be8d0fa85..08ea61db46fe 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -2530,6 +2530,35 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev) return &gp->net_stats; } +static int gem_set_mac_address(struct net_device *dev, void *addr) +{ + struct sockaddr *macaddr = (struct sockaddr *) addr; + struct gem *gp = dev->priv; + unsigned char *e = &dev->dev_addr[0]; + + if (!is_valid_ether_addr(macaddr->sa_data)) + return -EADDRNOTAVAIL; + + if (!netif_running(dev) || !netif_device_present(dev)) { + /* We'll just catch it later when the + * device is up'd or resumed. + */ + memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len); + return 0; + } + + mutex_lock(&gp->pm_mutex); + memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len); + if (gp->running) { + writel((e[4] << 8) | e[5], gp->regs + MAC_ADDR0); + writel((e[2] << 8) | e[3], gp->regs + MAC_ADDR1); + writel((e[0] << 8) | e[1], gp->regs + MAC_ADDR2); + } + mutex_unlock(&gp->pm_mutex); + + return 0; +} + static void gem_set_multicast(struct net_device *dev) { struct gem *gp = dev->priv; @@ -3122,6 +3151,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, dev->change_mtu = gem_change_mtu; dev->irq = pdev->irq; dev->dma = 0; + dev->set_mac_address = gem_set_mac_address; #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = gem_poll_controller; #endif diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 8c8f9f4d47a5..0acee9f324e9 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -64,8 +64,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.74" -#define DRV_MODULE_RELDATE "February 20, 2007" +#define DRV_MODULE_VERSION "3.75" +#define DRV_MODULE_RELDATE "March 23, 2007" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -3568,32 +3568,34 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id) * Reading the PCI State register will confirm whether the * interrupt is ours and will flush the status block. */ - if ((sblk->status & SD_STATUS_UPDATED) || - !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { - /* - * Writing any value to intr-mbox-0 clears PCI INTA# and - * chip-internal interrupt pending events. - * Writing non-zero to intr-mbox-0 additional tells the - * NIC to stop sending us irqs, engaging "in-intr-handler" - * event coalescing. - */ - tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - 0x00000001); - if (tg3_irq_sync(tp)) + if (unlikely(!(sblk->status & SD_STATUS_UPDATED))) { + if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) || + (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { + handled = 0; goto out; - sblk->status &= ~SD_STATUS_UPDATED; - if (likely(tg3_has_work(tp))) { - prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); - netif_rx_schedule(dev); /* schedule NAPI poll */ - } else { - /* No work, shared interrupt perhaps? re-enable - * interrupts, and flush that PCI write - */ - tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - 0x00000000); } - } else { /* shared interrupt */ - handled = 0; + } + + /* + * Writing any value to intr-mbox-0 clears PCI INTA# and + * chip-internal interrupt pending events. + * Writing non-zero to intr-mbox-0 additional tells the + * NIC to stop sending us irqs, engaging "in-intr-handler" + * event coalescing. + */ + tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); + if (tg3_irq_sync(tp)) + goto out; + sblk->status &= ~SD_STATUS_UPDATED; + if (likely(tg3_has_work(tp))) { + prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); + netif_rx_schedule(dev); /* schedule NAPI poll */ + } else { + /* No work, shared interrupt perhaps? re-enable + * interrupts, and flush that PCI write + */ + tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, + 0x00000000); } out: return IRQ_RETVAL(handled); @@ -3611,31 +3613,33 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id) * Reading the PCI State register will confirm whether the * interrupt is ours and will flush the status block. */ - if ((sblk->status_tag != tp->last_tag) || - !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { - /* - * writing any value to intr-mbox-0 clears PCI INTA# and - * chip-internal interrupt pending events. - * writing non-zero to intr-mbox-0 additional tells the - * NIC to stop sending us irqs, engaging "in-intr-handler" - * event coalescing. - */ - tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - 0x00000001); - if (tg3_irq_sync(tp)) + if (unlikely(sblk->status_tag == tp->last_tag)) { + if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) || + (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { + handled = 0; goto out; - if (netif_rx_schedule_prep(dev)) { - prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); - /* Update last_tag to mark that this status has been - * seen. Because interrupt may be shared, we may be - * racing with tg3_poll(), so only update last_tag - * if tg3_poll() is not scheduled. - */ - tp->last_tag = sblk->status_tag; - __netif_rx_schedule(dev); } - } else { /* shared interrupt */ - handled = 0; + } + + /* + * writing any value to intr-mbox-0 clears PCI INTA# and + * chip-internal interrupt pending events. + * writing non-zero to intr-mbox-0 additional tells the + * NIC to stop sending us irqs, engaging "in-intr-handler" + * event coalescing. + */ + tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); + if (tg3_irq_sync(tp)) + goto out; + if (netif_rx_schedule_prep(dev)) { + prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); + /* Update last_tag to mark that this status has been + * seen. Because interrupt may be shared, we may be + * racing with tg3_poll(), so only update last_tag + * if tg3_poll() is not scheduled. + */ + tp->last_tag = sblk->status_tag; + __netif_rx_schedule(dev); } out: return IRQ_RETVAL(handled); @@ -4823,6 +4827,19 @@ static int tg3_chip_reset(struct tg3 *tp) if (write_op == tg3_write_flush_reg32) tp->write32 = tg3_write32; + /* Prevent the irq handler from reading or writing PCI registers + * during chip reset when the memory enable bit in the PCI command + * register may be cleared. The chip does not generate interrupt + * at this time, but the irq handler may still be called due to irq + * sharing or irqpoll. + */ + tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING; + tp->hw_status->status = 0; + tp->hw_status->status_tag = 0; + tp->last_tag = 0; + smp_mb(); + synchronize_irq(tp->pdev->irq); + /* do the reset */ val = GRC_MISC_CFG_CORECLK_RESET; @@ -4904,6 +4921,8 @@ static int tg3_chip_reset(struct tg3 *tp) pci_restore_state(tp->pdev); + tp->tg3_flags &= ~TG3_FLAG_CHIP_RESETTING; + /* Make sure PCI-X relaxed ordering bit is clear. */ pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val); val &= ~PCIX_CAPS_RELAXED_ORDERING; @@ -6321,8 +6340,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB | RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB | RDMAC_MODE_LNGREAD_ENAB); - if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) - rdmac_mode |= RDMAC_MODE_SPLIT_ENABLE; /* If statement applies to 5705 and 5750 PCI devices only */ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && @@ -6495,9 +6512,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) { val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK); val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT); - if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) - val |= (tp->split_mode_max_reqs << - PCIX_CAPS_SPLIT_SHIFT); } tw32(TG3PCI_X_CAPS, val); } @@ -10863,14 +10877,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) grc_misc_cfg = tr32(GRC_MISC_CFG); grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK; - /* Broadcom's driver says that CIOBE multisplit has a bug */ -#if 0 - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && - grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) { - tp->tg3_flags |= TG3_FLAG_SPLIT_MODE; - tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ; - } -#endif if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 && (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 || grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M)) @@ -11968,14 +11974,12 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, i == 5 ? '\n' : ':'); printk(KERN_INFO "%s: RXcsums[%d] LinkChgREG[%d] " - "MIirq[%d] ASF[%d] Split[%d] WireSpeed[%d] " - "TSOcap[%d] \n", + "MIirq[%d] ASF[%d] WireSpeed[%d] TSOcap[%d]\n", dev->name, (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0, (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) != 0, (tp->tg3_flags & TG3_FLAG_USE_MI_INTERRUPT) != 0, (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0, - (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0, (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0, (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); printk(KERN_INFO "%s: dma_rwctrl[%08x] dma_mask[%d-bit]\n", diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 086892d8c1f1..d515ed23841b 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2223,7 +2223,7 @@ struct tg3 { #define TG3_FLAG_40BIT_DMA_BUG 0x08000000 #define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 #define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 -#define TG3_FLAG_SPLIT_MODE 0x40000000 +#define TG3_FLAG_CHIP_RESETTING 0x40000000 #define TG3_FLAG_INIT_COMPLETE 0x80000000 u32 tg3_flags2; #define TG3_FLG2_RESTART_TIMER 0x00000001 @@ -2262,9 +2262,6 @@ struct tg3 { #define TG3_FLG2_NO_FWARE_REPORTED 0x40000000 #define TG3_FLG2_PHY_ADJUST_TRIM 0x80000000 - u32 split_mode_max_reqs; -#define SPLIT_MODE_5704_MAX_REQ 3 - struct timer_list timer; u16 timer_counter; u16 timer_multiplier; diff --git a/drivers/net/wan/lmc/lmc_media.h b/drivers/net/wan/lmc/lmc_media.h deleted file mode 100644 index ddcc00403563..000000000000 --- a/drivers/net/wan/lmc/lmc_media.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef _LMC_MEDIA_H_ -#define _LMC_MEDIA_H_ - -lmc_media_t lmc_ds3_media = { - lmc_ds3_init, /* special media init stuff */ - lmc_ds3_default, /* reset to default state */ - lmc_ds3_set_status, /* reset status to state provided */ - lmc_dummy_set_1, /* set clock source */ - lmc_dummy_set2_1, /* set line speed */ - lmc_ds3_set_100ft, /* set cable length */ - lmc_ds3_set_scram, /* set scrambler */ - lmc_ds3_get_link_status, /* get link status */ - lmc_dummy_set_1, /* set link status */ - lmc_ds3_set_crc_length, /* set CRC length */ - lmc_dummy_set_1, /* set T1 or E1 circuit type */ - lmc_ds3_watchdog -}; - -lmc_media_t lmc_hssi_media = { - lmc_hssi_init, /* special media init stuff */ - lmc_hssi_default, /* reset to default state */ - lmc_hssi_set_status, /* reset status to state provided */ - lmc_hssi_set_clock, /* set clock source */ - lmc_dummy_set2_1, /* set line speed */ - lmc_dummy_set_1, /* set cable length */ - lmc_dummy_set_1, /* set scrambler */ - lmc_hssi_get_link_status, /* get link status */ - lmc_hssi_set_link_status, /* set link status */ - lmc_hssi_set_crc_length, /* set CRC length */ - lmc_dummy_set_1, /* set T1 or E1 circuit type */ - lmc_hssi_watchdog -}; - -lmc_media_t lmc_ssi_media = { lmc_ssi_init, /* special media init stuff */ - lmc_ssi_default, /* reset to default state */ - lmc_ssi_set_status, /* reset status to state provided */ - lmc_ssi_set_clock, /* set clock source */ - lmc_ssi_set_speed, /* set line speed */ - lmc_dummy_set_1, /* set cable length */ - lmc_dummy_set_1, /* set scrambler */ - lmc_ssi_get_link_status, /* get link status */ - lmc_ssi_set_link_status, /* set link status */ - lmc_ssi_set_crc_length, /* set CRC length */ - lmc_dummy_set_1, /* set T1 or E1 circuit type */ - lmc_ssi_watchdog -}; - -lmc_media_t lmc_t1_media = { - lmc_t1_init, /* special media init stuff */ - lmc_t1_default, /* reset to default state */ - lmc_t1_set_status, /* reset status to state provided */ - lmc_t1_set_clock, /* set clock source */ - lmc_dummy_set2_1, /* set line speed */ - lmc_dummy_set_1, /* set cable length */ - lmc_dummy_set_1, /* set scrambler */ - lmc_t1_get_link_status, /* get link status */ - lmc_dummy_set_1, /* set link status */ - lmc_t1_set_crc_length, /* set CRC length */ - lmc_t1_set_circuit_type, /* set T1 or E1 circuit type */ - lmc_t1_watchdog -}; - - -#endif - diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 0be5a0b30725..df383645e366 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -93,7 +93,7 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, if (!dev->irq && dev->pin) { printk(KERN_WARNING "%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", - __FUNCTION__, dev->device, dev->vendor); + __FUNCTION__, dev->vendor, dev->device); } if (pcie_port_device_register(dev)) { pci_disable_device(dev); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 7f94fc098cd3..65d6f23ead41 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -963,6 +963,13 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_ho * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it * becomes necessary to do this tweak in two steps -- I've chosen the Host * bridge as trigger. + * + * Note that we used to unhide the SMBus that way on Toshiba laptops + * (Satellite A40 and Tecra M2) but then found that the thermal management + * was done by SMM code, which could cause unsynchronized concurrent + * accesses to the SMBus registers, with potentially bad effects. Thus you + * should be very careful when adding new entries: if SMM is accessing the + * Intel SMBus, this is a very good reason to leave it hidden. */ static int asus_hides_smbus; @@ -1040,17 +1047,6 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) case 0x099c: /* HP Compaq nx6110 */ asus_hides_smbus = 1; } - } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) { - if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB) - switch(dev->subsystem_device) { - case 0x0001: /* Toshiba Satellite A40 */ - asus_hides_smbus = 1; - } - else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) - switch(dev->subsystem_device) { - case 0x0001: /* Toshiba Tecra M2 */ - asus_hides_smbus = 1; - } } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG)) { if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) switch(dev->subsystem_device) { diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index 551bde5d9430..b693367d38cd 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c @@ -372,7 +372,7 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, skt->socket.resource_ops = &pccard_static_ops; skt->socket.ops = &au1x00_pcmcia_operations; skt->socket.owner = ops->owner; - skt->socket.dev.dev = dev; + skt->socket.dev.parent = dev; init_timer(&skt->poll_timer); skt->poll_timer.function = au1x00_pcmcia_poll_event; diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index ab782bb46ac1..e810e4a44ed4 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -65,7 +65,7 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */ * resulting condition code and DIAG return code. */ static inline int dia250(void *iob, int cmd) { - register unsigned long reg0 asm ("0") = (unsigned long) iob; + register unsigned long reg2 asm ("2") = (unsigned long) iob; typedef union { struct dasd_diag_init_io init_io; struct dasd_diag_rw_io rw_io; @@ -74,15 +74,15 @@ static inline int dia250(void *iob, int cmd) rc = 3; asm volatile( - " diag 0,%2,0x250\n" + " diag 2,%2,0x250\n" "0: ipm %0\n" " srl %0,28\n" - " or %0,1\n" + " or %0,3\n" "1:\n" EX_TABLE(0b,1b) : "+d" (rc), "=m" (*(addr_type *) iob) - : "d" (cmd), "d" (reg0), "m" (*(addr_type *) iob) - : "1", "cc"); + : "d" (cmd), "d" (reg2), "m" (*(addr_type *) iob) + : "3", "cc"); return rc; } diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c index 6b1caea622ea..25d99bd28089 100644 --- a/drivers/s390/cio/device_status.c +++ b/drivers/s390/cio/device_status.c @@ -263,7 +263,11 @@ ccw_device_accumulate_irb(struct ccw_device *cdev, struct irb *irb) cdev_irb->scsw.cpa = irb->scsw.cpa; /* Accumulate device status, but not the device busy flag. */ cdev_irb->scsw.dstat &= ~DEV_STAT_BUSY; - cdev_irb->scsw.dstat |= irb->scsw.dstat; + /* dstat is not always valid. */ + if (irb->scsw.stctl & + (SCSW_STCTL_PRIM_STATUS | SCSW_STCTL_SEC_STATUS + | SCSW_STCTL_INTER_STATUS | SCSW_STCTL_ALERT_STATUS)) + cdev_irb->scsw.dstat |= irb->scsw.dstat; /* Accumulate subchannel status. */ cdev_irb->scsw.cstat |= irb->scsw.cstat; /* Copy residual count if it is valid. */ diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 181b51772b1b..bf37cdf43fae 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -505,6 +505,9 @@ static int ap_device_remove(struct device *dev) spin_lock_bh(&ap_device_lock); list_del_init(&ap_dev->list); spin_unlock_bh(&ap_device_lock); + spin_lock_bh(&ap_dev->lock); + atomic_sub(ap_dev->queue_count, &ap_poll_requests); + spin_unlock_bh(&ap_dev->lock); return 0; } @@ -757,10 +760,16 @@ static void ap_scan_bus(struct work_struct *unused) (void *)(unsigned long)qid, __ap_scan_bus); rc = ap_query_queue(qid, &queue_depth, &device_type); - if (dev && rc) { - put_device(dev); - device_unregister(dev); - continue; + if (dev) { + ap_dev = to_ap_dev(dev); + spin_lock_bh(&ap_dev->lock); + if (rc || ap_dev->unregistered) { + spin_unlock_bh(&ap_dev->lock); + put_device(dev); + device_unregister(dev); + continue; + } else + spin_unlock_bh(&ap_dev->lock); } if (dev) { put_device(dev); @@ -861,6 +870,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags) case AP_RESPONSE_NO_PENDING_REPLY: if (status.queue_empty) { /* The card shouldn't forget requests but who knows. */ + atomic_sub(ap_dev->queue_count, &ap_poll_requests); ap_dev->queue_count = 0; list_splice_init(&ap_dev->pendingq, &ap_dev->requestq); ap_dev->requestq_count += ap_dev->pendingq_count; @@ -994,7 +1004,7 @@ void ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_msg) ap_dev->unregistered = 1; } else { ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV)); - rc = 0; + rc = -ENODEV; } spin_unlock_bh(&ap_dev->lock); if (rc == -ENODEV) @@ -1044,18 +1054,12 @@ static void ap_poll_timeout(unsigned long unused) */ static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags) { - int rc; - spin_lock(&ap_dev->lock); if (!ap_dev->unregistered) { - rc = ap_poll_queue(ap_dev, flags); - if (rc) + if (ap_poll_queue(ap_dev, flags)) ap_dev->unregistered = 1; - } else - rc = 0; + } spin_unlock(&ap_dev->lock); - if (rc) - device_unregister(&ap_dev->device); return 0; } diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 8c81cec85298..60446b88f721 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -3091,6 +3091,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) cmdp->u.raw64.direction = gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN; memcpy(cmdp->u.raw64.cmd,scp->cmnd,16); + cmdp->u.raw64.sg_ranz = 0; } else { cmdp->u.raw.reserved = 0; cmdp->u.raw.mdisc_time = 0; @@ -3107,6 +3108,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) cmdp->u.raw.direction = gdth_direction_tab[scp->cmnd[0]]==DOU ? GDTH_DATA_OUT:GDTH_DATA_IN; memcpy(cmdp->u.raw.cmd,scp->cmnd,12); + cmdp->u.raw.sg_ranz = 0; } if (scp->use_sg) { diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 9d014e5a81c4..057fd7e0e379 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1817,10 +1817,9 @@ static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev, struct lpfc_sli *psli = &phba->sli; struct lpfc_sli_ring *pring; - if (state == pci_channel_io_perm_failure) { - lpfc_pci_remove_one(pdev); + if (state == pci_channel_io_perm_failure) return PCI_ERS_RESULT_DISCONNECT; - } + pci_disable_device(pdev); /* * There may be I/Os dropped by the firmware. diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 2328128728be..6657331eed93 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -189,8 +189,8 @@ static DECLARE_MUTEX(board_lock); * this is exported so that for example a USB or parport based adapter * driver could add devices (which it would learn about out-of-band). */ -struct spi_device *__init_or_module -spi_new_device(struct spi_master *master, struct spi_board_info *chip) +struct spi_device *spi_new_device(struct spi_master *master, + struct spi_board_info *chip) { struct spi_device *proxy; struct device *dev = master->cdev.dev; @@ -352,8 +352,7 @@ static struct class spi_master_class = { * the master's methods before calling spi_register_master(); and (after errors * adding the device) calling spi_master_put() to prevent a memory leak. */ -struct spi_master * __init_or_module -spi_alloc_master(struct device *dev, unsigned size) +struct spi_master *spi_alloc_master(struct device *dev, unsigned size) { struct spi_master *master; @@ -392,8 +391,7 @@ EXPORT_SYMBOL_GPL(spi_alloc_master); * After a successful return, the caller is responsible for calling * spi_unregister_master(). */ -int __init_or_module -spi_register_master(struct spi_master *master) +int spi_register_master(struct spi_master *master) { static atomic_t dyn_bus_id = ATOMIC_INIT((1<<16) - 1); struct device *dev = master->cdev.dev; diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 0e5c646cb4f6..f08ec85a6d64 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -30,7 +30,8 @@ static const struct usb_device_id usb_quirk_list[] = { /* HP 5300/5370C scanner */ { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, - + /* Seiko Epson Corp - Perfection 1670 */ + { USB_DEVICE(0x04b8, 0x011f), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Elsa MicroLink 56k (V.250) */ { USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 8f9a2b615422..b394e63894d2 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -296,6 +296,15 @@ omap_free_request(struct usb_ep *ep, struct usb_request *_req) /*-------------------------------------------------------------------------*/ +/* + * dma-coherent memory allocation (for dma-capable endpoints) + * + * NOTE: the dma_*_coherent() API calls suck. Most implementations are + * (a) page-oriented, so small buffers lose big; and (b) asymmetric with + * respect to calls with irqs disabled: alloc is safe, free is not. + * We currently work around (b), but not (a). + */ + static void * omap_alloc_buffer( struct usb_ep *_ep, @@ -307,6 +316,9 @@ omap_alloc_buffer( void *retval; struct omap_ep *ep; + if (!_ep) + return NULL; + ep = container_of(_ep, struct omap_ep, ep); if (use_dma && ep->has_dma) { static int warned; @@ -326,6 +338,35 @@ omap_alloc_buffer( return retval; } +static DEFINE_SPINLOCK(buflock); +static LIST_HEAD(buffers); + +struct free_record { + struct list_head list; + struct device *dev; + unsigned bytes; + dma_addr_t dma; +}; + +static void do_free(unsigned long ignored) +{ + spin_lock_irq(&buflock); + while (!list_empty(&buffers)) { + struct free_record *buf; + + buf = list_entry(buffers.next, struct free_record, list); + list_del(&buf->list); + spin_unlock_irq(&buflock); + + dma_free_coherent(buf->dev, buf->bytes, buf, buf->dma); + + spin_lock_irq(&buflock); + } + spin_unlock_irq(&buflock); +} + +static DECLARE_TASKLET(deferred_free, do_free, 0); + static void omap_free_buffer( struct usb_ep *_ep, void *buf, @@ -333,13 +374,29 @@ static void omap_free_buffer( unsigned bytes ) { - struct omap_ep *ep; + if (!_ep) { + WARN_ON(1); + return; + } - ep = container_of(_ep, struct omap_ep, ep); - if (use_dma && _ep && ep->has_dma) - dma_free_coherent(ep->udc->gadget.dev.parent, bytes, buf, dma); - else - kfree (buf); + /* free memory into the right allocator */ + if (dma != DMA_ADDR_INVALID) { + struct omap_ep *ep; + struct free_record *rec = buf; + unsigned long flags; + + ep = container_of(_ep, struct omap_ep, ep); + + rec->dev = ep->udc->gadget.dev.parent; + rec->bytes = bytes; + rec->dma = dma; + + spin_lock_irqsave(&buflock, flags); + list_add_tail(&rec->list, &buffers); + tasklet_schedule(&deferred_free); + spin_unlock_irqrestore(&buflock, flags); + } else + kfree(buf); } /*-------------------------------------------------------------------------*/ @@ -1691,12 +1748,38 @@ ep0out_status_stage: udc->ep0_pending = 0; break; case USB_REQ_GET_STATUS: + /* USB_ENDPOINT_HALT status? */ + if (u.r.bRequestType != (USB_DIR_IN|USB_RECIP_ENDPOINT)) + goto intf_status; + + /* ep0 never stalls */ + if (!(w_index & 0xf)) + goto zero_status; + + /* only active endpoints count */ + ep = &udc->ep[w_index & 0xf]; + if (w_index & USB_DIR_IN) + ep += 16; + if (!ep->desc) + goto do_stall; + + /* iso never stalls */ + if (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) + goto zero_status; + + /* FIXME don't assume non-halted endpoints!! */ + ERR("%s status, can't report\n", ep->ep.name); + goto do_stall; + +intf_status: /* return interface status. if we were pedantic, * we'd detect non-existent interfaces, and stall. */ if (u.r.bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)) goto delegate; + +zero_status: /* return two zero bytes */ UDC_EP_NUM_REG = UDC_EP_SEL|UDC_EP_DIR; UDC_DATA_REG = 0; @@ -2068,7 +2151,7 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev) /*-------------------------------------------------------------------------*/ -static inline int machine_needs_vbus_session(void) +static inline int machine_without_vbus_sense(void) { return (machine_is_omap_innovator() || machine_is_omap_osk() @@ -2156,7 +2239,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) /* boards that don't have VBUS sensing can't autogate 48MHz; * can't enter deep sleep while a gadget driver is active. */ - if (machine_needs_vbus_session()) + if (machine_without_vbus_sense()) omap_vbus_session(&udc->gadget, 1); done: @@ -2179,7 +2262,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) if (udc->dc_clk != NULL) omap_udc_enable_clock(1); - if (machine_needs_vbus_session()) + if (machine_without_vbus_sense()) omap_vbus_session(&udc->gadget, 0); if (udc->transceiver) @@ -2822,7 +2905,7 @@ static int __init omap_udc_probe(struct platform_device *pdev) hmc = HMC_1510; type = "(unknown)"; - if (machine_is_omap_innovator() || machine_is_sx1()) { + if (machine_without_vbus_sense()) { /* just set up software VBUS detect, and then * later rig it so we always report VBUS. * FIXME without really sensing VBUS, we can't diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 8d24d3dc0a61..1497371583b9 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -145,7 +145,8 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space) return out - buf; } -static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) +static int uhci_show_qh(struct uhci_hcd *uhci, + struct uhci_qh *qh, char *buf, int len, int space) { char *out = buf; int i, nurbs; @@ -190,6 +191,9 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) if (list_empty(&qh->queue)) { out += sprintf(out, "%*s queue is empty\n", space, ""); + if (qh == uhci->skel_async_qh) + out += uhci_show_td(uhci->term_td, out, + len - (out - buf), 0); } else { struct urb_priv *urbp = list_entry(qh->queue.next, struct urb_priv, node); @@ -343,6 +347,7 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) struct list_head *tmp, *head; int nframes, nerrs; __le32 link; + __le32 fsbr_link; static const char * const qh_names[] = { "unlink", "iso", "int128", "int64", "int32", "int16", @@ -424,21 +429,22 @@ check_link: out += sprintf(out, "Skeleton QHs\n"); + fsbr_link = 0; for (i = 0; i < UHCI_NUM_SKELQH; ++i) { int cnt = 0; - __le32 fsbr_link = 0; qh = uhci->skelqh[i]; out += sprintf(out, "- skel_%s_qh\n", qh_names[i]); \ - out += uhci_show_qh(qh, out, len - (out - buf), 4); + out += uhci_show_qh(uhci, qh, out, len - (out - buf), 4); /* Last QH is the Terminating QH, it's different */ if (i == SKEL_TERM) { if (qh_element(qh) != LINK_TO_TD(uhci->term_td)) out += sprintf(out, " skel_term_qh element is not set to term_td!\n"); - if (link == LINK_TO_QH(uhci->skel_term_qh)) - goto check_qh_link; - continue; + link = fsbr_link; + if (!link) + link = LINK_TO_QH(uhci->skel_term_qh); + goto check_qh_link; } head = &qh->node; @@ -448,7 +454,7 @@ check_link: qh = list_entry(tmp, struct uhci_qh, node); tmp = tmp->next; if (++cnt <= 10) - out += uhci_show_qh(qh, out, + out += uhci_show_qh(uhci, qh, out, len - (out - buf), 4); if (!fsbr_link && qh->skel >= SKEL_FSBR) fsbr_link = LINK_TO_QH(qh); @@ -463,8 +469,6 @@ check_link: link = LINK_TO_QH(uhci->skel_async_qh); else if (!uhci->fsbr_is_on) ; - else if (fsbr_link) - link = fsbr_link; else link = LINK_TO_QH(uhci->skel_term_qh); check_qh_link: @@ -573,8 +577,8 @@ static const struct file_operations uhci_debug_operations = { static inline void lprintk(char *buf) {} -static inline int uhci_show_qh(struct uhci_qh *qh, char *buf, - int len, int space) +static inline int uhci_show_qh(struct uhci_hcd *uhci, + struct uhci_qh *qh, char *buf, int len, int space) { return 0; } diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 44da4334f1d6..d22da26ff167 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -632,7 +632,8 @@ static int uhci_start(struct usb_hcd *hcd) */ for (i = SKEL_ISO + 1; i < SKEL_ASYNC; ++i) uhci->skelqh[i]->link = LINK_TO_QH(uhci->skel_async_qh); - uhci->skel_async_qh->link = uhci->skel_term_qh->link = UHCI_PTR_TERM; + uhci->skel_async_qh->link = UHCI_PTR_TERM; + uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_term_qh); /* This dummy TD is to work around a bug in Intel PIIX controllers */ uhci_fill_td(uhci->term_td, 0, uhci_explen(0) | diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index f4ebdb3e488f..19a0cc02b9a2 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -45,43 +45,27 @@ static inline void uhci_clear_next_interrupt(struct uhci_hcd *uhci) */ static void uhci_fsbr_on(struct uhci_hcd *uhci) { - struct uhci_qh *fsbr_qh, *lqh, *tqh; + struct uhci_qh *lqh; + /* The terminating skeleton QH always points back to the first + * FSBR QH. Make the last async QH point to the terminating + * skeleton QH. */ uhci->fsbr_is_on = 1; lqh = list_entry(uhci->skel_async_qh->node.prev, struct uhci_qh, node); - - /* Find the first FSBR QH. Linear search through the list is - * acceptable because normally FSBR gets turned on as soon as - * one QH needs it. */ - fsbr_qh = NULL; - list_for_each_entry_reverse(tqh, &uhci->skel_async_qh->node, node) { - if (tqh->skel < SKEL_FSBR) - break; - fsbr_qh = tqh; - } - - /* No FSBR QH means we must insert the terminating skeleton QH */ - if (!fsbr_qh) { - uhci->skel_term_qh->link = LINK_TO_QH(uhci->skel_term_qh); - wmb(); - lqh->link = uhci->skel_term_qh->link; - - /* Otherwise loop the last QH to the first FSBR QH */ - } else - lqh->link = LINK_TO_QH(fsbr_qh); + lqh->link = LINK_TO_QH(uhci->skel_term_qh); } static void uhci_fsbr_off(struct uhci_hcd *uhci) { struct uhci_qh *lqh; + /* Remove the link from the last async QH to the terminating + * skeleton QH. */ uhci->fsbr_is_on = 0; lqh = list_entry(uhci->skel_async_qh->node.prev, struct uhci_qh, node); - - /* End the async list normally and unlink the terminating QH */ - lqh->link = uhci->skel_term_qh->link = UHCI_PTR_TERM; + lqh->link = UHCI_PTR_TERM; } static void uhci_add_fsbr(struct uhci_hcd *uhci, struct urb *urb) @@ -464,9 +448,8 @@ static void link_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh) */ static void link_async(struct uhci_hcd *uhci, struct uhci_qh *qh) { - struct uhci_qh *pqh, *lqh; + struct uhci_qh *pqh; __le32 link_to_new_qh; - __le32 *extra_link = &link_to_new_qh; /* Find the predecessor QH for our new one and insert it in the list. * The list of QHs is expected to be short, so linear search won't @@ -476,31 +459,17 @@ static void link_async(struct uhci_hcd *uhci, struct uhci_qh *qh) break; } list_add(&qh->node, &pqh->node); - qh->link = pqh->link; - - link_to_new_qh = LINK_TO_QH(qh); - - /* If this is now the first FSBR QH, take special action */ - if (uhci->fsbr_is_on && pqh->skel < SKEL_FSBR && - qh->skel >= SKEL_FSBR) { - lqh = list_entry(uhci->skel_async_qh->node.prev, - struct uhci_qh, node); - - /* If the new QH is also the last one, we must unlink - * the terminating skeleton QH and make the new QH point - * back to itself. */ - if (qh == lqh) { - qh->link = link_to_new_qh; - extra_link = &uhci->skel_term_qh->link; - - /* Otherwise the last QH must point to the new QH */ - } else - extra_link = &lqh->link; - } /* Link it into the schedule */ + qh->link = pqh->link; wmb(); - *extra_link = pqh->link = link_to_new_qh; + link_to_new_qh = LINK_TO_QH(qh); + pqh->link = link_to_new_qh; + + /* If this is now the first FSBR QH, link the terminating skeleton + * QH to it. */ + if (pqh->skel < SKEL_FSBR && qh->skel >= SKEL_FSBR) + uhci->skel_term_qh->link = link_to_new_qh; } /* @@ -561,31 +530,16 @@ static void unlink_interrupt(struct uhci_hcd *uhci, struct uhci_qh *qh) */ static void unlink_async(struct uhci_hcd *uhci, struct uhci_qh *qh) { - struct uhci_qh *pqh, *lqh; + struct uhci_qh *pqh; __le32 link_to_next_qh = qh->link; pqh = list_entry(qh->node.prev, struct uhci_qh, node); - - /* If this is the first FSBQ QH, take special action */ - if (uhci->fsbr_is_on && pqh->skel < SKEL_FSBR && - qh->skel >= SKEL_FSBR) { - lqh = list_entry(uhci->skel_async_qh->node.prev, - struct uhci_qh, node); - - /* If this QH is also the last one, we must link in - * the terminating skeleton QH. */ - if (qh == lqh) { - link_to_next_qh = LINK_TO_QH(uhci->skel_term_qh); - uhci->skel_term_qh->link = link_to_next_qh; - wmb(); - qh->link = link_to_next_qh; - - /* Otherwise the last QH must point to the new first FSBR QH */ - } else - lqh->link = link_to_next_qh; - } - pqh->link = link_to_next_qh; + + /* If this was the old first FSBR QH, link the terminating skeleton + * QH to the next (new first FSBR) QH. */ + if (pqh->skel < SKEL_FSBR && qh->skel >= SKEL_FSBR) + uhci->skel_term_qh->link = link_to_next_qh; mb(); } @@ -1217,7 +1171,7 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) if (debug > 1 && errbuf) { /* Print the chain for debugging */ - uhci_show_qh(urbp->qh, errbuf, + uhci_show_qh(uhci, urbp->qh, errbuf, ERRBUF_LEN, 0); lprintk(errbuf); } diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 7538c64a5097..39a498362594 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -18,7 +18,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ - { USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */ { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */ { }, }; diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 1633a0fd48e8..8ff9d54b21e6 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -879,6 +879,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port) break; case FT232BM: /* FT232BM chip */ case FT2232C: /* FT2232C chip */ + case FT232RL: if (baud <= 3000000) { div_value = ftdi_232bm_baud_to_divisor(baud); } else { @@ -1021,9 +1022,12 @@ static void ftdi_determine_type(struct usb_serial_port *port) /* (It might be a BM because of the iSerialNumber bug, * but it will still work as an AM device.) */ priv->chip_type = FT8U232AM; - } else { + } else if (version < 0x600) { /* Assume its an FT232BM (or FT245BM) */ priv->chip_type = FT232BM; + } else { + /* Assume its an FT232R */ + priv->chip_type = FT232RL; } info("Detected %s", ftdi_chip_name[priv->chip_type]); } diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 53baeec8f265..4f8282ad7720 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -20,13 +20,14 @@ #include <linux/usb/serial.h> #include <asm/uaccess.h> -static int generic_probe(struct usb_interface *interface, - const struct usb_device_id *id); - static int debug; #ifdef CONFIG_USB_SERIAL_GENERIC + +static int generic_probe(struct usb_interface *interface, + const struct usb_device_id *id); + static __u16 vendor = 0x05f9; static __u16 product = 0xffff; diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index 8ada4c5c5d70..6a82d39dc498 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h @@ -40,7 +40,6 @@ extern struct file_system_type v9fs_fs_type; extern const struct address_space_operations v9fs_addr_operations; extern const struct file_operations v9fs_file_operations; -extern const struct file_operations v9fs_cached_file_operations; extern const struct file_operations v9fs_dir_operations; extern struct dentry_operations v9fs_dentry_operations; extern struct dentry_operations v9fs_cached_dentry_operations; diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 653dfa5b2531..c7b677253843 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c @@ -42,6 +42,8 @@ #include "v9fs_vfs.h" #include "fid.h" +static const struct file_operations v9fs_cached_file_operations; + /** * v9fs_file_open - open a file (or directory) * @inode: inode to be opened @@ -245,7 +247,7 @@ v9fs_file_write(struct file *filp, const char __user * data, return total; } -const struct file_operations v9fs_cached_file_operations = { +static const struct file_operations v9fs_cached_file_operations = { .llseek = generic_file_llseek, .read = do_sync_read, .aio_read = generic_file_aio_read, @@ -136,7 +136,6 @@ static int aio_setup_ring(struct kioctx *ctx) 0); if (IS_ERR((void *)info->mmap_base)) { up_write(&ctx->mm->mmap_sem); - printk("mmap err: %ld\n", -info->mmap_base); info->mmap_size = 0; aio_free_ring(ctx); return -EAGAIN; diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 6f677988c71d..7e4bb0af24d7 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -859,8 +859,8 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, #define NFS3_ENTRY_BAGGAGE (2 + 1 + 2 + 1) #define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2)) static int -encode_entry(struct readdir_cd *ccd, const char *name, - int namlen, off_t offset, ino_t ino, unsigned int d_type, int plus) +encode_entry(struct readdir_cd *ccd, const char *name, int namlen, + loff_t offset, ino_t ino, unsigned int d_type, int plus) { struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres, common); @@ -880,7 +880,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, *cd->offset1 = htonl(offset64 & 0xffffffff); cd->offset1 = NULL; } else { - xdr_encode_hyper(cd->offset, (u64) offset); + xdr_encode_hyper(cd->offset, offset64); } } diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 832673b14587..673a53c014a3 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -228,7 +228,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, struct posix_acl_summary pas; unsigned short deny; int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ? - NFS4_INHERITANCE_FLAGS : 0); + NFS4_INHERITANCE_FLAGS | NFS4_ACE_INHERIT_ONLY_ACE : 0); BUG_ON(pacl->a_count < 3); summarize_posix_acl(pacl, &pas); diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 9e4067999209..af360705e551 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -750,9 +750,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, status = nfserr_clid_inuse; if (!cmp_creds(&conf->cl_cred, &rqstp->rq_cred) || conf->cl_addr != sin->sin_addr.s_addr) { - printk("NFSD: setclientid: string in use by client" - "(clientid %08x/%08x)\n", - conf->cl_clientid.cl_boot, conf->cl_clientid.cl_id); + dprintk("NFSD: setclientid: string in use by client" + "at %u.%u.%u.%u\n", NIPQUAD(conf->cl_addr)); goto out; } } @@ -3261,7 +3260,6 @@ __nfs4_state_shutdown(void) unhash_delegation(dp); } - cancel_delayed_work(&laundromat_work); nfsd4_shutdown_recdir(); nfs4_init = 0; } diff --git a/fs/proc/Makefile b/fs/proc/Makefile index a6b3a8f878f0..bce38e3f06cb 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile @@ -8,8 +8,9 @@ proc-y := nommu.o task_nommu.o proc-$(CONFIG_MMU) := mmu.o task_mmu.o proc-y += inode.o root.o base.o generic.o array.o \ - proc_tty.o proc_misc.o proc_sysctl.o + proc_tty.o proc_misc.o +proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o proc-$(CONFIG_PROC_KCORE) += kcore.o proc-$(CONFIG_PROC_VMCORE) += vmcore.o proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o diff --git a/fs/splice.c b/fs/splice.c index 2fca6ebf4cc2..07f6556add0a 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -576,76 +576,21 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, if (this_len + offset > PAGE_CACHE_SIZE) this_len = PAGE_CACHE_SIZE - offset; - /* - * Reuse buf page, if SPLICE_F_MOVE is set and we are doing a full - * page. - */ - if ((sd->flags & SPLICE_F_MOVE) && this_len == PAGE_CACHE_SIZE) { - /* - * If steal succeeds, buf->page is now pruned from the - * pagecache and we can reuse it. The page will also be - * locked on successful return. - */ - if (buf->ops->steal(pipe, buf)) - goto find_page; - - page = buf->page; - if (add_to_page_cache(page, mapping, index, GFP_KERNEL)) { - unlock_page(page); - goto find_page; - } - - page_cache_get(page); - - if (!(buf->flags & PIPE_BUF_FLAG_LRU)) - lru_cache_add(page); - } else { find_page: - page = find_lock_page(mapping, index); - if (!page) { - ret = -ENOMEM; - page = page_cache_alloc_cold(mapping); - if (unlikely(!page)) - goto out_ret; - - /* - * This will also lock the page - */ - ret = add_to_page_cache_lru(page, mapping, index, - GFP_KERNEL); - if (unlikely(ret)) - goto out; - } + page = find_lock_page(mapping, index); + if (!page) { + ret = -ENOMEM; + page = page_cache_alloc_cold(mapping); + if (unlikely(!page)) + goto out_ret; /* - * We get here with the page locked. If the page is also - * uptodate, we don't need to do more. If it isn't, we - * may need to bring it in if we are not going to overwrite - * the full page. + * This will also lock the page */ - if (!PageUptodate(page)) { - if (this_len < PAGE_CACHE_SIZE) { - ret = mapping->a_ops->readpage(file, page); - if (unlikely(ret)) - goto out; - - lock_page(page); - - if (!PageUptodate(page)) { - /* - * Page got invalidated, repeat. - */ - if (!page->mapping) { - unlock_page(page); - page_cache_release(page); - goto find_page; - } - ret = -EIO; - goto out; - } - } else - SetPageUptodate(page); - } + ret = add_to_page_cache_lru(page, mapping, index, + GFP_KERNEL); + if (unlikely(ret)) + goto out; } ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); @@ -706,9 +651,9 @@ out_ret: * key here is the 'actor' worker passed in that actually moves the data * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. */ -static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, - struct file *out, loff_t *ppos, size_t len, - unsigned int flags, splice_actor *actor) +ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, + struct file *out, loff_t *ppos, size_t len, + unsigned int flags, splice_actor *actor) { int ret, do_wakeup, err; struct splice_desc sd; @@ -802,6 +747,7 @@ static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, return ret; } +EXPORT_SYMBOL(__splice_from_pipe); ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, loff_t *ppos, size_t len, unsigned int flags, diff --git a/include/asm-i386/termbits.h b/include/asm-i386/termbits.h index 12baf1d6343f..2e6237693814 100644 --- a/include/asm-i386/termbits.h +++ b/include/asm-i386/termbits.h @@ -144,7 +144,7 @@ struct ktermios { #define B3000000 0010015 #define B3500000 0010016 #define B4000000 0010017 -#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CIBAUD 002003600000 #define CMSPAR 010000000000 /* mark or space (stick) parity */ #define CRTSCTS 020000000000 /* flow control */ diff --git a/include/asm-s390/checksum.h b/include/asm-s390/checksum.h index 0a3cd7ec8451..d5a8e7c1477c 100644 --- a/include/asm-s390/checksum.h +++ b/include/asm-s390/checksum.h @@ -121,50 +121,21 @@ csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, unsigned short proto, __wsum sum) { -#ifndef __s390x__ - asm volatile( - " alr %0,%1\n" /* sum += saddr */ - " brc 12,0f\n" - " ahi %0,1\n" /* add carry */ - "0:" - : "+&d" (sum) : "d" (saddr) : "cc"); - asm volatile( - " alr %0,%1\n" /* sum += daddr */ - " brc 12,1f\n" - " ahi %0,1\n" /* add carry */ - "1:" - : "+&d" (sum) : "d" (daddr) : "cc"); - asm volatile( - " alr %0,%1\n" /* sum += len + proto */ - " brc 12,2f\n" - " ahi %0,1\n" /* add carry */ - "2:" - : "+&d" (sum) - : "d" (len + proto) - : "cc"); -#else /* __s390x__ */ - asm volatile( - " lgfr %0,%0\n" - " algr %0,%1\n" /* sum += saddr */ - " brc 12,0f\n" - " aghi %0,1\n" /* add carry */ - "0: algr %0,%2\n" /* sum += daddr */ - " brc 12,1f\n" - " aghi %0,1\n" /* add carry */ - "1: algfr %0,%3\n" /* sum += len + proto */ - " brc 12,2f\n" - " aghi %0,1\n" /* add carry */ - "2: srlg 0,%0,32\n" - " alr %0,0\n" /* fold to 32 bits */ - " brc 12,3f\n" - " ahi %0,1\n" /* add carry */ - "3: llgfr %0,%0" - : "+&d" (sum) - : "d" (saddr), "d" (daddr), - "d" (len + proto) - : "cc", "0"); -#endif /* __s390x__ */ - return sum; + __u32 csum = (__force __u32)sum; + + csum += (__force __u32)saddr; + if (csum < (__force __u32)saddr) + csum++; + + csum += (__force __u32)daddr; + if (csum < (__force __u32)daddr) + csum++; + + csum += len + proto; + if (csum < len + proto) + csum++; + + return (__force __wsum)csum; } /* diff --git a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S index f0454516dd31..b16222b42821 100644 --- a/include/asm-um/common.lds.S +++ b/include/asm-um/common.lds.S @@ -15,6 +15,7 @@ PROVIDE (_unprotected_end = .); . = ALIGN(4096); + .note : { *(note.*) } __start___ex_table = .; __ex_table : { *(__ex_table) } __stop___ex_table = .; diff --git a/include/linux/compiler.h b/include/linux/compiler.h index aca66984aafd..3b6949b41745 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -15,8 +15,8 @@ # define __acquire(x) __context__(x,1) # define __release(x) __context__(x,-1) # define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0) -extern void __chk_user_ptr(void __user *); -extern void __chk_io_ptr(void __iomem *); +extern void __chk_user_ptr(const void __user *); +extern void __chk_io_ptr(const void __iomem *); #else # define __user # define __kernel diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h index 84cfa8bbdc36..d2a96cbf4f0e 100644 --- a/include/linux/eventpoll.h +++ b/include/linux/eventpoll.h @@ -31,12 +31,19 @@ /* * On x86-64 make the 64bit structure have the same alignment as the * 32bit structure. This makes 32bit emulation easier. + * + * UML/x86_64 needs the same packing as x86_64 - UML + UML_X86 + + * 64_BIT adds up to UML/x86_64. */ #ifdef __x86_64__ #define EPOLL_PACKED __attribute__((packed)) #else +#if defined(CONFIG_UML) && defined(CONFIG_UML_X86) && defined(CONFIG_64BIT) +#define EPOLL_PACKED __attribute__((packed)) +#else #define EPOLL_PACKED #endif +#endif struct epoll_event { __u32 events; diff --git a/include/linux/ide.h b/include/linux/ide.h index 34f2676b3c62..58564a199862 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -615,6 +615,7 @@ typedef struct ide_drive_s { u8 init_speed; /* transfer rate set at boot */ u8 pio_speed; /* unused by core, used by some drivers for fallback from DMA */ u8 current_speed; /* current transfer rate set */ + u8 desired_speed; /* desired transfer rate set */ u8 dn; /* now wide spread use */ u8 wcache; /* status of write cache */ u8 acoustic; /* acoustic management */ diff --git a/include/linux/ipc.h b/include/linux/ipc.h index 636094c29b16..6da6772c19ff 100644 --- a/include/linux/ipc.h +++ b/include/linux/ipc.h @@ -92,19 +92,16 @@ extern struct ipc_namespace init_ipc_ns; #ifdef CONFIG_SYSVIPC #define INIT_IPC_NS(ns) .ns = &init_ipc_ns, +extern int copy_ipcs(unsigned long flags, struct task_struct *tsk); #else #define INIT_IPC_NS(ns) +static inline int copy_ipcs(unsigned long flags, struct task_struct *tsk) +{ return 0; } #endif #ifdef CONFIG_IPC_NS extern void free_ipc_ns(struct kref *kref); -extern int copy_ipcs(unsigned long flags, struct task_struct *tsk); extern int unshare_ipcs(unsigned long flags, struct ipc_namespace **ns); -#else -static inline int copy_ipcs(unsigned long flags, struct task_struct *tsk) -{ - return 0; -} #endif static inline struct ipc_namespace *get_ipc_ns(struct ipc_namespace *ns) diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index 2e19478e9e84..8bcbc54e1b48 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h @@ -99,4 +99,8 @@ extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int, splice_actor *); +extern ssize_t __splice_from_pipe(struct pipe_inode_info *, struct file *, + loff_t *, size_t, unsigned int, + splice_actor *); + #endif diff --git a/include/linux/utsname.h b/include/linux/utsname.h index a4555fe3754c..e10267d402c5 100644 --- a/include/linux/utsname.h +++ b/include/linux/utsname.h @@ -70,6 +70,8 @@ static inline int unshare_utsname(unsigned long unshare_flags, static inline int copy_utsname(int flags, struct task_struct *tsk) { + if (flags & CLONE_NEWUTS) + return -EINVAL; return 0; } static inline void put_uts_ns(struct uts_namespace *ns) diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h index 83fe2e3d1e25..50e33b0e9349 100644 --- a/include/media/saa7146_vv.h +++ b/include/media/saa7146_vv.h @@ -239,7 +239,8 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits); #define SAA7146_HPS_SYNC_PORT_B 0x01 /* some memory sizes */ -#define SAA7146_CLIPPING_MEM (14*PAGE_SIZE) +/* max. 16 clipping rectangles */ +#define SAA7146_CLIPPING_MEM (16 * 4 * sizeof(u32)) /* some defines for the various clipping-modes */ #define SAA7146_CLIPPING_RECT 0x4 diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index bc3c26494c3d..d585ea9fa97d 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h @@ -34,6 +34,7 @@ struct fib_rules_ops int family; struct list_head list; int rule_size; + int addr_size; int (*action)(struct fib_rule *, struct flowi *, int, diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 9eda572a2a65..cf355a3c2ad5 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -58,6 +58,7 @@ struct fib6_node __u16 fn_bit; /* bit key */ __u16 fn_flags; __u32 fn_sernum; + struct rt6_info *rr_ptr; }; #ifndef CONFIG_IPV6_SUBTREES diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 3725b93c52f3..ad7fe1121412 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -36,7 +36,7 @@ struct neigh_parms struct net_device *dev; struct neigh_parms *next; int (*neigh_setup)(struct neighbour *); - void (*neigh_destructor)(struct neighbour *); + void (*neigh_cleanup)(struct neighbour *); struct neigh_table *tbl; void *sysctl_table; diff --git a/ipc/util.c b/ipc/util.c index 08a647965b9e..0b652387d169 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -144,6 +144,13 @@ void free_ipc_ns(struct kref *kref) shm_exit_ns(ns); kfree(ns); } +#else +int copy_ipcs(unsigned long flags, struct task_struct *tsk) +{ + if (flags & CLONE_NEWIPC) + return -EINVAL; + return 0; +} #endif /** diff --git a/kernel/power/disk.c b/kernel/power/disk.c index dee0ff40befd..aec19b063e3f 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c @@ -58,7 +58,6 @@ static inline int platform_prepare(void) static void power_down(suspend_disk_method_t mode) { - disable_nonboot_cpus(); switch(mode) { case PM_DISK_PLATFORM: if (pm_ops && pm_ops->enter) { diff --git a/kernel/power/user.c b/kernel/power/user.c index bf211fee1222..7cf6713b2325 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -401,10 +401,9 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, case PMOPS_ENTER: if (data->platform_suspend) { - disable_nonboot_cpus(); kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); error = pm_ops->enter(PM_SUSPEND_DISK); - enable_nonboot_cpus(); + error = 0; } break; diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c index 67932ea78c17..76212b2a99de 100644 --- a/kernel/time/clockevents.c +++ b/kernel/time/clockevents.c @@ -274,72 +274,3 @@ void clockevents_notify(unsigned long reason, void *arg) } EXPORT_SYMBOL_GPL(clockevents_notify); -#ifdef CONFIG_SYSFS - -/** - * clockevents_show_registered - sysfs interface for listing clockevents - * @dev: unused - * @buf: char buffer to be filled with clock events list - * - * Provides sysfs interface for listing registered clock event devices - */ -static ssize_t clockevents_show_registered(struct sys_device *dev, char *buf) -{ - struct list_head *tmp; - char *p = buf; - int cpu; - - spin_lock(&clockevents_lock); - - list_for_each(tmp, &clockevent_devices) { - struct clock_event_device *ce; - - ce = list_entry(tmp, struct clock_event_device, list); - p += sprintf(p, "%-20s F:%04x M:%d", ce->name, - ce->features, ce->mode); - p += sprintf(p, " C:"); - if (!cpus_equal(ce->cpumask, cpu_possible_map)) { - for_each_cpu_mask(cpu, ce->cpumask) - p += sprintf(p, " %d", cpu); - } else { - /* - * FIXME: Add the cpu which is handling this sucker - */ - } - p += sprintf(p, "\n"); - } - - spin_unlock(&clockevents_lock); - - return p - buf; -} - -/* - * Sysfs setup bits: - */ -static SYSDEV_ATTR(registered, 0600, - clockevents_show_registered, NULL); - -static struct sysdev_class clockevents_sysclass = { - set_kset_name("clockevents"), -}; - -static struct sys_device clockevents_sys_device = { - .id = 0, - .cls = &clockevents_sysclass, -}; - -static int __init clockevents_sysfs_init(void) -{ - int error = sysdev_class_register(&clockevents_sysclass); - - if (!error) - error = sysdev_register(&clockevents_sys_device); - if (!error) - error = sysdev_create_file( - &clockevents_sys_device, - &attr_registered); - return error; -} -device_initcall(clockevents_sysfs_init); -#endif diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index eb12509e00bd..cb25649c6f50 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c @@ -32,7 +32,7 @@ static u64 tick_length, tick_length_base; /* TIME_ERROR prevents overwriting the CMOS clock */ static int time_state = TIME_OK; /* clock synchronization status */ int time_status = STA_UNSYNC; /* clock status bits */ -static long time_offset; /* time adjustment (ns) */ +static s64 time_offset; /* time adjustment (ns) */ static long time_constant = 2; /* pll time constant */ long time_maxerror = NTP_PHASE_LIMIT; /* maximum error (us) */ long time_esterror = NTP_PHASE_LIMIT; /* estimated error (us) */ @@ -196,7 +196,7 @@ void __attribute__ ((weak)) notify_arch_cmos_timer(void) */ int do_adjtimex(struct timex *txc) { - long ltemp, mtemp, save_adjust; + long mtemp, save_adjust, rem; s64 freq_adj, temp64; int result; @@ -277,14 +277,14 @@ int do_adjtimex(struct timex *txc) time_adjust = txc->offset; } else if (time_status & STA_PLL) { - ltemp = txc->offset * NSEC_PER_USEC; + time_offset = txc->offset * NSEC_PER_USEC; /* * Scale the phase adjustment and * clamp to the operating range. */ - time_offset = min(ltemp, MAXPHASE * NSEC_PER_USEC); - time_offset = max(time_offset, -MAXPHASE * NSEC_PER_USEC); + time_offset = min(time_offset, (s64)MAXPHASE * NSEC_PER_USEC); + time_offset = max(time_offset, (s64)-MAXPHASE * NSEC_PER_USEC); /* * Select whether the frequency is to be controlled @@ -297,11 +297,11 @@ int do_adjtimex(struct timex *txc) mtemp = xtime.tv_sec - time_reftime; time_reftime = xtime.tv_sec; - freq_adj = (s64)time_offset * mtemp; + freq_adj = time_offset * mtemp; freq_adj = shift_right(freq_adj, time_constant * 2 + (SHIFT_PLL + 2) * 2 - SHIFT_NSEC); if (mtemp >= MINSEC && (time_status & STA_FLL || mtemp > MAXSEC)) { - temp64 = (s64)time_offset << (SHIFT_NSEC - SHIFT_FLL); + temp64 = time_offset << (SHIFT_NSEC - SHIFT_FLL); if (time_offset < 0) { temp64 = -temp64; do_div(temp64, mtemp); @@ -314,8 +314,10 @@ int do_adjtimex(struct timex *txc) freq_adj += time_freq; freq_adj = min(freq_adj, (s64)MAXFREQ_NSEC); time_freq = max(freq_adj, (s64)-MAXFREQ_NSEC); - time_offset = (time_offset / NTP_INTERVAL_FREQ) - << SHIFT_UPDATE; + time_offset = div_long_long_rem_signed(time_offset, + NTP_INTERVAL_FREQ, + &rem); + time_offset <<= SHIFT_UPDATE; } /* STA_PLL */ } /* txc->modes & ADJ_OFFSET */ if (txc->modes & ADJ_TICK) @@ -328,12 +330,12 @@ leave: if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0) result = TIME_ERROR; if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT) - txc->offset = save_adjust; + txc->offset = save_adjust; else - txc->offset = shift_right(time_offset, SHIFT_UPDATE) - * NTP_INTERVAL_FREQ / 1000; - txc->freq = (time_freq / NSEC_PER_USEC) - << (SHIFT_USEC - SHIFT_NSEC); + txc->offset = ((long)shift_right(time_offset, SHIFT_UPDATE)) * + NTP_INTERVAL_FREQ / 1000; + txc->freq = (time_freq / NSEC_PER_USEC) << + (SHIFT_USEC - SHIFT_NSEC); txc->maxerror = time_maxerror; txc->esterror = time_esterror; txc->status = time_status; diff --git a/mm/bounce.c b/mm/bounce.c index 643efbe82402..ad401fc57440 100644 --- a/mm/bounce.c +++ b/mm/bounce.c @@ -204,7 +204,7 @@ static void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig, /* * is destination page below bounce pfn? */ - if (page_to_pfn(page) < q->bounce_pfn) + if (page_to_pfn(page) <= q->bounce_pfn) continue; /* diff --git a/net/atm/clip.c b/net/atm/clip.c index ebb5d0ce8b6f..8c3825816085 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -261,14 +261,6 @@ static void clip_pop(struct atm_vcc *vcc, struct sk_buff *skb) spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags); } -static void clip_neigh_destroy(struct neighbour *neigh) -{ - DPRINTK("clip_neigh_destroy (neigh %p)\n", neigh); - if (NEIGH2ENTRY(neigh)->vccs) - printk(KERN_CRIT "clip_neigh_destroy: vccs != NULL !!!\n"); - NEIGH2ENTRY(neigh)->vccs = (void *) NEIGHBOR_DEAD; -} - static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb) { DPRINTK("clip_neigh_solicit (neigh %p, skb %p)\n", neigh, skb); @@ -342,7 +334,6 @@ static struct neigh_table clip_tbl = { /* parameters are copied from ARP ... */ .parms = { .tbl = &clip_tbl, - .neigh_destructor = clip_neigh_destroy, .base_reachable_time = 30 * HZ, .retrans_time = 1 * HZ, .gc_staletime = 60 * HZ, diff --git a/net/ax25/Kconfig b/net/ax25/Kconfig index a8993a041724..43dd86fca4d3 100644 --- a/net/ax25/Kconfig +++ b/net/ax25/Kconfig @@ -1,30 +1,27 @@ # # Amateur Radio protocols and AX.25 device configuration # -# 19971130 Now in an own category to make correct compilation of the -# AX.25 stuff easier... -# Joerg Reuter DL1BKE <jreuter@yaina.de> -# 19980129 Moved to net/ax25/Config.in, sourcing device drivers. menuconfig HAMRADIO depends on NET bool "Amateur Radio support" help If you want to connect your Linux box to an amateur radio, answer Y - here. You want to read <http://www.tapr.org/tapr/html/pkthome.html> and - the AX25-HOWTO, available from <http://www.tldp.org/docs.html#howto>. + here. You want to read <http://www.tapr.org/tapr/html/pkthome.html> + and more specifically about AX.25 on Linux + <http://www.linux-ax25.org/>. Note that the answer to this question won't directly affect the kernel: saying N will just cause the configurator to skip all the questions about amateur radio. comment "Packet Radio protocols" - depends on HAMRADIO && NET + depends on HAMRADIO config AX25 tristate "Amateur Radio AX.25 Level 2 protocol" - depends on HAMRADIO && NET - ---help--- + depends on HAMRADIO + help This is the protocol used for computer communication over amateur radio. It is either used by itself for point-to-point links, or to carry other protocols such as tcp/ip. To use it, you need a device @@ -52,6 +49,7 @@ config AX25 config AX25_DAMA_SLAVE bool "AX.25 DAMA Slave support" + default y depends on AX25 help DAMA is a mechanism to prevent collisions when doing AX.25 @@ -59,23 +57,38 @@ config AX25_DAMA_SLAVE from clients (called "slaves") and redistributes it to other slaves. If you say Y here, your Linux box will act as a DAMA slave; this is transparent in that you don't have to do any special DAMA - configuration. (Linux cannot yet act as a DAMA server.) If unsure, - say N. + configuration. Linux cannot yet act as a DAMA server. This option + only compiles DAMA slave support into the kernel. It still needs to + be enabled at runtime. For more about DAMA see + <http://www.linux-ax25.org>. If unsure, say Y. + +# placeholder until implemented +config AX25_DAMA_MASTER + bool 'AX.25 DAMA Master support' + depends on AX25_DAMA_SLAVE && BROKEN + help + DAMA is a mechanism to prevent collisions when doing AX.25 + networking. A DAMA server (called "master") accepts incoming traffic + from clients (called "slaves") and redistributes it to other slaves. + If you say Y here, your Linux box will act as a DAMA master; this is + transparent in that you don't have to do any special DAMA + configuration. Linux cannot yet act as a DAMA server. This option + only compiles DAMA slave support into the kernel. It still needs to + be explicitly enabled, so if unsure, say Y. -# bool ' AX.25 DAMA Master support' CONFIG_AX25_DAMA_MASTER config NETROM tristate "Amateur Radio NET/ROM protocol" depends on AX25 - ---help--- + help NET/ROM is a network layer protocol on top of AX.25 useful for routing. A comprehensive listing of all the software for Linux amateur radio users as well as information about how to configure an AX.25 port is - contained in the AX25-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. You also might want to - check out the file <file:Documentation/networking/ax25.txt>. More - information about digital amateur radio in general is on the WWW at + contained in the Linux Ham Wiki, available from + <http://www.linux-ax25.org>. You also might want to check out the + file <file:Documentation/networking/ax25.txt>. More information about + digital amateur radio in general is on the WWW at <http://www.tapr.org/tapr/html/pkthome.html>. To compile this driver as a module, choose M here: the @@ -84,27 +97,25 @@ config NETROM config ROSE tristate "Amateur Radio X.25 PLP (Rose)" depends on AX25 - ---help--- + help The Packet Layer Protocol (PLP) is a way to route packets over X.25 connections in general and amateur radio AX.25 connections in particular, essentially an alternative to NET/ROM. A comprehensive listing of all the software for Linux amateur radio users as well as information about how to configure an AX.25 port is - contained in the AX25-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. You also might want to - check out the file <file:Documentation/networking/ax25.txt>. More - information about digital amateur radio in general is on the WWW at + contained in the Linux Ham Wiki, available from + <http://www.linux-ax25.org>. You also might want to check out the + file <file:Documentation/networking/ax25.txt>. More information about + digital amateur radio in general is on the WWW at <http://www.tapr.org/tapr/html/pkthome.html>. To compile this driver as a module, choose M here: the module will be called rose. - menu "AX.25 network device drivers" - depends on HAMRADIO && NET && AX25!=n + depends on HAMRADIO && AX25 source "drivers/net/hamradio/Kconfig" endmenu - diff --git a/net/core/dev.c b/net/core/dev.c index cf71614dae93..5984b55311a1 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1750,10 +1750,10 @@ static int ing_filter(struct sk_buff *skb) skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_INGRESS); - spin_lock(&dev->ingress_lock); + spin_lock(&dev->queue_lock); if ((q = dev->qdisc_ingress) != NULL) result = q->enqueue(skb, q); - spin_unlock(&dev->ingress_lock); + spin_unlock(&dev->queue_lock); } diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 3aea4e87d3d7..d011819a8058 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -152,6 +152,28 @@ out: EXPORT_SYMBOL_GPL(fib_rules_lookup); +static int validate_rulemsg(struct fib_rule_hdr *frh, struct nlattr **tb, + struct fib_rules_ops *ops) +{ + int err = -EINVAL; + + if (frh->src_len) + if (tb[FRA_SRC] == NULL || + frh->src_len > (ops->addr_size * 8) || + nla_len(tb[FRA_SRC]) != ops->addr_size) + goto errout; + + if (frh->dst_len) + if (tb[FRA_DST] == NULL || + frh->dst_len > (ops->addr_size * 8) || + nla_len(tb[FRA_DST]) != ops->addr_size) + goto errout; + + err = 0; +errout: + return err; +} + int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) { struct fib_rule_hdr *frh = nlmsg_data(nlh); @@ -173,6 +195,10 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) if (err < 0) goto errout; + err = validate_rulemsg(frh, tb, ops); + if (err < 0) + goto errout; + rule = kzalloc(ops->rule_size, GFP_KERNEL); if (rule == NULL) { err = -ENOMEM; @@ -260,6 +286,10 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) if (err < 0) goto errout; + err = validate_rulemsg(frh, tb, ops); + if (err < 0) + goto errout; + list_for_each_entry(rule, ops->rules_list, list) { if (frh->action && (frh->action != rule->action)) continue; diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 3183142c6044..cfc60019cf92 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -140,6 +140,8 @@ static int neigh_forced_gc(struct neigh_table *tbl) n->dead = 1; shrunk = 1; write_unlock(&n->lock); + if (n->parms->neigh_cleanup) + n->parms->neigh_cleanup(n); neigh_release(n); continue; } @@ -211,6 +213,8 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev) NEIGH_PRINTK2("neigh %p is stray.\n", n); } write_unlock(&n->lock); + if (n->parms->neigh_cleanup) + n->parms->neigh_cleanup(n); neigh_release(n); } } @@ -582,9 +586,6 @@ void neigh_destroy(struct neighbour *neigh) kfree(hh); } - if (neigh->parms->neigh_destructor) - (neigh->parms->neigh_destructor)(neigh); - skb_queue_purge(&neigh->arp_queue); dev_put(neigh->dev); @@ -675,6 +676,8 @@ static void neigh_periodic_timer(unsigned long arg) *np = n->next; n->dead = 1; write_unlock(&n->lock); + if (n->parms->neigh_cleanup) + n->parms->neigh_cleanup(n); neigh_release(n); continue; } @@ -2088,8 +2091,11 @@ void __neigh_for_each_release(struct neigh_table *tbl, } else np = &n->next; write_unlock(&n->lock); - if (release) + if (release) { + if (n->parms->neigh_cleanup) + n->parms->neigh_cleanup(n); neigh_release(n); + } } } } diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index a0e7cd183a5d..e33a9edb4036 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -191,7 +191,6 @@ extern void dccp_send_sync(struct sock *sk, const u64 seq, const enum dccp_pkt_type pkt_type); extern void dccp_write_xmit(struct sock *sk, int block); -extern void dccp_write_xmit_timer(unsigned long data); extern void dccp_write_space(struct sock *sk); extern void dccp_init_xmit_timers(struct sock *sk); diff --git a/net/dccp/timer.c b/net/dccp/timer.c index b038a0a3ad40..0197a41c256a 100644 --- a/net/dccp/timer.c +++ b/net/dccp/timer.c @@ -262,7 +262,7 @@ out: } /* Transmit-delay timer: used by the CCIDs to delay actual send time */ -void dccp_write_xmit_timer(unsigned long data) +static void dccp_write_xmit_timer(unsigned long data) { struct sock *sk = (struct sock *)data; struct dccp_sock *dp = dccp_sk(sk); diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 3cbfddc98430..82d58a977e6f 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -63,7 +63,7 @@ static struct { int error; u8 scope; -} dn_fib_props[RTA_MAX+1] = { +} dn_fib_props[RTN_MAX+1] = { [RTN_UNSPEC] = { .error = 0, .scope = RT_SCOPE_NOWHERE }, [RTN_UNICAST] = { .error = 0, .scope = RT_SCOPE_UNIVERSE }, [RTN_LOCAL] = { .error = 0, .scope = RT_SCOPE_HOST }, @@ -276,6 +276,9 @@ struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, struct dn_kern_rta struct dn_fib_info *ofi; int nhs = 1; + if (r->rtm_type > RTN_MAX) + goto err_inval; + if (dn_fib_props[r->rtm_type].scope > r->rtm_scope) goto err_inval; diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index b6c98ac93dc8..5e86dd542302 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c @@ -109,8 +109,6 @@ errout: static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { FRA_GENERIC_POLICY, - [FRA_SRC] = { .type = NLA_U16 }, - [FRA_DST] = { .type = NLA_U16 }, }; static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) @@ -133,7 +131,7 @@ static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb, int err = -EINVAL; struct dn_fib_rule *r = (struct dn_fib_rule *)rule; - if (frh->src_len > 16 || frh->dst_len > 16 || frh->tos) + if (frh->tos) goto errout; if (rule->table == RT_TABLE_UNSPEC) { @@ -150,10 +148,10 @@ static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb, } } - if (tb[FRA_SRC]) + if (frh->src_len) r->src = nla_get_le16(tb[FRA_SRC]); - if (tb[FRA_DST]) + if (frh->dst_len) r->dst = nla_get_le16(tb[FRA_DST]); r->src_len = frh->src_len; @@ -176,10 +174,10 @@ static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, if (frh->dst_len && (r->dst_len != frh->dst_len)) return 0; - if (tb[FRA_SRC] && (r->src != nla_get_le16(tb[FRA_SRC]))) + if (frh->src_len && (r->src != nla_get_le16(tb[FRA_SRC]))) return 0; - if (tb[FRA_DST] && (r->dst != nla_get_le16(tb[FRA_DST]))) + if (frh->dst_len && (r->dst != nla_get_le16(tb[FRA_DST]))) return 0; return 1; @@ -249,6 +247,7 @@ int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb) static struct fib_rules_ops dn_fib_rules_ops = { .family = AF_DECnet, .rule_size = sizeof(struct dn_fib_rule), + .addr_size = sizeof(u16), .action = dn_fib_rule_action, .match = dn_fib_rule_match, .configure = dn_fib_rule_configure, diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 1fba6439fc57..fc920f63452b 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -493,6 +493,11 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh, cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid; cfg->fc_nlinfo.nlh = nlh; + if (cfg->fc_type > RTN_MAX) { + err = -EINVAL; + goto errout; + } + nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) { switch (attr->nla_type) { case RTA_DST: diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index b837c33e0404..c660c074c76c 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c @@ -171,8 +171,6 @@ static struct fib_table *fib_empty_table(void) static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = { FRA_GENERIC_POLICY, - [FRA_SRC] = { .type = NLA_U32 }, - [FRA_DST] = { .type = NLA_U32 }, [FRA_FLOW] = { .type = NLA_U32 }, }; @@ -183,8 +181,7 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, int err = -EINVAL; struct fib4_rule *rule4 = (struct fib4_rule *) rule; - if (frh->src_len > 32 || frh->dst_len > 32 || - (frh->tos & ~IPTOS_TOS_MASK)) + if (frh->tos & ~IPTOS_TOS_MASK) goto errout; if (rule->table == RT_TABLE_UNSPEC) { @@ -201,10 +198,10 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, } } - if (tb[FRA_SRC]) + if (frh->src_len) rule4->src = nla_get_be32(tb[FRA_SRC]); - if (tb[FRA_DST]) + if (frh->dst_len) rule4->dst = nla_get_be32(tb[FRA_DST]); #ifdef CONFIG_NET_CLS_ROUTE @@ -242,10 +239,10 @@ static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, return 0; #endif - if (tb[FRA_SRC] && (rule4->src != nla_get_be32(tb[FRA_SRC]))) + if (frh->src_len && (rule4->src != nla_get_be32(tb[FRA_SRC]))) return 0; - if (tb[FRA_DST] && (rule4->dst != nla_get_be32(tb[FRA_DST]))) + if (frh->dst_len && (rule4->dst != nla_get_be32(tb[FRA_DST]))) return 0; return 1; @@ -309,6 +306,7 @@ static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule) static struct fib_rules_ops fib4_rules_ops = { .family = AF_INET, .rule_size = sizeof(struct fib4_rule), + .addr_size = sizeof(u32), .action = fib4_rule_action, .match = fib4_rule_match, .configure = fib4_rule_configure, diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 2f1fdae6efa6..3dad12ee76c3 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -89,7 +89,7 @@ static const struct { int error; u8 scope; -} fib_props[RTA_MAX + 1] = { +} fib_props[RTN_MAX + 1] = { { .error = 0, .scope = RT_SCOPE_NOWHERE, diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index ada9b3db507d..214c34732e84 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1123,6 +1123,9 @@ err: return fa_head; } +/* + * Caller must hold RTNL. + */ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) { struct trie *t = (struct trie *) tb->tb_data; @@ -1540,6 +1543,9 @@ static int trie_leaf_remove(struct trie *t, t_key key) return 1; } +/* + * Caller must hold RTNL. + */ static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg) { struct trie *t = (struct trie *) tb->tb_data; @@ -1718,6 +1724,9 @@ up: return NULL; /* Ready. Root of trie */ } +/* + * Caller must hold RTNL. + */ static int fn_trie_flush(struct fib_table *tb) { struct trie *t = (struct trie *) tb->tb_data; diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 0862809ffcf7..ea3035b4e3e8 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -131,8 +131,6 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = { FRA_GENERIC_POLICY, - [FRA_SRC] = { .len = sizeof(struct in6_addr) }, - [FRA_DST] = { .len = sizeof(struct in6_addr) }, }; static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, @@ -142,9 +140,6 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, int err = -EINVAL; struct fib6_rule *rule6 = (struct fib6_rule *) rule; - if (frh->src_len > 128 || frh->dst_len > 128) - goto errout; - if (rule->action == FR_ACT_TO_TBL) { if (rule->table == RT6_TABLE_UNSPEC) goto errout; @@ -155,11 +150,11 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, } } - if (tb[FRA_SRC]) + if (frh->src_len) nla_memcpy(&rule6->src.addr, tb[FRA_SRC], sizeof(struct in6_addr)); - if (tb[FRA_DST]) + if (frh->dst_len) nla_memcpy(&rule6->dst.addr, tb[FRA_DST], sizeof(struct in6_addr)); @@ -186,11 +181,11 @@ static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, if (frh->tos && (rule6->tclass != frh->tos)) return 0; - if (tb[FRA_SRC] && + if (frh->src_len && nla_memcmp(tb[FRA_SRC], &rule6->src.addr, sizeof(struct in6_addr))) return 0; - if (tb[FRA_DST] && + if (frh->dst_len && nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr))) return 0; @@ -240,6 +235,7 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule) static struct fib_rules_ops fib6_rules_ops = { .family = AF_INET6, .rule_size = sizeof(struct fib6_rule), + .addr_size = sizeof(struct in6_addr), .action = fib6_rule_action, .match = fib6_rule_match, .configure = fib6_rule_configure, diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index f4d7be77eb0f..268f476ef3db 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -658,6 +658,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, ins = &iter->u.dst.rt6_next; } + /* Reset round-robin state, if necessary */ + if (ins == &fn->leaf) + fn->rr_ptr = NULL; + /* * insert node */ @@ -1109,6 +1113,10 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, rt6_stats.fib_rt_entries--; rt6_stats.fib_discarded_routes++; + /* Reset round-robin state, if necessary */ + if (fn->rr_ptr == rt) + fn->rr_ptr = NULL; + /* Adjust walkers */ read_lock(&fib6_walker_lock); FOR_WALKERS(w) { diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a6b3117df546..3931b33b25e8 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -363,55 +363,76 @@ static int rt6_score_route(struct rt6_info *rt, int oif, return m; } -static struct rt6_info *rt6_select(struct rt6_info **head, int oif, - int strict) +static struct rt6_info *find_match(struct rt6_info *rt, int oif, int strict, + int *mpri, struct rt6_info *match) { - struct rt6_info *match = NULL, *last = NULL; - struct rt6_info *rt, *rt0 = *head; - u32 metric; + int m; + + if (rt6_check_expired(rt)) + goto out; + + m = rt6_score_route(rt, oif, strict); + if (m < 0) + goto out; + + if (m > *mpri) { + if (strict & RT6_LOOKUP_F_REACHABLE) + rt6_probe(match); + *mpri = m; + match = rt; + } else if (strict & RT6_LOOKUP_F_REACHABLE) { + rt6_probe(rt); + } + +out: + return match; +} + +static struct rt6_info *find_rr_leaf(struct fib6_node *fn, + struct rt6_info *rr_head, + u32 metric, int oif, int strict) +{ + struct rt6_info *rt, *match; int mpri = -1; - RT6_TRACE("%s(head=%p(*head=%p), oif=%d)\n", - __FUNCTION__, head, head ? *head : NULL, oif); + match = NULL; + for (rt = rr_head; rt && rt->rt6i_metric == metric; + rt = rt->u.dst.rt6_next) + match = find_match(rt, oif, strict, &mpri, match); + for (rt = fn->leaf; rt && rt != rr_head && rt->rt6i_metric == metric; + rt = rt->u.dst.rt6_next) + match = find_match(rt, oif, strict, &mpri, match); - for (rt = rt0, metric = rt0->rt6i_metric; - rt && rt->rt6i_metric == metric && (!last || rt != rt0); - rt = rt->u.dst.rt6_next) { - int m; + return match; +} - if (rt6_check_expired(rt)) - continue; +static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict) +{ + struct rt6_info *match, *rt0; - last = rt; + RT6_TRACE("%s(fn->leaf=%p, oif=%d)\n", + __FUNCTION__, fn->leaf, oif); - m = rt6_score_route(rt, oif, strict); - if (m < 0) - continue; + rt0 = fn->rr_ptr; + if (!rt0) + fn->rr_ptr = rt0 = fn->leaf; - if (m > mpri) { - if (strict & RT6_LOOKUP_F_REACHABLE) - rt6_probe(match); - match = rt; - mpri = m; - } else if (strict & RT6_LOOKUP_F_REACHABLE) { - rt6_probe(rt); - } - } + match = find_rr_leaf(fn, rt0, rt0->rt6i_metric, oif, strict); if (!match && - (strict & RT6_LOOKUP_F_REACHABLE) && - last && last != rt0) { + (strict & RT6_LOOKUP_F_REACHABLE)) { + struct rt6_info *next = rt0->u.dst.rt6_next; + /* no entries matched; do round-robin */ - static DEFINE_SPINLOCK(lock); - spin_lock(&lock); - *head = rt0->u.dst.rt6_next; - rt0->u.dst.rt6_next = last->u.dst.rt6_next; - last->u.dst.rt6_next = rt0; - spin_unlock(&lock); + if (!next || next->rt6i_metric != rt0->rt6i_metric) + next = fn->leaf; + + if (next != rt0) + fn->rr_ptr = next; } - RT6_TRACE("%s() => %p, score=%d\n", - __FUNCTION__, match, mpri); + RT6_TRACE("%s() => %p\n", + __FUNCTION__, match); return (match ? match : &ip6_null_entry); } @@ -657,7 +678,7 @@ restart_2: fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); restart: - rt = rt6_select(&fn->leaf, fl->iif, strict | reachable); + rt = rt6_select(fn, fl->iif, strict | reachable); BACKTRACK(&fl->fl6_src); if (rt == &ip6_null_entry || rt->rt6i_flags & RTF_CACHE) @@ -752,7 +773,7 @@ restart_2: fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); restart: - rt = rt6_select(&fn->leaf, fl->oif, strict | reachable); + rt = rt6_select(fn, fl->oif, strict | reachable); BACKTRACK(&fl->fl6_src); if (rt == &ip6_null_entry || rt->rt6i_flags & RTF_CACHE) diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index fad08e521c24..70fe36eb66a2 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -81,6 +81,13 @@ static void basic_put(struct tcf_proto *tp, unsigned long f) static int basic_init(struct tcf_proto *tp) { + struct basic_head *head; + + head = kzalloc(sizeof(*head), GFP_KERNEL); + if (head == NULL) + return -ENOBUFS; + INIT_LIST_HEAD(&head->flist); + tp->root = head; return 0; } @@ -176,15 +183,6 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle, } err = -ENOBUFS; - if (head == NULL) { - head = kzalloc(sizeof(*head), GFP_KERNEL); - if (head == NULL) - goto errout; - - INIT_LIST_HEAD(&head->flist); - tp->root = head; - } - f = kzalloc(sizeof(*f), GFP_KERNEL); if (f == NULL) goto errout; diff --git a/net/socket.c b/net/socket.c index 9566e57ac7f5..ea8f81abc45c 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1381,7 +1381,7 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, err = sock_attach_fd(newsock, newfile); if (err < 0) - goto out_fd; + goto out_fd_simple; err = security_socket_accept(sock, newsock); if (err) @@ -1414,6 +1414,11 @@ out_put: fput_light(sock->file, fput_needed); out: return err; +out_fd_simple: + sock_release(newsock); + put_filp(newfile); + put_unused_fd(newfd); + goto out_put; out_fd: fput(newfile); put_unused_fd(newfd); |