diff options
-rw-r--r-- | 2.6.32/0000_README | 4 | ||||
-rw-r--r-- | 2.6.32/1043_linux-2.6.32.44.patch | 1455 |
2 files changed, 1459 insertions, 0 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README index 97013da..5e4d4d1 100644 --- a/2.6.32/0000_README +++ b/2.6.32/0000_README @@ -3,6 +3,10 @@ README Individual Patch Descriptions: ----------------------------------------------------------------------------- +Patch: 1043_linux-2.6.32.44.patch +From: http://www.kernel.org +Desc: Linux 2.6.39.44 + Patch: 4420_grsecurity-2.2.2-2.6.32.44-201108111959.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/2.6.32/1043_linux-2.6.32.44.patch b/2.6.32/1043_linux-2.6.32.44.patch new file mode 100644 index 0000000..c71b835 --- /dev/null +++ b/2.6.32/1043_linux-2.6.32.44.patch @@ -0,0 +1,1455 @@ +diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c +index 62619f2..a94e49c 100644 +--- a/arch/alpha/kernel/osf_sys.c ++++ b/arch/alpha/kernel/osf_sys.c +@@ -431,7 +431,7 @@ SYSCALL_DEFINE2(osf_getdomainname, char __user *, name, int, namelen) + return -EFAULT; + + len = namelen; +- if (namelen > 32) ++ if (len > 32) + len = 32; + + down_read(&uts_sem); +@@ -618,7 +618,7 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count) + down_read(&uts_sem); + res = sysinfo_table[offset]; + len = strlen(res)+1; +- if (len > count) ++ if ((unsigned long)len > (unsigned long)count) + len = count; + if (copy_to_user(buf, res, len)) + err = -EFAULT; +@@ -673,7 +673,7 @@ SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer, + return 1; + + case GSI_GET_HWRPB: +- if (nbytes < sizeof(*hwrpb)) ++ if (nbytes > sizeof(*hwrpb)) + return -EINVAL; + if (copy_to_user(buffer, hwrpb, nbytes) != 0) + return -EFAULT; +@@ -1035,6 +1035,7 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options, + { + struct rusage r; + long ret, err; ++ unsigned int status = 0; + mm_segment_t old_fs; + + if (!ur) +@@ -1043,13 +1044,15 @@ SYSCALL_DEFINE4(osf_wait4, pid_t, pid, int __user *, ustatus, int, options, + old_fs = get_fs(); + + set_fs (KERNEL_DS); +- ret = sys_wait4(pid, ustatus, options, (struct rusage __user *) &r); ++ ret = sys_wait4(pid, (unsigned int __user *) &status, options, ++ (struct rusage __user *) &r); + set_fs (old_fs); + + if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur))) + return -EFAULT; + + err = 0; ++ err |= put_user(status, ustatus); + err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec); + err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec); + err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec); +diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c +index 52dd804..8904495 100644 +--- a/arch/arm/mach-davinci/board-dm365-evm.c ++++ b/arch/arm/mach-davinci/board-dm365-evm.c +@@ -413,7 +413,7 @@ fail: + */ + if (have_imager()) { + label = "HD imager"; +- mux |= 1; ++ mux |= 2; + + /* externally mux MMC1/ENET/AIC33 to imager */ + mux |= BIT(6) | BIT(5) | BIT(3); +@@ -434,7 +434,7 @@ fail: + resets &= ~BIT(1); + + if (have_tvp7002()) { +- mux |= 2; ++ mux |= 1; + resets &= ~BIT(2); + label = "tvp7002 HD"; + } else { +diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c +index 102916f..b6bfe7e 100644 +--- a/arch/arm/mach-pxa/cm-x300.c ++++ b/arch/arm/mach-pxa/cm-x300.c +@@ -143,10 +143,10 @@ static mfp_cfg_t cm_x300_mfp_cfg[] __initdata = { + GPIO99_GPIO, /* Ethernet IRQ */ + + /* RTC GPIOs */ +- GPIO95_GPIO, /* RTC CS */ +- GPIO96_GPIO, /* RTC WR */ +- GPIO97_GPIO, /* RTC RD */ +- GPIO98_GPIO, /* RTC IO */ ++ GPIO95_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC CS */ ++ GPIO96_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC WR */ ++ GPIO97_GPIO | MFP_LPM_DRIVE_HIGH, /* RTC RD */ ++ GPIO98_GPIO, /* RTC IO */ + + /* Standard I2C */ + GPIO21_I2C_SCL, +diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c +index 5009198..d374974 100644 +--- a/arch/powerpc/kernel/crash.c ++++ b/arch/powerpc/kernel/crash.c +@@ -176,12 +176,8 @@ static void crash_kexec_wait_realmode(int cpu) + + while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) { + barrier(); +- if (!cpu_possible(i)) { ++ if (!cpu_possible(i) || !cpu_online(i) || (msecs <= 0)) + break; +- } +- if (!cpu_online(i)) { +- break; +- } + msecs--; + mdelay(1); + } +diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c +index 3f6a89b..041e87c 100644 +--- a/arch/powerpc/platforms/pseries/hvconsole.c ++++ b/arch/powerpc/platforms/pseries/hvconsole.c +@@ -73,7 +73,7 @@ int hvc_put_chars(uint32_t vtermno, const char *buf, int count) + if (ret == H_SUCCESS) + return count; + if (ret == H_BUSY) +- return 0; ++ return -EAGAIN; + return -EIO; + } + +diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c +index 69cab24..987ef29 100644 +--- a/arch/x86/kernel/hpet.c ++++ b/arch/x86/kernel/hpet.c +@@ -27,6 +27,9 @@ + #define HPET_DEV_FSB_CAP 0x1000 + #define HPET_DEV_PERI_CAP 0x2000 + ++#define HPET_MIN_CYCLES 128 ++#define HPET_MIN_PROG_DELTA (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1)) ++ + #define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt) + + /* +@@ -298,8 +301,9 @@ static void hpet_legacy_clockevent_register(void) + /* Calculate the min / max delta */ + hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, + &hpet_clockevent); +- /* 5 usec minimum reprogramming delta. */ +- hpet_clockevent.min_delta_ns = 5000; ++ /* Setup minimum reprogramming delta. */ ++ hpet_clockevent.min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, ++ &hpet_clockevent); + + /* + * Start hpet with the boot cpu mask and make it +@@ -379,36 +383,37 @@ static int hpet_next_event(unsigned long delta, + struct clock_event_device *evt, int timer) + { + u32 cnt; ++ s32 res; + + cnt = hpet_readl(HPET_COUNTER); + cnt += (u32) delta; + hpet_writel(cnt, HPET_Tn_CMP(timer)); + + /* +- * We need to read back the CMP register on certain HPET +- * implementations (ATI chipsets) which seem to delay the +- * transfer of the compare register into the internal compare +- * logic. With small deltas this might actually be too late as +- * the counter could already be higher than the compare value +- * at that point and we would wait for the next hpet interrupt +- * forever. We found out that reading the CMP register back +- * forces the transfer so we can rely on the comparison with +- * the counter register below. If the read back from the +- * compare register does not match the value we programmed +- * then we might have a real hardware problem. We can not do +- * much about it here, but at least alert the user/admin with +- * a prominent warning. +- * An erratum on some chipsets (ICH9,..), results in comparator read +- * immediately following a write returning old value. Workaround +- * for this is to read this value second time, when first +- * read returns old value. ++ * HPETs are a complete disaster. The compare register is ++ * based on a equal comparison and neither provides a less ++ * than or equal functionality (which would require to take ++ * the wraparound into account) nor a simple count down event ++ * mode. Further the write to the comparator register is ++ * delayed internally up to two HPET clock cycles in certain ++ * chipsets (ATI, ICH9,10). Some newer AMD chipsets have even ++ * longer delays. We worked around that by reading back the ++ * compare register, but that required another workaround for ++ * ICH9,10 chips where the first readout after write can ++ * return the old stale value. We already had a minimum ++ * programming delta of 5us enforced, but a NMI or SMI hitting ++ * between the counter readout and the comparator write can ++ * move us behind that point easily. Now instead of reading ++ * the compare register back several times, we make the ETIME ++ * decision based on the following: Return ETIME if the ++ * counter value after the write is less than HPET_MIN_CYCLES ++ * away from the event or if the counter is already ahead of ++ * the event. The minimum programming delta for the generic ++ * clockevents code is set to 1.5 * HPET_MIN_CYCLES. + */ +- if (unlikely((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt)) { +- WARN_ONCE((u32)hpet_readl(HPET_Tn_CMP(timer)) != cnt, +- KERN_WARNING "hpet: compare register read back failed.\n"); +- } ++ res = (s32)(cnt - (u32)hpet_readl(HPET_COUNTER)); + +- return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0; ++ return res < HPET_MIN_CYCLES ? -ETIME : 0; + } + + static void hpet_legacy_set_mode(enum clock_event_mode mode, +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index 200fcde..cf98100 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -469,6 +469,14 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"), + }, + }, ++ { /* Handle problems with rebooting on the Latitude E5420. */ ++ .callback = set_pci_reboot, ++ .ident = "Dell Latitude E5420", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), ++ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5420"), ++ }, ++ }, + { } + }; + +diff --git a/arch/x86/kernel/relocate_kernel_32.S b/arch/x86/kernel/relocate_kernel_32.S +index 4123553..36818f8 100644 +--- a/arch/x86/kernel/relocate_kernel_32.S ++++ b/arch/x86/kernel/relocate_kernel_32.S +@@ -97,6 +97,8 @@ relocate_kernel: + ret + + identity_mapped: ++ /* set return address to 0 if not preserving context */ ++ pushl $0 + /* store the start address on the stack */ + pushl %edx + +diff --git a/arch/x86/kernel/relocate_kernel_64.S b/arch/x86/kernel/relocate_kernel_64.S +index 4de8f5b..7a6f3b3 100644 +--- a/arch/x86/kernel/relocate_kernel_64.S ++++ b/arch/x86/kernel/relocate_kernel_64.S +@@ -100,6 +100,8 @@ relocate_kernel: + ret + + identity_mapped: ++ /* set return address to 0 if not preserving context */ ++ pushq $0 + /* store the start address on the stack */ + pushq %rdx + +diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c +index 9486882..885ebe7 100644 +--- a/arch/xtensa/kernel/ptrace.c ++++ b/arch/xtensa/kernel/ptrace.c +@@ -136,6 +136,9 @@ int ptrace_setxregs(struct task_struct *child, void __user *uregs) + elf_xtregs_t *xtregs = uregs; + int ret = 0; + ++ if (!access_ok(VERIFY_READ, uregs, sizeof(elf_xtregs_t))) ++ return -EFAULT; ++ + #if XTENSA_HAVE_COPROCESSORS + /* Flush all coprocessors before we overwrite them. */ + coprocessor_flush_all(ti); +diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c +index fa9bed0..e5bdb9b 100644 +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -2707,10 +2707,11 @@ int ata_eh_reset(struct ata_link *link, int classify, + } + + /* +- * Some controllers can't be frozen very well and may set +- * spuruious error conditions during reset. Clear accumulated +- * error information. As reset is the final recovery action, +- * nothing is lost by doing this. ++ * Some controllers can't be frozen very well and may set spurious ++ * error conditions during reset. Clear accumulated error ++ * information and re-thaw the port if frozen. As reset is the ++ * final recovery action and we cross check link onlineness against ++ * device classification later, no hotplug event is lost by this. + */ + spin_lock_irqsave(link->ap->lock, flags); + memset(&link->eh_info, 0, sizeof(link->eh_info)); +@@ -2719,6 +2720,9 @@ int ata_eh_reset(struct ata_link *link, int classify, + ap->pflags &= ~ATA_PFLAG_EH_PENDING; + spin_unlock_irqrestore(link->ap->lock, flags); + ++ if (ap->pflags & ATA_PFLAG_FROZEN) ++ ata_eh_thaw_port(ap); ++ + /* + * Make sure onlineness and classification result correspond. + * Hotplug could have happened during reset and some +diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h +index 5ae1b1c..04d6bf8 100644 +--- a/drivers/block/cciss.h ++++ b/drivers/block/cciss.h +@@ -165,7 +165,7 @@ static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c) + printk("Sending %x - down to controller\n", c->busaddr ); + #endif /* CCISS_DEBUG */ + writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); +- readl(h->vaddr + SA5_REQUEST_PORT_OFFSET); ++ readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); + h->commands_outstanding++; + if ( h->commands_outstanding > h->max_outstanding) + h->max_outstanding = h->commands_outstanding; +diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c +index 9ac4972..5b6001b 100644 +--- a/drivers/hwmon/max1111.c ++++ b/drivers/hwmon/max1111.c +@@ -39,6 +39,8 @@ struct max1111_data { + struct spi_transfer xfer[2]; + uint8_t *tx_buf; + uint8_t *rx_buf; ++ struct mutex drvdata_lock; ++ /* protect msg, xfer and buffers from multiple access */ + }; + + static int max1111_read(struct device *dev, int channel) +@@ -47,6 +49,9 @@ static int max1111_read(struct device *dev, int channel) + uint8_t v1, v2; + int err; + ++ /* writing to drvdata struct is not thread safe, wait on mutex */ ++ mutex_lock(&data->drvdata_lock); ++ + data->tx_buf[0] = (channel << MAX1111_CTRL_SEL_SH) | + MAX1111_CTRL_PD0 | MAX1111_CTRL_PD1 | + MAX1111_CTRL_SGL | MAX1111_CTRL_UNI | MAX1111_CTRL_STR; +@@ -54,12 +59,15 @@ static int max1111_read(struct device *dev, int channel) + err = spi_sync(data->spi, &data->msg); + if (err < 0) { + dev_err(dev, "spi_sync failed with %d\n", err); ++ mutex_unlock(&data->drvdata_lock); + return err; + } + + v1 = data->rx_buf[0]; + v2 = data->rx_buf[1]; + ++ mutex_unlock(&data->drvdata_lock); ++ + if ((v1 & 0xc0) || (v2 & 0x3f)) + return -EINVAL; + +@@ -175,6 +183,8 @@ static int __devinit max1111_probe(struct spi_device *spi) + if (err) + goto err_free_data; + ++ mutex_init(&data->drvdata_lock); ++ + data->spi = spi; + spi_set_drvdata(spi, data); + +@@ -212,6 +222,7 @@ static int __devexit max1111_remove(struct spi_device *spi) + + hwmon_device_unregister(data->hwmon_dev); + sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); ++ mutex_destroy(&data->drvdata_lock); + kfree(data->rx_buf); + kfree(data->tx_buf); + kfree(data); +diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c +index fcf717c..b03cd39 100644 +--- a/drivers/md/dm-mpath.c ++++ b/drivers/md/dm-mpath.c +@@ -778,6 +778,11 @@ static int parse_features(struct arg_set *as, struct multipath *m) + if (!argc) + return 0; + ++ if (argc > as->argc) { ++ ti->error = "not enough arguments for features"; ++ return -EINVAL; ++ } ++ + do { + param_name = shift(as); + argc--; +diff --git a/drivers/md/dm.c b/drivers/md/dm.c +index d186687..c988ac2 100644 +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -36,6 +36,8 @@ static const char *_name = DM_NAME; + static unsigned int major = 0; + static unsigned int _major = 0; + ++static DEFINE_IDR(_minor_idr); ++ + static DEFINE_SPINLOCK(_minor_lock); + /* + * For bio-based dm. +@@ -315,6 +317,12 @@ static void __exit dm_exit(void) + + while (i--) + _exits[i](); ++ ++ /* ++ * Should be empty by this point. ++ */ ++ idr_remove_all(&_minor_idr); ++ idr_destroy(&_minor_idr); + } + + /* +@@ -1663,8 +1671,6 @@ static int dm_any_congested(void *congested_data, int bdi_bits) + /*----------------------------------------------------------------- + * An IDR is used to keep track of allocated minor numbers. + *---------------------------------------------------------------*/ +-static DEFINE_IDR(_minor_idr); +- + static void free_minor(int minor) + { + spin_lock(&_minor_lock); +diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c +index 6a0028e..93653c6 100644 +--- a/drivers/media/radio/si4713-i2c.c ++++ b/drivers/media/radio/si4713-i2c.c +@@ -1003,7 +1003,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev, + char ps_name[MAX_RDS_PS_NAME + 1]; + + len = control->size - 1; +- if (len > MAX_RDS_PS_NAME) { ++ if (len < 0 || len > MAX_RDS_PS_NAME) { + rval = -ERANGE; + goto exit; + } +@@ -1025,7 +1025,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev, + char radio_text[MAX_RDS_RADIO_TEXT + 1]; + + len = control->size - 1; +- if (len > MAX_RDS_RADIO_TEXT) { ++ if (len < 0 || len > MAX_RDS_RADIO_TEXT) { + rval = -ERANGE; + goto exit; + } +diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c +index d258ed7..f0e9c75 100644 +--- a/drivers/media/video/bt8xx/bttv-driver.c ++++ b/drivers/media/video/bt8xx/bttv-driver.c +@@ -3532,7 +3532,7 @@ static int radio_s_tuner(struct file *file, void *priv, + if (0 != t->index) + return -EINVAL; + +- bttv_call_all(btv, tuner, g_tuner, t); ++ bttv_call_all(btv, tuner, s_tuner, t); + return 0; + } + +diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c +index 13639b3..5891e30 100644 +--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c ++++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c +@@ -2979,6 +2979,8 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw) + if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) { + struct v4l2_tuner vt; + memset(&vt, 0, sizeof(vt)); ++ vt.type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ? ++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + vt.audmode = hdw->audiomode_val; + v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt); + } +@@ -5064,6 +5066,8 @@ void pvr2_hdw_status_poll(struct pvr2_hdw *hdw) + { + struct v4l2_tuner *vtp = &hdw->tuner_signal_info; + memset(vtp, 0, sizeof(*vtp)); ++ vtp->type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ? ++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + hdw->tuner_signal_stale = 0; + /* Note: There apparently is no replacement for VIDIOC_CROPCAP + using v4l2-subdev - therefore we can't support that AT ALL right +diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c +index 30cc334..265bfb5 100644 +--- a/drivers/media/video/v4l2-ioctl.c ++++ b/drivers/media/video/v4l2-ioctl.c +@@ -1600,6 +1600,8 @@ static long __video_do_ioctl(struct file *file, + if (!ops->vidioc_g_tuner) + break; + ++ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? ++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + ret = ops->vidioc_g_tuner(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, type=%d, " +@@ -1618,6 +1620,8 @@ static long __video_do_ioctl(struct file *file, + + if (!ops->vidioc_s_tuner) + break; ++ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? ++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + dbgarg(cmd, "index=%d, name=%s, type=%d, " + "capability=0x%x, rangelow=%d, " + "rangehigh=%d, signal=%d, afc=%d, " +@@ -1636,6 +1640,8 @@ static long __video_do_ioctl(struct file *file, + if (!ops->vidioc_g_frequency) + break; + ++ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? ++ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; + ret = ops->vidioc_g_frequency(file, fh, p); + if (!ret) + dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", +diff --git a/drivers/net/jme.c b/drivers/net/jme.c +index a893f45..0fbca76 100644 +--- a/drivers/net/jme.c ++++ b/drivers/net/jme.c +@@ -681,20 +681,28 @@ jme_make_new_rx_buf(struct jme_adapter *jme, int i) + struct jme_ring *rxring = &(jme->rxring[0]); + struct jme_buffer_info *rxbi = rxring->bufinf + i; + struct sk_buff *skb; ++ dma_addr_t mapping; + + skb = netdev_alloc_skb(jme->dev, + jme->dev->mtu + RX_EXTRA_LEN); + if (unlikely(!skb)) + return -ENOMEM; + ++ mapping = pci_map_page(jme->pdev, virt_to_page(skb->data), ++ offset_in_page(skb->data), skb_tailroom(skb), ++ PCI_DMA_FROMDEVICE); ++ if (unlikely(pci_dma_mapping_error(jme->pdev, mapping))) { ++ dev_kfree_skb(skb); ++ return -ENOMEM; ++ } ++ ++ if (likely(rxbi->mapping)) ++ pci_unmap_page(jme->pdev, rxbi->mapping, ++ rxbi->len, PCI_DMA_FROMDEVICE); ++ + rxbi->skb = skb; + rxbi->len = skb_tailroom(skb); +- rxbi->mapping = pci_map_page(jme->pdev, +- virt_to_page(skb->data), +- offset_in_page(skb->data), +- rxbi->len, +- PCI_DMA_FROMDEVICE); +- ++ rxbi->mapping = mapping; + return 0; + } + +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 0d3326d..6f8352c 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -1507,7 +1507,7 @@ void pci_enable_ari(struct pci_dev *dev) + { + int pos; + u32 cap; +- u16 ctrl; ++ u16 flags, ctrl; + struct pci_dev *bridge; + + if (!dev->is_pcie || dev->devfn) +@@ -1525,6 +1525,11 @@ void pci_enable_ari(struct pci_dev *dev) + if (!pos) + return; + ++ /* ARI is a PCIe v2 feature */ ++ pci_read_config_word(bridge, pos + PCI_EXP_FLAGS, &flags); ++ if ((flags & PCI_EXP_FLAGS_VERS) < 2) ++ return; ++ + pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap); + if (!(cap & PCI_EXP_DEVCAP2_ARI)) + return; +diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c +index 33cf988..4f43306 100644 +--- a/drivers/scsi/libsas/sas_expander.c ++++ b/drivers/scsi/libsas/sas_expander.c +@@ -840,6 +840,9 @@ static struct domain_device *sas_ex_discover_expander( + + res = sas_discover_expander(child); + if (res) { ++ spin_lock_irq(&parent->port->dev_list_lock); ++ list_del(&child->dev_list_node); ++ spin_unlock_irq(&parent->port->dev_list_lock); + kfree(child); + return NULL; + } +diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c +index 483370f..9ab8c86 100644 +--- a/drivers/scsi/pmcraid.c ++++ b/drivers/scsi/pmcraid.c +@@ -3557,6 +3557,9 @@ static long pmcraid_ioctl_passthrough( + pmcraid_err("couldn't build passthrough ioadls\n"); + goto out_free_buffer; + } ++ } else if (request_size < 0) { ++ rc = -EINVAL; ++ goto out_free_buffer; + } + + /* If data is being written into the device, copy the data from user +diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c +index 802e91c..ae0ae2d 100644 +--- a/drivers/scsi/scsi_devinfo.c ++++ b/drivers/scsi/scsi_devinfo.c +@@ -196,6 +196,7 @@ static struct { + {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, + {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, + {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, ++ {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN}, + {"IOMEGA", "Io20S *F", NULL, BLIST_KEY}, + {"INSITE", "Floptical F*8I", NULL, BLIST_KEY}, + {"INSITE", "I325VM", NULL, BLIST_KEY}, +@@ -242,6 +243,7 @@ static struct { + {"Tornado-", "F4", "*", BLIST_NOREPORTLUN}, + {"TOSHIBA", "CDROM", NULL, BLIST_ISROM}, + {"TOSHIBA", "CD-ROM", NULL, BLIST_ISROM}, ++ {"Traxdata", "CDR4120", NULL, BLIST_NOLUN}, /* locks up */ + {"USB2.0", "SMARTMEDIA/XD", NULL, BLIST_FORCELUN | BLIST_INQUIRY_36}, + {"WangDAT", "Model 2600", "01.7", BLIST_SELECT_NO_ATN}, + {"WangDAT", "Model 3200", "02.2", BLIST_SELECT_NO_ATN}, +diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c +index 3b082dd..340124d 100644 +--- a/drivers/scsi/ses.c ++++ b/drivers/scsi/ses.c +@@ -157,6 +157,10 @@ static unsigned char *ses_get_page2_descriptor(struct enclosure_device *edev, + return NULL; + } + ++/* For device slot and array device slot elements, byte 3 bit 6 ++ * is "fault sensed" while byte 3 bit 5 is "fault reqstd". As this ++ * code stands these bits are shifted 4 positions right so in ++ * sysfs they will appear as bits 2 and 1 respectively. Strange. */ + static void ses_get_fault(struct enclosure_device *edev, + struct enclosure_component *ecomp) + { +@@ -178,7 +182,7 @@ static int ses_set_fault(struct enclosure_device *edev, + /* zero is disabled */ + break; + case ENCLOSURE_SETTING_ENABLED: +- desc[2] = 0x02; ++ desc[3] = 0x20; + break; + default: + /* SES doesn't do the SGPIO blink settings */ +diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c +index aaad76e..80a1071 100644 +--- a/drivers/staging/comedi/comedi_fops.c ++++ b/drivers/staging/comedi/comedi_fops.c +@@ -367,8 +367,8 @@ static int do_devinfo_ioctl(struct comedi_device *dev, + /* fill devinfo structure */ + devinfo.version_code = COMEDI_VERSION_CODE; + devinfo.n_subdevs = dev->n_subdevices; +- memcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN); +- memcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN); ++ strlcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN); ++ strlcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN); + + if (read_subdev) + devinfo.read_subdevice = read_subdev - dev->subdevices; +diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c +index 5e09664..7adb671 100644 +--- a/drivers/usb/gadget/dummy_hcd.c ++++ b/drivers/usb/gadget/dummy_hcd.c +@@ -1886,6 +1886,7 @@ static int dummy_hcd_probe(struct platform_device *pdev) + if (!hcd) + return -ENOMEM; + the_controller = hcd_to_dummy (hcd); ++ hcd->has_tt = 1; + + retval = usb_add_hcd(hcd, 0, 0); + if (retval != 0) { +diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c +index 6ac3976..1bcf6ee 100644 +--- a/drivers/usb/host/ehci-hub.c ++++ b/drivers/usb/host/ehci-hub.c +@@ -758,10 +758,11 @@ static int ehci_hub_control ( + * power switching; they're allowed to just limit the + * current. khubd will turn the power back on. + */ +- if (HCS_PPC (ehci->hcs_params)){ ++ if ((temp & PORT_OC) && HCS_PPC(ehci->hcs_params)) { + ehci_writel(ehci, + temp & ~(PORT_RWC_BITS | PORT_POWER), + status_reg); ++ temp = ehci_readl(ehci, status_reg); + } + } + +diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c +index f51345f..0ee5b4b 100644 +--- a/drivers/usb/host/ehci-q.c ++++ b/drivers/usb/host/ehci-q.c +@@ -103,7 +103,7 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd) + if (!(hw->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) { + unsigned is_out, epnum; + +- is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8)); ++ is_out = qh->is_out; + epnum = (hc32_to_cpup(ehci, &hw->hw_info1) >> 8) & 0x0f; + if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) { + hw->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); +@@ -923,6 +923,7 @@ done: + hw = qh->hw; + hw->hw_info1 = cpu_to_hc32(ehci, info1); + hw->hw_info2 = cpu_to_hc32(ehci, info2); ++ qh->is_out = !is_input; + usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1); + qh_refresh (ehci, qh); + return qh; +diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h +index ac321ef..5b3ca74 100644 +--- a/drivers/usb/host/ehci.h ++++ b/drivers/usb/host/ehci.h +@@ -366,6 +366,7 @@ struct ehci_qh { + #define NO_FRAME ((unsigned short)~0) /* pick new start */ + + struct usb_device *dev; /* access to TT */ ++ unsigned is_out:1; /* bulk or intr OUT */ + unsigned clearing_tt:1; /* Clear-TT-Buf in progress */ + }; + +diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c +index 464ed97..bcf7a88 100644 +--- a/drivers/usb/host/pci-quirks.c ++++ b/drivers/usb/host/pci-quirks.c +@@ -34,6 +34,8 @@ + #define OHCI_INTRSTATUS 0x0c + #define OHCI_INTRENABLE 0x10 + #define OHCI_INTRDISABLE 0x14 ++#define OHCI_FMINTERVAL 0x34 ++#define OHCI_HCR (1 << 0) /* host controller reset */ + #define OHCI_OCR (1 << 3) /* ownership change request */ + #define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ + #define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ +@@ -204,6 +206,32 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) + + /* reset controller, preserving RWC (and possibly IR) */ + writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); ++ readl(base + OHCI_CONTROL); ++ ++ /* Some NVIDIA controllers stop working if kept in RESET for too long */ ++ if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) { ++ u32 fminterval; ++ int cnt; ++ ++ /* drive reset for at least 50 ms (7.1.7.5) */ ++ msleep(50); ++ ++ /* software reset of the controller, preserving HcFmInterval */ ++ fminterval = readl(base + OHCI_FMINTERVAL); ++ writel(OHCI_HCR, base + OHCI_CMDSTATUS); ++ ++ /* reset requires max 10 us delay */ ++ for (cnt = 30; cnt > 0; --cnt) { /* ... allow extra time */ ++ if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0) ++ break; ++ udelay(1); ++ } ++ writel(fminterval, base + OHCI_FMINTERVAL); ++ ++ /* Now we're in the SUSPEND state with all devices reset ++ * and wakeups and interrupts disabled ++ */ ++ } + + /* + * disable interrupts +diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c +index 24212be..b9afd6a 100644 +--- a/drivers/usb/musb/musb_core.c ++++ b/drivers/usb/musb/musb_core.c +@@ -1634,6 +1634,7 @@ void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit) + } + } + } ++ musb_writeb(musb_base, MUSB_INDEX, musb->context.index); + } + + #else +diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c +index b336017..4a18fd2 100644 +--- a/drivers/usb/serial/pl2303.c ++++ b/drivers/usb/serial/pl2303.c +@@ -100,6 +100,8 @@ static struct usb_device_id id_table [] = { + { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) }, + { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, + { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, ++ { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, ++ { USB_DEVICE(WINCHIPHEAD_VENDOR_ID, WINCHIPHEAD_USBSER_PRODUCT_ID) }, + { } /* Terminating entry */ + }; + +diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h +index 4d043e4..ca0d237 100644 +--- a/drivers/usb/serial/pl2303.h ++++ b/drivers/usb/serial/pl2303.h +@@ -5,7 +5,7 @@ + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. +- * ++ * + */ + + #define BENQ_VENDOR_ID 0x04a5 +@@ -140,3 +140,11 @@ + /* Sanwa KB-USB2 multimeter cable (ID: 11ad:0001) */ + #define SANWA_VENDOR_ID 0x11ad + #define SANWA_PRODUCT_ID 0x0001 ++ ++/* ADLINK ND-6530 RS232,RS485 and RS422 adapter */ ++#define ADLINK_VENDOR_ID 0x0b63 ++#define ADLINK_ND6530_PRODUCT_ID 0x6530 ++ ++/* WinChipHead USB->RS 232 adapter */ ++#define WINCHIPHEAD_VENDOR_ID 0x4348 ++#define WINCHIPHEAD_USBSER_PRODUCT_ID 0x5523 +diff --git a/fs/block_dev.c b/fs/block_dev.c +index 16cea86..e65efa2 100644 +--- a/fs/block_dev.c ++++ b/fs/block_dev.c +@@ -1203,7 +1203,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) + if (!bdev->bd_part) + goto out_clear; + +- ret = 0; + if (disk->fops->open) { + ret = disk->fops->open(bdev, mode); + if (ret == -ERESTARTSYS) { +@@ -1219,18 +1218,9 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) + mutex_unlock(&bdev->bd_mutex); + goto restart; + } ++ if (ret) ++ goto out_clear; + } +- /* +- * If the device is invalidated, rescan partition +- * if open succeeded or failed with -ENOMEDIUM. +- * The latter is necessary to prevent ghost +- * partitions on a removed medium. +- */ +- if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM)) +- rescan_partitions(disk, bdev); +- if (ret) +- goto out_clear; +- + if (!bdev->bd_openers) { + bd_set_size(bdev,(loff_t)get_capacity(disk)<<9); + bdi = blk_get_backing_dev_info(bdev); +@@ -1238,6 +1228,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) + bdi = &default_backing_dev_info; + bdev->bd_inode->i_data.backing_dev_info = bdi; + } ++ if (bdev->bd_invalidated) ++ rescan_partitions(disk, bdev); + } else { + struct block_device *whole; + whole = bdget_disk(disk, 0); +@@ -1264,14 +1256,13 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) + put_disk(disk); + disk = NULL; + if (bdev->bd_contains == bdev) { +- ret = 0; +- if (bdev->bd_disk->fops->open) ++ if (bdev->bd_disk->fops->open) { + ret = bdev->bd_disk->fops->open(bdev, mode); +- /* the same as first opener case, read comment there */ +- if (bdev->bd_invalidated && (!ret || ret == -ENOMEDIUM)) ++ if (ret) ++ goto out_unlock_bdev; ++ } ++ if (bdev->bd_invalidated) + rescan_partitions(bdev->bd_disk, bdev); +- if (ret) +- goto out_unlock_bdev; + } + } + bdev->bd_openers++; +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index c4dbc63..e29581e 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -33,7 +33,7 @@ + #define MAX_SHARE_SIZE 64 /* used to be 20, this should still be enough */ + #define MAX_USERNAME_SIZE 32 /* 32 is to allow for 15 char names + null + termination then *2 for unicode versions */ +-#define MAX_PASSWORD_SIZE 16 ++#define MAX_PASSWORD_SIZE 512 /* max for windows seems to be 256 wide chars */ + + #define CIFS_MIN_RCV_POOL 4 + +diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c +index 6234417..b6bb82e 100644 +--- a/fs/cifs/connect.c ++++ b/fs/cifs/connect.c +@@ -1588,17 +1588,29 @@ out_err: + } + + static struct cifsSesInfo * +-cifs_find_smb_ses(struct TCP_Server_Info *server, char *username) ++cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) + { +- struct list_head *tmp; + struct cifsSesInfo *ses; + + write_lock(&cifs_tcp_ses_lock); +- list_for_each(tmp, &server->smb_ses_list) { +- ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); +- if (strncmp(ses->userName, username, MAX_USERNAME_SIZE)) +- continue; +- ++ list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { ++ switch (server->secType) { ++ case Kerberos: ++ if (vol->linux_uid != ses->linux_uid) ++ continue; ++ break; ++ default: ++ /* anything else takes username/password */ ++ if (strncmp(ses->userName, vol->username, ++ MAX_USERNAME_SIZE)) ++ continue; ++ if (strlen(vol->username) != 0 && ++ ses->password != NULL && ++ strncmp(ses->password, ++ vol->password ? vol->password : "", ++ MAX_PASSWORD_SIZE)) ++ continue; ++ } + ++ses->ses_count; + write_unlock(&cifs_tcp_ses_lock); + return ses; +@@ -2362,7 +2374,7 @@ try_mount_again: + goto out; + } + +- pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username); ++ pSesInfo = cifs_find_smb_ses(srvTcp, volume_info); + if (pSesInfo) { + cFYI(1, ("Existing smb sess found (status=%d)", + pSesInfo->status)); +diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c +index 387d92d..d7add4c 100644 +--- a/fs/ext3/xattr.c ++++ b/fs/ext3/xattr.c +@@ -800,8 +800,16 @@ inserted: + /* We need to allocate a new block */ + ext3_fsblk_t goal = ext3_group_first_block_no(sb, + EXT3_I(inode)->i_block_group); +- ext3_fsblk_t block = ext3_new_block(handle, inode, +- goal, &error); ++ ext3_fsblk_t block; ++ ++ /* ++ * Protect us agaist concurrent allocations to the ++ * same inode from ext3_..._writepage(). Reservation ++ * code does not expect racing allocations. ++ */ ++ mutex_lock(&EXT3_I(inode)->truncate_mutex); ++ block = ext3_new_block(handle, inode, goal, &error); ++ mutex_unlock(&EXT3_I(inode)->truncate_mutex); + if (error) + goto cleanup; + ea_idebug(inode, "creating block %d", block); +diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c +index e81b2bf..7ee8ebc 100644 +--- a/fs/nfs/nfs4xdr.c ++++ b/fs/nfs/nfs4xdr.c +@@ -88,7 +88,7 @@ static int nfs4_stat_to_errno(int); + #define encode_getfh_maxsz (op_encode_hdr_maxsz) + #define decode_getfh_maxsz (op_decode_hdr_maxsz + 1 + \ + ((3+NFS4_FHSIZE) >> 2)) +-#define nfs4_fattr_bitmap_maxsz 3 ++#define nfs4_fattr_bitmap_maxsz 4 + #define encode_getattr_maxsz (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz) + #define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2)) + #define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2)) +diff --git a/fs/proc/base.c b/fs/proc/base.c +index 3d09a10..7b5819c 100644 +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -2454,6 +2454,9 @@ static int do_io_accounting(struct task_struct *task, char *buffer, int whole) + struct task_io_accounting acct = task->ioac; + unsigned long flags; + ++ if (!ptrace_may_access(task, PTRACE_MODE_READ)) ++ return -EACCES; ++ + if (whole && lock_task_sighand(task, &flags)) { + struct task_struct *t = task; + +@@ -2575,7 +2578,7 @@ static const struct pid_entry tgid_base_stuff[] = { + REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations), + #endif + #ifdef CONFIG_TASK_IO_ACCOUNTING +- INF("io", S_IRUGO, proc_tgid_io_accounting), ++ INF("io", S_IRUSR, proc_tgid_io_accounting), + #endif + }; + +@@ -2910,7 +2913,7 @@ static const struct pid_entry tid_base_stuff[] = { + REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations), + #endif + #ifdef CONFIG_TASK_IO_ACCOUNTING +- INF("io", S_IRUGO, proc_tid_io_accounting), ++ INF("io", S_IRUSR, proc_tid_io_accounting), + #endif + }; + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index c27a182..9d7e8f7 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1164,9 +1164,12 @@ static inline int skb_gro_header_hard(struct sk_buff *skb, unsigned int hlen) + static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen, + unsigned int offset) + { ++ if (!pskb_may_pull(skb, hlen)) ++ return NULL; ++ + NAPI_GRO_CB(skb)->frag0 = NULL; + NAPI_GRO_CB(skb)->frag0_len = 0; +- return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL; ++ return skb->data + offset; + } + + static inline void *skb_gro_mac_header(struct sk_buff *skb) +diff --git a/kernel/perf_event.c b/kernel/perf_event.c +index fc5ab8e..37ebc14 100644 +--- a/kernel/perf_event.c ++++ b/kernel/perf_event.c +@@ -3694,12 +3694,8 @@ static int __perf_event_overflow(struct perf_event *event, int nmi, + if (events && atomic_dec_and_test(&event->event_limit)) { + ret = 1; + event->pending_kill = POLL_HUP; +- if (nmi) { +- event->pending_disable = 1; +- perf_pending_queue(&event->pending, +- perf_pending_event); +- } else +- perf_event_disable(event); ++ event->pending_disable = 1; ++ perf_pending_queue(&event->pending, perf_pending_event); + } + + perf_event_output(event, nmi, data, regs); +diff --git a/net/atm/br2684.c b/net/atm/br2684.c +index 26a646d..c9230c3 100644 +--- a/net/atm/br2684.c ++++ b/net/atm/br2684.c +@@ -554,6 +554,12 @@ static const struct net_device_ops br2684_netdev_ops = { + .ndo_validate_addr = eth_validate_addr, + }; + ++static const struct net_device_ops br2684_netdev_ops_routed = { ++ .ndo_start_xmit = br2684_start_xmit, ++ .ndo_set_mac_address = br2684_mac_addr, ++ .ndo_change_mtu = eth_change_mtu ++}; ++ + static void br2684_setup(struct net_device *netdev) + { + struct br2684_dev *brdev = BRPRIV(netdev); +@@ -569,11 +575,10 @@ static void br2684_setup(struct net_device *netdev) + static void br2684_setup_routed(struct net_device *netdev) + { + struct br2684_dev *brdev = BRPRIV(netdev); +- brdev->net_dev = netdev; + ++ brdev->net_dev = netdev; + netdev->hard_header_len = 0; +- +- netdev->netdev_ops = &br2684_netdev_ops; ++ netdev->netdev_ops = &br2684_netdev_ops_routed; + netdev->addr_len = 0; + netdev->mtu = 1500; + netdev->type = ARPHRD_PPP; +diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h +index 2114e45..8567d47 100644 +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -75,6 +75,7 @@ struct net_bridge_port + bridge_id designated_bridge; + u32 path_cost; + u32 designated_cost; ++ unsigned long designated_age; + + struct timer_list forward_delay_timer; + struct timer_list hold_timer; +diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c +index fd3f8d6..c7d6bfc 100644 +--- a/net/bridge/br_stp.c ++++ b/net/bridge/br_stp.c +@@ -165,8 +165,7 @@ void br_transmit_config(struct net_bridge_port *p) + else { + struct net_bridge_port *root + = br_get_port(br, br->root_port); +- bpdu.message_age = br->max_age +- - (root->message_age_timer.expires - jiffies) ++ bpdu.message_age = (jiffies - root->designated_age) + + MESSAGE_AGE_INCR; + } + bpdu.max_age = br->max_age; +@@ -190,6 +189,7 @@ static inline void br_record_config_information(struct net_bridge_port *p, + p->designated_cost = bpdu->root_path_cost; + p->designated_bridge = bpdu->bridge_id; + p->designated_port = bpdu->port_id; ++ p->designated_age = jiffies + bpdu->message_age; + + mod_timer(&p->message_age_timer, jiffies + + (p->br->max_age - bpdu->message_age)); +diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c +index cfab9e4..f614584 100644 +--- a/net/ipv4/ip_gre.c ++++ b/net/ipv4/ip_gre.c +@@ -1665,14 +1665,15 @@ static int __init ipgre_init(void) + + printk(KERN_INFO "GRE over IPv4 tunneling driver\n"); + +- if (inet_add_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) { +- printk(KERN_INFO "ipgre init: can't add protocol\n"); +- return -EAGAIN; +- } +- + err = register_pernet_gen_device(&ipgre_net_id, &ipgre_net_ops); + if (err < 0) +- goto gen_device_failed; ++ return err; ++ ++ err = inet_add_protocol(&ipgre_protocol, IPPROTO_GRE); ++ if (err < 0) { ++ printk(KERN_INFO "ipgre init: can't add protocol\n"); ++ goto add_proto_failed; ++ } + + err = rtnl_link_register(&ipgre_link_ops); + if (err < 0) +@@ -1688,9 +1689,9 @@ out: + tap_ops_failed: + rtnl_link_unregister(&ipgre_link_ops); + rtnl_link_failed: +- unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops); +-gen_device_failed: + inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); ++add_proto_failed: ++ unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops); + goto out; + } + +@@ -1698,9 +1699,9 @@ static void __exit ipgre_fini(void) + { + rtnl_link_unregister(&ipgre_tap_ops); + rtnl_link_unregister(&ipgre_link_ops); +- unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops); + if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) + printk(KERN_INFO "ipgre close: can't remove protocol\n"); ++ unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops); + } + + module_init(ipgre_init); +diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c +index f37df1a..860b5c5 100644 +--- a/net/ipv4/ipip.c ++++ b/net/ipv4/ipip.c +@@ -830,15 +830,14 @@ static int __init ipip_init(void) + + printk(banner); + +- if (xfrm4_tunnel_register(&ipip_handler, AF_INET)) { ++ err = register_pernet_gen_device(&ipip_net_id, &ipip_net_ops); ++ if (err < 0) ++ return err; ++ err = xfrm4_tunnel_register(&ipip_handler, AF_INET); ++ if (err < 0) { ++ unregister_pernet_device(&ipip_net_ops); + printk(KERN_INFO "ipip init: can't register tunnel\n"); +- return -EAGAIN; + } +- +- err = register_pernet_gen_device(&ipip_net_id, &ipip_net_ops); +- if (err) +- xfrm4_tunnel_deregister(&ipip_handler, AF_INET); +- + return err; + } + +diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c +index 9a95c82..7fb3e02 100644 +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -1466,27 +1466,29 @@ static int __init ip6_tunnel_init(void) + { + int err; + +- if (xfrm6_tunnel_register(&ip4ip6_handler, AF_INET)) { ++ err = register_pernet_device(&ip6_tnl_net_ops); ++ if (err < 0) ++ goto out_pernet; ++ ++ err = xfrm6_tunnel_register(&ip4ip6_handler, AF_INET); ++ if (err < 0) { + printk(KERN_ERR "ip6_tunnel init: can't register ip4ip6\n"); +- err = -EAGAIN; +- goto out; ++ goto out_ip4ip6; + } + +- if (xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6)) { ++ err = xfrm6_tunnel_register(&ip6ip6_handler, AF_INET6); ++ if (err < 0) { + printk(KERN_ERR "ip6_tunnel init: can't register ip6ip6\n"); +- err = -EAGAIN; +- goto unreg_ip4ip6; ++ goto out_ip6ip6; + } + +- err = register_pernet_gen_device(&ip6_tnl_net_id, &ip6_tnl_net_ops); +- if (err < 0) +- goto err_pernet; + return 0; +-err_pernet: +- xfrm6_tunnel_deregister(&ip6ip6_handler, AF_INET6); +-unreg_ip4ip6: ++ ++out_ip6ip6: + xfrm6_tunnel_deregister(&ip4ip6_handler, AF_INET); +-out: ++out_ip4ip6: ++ unregister_pernet_device(&ip6_tnl_net_ops); ++out_pernet: + return err; + } + +diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c +index de2ffef..b128c07 100644 +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -1086,15 +1086,14 @@ static int __init sit_init(void) + + printk(KERN_INFO "IPv6 over IPv4 tunneling driver\n"); + +- if (xfrm4_tunnel_register(&sit_handler, AF_INET6) < 0) { +- printk(KERN_INFO "sit init: Can't add protocol\n"); +- return -EAGAIN; +- } +- + err = register_pernet_gen_device(&sit_net_id, &sit_net_ops); + if (err < 0) +- xfrm4_tunnel_deregister(&sit_handler, AF_INET6); +- ++ return err; ++ err = xfrm4_tunnel_register(&sit_handler, AF_INET6); ++ if (err < 0) { ++ unregister_pernet_device(&sit_net_ops); ++ printk(KERN_INFO "sit init: Can't add protocol\n"); ++ } + return err; + } + +diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c +index 81a95c0..48bb1e3 100644 +--- a/net/ipv6/xfrm6_tunnel.c ++++ b/net/ipv6/xfrm6_tunnel.c +@@ -344,32 +344,38 @@ static struct xfrm6_tunnel xfrm46_tunnel_handler = { + + static int __init xfrm6_tunnel_init(void) + { +- if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) ++ int rv; ++ ++ rv = xfrm6_tunnel_spi_init(); ++ if (rv < 0) + goto err; +- if (xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6)) +- goto unreg; +- if (xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET)) +- goto dereg6; +- if (xfrm6_tunnel_spi_init() < 0) +- goto dereg46; ++ rv = xfrm_register_type(&xfrm6_tunnel_type, AF_INET6); ++ if (rv < 0) ++ goto out_type; ++ rv = xfrm6_tunnel_register(&xfrm6_tunnel_handler, AF_INET6); ++ if (rv < 0) ++ goto out_xfrm6; ++ rv = xfrm6_tunnel_register(&xfrm46_tunnel_handler, AF_INET); ++ if (rv < 0) ++ goto out_xfrm46; + return 0; + +-dereg46: +- xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET); +-dereg6: ++out_xfrm46: + xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); +-unreg: ++out_xfrm6: + xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); ++out_type: ++ xfrm6_tunnel_spi_fini(); + err: +- return -EAGAIN; ++ return rv; + } + + static void __exit xfrm6_tunnel_fini(void) + { +- xfrm6_tunnel_spi_fini(); + xfrm6_tunnel_deregister(&xfrm46_tunnel_handler, AF_INET); + xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); + xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); ++ xfrm6_tunnel_spi_fini(); + } + + module_init(xfrm6_tunnel_init); +diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c +index 5bea319..e67eea7 100644 +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -2308,6 +2308,9 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) + { + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + ++ if (!ifmgd->associated) ++ return; ++ + if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running)) + add_timer(&ifmgd->timer); + if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running)) +diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c +index 830faf4..4418bb4 100644 +--- a/net/sunrpc/rpcb_clnt.c ++++ b/net/sunrpc/rpcb_clnt.c +@@ -533,7 +533,7 @@ void rpcb_getport_async(struct rpc_task *task) + u32 bind_version; + struct rpc_xprt *xprt; + struct rpc_clnt *rpcb_clnt; +- static struct rpcbind_args *map; ++ struct rpcbind_args *map; + struct rpc_task *child; + struct sockaddr_storage addr; + struct sockaddr *sap = (struct sockaddr *)&addr; +diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c +index 9191b2f..570da30 100644 +--- a/net/sunrpc/sched.c ++++ b/net/sunrpc/sched.c +@@ -613,30 +613,25 @@ static void __rpc_execute(struct rpc_task *task) + BUG_ON(RPC_IS_QUEUED(task)); + + for (;;) { ++ void (*do_action)(struct rpc_task *); + + /* +- * Execute any pending callback. ++ * Execute any pending callback first. + */ +- if (task->tk_callback) { +- void (*save_callback)(struct rpc_task *); +- +- /* +- * We set tk_callback to NULL before calling it, +- * in case it sets the tk_callback field itself: +- */ +- save_callback = task->tk_callback; +- task->tk_callback = NULL; +- save_callback(task); +- } else { ++ do_action = task->tk_callback; ++ task->tk_callback = NULL; ++ if (do_action == NULL) { + /* + * Perform the next FSM step. +- * tk_action may be NULL when the task has been killed +- * by someone else. ++ * tk_action may be NULL if the task has been killed. ++ * In particular, note that rpc_killall_tasks may ++ * do this at any time, so beware when dereferencing. + */ +- if (task->tk_action == NULL) ++ do_action = task->tk_action; ++ if (do_action == NULL) + break; +- task->tk_action(task); + } ++ do_action(task); + + /* + * Lockless check for whether task is sleeping or not. +diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c +index df760ad..cc1fb36 100644 +--- a/net/sunrpc/svc_xprt.c ++++ b/net/sunrpc/svc_xprt.c +@@ -896,12 +896,13 @@ void svc_delete_xprt(struct svc_xprt *xprt) + if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags)) + list_del_init(&xprt->xpt_list); + /* +- * We used to delete the transport from whichever list +- * it's sk_xprt.xpt_ready node was on, but we don't actually +- * need to. This is because the only time we're called +- * while still attached to a queue, the queue itself +- * is about to be destroyed (in svc_destroy). ++ * The only time we're called while xpt_ready is still on a list ++ * is while the list itself is about to be destroyed (in ++ * svc_destroy). BUT svc_xprt_enqueue could still be attempting ++ * to add new entries to the sp_sockets list, so we can't leave ++ * a freed xprt on it. + */ ++ list_del_init(&xprt->xpt_ready); + if (test_bit(XPT_TEMP, &xprt->xpt_flags)) + serv->sv_tmpcnt--; + +diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c +index 08bfed5..038232d 100644 +--- a/sound/core/pcm_compat.c ++++ b/sound/core/pcm_compat.c +@@ -341,7 +341,7 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream, + kfree(bufs); + return -EFAULT; + } +- bufs[ch] = compat_ptr(ptr); ++ bufs[i] = compat_ptr(ptr); + bufptr++; + } + if (dir == SNDRV_PCM_STREAM_PLAYBACK) +diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c +index 62fbb84..77dae16 100644 +--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c ++++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c +@@ -139,11 +139,20 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream) + pr_debug("%s enter\n", __func__); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + diff = sport_curr_offset_tx(sport); +- frames = bytes_to_frames(substream->runtime, diff); + } else { + diff = sport_curr_offset_rx(sport); +- frames = bytes_to_frames(substream->runtime, diff); + } ++ ++ /* ++ * TX at least can report one frame beyond the end of the ++ * buffer if we hit the wraparound case - clamp to within the ++ * buffer as the ALSA APIs require. ++ */ ++ if (diff == snd_pcm_lib_buffer_bytes(substream)) ++ diff = 0; ++ ++ frames = bytes_to_frames(substream->runtime, diff); ++ + return frames; + } + |