diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2011-12-25 16:53:44 -0500 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2011-12-25 16:53:44 -0500 |
commit | 581ff55f4dea2e36cc091c833958eccfa4975fd3 (patch) | |
tree | fcf9111ce9684267b2de3f3dcd8eaba703ff62c2 | |
parent | Grsec/PaX: 2.6.32.51-201112222105 + 3.1.6-201112222105 (diff) | |
download | hardened-patchset-581ff55f4dea2e36cc091c833958eccfa4975fd3.tar.gz hardened-patchset-581ff55f4dea2e36cc091c833958eccfa4975fd3.tar.bz2 hardened-patchset-581ff55f4dea2e36cc091c833958eccfa4975fd3.zip |
Add patch to bump to 3.1.6
-rw-r--r-- | 3.1.6/0000_README | 4 | ||||
-rw-r--r-- | 3.1.6/1005_linux-3.1.6.patch | 2178 |
2 files changed, 2182 insertions, 0 deletions
diff --git a/3.1.6/0000_README b/3.1.6/0000_README index 29427c6..e8dbb91 100644 --- a/3.1.6/0000_README +++ b/3.1.6/0000_README @@ -3,6 +3,10 @@ README Individual Patch Descriptions: ----------------------------------------------------------------------------- +Patch: 1005_linux-3.1.6.patch +From: http://www.kernel.org +Desc: Linux 3.1.6 + Patch: 4420_grsecurity-2.2.2-3.1.6-201112222105.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.1.6/1005_linux-3.1.6.patch b/3.1.6/1005_linux-3.1.6.patch new file mode 100644 index 0000000..afd900d --- /dev/null +++ b/3.1.6/1005_linux-3.1.6.patch @@ -0,0 +1,2178 @@ +diff --git a/Makefile b/Makefile +index 94ab2ad..2d6e0a8 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 1 +-SUBLEVEL = 5 ++SUBLEVEL = 6 + EXTRAVERSION = + NAME = "Divemaster Edition" + +diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c +index e514c76..3e42faf 100644 +--- a/arch/arm/kernel/setup.c ++++ b/arch/arm/kernel/setup.c +@@ -890,6 +890,12 @@ void __init setup_arch(char **cmdline_p) + machine_desc = mdesc; + machine_name = mdesc->name; + ++#ifdef CONFIG_ZONE_DMA ++ if (mdesc->dma_zone_size) { ++ extern unsigned long arm_dma_zone_size; ++ arm_dma_zone_size = mdesc->dma_zone_size; ++ } ++#endif + if (mdesc->soft_reboot) + reboot_setup("s"); + +@@ -920,12 +926,6 @@ void __init setup_arch(char **cmdline_p) + + tcm_init(); + +-#ifdef CONFIG_ZONE_DMA +- if (mdesc->dma_zone_size) { +- extern unsigned long arm_dma_zone_size; +- arm_dma_zone_size = mdesc->dma_zone_size; +- } +-#endif + #ifdef CONFIG_MULTI_IRQ_HANDLER + handle_arch_irq = mdesc->handle_irq; + #endif +diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c +index 7227755..e596f45 100644 +--- a/arch/arm/mach-at91/at91rm9200_devices.c ++++ b/arch/arm/mach-at91/at91rm9200_devices.c +@@ -75,7 +75,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} + * USB Device (Gadget) + * -------------------------------------------------------------------- */ + +-#ifdef CONFIG_USB_GADGET_AT91 ++#ifdef CONFIG_USB_AT91 + static struct at91_udc_data udc_data; + + static struct resource udc_resources[] = { +diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c +index cb397be..de4036f 100644 +--- a/arch/arm/mach-at91/at91sam9260.c ++++ b/arch/arm/mach-at91/at91sam9260.c +@@ -195,9 +195,9 @@ static struct clk_lookup periph_clocks_lookups[] = { + CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), + CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), + CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), +- CLKDEV_CON_DEV_ID("t3_clk", "atmel_tcb.1", &tc3_clk), +- CLKDEV_CON_DEV_ID("t4_clk", "atmel_tcb.1", &tc4_clk), +- CLKDEV_CON_DEV_ID("t5_clk", "atmel_tcb.1", &tc5_clk), ++ CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk), ++ CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), ++ CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), + CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), + }; + +diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c +index 39f81f4..ec257265 100644 +--- a/arch/arm/mach-at91/at91sam9260_devices.c ++++ b/arch/arm/mach-at91/at91sam9260_devices.c +@@ -76,7 +76,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} + * USB Device (Gadget) + * -------------------------------------------------------------------- */ + +-#ifdef CONFIG_USB_GADGET_AT91 ++#ifdef CONFIG_USB_AT91 + static struct at91_udc_data udc_data; + + static struct resource udc_resources[] = { +diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c +index 0f91792..9e113f6 100644 +--- a/arch/arm/mach-at91/at91sam9261_devices.c ++++ b/arch/arm/mach-at91/at91sam9261_devices.c +@@ -79,7 +79,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} + * USB Device (Gadget) + * -------------------------------------------------------------------- */ + +-#ifdef CONFIG_USB_GADGET_AT91 ++#ifdef CONFIG_USB_AT91 + static struct at91_udc_data udc_data; + + static struct resource udc_resources[] = { +diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c +index a050f41..863e466 100644 +--- a/arch/arm/mach-at91/at91sam9263_devices.c ++++ b/arch/arm/mach-at91/at91sam9263_devices.c +@@ -86,7 +86,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} + * USB Device (Gadget) + * -------------------------------------------------------------------- */ + +-#ifdef CONFIG_USB_GADGET_AT91 ++#ifdef CONFIG_USB_AT91 + static struct at91_udc_data udc_data; + + static struct resource udc_resources[] = { +diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c +index 008d514..d5ec333 100644 +--- a/arch/arm/mach-davinci/board-da850-evm.c ++++ b/arch/arm/mach-davinci/board-da850-evm.c +@@ -748,7 +748,7 @@ static struct snd_platform_data da850_evm_snd_data = { + .num_serializer = ARRAY_SIZE(da850_iis_serializer_direction), + .tdm_slots = 2, + .serial_dir = da850_iis_serializer_direction, +- .asp_chan_q = EVENTQ_1, ++ .asp_chan_q = EVENTQ_0, + .version = MCASP_VERSION_2, + .txnumevt = 1, + .rxnumevt = 1, +diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c +index 993a314..1cc11d8 100644 +--- a/arch/arm/mach-davinci/board-dm646x-evm.c ++++ b/arch/arm/mach-davinci/board-dm646x-evm.c +@@ -563,7 +563,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) + int val; + u32 value; + +- if (!vpif_vsclkdis_reg || !cpld_client) ++ if (!vpif_vidclkctl_reg || !cpld_client) + return -ENXIO; + + val = i2c_smbus_read_byte(cpld_client); +@@ -571,7 +571,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) + return val; + + spin_lock_irqsave(&vpif_reg_lock, flags); +- value = __raw_readl(vpif_vsclkdis_reg); ++ value = __raw_readl(vpif_vidclkctl_reg); + if (mux_mode) { + val &= VPIF_INPUT_TWO_CHANNEL; + value |= VIDCH1CLK; +@@ -579,7 +579,7 @@ static int setup_vpif_input_channel_mode(int mux_mode) + val |= VPIF_INPUT_ONE_CHANNEL; + value &= ~VIDCH1CLK; + } +- __raw_writel(value, vpif_vsclkdis_reg); ++ __raw_writel(value, vpif_vidclkctl_reg); + spin_unlock_irqrestore(&vpif_reg_lock, flags); + + err = i2c_smbus_write_byte(cpld_client, val); +diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h +index 35a89dd..1332f73 100644 +--- a/arch/arm/mach-mxs/include/mach/mxs.h ++++ b/arch/arm/mach-mxs/include/mach/mxs.h +@@ -30,6 +30,7 @@ + */ + #define cpu_is_mx23() ( \ + machine_is_mx23evk() || \ ++ machine_is_stmp378x() || \ + 0) + #define cpu_is_mx28() ( \ + machine_is_mx28evk() || \ +diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h +index c2ff2a1..2d2f01c 100644 +--- a/arch/x86/include/asm/system.h ++++ b/arch/x86/include/asm/system.h +@@ -401,6 +401,7 @@ extern unsigned long arch_align_stack(unsigned long sp); + extern void free_init_pages(char *what, unsigned long begin, unsigned long end); + + void default_idle(void); ++bool set_pm_idle_to_default(void); + + void stop_this_cpu(void *dummy); + +diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c +index 4aecc54..4d5a100 100644 +--- a/arch/x86/kernel/hpet.c ++++ b/arch/x86/kernel/hpet.c +@@ -1048,6 +1048,14 @@ int hpet_rtc_timer_init(void) + } + EXPORT_SYMBOL_GPL(hpet_rtc_timer_init); + ++static void hpet_disable_rtc_channel(void) ++{ ++ unsigned long cfg; ++ cfg = hpet_readl(HPET_T1_CFG); ++ cfg &= ~HPET_TN_ENABLE; ++ hpet_writel(cfg, HPET_T1_CFG); ++} ++ + /* + * The functions below are called from rtc driver. + * Return 0 if HPET is not being used. +@@ -1059,6 +1067,9 @@ int hpet_mask_rtc_irq_bit(unsigned long bit_mask) + return 0; + + hpet_rtc_flags &= ~bit_mask; ++ if (unlikely(!hpet_rtc_flags)) ++ hpet_disable_rtc_channel(); ++ + return 1; + } + EXPORT_SYMBOL_GPL(hpet_mask_rtc_irq_bit); +@@ -1124,15 +1135,11 @@ EXPORT_SYMBOL_GPL(hpet_rtc_dropped_irq); + + static void hpet_rtc_timer_reinit(void) + { +- unsigned int cfg, delta; ++ unsigned int delta; + int lost_ints = -1; + +- if (unlikely(!hpet_rtc_flags)) { +- cfg = hpet_readl(HPET_T1_CFG); +- cfg &= ~HPET_TN_ENABLE; +- hpet_writel(cfg, HPET_T1_CFG); +- return; +- } ++ if (unlikely(!hpet_rtc_flags)) ++ hpet_disable_rtc_channel(); + + if (!(hpet_rtc_flags & RTC_PIE) || hpet_pie_limit) + delta = hpet_default_delta; +diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c +index e7e3b01..30eb651 100644 +--- a/arch/x86/kernel/process.c ++++ b/arch/x86/kernel/process.c +@@ -403,6 +403,14 @@ void default_idle(void) + EXPORT_SYMBOL(default_idle); + #endif + ++bool set_pm_idle_to_default(void) ++{ ++ bool ret = !!pm_idle; ++ ++ pm_idle = default_idle; ++ ++ return ret; ++} + void stop_this_cpu(void *dummy) + { + local_irq_disable(); +diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c +index ea30585..dd74e46 100644 +--- a/arch/x86/mm/gup.c ++++ b/arch/x86/mm/gup.c +@@ -201,6 +201,8 @@ static noinline int gup_huge_pud(pud_t pud, unsigned long addr, + do { + VM_BUG_ON(compound_head(page) != head); + pages[*nr] = page; ++ if (PageTail(page)) ++ get_huge_page_tail(page); + (*nr)++; + page++; + refs++; +diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c +index 46d6d21..e191302 100644 +--- a/arch/x86/xen/setup.c ++++ b/arch/x86/xen/setup.c +@@ -191,9 +191,21 @@ static unsigned long __init xen_get_max_pages(void) + domid_t domid = DOMID_SELF; + int ret; + +- ret = HYPERVISOR_memory_op(XENMEM_maximum_reservation, &domid); +- if (ret > 0) +- max_pages = ret; ++ /* ++ * For the initial domain we use the maximum reservation as ++ * the maximum page. ++ * ++ * For guest domains the current maximum reservation reflects ++ * the current maximum rather than the static maximum. In this ++ * case the e820 map provided to us will cover the static ++ * maximum region. ++ */ ++ if (xen_initial_domain()) { ++ ret = HYPERVISOR_memory_op(XENMEM_maximum_reservation, &domid); ++ if (ret > 0) ++ max_pages = ret; ++ } ++ + return min(max_pages, MAX_DOMAIN_PAGES); + } + +@@ -448,6 +460,6 @@ void __init xen_arch_setup(void) + #endif + disable_cpuidle(); + boot_option_idle_override = IDLE_HALT; +- ++ WARN_ON(set_pm_idle_to_default()); + fiddle_vdso(); + } +diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c +index c811cb1..2cce44a 100644 +--- a/drivers/firmware/iscsi_ibft.c ++++ b/drivers/firmware/iscsi_ibft.c +@@ -746,6 +746,37 @@ static void __exit ibft_exit(void) + ibft_cleanup(); + } + ++#ifdef CONFIG_ACPI ++static const struct { ++ char *sign; ++} ibft_signs[] = { ++ /* ++ * One spec says "IBFT", the other says "iBFT". We have to check ++ * for both. ++ */ ++ { ACPI_SIG_IBFT }, ++ { "iBFT" }, ++}; ++ ++static void __init acpi_find_ibft_region(void) ++{ ++ int i; ++ struct acpi_table_header *table = NULL; ++ ++ if (acpi_disabled) ++ return; ++ ++ for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) { ++ acpi_get_table(ibft_signs[i].sign, 0, &table); ++ ibft_addr = (struct acpi_table_ibft *)table; ++ } ++} ++#else ++static void __init acpi_find_ibft_region(void) ++{ ++} ++#endif ++ + /* + * ibft_init() - creates sysfs tree entries for the iBFT data. + */ +@@ -753,9 +784,16 @@ static int __init ibft_init(void) + { + int rc = 0; + ++ /* ++ As on UEFI systems the setup_arch()/find_ibft_region() ++ is called before ACPI tables are parsed and it only does ++ legacy finding. ++ */ ++ if (!ibft_addr) ++ acpi_find_ibft_region(); ++ + if (ibft_addr) { +- printk(KERN_INFO "iBFT detected at 0x%llx.\n", +- (u64)isa_virt_to_bus(ibft_addr)); ++ pr_info("iBFT detected.\n"); + + rc = ibft_check_device(); + if (rc) +diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c +index bfe7232..4da4eb9 100644 +--- a/drivers/firmware/iscsi_ibft_find.c ++++ b/drivers/firmware/iscsi_ibft_find.c +@@ -45,13 +45,6 @@ EXPORT_SYMBOL_GPL(ibft_addr); + static const struct { + char *sign; + } ibft_signs[] = { +-#ifdef CONFIG_ACPI +- /* +- * One spec says "IBFT", the other says "iBFT". We have to check +- * for both. +- */ +- { ACPI_SIG_IBFT }, +-#endif + { "iBFT" }, + { "BIFT" }, /* Broadcom iSCSI Offload */ + }; +@@ -62,14 +55,6 @@ static const struct { + #define VGA_MEM 0xA0000 /* VGA buffer */ + #define VGA_SIZE 0x20000 /* 128kB */ + +-#ifdef CONFIG_ACPI +-static int __init acpi_find_ibft(struct acpi_table_header *header) +-{ +- ibft_addr = (struct acpi_table_ibft *)header; +- return 0; +-} +-#endif /* CONFIG_ACPI */ +- + static int __init find_ibft_in_mem(void) + { + unsigned long pos; +@@ -94,6 +79,7 @@ static int __init find_ibft_in_mem(void) + * the table cannot be valid. */ + if (pos + len <= (IBFT_END-1)) { + ibft_addr = (struct acpi_table_ibft *)virt; ++ pr_info("iBFT found at 0x%lx.\n", pos); + goto done; + } + } +@@ -108,20 +94,12 @@ done: + */ + unsigned long __init find_ibft_region(unsigned long *sizep) + { +-#ifdef CONFIG_ACPI +- int i; +-#endif + ibft_addr = NULL; + +-#ifdef CONFIG_ACPI +- for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++) +- acpi_table_parse(ibft_signs[i].sign, acpi_find_ibft); +-#endif /* CONFIG_ACPI */ +- + /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will + * only use ACPI for this */ + +- if (!ibft_addr && !efi_enabled) ++ if (!efi_enabled) + find_ibft_in_mem(); + + if (ibft_addr) { +diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c +index a515b2a..9bb3d6f 100644 +--- a/drivers/gpu/drm/radeon/atombios_crtc.c ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c +@@ -558,7 +558,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, + bpc = connector->display_info.bpc; + encoder_mode = atombios_get_encoder_mode(encoder); + if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || +- radeon_encoder_is_dp_bridge(encoder)) { ++ (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { + if (connector) { + struct radeon_connector *radeon_connector = to_radeon_connector(connector); + struct radeon_connector_atom_dig *dig_connector = +@@ -638,44 +638,29 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, + if (ss_enabled && ss->percentage) + args.v3.sInput.ucDispPllConfig |= + DISPPLL_CONFIG_SS_ENABLE; +- if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT) || +- radeon_encoder_is_dp_bridge(encoder)) { ++ if (encoder_mode == ATOM_ENCODER_MODE_DP) { ++ args.v3.sInput.ucDispPllConfig |= ++ DISPPLL_CONFIG_COHERENT_MODE; ++ /* 16200 or 27000 */ ++ args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); ++ } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; +- if (encoder_mode == ATOM_ENCODER_MODE_DP) { ++ if (encoder_mode == ATOM_ENCODER_MODE_HDMI) ++ /* deep color support */ ++ args.v3.sInput.usPixelClock = ++ cpu_to_le16((mode->clock * bpc / 8) / 10); ++ if (dig->coherent_mode) + args.v3.sInput.ucDispPllConfig |= + DISPPLL_CONFIG_COHERENT_MODE; +- /* 16200 or 27000 */ +- args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); +- } else { +- if (encoder_mode == ATOM_ENCODER_MODE_HDMI) { +- /* deep color support */ +- args.v3.sInput.usPixelClock = +- cpu_to_le16((mode->clock * bpc / 8) / 10); +- } +- if (dig->coherent_mode) +- args.v3.sInput.ucDispPllConfig |= +- DISPPLL_CONFIG_COHERENT_MODE; +- if (mode->clock > 165000) +- args.v3.sInput.ucDispPllConfig |= +- DISPPLL_CONFIG_DUAL_LINK; +- } +- } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { +- if (encoder_mode == ATOM_ENCODER_MODE_DP) { ++ if (mode->clock > 165000) + args.v3.sInput.ucDispPllConfig |= +- DISPPLL_CONFIG_COHERENT_MODE; +- /* 16200 or 27000 */ +- args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); +- } else if (encoder_mode != ATOM_ENCODER_MODE_LVDS) { +- if (mode->clock > 165000) +- args.v3.sInput.ucDispPllConfig |= +- DISPPLL_CONFIG_DUAL_LINK; +- } ++ DISPPLL_CONFIG_DUAL_LINK; + } +- if (radeon_encoder_is_dp_bridge(encoder)) { +- struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder); +- struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder); +- args.v3.sInput.ucExtTransmitterID = ext_radeon_encoder->encoder_id; +- } else ++ if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ++ ENCODER_OBJECT_ID_NONE) ++ args.v3.sInput.ucExtTransmitterID = ++ radeon_encoder_get_dp_bridge_encoder_id(encoder); ++ else + args.v3.sInput.ucExtTransmitterID = 0; + + atom_execute_table(rdev->mode_info.atom_context, +diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c +index 3b77ad6..03a347a 100644 +--- a/drivers/gpu/drm/radeon/atombios_dp.c ++++ b/drivers/gpu/drm/radeon/atombios_dp.c +@@ -482,7 +482,8 @@ static int radeon_dp_get_dp_link_clock(struct drm_connector *connector, + int bpp = convert_bpc_to_bpp(connector->display_info.bpc); + int lane_num, max_pix_clock; + +- if (radeon_connector_encoder_is_dp_bridge(connector)) ++ if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != ++ ENCODER_OBJECT_ID_NONE) + return 270000; + + lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock); +@@ -559,8 +560,12 @@ static void radeon_dp_set_panel_mode(struct drm_encoder *encoder, + if (!ASIC_IS_DCE4(rdev)) + return; + +- if (radeon_connector_encoder_is_dp_bridge(connector)) ++ if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == ++ ENCODER_OBJECT_ID_NUTMEG) + panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; ++ else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == ++ ENCODER_OBJECT_ID_TRAVIS) ++ panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; + else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { + u8 tmp = radeon_read_dpcd_reg(radeon_connector, DP_EDP_CONFIGURATION_CAP); + if (tmp & 1) +diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c +index ff6a2e0..a58b452 100644 +--- a/drivers/gpu/drm/radeon/radeon_connectors.c ++++ b/drivers/gpu/drm/radeon/radeon_connectors.c +@@ -44,8 +44,6 @@ extern void + radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, + struct drm_connector *drm_connector); + +-bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector); +- + void radeon_connector_hotplug(struct drm_connector *connector) + { + struct drm_device *dev = connector->dev; +@@ -1204,7 +1202,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector) + } + } else { + /* need to setup ddc on the bridge */ +- if (radeon_connector_encoder_is_dp_bridge(connector)) { ++ if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != ++ ENCODER_OBJECT_ID_NONE) { + if (encoder) + radeon_atom_ext_encoder_setup_ddc(encoder); + } +@@ -1214,13 +1213,12 @@ static int radeon_dp_get_modes(struct drm_connector *connector) + return ret; + } + +-bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector) ++u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector) + { + struct drm_mode_object *obj; + struct drm_encoder *encoder; + struct radeon_encoder *radeon_encoder; + int i; +- bool found = false; + + for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { + if (connector->encoder_ids[i] == 0) +@@ -1236,14 +1234,13 @@ bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector) + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_TRAVIS: + case ENCODER_OBJECT_ID_NUTMEG: +- found = true; +- break; ++ return radeon_encoder->encoder_id; + default: + break; + } + } + +- return found; ++ return ENCODER_OBJECT_ID_NONE; + } + + bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector) +@@ -1320,7 +1317,8 @@ radeon_dp_detect(struct drm_connector *connector, bool force) + if (!radeon_dig_connector->edp_on) + atombios_set_edp_panel_power(connector, + ATOM_TRANSMITTER_ACTION_POWER_OFF); +- } else if (radeon_connector_encoder_is_dp_bridge(connector)) { ++ } else if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != ++ ENCODER_OBJECT_ID_NONE) { + /* DP bridges are always DP */ + radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; + /* get the DPCD from the bridge */ +diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c +index 6adb3e5..07ac481 100644 +--- a/drivers/gpu/drm/radeon/radeon_display.c ++++ b/drivers/gpu/drm/radeon/radeon_display.c +@@ -708,7 +708,8 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) + + if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || + (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) || +- radeon_connector_encoder_is_dp_bridge(&radeon_connector->base)) { ++ (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) != ++ ENCODER_OBJECT_ID_NONE)) { + struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; + + if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT || +diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c +index eb3f6dc..9838865 100644 +--- a/drivers/gpu/drm/radeon/radeon_encoders.c ++++ b/drivers/gpu/drm/radeon/radeon_encoders.c +@@ -266,7 +266,7 @@ struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder + return NULL; + } + +-bool radeon_encoder_is_dp_bridge(struct drm_encoder *encoder) ++u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder) + { + struct drm_encoder *other_encoder = radeon_atom_get_external_encoder(encoder); + +@@ -368,7 +368,7 @@ static bool radeon_atom_mode_fixup(struct drm_encoder *encoder, + + if (ASIC_IS_DCE3(rdev) && + ((radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || +- radeon_encoder_is_dp_bridge(encoder))) { ++ (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE))) { + struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + radeon_dp_set_link_config(connector, mode); + } +@@ -658,7 +658,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) + struct radeon_connector_atom_dig *dig_connector; + + /* dp bridges are always DP */ +- if (radeon_encoder_is_dp_bridge(encoder)) ++ if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE) + return ATOM_ENCODER_MODE_DP; + + /* DVO is always DVO */ +@@ -1638,7 +1638,7 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) + break; + case 2: + args.v2.ucCRTC = radeon_crtc->crtc_id; +- if (radeon_encoder_is_dp_bridge(encoder)) { ++ if (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE) { + struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); + + if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) +@@ -2099,7 +2099,8 @@ static void radeon_atom_encoder_prepare(struct drm_encoder *encoder) + + if ((radeon_encoder->active_device & + (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) || +- radeon_encoder_is_dp_bridge(encoder)) { ++ (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ++ ENCODER_OBJECT_ID_NONE)) { + struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; + if (dig) + dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder); +diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h +index ed0178f..cbf80de 100644 +--- a/drivers/gpu/drm/radeon/radeon_mode.h ++++ b/drivers/gpu/drm/radeon/radeon_mode.h +@@ -468,8 +468,8 @@ radeon_atombios_get_tv_info(struct radeon_device *rdev); + extern struct drm_connector * + radeon_get_connector_for_encoder(struct drm_encoder *encoder); + +-extern bool radeon_encoder_is_dp_bridge(struct drm_encoder *encoder); +-extern bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector); ++extern u16 radeon_encoder_get_dp_bridge_encoder_id(struct drm_encoder *encoder); ++extern u16 radeon_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector); + extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector); + extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector); + +diff --git a/drivers/hwmon/jz4740-hwmon.c b/drivers/hwmon/jz4740-hwmon.c +index fea292d..b65a4da 100644 +--- a/drivers/hwmon/jz4740-hwmon.c ++++ b/drivers/hwmon/jz4740-hwmon.c +@@ -59,7 +59,7 @@ static ssize_t jz4740_hwmon_read_adcin(struct device *dev, + { + struct jz4740_hwmon *hwmon = dev_get_drvdata(dev); + struct completion *completion = &hwmon->read_completion; +- unsigned long t; ++ long t; + unsigned long val; + int ret; + +diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c +index 14aa213..b87143d 100644 +--- a/drivers/mmc/host/mxcmmc.c ++++ b/drivers/mmc/host/mxcmmc.c +@@ -731,6 +731,7 @@ static void mxcmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + "failed to config DMA channel. Falling back to PIO\n"); + dma_release_channel(host->dma); + host->do_dma = 0; ++ host->dma = NULL; + } + } + +diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c +index cf3f999..10451a1 100644 +--- a/drivers/ptp/ptp_clock.c ++++ b/drivers/ptp/ptp_clock.c +@@ -101,7 +101,9 @@ static s32 scaled_ppm_to_ppb(long ppm) + + static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp) + { +- return 1; /* always round timer functions to one nanosecond */ ++ tp->tv_sec = 0; ++ tp->tv_nsec = 1; ++ return 0; + } + + static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp) +diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c +index 7639ab9..5b979d9 100644 +--- a/drivers/rtc/rtc-s3c.c ++++ b/drivers/rtc/rtc-s3c.c +@@ -202,7 +202,6 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) + void __iomem *base = s3c_rtc_base; + int year = tm->tm_year - 100; + +- clk_enable(rtc_clk); + pr_debug("set time %04d.%02d.%02d %02d:%02d:%02d\n", + 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); +@@ -214,6 +213,7 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm) + return -EINVAL; + } + ++ clk_enable(rtc_clk); + writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC); + writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN); + writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR); +diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c +index 21ce2af..6cb7e28 100644 +--- a/drivers/staging/rtl8712/usb_intf.c ++++ b/drivers/staging/rtl8712/usb_intf.c +@@ -86,6 +86,7 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = { + {USB_DEVICE(0x0DF6, 0x0045)}, + {USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */ + {USB_DEVICE(0x0DF6, 0x004B)}, ++ {USB_DEVICE(0x0DF6, 0x005D)}, + {USB_DEVICE(0x0DF6, 0x0063)}, + /* Sweex */ + {USB_DEVICE(0x177F, 0x0154)}, +diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c +index 26a5d8b..c4ac6f6 100644 +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -1043,6 +1043,8 @@ done: + */ + send_check_condition = 1; + } else { ++ cmd->data_length = cmd->se_cmd.data_length; ++ + if (iscsit_decide_list_to_build(cmd, payload_length) < 0) + return iscsit_add_reject_from_cmd( + ISCSI_REASON_BOOKMARK_NO_RESOURCES, +@@ -2512,10 +2514,10 @@ static int iscsit_send_data_in( + if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { + if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { + hdr->flags |= ISCSI_FLAG_DATA_OVERFLOW; +- hdr->residual_count = cpu_to_be32(cmd->residual_count); ++ hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); + } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { + hdr->flags |= ISCSI_FLAG_DATA_UNDERFLOW; +- hdr->residual_count = cpu_to_be32(cmd->residual_count); ++ hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); + } + } + hton24(hdr->dlength, datain.length); +@@ -3017,10 +3019,10 @@ static int iscsit_send_status( + hdr->flags |= ISCSI_FLAG_CMD_FINAL; + if (cmd->se_cmd.se_cmd_flags & SCF_OVERFLOW_BIT) { + hdr->flags |= ISCSI_FLAG_CMD_OVERFLOW; +- hdr->residual_count = cpu_to_be32(cmd->residual_count); ++ hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); + } else if (cmd->se_cmd.se_cmd_flags & SCF_UNDERFLOW_BIT) { + hdr->flags |= ISCSI_FLAG_CMD_UNDERFLOW; +- hdr->residual_count = cpu_to_be32(cmd->residual_count); ++ hdr->residual_count = cpu_to_be32(cmd->se_cmd.residual_count); + } + hdr->response = cmd->iscsi_response; + hdr->cmd_status = cmd->se_cmd.scsi_status; +@@ -3132,6 +3134,7 @@ static int iscsit_send_task_mgt_rsp( + hdr = (struct iscsi_tm_rsp *) cmd->pdu; + memset(hdr, 0, ISCSI_HDR_LEN); + hdr->opcode = ISCSI_OP_SCSI_TMFUNC_RSP; ++ hdr->flags = ISCSI_FLAG_CMD_FINAL; + hdr->response = iscsit_convert_tcm_tmr_rsp(se_tmr); + hdr->itt = cpu_to_be32(cmd->init_task_tag); + cmd->stat_sn = conn->stat_sn++; +diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h +index 470ed55..8d18b2c 100644 +--- a/drivers/target/iscsi/iscsi_target_core.h ++++ b/drivers/target/iscsi/iscsi_target_core.h +@@ -395,7 +395,6 @@ struct iscsi_cmd { + u32 pdu_send_order; + /* Current struct iscsi_pdu in struct iscsi_cmd->pdu_list */ + u32 pdu_start; +- u32 residual_count; + /* Next struct iscsi_seq to send in struct iscsi_cmd->seq_list */ + u32 seq_send_order; + /* Number of struct iscsi_seq in struct iscsi_cmd->seq_list */ +diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c +index f04d4ef..5f91397 100644 +--- a/drivers/target/target_core_cdb.c ++++ b/drivers/target/target_core_cdb.c +@@ -477,7 +477,7 @@ target_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) + if (cmd->data_length < 60) + return 0; + +- buf[2] = 0x3c; ++ buf[3] = 0x3c; + /* Set HEADSUP, ORDSUP, SIMPSUP */ + buf[5] = 0x07; + +diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c +index bc1b336..ceb2a28 100644 +--- a/drivers/target/target_core_file.c ++++ b/drivers/target/target_core_file.c +@@ -288,9 +288,9 @@ static int fd_do_readv(struct se_task *task) + return -ENOMEM; + } + +- for (i = 0; i < task->task_sg_nents; i++) { +- iov[i].iov_len = sg[i].length; +- iov[i].iov_base = sg_virt(&sg[i]); ++ for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { ++ iov[i].iov_len = sg->length; ++ iov[i].iov_base = sg_virt(sg); + } + + old_fs = get_fs(); +@@ -340,9 +340,9 @@ static int fd_do_writev(struct se_task *task) + return -ENOMEM; + } + +- for (i = 0; i < task->task_sg_nents; i++) { +- iov[i].iov_len = sg[i].length; +- iov[i].iov_base = sg_virt(&sg[i]); ++ for_each_sg(task->task_sg, sg, task->task_sg_nents, i) { ++ iov[i].iov_len = sg->length; ++ iov[i].iov_base = sg_virt(sg); + } + + old_fs = get_fs(); +diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c +index 013c100..e2added 100644 +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -2562,10 +2562,15 @@ static inline u32 transport_get_sectors_6( + + /* + * Everything else assume TYPE_DISK Sector CDB location. +- * Use 8-bit sector value. ++ * Use 8-bit sector value. SBC-3 says: ++ * ++ * A TRANSFER LENGTH field set to zero specifies that 256 ++ * logical blocks shall be written. Any other value ++ * specifies the number of logical blocks that shall be ++ * written. + */ + type_disk: +- return (u32)cdb[4]; ++ return cdb[4] ? : 256; + } + + static inline u32 transport_get_sectors_10( +@@ -3873,6 +3878,18 @@ int transport_generic_map_mem_to_cmd( + + if ((cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) || + (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB)) { ++ /* ++ * Reject SCSI data overflow with map_mem_to_cmd() as incoming ++ * scatterlists already have been set to follow what the fabric ++ * passes for the original expected data transfer length. ++ */ ++ if (cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { ++ pr_warn("Rejecting SCSI DATA overflow for fabric using" ++ " SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC\n"); ++ cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; ++ cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; ++ return -EINVAL; ++ } + + cmd->t_data_sg = sgl; + cmd->t_data_nents = sgl_count; +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index 2ffcaa0..8faa23c 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1458,6 +1458,16 @@ static const struct usb_device_id acm_ids[] = { + }, + { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ + }, ++ /* Motorola H24 HSPA module: */ ++ { USB_DEVICE(0x22b8, 0x2d91) }, /* modem */ ++ { USB_DEVICE(0x22b8, 0x2d92) }, /* modem + diagnostics */ ++ { USB_DEVICE(0x22b8, 0x2d93) }, /* modem + AT port */ ++ { USB_DEVICE(0x22b8, 0x2d95) }, /* modem + AT port + diagnostics */ ++ { USB_DEVICE(0x22b8, 0x2d96) }, /* modem + NMEA */ ++ { USB_DEVICE(0x22b8, 0x2d97) }, /* modem + diagnostics + NMEA */ ++ { USB_DEVICE(0x22b8, 0x2d99) }, /* modem + AT port + NMEA */ ++ { USB_DEVICE(0x22b8, 0x2d9a) }, /* modem + AT port + diagnostics + NMEA */ ++ + { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ + .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on + data interface instead of +diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c +index e98a1e1..d2becb9 100644 +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -659,7 +659,12 @@ static const struct usb_device_id option_ids[] = { + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) }, +- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x08) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x10) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x12) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x13) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x01) }, /* E398 3G Modem */ ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x02) }, /* E398 3G PC UI Interface */ ++ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x03) }, /* E398 3G Application Interface */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, +diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c +index 5de03ec..a090bbe 100644 +--- a/fs/cifs/readdir.c ++++ b/fs/cifs/readdir.c +@@ -554,7 +554,10 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon, + rc); + return rc; + } +- cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile); ++ /* FindFirst/Next set last_entry to NULL on malformed reply */ ++ if (cifsFile->srch_inf.last_entry) ++ cifs_save_resume_key(cifsFile->srch_inf.last_entry, ++ cifsFile); + } + + while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && +@@ -562,7 +565,10 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon, + cFYI(1, "calling findnext2"); + rc = CIFSFindNext(xid, pTcon, cifsFile->netfid, + &cifsFile->srch_inf); +- cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile); ++ /* FindFirst/Next set last_entry to NULL on malformed reply */ ++ if (cifsFile->srch_inf.last_entry) ++ cifs_save_resume_key(cifsFile->srch_inf.last_entry, ++ cifsFile); + if (rc) + return -ENOENT; + } +diff --git a/fs/dcache.c b/fs/dcache.c +index a88948b..8b732a2 100644 +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -2398,16 +2398,14 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name) + /** + * prepend_path - Prepend path string to a buffer + * @path: the dentry/vfsmount to report +- * @root: root vfsmnt/dentry (may be modified by this function) ++ * @root: root vfsmnt/dentry + * @buffer: pointer to the end of the buffer + * @buflen: pointer to buffer length + * + * Caller holds the rename_lock. +- * +- * If path is not reachable from the supplied root, then the value of +- * root is changed (without modifying refcounts). + */ +-static int prepend_path(const struct path *path, struct path *root, ++static int prepend_path(const struct path *path, ++ const struct path *root, + char **buffer, int *buflen) + { + struct dentry *dentry = path->dentry; +@@ -2442,10 +2440,10 @@ static int prepend_path(const struct path *path, struct path *root, + dentry = parent; + } + +-out: + if (!error && !slash) + error = prepend(buffer, buflen, "/", 1); + ++out: + br_read_unlock(vfsmount_lock); + return error; + +@@ -2459,15 +2457,17 @@ global_root: + WARN(1, "Root dentry has weird name <%.*s>\n", + (int) dentry->d_name.len, dentry->d_name.name); + } +- root->mnt = vfsmnt; +- root->dentry = dentry; ++ if (!slash) ++ error = prepend(buffer, buflen, "/", 1); ++ if (!error) ++ error = vfsmnt->mnt_ns ? 1 : 2; + goto out; + } + + /** + * __d_path - return the path of a dentry + * @path: the dentry/vfsmount to report +- * @root: root vfsmnt/dentry (may be modified by this function) ++ * @root: root vfsmnt/dentry + * @buf: buffer to return value in + * @buflen: buffer length + * +@@ -2478,10 +2478,10 @@ global_root: + * + * "buflen" should be positive. + * +- * If path is not reachable from the supplied root, then the value of +- * root is changed (without modifying refcounts). ++ * If the path is not reachable from the supplied root, return %NULL. + */ +-char *__d_path(const struct path *path, struct path *root, ++char *__d_path(const struct path *path, ++ const struct path *root, + char *buf, int buflen) + { + char *res = buf + buflen; +@@ -2492,7 +2492,28 @@ char *__d_path(const struct path *path, struct path *root, + error = prepend_path(path, root, &res, &buflen); + write_sequnlock(&rename_lock); + +- if (error) ++ if (error < 0) ++ return ERR_PTR(error); ++ if (error > 0) ++ return NULL; ++ return res; ++} ++ ++char *d_absolute_path(const struct path *path, ++ char *buf, int buflen) ++{ ++ struct path root = {}; ++ char *res = buf + buflen; ++ int error; ++ ++ prepend(&res, &buflen, "\0", 1); ++ write_seqlock(&rename_lock); ++ error = prepend_path(path, &root, &res, &buflen); ++ write_sequnlock(&rename_lock); ++ ++ if (error > 1) ++ error = -EINVAL; ++ if (error < 0) + return ERR_PTR(error); + return res; + } +@@ -2500,8 +2521,9 @@ char *__d_path(const struct path *path, struct path *root, + /* + * same as __d_path but appends "(deleted)" for unlinked files. + */ +-static int path_with_deleted(const struct path *path, struct path *root, +- char **buf, int *buflen) ++static int path_with_deleted(const struct path *path, ++ const struct path *root, ++ char **buf, int *buflen) + { + prepend(buf, buflen, "\0", 1); + if (d_unlinked(path->dentry)) { +@@ -2538,7 +2560,6 @@ char *d_path(const struct path *path, char *buf, int buflen) + { + char *res = buf + buflen; + struct path root; +- struct path tmp; + int error; + + /* +@@ -2553,9 +2574,8 @@ char *d_path(const struct path *path, char *buf, int buflen) + + get_fs_root(current->fs, &root); + write_seqlock(&rename_lock); +- tmp = root; +- error = path_with_deleted(path, &tmp, &res, &buflen); +- if (error) ++ error = path_with_deleted(path, &root, &res, &buflen); ++ if (error < 0) + res = ERR_PTR(error); + write_sequnlock(&rename_lock); + path_put(&root); +@@ -2576,7 +2596,6 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen) + { + char *res = buf + buflen; + struct path root; +- struct path tmp; + int error; + + if (path->dentry->d_op && path->dentry->d_op->d_dname) +@@ -2584,9 +2603,8 @@ char *d_path_with_unreachable(const struct path *path, char *buf, int buflen) + + get_fs_root(current->fs, &root); + write_seqlock(&rename_lock); +- tmp = root; +- error = path_with_deleted(path, &tmp, &res, &buflen); +- if (!error && !path_equal(&tmp, &root)) ++ error = path_with_deleted(path, &root, &res, &buflen); ++ if (error > 0) + error = prepend_unreachable(&res, &buflen); + write_sequnlock(&rename_lock); + path_put(&root); +@@ -2717,19 +2735,18 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) + write_seqlock(&rename_lock); + if (!d_unlinked(pwd.dentry)) { + unsigned long len; +- struct path tmp = root; + char *cwd = page + PAGE_SIZE; + int buflen = PAGE_SIZE; + + prepend(&cwd, &buflen, "\0", 1); +- error = prepend_path(&pwd, &tmp, &cwd, &buflen); ++ error = prepend_path(&pwd, &root, &cwd, &buflen); + write_sequnlock(&rename_lock); + +- if (error) ++ if (error < 0) + goto out; + + /* Unreachable from current root */ +- if (!path_equal(&tmp, &root)) { ++ if (error > 0) { + error = prepend_unreachable(&cwd, &buflen); + if (error) + goto out; +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index b644b9c..5dbdb6b 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -1261,8 +1261,11 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, + clear_buffer_unwritten(bh); + } + +- /* skip page if block allocation undone */ +- if (buffer_delay(bh) || buffer_unwritten(bh)) ++ /* ++ * skip page if block allocation undone and ++ * block is dirty ++ */ ++ if (ext4_bh_delay_or_unwritten(NULL, bh)) + skip_page = 1; + bh = bh->b_this_page; + block_start += bh->b_size; +@@ -2367,7 +2370,7 @@ static int ext4_da_write_end(struct file *file, + */ + + new_i_size = pos + copied; +- if (new_i_size > EXT4_I(inode)->i_disksize) { ++ if (copied && new_i_size > EXT4_I(inode)->i_disksize) { + if (ext4_da_should_update_i_disksize(page, end)) { + down_write(&EXT4_I(inode)->i_data_sem); + if (new_i_size > EXT4_I(inode)->i_disksize) { +@@ -2630,10 +2633,11 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, + iocb->private, io_end->inode->i_ino, iocb, offset, + size); + ++ iocb->private = NULL; ++ + /* if not aio dio with unwritten extents, just free io and return */ + if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) { + ext4_free_io_end(io_end); +- iocb->private = NULL; + out: + if (is_async) + aio_complete(iocb, ret, 0); +@@ -2656,7 +2660,6 @@ out: + spin_unlock_irqrestore(&ei->i_completed_io_lock, flags); + + /* queue the work to convert unwritten extents to written */ +- iocb->private = NULL; + queue_work(wq, &io_end->work); + + /* XXX: probably should move into the real I/O completion handler */ +diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c +index 92f38ee..78ab854 100644 +--- a/fs/ext4/page-io.c ++++ b/fs/ext4/page-io.c +@@ -401,6 +401,18 @@ int ext4_bio_write_page(struct ext4_io_submit *io, + + block_end = block_start + blocksize; + if (block_start >= len) { ++ /* ++ * Comments copied from block_write_full_page_endio: ++ * ++ * The page straddles i_size. It must be zeroed out on ++ * each and every writepage invocation because it may ++ * be mmapped. "A file is mapped in multiples of the ++ * page size. For a file that is not a multiple of ++ * the page size, the remaining memory is zeroed when ++ * mapped, and writes to that region are not written ++ * out to the file." ++ */ ++ zero_user_segment(page, block_start, block_end); + clear_buffer_dirty(bh); + set_buffer_uptodate(bh); + continue; +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 44d0c8d..065ff37 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -1140,9 +1140,9 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) + seq_puts(seq, ",block_validity"); + + if (!test_opt(sb, INIT_INODE_TABLE)) +- seq_puts(seq, ",noinit_inode_table"); ++ seq_puts(seq, ",noinit_itable"); + else if (sbi->s_li_wait_mult != EXT4_DEF_LI_WAIT_MULT) +- seq_printf(seq, ",init_inode_table=%u", ++ seq_printf(seq, ",init_itable=%u", + (unsigned) sbi->s_li_wait_mult); + + ext4_show_quota_options(seq, sb); +@@ -1318,8 +1318,7 @@ enum { + Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, + Opt_inode_readahead_blks, Opt_journal_ioprio, + Opt_dioread_nolock, Opt_dioread_lock, +- Opt_discard, Opt_nodiscard, +- Opt_init_inode_table, Opt_noinit_inode_table, ++ Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable, + }; + + static const match_table_t tokens = { +@@ -1392,9 +1391,9 @@ static const match_table_t tokens = { + {Opt_dioread_lock, "dioread_lock"}, + {Opt_discard, "discard"}, + {Opt_nodiscard, "nodiscard"}, +- {Opt_init_inode_table, "init_itable=%u"}, +- {Opt_init_inode_table, "init_itable"}, +- {Opt_noinit_inode_table, "noinit_itable"}, ++ {Opt_init_itable, "init_itable=%u"}, ++ {Opt_init_itable, "init_itable"}, ++ {Opt_noinit_itable, "noinit_itable"}, + {Opt_err, NULL}, + }; + +@@ -1871,7 +1870,7 @@ set_qf_format: + case Opt_dioread_lock: + clear_opt(sb, DIOREAD_NOLOCK); + break; +- case Opt_init_inode_table: ++ case Opt_init_itable: + set_opt(sb, INIT_INODE_TABLE); + if (args[0].from) { + if (match_int(&args[0], &option)) +@@ -1882,7 +1881,7 @@ set_qf_format: + return 0; + sbi->s_li_wait_mult = option; + break; +- case Opt_noinit_inode_table: ++ case Opt_noinit_itable: + clear_opt(sb, INIT_INODE_TABLE); + break; + default: +diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c +index 5cb8614..2aaf3ea 100644 +--- a/fs/fuse/dev.c ++++ b/fs/fuse/dev.c +@@ -1512,7 +1512,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, + else if (outarg->offset + num > file_size) + num = file_size - outarg->offset; + +- while (num) { ++ while (num && req->num_pages < FUSE_MAX_PAGES_PER_REQ) { + struct page *page; + unsigned int this_num; + +@@ -1526,6 +1526,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, + + num -= this_num; + total_len += this_num; ++ index++; + } + req->misc.retrieve_in.offset = outarg->offset; + req->misc.retrieve_in.size = total_len; +diff --git a/fs/fuse/file.c b/fs/fuse/file.c +index 594f07a..19029e9 100644 +--- a/fs/fuse/file.c ++++ b/fs/fuse/file.c +@@ -1556,7 +1556,7 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int origin) + struct inode *inode = file->f_path.dentry->d_inode; + + mutex_lock(&inode->i_mutex); +- if (origin != SEEK_CUR || origin != SEEK_SET) { ++ if (origin != SEEK_CUR && origin != SEEK_SET) { + retval = fuse_update_attributes(inode, NULL, file, NULL); + if (retval) + goto exit; +diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c +index 3ebc437..1cbdeea 100644 +--- a/fs/hfs/btree.c ++++ b/fs/hfs/btree.c +@@ -46,11 +46,26 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke + case HFS_EXT_CNID: + hfs_inode_read_fork(tree->inode, mdb->drXTExtRec, mdb->drXTFlSize, + mdb->drXTFlSize, be32_to_cpu(mdb->drXTClpSiz)); ++ if (HFS_I(tree->inode)->alloc_blocks > ++ HFS_I(tree->inode)->first_blocks) { ++ printk(KERN_ERR "hfs: invalid btree extent records\n"); ++ unlock_new_inode(tree->inode); ++ goto free_inode; ++ } ++ + tree->inode->i_mapping->a_ops = &hfs_btree_aops; + break; + case HFS_CAT_CNID: + hfs_inode_read_fork(tree->inode, mdb->drCTExtRec, mdb->drCTFlSize, + mdb->drCTFlSize, be32_to_cpu(mdb->drCTClpSiz)); ++ ++ if (!HFS_I(tree->inode)->first_blocks) { ++ printk(KERN_ERR "hfs: invalid btree extent records " ++ "(0 size).\n"); ++ unlock_new_inode(tree->inode); ++ goto free_inode; ++ } ++ + tree->inode->i_mapping->a_ops = &hfs_btree_aops; + break; + default: +@@ -59,11 +74,6 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke + } + unlock_new_inode(tree->inode); + +- if (!HFS_I(tree->inode)->first_blocks) { +- printk(KERN_ERR "hfs: invalid btree extent records (0 size).\n"); +- goto free_inode; +- } +- + mapping = tree->inode->i_mapping; + page = read_mapping_page(mapping, 0, NULL); + if (IS_ERR(page)) +diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c +index 9fe061f..fea8dd6 100644 +--- a/fs/jbd/journal.c ++++ b/fs/jbd/journal.c +@@ -1135,6 +1135,14 @@ static int journal_get_superblock(journal_t *journal) + goto out; + } + ++ if (be32_to_cpu(sb->s_first) == 0 || ++ be32_to_cpu(sb->s_first) >= journal->j_maxlen) { ++ printk(KERN_WARNING ++ "JBD: Invalid start block of journal: %u\n", ++ be32_to_cpu(sb->s_first)); ++ goto out; ++ } ++ + return 0; + + out: +diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c +index f24df13..d6e93d0 100644 +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -1251,6 +1251,14 @@ static int journal_get_superblock(journal_t *journal) + goto out; + } + ++ if (be32_to_cpu(sb->s_first) == 0 || ++ be32_to_cpu(sb->s_first) >= journal->j_maxlen) { ++ printk(KERN_WARNING ++ "JBD2: Invalid start block of journal: %u\n", ++ be32_to_cpu(sb->s_first)); ++ goto out; ++ } ++ + return 0; + + out: +diff --git a/fs/namespace.c b/fs/namespace.c +index e5e1c7d..5e7f2e9 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -1048,15 +1048,12 @@ static int show_mountinfo(struct seq_file *m, void *v) + if (err) + goto out; + seq_putc(m, ' '); +- seq_path_root(m, &mnt_path, &root, " \t\n\\"); +- if (root.mnt != p->root.mnt || root.dentry != p->root.dentry) { +- /* +- * Mountpoint is outside root, discard that one. Ugly, +- * but less so than trying to do that in iterator in a +- * race-free way (due to renames). +- */ +- return SEQ_SKIP; +- } ++ ++ /* mountpoints outside of chroot jail will give SEQ_SKIP on this */ ++ err = seq_path_root(m, &mnt_path, &root, " \t\n\\"); ++ if (err) ++ goto out; ++ + seq_puts(m, mnt->mnt_flags & MNT_READONLY ? " ro" : " rw"); + show_mnt_opts(m, mnt); + +@@ -2744,3 +2741,8 @@ void kern_unmount(struct vfsmount *mnt) + } + } + EXPORT_SYMBOL(kern_unmount); ++ ++bool our_mnt(struct vfsmount *mnt) ++{ ++ return check_mnt(mnt); ++} +diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c +index 5861741..80e4645 100644 +--- a/fs/proc/meminfo.c ++++ b/fs/proc/meminfo.c +@@ -131,12 +131,13 @@ static int meminfo_proc_show(struct seq_file *m, void *v) + K(i.freeswap), + K(global_page_state(NR_FILE_DIRTY)), + K(global_page_state(NR_WRITEBACK)), +- K(global_page_state(NR_ANON_PAGES) + #ifdef CONFIG_TRANSPARENT_HUGEPAGE ++ K(global_page_state(NR_ANON_PAGES) + + global_page_state(NR_ANON_TRANSPARENT_HUGEPAGES) * +- HPAGE_PMD_NR ++ HPAGE_PMD_NR), ++#else ++ K(global_page_state(NR_ANON_PAGES)), + #endif +- ), + K(global_page_state(NR_FILE_MAPPED)), + K(global_page_state(NR_SHMEM)), + K(global_page_state(NR_SLAB_RECLAIMABLE) + +diff --git a/fs/seq_file.c b/fs/seq_file.c +index 05d6b0e..dba43c3 100644 +--- a/fs/seq_file.c ++++ b/fs/seq_file.c +@@ -449,8 +449,6 @@ EXPORT_SYMBOL(seq_path); + + /* + * Same as seq_path, but relative to supplied root. +- * +- * root may be changed, see __d_path(). + */ + int seq_path_root(struct seq_file *m, struct path *path, struct path *root, + char *esc) +@@ -463,6 +461,8 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root, + char *p; + + p = __d_path(path, root, buf, size); ++ if (!p) ++ return SEQ_SKIP; + res = PTR_ERR(p); + if (!IS_ERR(p)) { + char *end = mangle_path(buf, p, esc); +@@ -474,7 +474,7 @@ int seq_path_root(struct seq_file *m, struct path *path, struct path *root, + } + seq_commit(m, res); + +- return res < 0 ? res : 0; ++ return res < 0 && res != -ENAMETOOLONG ? res : 0; + } + + /* +diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h +index 4e4fbb8..14b6cd0 100644 +--- a/include/drm/drm_pciids.h ++++ b/include/drm/drm_pciids.h +@@ -182,8 +182,11 @@ + {0x1002, 0x6748, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x6751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6758, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6759, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x675B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x675D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x675F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6761, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ +@@ -195,8 +198,10 @@ + {0x1002, 0x6767, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6768, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6770, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x6772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6778, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6779, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x677B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6840, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6841, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x6842, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ +@@ -246,6 +251,7 @@ + {0x1002, 0x68f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68f8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68f9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ ++ {0x1002, 0x68fa, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x68fe, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CEDAR|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x7100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x7101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ +@@ -488,6 +494,8 @@ + {0x1002, 0x9647, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\ + {0x1002, 0x9648, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\ + {0x1002, 0x964a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x964b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x964c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x964e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\ + {0x1002, 0x964f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_SUMO|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP},\ + {0x1002, 0x9710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ +@@ -502,6 +510,8 @@ + {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}, \ ++ {0x1002, 0x9808, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ ++ {0x1002, 0x9809, 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/dcache.h b/include/linux/dcache.h +index 62157c0..713c7c6 100644 +--- a/include/linux/dcache.h ++++ b/include/linux/dcache.h +@@ -337,7 +337,8 @@ extern int d_validate(struct dentry *, struct dentry *); + */ + extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); + +-extern char *__d_path(const struct path *path, struct path *root, char *, int); ++extern char *__d_path(const struct path *, const struct path *, char *, int); ++extern char *d_absolute_path(const struct path *, char *, int); + extern char *d_path(const struct path *, char *, int); + extern char *d_path_with_unreachable(const struct path *, char *, int); + extern char *dentry_path_raw(struct dentry *, char *, int); +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 277f497..cf7bc25 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1907,6 +1907,7 @@ extern int fd_statfs(int, struct kstatfs *); + extern int statfs_by_dentry(struct dentry *, struct kstatfs *); + extern int freeze_super(struct super_block *super); + extern int thaw_super(struct super_block *super); ++extern bool our_mnt(struct vfsmount *mnt); + + extern int current_umask(void); + +diff --git a/include/linux/log2.h b/include/linux/log2.h +index 25b8086..fd7ff3d 100644 +--- a/include/linux/log2.h ++++ b/include/linux/log2.h +@@ -185,7 +185,6 @@ unsigned long __rounddown_pow_of_two(unsigned long n) + #define rounddown_pow_of_two(n) \ + ( \ + __builtin_constant_p(n) ? ( \ +- (n == 1) ? 0 : \ + (1UL << ilog2(n))) : \ + __rounddown_pow_of_two(n) \ + ) +diff --git a/kernel/lockdep.c b/kernel/lockdep.c +index 91d67ce..4479606 100644 +--- a/kernel/lockdep.c ++++ b/kernel/lockdep.c +@@ -44,6 +44,7 @@ + #include <linux/stringify.h> + #include <linux/bitops.h> + #include <linux/gfp.h> ++#include <linux/kmemcheck.h> + + #include <asm/sections.h> + +@@ -2874,7 +2875,12 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, + void lockdep_init_map(struct lockdep_map *lock, const char *name, + struct lock_class_key *key, int subclass) + { +- memset(lock, 0, sizeof(*lock)); ++ int i; ++ ++ kmemcheck_mark_initialized(lock, sizeof(*lock)); ++ ++ for (i = 0; i < NR_LOCKDEP_CACHING_CLASSES; i++) ++ lock->class_cache[i] = NULL; + + #ifdef CONFIG_LOCK_STAT + lock->cpu = raw_smp_processor_id(); +diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c +index ea5e1a9..8b70c76 100644 +--- a/kernel/time/alarmtimer.c ++++ b/kernel/time/alarmtimer.c +@@ -181,7 +181,7 @@ static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer) + struct alarm *alarm; + ktime_t expired = next->expires; + +- if (expired.tv64 >= now.tv64) ++ if (expired.tv64 > now.tv64) + break; + + alarm = container_of(next, struct alarm, node); +diff --git a/mm/hugetlb.c b/mm/hugetlb.c +index bb28a5f..73f17c0 100644 +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -576,6 +576,7 @@ static void prep_compound_gigantic_page(struct page *page, unsigned long order) + __SetPageHead(page); + for (i = 1; i < nr_pages; i++, p = mem_map_next(p, page, i)) { + __SetPageTail(p); ++ set_page_count(p, 0); + p->first_page = page; + } + } +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 6e8ecb6..e8fae15 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -355,8 +355,8 @@ void prep_compound_page(struct page *page, unsigned long order) + __SetPageHead(page); + for (i = 1; i < nr_pages; i++) { + struct page *p = page + i; +- + __SetPageTail(p); ++ set_page_count(p, 0); + p->first_page = page; + } + } +@@ -3370,9 +3370,15 @@ static void setup_zone_migrate_reserve(struct zone *zone) + unsigned long block_migratetype; + int reserve; + +- /* Get the start pfn, end pfn and the number of blocks to reserve */ ++ /* ++ * Get the start pfn, end pfn and the number of blocks to reserve ++ * We have to be careful to be aligned to pageblock_nr_pages to ++ * make sure that we always check pfn_valid for the first page in ++ * the block. ++ */ + start_pfn = zone->zone_start_pfn; + end_pfn = start_pfn + zone->spanned_pages; ++ start_pfn = roundup(start_pfn, pageblock_nr_pages); + reserve = roundup(min_wmark_pages(zone), pageblock_nr_pages) >> + pageblock_order; + +diff --git a/mm/percpu-vm.c b/mm/percpu-vm.c +index ea53496..bfad724 100644 +--- a/mm/percpu-vm.c ++++ b/mm/percpu-vm.c +@@ -143,8 +143,8 @@ static void pcpu_pre_unmap_flush(struct pcpu_chunk *chunk, + int page_start, int page_end) + { + flush_cache_vunmap( +- pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start), +- pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end)); ++ pcpu_chunk_addr(chunk, pcpu_low_unit_cpu, page_start), ++ pcpu_chunk_addr(chunk, pcpu_high_unit_cpu, page_end)); + } + + static void __pcpu_unmap_pages(unsigned long addr, int nr_pages) +@@ -206,8 +206,8 @@ static void pcpu_post_unmap_tlb_flush(struct pcpu_chunk *chunk, + int page_start, int page_end) + { + flush_tlb_kernel_range( +- pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start), +- pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end)); ++ pcpu_chunk_addr(chunk, pcpu_low_unit_cpu, page_start), ++ pcpu_chunk_addr(chunk, pcpu_high_unit_cpu, page_end)); + } + + static int __pcpu_map_pages(unsigned long addr, struct page **pages, +@@ -284,8 +284,8 @@ static void pcpu_post_map_flush(struct pcpu_chunk *chunk, + int page_start, int page_end) + { + flush_cache_vmap( +- pcpu_chunk_addr(chunk, pcpu_first_unit_cpu, page_start), +- pcpu_chunk_addr(chunk, pcpu_last_unit_cpu, page_end)); ++ pcpu_chunk_addr(chunk, pcpu_low_unit_cpu, page_start), ++ pcpu_chunk_addr(chunk, pcpu_high_unit_cpu, page_end)); + } + + /** +diff --git a/mm/percpu.c b/mm/percpu.c +index bf80e55..93b5a7c 100644 +--- a/mm/percpu.c ++++ b/mm/percpu.c +@@ -116,9 +116,9 @@ static int pcpu_atom_size __read_mostly; + static int pcpu_nr_slots __read_mostly; + static size_t pcpu_chunk_struct_size __read_mostly; + +-/* cpus with the lowest and highest unit numbers */ +-static unsigned int pcpu_first_unit_cpu __read_mostly; +-static unsigned int pcpu_last_unit_cpu __read_mostly; ++/* cpus with the lowest and highest unit addresses */ ++static unsigned int pcpu_low_unit_cpu __read_mostly; ++static unsigned int pcpu_high_unit_cpu __read_mostly; + + /* the address of the first chunk which starts with the kernel static area */ + void *pcpu_base_addr __read_mostly; +@@ -984,19 +984,19 @@ phys_addr_t per_cpu_ptr_to_phys(void *addr) + { + void __percpu *base = __addr_to_pcpu_ptr(pcpu_base_addr); + bool in_first_chunk = false; +- unsigned long first_start, first_end; ++ unsigned long first_low, first_high; + unsigned int cpu; + + /* +- * The following test on first_start/end isn't strictly ++ * The following test on unit_low/high isn't strictly + * necessary but will speed up lookups of addresses which + * aren't in the first chunk. + */ +- first_start = pcpu_chunk_addr(pcpu_first_chunk, pcpu_first_unit_cpu, 0); +- first_end = pcpu_chunk_addr(pcpu_first_chunk, pcpu_last_unit_cpu, +- pcpu_unit_pages); +- if ((unsigned long)addr >= first_start && +- (unsigned long)addr < first_end) { ++ first_low = pcpu_chunk_addr(pcpu_first_chunk, pcpu_low_unit_cpu, 0); ++ first_high = pcpu_chunk_addr(pcpu_first_chunk, pcpu_high_unit_cpu, ++ pcpu_unit_pages); ++ if ((unsigned long)addr >= first_low && ++ (unsigned long)addr < first_high) { + for_each_possible_cpu(cpu) { + void *start = per_cpu_ptr(base, cpu); + +@@ -1233,7 +1233,9 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, + + for (cpu = 0; cpu < nr_cpu_ids; cpu++) + unit_map[cpu] = UINT_MAX; +- pcpu_first_unit_cpu = NR_CPUS; ++ ++ pcpu_low_unit_cpu = NR_CPUS; ++ pcpu_high_unit_cpu = NR_CPUS; + + for (group = 0, unit = 0; group < ai->nr_groups; group++, unit += i) { + const struct pcpu_group_info *gi = &ai->groups[group]; +@@ -1253,9 +1255,13 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, + unit_map[cpu] = unit + i; + unit_off[cpu] = gi->base_offset + i * ai->unit_size; + +- if (pcpu_first_unit_cpu == NR_CPUS) +- pcpu_first_unit_cpu = cpu; +- pcpu_last_unit_cpu = cpu; ++ /* determine low/high unit_cpu */ ++ if (pcpu_low_unit_cpu == NR_CPUS || ++ unit_off[cpu] < unit_off[pcpu_low_unit_cpu]) ++ pcpu_low_unit_cpu = cpu; ++ if (pcpu_high_unit_cpu == NR_CPUS || ++ unit_off[cpu] > unit_off[pcpu_high_unit_cpu]) ++ pcpu_high_unit_cpu = cpu; + } + } + pcpu_nr_units = unit; +diff --git a/mm/vmalloc.c b/mm/vmalloc.c +index 56faf31..3a65d6f7 100644 +--- a/mm/vmalloc.c ++++ b/mm/vmalloc.c +@@ -1634,6 +1634,8 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align, + return NULL; + + addr = __vmalloc_area_node(area, gfp_mask, prot, node, caller); ++ if (!addr) ++ return NULL; + + /* + * In this function, newly allocated vm_struct is not added +diff --git a/security/apparmor/path.c b/security/apparmor/path.c +index 36cc0cc..b566eba 100644 +--- a/security/apparmor/path.c ++++ b/security/apparmor/path.c +@@ -57,23 +57,44 @@ static int prepend(char **buffer, int buflen, const char *str, int namelen) + static int d_namespace_path(struct path *path, char *buf, int buflen, + char **name, int flags) + { +- struct path root, tmp; + char *res; +- int connected, error = 0; ++ int error = 0; ++ int connected = 1; ++ ++ if (path->mnt->mnt_flags & MNT_INTERNAL) { ++ /* it's not mounted anywhere */ ++ res = dentry_path(path->dentry, buf, buflen); ++ *name = res; ++ if (IS_ERR(res)) { ++ *name = buf; ++ return PTR_ERR(res); ++ } ++ if (path->dentry->d_sb->s_magic == PROC_SUPER_MAGIC && ++ strncmp(*name, "/sys/", 5) == 0) { ++ /* TODO: convert over to using a per namespace ++ * control instead of hard coded /proc ++ */ ++ return prepend(name, *name - buf, "/proc", 5); ++ } ++ return 0; ++ } + +- /* Get the root we want to resolve too, released below */ ++ /* resolve paths relative to chroot?*/ + if (flags & PATH_CHROOT_REL) { +- /* resolve paths relative to chroot */ ++ struct path root; + get_fs_root(current->fs, &root); +- } else { +- /* resolve paths relative to namespace */ +- root.mnt = current->nsproxy->mnt_ns->root; +- root.dentry = root.mnt->mnt_root; +- path_get(&root); ++ res = __d_path(path, &root, buf, buflen); ++ if (res && !IS_ERR(res)) { ++ /* everything's fine */ ++ *name = res; ++ path_put(&root); ++ goto ok; ++ } ++ path_put(&root); ++ connected = 0; + } + +- tmp = root; +- res = __d_path(path, &tmp, buf, buflen); ++ res = d_absolute_path(path, buf, buflen); + + *name = res; + /* handle error conditions - and still allow a partial path to +@@ -84,7 +105,10 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, + *name = buf; + goto out; + } ++ if (!our_mnt(path->mnt)) ++ connected = 0; + ++ok: + /* Handle two cases: + * 1. A deleted dentry && profile is not allowing mediation of deleted + * 2. On some filesystems, newly allocated dentries appear to the +@@ -97,10 +121,7 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, + goto out; + } + +- /* Determine if the path is connected to the expected root */ +- connected = tmp.dentry == root.dentry && tmp.mnt == root.mnt; +- +- /* If the path is not connected, ++ /* If the path is not connected to the expected root, + * check if it is a sysctl and handle specially else remove any + * leading / that __d_path may have returned. + * Unless +@@ -112,17 +133,9 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, + * namespace root. + */ + if (!connected) { +- /* is the disconnect path a sysctl? */ +- if (tmp.dentry->d_sb->s_magic == PROC_SUPER_MAGIC && +- strncmp(*name, "/sys/", 5) == 0) { +- /* TODO: convert over to using a per namespace +- * control instead of hard coded /proc +- */ +- error = prepend(name, *name - buf, "/proc", 5); +- } else if (!(flags & PATH_CONNECT_PATH) && ++ if (!(flags & PATH_CONNECT_PATH) && + !(((flags & CHROOT_NSCONNECT) == CHROOT_NSCONNECT) && +- (tmp.mnt == current->nsproxy->mnt_ns->root && +- tmp.dentry == tmp.mnt->mnt_root))) { ++ our_mnt(path->mnt))) { + /* disconnected path, don't return pathname starting + * with '/' + */ +@@ -133,8 +146,6 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, + } + + out: +- path_put(&root); +- + return error; + } + +diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c +index 6c601bd..d46922d 100644 +--- a/security/tomoyo/realpath.c ++++ b/security/tomoyo/realpath.c +@@ -83,9 +83,8 @@ static char *tomoyo_get_absolute_path(struct path *path, char * const buffer, + { + char *pos = ERR_PTR(-ENOMEM); + if (buflen >= 256) { +- struct path ns_root = { }; + /* go to whatever namespace root we are under */ +- pos = __d_path(path, &ns_root, buffer, buflen - 1); ++ pos = d_absolute_path(path, buffer, buflen - 1); + if (!IS_ERR(pos) && *pos == '/' && pos[1]) { + struct inode *inode = path->dentry->d_inode; + if (inode && S_ISDIR(inode->i_mode)) { +@@ -276,8 +275,16 @@ char *tomoyo_realpath_from_path(struct path *path) + pos = tomoyo_get_local_path(path->dentry, buf, + buf_len - 1); + /* Get absolute name for the rest. */ +- else ++ else { + pos = tomoyo_get_absolute_path(path, buf, buf_len - 1); ++ /* ++ * Fall back to local name if absolute name is not ++ * available. ++ */ ++ if (pos == ERR_PTR(-EINVAL)) ++ pos = tomoyo_get_local_path(path->dentry, buf, ++ buf_len - 1); ++ } + encode: + if (IS_ERR(pos)) + continue; +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index c687e14..20d92074 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -280,6 +280,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, + imux = &spec->input_mux[mux_idx]; + if (!imux->num_items && mux_idx > 0) + imux = &spec->input_mux[0]; ++ if (!imux->num_items) ++ return 0; + + if (idx >= imux->num_items) + idx = imux->num_items - 1; +diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c +index 4538caa..5261fd8 100644 +--- a/sound/pci/hda/patch_sigmatel.c ++++ b/sound/pci/hda/patch_sigmatel.c +@@ -214,6 +214,7 @@ struct sigmatel_spec { + unsigned int gpio_mute; + unsigned int gpio_led; + unsigned int gpio_led_polarity; ++ unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */ + unsigned int vref_led; + + /* stream */ +@@ -4298,12 +4299,10 @@ static void stac_store_hints(struct hda_codec *codec) + spec->eapd_switch = val; + get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); + if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { +- if (spec->gpio_led <= 8) { +- spec->gpio_mask |= spec->gpio_led; +- spec->gpio_dir |= spec->gpio_led; +- if (spec->gpio_led_polarity) +- spec->gpio_data |= spec->gpio_led; +- } ++ spec->gpio_mask |= spec->gpio_led; ++ spec->gpio_dir |= spec->gpio_led; ++ if (spec->gpio_led_polarity) ++ spec->gpio_data |= spec->gpio_led; + } + } + +@@ -4893,8 +4892,14 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) + if (sscanf(dev->name, "HP_Mute_LED_%d_%x", + &spec->gpio_led_polarity, + &spec->gpio_led) == 2) { +- if (spec->gpio_led < 4) ++ unsigned int max_gpio; ++ max_gpio = snd_hda_param_read(codec, codec->afg, ++ AC_PAR_GPIO_CAP); ++ max_gpio &= AC_GPIO_IO_COUNT; ++ if (spec->gpio_led < max_gpio) + spec->gpio_led = 1 << spec->gpio_led; ++ else ++ spec->vref_mute_led_nid = spec->gpio_led; + return 1; + } + if (sscanf(dev->name, "HP_Mute_LED_%d", +@@ -5023,15 +5028,12 @@ static int stac92xx_pre_resume(struct hda_codec *codec) + struct sigmatel_spec *spec = codec->spec; + + /* sync mute LED */ +- if (spec->gpio_led) { +- if (spec->gpio_led <= 8) { +- stac_gpio_set(codec, spec->gpio_mask, +- spec->gpio_dir, spec->gpio_data); +- } else { +- stac_vrefout_set(codec, +- spec->gpio_led, spec->vref_led); +- } +- } ++ if (spec->vref_mute_led_nid) ++ stac_vrefout_set(codec, spec->vref_mute_led_nid, ++ spec->vref_led); ++ else if (spec->gpio_led) ++ stac_gpio_set(codec, spec->gpio_mask, ++ spec->gpio_dir, spec->gpio_data); + return 0; + } + +@@ -5042,7 +5044,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg, + struct sigmatel_spec *spec = codec->spec; + + if (power_state == AC_PWRST_D3) { +- if (spec->gpio_led > 8) { ++ if (spec->vref_mute_led_nid) { + /* with vref-out pin used for mute led control + * codec AFG is prevented from D3 state + */ +@@ -5095,7 +5097,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec) + } + } + /*polarity defines *not* muted state level*/ +- if (spec->gpio_led <= 8) { ++ if (!spec->vref_mute_led_nid) { + if (muted) + spec->gpio_data &= ~spec->gpio_led; /* orange */ + else +@@ -5113,7 +5115,8 @@ static int stac92xx_update_led_status(struct hda_codec *codec) + muted_lvl = spec->gpio_led_polarity ? + AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; + spec->vref_led = muted ? muted_lvl : notmtd_lvl; +- stac_vrefout_set(codec, spec->gpio_led, spec->vref_led); ++ stac_vrefout_set(codec, spec->vref_mute_led_nid, ++ spec->vref_led); + } + return 0; + } +@@ -5634,7 +5637,7 @@ again: + + #ifdef CONFIG_SND_HDA_POWER_SAVE + if (spec->gpio_led) { +- if (spec->gpio_led <= 8) { ++ if (!spec->vref_mute_led_nid) { + spec->gpio_mask |= spec->gpio_led; + spec->gpio_dir |= spec->gpio_led; + spec->gpio_data |= spec->gpio_led; +@@ -5955,7 +5958,7 @@ again: + + #ifdef CONFIG_SND_HDA_POWER_SAVE + if (spec->gpio_led) { +- if (spec->gpio_led <= 8) { ++ if (!spec->vref_mute_led_nid) { + spec->gpio_mask |= spec->gpio_led; + spec->gpio_dir |= spec->gpio_led; + spec->gpio_data |= spec->gpio_led; +diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c +index bcf6152..fdc78ad 100644 +--- a/sound/pci/sis7019.c ++++ b/sound/pci/sis7019.c +@@ -41,6 +41,7 @@ MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}"); + static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ + static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ + static int enable = 1; ++static int codecs = 1; + + module_param(index, int, 0444); + MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator."); +@@ -48,6 +49,8 @@ module_param(id, charp, 0444); + MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator."); + module_param(enable, bool, 0444); + MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); ++module_param(codecs, int, 0444); ++MODULE_PARM_DESC(codecs, "Set bit to indicate that codec number is expected to be present (default 1)"); + + static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = { + { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, +@@ -140,6 +143,9 @@ struct sis7019 { + dma_addr_t silence_dma_addr; + }; + ++/* These values are also used by the module param 'codecs' to indicate ++ * which codecs should be present. ++ */ + #define SIS_PRIMARY_CODEC_PRESENT 0x0001 + #define SIS_SECONDARY_CODEC_PRESENT 0x0002 + #define SIS_TERTIARY_CODEC_PRESENT 0x0004 +@@ -1078,6 +1084,7 @@ static int sis_chip_init(struct sis7019 *sis) + { + unsigned long io = sis->ioport; + void __iomem *ioaddr = sis->ioaddr; ++ unsigned long timeout; + u16 status; + int count; + int i; +@@ -1104,21 +1111,45 @@ static int sis_chip_init(struct sis7019 *sis) + while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) + udelay(1); + ++ /* Command complete, we can let go of the semaphore now. ++ */ ++ outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); ++ if (!count) ++ return -EIO; ++ + /* Now that we've finished the reset, find out what's attached. ++ * There are some codec/board combinations that take an extremely ++ * long time to come up. 350+ ms has been observed in the field, ++ * so we'll give them up to 500ms. + */ +- status = inl(io + SIS_AC97_STATUS); +- if (status & SIS_AC97_STATUS_CODEC_READY) +- sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; +- if (status & SIS_AC97_STATUS_CODEC2_READY) +- sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; +- if (status & SIS_AC97_STATUS_CODEC3_READY) +- sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; +- +- /* All done, let go of the semaphore, and check for errors ++ sis->codecs_present = 0; ++ timeout = msecs_to_jiffies(500) + jiffies; ++ while (time_before_eq(jiffies, timeout)) { ++ status = inl(io + SIS_AC97_STATUS); ++ if (status & SIS_AC97_STATUS_CODEC_READY) ++ sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; ++ if (status & SIS_AC97_STATUS_CODEC2_READY) ++ sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; ++ if (status & SIS_AC97_STATUS_CODEC3_READY) ++ sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; ++ ++ if (sis->codecs_present == codecs) ++ break; ++ ++ msleep(1); ++ } ++ ++ /* All done, check for errors. + */ +- outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); +- if (!sis->codecs_present || !count) ++ if (!sis->codecs_present) { ++ printk(KERN_ERR "sis7019: could not find any codecs\n"); + return -EIO; ++ } ++ ++ if (sis->codecs_present != codecs) { ++ printk(KERN_WARNING "sis7019: missing codecs, found %0x, expected %0x\n", ++ sis->codecs_present, codecs); ++ } + + /* Let the hardware know that the audio driver is alive, + * and enable PCM slots on the AC-link for L/R playback (3 & 4) and +@@ -1390,6 +1421,17 @@ static int __devinit snd_sis7019_probe(struct pci_dev *pci, + if (!enable) + goto error_out; + ++ /* The user can specify which codecs should be present so that we ++ * can wait for them to show up if they are slow to recover from ++ * the AC97 cold reset. We default to a single codec, the primary. ++ * ++ * We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2. ++ */ ++ codecs &= SIS_PRIMARY_CODEC_PRESENT | SIS_SECONDARY_CODEC_PRESENT | ++ SIS_TERTIARY_CODEC_PRESENT; ++ if (!codecs) ++ codecs = SIS_PRIMARY_CODEC_PRESENT; ++ + rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card); + if (rc < 0) + goto error_out; +diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c +index ec921ec..cd987de 100644 +--- a/sound/soc/soc-utils.c ++++ b/sound/soc/soc-utils.c +@@ -57,7 +57,36 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params) + } + EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk); + +-static struct snd_soc_platform_driver dummy_platform; ++static const struct snd_pcm_hardware dummy_dma_hardware = { ++ .formats = 0xffffffff, ++ .channels_min = 1, ++ .channels_max = UINT_MAX, ++ ++ /* Random values to keep userspace happy when checking constraints */ ++ .info = SNDRV_PCM_INFO_INTERLEAVED | ++ SNDRV_PCM_INFO_BLOCK_TRANSFER, ++ .buffer_bytes_max = 128*1024, ++ .period_bytes_min = PAGE_SIZE, ++ .period_bytes_max = PAGE_SIZE*2, ++ .periods_min = 2, ++ .periods_max = 128, ++}; ++ ++static int dummy_dma_open(struct snd_pcm_substream *substream) ++{ ++ snd_soc_set_runtime_hwparams(substream, &dummy_dma_hardware); ++ ++ return 0; ++} ++ ++static struct snd_pcm_ops dummy_dma_ops = { ++ .open = dummy_dma_open, ++ .ioctl = snd_pcm_lib_ioctl, ++}; ++ ++static struct snd_soc_platform_driver dummy_platform = { ++ .ops = &dummy_dma_ops, ++}; + + static __devinit int snd_soc_dummy_probe(struct platform_device *pdev) + { |