diff --git a/debian/changelog b/debian/changelog index e300cb202..75ff6b4bd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,38 @@ linux-2.6 (2.6.38-4) UNRELEASED; urgency=low * usb-audio: Define another USB ID for a buggy USB MIDI cable (Closes: #617743) * net: Enable BATMAN_ADV as module (Closes: #622361) + * Add stable 2.6.38.3, including: + - eCryptfs: Unlock page in write_begin error path + - irda: validate peer name and attribute lengths (CVE-2011-1180) + - irda: prevent heap corruption on invalid nickname + - nilfs2: fix data loss in mmap page write for hole blocks + - ALSA: pcm: fix infinite loop in snd_pcm_update_hw_ptr0() + - inotify: fix double free/corruption of stuct user + - perf: Fix task_struct reference leak + - ROSE: prevent heap corruption with bad facilities + - [x86] mtrr, pat: Fix one cpu getting out of sync during resume + - Input: synaptics - fix crash in synaptics_module_init() + - ath9k: fix a chip wakeup related crash in ath9k_start + - mac80211: fix a crash in minstrel_ht in HT mode with no supported MCS + rates + - UBIFS: fix oops on error path in read_pnode + - quota: Don't write quota info in dquot_commit() + - mm: avoid wrapping vm_pgoff in mremap() + - wl12xx: fix potential buffer overflow in testmode nvs push + - Bluetooth: sco: fix information leak to userspace (CVE-2011-1078) + - bridge: netfilter: fix information leak (CVE-2011-1080) + - Bluetooth: bnep: fix buffer overflow (CVE-2011-1079) + - netfilter: ip_tables: fix infoleak to userspace (CVE-2011-1171) + - netfilter: arp_tables: fix infoleak to userspace (CVE-2011-1170) + - [x86] Revert "x86: Cleanup highmap after brk is concluded" + (Closes: #621072) + - Squashfs: handle corruption of directory structure + - ext4: fix a double free in ext4_register_li_request + - ext4: fix credits computing for indirect mapped files + - nfsd: fix auth_domain reference leak on nlm operations + - nfsd4: fix oops on lock failure + For the complete list of changes, see: + http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.38.3 -- Ben Hutchings Fri, 08 Apr 2011 00:59:57 +0100 diff --git a/debian/patches/bugfix/all/stable/2.6.38.3.patch b/debian/patches/bugfix/all/stable/2.6.38.3.patch new file mode 100644 index 000000000..2d56d6a9e --- /dev/null +++ b/debian/patches/bugfix/all/stable/2.6.38.3.patch @@ -0,0 +1,3887 @@ +diff --git a/Makefile b/Makefile +index 6c15525..e47e39e 100644 +diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c +index 09d31db..aa92696 100644 +--- a/arch/powerpc/kernel/time.c ++++ b/arch/powerpc/kernel/time.c +@@ -356,7 +356,7 @@ void account_system_vtime(struct task_struct *tsk) + } + get_paca()->user_time_scaled += user_scaled; + +- if (in_irq() || idle_task(smp_processor_id()) != tsk) { ++ if (in_interrupt() || idle_task(smp_processor_id()) != tsk) { + account_system_time(tsk, 0, delta, sys_scaled); + if (stolen) + account_steal_time(stolen); +diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S +index 8fe2a49..4292df7 100644 +--- a/arch/x86/crypto/aesni-intel_asm.S ++++ b/arch/x86/crypto/aesni-intel_asm.S +@@ -1612,6 +1612,7 @@ _zero_cipher_left_encrypt: + movdqa SHUF_MASK(%rip), %xmm10 + PSHUFB_XMM %xmm10, %xmm0 + ++ + ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # Encrypt(K, Yn) + sub $16, %r11 + add %r13, %r11 +@@ -1634,7 +1635,9 @@ _zero_cipher_left_encrypt: + # GHASH computation for the last <16 byte block + sub %r13, %r11 + add $16, %r11 +- PSHUFB_XMM %xmm10, %xmm1 ++ ++ movdqa SHUF_MASK(%rip), %xmm10 ++ PSHUFB_XMM %xmm10, %xmm0 + + # shuffle xmm0 back to output as ciphertext + +diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c +index e1e60c7..b375b2a 100644 +--- a/arch/x86/crypto/aesni-intel_glue.c ++++ b/arch/x86/crypto/aesni-intel_glue.c +@@ -828,9 +828,15 @@ static int rfc4106_init(struct crypto_tfm *tfm) + struct cryptd_aead *cryptd_tfm; + struct aesni_rfc4106_gcm_ctx *ctx = (struct aesni_rfc4106_gcm_ctx *) + PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN); ++ struct crypto_aead *cryptd_child; ++ struct aesni_rfc4106_gcm_ctx *child_ctx; + cryptd_tfm = cryptd_alloc_aead("__driver-gcm-aes-aesni", 0, 0); + if (IS_ERR(cryptd_tfm)) + return PTR_ERR(cryptd_tfm); ++ ++ cryptd_child = cryptd_aead_child(cryptd_tfm); ++ child_ctx = aesni_rfc4106_gcm_ctx_get(cryptd_child); ++ memcpy(child_ctx, ctx, sizeof(*ctx)); + ctx->cryptd_tfm = cryptd_tfm; + tfm->crt_aead.reqsize = sizeof(struct aead_request) + + crypto_aead_reqsize(&cryptd_tfm->base); +@@ -925,6 +931,9 @@ static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key, + int ret = 0; + struct crypto_tfm *tfm = crypto_aead_tfm(parent); + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent); ++ struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); ++ struct aesni_rfc4106_gcm_ctx *child_ctx = ++ aesni_rfc4106_gcm_ctx_get(cryptd_child); + u8 *new_key_mem = NULL; + + if (key_len < 4) { +@@ -968,6 +977,7 @@ static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key, + goto exit; + } + ret = rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len); ++ memcpy(child_ctx, ctx, sizeof(*ctx)); + exit: + kfree(new_key_mem); + return ret; +@@ -999,7 +1009,6 @@ static int rfc4106_encrypt(struct aead_request *req) + int ret; + struct crypto_aead *tfm = crypto_aead_reqtfm(req); + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); +- struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); + + if (!irq_fpu_usable()) { + struct aead_request *cryptd_req = +@@ -1008,6 +1017,7 @@ static int rfc4106_encrypt(struct aead_request *req) + aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); + return crypto_aead_encrypt(cryptd_req); + } else { ++ struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); + kernel_fpu_begin(); + ret = cryptd_child->base.crt_aead.encrypt(req); + kernel_fpu_end(); +@@ -1020,7 +1030,6 @@ static int rfc4106_decrypt(struct aead_request *req) + int ret; + struct crypto_aead *tfm = crypto_aead_reqtfm(req); + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); +- struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); + + if (!irq_fpu_usable()) { + struct aead_request *cryptd_req = +@@ -1029,6 +1038,7 @@ static int rfc4106_decrypt(struct aead_request *req) + aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); + return crypto_aead_decrypt(cryptd_req); + } else { ++ struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); + kernel_fpu_begin(); + ret = cryptd_child->base.crt_aead.decrypt(req); + kernel_fpu_end(); +diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c +index bebabec..151787e 100644 +--- a/arch/x86/kernel/cpu/mtrr/main.c ++++ b/arch/x86/kernel/cpu/mtrr/main.c +@@ -292,14 +292,24 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ + + /* + * HACK! +- * We use this same function to initialize the mtrrs on boot. +- * The state of the boot cpu's mtrrs has been saved, and we want +- * to replicate across all the APs. +- * If we're doing that @reg is set to something special... ++ * ++ * We use this same function to initialize the mtrrs during boot, ++ * resume, runtime cpu online and on an explicit request to set a ++ * specific MTRR. ++ * ++ * During boot or suspend, the state of the boot cpu's mtrrs has been ++ * saved, and we want to replicate that across all the cpus that come ++ * online (either at the end of boot or resume or during a runtime cpu ++ * online). If we're doing that, @reg is set to something special and on ++ * this cpu we still do mtrr_if->set_all(). During boot/resume, this ++ * is unnecessary if at this point we are still on the cpu that started ++ * the boot/resume sequence. But there is no guarantee that we are still ++ * on the same cpu. So we do mtrr_if->set_all() on this cpu aswell to be ++ * sure that we are in sync with everyone else. + */ + if (reg != ~0U) + mtrr_if->set(reg, base, size, type); +- else if (!mtrr_aps_delayed_init) ++ else + mtrr_if->set_all(); + + /* Wait for the others */ +diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c +index 5655c22..2d2673c 100644 +--- a/arch/x86/kernel/head64.c ++++ b/arch/x86/kernel/head64.c +@@ -77,6 +77,9 @@ void __init x86_64_start_kernel(char * real_mode_data) + /* Make NULL pointers segfault */ + zap_identity_mappings(); + ++ /* Cleanup the over mapped high alias */ ++ cleanup_highmap(); ++ + max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT; + + for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) { +diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c +index e543fe9..d3cfe26 100644 +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -297,9 +297,6 @@ static void __init init_gbpages(void) + static inline void init_gbpages(void) + { + } +-static void __init cleanup_highmap(void) +-{ +-} + #endif + + static void __init reserve_brk(void) +@@ -925,8 +922,6 @@ void __init setup_arch(char **cmdline_p) + */ + reserve_brk(); + +- cleanup_highmap(); +- + memblock.current_limit = get_max_mapped(); + memblock_x86_fill(); + +diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c +index f13ff3a..947f42a 100644 +--- a/arch/x86/mm/init.c ++++ b/arch/x86/mm/init.c +@@ -279,6 +279,25 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, + load_cr3(swapper_pg_dir); + #endif + ++#ifdef CONFIG_X86_64 ++ if (!after_bootmem && !start) { ++ pud_t *pud; ++ pmd_t *pmd; ++ ++ mmu_cr4_features = read_cr4(); ++ ++ /* ++ * _brk_end cannot change anymore, but it and _end may be ++ * located on different 2M pages. cleanup_highmap(), however, ++ * can only consider _end when it runs, so destroy any ++ * mappings beyond _brk_end here. ++ */ ++ pud = pud_offset(pgd_offset_k(_brk_end), _brk_end); ++ pmd = pmd_offset(pud, _brk_end - 1); ++ while (++pmd <= pmd_offset(pud, (unsigned long)_end - 1)) ++ pmd_clear(pmd); ++ } ++#endif + __flush_tlb_all(); + + if (!after_bootmem && e820_table_end > e820_table_start) +diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c +index 68f9921..c14a542 100644 +--- a/arch/x86/mm/init_64.c ++++ b/arch/x86/mm/init_64.c +@@ -51,7 +51,6 @@ + #include + #include + #include +-#include + + static int __init parse_direct_gbpages_off(char *arg) + { +@@ -294,18 +293,18 @@ void __init init_extra_mapping_uc(unsigned long phys, unsigned long size) + * to the compile time generated pmds. This results in invalid pmds up + * to the point where we hit the physaddr 0 mapping. + * +- * We limit the mappings to the region from _text to _brk_end. _brk_end +- * is rounded up to the 2MB boundary. This catches the invalid pmds as ++ * We limit the mappings to the region from _text to _end. _end is ++ * rounded up to the 2MB boundary. This catches the invalid pmds as + * well, as they are located before _text: + */ + void __init cleanup_highmap(void) + { + unsigned long vaddr = __START_KERNEL_map; +- unsigned long vaddr_end = __START_KERNEL_map + (max_pfn_mapped << PAGE_SHIFT); +- unsigned long end = roundup((unsigned long)_brk_end, PMD_SIZE) - 1; ++ unsigned long end = roundup((unsigned long)_end, PMD_SIZE) - 1; + pmd_t *pmd = level2_kernel_pgt; ++ pmd_t *last_pmd = pmd + PTRS_PER_PMD; + +- for (; vaddr + PMD_SIZE - 1 < vaddr_end; pmd++, vaddr += PMD_SIZE) { ++ for (; pmd < last_pmd; pmd++, vaddr += PMD_SIZE) { + if (pmd_none(*pmd)) + continue; + if (vaddr < (unsigned long) _text || vaddr > end) +diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c +index 8524939..c7358dd 100644 +--- a/drivers/acpi/pci_root.c ++++ b/drivers/acpi/pci_root.c +@@ -564,7 +564,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) + /* Indicate support for various _OSC capabilities. */ + if (pci_ext_cfg_avail(root->bus->self)) + flags |= OSC_EXT_PCI_CONFIG_SUPPORT; +- if (pcie_aspm_enabled()) ++ if (pcie_aspm_support_enabled()) + flags |= OSC_ACTIVE_STATE_PWR_SUPPORT | + OSC_CLOCK_PWR_CAPABILITY_SUPPORT; + if (pci_msi_enabled()) +diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c +index 25ef1a4..b836e11 100644 +--- a/drivers/atm/solos-pci.c ++++ b/drivers/atm/solos-pci.c +@@ -165,7 +165,6 @@ static uint32_t fpga_tx(struct solos_card *); + static irqreturn_t solos_irq(int irq, void *dev_id); + static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci); + static int list_vccs(int vci); +-static void release_vccs(struct atm_dev *dev); + static int atm_init(struct solos_card *, struct device *); + static void atm_remove(struct solos_card *); + static int send_command(struct solos_card *card, int dev, const char *buf, size_t size); +@@ -384,7 +383,6 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb + /* Anything but 'Showtime' is down */ + if (strcmp(state_str, "Showtime")) { + atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_LOST); +- release_vccs(card->atmdev[port]); + dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str); + return 0; + } +@@ -697,7 +695,7 @@ void solos_bh(unsigned long card_arg) + size); + } + if (atmdebug) { +- dev_info(&card->dev->dev, "Received: device %d\n", port); ++ dev_info(&card->dev->dev, "Received: port %d\n", port); + dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n", + size, le16_to_cpu(header->vpi), + le16_to_cpu(header->vci)); +@@ -830,28 +828,6 @@ static int list_vccs(int vci) + return num_found; + } + +-static void release_vccs(struct atm_dev *dev) +-{ +- int i; +- +- write_lock_irq(&vcc_sklist_lock); +- for (i = 0; i < VCC_HTABLE_SIZE; i++) { +- struct hlist_head *head = &vcc_hash[i]; +- struct hlist_node *node, *tmp; +- struct sock *s; +- struct atm_vcc *vcc; +- +- sk_for_each_safe(s, node, tmp, head) { +- vcc = atm_sk(s); +- if (vcc->dev == dev) { +- vcc_release_async(vcc, -EPIPE); +- sk_del_node_init(s); +- } +- } +- } +- write_unlock_irq(&vcc_sklist_lock); +-} +- + + static int popen(struct atm_vcc *vcc) + { +@@ -1018,8 +994,15 @@ static uint32_t fpga_tx(struct solos_card *card) + + /* Clean up and free oldskb now it's gone */ + if (atmdebug) { ++ struct pkt_hdr *header = (void *)oldskb->data; ++ int size = le16_to_cpu(header->size); ++ ++ skb_pull(oldskb, sizeof(*header)); + dev_info(&card->dev->dev, "Transmitted: port %d\n", + port); ++ dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n", ++ size, le16_to_cpu(header->vpi), ++ le16_to_cpu(header->vci)); + print_buffer(oldskb); + } + +@@ -1262,7 +1245,7 @@ static int atm_init(struct solos_card *card, struct device *parent) + card->atmdev[i]->ci_range.vci_bits = 16; + card->atmdev[i]->dev_data = card; + card->atmdev[i]->phy_data = (void *)(unsigned long)i; +- atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_UNKNOWN); ++ atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_FOUND); + + skb = alloc_skb(sizeof(*header), GFP_ATOMIC); + if (!skb) { +diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h +index 579f749..554bbd9 100644 +--- a/drivers/block/cciss.h ++++ b/drivers/block/cciss.h +@@ -222,6 +222,7 @@ static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c) + h->ctlr, c->busaddr); + #endif /* CCISS_DEBUG */ + writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); ++ readl(h->vaddr + SA5_REQUEST_PORT_OFFSET); + h->commands_outstanding++; + if ( h->commands_outstanding > h->max_outstanding) + h->max_outstanding = h->commands_outstanding; +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 700a384..f44ca40 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -71,6 +71,9 @@ static struct usb_device_id btusb_table[] = { + /* Apple MacBookAir3,1, MacBookAir3,2 */ + { USB_DEVICE(0x05ac, 0x821b) }, + ++ /* Apple MacBookPro8,2 */ ++ { USB_DEVICE(0x05ac, 0x821a) }, ++ + /* AVM BlueFRITZ! USB v2.0 */ + { USB_DEVICE(0x057c, 0x3800) }, + +diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c +index 1f46f1c..7beb0e2 100644 +--- a/drivers/char/tpm/tpm.c ++++ b/drivers/char/tpm/tpm.c +@@ -980,7 +980,7 @@ int tpm_open(struct inode *inode, struct file *file) + return -EBUSY; + } + +- chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL); ++ chip->data_buffer = kzalloc(TPM_BUFSIZE, GFP_KERNEL); + if (chip->data_buffer == NULL) { + clear_bit(0, &chip->is_open); + put_device(chip->dev); +diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c +index 23e0355..7e0e660 100644 +--- a/drivers/edac/amd64_edac.c ++++ b/drivers/edac/amd64_edac.c +@@ -2765,7 +2765,7 @@ static int __init amd64_edac_init(void) + mcis = kzalloc(amd_nb_num() * sizeof(mcis[0]), GFP_KERNEL); + ecc_stngs = kzalloc(amd_nb_num() * sizeof(ecc_stngs[0]), GFP_KERNEL); + if (!(mcis && ecc_stngs)) +- goto err_ret; ++ goto err_free; + + msrs = msrs_alloc(); + if (!msrs) +diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c +index 02d5c41..99768d9 100644 +--- a/drivers/gpu/drm/radeon/radeon_atombios.c ++++ b/drivers/gpu/drm/radeon/radeon_atombios.c +@@ -675,7 +675,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) + ATOM_ENCODER_CAP_RECORD *cap_record; + u16 caps = 0; + +- while (record->ucRecordType > 0 && ++ while (record->ucRecordSize > 0 && ++ record->ucRecordType > 0 && + record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { + switch (record->ucRecordType) { + case ATOM_ENCODER_CAP_RECORD_TYPE: +@@ -720,7 +721,8 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) + break; + } + +- while (record->ucRecordType > 0 && ++ while (record->ucRecordSize > 0 && ++ record->ucRecordType > 0 && + record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { + switch (record->ucRecordType) { + case ATOM_I2C_RECORD_TYPE: +@@ -782,10 +784,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) + ATOM_HPD_INT_RECORD *hpd_record; + ATOM_I2C_ID_CONFIG_ACCESS *i2c_config; + +- while (record->ucRecordType > 0 +- && record-> +- ucRecordType <= +- ATOM_MAX_OBJECT_RECORD_NUMBER) { ++ while (record->ucRecordSize > 0 && ++ record->ucRecordType > 0 && ++ record->ucRecordType <= ATOM_MAX_OBJECT_RECORD_NUMBER) { + switch (record->ucRecordType) { + case ATOM_I2C_RECORD_TYPE: + i2c_record = +diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c +index 318cc40..418c399 100644 +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -418,6 +418,8 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h + input_set_abs_params(input, ABS_MT_POSITION_Y, -2456, + 2565, 4, 0); + } ++ ++ input_set_events_per_packet(input, 60); + } + + if (report_undeciphered) { +diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c +index aa186cf..e06e045 100644 +--- a/drivers/input/mouse/synaptics.c ++++ b/drivers/input/mouse/synaptics.c +@@ -836,8 +836,8 @@ static const struct dmi_system_id __initconst toshiba_dmi_table[] = { + }, + + }, +- { } + #endif ++ { } + }; + + static bool broken_olpc_ec; +@@ -851,8 +851,8 @@ static const struct dmi_system_id __initconst olpc_dmi_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "XO"), + }, + }, +- { } + #endif ++ { } + }; + + void __init synaptics_module_init(void) +diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c +index 80a3ae3..c0cff64 100644 +--- a/drivers/leds/leds-lp5521.c ++++ b/drivers/leds/leds-lp5521.c +@@ -534,7 +534,7 @@ static ssize_t lp5521_selftest(struct device *dev, + } + + /* led class device attributes */ +-static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current); ++static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, show_current, store_current); + static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL); + + static struct attribute *lp5521_led_attributes[] = { +@@ -548,15 +548,15 @@ static struct attribute_group lp5521_led_attribute_group = { + }; + + /* device attributes */ +-static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUGO, ++static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUSR, + show_engine1_mode, store_engine1_mode); +-static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUGO, ++static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUSR, + show_engine2_mode, store_engine2_mode); +-static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUGO, ++static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUSR, + show_engine3_mode, store_engine3_mode); +-static DEVICE_ATTR(engine1_load, S_IWUGO, NULL, store_engine1_load); +-static DEVICE_ATTR(engine2_load, S_IWUGO, NULL, store_engine2_load); +-static DEVICE_ATTR(engine3_load, S_IWUGO, NULL, store_engine3_load); ++static DEVICE_ATTR(engine1_load, S_IWUSR, NULL, store_engine1_load); ++static DEVICE_ATTR(engine2_load, S_IWUSR, NULL, store_engine2_load); ++static DEVICE_ATTR(engine3_load, S_IWUSR, NULL, store_engine3_load); + static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL); + + static struct attribute *lp5521_attributes[] = { +diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c +index d0c4068..e19fed2 100644 +--- a/drivers/leds/leds-lp5523.c ++++ b/drivers/leds/leds-lp5523.c +@@ -713,7 +713,7 @@ static ssize_t store_current(struct device *dev, + } + + /* led class device attributes */ +-static DEVICE_ATTR(led_current, S_IRUGO | S_IWUGO, show_current, store_current); ++static DEVICE_ATTR(led_current, S_IRUGO | S_IWUSR, show_current, store_current); + static DEVICE_ATTR(max_current, S_IRUGO , show_max_current, NULL); + + static struct attribute *lp5523_led_attributes[] = { +@@ -727,21 +727,21 @@ static struct attribute_group lp5523_led_attribute_group = { + }; + + /* device attributes */ +-static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUGO, ++static DEVICE_ATTR(engine1_mode, S_IRUGO | S_IWUSR, + show_engine1_mode, store_engine1_mode); +-static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUGO, ++static DEVICE_ATTR(engine2_mode, S_IRUGO | S_IWUSR, + show_engine2_mode, store_engine2_mode); +-static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUGO, ++static DEVICE_ATTR(engine3_mode, S_IRUGO | S_IWUSR, + show_engine3_mode, store_engine3_mode); +-static DEVICE_ATTR(engine1_leds, S_IRUGO | S_IWUGO, ++static DEVICE_ATTR(engine1_leds, S_IRUGO | S_IWUSR, + show_engine1_leds, store_engine1_leds); +-static DEVICE_ATTR(engine2_leds, S_IRUGO | S_IWUGO, ++static DEVICE_ATTR(engine2_leds, S_IRUGO | S_IWUSR, + show_engine2_leds, store_engine2_leds); +-static DEVICE_ATTR(engine3_leds, S_IRUGO | S_IWUGO, ++static DEVICE_ATTR(engine3_leds, S_IRUGO | S_IWUSR, + show_engine3_leds, store_engine3_leds); +-static DEVICE_ATTR(engine1_load, S_IWUGO, NULL, store_engine1_load); +-static DEVICE_ATTR(engine2_load, S_IWUGO, NULL, store_engine2_load); +-static DEVICE_ATTR(engine3_load, S_IWUGO, NULL, store_engine3_load); ++static DEVICE_ATTR(engine1_load, S_IWUSR, NULL, store_engine1_load); ++static DEVICE_ATTR(engine2_load, S_IWUSR, NULL, store_engine2_load); ++static DEVICE_ATTR(engine3_load, S_IWUSR, NULL, store_engine3_load); + static DEVICE_ATTR(selftest, S_IRUGO, lp5523_selftest, NULL); + + static struct attribute *lp5523_attributes[] = { +diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig +index ecdffa6..c090246 100644 +--- a/drivers/media/radio/Kconfig ++++ b/drivers/media/radio/Kconfig +@@ -441,6 +441,7 @@ config RADIO_TIMBERDALE + config RADIO_WL1273 + tristate "Texas Instruments WL1273 I2C FM Radio" + depends on I2C && VIDEO_V4L2 ++ select MFD_CORE + select MFD_WL1273_CORE + select FW_LOADER + ---help--- +diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c +index df33a1d..a794ae6 100644 +--- a/drivers/media/video/tlg2300/pd-video.c ++++ b/drivers/media/video/tlg2300/pd-video.c +@@ -764,10 +764,8 @@ static int pd_vidioc_s_fmt(struct poseidon *pd, struct v4l2_pix_format *pix) + } + ret |= send_set_req(pd, VIDEO_ROSOLU_SEL, + vid_resol, &cmd_status); +- if (ret || cmd_status) { +- mutex_unlock(&pd->lock); ++ if (ret || cmd_status) + return -EBUSY; +- } + + pix_def->pixelformat = pix->pixelformat; /* save it */ + pix->height = (context->tvnormid & V4L2_STD_525_60) ? 480 : 576; +diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c +index 4193af5..1707d22 100644 +--- a/drivers/mfd/ab3100-core.c ++++ b/drivers/mfd/ab3100-core.c +@@ -613,7 +613,7 @@ static void ab3100_setup_debugfs(struct ab3100 *ab3100) + ab3100_get_priv.ab3100 = ab3100; + ab3100_get_priv.mode = false; + ab3100_get_reg_file = debugfs_create_file("get_reg", +- S_IWUGO, ab3100_dir, &ab3100_get_priv, ++ S_IWUSR, ab3100_dir, &ab3100_get_priv, + &ab3100_get_set_reg_fops); + if (!ab3100_get_reg_file) { + err = -ENOMEM; +@@ -623,7 +623,7 @@ static void ab3100_setup_debugfs(struct ab3100 *ab3100) + ab3100_set_priv.ab3100 = ab3100; + ab3100_set_priv.mode = true; + ab3100_set_reg_file = debugfs_create_file("set_reg", +- S_IWUGO, ab3100_dir, &ab3100_set_priv, ++ S_IWUSR, ab3100_dir, &ab3100_set_priv, + &ab3100_get_set_reg_fops); + if (!ab3100_set_reg_file) { + err = -ENOMEM; +diff --git a/drivers/mfd/ab3550-core.c b/drivers/mfd/ab3550-core.c +index 5fbca34..681984d 100644 +--- a/drivers/mfd/ab3550-core.c ++++ b/drivers/mfd/ab3550-core.c +@@ -1053,17 +1053,17 @@ static inline void ab3550_setup_debugfs(struct ab3550 *ab) + goto exit_destroy_dir; + + ab3550_bank_file = debugfs_create_file("register-bank", +- (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_bank_fops); ++ (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_bank_fops); + if (!ab3550_bank_file) + goto exit_destroy_reg; + + ab3550_address_file = debugfs_create_file("register-address", +- (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_address_fops); ++ (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_address_fops); + if (!ab3550_address_file) + goto exit_destroy_bank; + + ab3550_val_file = debugfs_create_file("register-value", +- (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_val_fops); ++ (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_val_fops); + if (!ab3550_val_file) + goto exit_destroy_address; + +diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c +index 3c1541a..64748e4 100644 +--- a/drivers/mfd/ab8500-debugfs.c ++++ b/drivers/mfd/ab8500-debugfs.c +@@ -585,18 +585,18 @@ static int __devinit ab8500_debug_probe(struct platform_device *plf) + goto exit_destroy_dir; + + ab8500_bank_file = debugfs_create_file("register-bank", +- (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_bank_fops); ++ (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev, &ab8500_bank_fops); + if (!ab8500_bank_file) + goto exit_destroy_reg; + + ab8500_address_file = debugfs_create_file("register-address", +- (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, ++ (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev, + &ab8500_address_fops); + if (!ab8500_address_file) + goto exit_destroy_bank; + + ab8500_val_file = debugfs_create_file("register-value", +- (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_val_fops); ++ (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev, &ab8500_val_fops); + if (!ab8500_val_file) + goto exit_destroy_address; + +diff --git a/drivers/misc/ep93xx_pwm.c b/drivers/misc/ep93xx_pwm.c +index 46b3439..16d7179 100644 +--- a/drivers/misc/ep93xx_pwm.c ++++ b/drivers/misc/ep93xx_pwm.c +@@ -249,11 +249,11 @@ static ssize_t ep93xx_pwm_set_invert(struct device *dev, + + static DEVICE_ATTR(min_freq, S_IRUGO, ep93xx_pwm_get_min_freq, NULL); + static DEVICE_ATTR(max_freq, S_IRUGO, ep93xx_pwm_get_max_freq, NULL); +-static DEVICE_ATTR(freq, S_IWUGO | S_IRUGO, ++static DEVICE_ATTR(freq, S_IWUSR | S_IRUGO, + ep93xx_pwm_get_freq, ep93xx_pwm_set_freq); +-static DEVICE_ATTR(duty_percent, S_IWUGO | S_IRUGO, ++static DEVICE_ATTR(duty_percent, S_IWUSR | S_IRUGO, + ep93xx_pwm_get_duty_percent, ep93xx_pwm_set_duty_percent); +-static DEVICE_ATTR(invert, S_IWUGO | S_IRUGO, ++static DEVICE_ATTR(invert, S_IWUSR | S_IRUGO, + ep93xx_pwm_get_invert, ep93xx_pwm_set_invert); + + static struct attribute *ep93xx_pwm_attrs[] = { +diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c +index ea5cfe2..24386a8 100644 +--- a/drivers/net/myri10ge/myri10ge.c ++++ b/drivers/net/myri10ge/myri10ge.c +@@ -3645,6 +3645,7 @@ static void myri10ge_free_slices(struct myri10ge_priv *mgp) + dma_free_coherent(&pdev->dev, bytes, + ss->fw_stats, ss->fw_stats_bus); + ss->fw_stats = NULL; ++ netif_napi_del(&ss->napi); + } + } + kfree(mgp->ss); +diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c +index 587498e..3de98cb 100644 +--- a/drivers/net/netxen/netxen_nic_ethtool.c ++++ b/drivers/net/netxen/netxen_nic_ethtool.c +@@ -901,7 +901,7 @@ static int netxen_nic_set_flags(struct net_device *netdev, u32 data) + struct netxen_adapter *adapter = netdev_priv(netdev); + int hw_lro; + +- if (data & ~ETH_FLAG_LRO) ++ if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO)) + return -EINVAL; + + if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)) +diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c +index 4c14510..45b2755 100644 +--- a/drivers/net/qlcnic/qlcnic_ethtool.c ++++ b/drivers/net/qlcnic/qlcnic_ethtool.c +@@ -1003,7 +1003,7 @@ static int qlcnic_set_flags(struct net_device *netdev, u32 data) + struct qlcnic_adapter *adapter = netdev_priv(netdev); + int hw_lro; + +- if (data & ~ETH_FLAG_LRO) ++ if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO)) + return -EINVAL; + + if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)) +diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c +index 39c17ce..0cdff2b 100644 +--- a/drivers/net/s2io.c ++++ b/drivers/net/s2io.c +@@ -6726,7 +6726,7 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data) + int rc = 0; + int changed = 0; + +- if (data & ~ETH_FLAG_LRO) ++ if (ethtool_invalid_flags(dev, data, ETH_FLAG_LRO)) + return -EINVAL; + + if (data & ETH_FLAG_LRO) { +diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c +index 81254be..51f2ef1 100644 +--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c ++++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c +@@ -304,8 +304,8 @@ vmxnet3_set_flags(struct net_device *netdev, u32 data) + u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1; + unsigned long flags; + +- if (data & ~ETH_FLAG_LRO) +- return -EOPNOTSUPP; ++ if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO)) ++ return -EINVAL; + + if (lro_requested ^ lro_present) { + /* toggle the LRO feature*/ +diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c +index 1dd3a21..c5eb034 100644 +--- a/drivers/net/vxge/vxge-ethtool.c ++++ b/drivers/net/vxge/vxge-ethtool.c +@@ -1117,8 +1117,8 @@ static int vxge_set_flags(struct net_device *dev, u32 data) + struct vxgedev *vdev = netdev_priv(dev); + enum vxge_hw_status status; + +- if (data & ~ETH_FLAG_RXHASH) +- return -EOPNOTSUPP; ++ if (ethtool_invalid_flags(dev, data, ETH_FLAG_RXHASH)) ++ return -EINVAL; + + if (!!(data & ETH_FLAG_RXHASH) == vdev->devh->config.rth_en) + return 0; +diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c +index a09d15f..0848e09 100644 +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1063,6 +1063,8 @@ static int ath9k_start(struct ieee80211_hw *hw) + "Starting driver with initial channel: %d MHz\n", + curchan->center_freq); + ++ ath9k_ps_wakeup(sc); ++ + mutex_lock(&sc->mutex); + + if (ath9k_wiphy_started(sc)) { +@@ -1179,6 +1181,8 @@ static int ath9k_start(struct ieee80211_hw *hw) + mutex_unlock: + mutex_unlock(&sc->mutex); + ++ ath9k_ps_restore(sc); ++ + return r; + } + +diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c +index 07b7804..5c9d83b 100644 +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -1699,8 +1699,8 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, + u8 tidno; + + spin_lock_bh(&txctl->txq->axq_lock); +- +- if (ieee80211_is_data_qos(hdr->frame_control) && txctl->an) { ++ if ((sc->sc_flags & SC_OP_TXAGGR) && txctl->an && ++ ieee80211_is_data_qos(hdr->frame_control)) { + tidno = ieee80211_get_qos_ctl(hdr)[0] & + IEEE80211_QOS_CTL_TID_MASK; + tid = ATH_AN_2_TID(txctl->an, tidno); +diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c +index 3d5566e..ff0f5ba 100644 +--- a/drivers/net/wireless/b43/dma.c ++++ b/drivers/net/wireless/b43/dma.c +@@ -1536,7 +1536,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) + dmaaddr = meta->dmaaddr; + goto drop_recycle_buffer; + } +- if (unlikely(len > ring->rx_buffersize)) { ++ if (unlikely(len + ring->frameoffset > ring->rx_buffersize)) { + /* The data did not fit into one descriptor buffer + * and is split over multiple buffers. + * This should never happen, as we try to allocate buffers +diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h +index a01c210..e8a80a1 100644 +--- a/drivers/net/wireless/b43/dma.h ++++ b/drivers/net/wireless/b43/dma.h +@@ -163,7 +163,7 @@ struct b43_dmadesc_generic { + /* DMA engine tuning knobs */ + #define B43_TXRING_SLOTS 256 + #define B43_RXRING_SLOTS 64 +-#define B43_DMA0_RX_BUFFERSIZE IEEE80211_MAX_FRAME_LEN ++#define B43_DMA0_RX_BUFFERSIZE (B43_DMA0_RX_FRAMEOFFSET + IEEE80211_MAX_FRAME_LEN) + + /* Pointer poison */ + #define B43_DMA_PTR_POISON ((void *)ERR_PTR(-ENOMEM)) +diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h +index 9e6f313..c0cd307 100644 +--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h ++++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h +@@ -241,7 +241,7 @@ struct iwl_eeprom_enhanced_txpwr { + + /* 6x00 Specific */ + #define EEPROM_6000_TX_POWER_VERSION (4) +-#define EEPROM_6000_EEPROM_VERSION (0x434) ++#define EEPROM_6000_EEPROM_VERSION (0x423) + + /* 6x50 Specific */ + #define EEPROM_6050_TX_POWER_VERSION (4) +diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c +index 9b344a9..e183587 100644 +--- a/drivers/net/wireless/p54/p54usb.c ++++ b/drivers/net/wireless/p54/p54usb.c +@@ -56,6 +56,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { + {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */ + {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ + {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ ++ {USB_DEVICE(0x0bf8, 0x1007)}, /* Fujitsu E-5400 USB */ + {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */ + {USB_DEVICE(0x0db0, 0x6826)}, /* MSI UB54G (MS-6826) */ + {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */ +@@ -68,6 +69,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { + {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */ + {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */ + {USB_DEVICE(0x2001, 0x3703)}, /* DLink DWL-G122 */ ++ {USB_DEVICE(0x2001, 0x3762)}, /* Conceptronic C54U */ + {USB_DEVICE(0x5041, 0x2234)}, /* Linksys WUSB54G */ + {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */ + +diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c +index 54917a2..e2a528d 100644 +--- a/drivers/net/wireless/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/rt2x00/rt2800lib.c +@@ -2810,10 +2810,7 @@ void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev) + + rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); +- rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); +- rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); +- rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); + rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); + + /* Wait for DMA, ignore error */ +@@ -2823,9 +2820,6 @@ void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev) + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 0); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); +- +- rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); +- rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); + } + EXPORT_SYMBOL_GPL(rt2800_disable_radio); + +diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c +index 3b3f1e4..37a38b5 100644 +--- a/drivers/net/wireless/rt2x00/rt2800pci.c ++++ b/drivers/net/wireless/rt2x00/rt2800pci.c +@@ -475,39 +475,23 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) + + static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) + { +- u32 reg; +- +- rt2800_disable_radio(rt2x00dev); +- +- rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001280); +- +- rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); +- rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); +- rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); +- rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); +- rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, 1); +- rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); +- rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); +- rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); +- rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); +- +- rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); +- rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); ++ if (rt2x00_is_soc(rt2x00dev)) { ++ rt2800_disable_radio(rt2x00dev); ++ rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); ++ rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); ++ } + } + + static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, + enum dev_state state) + { +- /* +- * Always put the device to sleep (even when we intend to wakeup!) +- * if the device is booting and wasn't asleep it will return +- * failure when attempting to wakeup. +- */ +- rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0xff, 2); +- + if (state == STATE_AWAKE) { +- rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0); ++ rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0x02); + rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKUP); ++ } else if (state == STATE_SLEEP) { ++ rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, 0xffffffff); ++ rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, 0xffffffff); ++ rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0x01, 0xff, 0x01); + } + + return 0; +diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c +index 9597a03..2b77a29 100644 +--- a/drivers/net/wireless/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c +@@ -1031,8 +1031,10 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) + * Stop all work. + */ + cancel_work_sync(&rt2x00dev->intf_work); +- cancel_work_sync(&rt2x00dev->rxdone_work); +- cancel_work_sync(&rt2x00dev->txdone_work); ++ if (rt2x00_is_usb(rt2x00dev)) { ++ cancel_work_sync(&rt2x00dev->rxdone_work); ++ cancel_work_sync(&rt2x00dev->txdone_work); ++ } + + /* + * Free the tx status fifo. +diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c +index e64403b..6ec06a4 100644 +--- a/drivers/net/wireless/wl12xx/testmode.c ++++ b/drivers/net/wireless/wl12xx/testmode.c +@@ -204,7 +204,10 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) + + kfree(wl->nvs); + +- wl->nvs = kzalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL); ++ if (len != sizeof(struct wl1271_nvs_file)) ++ return -EINVAL; ++ ++ wl->nvs = kzalloc(len, GFP_KERNEL); + if (!wl->nvs) { + wl1271_error("could not allocate memory for the nvs file"); + ret = -ENOMEM; +diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c +index 3188cd9..bbdb4fd 100644 +--- a/drivers/pci/pcie/aspm.c ++++ b/drivers/pci/pcie/aspm.c +@@ -69,6 +69,7 @@ struct pcie_link_state { + }; + + static int aspm_disabled, aspm_force, aspm_clear_state; ++static bool aspm_support_enabled = true; + static DEFINE_MUTEX(aspm_lock); + static LIST_HEAD(link_list); + +@@ -896,6 +897,7 @@ static int __init pcie_aspm_disable(char *str) + { + if (!strcmp(str, "off")) { + aspm_disabled = 1; ++ aspm_support_enabled = false; + printk(KERN_INFO "PCIe ASPM is disabled\n"); + } else if (!strcmp(str, "force")) { + aspm_force = 1; +@@ -930,3 +932,8 @@ int pcie_aspm_enabled(void) + } + EXPORT_SYMBOL(pcie_aspm_enabled); + ++bool pcie_aspm_support_enabled(void) ++{ ++ return aspm_support_enabled; ++} ++EXPORT_SYMBOL(pcie_aspm_support_enabled); +diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c +index 38b34a7..fa54ba7 100644 +--- a/drivers/platform/x86/acer-wmi.c ++++ b/drivers/platform/x86/acer-wmi.c +@@ -222,6 +222,7 @@ struct acer_debug { + static struct rfkill *wireless_rfkill; + static struct rfkill *bluetooth_rfkill; + static struct rfkill *threeg_rfkill; ++static bool rfkill_inited; + + /* Each low-level interface must define at least some of the following */ + struct wmi_interface { +@@ -1161,9 +1162,13 @@ static int acer_rfkill_set(void *data, bool blocked) + { + acpi_status status; + u32 cap = (unsigned long)data; +- status = set_u32(!blocked, cap); +- if (ACPI_FAILURE(status)) +- return -ENODEV; ++ ++ if (rfkill_inited) { ++ status = set_u32(!blocked, cap); ++ if (ACPI_FAILURE(status)) ++ return -ENODEV; ++ } ++ + return 0; + } + +@@ -1187,14 +1192,16 @@ static struct rfkill *acer_rfkill_register(struct device *dev, + return ERR_PTR(-ENOMEM); + + status = get_device_status(&state, cap); +- if (ACPI_SUCCESS(status)) +- rfkill_init_sw_state(rfkill_dev, !state); + + err = rfkill_register(rfkill_dev); + if (err) { + rfkill_destroy(rfkill_dev); + return ERR_PTR(err); + } ++ ++ if (ACPI_SUCCESS(status)) ++ rfkill_set_sw_state(rfkill_dev, !state); ++ + return rfkill_dev; + } + +@@ -1229,6 +1236,8 @@ static int acer_rfkill_init(struct device *dev) + } + } + ++ rfkill_inited = true; ++ + schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); + + return 0; +diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c +index 37268e9..afeb546 100644 +--- a/drivers/rtc/rtc-ds1511.c ++++ b/drivers/rtc/rtc-ds1511.c +@@ -485,7 +485,7 @@ ds1511_nvram_write(struct file *filp, struct kobject *kobj, + static struct bin_attribute ds1511_nvram_attr = { + .attr = { + .name = "nvram", +- .mode = S_IRUGO | S_IWUGO, ++ .mode = S_IRUGO | S_IWUSR, + }, + .size = DS1511_RAM_MAX, + .read = ds1511_nvram_read, +diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c +index f905ecb..01543d2 100644 +--- a/drivers/scsi/scsi_transport_iscsi.c ++++ b/drivers/scsi/scsi_transport_iscsi.c +@@ -1847,7 +1847,7 @@ store_priv_session_##field(struct device *dev, \ + #define iscsi_priv_session_rw_attr(field, format) \ + iscsi_priv_session_attr_show(field, format) \ + iscsi_priv_session_attr_store(field) \ +-static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO | S_IWUGO, \ ++static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO | S_IWUSR, \ + show_priv_session_##field, \ + store_priv_session_##field) + iscsi_priv_session_rw_attr(recovery_tmo, "%d"); +diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c +index 7f5a6a8..3b00e90 100644 +--- a/drivers/scsi/ses.c ++++ b/drivers/scsi/ses.c +@@ -390,9 +390,9 @@ static void ses_enclosure_data_process(struct enclosure_device *edev, + len = (desc_ptr[2] << 8) + desc_ptr[3]; + /* skip past overall descriptor */ + desc_ptr += len + 4; +- if (ses_dev->page10) +- addl_desc_ptr = ses_dev->page10 + 8; + } ++ if (ses_dev->page10) ++ addl_desc_ptr = ses_dev->page10 + 8; + type_ptr = ses_dev->page1 + 12 + ses_dev->page1[11]; + components = 0; + for (i = 0; i < types; i++, type_ptr += 4) { +diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c +index 45a627d..09e596a 100644 +--- a/drivers/staging/hv/channel.c ++++ b/drivers/staging/hv/channel.c +@@ -76,14 +76,14 @@ static void vmbus_setevent(struct vmbus_channel *channel) + + if (channel->offermsg.monitor_allocated) { + /* Each u32 represents 32 channels */ +- set_bit(channel->offermsg.child_relid & 31, ++ sync_set_bit(channel->offermsg.child_relid & 31, + (unsigned long *) gVmbusConnection.SendInterruptPage + + (channel->offermsg.child_relid >> 5)); + + monitorpage = gVmbusConnection.MonitorPages; + monitorpage++; /* Get the child to parent monitor page */ + +- set_bit(channel->monitor_bit, ++ sync_set_bit(channel->monitor_bit, + (unsigned long *)&monitorpage->trigger_group + [channel->monitor_grp].pending); + +@@ -99,7 +99,7 @@ static void VmbusChannelClearEvent(struct vmbus_channel *channel) + + if (Channel->offermsg.monitor_allocated) { + /* Each u32 represents 32 channels */ +- clear_bit(Channel->offermsg.child_relid & 31, ++ sync_clear_bit(Channel->offermsg.child_relid & 31, + (unsigned long *)gVmbusConnection.SendInterruptPage + + (Channel->offermsg.child_relid >> 5)); + +@@ -107,7 +107,7 @@ static void VmbusChannelClearEvent(struct vmbus_channel *channel) + (struct hv_monitor_page *)gVmbusConnection.MonitorPages; + monitorPage++; /* Get the child to parent monitor page */ + +- clear_bit(Channel->monitor_bit, ++ sync_clear_bit(Channel->monitor_bit, + (unsigned long *)&monitorPage->trigger_group + [Channel->monitor_grp].Pending); + } +diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c +index c2e298f..0739eb7 100644 +--- a/drivers/staging/hv/connection.c ++++ b/drivers/staging/hv/connection.c +@@ -281,7 +281,7 @@ void VmbusOnEvents(void) + for (dword = 0; dword < maxdword; dword++) { + if (recvInterruptPage[dword]) { + for (bit = 0; bit < 32; bit++) { +- if (test_and_clear_bit(bit, (unsigned long *)&recvInterruptPage[dword])) { ++ if (sync_test_and_clear_bit(bit, (unsigned long *)&recvInterruptPage[dword])) { + relid = (dword << 5) + bit; + DPRINT_DBG(VMBUS, "event detected for relid - %d", relid); + +@@ -320,7 +320,7 @@ int VmbusPostMessage(void *buffer, size_t bufferLen) + int VmbusSetEvent(u32 childRelId) + { + /* Each u32 represents 32 channels */ +- set_bit(childRelId & 31, ++ sync_set_bit(childRelId & 31, + (unsigned long *)gVmbusConnection.SendInterruptPage + + (childRelId >> 5)); + +diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c +index b41c964..f433add 100644 +--- a/drivers/staging/hv/netvsc_drv.c ++++ b/drivers/staging/hv/netvsc_drv.c +@@ -46,6 +46,7 @@ struct net_device_context { + /* point back to our device context */ + struct vm_device *device_ctx; + unsigned long avail; ++ struct work_struct work; + }; + + struct netvsc_driver_context { +@@ -225,6 +226,7 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj, + unsigned int status) + { + struct vm_device *device_ctx = to_vm_device(device_obj); ++ struct net_device_context *ndev_ctx; + struct net_device *net = dev_get_drvdata(&device_ctx->device); + + if (!net) { +@@ -237,6 +239,8 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj, + netif_carrier_on(net); + netif_wake_queue(net); + netif_notify_peers(net); ++ ndev_ctx = netdev_priv(net); ++ schedule_work(&ndev_ctx->work); + } else { + netif_carrier_off(net); + netif_stop_queue(net); +@@ -336,6 +340,25 @@ static const struct net_device_ops device_ops = { + .ndo_set_mac_address = eth_mac_addr, + }; + ++/* ++ * Send GARP packet to network peers after migrations. ++ * After Quick Migration, the network is not immediately operational in the ++ * current context when receiving RNDIS_STATUS_MEDIA_CONNECT event. So, add ++ * another netif_notify_peers() into a scheduled work, otherwise GARP packet ++ * will not be sent after quick migration, and cause network disconnection. ++ */ ++static void netvsc_send_garp(struct work_struct *w) ++{ ++ struct net_device_context *ndev_ctx; ++ struct net_device *net; ++ ++ msleep(20); ++ ndev_ctx = container_of(w, struct net_device_context, work); ++ net = dev_get_drvdata(&ndev_ctx->device_ctx->device); ++ netif_notify_peers(net); ++} ++ ++ + static int netvsc_probe(struct device *device) + { + struct driver_context *driver_ctx = +@@ -364,6 +387,7 @@ static int netvsc_probe(struct device *device) + net_device_ctx->device_ctx = device_ctx; + net_device_ctx->avail = ring_size; + dev_set_drvdata(device, net); ++ INIT_WORK(&net_device_ctx->work, netvsc_send_garp); + + /* Notify the netvsc driver of the new device */ + ret = net_drv_obj->base.OnDeviceAdd(device_obj, &device_info); +diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c +index 84fdb64..87e6cf2 100644 +--- a/drivers/staging/hv/vmbus_drv.c ++++ b/drivers/staging/hv/vmbus_drv.c +@@ -291,7 +291,7 @@ static int vmbus_on_isr(struct hv_driver *drv) + event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; + + /* Since we are a child, we only need to check bit 0 */ +- if (test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) { ++ if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) { + DPRINT_DBG(VMBUS, "received event %d", event->flags32[0]); + ret |= 0x2; + } +diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h +index 07f6d22..c75b2d7 100644 +--- a/drivers/staging/hv/vmbus_private.h ++++ b/drivers/staging/hv/vmbus_private.h +@@ -31,6 +31,7 @@ + #include "channel_mgmt.h" + #include "ring_buffer.h" + #include ++#include + + + /* +diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h +index 6ff33e1..90e90f0 100644 +--- a/drivers/staging/iio/imu/adis16400.h ++++ b/drivers/staging/iio/imu/adis16400.h +@@ -17,7 +17,8 @@ + #ifndef SPI_ADIS16400_H_ + #define SPI_ADIS16400_H_ + +-#define ADIS16400_STARTUP_DELAY 220 /* ms */ ++#define ADIS16400_STARTUP_DELAY 290 /* ms */ ++#define ADIS16400_MTEST_DELAY 90 /* ms */ + + #define ADIS16400_READ_REG(a) a + #define ADIS16400_WRITE_REG(a) ((a) | 0x80) +diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c +index cfb108a..2107edb 100644 +--- a/drivers/staging/iio/imu/adis16400_core.c ++++ b/drivers/staging/iio/imu/adis16400_core.c +@@ -93,7 +93,6 @@ static int adis16400_spi_write_reg_16(struct device *dev, + .tx_buf = st->tx + 2, + .bits_per_word = 8, + .len = 2, +- .cs_change = 1, + }, + }; + +@@ -137,7 +136,6 @@ static int adis16400_spi_read_reg_16(struct device *dev, + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, +- .cs_change = 1, + }, + }; + +@@ -375,7 +373,7 @@ static int adis16400_self_test(struct device *dev) + dev_err(dev, "problem starting self test"); + goto err_ret; + } +- ++ msleep(ADIS16400_MTEST_DELAY); + adis16400_check_status(dev); + + err_ret: +@@ -497,12 +495,12 @@ err_ret: + _reg) + + static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_X, ADIS16400_XGYRO_OFF); +-static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_Y, ADIS16400_XGYRO_OFF); +-static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_Z, ADIS16400_XGYRO_OFF); ++static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_Y, ADIS16400_YGYRO_OFF); ++static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_Z, ADIS16400_ZGYRO_OFF); + + static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_X, ADIS16400_XACCL_OFF); +-static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_Y, ADIS16400_XACCL_OFF); +-static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_Z, ADIS16400_XACCL_OFF); ++static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_Y, ADIS16400_YACCL_OFF); ++static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_Z, ADIS16400_ZACCL_OFF); + + + static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16400_read_14bit_signed, +diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c +index 33293fb..da28cb428 100644 +--- a/drivers/staging/iio/imu/adis16400_ring.c ++++ b/drivers/staging/iio/imu/adis16400_ring.c +@@ -122,12 +122,10 @@ static int adis16400_spi_read_burst(struct device *dev, u8 *rx) + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, +- .cs_change = 0, + }, { + .rx_buf = rx, + .bits_per_word = 8, + .len = 24, +- .cs_change = 1, + }, + }; + +@@ -162,9 +160,10 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s) + work_trigger_to_ring); + struct iio_ring_buffer *ring = st->indio_dev->ring; + +- int i = 0; ++ int i = 0, j; + s16 *data; + size_t datasize = ring->access.get_bytes_per_datum(ring); ++ unsigned long mask = ring->scan_mask; + + data = kmalloc(datasize , GFP_KERNEL); + if (data == NULL) { +@@ -174,9 +173,12 @@ static void adis16400_trigger_bh_to_ring(struct work_struct *work_s) + + if (ring->scan_count) + if (adis16400_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0) +- for (; i < ring->scan_count; i++) ++ for (; i < ring->scan_count; i++) { ++ j = __ffs(mask); ++ mask &= ~(1 << j); + data[i] = be16_to_cpup( +- (__be16 *)&(st->rx[i*2])); ++ (__be16 *)&(st->rx[j*2])); ++ } + + /* Guaranteed to be aligned with 8 byte boundary */ + if (ring->scan_timestamp) +diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c +index ae6ac82..8e60332 100644 +--- a/drivers/staging/usbip/stub_rx.c ++++ b/drivers/staging/usbip/stub_rx.c +@@ -170,33 +170,23 @@ static int tweak_set_configuration_cmd(struct urb *urb) + + static int tweak_reset_device_cmd(struct urb *urb) + { +- struct usb_ctrlrequest *req; +- __u16 value; +- __u16 index; +- int ret; +- +- req = (struct usb_ctrlrequest *) urb->setup_packet; +- value = le16_to_cpu(req->wValue); +- index = le16_to_cpu(req->wIndex); +- +- usbip_uinfo("reset_device (port %d) to %s\n", index, +- dev_name(&urb->dev->dev)); ++ struct stub_priv *priv = (struct stub_priv *) urb->context; ++ struct stub_device *sdev = priv->sdev; + +- /* all interfaces should be owned by usbip driver, so just reset it. */ +- ret = usb_lock_device_for_reset(urb->dev, NULL); +- if (ret < 0) { +- dev_err(&urb->dev->dev, "lock for reset\n"); +- return ret; +- } +- +- /* try to reset the device */ +- ret = usb_reset_device(urb->dev); +- if (ret < 0) +- dev_err(&urb->dev->dev, "device reset\n"); ++ usbip_uinfo("reset_device %s\n", dev_name(&urb->dev->dev)); + +- usb_unlock_device(urb->dev); +- +- return ret; ++ /* ++ * usb_lock_device_for_reset caused a deadlock: it causes the driver ++ * to unbind. In the shutdown the rx thread is signalled to shut down ++ * but this thread is pending in the usb_lock_device_for_reset. ++ * ++ * Instead queue the reset. ++ * ++ * Unfortunatly an existing usbip connection will be dropped due to ++ * driver unbinding. ++ */ ++ usb_queue_reset_device(sdev->interface); ++ return 0; + } + + /* +diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c +index d7136e2..b7a493c 100644 +--- a/drivers/staging/usbip/stub_tx.c ++++ b/drivers/staging/usbip/stub_tx.c +@@ -169,7 +169,6 @@ static int stub_send_ret_submit(struct stub_device *sdev) + struct stub_priv *priv, *tmp; + + struct msghdr msg; +- struct kvec iov[3]; + size_t txsize; + + size_t total_size = 0; +@@ -179,28 +178,73 @@ static int stub_send_ret_submit(struct stub_device *sdev) + struct urb *urb = priv->urb; + struct usbip_header pdu_header; + void *iso_buffer = NULL; ++ struct kvec *iov = NULL; ++ int iovnum = 0; + + txsize = 0; + memset(&pdu_header, 0, sizeof(pdu_header)); + memset(&msg, 0, sizeof(msg)); +- memset(&iov, 0, sizeof(iov)); + +- usbip_dbg_stub_tx("setup txdata urb %p\n", urb); ++ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) ++ iovnum = 2 + urb->number_of_packets; ++ else ++ iovnum = 2; ++ ++ iov = kzalloc(iovnum * sizeof(struct kvec), GFP_KERNEL); + ++ if (!iov) { ++ usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_MALLOC); ++ return -1; ++ } ++ ++ iovnum = 0; + + /* 1. setup usbip_header */ + setup_ret_submit_pdu(&pdu_header, urb); ++ usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n", ++ pdu_header.base.seqnum, urb); ++ /*usbip_dump_header(pdu_header);*/ + usbip_header_correct_endian(&pdu_header, 1); + +- iov[0].iov_base = &pdu_header; +- iov[0].iov_len = sizeof(pdu_header); ++ iov[iovnum].iov_base = &pdu_header; ++ iov[iovnum].iov_len = sizeof(pdu_header); ++ iovnum++; + txsize += sizeof(pdu_header); + + /* 2. setup transfer buffer */ +- if (usb_pipein(urb->pipe) && urb->actual_length > 0) { +- iov[1].iov_base = urb->transfer_buffer; +- iov[1].iov_len = urb->actual_length; ++ if (usb_pipein(urb->pipe) && ++ usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS && ++ urb->actual_length > 0) { ++ iov[iovnum].iov_base = urb->transfer_buffer; ++ iov[iovnum].iov_len = urb->actual_length; ++ iovnum++; + txsize += urb->actual_length; ++ } else if (usb_pipein(urb->pipe) && ++ usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { ++ /* ++ * For isochronous packets: actual length is the sum of ++ * the actual length of the individual, packets, but as ++ * the packet offsets are not changed there will be ++ * padding between the packets. To optimally use the ++ * bandwidth the padding is not transmitted. ++ */ ++ ++ int i; ++ for (i = 0; i < urb->number_of_packets; i++) { ++ iov[iovnum].iov_base = urb->transfer_buffer + urb->iso_frame_desc[i].offset; ++ iov[iovnum].iov_len = urb->iso_frame_desc[i].actual_length; ++ iovnum++; ++ txsize += urb->iso_frame_desc[i].actual_length; ++ } ++ ++ if (txsize != sizeof(pdu_header) + urb->actual_length) { ++ dev_err(&sdev->interface->dev, ++ "actual length of urb (%d) does not match iso packet sizes (%d)\n", ++ urb->actual_length, txsize-sizeof(pdu_header)); ++ kfree(iov); ++ usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP); ++ return -1; ++ } + } + + /* 3. setup iso_packet_descriptor */ +@@ -211,32 +255,34 @@ static int stub_send_ret_submit(struct stub_device *sdev) + if (!iso_buffer) { + usbip_event_add(&sdev->ud, + SDEV_EVENT_ERROR_MALLOC); ++ kfree(iov); + return -1; + } + +- iov[2].iov_base = iso_buffer; +- iov[2].iov_len = len; ++ iov[iovnum].iov_base = iso_buffer; ++ iov[iovnum].iov_len = len; + txsize += len; ++ iovnum++; + } + +- ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov, +- 3, txsize); ++ ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, ++ iov, iovnum, txsize); + if (ret != txsize) { + dev_err(&sdev->interface->dev, + "sendmsg failed!, retval %d for %zd\n", + ret, txsize); ++ kfree(iov); + kfree(iso_buffer); + usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP); + return -1; + } + ++ kfree(iov); + kfree(iso_buffer); +- usbip_dbg_stub_tx("send txdata\n"); + + total_size += txsize; + } + +- + spin_lock_irqsave(&sdev->priv_lock, flags); + + list_for_each_entry_safe(priv, tmp, &sdev->priv_free, list) { +diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c +index 210ef16..2108ca1 100644 +--- a/drivers/staging/usbip/usbip_common.c ++++ b/drivers/staging/usbip/usbip_common.c +@@ -334,10 +334,11 @@ void usbip_dump_header(struct usbip_header *pdu) + usbip_udbg("CMD_UNLINK: seq %u\n", pdu->u.cmd_unlink.seqnum); + break; + case USBIP_RET_SUBMIT: +- usbip_udbg("RET_SUBMIT: st %d al %u sf %d ec %d\n", ++ usbip_udbg("RET_SUBMIT: st %d al %u sf %d #p %d ec %d\n", + pdu->u.ret_submit.status, + pdu->u.ret_submit.actual_length, + pdu->u.ret_submit.start_frame, ++ pdu->u.ret_submit.number_of_packets, + pdu->u.ret_submit.error_count); + case USBIP_RET_UNLINK: + usbip_udbg("RET_UNLINK: status %d\n", pdu->u.ret_unlink.status); +@@ -625,6 +626,7 @@ static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb, + rpdu->status = urb->status; + rpdu->actual_length = urb->actual_length; + rpdu->start_frame = urb->start_frame; ++ rpdu->number_of_packets = urb->number_of_packets; + rpdu->error_count = urb->error_count; + } else { + /* vhci_rx.c */ +@@ -632,6 +634,7 @@ static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb, + urb->status = rpdu->status; + urb->actual_length = rpdu->actual_length; + urb->start_frame = rpdu->start_frame; ++ urb->number_of_packets = rpdu->number_of_packets; + urb->error_count = rpdu->error_count; + } + } +@@ -700,11 +703,13 @@ static void correct_endian_ret_submit(struct usbip_header_ret_submit *pdu, + cpu_to_be32s(&pdu->status); + cpu_to_be32s(&pdu->actual_length); + cpu_to_be32s(&pdu->start_frame); ++ cpu_to_be32s(&pdu->number_of_packets); + cpu_to_be32s(&pdu->error_count); + } else { + be32_to_cpus(&pdu->status); + be32_to_cpus(&pdu->actual_length); + be32_to_cpus(&pdu->start_frame); ++ cpu_to_be32s(&pdu->number_of_packets); + be32_to_cpus(&pdu->error_count); + } + } +@@ -830,6 +835,7 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb) + int size = np * sizeof(*iso); + int i; + int ret; ++ int total_length = 0; + + if (!usb_pipeisoc(urb->pipe)) + return 0; +@@ -859,19 +865,75 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb) + return -EPIPE; + } + ++ + for (i = 0; i < np; i++) { + iso = buff + (i * sizeof(*iso)); + + usbip_iso_pakcet_correct_endian(iso, 0); + usbip_pack_iso(iso, &urb->iso_frame_desc[i], 0); ++ total_length += urb->iso_frame_desc[i].actual_length; + } + + kfree(buff); + ++ if (total_length != urb->actual_length) { ++ dev_err(&urb->dev->dev, ++ "total length of iso packets (%d) not equal to actual length of buffer (%d)\n", ++ total_length, urb->actual_length); ++ ++ if (ud->side == USBIP_STUB) ++ usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); ++ else ++ usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); ++ ++ return -EPIPE; ++ } ++ + return ret; + } + EXPORT_SYMBOL_GPL(usbip_recv_iso); + ++/* ++ * This functions restores the padding which was removed for optimizing ++ * the bandwidth during transfer over tcp/ip ++ * ++ * buffer and iso packets need to be stored and be in propeper endian in urb ++ * before calling this function ++ */ ++int usbip_pad_iso(struct usbip_device *ud, struct urb *urb) ++{ ++ int np = urb->number_of_packets; ++ int i; ++ int ret; ++ int actualoffset = urb->actual_length; ++ ++ if (!usb_pipeisoc(urb->pipe)) ++ return 0; ++ ++ /* if no packets or length of data is 0, then nothing to unpack */ ++ if (np == 0 || urb->actual_length == 0) ++ return 0; ++ ++ /* ++ * if actual_length is transfer_buffer_length then no padding is ++ * present. ++ */ ++ if (urb->actual_length == urb->transfer_buffer_length) ++ return 0; ++ ++ /* ++ * loop over all packets from last to first (to prevent overwritting ++ * memory when padding) and move them into the proper place ++ */ ++ for (i = np-1; i > 0; i--) { ++ actualoffset -= urb->iso_frame_desc[i].actual_length; ++ memmove(urb->transfer_buffer + urb->iso_frame_desc[i].offset, ++ urb->transfer_buffer + actualoffset, ++ urb->iso_frame_desc[i].actual_length); ++ } ++ return ret; ++} ++EXPORT_SYMBOL_GPL(usbip_pad_iso); + + /* some members of urb must be substituted before. */ + int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb) +diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h +index d280e23..baa4c09 100644 +--- a/drivers/staging/usbip/usbip_common.h ++++ b/drivers/staging/usbip/usbip_common.h +@@ -393,6 +393,8 @@ void usbip_header_correct_endian(struct usbip_header *pdu, int send); + int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb); + /* some members of urb must be substituted before. */ + int usbip_recv_iso(struct usbip_device *ud, struct urb *urb); ++/* some members of urb must be substituted before. */ ++int usbip_pad_iso(struct usbip_device *ud, struct urb *urb); + void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen); + + +diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c +index bf69914..109002a 100644 +--- a/drivers/staging/usbip/vhci_rx.c ++++ b/drivers/staging/usbip/vhci_rx.c +@@ -99,6 +99,9 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, + if (usbip_recv_iso(ud, urb) < 0) + return; + ++ /* restore the padding in iso packets */ ++ if (usbip_pad_iso(ud, urb) < 0) ++ return; + + if (usbip_dbg_flag_vhci_rx) + usbip_dump_urb(urb); +diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c +index 596ba60..51b5551 100644 +--- a/drivers/watchdog/davinci_wdt.c ++++ b/drivers/watchdog/davinci_wdt.c +@@ -202,7 +202,6 @@ static struct miscdevice davinci_wdt_miscdev = { + static int __devinit davinci_wdt_probe(struct platform_device *pdev) + { + int ret = 0, size; +- struct resource *res; + struct device *dev = &pdev->dev; + + wdt_clk = clk_get(dev, NULL); +@@ -216,31 +215,31 @@ static int __devinit davinci_wdt_probe(struct platform_device *pdev) + + dev_info(dev, "heartbeat %d sec\n", heartbeat); + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (res == NULL) { ++ wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (wdt_mem == NULL) { + dev_err(dev, "failed to get memory region resource\n"); + return -ENOENT; + } + +- size = resource_size(res); +- wdt_mem = request_mem_region(res->start, size, pdev->name); +- +- if (wdt_mem == NULL) { ++ size = resource_size(wdt_mem); ++ if (!request_mem_region(wdt_mem->start, size, pdev->name)) { + dev_err(dev, "failed to get memory region\n"); + return -ENOENT; + } + +- wdt_base = ioremap(res->start, size); ++ wdt_base = ioremap(wdt_mem->start, size); + if (!wdt_base) { + dev_err(dev, "failed to map memory region\n"); ++ release_mem_region(wdt_mem->start, size); ++ wdt_mem = NULL; + return -ENOMEM; + } + + ret = misc_register(&davinci_wdt_miscdev); + if (ret < 0) { + dev_err(dev, "cannot register misc device\n"); +- release_resource(wdt_mem); +- kfree(wdt_mem); ++ release_mem_region(wdt_mem->start, size); ++ wdt_mem = NULL; + } else { + set_bit(WDT_DEVICE_INITED, &wdt_status); + } +@@ -253,8 +252,7 @@ static int __devexit davinci_wdt_remove(struct platform_device *pdev) + { + misc_deregister(&davinci_wdt_miscdev); + if (wdt_mem) { +- release_resource(wdt_mem); +- kfree(wdt_mem); ++ release_mem_region(wdt_mem->start, resource_size(wdt_mem)); + wdt_mem = NULL; + } + +diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c +index 3053ff0..1fe9bc5 100644 +--- a/drivers/watchdog/max63xx_wdt.c ++++ b/drivers/watchdog/max63xx_wdt.c +@@ -270,7 +270,6 @@ static int __devinit max63xx_wdt_probe(struct platform_device *pdev) + { + int ret = 0; + int size; +- struct resource *res; + struct device *dev = &pdev->dev; + struct max63xx_timeout *table; + +@@ -294,21 +293,19 @@ static int __devinit max63xx_wdt_probe(struct platform_device *pdev) + + max63xx_pdev = pdev; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (res == NULL) { ++ wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (wdt_mem == NULL) { + dev_err(dev, "failed to get memory region resource\n"); + return -ENOENT; + } + +- size = resource_size(res); +- wdt_mem = request_mem_region(res->start, size, pdev->name); +- +- if (wdt_mem == NULL) { ++ size = resource_size(wdt_mem); ++ if (!request_mem_region(wdt_mem->start, size, pdev->name)) { + dev_err(dev, "failed to get memory region\n"); + return -ENOENT; + } + +- wdt_base = ioremap(res->start, size); ++ wdt_base = ioremap(wdt_mem->start, size); + if (!wdt_base) { + dev_err(dev, "failed to map memory region\n"); + ret = -ENOMEM; +@@ -326,8 +323,8 @@ static int __devinit max63xx_wdt_probe(struct platform_device *pdev) + out_unmap: + iounmap(wdt_base); + out_request: +- release_resource(wdt_mem); +- kfree(wdt_mem); ++ release_mem_region(wdt_mem->start, size); ++ wdt_mem = NULL; + + return ret; + } +@@ -336,8 +333,7 @@ static int __devexit max63xx_wdt_remove(struct platform_device *pdev) + { + misc_deregister(&max63xx_wdt_miscdev); + if (wdt_mem) { +- release_resource(wdt_mem); +- kfree(wdt_mem); ++ release_mem_region(wdt_mem->start, resource_size(wdt_mem)); + wdt_mem = NULL; + } + +diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c +index bf5b97c..8c8c7d5 100644 +--- a/drivers/watchdog/pnx4008_wdt.c ++++ b/drivers/watchdog/pnx4008_wdt.c +@@ -254,7 +254,6 @@ static struct miscdevice pnx4008_wdt_miscdev = { + static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) + { + int ret = 0, size; +- struct resource *res; + + if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT) + heartbeat = DEFAULT_HEARTBEAT; +@@ -262,42 +261,42 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) + printk(KERN_INFO MODULE_NAME + "PNX4008 Watchdog Timer: heartbeat %d sec\n", heartbeat); + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (res == NULL) { ++ wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (wdt_mem == NULL) { + printk(KERN_INFO MODULE_NAME + "failed to get memory region resouce\n"); + return -ENOENT; + } + +- size = resource_size(res); +- wdt_mem = request_mem_region(res->start, size, pdev->name); ++ size = resource_size(wdt_mem); + +- if (wdt_mem == NULL) { ++ if (!request_mem_region(wdt_mem->start, size, pdev->name)) { + printk(KERN_INFO MODULE_NAME "failed to get memory region\n"); + return -ENOENT; + } +- wdt_base = (void __iomem *)IO_ADDRESS(res->start); ++ wdt_base = (void __iomem *)IO_ADDRESS(wdt_mem->start); + + wdt_clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(wdt_clk)) { + ret = PTR_ERR(wdt_clk); +- release_resource(wdt_mem); +- kfree(wdt_mem); ++ release_mem_region(wdt_mem->start, size); ++ wdt_mem = NULL; + goto out; + } + + ret = clk_enable(wdt_clk); + if (ret) { +- release_resource(wdt_mem); +- kfree(wdt_mem); ++ release_mem_region(wdt_mem->start, size); ++ wdt_mem = NULL; ++ clk_put(wdt_clk); + goto out; + } + + ret = misc_register(&pnx4008_wdt_miscdev); + if (ret < 0) { + printk(KERN_ERR MODULE_NAME "cannot register misc device\n"); +- release_resource(wdt_mem); +- kfree(wdt_mem); ++ release_mem_region(wdt_mem->start, size); ++ wdt_mem = NULL; + clk_disable(wdt_clk); + clk_put(wdt_clk); + } else { +@@ -320,8 +319,7 @@ static int __devexit pnx4008_wdt_remove(struct platform_device *pdev) + clk_put(wdt_clk); + + if (wdt_mem) { +- release_resource(wdt_mem); +- kfree(wdt_mem); ++ release_mem_region(wdt_mem->start, resource_size(wdt_mem)); + wdt_mem = NULL; + } + return 0; +diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c +index ae53662..8303c57 100644 +--- a/drivers/watchdog/s3c2410_wdt.c ++++ b/drivers/watchdog/s3c2410_wdt.c +@@ -402,7 +402,6 @@ static inline void s3c2410wdt_cpufreq_deregister(void) + + static int __devinit s3c2410wdt_probe(struct platform_device *pdev) + { +- struct resource *res; + struct device *dev; + unsigned int wtcon; + int started = 0; +@@ -416,20 +415,19 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) + + /* get the memory region for the watchdog timer */ + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (res == NULL) { ++ wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (wdt_mem == NULL) { + dev_err(dev, "no memory resource specified\n"); + return -ENOENT; + } + +- size = resource_size(res); +- wdt_mem = request_mem_region(res->start, size, pdev->name); +- if (wdt_mem == NULL) { ++ size = resource_size(wdt_mem); ++ if (!request_mem_region(wdt_mem->start, size, pdev->name)) { + dev_err(dev, "failed to get memory region\n"); + return -EBUSY; + } + +- wdt_base = ioremap(res->start, size); ++ wdt_base = ioremap(wdt_mem->start, size); + if (wdt_base == NULL) { + dev_err(dev, "failed to ioremap() region\n"); + ret = -EINVAL; +@@ -524,8 +522,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) + iounmap(wdt_base); + + err_req: +- release_resource(wdt_mem); +- kfree(wdt_mem); ++ release_mem_region(wdt_mem->start, size); ++ wdt_mem = NULL; + + return ret; + } +@@ -545,8 +543,7 @@ static int __devexit s3c2410wdt_remove(struct platform_device *dev) + + iounmap(wdt_base); + +- release_resource(wdt_mem); +- kfree(wdt_mem); ++ release_mem_region(wdt_mem->start, resource_size(wdt_mem)); + wdt_mem = NULL; + return 0; + } +diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c +index 8083728..c7ea4be 100644 +--- a/drivers/watchdog/sp5100_tco.c ++++ b/drivers/watchdog/sp5100_tco.c +@@ -42,6 +42,7 @@ + #define PFX TCO_MODULE_NAME ": " + + /* internal variables */ ++static u32 tcobase_phys; + static void __iomem *tcobase; + static unsigned int pm_iobase; + static DEFINE_SPINLOCK(tco_lock); /* Guards the hardware */ +@@ -305,10 +306,18 @@ static unsigned char __devinit sp5100_tco_setupdevice(void) + /* Low three bits of BASE0 are reserved. */ + val = val << 8 | (inb(SP5100_IO_PM_DATA_REG) & 0xf8); + ++ if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE, ++ "SP5100 TCO")) { ++ printk(KERN_ERR PFX "mmio address 0x%04x already in use\n", ++ val); ++ goto unreg_region; ++ } ++ tcobase_phys = val; ++ + tcobase = ioremap(val, SP5100_WDT_MEM_MAP_SIZE); + if (tcobase == 0) { + printk(KERN_ERR PFX "failed to get tcobase address\n"); +- goto unreg_region; ++ goto unreg_mem_region; + } + + /* Enable watchdog decode bit */ +@@ -346,7 +355,8 @@ static unsigned char __devinit sp5100_tco_setupdevice(void) + /* Done */ + return 1; + +- iounmap(tcobase); ++unreg_mem_region: ++ release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); + unreg_region: + release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); + exit: +@@ -401,6 +411,7 @@ static int __devinit sp5100_tco_init(struct platform_device *dev) + + exit: + iounmap(tcobase); ++ release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); + release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); + return ret; + } +@@ -414,6 +425,7 @@ static void __devexit sp5100_tco_cleanup(void) + /* Deregister */ + misc_deregister(&sp5100_tco_miscdev); + iounmap(tcobase); ++ release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE); + release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE); + } + +diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h +index 7f78cc7..bd64b41 100644 +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -1284,6 +1284,8 @@ struct btrfs_root { + #define BTRFS_INODE_NOATIME (1 << 9) + #define BTRFS_INODE_DIRSYNC (1 << 10) + ++#define BTRFS_INODE_ROOT_ITEM_INIT (1 << 31) ++ + /* some macros to generate set/get funcs for the struct fields. This + * assumes there is a lefoo_to_cpu for every type, so lets make a simple + * one for u8: +@@ -2355,6 +2357,8 @@ int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid); + int btrfs_find_orphan_roots(struct btrfs_root *tree_root); + int btrfs_set_root_node(struct btrfs_root_item *item, + struct extent_buffer *node); ++void btrfs_check_and_init_root_item(struct btrfs_root_item *item); ++ + /* dir-item.c */ + int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, + struct btrfs_root *root, const char *name, +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index e1aa8d6..edd9efa 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -1184,8 +1184,10 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, + root->commit_root = btrfs_root_node(root); + BUG_ON(!root->node); + out: +- if (location->objectid != BTRFS_TREE_LOG_OBJECTID) ++ if (location->objectid != BTRFS_TREE_LOG_OBJECTID) { + root->ref_cows = 1; ++ btrfs_check_and_init_root_item(&root->root_item); ++ } + + return root; + } +diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c +index 5fdb2ab..2ff51e6 100644 +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -294,6 +294,10 @@ static noinline int create_subvol(struct btrfs_root *root, + inode_item->nbytes = cpu_to_le64(root->leafsize); + inode_item->mode = cpu_to_le32(S_IFDIR | 0755); + ++ root_item.flags = 0; ++ root_item.byte_limit = 0; ++ inode_item->flags = cpu_to_le64(BTRFS_INODE_ROOT_ITEM_INIT); ++ + btrfs_set_root_bytenr(&root_item, leaf->start); + btrfs_set_root_generation(&root_item, trans->transid); + btrfs_set_root_level(&root_item, 0); +diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c +index 6a1086e..3e45c32 100644 +--- a/fs/btrfs/root-tree.c ++++ b/fs/btrfs/root-tree.c +@@ -471,3 +471,21 @@ again: + btrfs_free_path(path); + return 0; + } ++ ++/* ++ * Old btrfs forgets to init root_item->flags and root_item->byte_limit ++ * for subvolumes. To work around this problem, we steal a bit from ++ * root_item->inode_item->flags, and use it to indicate if those fields ++ * have been properly initialized. ++ */ ++void btrfs_check_and_init_root_item(struct btrfs_root_item *root_item) ++{ ++ u64 inode_flags = le64_to_cpu(root_item->inode.flags); ++ ++ if (!(inode_flags & BTRFS_INODE_ROOT_ITEM_INIT)) { ++ inode_flags |= BTRFS_INODE_ROOT_ITEM_INIT; ++ root_item->inode.flags = cpu_to_le64(inode_flags); ++ root_item->flags = 0; ++ root_item->byte_limit = 0; ++ } ++} +diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c +index 3d73c8d..f3d6681 100644 +--- a/fs/btrfs/transaction.c ++++ b/fs/btrfs/transaction.c +@@ -970,6 +970,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, + record_root_in_trans(trans, root); + btrfs_set_root_last_snapshot(&root->root_item, trans->transid); + memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); ++ btrfs_check_and_init_root_item(new_root_item); + + root_flags = btrfs_root_flags(new_root_item); + if (pending->readonly) +diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c +index c1436cf..4feb78c 100644 +--- a/fs/ecryptfs/keystore.c ++++ b/fs/ecryptfs/keystore.c +@@ -1563,6 +1563,7 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, + printk(KERN_ERR "Could not find key with description: [%s]\n", + sig); + rc = process_request_key_err(PTR_ERR(*auth_tok_key)); ++ (*auth_tok_key) = NULL; + goto out; + } + (*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key); +diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c +index cc64fca..eb9d967 100644 +--- a/fs/ecryptfs/mmap.c ++++ b/fs/ecryptfs/mmap.c +@@ -374,6 +374,11 @@ static int ecryptfs_write_begin(struct file *file, + && (pos != 0)) + zero_user(page, 0, PAGE_CACHE_SIZE); + out: ++ if (unlikely(rc)) { ++ unlock_page(page); ++ page_cache_release(page); ++ *pagep = NULL; ++ } + return rc; + } + +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index 9f7f9e4..fee51db 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -5460,13 +5460,12 @@ static int ext4_indirect_trans_blocks(struct inode *inode, int nrblocks, + /* if nrblocks are contiguous */ + if (chunk) { + /* +- * With N contiguous data blocks, it need at most +- * N/EXT4_ADDR_PER_BLOCK(inode->i_sb) indirect blocks +- * 2 dindirect blocks +- * 1 tindirect block ++ * With N contiguous data blocks, we need at most ++ * N/EXT4_ADDR_PER_BLOCK(inode->i_sb) + 1 indirect blocks, ++ * 2 dindirect blocks, and 1 tindirect block + */ +- indirects = nrblocks / EXT4_ADDR_PER_BLOCK(inode->i_sb); +- return indirects + 3; ++ return DIV_ROUND_UP(nrblocks, ++ EXT4_ADDR_PER_BLOCK(inode->i_sb)) + 4; + } + /* + * if nrblocks are not contiguous, worse case, each block touch +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 4381efe..243deb0 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2978,6 +2978,12 @@ static int ext4_register_li_request(struct super_block *sb, + mutex_unlock(&ext4_li_info->li_list_mtx); + + sbi->s_li_request = elr; ++ /* ++ * set elr to NULL here since it has been inserted to ++ * the request_list and the removal and free of it is ++ * handled by ext4_clear_request_list from now on. ++ */ ++ elr = NULL; + + if (!(ext4_li_info->li_state & EXT4_LAZYINIT_RUNNING)) { + ret = ext4_run_lazyinit_thread(); +diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c +index 0c6d816..7c831a2 100644 +--- a/fs/nfsd/lockd.c ++++ b/fs/nfsd/lockd.c +@@ -38,7 +38,6 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp) + exp_readlock(); + nfserr = nfsd_open(rqstp, &fh, S_IFREG, NFSD_MAY_LOCK, filp); + fh_put(&fh); +- rqstp->rq_client = NULL; + exp_readunlock(); + /* We return nlm error codes as nlm doesn't know + * about nfsd, but nfsd does know about nlm.. +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index f0e448a..96aaaa4 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -397,10 +397,13 @@ static void unhash_generic_stateid(struct nfs4_stateid *stp) + + static void free_generic_stateid(struct nfs4_stateid *stp) + { +- int oflag = nfs4_access_bmap_to_omode(stp); ++ int oflag; + +- nfs4_file_put_access(stp->st_file, oflag); +- put_nfs4_file(stp->st_file); ++ if (stp->st_access_bmap) { ++ oflag = nfs4_access_bmap_to_omode(stp); ++ nfs4_file_put_access(stp->st_file, oflag); ++ put_nfs4_file(stp->st_file); ++ } + kmem_cache_free(stateid_slab, stp); + } + +diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c +index 2f560c9..f49e628 100644 +--- a/fs/nilfs2/file.c ++++ b/fs/nilfs2/file.c +@@ -72,10 +72,9 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) + /* + * check to see if the page is mapped already (no holes) + */ +- if (PageMappedToDisk(page)) { +- unlock_page(page); ++ if (PageMappedToDisk(page)) + goto mapped; +- } ++ + if (page_has_buffers(page)) { + struct buffer_head *bh, *head; + int fully_mapped = 1; +@@ -90,7 +89,6 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) + + if (fully_mapped) { + SetPageMappedToDisk(page); +- unlock_page(page); + goto mapped; + } + } +@@ -105,16 +103,17 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) + return VM_FAULT_SIGBUS; + + ret = block_page_mkwrite(vma, vmf, nilfs_get_block); +- if (unlikely(ret)) { ++ if (ret != VM_FAULT_LOCKED) { + nilfs_transaction_abort(inode->i_sb); + return ret; + } ++ nilfs_set_file_dirty(inode, 1 << (PAGE_SHIFT - inode->i_blkbits)); + nilfs_transaction_commit(inode->i_sb); + + mapped: + SetPageChecked(page); + wait_on_page_writeback(page); +- return 0; ++ return VM_FAULT_LOCKED; + } + + static const struct vm_operations_struct nilfs_file_vm_ops = { +diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c +index a91b69a..0348d0c 100644 +--- a/fs/notify/inotify/inotify_fsnotify.c ++++ b/fs/notify/inotify/inotify_fsnotify.c +@@ -198,6 +198,7 @@ static void inotify_free_group_priv(struct fsnotify_group *group) + idr_for_each(&group->inotify_data.idr, idr_callback, group); + idr_remove_all(&group->inotify_data.idr); + idr_destroy(&group->inotify_data.idr); ++ atomic_dec(&group->inotify_data.user->inotify_devs); + free_uid(group->inotify_data.user); + } + +diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c +index 4cd5d5d..aec9b4a 100644 +--- a/fs/notify/inotify/inotify_user.c ++++ b/fs/notify/inotify/inotify_user.c +@@ -290,7 +290,6 @@ static int inotify_fasync(int fd, struct file *file, int on) + static int inotify_release(struct inode *ignored, struct file *file) + { + struct fsnotify_group *group = file->private_data; +- struct user_struct *user = group->inotify_data.user; + + pr_debug("%s: group=%p\n", __func__, group); + +@@ -299,8 +298,6 @@ static int inotify_release(struct inode *ignored, struct file *file) + /* free this group, matching get was inotify_init->fsnotify_obtain_group */ + fsnotify_put_group(group); + +- atomic_dec(&user->inotify_devs); +- + return 0; + } + +@@ -697,7 +694,7 @@ retry: + return ret; + } + +-static struct fsnotify_group *inotify_new_group(struct user_struct *user, unsigned int max_events) ++static struct fsnotify_group *inotify_new_group(unsigned int max_events) + { + struct fsnotify_group *group; + +@@ -710,8 +707,14 @@ static struct fsnotify_group *inotify_new_group(struct user_struct *user, unsign + spin_lock_init(&group->inotify_data.idr_lock); + idr_init(&group->inotify_data.idr); + group->inotify_data.last_wd = 0; +- group->inotify_data.user = user; + group->inotify_data.fa = NULL; ++ group->inotify_data.user = get_current_user(); ++ ++ if (atomic_inc_return(&group->inotify_data.user->inotify_devs) > ++ inotify_max_user_instances) { ++ fsnotify_put_group(group); ++ return ERR_PTR(-EMFILE); ++ } + + return group; + } +@@ -721,7 +724,6 @@ static struct fsnotify_group *inotify_new_group(struct user_struct *user, unsign + SYSCALL_DEFINE1(inotify_init1, int, flags) + { + struct fsnotify_group *group; +- struct user_struct *user; + int ret; + + /* Check the IN_* constants for consistency. */ +@@ -731,31 +733,16 @@ SYSCALL_DEFINE1(inotify_init1, int, flags) + if (flags & ~(IN_CLOEXEC | IN_NONBLOCK)) + return -EINVAL; + +- user = get_current_user(); +- if (unlikely(atomic_read(&user->inotify_devs) >= +- inotify_max_user_instances)) { +- ret = -EMFILE; +- goto out_free_uid; +- } +- + /* fsnotify_obtain_group took a reference to group, we put this when we kill the file in the end */ +- group = inotify_new_group(user, inotify_max_queued_events); +- if (IS_ERR(group)) { +- ret = PTR_ERR(group); +- goto out_free_uid; +- } +- +- atomic_inc(&user->inotify_devs); ++ group = inotify_new_group(inotify_max_queued_events); ++ if (IS_ERR(group)) ++ return PTR_ERR(group); + + ret = anon_inode_getfd("inotify", &inotify_fops, group, + O_RDONLY | flags); +- if (ret >= 0) +- return ret; ++ if (ret < 0) ++ fsnotify_put_group(group); + +- fsnotify_put_group(group); +- atomic_dec(&user->inotify_devs); +-out_free_uid: +- free_uid(user); + return ret; + } + +diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c +index 1fbb0e2..bbba782 100644 +--- a/fs/ocfs2/aops.c ++++ b/fs/ocfs2/aops.c +@@ -1026,6 +1026,12 @@ static int ocfs2_prepare_page_for_write(struct inode *inode, u64 *p_blkno, + ocfs2_figure_cluster_boundaries(OCFS2_SB(inode->i_sb), cpos, + &cluster_start, &cluster_end); + ++ /* treat the write as new if the a hole/lseek spanned across ++ * the page boundary. ++ */ ++ new = new | ((i_size_read(inode) <= page_offset(page)) && ++ (page_offset(page) <= user_pos)); ++ + if (page == wc->w_target_page) { + map_from = user_pos & (PAGE_CACHE_SIZE - 1); + map_to = map_from + user_len; +diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c +index a2a622e..b59ee61 100644 +--- a/fs/quota/dquot.c ++++ b/fs/quota/dquot.c +@@ -442,7 +442,7 @@ EXPORT_SYMBOL(dquot_acquire); + */ + int dquot_commit(struct dquot *dquot) + { +- int ret = 0, ret2 = 0; ++ int ret = 0; + struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); + + mutex_lock(&dqopt->dqio_mutex); +@@ -454,15 +454,10 @@ int dquot_commit(struct dquot *dquot) + spin_unlock(&dq_list_lock); + /* Inactive dquot can be only if there was error during read/init + * => we have better not writing it */ +- if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { ++ if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) + ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); +- if (info_dirty(&dqopt->info[dquot->dq_type])) { +- ret2 = dqopt->ops[dquot->dq_type]->write_file_info( +- dquot->dq_sb, dquot->dq_type); +- } +- if (ret >= 0) +- ret = ret2; +- } ++ else ++ ret = -EIO; + out_sem: + mutex_unlock(&dqopt->dqio_mutex); + return ret; +diff --git a/fs/squashfs/dir.c b/fs/squashfs/dir.c +index 0dc340a..3f79cd1 100644 +--- a/fs/squashfs/dir.c ++++ b/fs/squashfs/dir.c +@@ -172,6 +172,11 @@ static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir) + length += sizeof(dirh); + + dir_count = le32_to_cpu(dirh.count) + 1; ++ ++ /* dir_count should never be larger than 256 */ ++ if (dir_count > 256) ++ goto failed_read; ++ + while (dir_count--) { + /* + * Read directory entry. +@@ -183,6 +188,10 @@ static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir) + + size = le16_to_cpu(dire->size) + 1; + ++ /* size should never be larger than SQUASHFS_NAME_LEN */ ++ if (size > SQUASHFS_NAME_LEN) ++ goto failed_read; ++ + err = squashfs_read_metadata(inode->i_sb, dire->name, + &block, &offset, size); + if (err < 0) +diff --git a/fs/squashfs/namei.c b/fs/squashfs/namei.c +index 7a9464d..5d922a6 100644 +--- a/fs/squashfs/namei.c ++++ b/fs/squashfs/namei.c +@@ -176,6 +176,11 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry, + length += sizeof(dirh); + + dir_count = le32_to_cpu(dirh.count) + 1; ++ ++ /* dir_count should never be larger than 256 */ ++ if (dir_count > 256) ++ goto data_error; ++ + while (dir_count--) { + /* + * Read directory entry. +@@ -187,6 +192,10 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry, + + size = le16_to_cpu(dire->size) + 1; + ++ /* size should never be larger than SQUASHFS_NAME_LEN */ ++ if (size > SQUASHFS_NAME_LEN) ++ goto data_error; ++ + err = squashfs_read_metadata(dir->i_sb, dire->name, + &block, &offset, size); + if (err < 0) +@@ -228,6 +237,9 @@ exit_lookup: + d_add(dentry, inode); + return ERR_PTR(0); + ++data_error: ++ err = -EIO; ++ + read_failure: + ERROR("Unable to read directory block [%llx:%x]\n", + squashfs_i(dir)->start + msblk->directory_table, +diff --git a/fs/squashfs/zlib_wrapper.c b/fs/squashfs/zlib_wrapper.c +index 4661ae2..04ae9a5 100644 +--- a/fs/squashfs/zlib_wrapper.c ++++ b/fs/squashfs/zlib_wrapper.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #include "squashfs_fs.h" + #include "squashfs_fs_sb.h" +@@ -37,8 +38,7 @@ static void *zlib_init(struct squashfs_sb_info *dummy) + z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL); + if (stream == NULL) + goto failed; +- stream->workspace = kmalloc(zlib_inflate_workspacesize(), +- GFP_KERNEL); ++ stream->workspace = vmalloc(zlib_inflate_workspacesize()); + if (stream->workspace == NULL) + goto failed; + +@@ -56,7 +56,7 @@ static void zlib_free(void *strm) + z_stream *stream = strm; + + if (stream) +- kfree(stream->workspace); ++ vfree(stream->workspace); + kfree(stream); + } + +diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c +index 02429d8..32bcb2c 100644 +--- a/fs/ubifs/commit.c ++++ b/fs/ubifs/commit.c +@@ -521,7 +521,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot) + size_t sz; + + if (!(ubifs_chk_flags & UBIFS_CHK_OLD_IDX)) +- goto out; ++ return 0; + + INIT_LIST_HEAD(&list); + +diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c +index 0bee4db..5b9e985 100644 +--- a/fs/ubifs/debug.c ++++ b/fs/ubifs/debug.c +@@ -961,11 +961,39 @@ void dbg_dump_index(struct ubifs_info *c) + void dbg_save_space_info(struct ubifs_info *c) + { + struct ubifs_debug_info *d = c->dbg; +- +- ubifs_get_lp_stats(c, &d->saved_lst); ++ int freeable_cnt; + + spin_lock(&c->space_lock); ++ memcpy(&d->saved_lst, &c->lst, sizeof(struct ubifs_lp_stats)); ++ ++ /* ++ * We use a dirty hack here and zero out @c->freeable_cnt, because it ++ * affects the free space calculations, and UBIFS might not know about ++ * all freeable eraseblocks. Indeed, we know about freeable eraseblocks ++ * only when we read their lprops, and we do this only lazily, upon the ++ * need. So at any given point of time @c->freeable_cnt might be not ++ * exactly accurate. ++ * ++ * Just one example about the issue we hit when we did not zero ++ * @c->freeable_cnt. ++ * 1. The file-system is mounted R/O, c->freeable_cnt is %0. We save the ++ * amount of free space in @d->saved_free ++ * 2. We re-mount R/W, which makes UBIFS to read the "lsave" ++ * information from flash, where we cache LEBs from various ++ * categories ('ubifs_remount_fs()' -> 'ubifs_lpt_init()' ++ * -> 'lpt_init_wr()' -> 'read_lsave()' -> 'ubifs_lpt_lookup()' ++ * -> 'ubifs_get_pnode()' -> 'update_cats()' ++ * -> 'ubifs_add_to_cat()'). ++ * 3. Lsave contains a freeable eraseblock, and @c->freeable_cnt ++ * becomes %1. ++ * 4. We calculate the amount of free space when the re-mount is ++ * finished in 'dbg_check_space_info()' and it does not match ++ * @d->saved_free. ++ */ ++ freeable_cnt = c->freeable_cnt; ++ c->freeable_cnt = 0; + d->saved_free = ubifs_get_free_space_nolock(c); ++ c->freeable_cnt = freeable_cnt; + spin_unlock(&c->space_lock); + } + +@@ -982,12 +1010,15 @@ int dbg_check_space_info(struct ubifs_info *c) + { + struct ubifs_debug_info *d = c->dbg; + struct ubifs_lp_stats lst; +- long long avail, free; ++ long long free; ++ int freeable_cnt; + + spin_lock(&c->space_lock); +- avail = ubifs_calc_available(c, c->min_idx_lebs); ++ freeable_cnt = c->freeable_cnt; ++ c->freeable_cnt = 0; ++ free = ubifs_get_free_space_nolock(c); ++ c->freeable_cnt = freeable_cnt; + spin_unlock(&c->space_lock); +- free = ubifs_get_free_space(c); + + if (free != d->saved_free) { + ubifs_err("free space changed from %lld to %lld", +diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c +index 72775d3..ef5155e 100644 +--- a/fs/ubifs/lpt.c ++++ b/fs/ubifs/lpt.c +@@ -1270,10 +1270,9 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip) + lnum = branch->lnum; + offs = branch->offs; + pnode = kzalloc(sizeof(struct ubifs_pnode), GFP_NOFS); +- if (!pnode) { +- err = -ENOMEM; +- goto out; +- } ++ if (!pnode) ++ return -ENOMEM; ++ + if (lnum == 0) { + /* + * This pnode was not written which just means that the LEB +diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c +index 9731898..ad485b6 100644 +--- a/fs/xfs/linux-2.6/xfs_super.c ++++ b/fs/xfs/linux-2.6/xfs_super.c +@@ -1551,10 +1551,14 @@ xfs_fs_fill_super( + if (error) + goto out_free_sb; + +- error = xfs_mountfs(mp); +- if (error) +- goto out_filestream_unmount; +- ++ /* ++ * we must configure the block size in the superblock before we run the ++ * full mount process as the mount process can lookup and cache inodes. ++ * For the same reason we must also initialise the syncd and register ++ * the inode cache shrinker so that inodes can be reclaimed during ++ * operations like a quotacheck that iterate all inodes in the ++ * filesystem. ++ */ + sb->s_magic = XFS_SB_MAGIC; + sb->s_blocksize = mp->m_sb.sb_blocksize; + sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1; +@@ -1562,6 +1566,16 @@ xfs_fs_fill_super( + sb->s_time_gran = 1; + set_posix_acl_flag(sb); + ++ error = xfs_syncd_init(mp); ++ if (error) ++ goto out_filestream_unmount; ++ ++ xfs_inode_shrinker_register(mp); ++ ++ error = xfs_mountfs(mp); ++ if (error) ++ goto out_syncd_stop; ++ + root = igrab(VFS_I(mp->m_rootip)); + if (!root) { + error = ENOENT; +@@ -1577,14 +1591,11 @@ xfs_fs_fill_super( + goto fail_vnrele; + } + +- error = xfs_syncd_init(mp); +- if (error) +- goto fail_vnrele; +- +- xfs_inode_shrinker_register(mp); +- + return 0; + ++ out_syncd_stop: ++ xfs_inode_shrinker_unregister(mp); ++ xfs_syncd_stop(mp); + out_filestream_unmount: + xfs_filestream_unmount(mp); + out_free_sb: +@@ -1608,6 +1619,9 @@ xfs_fs_fill_super( + } + + fail_unmount: ++ xfs_inode_shrinker_unregister(mp); ++ xfs_syncd_stop(mp); ++ + /* + * Blow away any referenced inode in the filestreams cache. + * This can and will cause log traffic as inodes go inactive +diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h +index 5ff1194..6724bf3 100644 +--- a/include/drm/drm_pciids.h ++++ b/include/drm/drm_pciids.h +@@ -458,6 +458,8 @@ + {0x1002, 0x9803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9804, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9806, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9807, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0, 0, 0} + + #define r128_PCI_IDS \ +diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h +index 475f8c4..381f4ce 100644 +--- a/include/linux/atmdev.h ++++ b/include/linux/atmdev.h +@@ -443,6 +443,7 @@ void atm_dev_signal_change(struct atm_dev *dev, char signal); + + void vcc_insert_socket(struct sock *sk); + ++void atm_dev_release_vccs(struct atm_dev *dev); + + /* + * This is approximately the algorithm used by alloc_skb. +diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h +index a3c1874..a04b6ce 100644 +--- a/include/linux/ethtool.h ++++ b/include/linux/ethtool.h +@@ -591,6 +591,7 @@ int ethtool_op_set_ufo(struct net_device *dev, u32 data); + u32 ethtool_op_get_flags(struct net_device *dev); + int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported); + void ethtool_ntuple_flush(struct net_device *dev); ++bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported); + + /** + * ðtool_ops - Alter and report network device settings +diff --git a/include/linux/pci.h b/include/linux/pci.h +index 559d028..6002bca 100644 +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -1002,12 +1002,11 @@ extern bool pcie_ports_auto; + #endif + + #ifndef CONFIG_PCIEASPM +-static inline int pcie_aspm_enabled(void) +-{ +- return 0; +-} ++static inline int pcie_aspm_enabled(void) { return 0; } ++static inline bool pcie_aspm_support_enabled(void) { return false; } + #else + extern int pcie_aspm_enabled(void); ++extern bool pcie_aspm_support_enabled(void); + #endif + + #ifdef CONFIG_PCIEAER +diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h +index 85867dc..bfd36ff 100644 +--- a/include/scsi/scsi_device.h ++++ b/include/scsi/scsi_device.h +@@ -461,7 +461,7 @@ static inline int scsi_device_qas(struct scsi_device *sdev) + } + static inline int scsi_device_enclosure(struct scsi_device *sdev) + { +- return sdev->inquiry[6] & (1<<6); ++ return sdev->inquiry ? (sdev->inquiry[6] & (1<<6)) : 1; + } + + static inline int scsi_device_protection(struct scsi_device *sdev) +diff --git a/include/sound/pcm.h b/include/sound/pcm.h +index e731f8d..ec26781 100644 +--- a/include/sound/pcm.h ++++ b/include/sound/pcm.h +@@ -1030,9 +1030,7 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s + #define snd_pcm_lib_mmap_iomem NULL + #endif + +-int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream, +- struct vm_area_struct *area); +-#define snd_pcm_lib_mmap_vmalloc snd_pcm_lib_mmap_noncached ++#define snd_pcm_lib_mmap_vmalloc NULL + + static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) + { +diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h +index 8031769..60f94fb 100644 +--- a/include/sound/soc-dapm.h ++++ b/include/sound/soc-dapm.h +@@ -45,25 +45,25 @@ + /* platform domain */ + #define SND_SOC_DAPM_INPUT(wname) \ + { .id = snd_soc_dapm_input, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0} ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM } + #define SND_SOC_DAPM_OUTPUT(wname) \ + { .id = snd_soc_dapm_output, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0} ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM } + #define SND_SOC_DAPM_MIC(wname, wevent) \ + { .id = snd_soc_dapm_mic, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0, .event = wevent, \ ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ + .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD} + #define SND_SOC_DAPM_HP(wname, wevent) \ + { .id = snd_soc_dapm_hp, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0, .event = wevent, \ ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ + .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} + #define SND_SOC_DAPM_SPK(wname, wevent) \ + { .id = snd_soc_dapm_spk, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0, .event = wevent, \ ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ + .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} + #define SND_SOC_DAPM_LINE(wname, wevent) \ + { .id = snd_soc_dapm_line, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0, .event = wevent, \ ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ + .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD} + + /* path domain */ +@@ -177,11 +177,11 @@ + /* events that are pre and post DAPM */ + #define SND_SOC_DAPM_PRE(wname, wevent) \ + { .id = snd_soc_dapm_pre, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0, .event = wevent, \ ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ + .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD} + #define SND_SOC_DAPM_POST(wname, wevent) \ + { .id = snd_soc_dapm_post, .name = wname, .kcontrols = NULL, \ +- .num_kcontrols = 0, .event = wevent, \ ++ .num_kcontrols = 0, .reg = SND_SOC_NOPM, .event = wevent, \ + .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD} + + /* stream domain */ +diff --git a/kernel/perf_event.c b/kernel/perf_event.c +index ad02fea..b2536bd 100644 +--- a/kernel/perf_event.c ++++ b/kernel/perf_event.c +@@ -62,7 +62,8 @@ static struct srcu_struct pmus_srcu; + */ + int sysctl_perf_event_paranoid __read_mostly = 1; + +-int sysctl_perf_event_mlock __read_mostly = 512; /* 'free' kb per user */ ++/* Minimum for 512 kiB + 1 user control page */ ++int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */ + + /* + * max perf event sample rate +@@ -5916,6 +5917,11 @@ SYSCALL_DEFINE5(perf_event_open, + goto err_alloc; + } + ++ if (task) { ++ put_task_struct(task); ++ task = NULL; ++ } ++ + /* + * Look up the group leader (we will attach this event to it): + */ +diff --git a/kernel/signal.c b/kernel/signal.c +index 3175186..bf11d269 100644 +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -2423,7 +2423,7 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig, + /* Not even root can pretend to send signals from the kernel. + * Nor can they impersonate a kill()/tgkill(), which adds source info. + */ +- if (info.si_code != SI_QUEUE) { ++ if (info.si_code >= 0 || info.si_code == SI_TKILL) { + /* We used to allow any < 0 si_code */ + WARN_ON_ONCE(info.si_code < 0); + return -EPERM; +@@ -2443,7 +2443,7 @@ long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info) + /* Not even root can pretend to send signals from the kernel. + * Nor can they impersonate a kill()/tgkill(), which adds source info. + */ +- if (info->si_code != SI_QUEUE) { ++ if (info->si_code >= 0 || info->si_code == SI_TKILL) { + /* We used to allow any < 0 si_code */ + WARN_ON_ONCE(info->si_code < 0); + return -EPERM; +diff --git a/mm/mremap.c b/mm/mremap.c +index 1de98d4..a7c1f9f 100644 +--- a/mm/mremap.c ++++ b/mm/mremap.c +@@ -277,9 +277,16 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr, + if (old_len > vma->vm_end - addr) + goto Efault; + +- if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) { +- if (new_len > old_len) ++ /* Need to be careful about a growing mapping */ ++ if (new_len > old_len) { ++ unsigned long pgoff; ++ ++ if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) + goto Efault; ++ pgoff = (addr - vma->vm_start) >> PAGE_SHIFT; ++ pgoff += vma->vm_pgoff; ++ if (pgoff + (new_len >> PAGE_SHIFT) < pgoff) ++ goto Einval; + } + + if (vma->vm_flags & VM_LOCKED) { +diff --git a/net/atm/common.c b/net/atm/common.c +index 1b9c52a..22b963d 100644 +--- a/net/atm/common.c ++++ b/net/atm/common.c +@@ -252,6 +252,7 @@ void atm_dev_release_vccs(struct atm_dev *dev) + } + write_unlock_irq(&vcc_sklist_lock); + } ++EXPORT_SYMBOL(atm_dev_release_vccs); + + static int adjust_tp(struct atm_trafprm *tp, unsigned char aal) + { +diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c +index 2862f53..d935da7 100644 +--- a/net/bluetooth/bnep/sock.c ++++ b/net/bluetooth/bnep/sock.c +@@ -88,6 +88,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long + sockfd_put(nsock); + return -EBADFD; + } ++ ca.device[sizeof(ca.device)-1] = 0; + + err = bnep_add_connection(&ca, nsock); + if (!err) { +diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c +index 960c6d1..926ed39 100644 +--- a/net/bluetooth/sco.c ++++ b/net/bluetooth/sco.c +@@ -703,6 +703,7 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user + break; + } + ++ memset(&cinfo, 0, sizeof(cinfo)); + cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle; + memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3); + +diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c +index 16df053..47acf4a 100644 +--- a/net/bridge/netfilter/ebtables.c ++++ b/net/bridge/netfilter/ebtables.c +@@ -1107,6 +1107,8 @@ static int do_replace(struct net *net, const void __user *user, + if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter)) + return -ENOMEM; + ++ tmp.name[sizeof(tmp.name) - 1] = 0; ++ + countersize = COUNTER_OFFSET(tmp.nentries) * nr_cpu_ids; + newinfo = vmalloc(sizeof(*newinfo) + countersize); + if (!newinfo) +diff --git a/net/core/ethtool.c b/net/core/ethtool.c +index ff23029..6c7c610 100644 +--- a/net/core/ethtool.c ++++ b/net/core/ethtool.c +@@ -146,9 +146,24 @@ u32 ethtool_op_get_flags(struct net_device *dev) + } + EXPORT_SYMBOL(ethtool_op_get_flags); + ++/* Check if device can enable (or disable) particular feature coded in "data" ++ * argument. Flags "supported" describe features that can be toggled by device. ++ * If feature can not be toggled, it state (enabled or disabled) must match ++ * hardcoded device features state, otherwise flags are marked as invalid. ++ */ ++bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported) ++{ ++ u32 features = dev->features & flags_dup_features; ++ /* "data" can contain only flags_dup_features bits, ++ * see __ethtool_set_flags */ ++ ++ return (features & ~supported) != (data & ~supported); ++} ++EXPORT_SYMBOL(ethtool_invalid_flags); ++ + int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported) + { +- if (data & ~supported) ++ if (ethtool_invalid_flags(dev, data, supported)) + return -EINVAL; + + dev->features = ((dev->features & ~flags_dup_features) | +diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c +index 0c28263..116d3fd 100644 +--- a/net/econet/af_econet.c ++++ b/net/econet/af_econet.c +@@ -435,10 +435,10 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, + udpdest.sin_addr.s_addr = htonl(network | addr.station); + } + ++ memset(&ah, 0, sizeof(ah)); + ah.port = port; + ah.cb = cb & 0x7f; + ah.code = 2; /* magic */ +- ah.pad = 0; + + /* tack our header on the front of the iovec */ + size = sizeof(struct aunhdr); +diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c +index e855fff..6d79aa1 100644 +--- a/net/ipv4/netfilter/arp_tables.c ++++ b/net/ipv4/netfilter/arp_tables.c +@@ -1065,6 +1065,7 @@ static int do_replace(struct net *net, const void __user *user, + /* overflow check */ + if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) + return -ENOMEM; ++ tmp.name[sizeof(tmp.name)-1] = 0; + + newinfo = xt_alloc_table_info(tmp.size); + if (!newinfo) +@@ -1486,6 +1487,7 @@ static int compat_do_replace(struct net *net, void __user *user, + return -ENOMEM; + if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) + return -ENOMEM; ++ tmp.name[sizeof(tmp.name)-1] = 0; + + newinfo = xt_alloc_table_info(tmp.size); + if (!newinfo) +@@ -1738,6 +1740,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len + ret = -EFAULT; + break; + } ++ rev.name[sizeof(rev.name)-1] = 0; + + try_then_request_module(xt_find_revision(NFPROTO_ARP, rev.name, + rev.revision, 1, &ret), +diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c +index 652efea..92fb4c5 100644 +--- a/net/ipv4/netfilter/ip_tables.c ++++ b/net/ipv4/netfilter/ip_tables.c +@@ -387,7 +387,7 @@ ipt_do_table(struct sk_buff *skb, + verdict = (unsigned)(-v) - 1; + break; + } +- if (*stackptr == 0) { ++ if (*stackptr <= origptr) { + e = get_entry(table_base, + private->underflow[hook]); + pr_debug("Underflow (this is normal) " +@@ -427,10 +427,10 @@ ipt_do_table(struct sk_buff *skb, + /* Verdict */ + break; + } while (!acpar.hotdrop); +- xt_info_rdunlock_bh(); + pr_debug("Exiting %s; resetting sp from %u to %u\n", + __func__, *stackptr, origptr); + *stackptr = origptr; ++ xt_info_rdunlock_bh(); + #ifdef DEBUG_ALLOW_ALL + return NF_ACCEPT; + #else +@@ -1261,6 +1261,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len) + /* overflow check */ + if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) + return -ENOMEM; ++ tmp.name[sizeof(tmp.name)-1] = 0; + + newinfo = xt_alloc_table_info(tmp.size); + if (!newinfo) +@@ -1805,6 +1806,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len) + return -ENOMEM; + if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) + return -ENOMEM; ++ tmp.name[sizeof(tmp.name)-1] = 0; + + newinfo = xt_alloc_table_info(tmp.size); + if (!newinfo) +@@ -2034,6 +2036,7 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) + ret = -EFAULT; + break; + } ++ rev.name[sizeof(rev.name)-1] = 0; + + if (cmd == IPT_SO_GET_REVISION_TARGET) + target = 1; +diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c +index 1e26a48..af7dec6 100644 +--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c ++++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c +@@ -669,8 +669,11 @@ static ssize_t clusterip_proc_write(struct file *file, const char __user *input, + char buffer[PROC_WRITELEN+1]; + unsigned long nodenum; + +- if (copy_from_user(buffer, input, PROC_WRITELEN)) ++ if (size > PROC_WRITELEN) ++ return -EIO; ++ if (copy_from_user(buffer, input, size)) + return -EFAULT; ++ buffer[size] = 0; + + if (*buffer == '+') { + nodenum = simple_strtoul(buffer+1, NULL, 10); +diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c +index 7d227c6..eadafbf 100644 +--- a/net/ipv6/netfilter/ip6_tables.c ++++ b/net/ipv6/netfilter/ip6_tables.c +@@ -410,7 +410,7 @@ ip6t_do_table(struct sk_buff *skb, + verdict = (unsigned)(-v) - 1; + break; + } +- if (*stackptr == 0) ++ if (*stackptr <= origptr) + e = get_entry(table_base, + private->underflow[hook]); + else +@@ -441,8 +441,8 @@ ip6t_do_table(struct sk_buff *skb, + break; + } while (!acpar.hotdrop); + +- xt_info_rdunlock_bh(); + *stackptr = origptr; ++ xt_info_rdunlock_bh(); + + #ifdef DEBUG_ALLOW_ALL + return NF_ACCEPT; +@@ -1274,6 +1274,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len) + /* overflow check */ + if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) + return -ENOMEM; ++ tmp.name[sizeof(tmp.name)-1] = 0; + + newinfo = xt_alloc_table_info(tmp.size); + if (!newinfo) +@@ -1820,6 +1821,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len) + return -ENOMEM; + if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) + return -ENOMEM; ++ tmp.name[sizeof(tmp.name)-1] = 0; + + newinfo = xt_alloc_table_info(tmp.size); + if (!newinfo) +@@ -2049,6 +2051,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) + ret = -EFAULT; + break; + } ++ rev.name[sizeof(rev.name)-1] = 0; + + if (cmd == IP6T_SO_GET_REVISION_TARGET) + target = 1; +diff --git a/net/irda/iriap.c b/net/irda/iriap.c +index 5b743bd..3647753 100644 +--- a/net/irda/iriap.c ++++ b/net/irda/iriap.c +@@ -656,10 +656,16 @@ static void iriap_getvaluebyclass_indication(struct iriap_cb *self, + n = 1; + + name_len = fp[n++]; ++ ++ IRDA_ASSERT(name_len < IAS_MAX_CLASSNAME + 1, return;); ++ + memcpy(name, fp+n, name_len); n+=name_len; + name[name_len] = '\0'; + + attr_len = fp[n++]; ++ ++ IRDA_ASSERT(attr_len < IAS_MAX_ATTRIBNAME + 1, return;); ++ + memcpy(attr, fp+n, attr_len); n+=attr_len; + attr[attr_len] = '\0'; + +diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c +index 7c567b8..2bb2beb 100644 +--- a/net/irda/irnet/irnet_ppp.c ++++ b/net/irda/irnet/irnet_ppp.c +@@ -105,6 +105,9 @@ irnet_ctrl_write(irnet_socket * ap, + while(isspace(start[length - 1])) + length--; + ++ DABORT(length < 5 || length > NICKNAME_MAX_LEN + 5, ++ -EINVAL, CTRL_ERROR, "Invalid nickname.\n"); ++ + /* Copy the name for later reuse */ + memcpy(ap->rname, start + 5, length - 5); + ap->rname[length - 5] = '\0'; +diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c +index 165a451..cac35ff 100644 +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -639,18 +639,14 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, + struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; + struct ieee80211_local *local = hw_to_local(mp->hw); + u16 sta_cap = sta->ht_cap.cap; ++ int n_supported = 0; + int ack_dur; + int stbc; + int i; + + /* fall back to the old minstrel for legacy stations */ +- if (!sta->ht_cap.ht_supported) { +- msp->is_ht = false; +- memset(&msp->legacy, 0, sizeof(msp->legacy)); +- msp->legacy.r = msp->ratelist; +- msp->legacy.sample_table = msp->sample_table; +- return mac80211_minstrel.rate_init(priv, sband, sta, &msp->legacy); +- } ++ if (!sta->ht_cap.ht_supported) ++ goto use_legacy; + + BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != + MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS); +@@ -705,7 +701,22 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, + + mi->groups[i].supported = + mcs->rx_mask[minstrel_mcs_groups[i].streams - 1]; ++ ++ if (mi->groups[i].supported) ++ n_supported++; + } ++ ++ if (!n_supported) ++ goto use_legacy; ++ ++ return; ++ ++use_legacy: ++ msp->is_ht = false; ++ memset(&msp->legacy, 0, sizeof(msp->legacy)); ++ msp->legacy.r = msp->ratelist; ++ msp->legacy.sample_table = msp->sample_table; ++ return mac80211_minstrel.rate_init(priv, sband, sta, &msp->legacy); + } + + static void +diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c +index c426504..604216e 100644 +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -243,6 +243,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, + memcpy(sta->sta.addr, addr, ETH_ALEN); + sta->local = local; + sta->sdata = sdata; ++ sta->last_rx = jiffies; + + ewma_init(&sta->avg_signal, 1024, 8); + +diff --git a/net/netfilter/nf_conntrack_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c +index 8678823..bcd5ed6 100644 +--- a/net/netfilter/nf_conntrack_h323_asn1.c ++++ b/net/netfilter/nf_conntrack_h323_asn1.c +@@ -631,7 +631,7 @@ static int decode_seqof(bitstr_t *bs, const struct field_t *f, + CHECK_BOUND(bs, 2); + count = *bs->cur++; + count <<= 8; +- count = *bs->cur++; ++ count += *bs->cur++; + break; + case SEMI: + BYTE_ALIGN(bs); +diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c +index 1734abb..174d51c 100644 +--- a/net/rose/rose_subr.c ++++ b/net/rose/rose_subr.c +@@ -290,10 +290,15 @@ static int rose_parse_national(unsigned char *p, struct rose_facilities_struct * + facilities->source_ndigis = 0; + facilities->dest_ndigis = 0; + for (pt = p + 2, lg = 0 ; lg < l ; pt += AX25_ADDR_LEN, lg += AX25_ADDR_LEN) { +- if (pt[6] & AX25_HBIT) ++ if (pt[6] & AX25_HBIT) { ++ if (facilities->dest_ndigis >= ROSE_MAX_DIGIS) ++ return -1; + memcpy(&facilities->dest_digis[facilities->dest_ndigis++], pt, AX25_ADDR_LEN); +- else ++ } else { ++ if (facilities->source_ndigis >= ROSE_MAX_DIGIS) ++ return -1; + memcpy(&facilities->source_digis[facilities->source_ndigis++], pt, AX25_ADDR_LEN); ++ } + } + } + p += l + 2; +@@ -333,6 +338,11 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac + + case 0xC0: + l = p[1]; ++ ++ /* Prevent overflows*/ ++ if (l < 10 || l > 20) ++ return -1; ++ + if (*p == FAC_CCITT_DEST_NSAP) { + memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN); + memcpy(callsign, p + 12, l - 10); +@@ -373,12 +383,16 @@ int rose_parse_facilities(unsigned char *p, + switch (*p) { + case FAC_NATIONAL: /* National */ + len = rose_parse_national(p + 1, facilities, facilities_len - 1); ++ if (len < 0) ++ return 0; + facilities_len -= len + 1; + p += len + 1; + break; + + case FAC_CCITT: /* CCITT */ + len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1); ++ if (len < 0) ++ return 0; + facilities_len -= len + 1; + p += len + 1; + break; +diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c +index f375dec..778e5df 100644 +--- a/net/sunrpc/auth_gss/gss_krb5_mech.c ++++ b/net/sunrpc/auth_gss/gss_krb5_mech.c +@@ -427,7 +427,7 @@ static int + context_derive_keys_rc4(struct krb5_ctx *ctx) + { + struct crypto_hash *hmac; +- static const char sigkeyconstant[] = "signaturekey"; ++ char sigkeyconstant[] = "signaturekey"; + int slen = strlen(sigkeyconstant) + 1; /* include null terminator */ + struct hash_desc desc; + struct scatterlist sg[1]; +diff --git a/sound/core/init.c b/sound/core/init.c +index 3e65da2..a0080aa 100644 +--- a/sound/core/init.c ++++ b/sound/core/init.c +@@ -848,6 +848,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file) + return -ENOMEM; + mfile->file = file; + mfile->disconnected_f_op = NULL; ++ INIT_LIST_HEAD(&mfile->shutdown_list); + spin_lock(&card->files_lock); + if (card->shutdown) { + spin_unlock(&card->files_lock); +@@ -883,6 +884,9 @@ int snd_card_file_remove(struct snd_card *card, struct file *file) + list_for_each_entry(mfile, &card->files_list, list) { + if (mfile->file == file) { + list_del(&mfile->list); ++ spin_lock(&shutdown_lock); ++ list_del(&mfile->shutdown_list); ++ spin_unlock(&shutdown_lock); + if (mfile->disconnected_f_op) + fops_put(mfile->disconnected_f_op); + found = mfile; +diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c +index a82e3756..64449cb 100644 +--- a/sound/core/pcm_lib.c ++++ b/sound/core/pcm_lib.c +@@ -375,6 +375,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, + } + + if (runtime->no_period_wakeup) { ++ snd_pcm_sframes_t xrun_threshold; + /* + * Without regular period interrupts, we have to check + * the elapsed time to detect xruns. +@@ -383,7 +384,8 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, + if (jdelta < runtime->hw_ptr_buffer_jiffies / 2) + goto no_delta_check; + hdelta = jdelta - delta * HZ / runtime->rate; +- while (hdelta > runtime->hw_ptr_buffer_jiffies / 2 + 1) { ++ xrun_threshold = runtime->hw_ptr_buffer_jiffies / 2 + 1; ++ while (hdelta > xrun_threshold) { + delta += runtime->buffer_size; + hw_base += runtime->buffer_size; + if (hw_base >= runtime->boundary) +diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c +index 4be45e7..6848dd9 100644 +--- a/sound/core/pcm_native.c ++++ b/sound/core/pcm_native.c +@@ -3201,15 +3201,6 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, + EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem); + #endif /* SNDRV_PCM_INFO_MMAP */ + +-/* mmap callback with pgprot_noncached */ +-int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream, +- struct vm_area_struct *area) +-{ +- area->vm_page_prot = pgprot_noncached(area->vm_page_prot); +- return snd_pcm_default_mmap(substream, area); +-} +-EXPORT_SYMBOL(snd_pcm_lib_mmap_noncached); +- + /* + * mmap DMA buffer + */ +diff --git a/sound/oss/dev_table.h b/sound/oss/dev_table.h +index b7617be..0199a31 100644 +--- a/sound/oss/dev_table.h ++++ b/sound/oss/dev_table.h +@@ -271,7 +271,7 @@ struct synth_operations + void (*reset) (int dev); + void (*hw_control) (int dev, unsigned char *event); + int (*load_patch) (int dev, int format, const char __user *addr, +- int offs, int count, int pmgr_flag); ++ int count, int pmgr_flag); + void (*aftertouch) (int dev, int voice, int pressure); + void (*controller) (int dev, int voice, int ctrl_num, int value); + void (*panning) (int dev, int voice, int value); +diff --git a/sound/oss/midi_synth.c b/sound/oss/midi_synth.c +index 3c09374..2292c23 100644 +--- a/sound/oss/midi_synth.c ++++ b/sound/oss/midi_synth.c +@@ -476,7 +476,7 @@ EXPORT_SYMBOL(midi_synth_hw_control); + + int + midi_synth_load_patch(int dev, int format, const char __user *addr, +- int offs, int count, int pmgr_flag) ++ int count, int pmgr_flag) + { + int orig_dev = synth_devs[dev]->midi_dev; + +@@ -491,33 +491,29 @@ midi_synth_load_patch(int dev, int format, const char __user *addr, + if (!prefix_cmd(orig_dev, 0xf0)) + return 0; + ++ /* Invalid patch format */ + if (format != SYSEX_PATCH) +- { +-/* printk("MIDI Error: Invalid patch format (key) 0x%x\n", format);*/ + return -EINVAL; +- } ++ ++ /* Patch header too short */ + if (count < hdr_size) +- { +-/* printk("MIDI Error: Patch header too short\n");*/ + return -EINVAL; +- } ++ + count -= hdr_size; + + /* +- * Copy the header from user space but ignore the first bytes which have +- * been transferred already. ++ * Copy the header from user space + */ + +- if(copy_from_user(&((char *) &sysex)[offs], &(addr)[offs], hdr_size - offs)) ++ if (copy_from_user(&sysex, addr, hdr_size)) + return -EFAULT; +- +- if (count < sysex.len) +- { +-/* printk(KERN_WARNING "MIDI Warning: Sysex record too short (%d<%d)\n", count, (int) sysex.len);*/ ++ ++ /* Sysex record too short */ ++ if ((unsigned)count < (unsigned)sysex.len) + sysex.len = count; +- } +- left = sysex.len; +- src_offs = 0; ++ ++ left = sysex.len; ++ src_offs = 0; + + for (i = 0; i < left && !signal_pending(current); i++) + { +diff --git a/sound/oss/midi_synth.h b/sound/oss/midi_synth.h +index 6bc9d00..b64ddd6 100644 +--- a/sound/oss/midi_synth.h ++++ b/sound/oss/midi_synth.h +@@ -8,7 +8,7 @@ int midi_synth_open (int dev, int mode); + void midi_synth_close (int dev); + void midi_synth_hw_control (int dev, unsigned char *event); + int midi_synth_load_patch (int dev, int format, const char __user * addr, +- int offs, int count, int pmgr_flag); ++ int count, int pmgr_flag); + void midi_synth_panning (int dev, int channel, int pressure); + void midi_synth_aftertouch (int dev, int channel, int pressure); + void midi_synth_controller (int dev, int channel, int ctrl_num, int value); +diff --git a/sound/oss/opl3.c b/sound/oss/opl3.c +index 938c48c..407cd67 100644 +--- a/sound/oss/opl3.c ++++ b/sound/oss/opl3.c +@@ -820,7 +820,7 @@ static void opl3_hw_control(int dev, unsigned char *event) + } + + static int opl3_load_patch(int dev, int format, const char __user *addr, +- int offs, int count, int pmgr_flag) ++ int count, int pmgr_flag) + { + struct sbi_instrument ins; + +@@ -830,11 +830,7 @@ static int opl3_load_patch(int dev, int format, const char __user *addr, + return -EINVAL; + } + +- /* +- * What the fuck is going on here? We leave junk in the beginning +- * of ins and then check the field pretty close to that beginning? +- */ +- if(copy_from_user(&((char *) &ins)[offs], addr + offs, sizeof(ins) - offs)) ++ if (copy_from_user(&ins, addr, sizeof(ins))) + return -EFAULT; + + if (ins.channel < 0 || ins.channel >= SBFM_MAXINSTR) +@@ -849,6 +845,10 @@ static int opl3_load_patch(int dev, int format, const char __user *addr, + + static void opl3_panning(int dev, int voice, int value) + { ++ ++ if (voice < 0 || voice >= devc->nr_voice) ++ return; ++ + devc->voc[voice].panning = value; + } + +@@ -1066,8 +1066,15 @@ static int opl3_alloc_voice(int dev, int chn, int note, struct voice_alloc_info + + static void opl3_setup_voice(int dev, int voice, int chn) + { +- struct channel_info *info = +- &synth_devs[dev]->chn_info[chn]; ++ struct channel_info *info; ++ ++ if (voice < 0 || voice >= devc->nr_voice) ++ return; ++ ++ if (chn < 0 || chn > 15) ++ return; ++ ++ info = &synth_devs[dev]->chn_info[chn]; + + opl3_set_instr(dev, voice, info->pgm_num); + +diff --git a/sound/oss/sequencer.c b/sound/oss/sequencer.c +index 5ea1098..30bcfe4 100644 +--- a/sound/oss/sequencer.c ++++ b/sound/oss/sequencer.c +@@ -241,7 +241,7 @@ int sequencer_write(int dev, struct file *file, const char __user *buf, int coun + return -ENXIO; + + fmt = (*(short *) &event_rec[0]) & 0xffff; +- err = synth_devs[dev]->load_patch(dev, fmt, buf, p + 4, c, 0); ++ err = synth_devs[dev]->load_patch(dev, fmt, buf + p, c, 0); + if (err < 0) + return err; + +diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c +index 537cfba..863eafe 100644 +--- a/sound/pci/ens1370.c ++++ b/sound/pci/ens1370.c +@@ -229,6 +229,7 @@ MODULE_PARM_DESC(lineio, "Line In to Rear Out (0 = auto, 1 = force)."); + #define ES_REG_1371_CODEC 0x14 /* W/R: Codec Read/Write register address */ + #define ES_1371_CODEC_RDY (1<<31) /* codec ready */ + #define ES_1371_CODEC_WIP (1<<30) /* codec register access in progress */ ++#define EV_1938_CODEC_MAGIC (1<<26) + #define ES_1371_CODEC_PIRD (1<<23) /* codec read/write select register */ + #define ES_1371_CODEC_WRITE(a,d) ((((a)&0x7f)<<16)|(((d)&0xffff)<<0)) + #define ES_1371_CODEC_READS(a) ((((a)&0x7f)<<16)|ES_1371_CODEC_PIRD) +@@ -603,12 +604,18 @@ static void snd_es1370_codec_write(struct snd_ak4531 *ak4531, + + #ifdef CHIP1371 + ++static inline bool is_ev1938(struct ensoniq *ensoniq) ++{ ++ return ensoniq->pci->device == 0x8938; ++} ++ + static void snd_es1371_codec_write(struct snd_ac97 *ac97, + unsigned short reg, unsigned short val) + { + struct ensoniq *ensoniq = ac97->private_data; +- unsigned int t, x; ++ unsigned int t, x, flag; + ++ flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0; + mutex_lock(&ensoniq->src_mutex); + for (t = 0; t < POLL_COUNT; t++) { + if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { +@@ -630,7 +637,8 @@ static void snd_es1371_codec_write(struct snd_ac97 *ac97, + 0x00010000) + break; + } +- outl(ES_1371_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1371_CODEC)); ++ outl(ES_1371_CODEC_WRITE(reg, val) | flag, ++ ES_REG(ensoniq, 1371_CODEC)); + /* restore SRC reg */ + snd_es1371_wait_src_ready(ensoniq); + outl(x, ES_REG(ensoniq, 1371_SMPRATE)); +@@ -647,8 +655,9 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, + unsigned short reg) + { + struct ensoniq *ensoniq = ac97->private_data; +- unsigned int t, x, fail = 0; ++ unsigned int t, x, flag, fail = 0; + ++ flag = is_ev1938(ensoniq) ? EV_1938_CODEC_MAGIC : 0; + __again: + mutex_lock(&ensoniq->src_mutex); + for (t = 0; t < POLL_COUNT; t++) { +@@ -671,7 +680,8 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, + 0x00010000) + break; + } +- outl(ES_1371_CODEC_READS(reg), ES_REG(ensoniq, 1371_CODEC)); ++ outl(ES_1371_CODEC_READS(reg) | flag, ++ ES_REG(ensoniq, 1371_CODEC)); + /* restore SRC reg */ + snd_es1371_wait_src_ready(ensoniq); + outl(x, ES_REG(ensoniq, 1371_SMPRATE)); +@@ -683,6 +693,11 @@ static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, + /* now wait for the stinkin' data (RDY) */ + for (t = 0; t < POLL_COUNT; t++) { + if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) { ++ if (is_ev1938(ensoniq)) { ++ for (t = 0; t < 100; t++) ++ inl(ES_REG(ensoniq, CONTROL)); ++ x = inl(ES_REG(ensoniq, 1371_CODEC)); ++ } + mutex_unlock(&ensoniq->src_mutex); + return ES_1371_CODEC_READ(x); + } +diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c +index 8dabab7..7aee900 100644 +--- a/sound/pci/hda/patch_analog.c ++++ b/sound/pci/hda/patch_analog.c +@@ -4353,6 +4353,84 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec) + } + + /* ++ * Precision R5500 ++ * 0x12 - HP/line-out ++ * 0x13 - speaker (mono) ++ * 0x15 - mic-in ++ */ ++ ++static struct hda_verb ad1984a_precision_verbs[] = { ++ /* Unmute main output path */ ++ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ ++ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */ ++ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */ ++ /* Analog mixer; mute as default */ ++ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, ++ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, ++ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, ++ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, ++ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, ++ /* Select mic as input */ ++ {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, ++ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */ ++ /* Configure as mic */ ++ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, ++ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ ++ /* HP unmute */ ++ {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, ++ /* turn on EAPD */ ++ {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, ++ /* unsolicited event for pin-sense */ ++ {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, ++ { } /* end */ ++}; ++ ++static struct snd_kcontrol_new ad1984a_precision_mixers[] = { ++ HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), ++ HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), ++ HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), ++ HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), ++ HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), ++ HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), ++ HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT), ++ HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), ++ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT), ++ HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), ++ HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), ++ { } /* end */ ++}; ++ ++ ++/* mute internal speaker if HP is plugged */ ++static void ad1984a_precision_automute(struct hda_codec *codec) ++{ ++ unsigned int present; ++ ++ present = snd_hda_jack_detect(codec, 0x12); ++ snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0, ++ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); ++} ++ ++ ++/* unsolicited event for HP jack sensing */ ++static void ad1984a_precision_unsol_event(struct hda_codec *codec, ++ unsigned int res) ++{ ++ if ((res >> 26) != AD1884A_HP_EVENT) ++ return; ++ ad1984a_precision_automute(codec); ++} ++ ++/* initialize jack-sensing, too */ ++static int ad1984a_precision_init(struct hda_codec *codec) ++{ ++ ad198x_init(codec); ++ ad1984a_precision_automute(codec); ++ return 0; ++} ++ ++ ++/* + * HP Touchsmart + * port-A (0x11) - front hp-out + * port-B (0x14) - unused +@@ -4481,6 +4559,7 @@ enum { + AD1884A_MOBILE, + AD1884A_THINKPAD, + AD1984A_TOUCHSMART, ++ AD1984A_PRECISION, + AD1884A_MODELS + }; + +@@ -4490,9 +4569,11 @@ static const char * const ad1884a_models[AD1884A_MODELS] = { + [AD1884A_MOBILE] = "mobile", + [AD1884A_THINKPAD] = "thinkpad", + [AD1984A_TOUCHSMART] = "touchsmart", ++ [AD1984A_PRECISION] = "precision", + }; + + static struct snd_pci_quirk ad1884a_cfg_tbl[] = { ++ SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION), + SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), + SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), + SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), +@@ -4586,6 +4667,14 @@ static int patch_ad1884a(struct hda_codec *codec) + codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; + codec->patch_ops.init = ad1984a_thinkpad_init; + break; ++ case AD1984A_PRECISION: ++ spec->mixers[0] = ad1984a_precision_mixers; ++ spec->init_verbs[spec->num_init_verbs++] = ++ ad1984a_precision_verbs; ++ spec->multiout.dig_out_nid = 0; ++ codec->patch_ops.unsol_event = ad1984a_precision_unsol_event; ++ codec->patch_ops.init = ad1984a_precision_init; ++ break; + case AD1984A_TOUCHSMART: + spec->mixers[0] = ad1984a_touchsmart_mixers; + spec->init_verbs[0] = ad1984a_touchsmart_verbs; +diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c +index 4d5004e..e33d69e 100644 +--- a/sound/pci/hda/patch_conexant.c ++++ b/sound/pci/hda/patch_conexant.c +@@ -3130,6 +3130,8 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), + SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), + SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), ++ SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), ++ SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), + SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), + SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */ + {} +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index ec0fa2d..520f94a 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -1276,6 +1276,39 @@ static int simple_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + stream_tag, format, substream); + } + ++static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec, ++ int channels) ++{ ++ unsigned int chanmask; ++ int chan = channels ? (channels - 1) : 1; ++ ++ switch (channels) { ++ default: ++ case 0: ++ case 2: ++ chanmask = 0x00; ++ break; ++ case 4: ++ chanmask = 0x08; ++ break; ++ case 6: ++ chanmask = 0x0b; ++ break; ++ case 8: ++ chanmask = 0x13; ++ break; ++ } ++ ++ /* Set the audio infoframe channel allocation and checksum fields. The ++ * channel count is computed implicitly by the hardware. */ ++ snd_hda_codec_write(codec, 0x1, 0, ++ Nv_VERB_SET_Channel_Allocation, chanmask); ++ ++ snd_hda_codec_write(codec, 0x1, 0, ++ Nv_VERB_SET_Info_Frame_Checksum, ++ (0x71 - chan - chanmask)); ++} ++ + static int nvhdmi_8ch_7x_pcm_close(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +@@ -1294,6 +1327,10 @@ static int nvhdmi_8ch_7x_pcm_close(struct hda_pcm_stream *hinfo, + AC_VERB_SET_STREAM_FORMAT, 0); + } + ++ /* The audio hardware sends a channel count of 0x7 (8ch) when all the ++ * streams are disabled. */ ++ nvhdmi_8ch_7x_set_info_frame_parameters(codec, 8); ++ + return snd_hda_multi_out_dig_close(codec, &spec->multiout); + } + +@@ -1304,37 +1341,16 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, + struct snd_pcm_substream *substream) + { + int chs; +- unsigned int dataDCC1, dataDCC2, chan, chanmask, channel_id; ++ unsigned int dataDCC1, dataDCC2, channel_id; + int i; + + mutex_lock(&codec->spdif_mutex); + + chs = substream->runtime->channels; +- chan = chs ? (chs - 1) : 1; + +- switch (chs) { +- default: +- case 0: +- case 2: +- chanmask = 0x00; +- break; +- case 4: +- chanmask = 0x08; +- break; +- case 6: +- chanmask = 0x0b; +- break; +- case 8: +- chanmask = 0x13; +- break; +- } + dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT; + dataDCC2 = 0x2; + +- /* set the Audio InforFrame Channel Allocation */ +- snd_hda_codec_write(codec, 0x1, 0, +- Nv_VERB_SET_Channel_Allocation, chanmask); +- + /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ + if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) + snd_hda_codec_write(codec, +@@ -1409,10 +1425,7 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, + } + } + +- /* set the Audio Info Frame Checksum */ +- snd_hda_codec_write(codec, 0x1, 0, +- Nv_VERB_SET_Info_Frame_Checksum, +- (0x71 - chan - chanmask)); ++ nvhdmi_8ch_7x_set_info_frame_parameters(codec, chs); + + mutex_unlock(&codec->spdif_mutex); + return 0; +@@ -1508,6 +1521,11 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) + spec->multiout.max_channels = 8; + spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x; + codec->patch_ops = nvhdmi_patch_ops_8ch_7x; ++ ++ /* Initialize the audio infoframe channel mask and checksum to something ++ * valid */ ++ nvhdmi_8ch_7x_set_info_frame_parameters(codec, 8); ++ + return 0; + } + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index c2eb6a7..e164a4b 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -1360,7 +1360,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) + case 0x10ec0883: + case 0x10ec0885: + case 0x10ec0887: +- case 0x10ec0889: ++ /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ + alc889_coef_init(codec); + break; + case 0x10ec0888: +@@ -14191,7 +14191,7 @@ static hda_nid_t alc269vb_capsrc_nids[1] = { + }; + + static hda_nid_t alc269_adc_candidates[] = { +- 0x08, 0x09, 0x07, ++ 0x08, 0x09, 0x07, 0x11, + }; + + #define alc269_modes alc260_modes +diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c +index 671ef8d..aab7765 100644 +--- a/sound/soc/imx/imx-pcm-dma-mx2.c ++++ b/sound/soc/imx/imx-pcm-dma-mx2.c +@@ -110,12 +110,12 @@ static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream, + slave_config.direction = DMA_TO_DEVICE; + slave_config.dst_addr = dma_params->dma_addr; + slave_config.dst_addr_width = buswidth; +- slave_config.dst_maxburst = dma_params->burstsize; ++ slave_config.dst_maxburst = dma_params->burstsize * buswidth; + } else { + slave_config.direction = DMA_FROM_DEVICE; + slave_config.src_addr = dma_params->dma_addr; + slave_config.src_addr_width = buswidth; +- slave_config.src_maxburst = dma_params->burstsize; ++ slave_config.src_maxburst = dma_params->burstsize * buswidth; + } + + ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config); +@@ -303,6 +303,11 @@ static struct snd_soc_platform_driver imx_soc_platform_mx2 = { + + static int __devinit imx_soc_platform_probe(struct platform_device *pdev) + { ++ struct imx_ssi *ssi = platform_get_drvdata(pdev); ++ ++ ssi->dma_params_tx.burstsize = 6; ++ ssi->dma_params_rx.burstsize = 4; ++ + return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2); + } + +diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h +index a4406a1..dc8a875 100644 +--- a/sound/soc/imx/imx-ssi.h ++++ b/sound/soc/imx/imx-ssi.h +@@ -234,7 +234,4 @@ void imx_pcm_free(struct snd_pcm *pcm); + */ + #define IMX_SSI_DMABUF_SIZE (64 * 1024) + +-#define DMA_RXFIFO_BURST 0x4 +-#define DMA_TXFIFO_BURST 0x6 +- + #endif /* _IMX_SSI_H */ +diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c +index 784cff5..9027da4 100644 +--- a/sound/soc/pxa/corgi.c ++++ b/sound/soc/pxa/corgi.c +@@ -310,7 +310,7 @@ static struct snd_soc_dai_link corgi_dai = { + .cpu_dai_name = "pxa2xx-i2s", + .codec_dai_name = "wm8731-hifi", + .platform_name = "pxa-pcm-audio", +- .codec_name = "wm8731-codec-0.001b", ++ .codec_name = "wm8731-codec.0-001b", + .init = corgi_wm8731_init, + .ops = &corgi_ops, + }; diff --git a/debian/patches/series/4 b/debian/patches/series/4 index 8993bc2b8..8f7d03145 100644 --- a/debian/patches/series/4 +++ b/debian/patches/series/4 @@ -1 +1,11 @@ + features/all/ALSA-usb-audio-define-another-USB-ID-for-a-buggy-USB.patch +- bugfix/all/pci-acpi-report-aspm-support-to-bios-if-not-disabled-from-command-line.patch +- bugfix/all/ses-avoid-kernel-panic-when-lun-0-is-not-mapped.patch +- bugfix/all/ath9k-fix-kernel-panic-in-ar2427.patch +- bugfix/all/cciss-fix-lost-command-issue.patch +- bugfix/all/alsa-fix-yet-another-race-in-disconnection.patch +- bugfix/x86/Save-cr4-to-mmu_cr4_features-at-boot-time.patch +- bugfix/all/radeon-add-sanity-checks-to-obj-info-record-parsing.patch +- bugfix/all/scsi-iscsi-world-writable-sysfs-priv_sess-file.patch +- bugfix/all/rtc-rtc-ds1511-world-writable-sysfs-nvram-file.patch ++ bugfix/all/stable/2.6.38.3.patch