Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: drivers/net/wireless/iwlwifi/pcie/tx.c Minor iwlwifi conflict in TX queue disabling between 'net', which removed a bogus warning, and 'net-next' which added some status register poking code. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
24bc518a68
155 changed files with 1385 additions and 573 deletions
5
CREDITS
5
CREDITS
|
@ -1823,6 +1823,11 @@ S: Kattreinstr 38
|
|||
S: D-64295
|
||||
S: Germany
|
||||
|
||||
N: Avi Kivity
|
||||
E: avi.kivity@gmail.com
|
||||
D: Kernel-based Virtual Machine (KVM)
|
||||
S: Ra'annana, Israel
|
||||
|
||||
N: Andi Kleen
|
||||
E: andi@firstfloor.org
|
||||
U: http://www.halobates.de
|
||||
|
|
|
@ -8,9 +8,16 @@ gpios property as described in section VIII.1 in the following order:
|
|||
|
||||
MDC, MDIO.
|
||||
|
||||
Note: Each gpio-mdio bus should have an alias correctly numbered in "aliases"
|
||||
node.
|
||||
|
||||
Example:
|
||||
|
||||
mdio {
|
||||
aliases {
|
||||
mdio-gpio0 = <&mdio0>;
|
||||
};
|
||||
|
||||
mdio0: mdio {
|
||||
compatible = "virtual,mdio-gpio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
|
|
@ -32,7 +32,7 @@ no entry is in the forwarding table.
|
|||
# ip link delete vxlan0
|
||||
|
||||
3. Show vxlan info
|
||||
# ip -d show vxlan0
|
||||
# ip -d link show vxlan0
|
||||
|
||||
It is possible to create, destroy and display the vxlan
|
||||
forwarding table using the new bridge command.
|
||||
|
@ -41,7 +41,7 @@ forwarding table using the new bridge command.
|
|||
# bridge fdb add to 00:17:42:8a:b4:05 dst 192.19.0.2 dev vxlan0
|
||||
|
||||
2. Delete forwarding table entry
|
||||
# bridge fdb delete 00:17:42:8a:b4:05
|
||||
# bridge fdb delete 00:17:42:8a:b4:05 dev vxlan0
|
||||
|
||||
3. Show forwarding table
|
||||
# bridge fdb show dev vxlan0
|
||||
|
|
28
MAINTAINERS
28
MAINTAINERS
|
@ -526,17 +526,17 @@ F: drivers/video/geode/
|
|||
F: arch/x86/include/asm/geode.h
|
||||
|
||||
AMD IOMMU (AMD-VI)
|
||||
M: Joerg Roedel <joerg.roedel@amd.com>
|
||||
M: Joerg Roedel <joro@8bytes.org>
|
||||
L: iommu@lists.linux-foundation.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git
|
||||
S: Supported
|
||||
S: Maintained
|
||||
F: drivers/iommu/amd_iommu*.[ch]
|
||||
F: include/linux/amd-iommu.h
|
||||
|
||||
AMD MICROCODE UPDATE SUPPORT
|
||||
M: Andreas Herrmann <andreas.herrmann3@amd.com>
|
||||
M: Andreas Herrmann <herrmann.der.user@googlemail.com>
|
||||
L: amd64-microcode@amd64.org
|
||||
S: Supported
|
||||
S: Maintained
|
||||
F: arch/x86/kernel/microcode_amd.c
|
||||
|
||||
AMS (Apple Motion Sensor) DRIVER
|
||||
|
@ -841,6 +841,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git
|
|||
F: arch/arm/mach-sa1100/jornada720.c
|
||||
F: arch/arm/mach-sa1100/include/mach/jornada720.h
|
||||
|
||||
ARM/IGEP MACHINE SUPPORT
|
||||
M: Enric Balletbo i Serra <eballetbo@gmail.com>
|
||||
M: Javier Martinez Canillas <javier@dowhile0.org>
|
||||
L: linux-omap@vger.kernel.org
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: arch/arm/mach-omap2/board-igep0020.c
|
||||
|
||||
ARM/INCOME PXA270 SUPPORT
|
||||
M: Marek Vasut <marek.vasut@gmail.com>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
|
@ -2708,10 +2716,10 @@ F: include/linux/edac.h
|
|||
|
||||
EDAC-AMD64
|
||||
M: Doug Thompson <dougthompson@xmission.com>
|
||||
M: Borislav Petkov <borislav.petkov@amd.com>
|
||||
M: Borislav Petkov <bp@alien8.de>
|
||||
L: linux-edac@vger.kernel.org
|
||||
W: bluesmoke.sourceforge.net
|
||||
S: Supported
|
||||
S: Maintained
|
||||
F: drivers/edac/amd64_edac*
|
||||
|
||||
EDAC-E752X
|
||||
|
@ -3753,7 +3761,7 @@ S: Maintained
|
|||
F: drivers/platform/x86/ideapad-laptop.c
|
||||
|
||||
IDE/ATAPI DRIVERS
|
||||
M: Borislav Petkov <petkovbb@gmail.com>
|
||||
M: Borislav Petkov <bp@alien8.de>
|
||||
L: linux-ide@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/cdrom/ide-cd
|
||||
|
@ -4282,8 +4290,8 @@ F: include/linux/lockd/
|
|||
F: include/linux/sunrpc/
|
||||
|
||||
KERNEL VIRTUAL MACHINE (KVM)
|
||||
M: Avi Kivity <avi@redhat.com>
|
||||
M: Marcelo Tosatti <mtosatti@redhat.com>
|
||||
M: Gleb Natapov <gleb@redhat.com>
|
||||
L: kvm@vger.kernel.org
|
||||
W: http://kvm.qumranet.com
|
||||
S: Supported
|
||||
|
@ -5415,7 +5423,7 @@ S: Maintained
|
|||
F: sound/drivers/opl4/
|
||||
|
||||
OPROFILE
|
||||
M: Robert Richter <robert.richter@amd.com>
|
||||
M: Robert Richter <rric@kernel.org>
|
||||
L: oprofile-list@lists.sf.net
|
||||
S: Maintained
|
||||
F: arch/*/include/asm/oprofile*.h
|
||||
|
@ -8207,7 +8215,7 @@ F: drivers/platform/x86
|
|||
|
||||
X86 MCE INFRASTRUCTURE
|
||||
M: Tony Luck <tony.luck@intel.com>
|
||||
M: Borislav Petkov <bp@amd64.org>
|
||||
M: Borislav Petkov <bp@alien8.de>
|
||||
L: linux-edac@vger.kernel.org
|
||||
S: Maintained
|
||||
F: arch/x86/kernel/cpu/mcheck/*
|
||||
|
|
|
@ -445,7 +445,7 @@ struct procfs_args {
|
|||
* unhappy with OSF UFS. [CHECKME]
|
||||
*/
|
||||
static int
|
||||
osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
|
||||
osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags)
|
||||
{
|
||||
int retval;
|
||||
struct cdfs_args tmp;
|
||||
|
@ -465,7 +465,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
|
|||
}
|
||||
|
||||
static int
|
||||
osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
|
||||
osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags)
|
||||
{
|
||||
int retval;
|
||||
struct cdfs_args tmp;
|
||||
|
@ -485,7 +485,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
|
|||
}
|
||||
|
||||
static int
|
||||
osf_procfs_mount(char *dirname, struct procfs_args __user *args, int flags)
|
||||
osf_procfs_mount(const char *dirname, struct procfs_args __user *args, int flags)
|
||||
{
|
||||
struct procfs_args tmp;
|
||||
|
||||
|
|
|
@ -713,8 +713,7 @@ static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type,
|
|||
break;
|
||||
case VPBE_ENC_CUSTOM_TIMINGS:
|
||||
if (pclock <= 27000000) {
|
||||
v |= DM644X_VPSS_MUXSEL_PLL2_MODE |
|
||||
DM644X_VPSS_DACCLKEN;
|
||||
v |= DM644X_VPSS_DACCLKEN;
|
||||
writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL));
|
||||
} else {
|
||||
/*
|
||||
|
|
|
@ -275,6 +275,9 @@ static int __init exynos_dma_init(void)
|
|||
exynos_pdma1_pdata.nr_valid_peri =
|
||||
ARRAY_SIZE(exynos4210_pdma1_peri);
|
||||
exynos_pdma1_pdata.peri_id = exynos4210_pdma1_peri;
|
||||
|
||||
if (samsung_rev() == EXYNOS4210_REV_0)
|
||||
exynos_mdma1_device.res.start = EXYNOS4_PA_S_MDMA1;
|
||||
} else if (soc_is_exynos4212() || soc_is_exynos4412()) {
|
||||
exynos_pdma0_pdata.nr_valid_peri =
|
||||
ARRAY_SIZE(exynos4212_pdma0_peri);
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
|
||||
#define EXYNOS4_PA_MDMA0 0x10810000
|
||||
#define EXYNOS4_PA_MDMA1 0x12850000
|
||||
#define EXYNOS4_PA_S_MDMA1 0x12840000
|
||||
#define EXYNOS4_PA_PDMA0 0x12680000
|
||||
#define EXYNOS4_PA_PDMA1 0x12690000
|
||||
#define EXYNOS5_PA_MDMA0 0x10800000
|
||||
|
|
|
@ -580,6 +580,11 @@ static void __init igep_wlan_bt_init(void)
|
|||
} else
|
||||
return;
|
||||
|
||||
/* Make sure that the GPIO pins are muxed correctly */
|
||||
omap_mux_init_gpio(igep_wlan_bt_gpios[0].gpio, OMAP_PIN_OUTPUT);
|
||||
omap_mux_init_gpio(igep_wlan_bt_gpios[1].gpio, OMAP_PIN_OUTPUT);
|
||||
omap_mux_init_gpio(igep_wlan_bt_gpios[2].gpio, OMAP_PIN_OUTPUT);
|
||||
|
||||
err = gpio_request_array(igep_wlan_bt_gpios,
|
||||
ARRAY_SIZE(igep_wlan_bt_gpios));
|
||||
if (err) {
|
||||
|
|
|
@ -64,30 +64,36 @@ void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
|
|||
struct spi_board_info *spi_bi = &ads7846_spi_board_info;
|
||||
int err;
|
||||
|
||||
err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown");
|
||||
if (err) {
|
||||
pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* If a board defines get_pendown_state() function, request the pendown
|
||||
* GPIO and set the GPIO debounce time.
|
||||
* If a board does not define the get_pendown_state() function, then
|
||||
* the ads7846 driver will setup the pendown GPIO itself.
|
||||
*/
|
||||
if (board_pdata && board_pdata->get_pendown_state) {
|
||||
err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown");
|
||||
if (err) {
|
||||
pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gpio_debounce)
|
||||
gpio_set_debounce(gpio_pendown, gpio_debounce);
|
||||
if (gpio_debounce)
|
||||
gpio_set_debounce(gpio_pendown, gpio_debounce);
|
||||
|
||||
gpio_export(gpio_pendown, 0);
|
||||
}
|
||||
|
||||
spi_bi->bus_num = bus_num;
|
||||
spi_bi->irq = gpio_to_irq(gpio_pendown);
|
||||
|
||||
ads7846_config.gpio_pendown = gpio_pendown;
|
||||
|
||||
if (board_pdata) {
|
||||
board_pdata->gpio_pendown = gpio_pendown;
|
||||
board_pdata->gpio_pendown_debounce = gpio_debounce;
|
||||
spi_bi->platform_data = board_pdata;
|
||||
if (board_pdata->get_pendown_state)
|
||||
gpio_export(gpio_pendown, 0);
|
||||
} else {
|
||||
ads7846_config.gpio_pendown = gpio_pendown;
|
||||
}
|
||||
|
||||
if (!board_pdata || (board_pdata && !board_pdata->get_pendown_state))
|
||||
gpio_free(gpio_pendown);
|
||||
|
||||
spi_register_board_info(&ads7846_spi_board_info, 1);
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -73,6 +73,7 @@ void __init omap4_pmic_init(const char *pmic_type,
|
|||
{
|
||||
/* PMIC part*/
|
||||
omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);
|
||||
omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT);
|
||||
omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data);
|
||||
|
||||
/* Register additional devices on i2c1 bus if needed */
|
||||
|
|
|
@ -26,12 +26,14 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-omap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <mach/irqs.h>
|
||||
#include <plat/i2c.h>
|
||||
#include <plat/omap-pm.h>
|
||||
#include <plat/omap_device.h>
|
||||
|
||||
#define OMAP_I2C_SIZE 0x3f
|
||||
|
@ -127,6 +129,16 @@ static inline int omap1_i2c_add_bus(int bus_id)
|
|||
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP2PLUS
|
||||
/*
|
||||
* XXX This function is a temporary compatibility wrapper - only
|
||||
* needed until the I2C driver can be converted to call
|
||||
* omap_pm_set_max_dev_wakeup_lat() and handle a return code.
|
||||
*/
|
||||
static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
|
||||
{
|
||||
omap_pm_set_max_mpu_wakeup_lat(dev, t);
|
||||
}
|
||||
|
||||
static inline int omap2_i2c_add_bus(int bus_id)
|
||||
{
|
||||
int l;
|
||||
|
@ -158,6 +170,15 @@ static inline int omap2_i2c_add_bus(int bus_id)
|
|||
dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr;
|
||||
pdata->flags = dev_attr->flags;
|
||||
|
||||
/*
|
||||
* When waiting for completion of a i2c transfer, we need to
|
||||
* set a wake up latency constraint for the MPU. This is to
|
||||
* ensure quick enough wakeup from idle, when transfer
|
||||
* completes.
|
||||
* Only omap3 has support for constraints
|
||||
*/
|
||||
if (cpu_is_omap34xx())
|
||||
pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
|
||||
pdev = omap_device_build(name, bus_id, oh, pdata,
|
||||
sizeof(struct omap_i2c_bus_platform_data),
|
||||
NULL, 0, 0);
|
||||
|
|
|
@ -41,7 +41,7 @@ struct k_sigaction {
|
|||
static inline void sigaddset(sigset_t *set, int _sig)
|
||||
{
|
||||
asm ("bfset %0{%1,#1}"
|
||||
: "+od" (*set)
|
||||
: "+o" (*set)
|
||||
: "id" ((_sig - 1) ^ 31)
|
||||
: "cc");
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ static inline void sigaddset(sigset_t *set, int _sig)
|
|||
static inline void sigdelset(sigset_t *set, int _sig)
|
||||
{
|
||||
asm ("bfclr %0{%1,#1}"
|
||||
: "+od" (*set)
|
||||
: "+o" (*set)
|
||||
: "id" ((_sig - 1) ^ 31)
|
||||
: "cc");
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ static inline int __gen_sigismember(sigset_t *set, int _sig)
|
|||
int ret;
|
||||
asm ("bfextu %1{%2,#1},%0"
|
||||
: "=d" (ret)
|
||||
: "od" (*set), "id" ((_sig-1) ^ 31)
|
||||
: "o" (*set), "id" ((_sig-1) ^ 31)
|
||||
: "cc");
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,8 @@ put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
|
|||
{
|
||||
compat_sigset_t s;
|
||||
|
||||
if (sz != sizeof *set) panic("put_sigset32()");
|
||||
if (sz != sizeof *set)
|
||||
return -EINVAL;
|
||||
sigset_64to32(&s, set);
|
||||
|
||||
return copy_to_user(up, &s, sizeof s);
|
||||
|
@ -77,7 +78,8 @@ get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
|
|||
compat_sigset_t s;
|
||||
int r;
|
||||
|
||||
if (sz != sizeof *set) panic("put_sigset32()");
|
||||
if (sz != sizeof *set)
|
||||
return -EINVAL;
|
||||
|
||||
if ((r = copy_from_user(&s, up, sz)) == 0) {
|
||||
sigset_32to64(set, &s);
|
||||
|
|
|
@ -73,6 +73,8 @@ static unsigned long get_shared_area(struct address_space *mapping,
|
|||
struct vm_area_struct *vma;
|
||||
int offset = mapping ? get_offset(mapping) : 0;
|
||||
|
||||
offset = (offset + (pgoff << PAGE_SHIFT)) & 0x3FF000;
|
||||
|
||||
addr = DCACHE_ALIGN(addr - offset) + offset;
|
||||
|
||||
for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
|
||||
|
|
|
@ -231,6 +231,12 @@
|
|||
interrupts = <2 7 0>;
|
||||
};
|
||||
|
||||
sclpc@3c00 {
|
||||
compatible = "fsl,mpc5200-lpbfifo";
|
||||
reg = <0x3c00 0x60>;
|
||||
interrupts = <2 23 0>;
|
||||
};
|
||||
|
||||
i2c@3d00 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
|
|
@ -86,12 +86,6 @@
|
|||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
sclpc@3c00 {
|
||||
compatible = "fsl,mpc5200-lpbfifo";
|
||||
reg = <0x3c00 0x60>;
|
||||
interrupts = <3 23 0>;
|
||||
};
|
||||
};
|
||||
|
||||
localbus {
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
psc@2000 { /* PSC1 in ac97 mode */
|
||||
audioplatform: psc@2000 { /* PSC1 in ac97 mode */
|
||||
compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97";
|
||||
cell-index = <0>;
|
||||
};
|
||||
|
@ -134,4 +134,9 @@
|
|||
localbus {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
sound {
|
||||
compatible = "phytec,pcm030-audio-fabric";
|
||||
asoc-platform = <&audioplatform>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -372,10 +372,11 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
|
|||
case MPC52xx_IRQ_L1_MAIN: irqchip = &mpc52xx_main_irqchip; break;
|
||||
case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break;
|
||||
case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break;
|
||||
default:
|
||||
pr_err("%s: invalid irq: virq=%i, l1=%i, l2=%i\n",
|
||||
__func__, virq, l1irq, l2irq);
|
||||
return -EINVAL;
|
||||
case MPC52xx_IRQ_L1_CRIT:
|
||||
pr_warn("%s: Critical IRQ #%d is unsupported! Nopping it.\n",
|
||||
__func__, l2irq);
|
||||
irq_set_chip(virq, &no_irq_chip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
irq_set_chip_and_handler(virq, irqchip, handle_level_irq);
|
||||
|
|
|
@ -63,10 +63,13 @@ extern char *of_console_options;
|
|||
extern void irq_trans_init(struct device_node *dp);
|
||||
extern char *build_path_component(struct device_node *dp);
|
||||
|
||||
/* SPARC has a local implementation */
|
||||
/* SPARC has local implementations */
|
||||
extern int of_address_to_resource(struct device_node *dev, int index,
|
||||
struct resource *r);
|
||||
#define of_address_to_resource of_address_to_resource
|
||||
|
||||
void __iomem *of_iomap(struct device_node *node, int index);
|
||||
#define of_iomap of_iomap
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _SPARC_PROM_H */
|
||||
|
|
|
@ -295,9 +295,7 @@ void do_rt_sigreturn(struct pt_regs *regs)
|
|||
err |= restore_fpu_state(regs, fpu_save);
|
||||
|
||||
err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
|
||||
err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf);
|
||||
|
||||
if (err)
|
||||
if (err || do_sigaltstack(&sf->stack, NULL, (unsigned long)sf) == -EFAULT)
|
||||
goto segv;
|
||||
|
||||
err |= __get_user(rwin_save, &sf->rwin_save);
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <asm/setup.h>
|
||||
#include <asm/desc.h>
|
||||
|
||||
#undef memcpy /* Use memcpy from misc.c */
|
||||
|
||||
#include "eboot.h"
|
||||
|
||||
static efi_system_table_t *sys_table;
|
||||
|
|
|
@ -476,6 +476,3 @@ die:
|
|||
setup_corrupt:
|
||||
.byte 7
|
||||
.string "No setup signature found...\n"
|
||||
|
||||
.data
|
||||
dummy: .long 0
|
||||
|
|
|
@ -205,21 +205,14 @@ static inline bool user_64bit_mode(struct pt_regs *regs)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode
|
||||
* when it traps. The previous stack will be directly underneath the saved
|
||||
* registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'.
|
||||
*
|
||||
* This is valid only for kernel mode traps.
|
||||
*/
|
||||
#ifdef CONFIG_X86_32
|
||||
extern unsigned long kernel_stack_pointer(struct pt_regs *regs);
|
||||
#else
|
||||
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
|
||||
{
|
||||
#ifdef CONFIG_X86_32
|
||||
return (unsigned long)(®s->sp);
|
||||
#else
|
||||
return regs->sp;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#define GET_IP(regs) ((regs)->ip)
|
||||
#define GET_FP(regs) ((regs)->bp)
|
||||
|
|
|
@ -631,6 +631,20 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The way access filter has a performance penalty on some workloads.
|
||||
* Disable it on the affected CPUs.
|
||||
*/
|
||||
if ((c->x86 == 0x15) &&
|
||||
(c->x86_model >= 0x02) && (c->x86_model < 0x20)) {
|
||||
u64 val;
|
||||
|
||||
if (!rdmsrl_safe(0xc0011021, &val) && !(val & 0x1E)) {
|
||||
val |= 0x1E;
|
||||
wrmsrl_safe(0xc0011021, val);
|
||||
}
|
||||
}
|
||||
|
||||
cpu_detect_cache_sizes(c);
|
||||
|
||||
/* Multi core CPU? */
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
* Written by Jacob Shin - AMD, Inc.
|
||||
*
|
||||
* Support: borislav.petkov@amd.com
|
||||
* Maintained by: Borislav Petkov <bp@alien8.de>
|
||||
*
|
||||
* April 2006
|
||||
* - added support for AMD Family 0x10 processors
|
||||
|
|
|
@ -285,34 +285,39 @@ void cmci_clear(void)
|
|||
raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
|
||||
}
|
||||
|
||||
static long cmci_rediscover_work_func(void *arg)
|
||||
{
|
||||
int banks;
|
||||
|
||||
/* Recheck banks in case CPUs don't all have the same */
|
||||
if (cmci_supported(&banks))
|
||||
cmci_discover(banks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* After a CPU went down cycle through all the others and rediscover
|
||||
* Must run in process context.
|
||||
*/
|
||||
void cmci_rediscover(int dying)
|
||||
{
|
||||
int banks;
|
||||
int cpu;
|
||||
cpumask_var_t old;
|
||||
int cpu, banks;
|
||||
|
||||
if (!cmci_supported(&banks))
|
||||
return;
|
||||
if (!alloc_cpumask_var(&old, GFP_KERNEL))
|
||||
return;
|
||||
cpumask_copy(old, ¤t->cpus_allowed);
|
||||
|
||||
for_each_online_cpu(cpu) {
|
||||
if (cpu == dying)
|
||||
continue;
|
||||
if (set_cpus_allowed_ptr(current, cpumask_of(cpu)))
|
||||
continue;
|
||||
/* Recheck banks in case CPUs don't all have the same */
|
||||
if (cmci_supported(&banks))
|
||||
cmci_discover(banks);
|
||||
}
|
||||
|
||||
set_cpus_allowed_ptr(current, old);
|
||||
free_cpumask_var(old);
|
||||
if (cpu == smp_processor_id()) {
|
||||
cmci_rediscover_work_func(NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
work_on_cpu(cpu, cmci_rediscover_work_func, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -995,8 +995,8 @@ END(interrupt)
|
|||
*/
|
||||
.p2align CONFIG_X86_L1_CACHE_SHIFT
|
||||
common_interrupt:
|
||||
ASM_CLAC
|
||||
XCPT_FRAME
|
||||
ASM_CLAC
|
||||
addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */
|
||||
interrupt do_IRQ
|
||||
/* 0(%rsp): old_rsp-ARGOFFSET */
|
||||
|
@ -1135,8 +1135,8 @@ END(common_interrupt)
|
|||
*/
|
||||
.macro apicinterrupt num sym do_sym
|
||||
ENTRY(\sym)
|
||||
ASM_CLAC
|
||||
INTR_FRAME
|
||||
ASM_CLAC
|
||||
pushq_cfi $~(\num)
|
||||
.Lcommon_\sym:
|
||||
interrupt \do_sym
|
||||
|
@ -1190,8 +1190,8 @@ apicinterrupt IRQ_WORK_VECTOR \
|
|||
*/
|
||||
.macro zeroentry sym do_sym
|
||||
ENTRY(\sym)
|
||||
ASM_CLAC
|
||||
INTR_FRAME
|
||||
ASM_CLAC
|
||||
PARAVIRT_ADJUST_EXCEPTION_FRAME
|
||||
pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */
|
||||
subq $ORIG_RAX-R15, %rsp
|
||||
|
@ -1208,8 +1208,8 @@ END(\sym)
|
|||
|
||||
.macro paranoidzeroentry sym do_sym
|
||||
ENTRY(\sym)
|
||||
ASM_CLAC
|
||||
INTR_FRAME
|
||||
ASM_CLAC
|
||||
PARAVIRT_ADJUST_EXCEPTION_FRAME
|
||||
pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */
|
||||
subq $ORIG_RAX-R15, %rsp
|
||||
|
@ -1227,8 +1227,8 @@ END(\sym)
|
|||
#define INIT_TSS_IST(x) PER_CPU_VAR(init_tss) + (TSS_ist + ((x) - 1) * 8)
|
||||
.macro paranoidzeroentry_ist sym do_sym ist
|
||||
ENTRY(\sym)
|
||||
ASM_CLAC
|
||||
INTR_FRAME
|
||||
ASM_CLAC
|
||||
PARAVIRT_ADJUST_EXCEPTION_FRAME
|
||||
pushq_cfi $-1 /* ORIG_RAX: no syscall to restart */
|
||||
subq $ORIG_RAX-R15, %rsp
|
||||
|
@ -1247,8 +1247,8 @@ END(\sym)
|
|||
|
||||
.macro errorentry sym do_sym
|
||||
ENTRY(\sym)
|
||||
ASM_CLAC
|
||||
XCPT_FRAME
|
||||
ASM_CLAC
|
||||
PARAVIRT_ADJUST_EXCEPTION_FRAME
|
||||
subq $ORIG_RAX-R15, %rsp
|
||||
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
|
||||
|
@ -1266,8 +1266,8 @@ END(\sym)
|
|||
/* error code is on the stack already */
|
||||
.macro paranoiderrorentry sym do_sym
|
||||
ENTRY(\sym)
|
||||
ASM_CLAC
|
||||
XCPT_FRAME
|
||||
ASM_CLAC
|
||||
PARAVIRT_ADJUST_EXCEPTION_FRAME
|
||||
subq $ORIG_RAX-R15, %rsp
|
||||
CFI_ADJUST_CFA_OFFSET ORIG_RAX-R15
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
* Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
|
||||
*
|
||||
* Maintainers:
|
||||
* Andreas Herrmann <andreas.herrmann3@amd.com>
|
||||
* Borislav Petkov <borislav.petkov@amd.com>
|
||||
* Andreas Herrmann <herrmann.der.user@googlemail.com>
|
||||
* Borislav Petkov <bp@alien8.de>
|
||||
*
|
||||
* This driver allows to upgrade microcode on F10h AMD
|
||||
* CPUs and later.
|
||||
|
@ -190,6 +190,7 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size,
|
|||
#define F1XH_MPB_MAX_SIZE 2048
|
||||
#define F14H_MPB_MAX_SIZE 1824
|
||||
#define F15H_MPB_MAX_SIZE 4096
|
||||
#define F16H_MPB_MAX_SIZE 3458
|
||||
|
||||
switch (c->x86) {
|
||||
case 0x14:
|
||||
|
@ -198,6 +199,9 @@ static unsigned int verify_patch_size(int cpu, u32 patch_size,
|
|||
case 0x15:
|
||||
max_size = F15H_MPB_MAX_SIZE;
|
||||
break;
|
||||
case 0x16:
|
||||
max_size = F16H_MPB_MAX_SIZE;
|
||||
break;
|
||||
default:
|
||||
max_size = F1XH_MPB_MAX_SIZE;
|
||||
break;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/perf_event.h>
|
||||
#include <linux/hw_breakpoint.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
@ -166,6 +167,35 @@ static inline bool invalid_selector(u16 value)
|
|||
|
||||
#define FLAG_MASK FLAG_MASK_32
|
||||
|
||||
/*
|
||||
* X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode
|
||||
* when it traps. The previous stack will be directly underneath the saved
|
||||
* registers, and 'sp/ss' won't even have been saved. Thus the '®s->sp'.
|
||||
*
|
||||
* Now, if the stack is empty, '®s->sp' is out of range. In this
|
||||
* case we try to take the previous stack. To always return a non-null
|
||||
* stack pointer we fall back to regs as stack if no previous stack
|
||||
* exists.
|
||||
*
|
||||
* This is valid only for kernel mode traps.
|
||||
*/
|
||||
unsigned long kernel_stack_pointer(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long context = (unsigned long)regs & ~(THREAD_SIZE - 1);
|
||||
unsigned long sp = (unsigned long)®s->sp;
|
||||
struct thread_info *tinfo;
|
||||
|
||||
if (context == (sp & ~(THREAD_SIZE - 1)))
|
||||
return sp;
|
||||
|
||||
tinfo = (struct thread_info *)context;
|
||||
if (tinfo->previous_esp)
|
||||
return tinfo->previous_esp;
|
||||
|
||||
return (unsigned long)regs;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(kernel_stack_pointer);
|
||||
|
||||
static unsigned long *pt_regs_access(struct pt_regs *regs, unsigned long regno)
|
||||
{
|
||||
BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0);
|
||||
|
|
|
@ -197,7 +197,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
|
|||
}
|
||||
|
||||
if (end == TLB_FLUSH_ALL || tlb_flushall_shift == -1
|
||||
|| vmflag == VM_HUGETLB) {
|
||||
|| vmflag & VM_HUGETLB) {
|
||||
local_flush_tlb();
|
||||
goto flush_all;
|
||||
}
|
||||
|
|
|
@ -115,6 +115,16 @@ static void sata_revid_read(struct sim_dev_reg *reg, u32 *value)
|
|||
reg_read(reg, value);
|
||||
}
|
||||
|
||||
static void reg_noirq_read(struct sim_dev_reg *reg, u32 *value)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&pci_config_lock, flags);
|
||||
/* force interrupt pin value to 0 */
|
||||
*value = reg->sim_reg.value & 0xfff00ff;
|
||||
raw_spin_unlock_irqrestore(&pci_config_lock, flags);
|
||||
}
|
||||
|
||||
static struct sim_dev_reg bus1_fixups[] = {
|
||||
DEFINE_REG(2, 0, 0x10, (16*MB), reg_init, reg_read, reg_write)
|
||||
DEFINE_REG(2, 0, 0x14, (256), reg_init, reg_read, reg_write)
|
||||
|
@ -144,6 +154,7 @@ static struct sim_dev_reg bus1_fixups[] = {
|
|||
DEFINE_REG(11, 5, 0x10, (64*KB), reg_init, reg_read, reg_write)
|
||||
DEFINE_REG(11, 6, 0x10, (256), reg_init, reg_read, reg_write)
|
||||
DEFINE_REG(11, 7, 0x10, (64*KB), reg_init, reg_read, reg_write)
|
||||
DEFINE_REG(11, 7, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
|
||||
DEFINE_REG(12, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
|
||||
DEFINE_REG(12, 0, 0x14, (256), reg_init, reg_read, reg_write)
|
||||
DEFINE_REG(12, 1, 0x10, (1024), reg_init, reg_read, reg_write)
|
||||
|
@ -161,8 +172,10 @@ static struct sim_dev_reg bus1_fixups[] = {
|
|||
DEFINE_REG(16, 0, 0x10, (64*KB), reg_init, reg_read, reg_write)
|
||||
DEFINE_REG(16, 0, 0x14, (64*MB), reg_init, reg_read, reg_write)
|
||||
DEFINE_REG(16, 0, 0x18, (64*MB), reg_init, reg_read, reg_write)
|
||||
DEFINE_REG(16, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
|
||||
DEFINE_REG(17, 0, 0x10, (128*KB), reg_init, reg_read, reg_write)
|
||||
DEFINE_REG(18, 0, 0x10, (1*KB), reg_init, reg_read, reg_write)
|
||||
DEFINE_REG(18, 0, 0x3c, 256, reg_init, reg_noirq_read, reg_write)
|
||||
};
|
||||
|
||||
static void __init init_sim_regs(void)
|
||||
|
|
|
@ -21,12 +21,25 @@
|
|||
#include <asm/i8259.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/io_apic.h>
|
||||
#include <asm/emergency-restart.h>
|
||||
|
||||
static int ce4100_i8042_detect(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The CE4100 platform has an internal 8051 Microcontroller which is
|
||||
* responsible for signaling to the external Power Management Unit the
|
||||
* intention to reset, reboot or power off the system. This 8051 device has
|
||||
* its command register mapped at I/O port 0xcf9 and the value 0x4 is used
|
||||
* to power off the system.
|
||||
*/
|
||||
static void ce4100_power_off(void)
|
||||
{
|
||||
outb(0x4, 0xcf9);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SERIAL_8250
|
||||
|
||||
static unsigned int mem_serial_in(struct uart_port *p, int offset)
|
||||
|
@ -139,8 +152,19 @@ void __init x86_ce4100_early_setup(void)
|
|||
x86_init.mpparse.find_smp_config = x86_init_noop;
|
||||
x86_init.pci.init = ce4100_pci_init;
|
||||
|
||||
/*
|
||||
* By default, the reboot method is ACPI which is supported by the
|
||||
* CE4100 bootloader CEFDK using FADT.ResetReg Address and ResetValue
|
||||
* the bootloader will however issue a system power off instead of
|
||||
* reboot. By using BOOT_KBD we ensure proper system reboot as
|
||||
* expected.
|
||||
*/
|
||||
reboot_type = BOOT_KBD;
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
x86_init.pci.init_irq = sdv_pci_init;
|
||||
x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc_nocheck;
|
||||
#endif
|
||||
|
||||
pm_power_off = ce4100_power_off;
|
||||
}
|
||||
|
|
|
@ -52,11 +52,17 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
|
|||
rq_end_io_fn *done)
|
||||
{
|
||||
int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
|
||||
bool is_pm_resume;
|
||||
|
||||
WARN_ON(irqs_disabled());
|
||||
|
||||
rq->rq_disk = bd_disk;
|
||||
rq->end_io = done;
|
||||
/*
|
||||
* need to check this before __blk_run_queue(), because rq can
|
||||
* be freed before that returns.
|
||||
*/
|
||||
is_pm_resume = rq->cmd_type == REQ_TYPE_PM_RESUME;
|
||||
|
||||
spin_lock_irq(q->queue_lock);
|
||||
|
||||
|
@ -71,7 +77,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
|
|||
__elv_add_request(q, rq, where);
|
||||
__blk_run_queue(q);
|
||||
/* the queue is stopped so it won't be run */
|
||||
if (rq->cmd_type == REQ_TYPE_PM_RESUME)
|
||||
if (is_pm_resume)
|
||||
q->request_fn(q);
|
||||
spin_unlock_irq(q->queue_lock);
|
||||
}
|
||||
|
|
|
@ -238,7 +238,7 @@ static int __devexit ahci_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int ahci_suspend(struct device *dev)
|
||||
{
|
||||
struct ahci_platform_data *pdata = dev_get_platdata(dev);
|
||||
|
|
|
@ -1105,10 +1105,15 @@ static int ata_acpi_bind_device(struct ata_port *ap, struct scsi_device *sdev,
|
|||
struct acpi_device *acpi_dev;
|
||||
struct acpi_device_power_state *states;
|
||||
|
||||
if (ap->flags & ATA_FLAG_ACPI_SATA)
|
||||
ata_dev = &ap->link.device[sdev->channel];
|
||||
else
|
||||
if (ap->flags & ATA_FLAG_ACPI_SATA) {
|
||||
if (!sata_pmp_attached(ap))
|
||||
ata_dev = &ap->link.device[sdev->id];
|
||||
else
|
||||
ata_dev = &ap->pmp_link[sdev->channel].device[sdev->id];
|
||||
}
|
||||
else {
|
||||
ata_dev = &ap->link.device[sdev->id];
|
||||
}
|
||||
|
||||
*handle = ata_dev_acpi_handle(ata_dev);
|
||||
|
||||
|
|
|
@ -2942,6 +2942,10 @@ const struct ata_timing *ata_timing_find_mode(u8 xfer_mode)
|
|||
|
||||
if (xfer_mode == t->mode)
|
||||
return t;
|
||||
|
||||
WARN_ONCE(true, "%s: unable to find timing for xfer_mode 0x%x\n",
|
||||
__func__, xfer_mode);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1052,6 +1052,8 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
|
|||
{
|
||||
sdev->use_10_for_rw = 1;
|
||||
sdev->use_10_for_ms = 1;
|
||||
sdev->no_report_opcodes = 1;
|
||||
sdev->no_write_same = 1;
|
||||
|
||||
/* Schedule policy is determined by ->qc_defer() callback and
|
||||
* it needs to see every deferred qc. Set dev_blocked to 1 to
|
||||
|
|
|
@ -317,6 +317,12 @@ static int cf_init(struct arasan_cf_dev *acdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_set_rate(acdev->clk, 166000000);
|
||||
if (ret) {
|
||||
dev_warn(acdev->host->dev, "clock set rate failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&acdev->host->lock, flags);
|
||||
/* configure CF interface clock */
|
||||
writel((pdata->cf_if_clk <= CF_IF_CLK_200M) ? pdata->cf_if_clk :
|
||||
|
@ -908,7 +914,7 @@ static int __devexit arasan_cf_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int arasan_cf_suspend(struct device *dev)
|
||||
{
|
||||
struct ata_host *host = dev_get_drvdata(dev);
|
||||
|
|
|
@ -260,7 +260,7 @@ static const struct of_device_id ahci_of_match[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(of, ahci_of_match);
|
||||
|
||||
static int __init ahci_highbank_probe(struct platform_device *pdev)
|
||||
static int __devinit ahci_highbank_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ahci_host_priv *hpriv;
|
||||
|
@ -378,7 +378,7 @@ static int __devexit ahci_highbank_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int ahci_highbank_suspend(struct device *dev)
|
||||
{
|
||||
struct ata_host *host = dev_get_drvdata(dev);
|
||||
|
|
|
@ -142,6 +142,39 @@ static int k2_sata_scr_write(struct ata_link *link,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int k2_sata_softreset(struct ata_link *link,
|
||||
unsigned int *class, unsigned long deadline)
|
||||
{
|
||||
u8 dmactl;
|
||||
void __iomem *mmio = link->ap->ioaddr.bmdma_addr;
|
||||
|
||||
dmactl = readb(mmio + ATA_DMA_CMD);
|
||||
|
||||
/* Clear the start bit */
|
||||
if (dmactl & ATA_DMA_START) {
|
||||
dmactl &= ~ATA_DMA_START;
|
||||
writeb(dmactl, mmio + ATA_DMA_CMD);
|
||||
}
|
||||
|
||||
return ata_sff_softreset(link, class, deadline);
|
||||
}
|
||||
|
||||
static int k2_sata_hardreset(struct ata_link *link,
|
||||
unsigned int *class, unsigned long deadline)
|
||||
{
|
||||
u8 dmactl;
|
||||
void __iomem *mmio = link->ap->ioaddr.bmdma_addr;
|
||||
|
||||
dmactl = readb(mmio + ATA_DMA_CMD);
|
||||
|
||||
/* Clear the start bit */
|
||||
if (dmactl & ATA_DMA_START) {
|
||||
dmactl &= ~ATA_DMA_START;
|
||||
writeb(dmactl, mmio + ATA_DMA_CMD);
|
||||
}
|
||||
|
||||
return sata_sff_hardreset(link, class, deadline);
|
||||
}
|
||||
|
||||
static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
|
||||
{
|
||||
|
@ -346,6 +379,8 @@ static struct scsi_host_template k2_sata_sht = {
|
|||
|
||||
static struct ata_port_operations k2_sata_ops = {
|
||||
.inherits = &ata_bmdma_port_ops,
|
||||
.softreset = k2_sata_softreset,
|
||||
.hardreset = k2_sata_hardreset,
|
||||
.sff_tf_load = k2_sata_tf_load,
|
||||
.sff_tf_read = k2_sata_tf_read,
|
||||
.sff_check_status = k2_stat_check_status,
|
||||
|
|
|
@ -451,7 +451,7 @@ int dev_pm_qos_add_ancestor_request(struct device *dev,
|
|||
if (ancestor)
|
||||
error = dev_pm_qos_add_request(ancestor, req, value);
|
||||
|
||||
if (error)
|
||||
if (error < 0)
|
||||
req->dev = NULL;
|
||||
|
||||
return error;
|
||||
|
|
|
@ -935,7 +935,7 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail)
|
|||
|
||||
/* cf. http://lkml.org/lkml/2006/10/31/28 */
|
||||
if (!fastfail)
|
||||
q->request_fn(q);
|
||||
__blk_run_queue(q);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -4330,6 +4330,7 @@ static int __init do_floppy_init(void)
|
|||
out_unreg_blkdev:
|
||||
unregister_blkdev(FLOPPY_MAJOR, "fd");
|
||||
out_put_disk:
|
||||
destroy_workqueue(floppy_wq);
|
||||
for (drive = 0; drive < N_DRIVE; drive++) {
|
||||
if (!disks[drive])
|
||||
break;
|
||||
|
@ -4340,7 +4341,6 @@ static int __init do_floppy_init(void)
|
|||
}
|
||||
put_disk(disks[drive]);
|
||||
}
|
||||
destroy_workqueue(floppy_wq);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -4555,6 +4555,8 @@ static void __exit floppy_module_exit(void)
|
|||
unregister_blkdev(FLOPPY_MAJOR, "fd");
|
||||
platform_driver_unregister(&floppy_driver);
|
||||
|
||||
destroy_workqueue(floppy_wq);
|
||||
|
||||
for (drive = 0; drive < N_DRIVE; drive++) {
|
||||
del_timer_sync(&motor_off_timer[drive]);
|
||||
|
||||
|
@ -4578,7 +4580,6 @@ static void __exit floppy_module_exit(void)
|
|||
|
||||
cancel_delayed_work_sync(&fd_timeout);
|
||||
cancel_delayed_work_sync(&fd_timer);
|
||||
destroy_workqueue(floppy_wq);
|
||||
|
||||
if (atomic_read(&usage_count))
|
||||
floppy_release_irq_and_dma();
|
||||
|
|
|
@ -559,7 +559,7 @@ static void mtip_timeout_function(unsigned long int data)
|
|||
struct mtip_cmd *command;
|
||||
int tag, cmdto_cnt = 0;
|
||||
unsigned int bit, group;
|
||||
unsigned int num_command_slots = port->dd->slot_groups * 32;
|
||||
unsigned int num_command_slots;
|
||||
unsigned long to, tagaccum[SLOTBITS_IN_LONGS];
|
||||
|
||||
if (unlikely(!port))
|
||||
|
@ -572,6 +572,7 @@ static void mtip_timeout_function(unsigned long int data)
|
|||
}
|
||||
/* clear the tag accumulator */
|
||||
memset(tagaccum, 0, SLOTBITS_IN_LONGS * sizeof(long));
|
||||
num_command_slots = port->dd->slot_groups * 32;
|
||||
|
||||
for (tag = 0; tag < num_command_slots; tag++) {
|
||||
/*
|
||||
|
@ -2218,8 +2219,8 @@ static int exec_drive_taskfile(struct driver_data *dd,
|
|||
fis.device);
|
||||
|
||||
/* check for erase mode support during secure erase.*/
|
||||
if ((fis.command == ATA_CMD_SEC_ERASE_UNIT)
|
||||
&& (outbuf[0] & MTIP_SEC_ERASE_MODE)) {
|
||||
if ((fis.command == ATA_CMD_SEC_ERASE_UNIT) && outbuf &&
|
||||
(outbuf[0] & MTIP_SEC_ERASE_MODE)) {
|
||||
erasemode = 1;
|
||||
}
|
||||
|
||||
|
@ -2439,7 +2440,7 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd,
|
|||
* return value
|
||||
* None
|
||||
*/
|
||||
static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
|
||||
static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector,
|
||||
int nsect, int nents, int tag, void *callback,
|
||||
void *data, int dir)
|
||||
{
|
||||
|
@ -2447,6 +2448,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
|
|||
struct mtip_port *port = dd->port;
|
||||
struct mtip_cmd *command = &port->commands[tag];
|
||||
int dma_dir = (dir == READ) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
|
||||
u64 start = sector;
|
||||
|
||||
/* Map the scatter list for DMA access */
|
||||
nents = dma_map_sg(&dd->pdev->dev, command->sg, nents, dma_dir);
|
||||
|
@ -2465,8 +2467,12 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
|
|||
fis->opts = 1 << 7;
|
||||
fis->command =
|
||||
(dir == READ ? ATA_CMD_FPDMA_READ : ATA_CMD_FPDMA_WRITE);
|
||||
*((unsigned int *) &fis->lba_low) = (start & 0xFFFFFF);
|
||||
*((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xFFFFFF);
|
||||
fis->lba_low = start & 0xFF;
|
||||
fis->lba_mid = (start >> 8) & 0xFF;
|
||||
fis->lba_hi = (start >> 16) & 0xFF;
|
||||
fis->lba_low_ex = (start >> 24) & 0xFF;
|
||||
fis->lba_mid_ex = (start >> 32) & 0xFF;
|
||||
fis->lba_hi_ex = (start >> 40) & 0xFF;
|
||||
fis->device = 1 << 6;
|
||||
fis->features = nsect & 0xFF;
|
||||
fis->features_ex = (nsect >> 8) & 0xFF;
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#define PCIE_CONFIG_EXT_DEVICE_CONTROL_OFFSET 0x48
|
||||
|
||||
/* check for erase mode support during secure erase */
|
||||
#define MTIP_SEC_ERASE_MODE 0x3
|
||||
#define MTIP_SEC_ERASE_MODE 0x2
|
||||
|
||||
/* # of times to retry timed out/failed IOs */
|
||||
#define MTIP_MAX_RETRIES 2
|
||||
|
@ -155,14 +155,14 @@ enum {
|
|||
MTIP_DDF_REBUILD_FAILED_BIT = 8,
|
||||
};
|
||||
|
||||
__packed struct smart_attr{
|
||||
struct smart_attr {
|
||||
u8 attr_id;
|
||||
u16 flags;
|
||||
u8 cur;
|
||||
u8 worst;
|
||||
u32 data;
|
||||
u8 res[3];
|
||||
};
|
||||
} __packed;
|
||||
|
||||
/* Register Frame Information Structure (FIS), host to device. */
|
||||
struct host_to_dev_fis {
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
* detection. The mods to Rev F required more family
|
||||
* information detection.
|
||||
*
|
||||
* Changes/Fixes by Borislav Petkov <borislav.petkov@amd.com>:
|
||||
* Changes/Fixes by Borislav Petkov <bp@alien8.de>:
|
||||
* - misc fixes and code cleanups
|
||||
*
|
||||
* This module is based on the following documents
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* 2007 (c) MontaVista Software, Inc.
|
||||
* 2010 (c) Advanced Micro Devices Inc.
|
||||
* Borislav Petkov <borislav.petkov@amd.com>
|
||||
* Borislav Petkov <bp@alien8.de>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* This file may be distributed under the terms of the GNU General Public
|
||||
* License version 2.
|
||||
*
|
||||
* Copyright (c) 2010: Borislav Petkov <borislav.petkov@amd.com>
|
||||
* Copyright (c) 2010: Borislav Petkov <bp@alien8.de>
|
||||
* Advanced Micro Devices Inc.
|
||||
*/
|
||||
|
||||
|
@ -168,6 +168,6 @@ module_init(edac_init_mce_inject);
|
|||
module_exit(edac_exit_mce_inject);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Borislav Petkov <borislav.petkov@amd.com>");
|
||||
MODULE_AUTHOR("Borislav Petkov <bp@alien8.de>");
|
||||
MODULE_AUTHOR("AMD Inc.");
|
||||
MODULE_DESCRIPTION("MCE injection facility for testing MCE decoding");
|
||||
|
|
|
@ -1546,6 +1546,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
|
|||
struct sbp2_logical_unit *lu = sdev->hostdata;
|
||||
|
||||
sdev->use_10_for_rw = 1;
|
||||
sdev->no_report_opcodes = 1;
|
||||
sdev->no_write_same = 1;
|
||||
|
||||
if (sbp2_param_exclusive_login)
|
||||
sdev->manage_start_stop = 1;
|
||||
|
|
|
@ -466,7 +466,7 @@ config GPIO_ADP5588_IRQ
|
|||
|
||||
config GPIO_ADNP
|
||||
tristate "Avionic Design N-bit GPIO expander"
|
||||
depends on I2C && OF
|
||||
depends on I2C && OF_GPIO
|
||||
help
|
||||
This option enables support for N GPIOs found on Avionic Design
|
||||
I2C GPIO expanders. The register space will be extended by powers
|
||||
|
|
|
@ -77,7 +77,7 @@ struct mcp23s08_driver_data {
|
|||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#ifdef CONFIG_I2C
|
||||
#if IS_ENABLED(CONFIG_I2C)
|
||||
|
||||
static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg)
|
||||
{
|
||||
|
@ -399,7 +399,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
|
|||
break;
|
||||
#endif /* CONFIG_SPI_MASTER */
|
||||
|
||||
#ifdef CONFIG_I2C
|
||||
#if IS_ENABLED(CONFIG_I2C)
|
||||
case MCP_TYPE_008:
|
||||
mcp->ops = &mcp23008_ops;
|
||||
mcp->chip.ngpio = 8;
|
||||
|
@ -473,7 +473,7 @@ static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
|
|||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#ifdef CONFIG_I2C
|
||||
#if IS_ENABLED(CONFIG_I2C)
|
||||
|
||||
static int __devinit mcp230xx_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
|
|
|
@ -92,6 +92,11 @@ static inline void __iomem *mvebu_gpioreg_out(struct mvebu_gpio_chip *mvchip)
|
|||
return mvchip->membase + GPIO_OUT_OFF;
|
||||
}
|
||||
|
||||
static inline void __iomem *mvebu_gpioreg_blink(struct mvebu_gpio_chip *mvchip)
|
||||
{
|
||||
return mvchip->membase + GPIO_BLINK_EN_OFF;
|
||||
}
|
||||
|
||||
static inline void __iomem *mvebu_gpioreg_io_conf(struct mvebu_gpio_chip *mvchip)
|
||||
{
|
||||
return mvchip->membase + GPIO_IO_CONF_OFF;
|
||||
|
@ -206,6 +211,23 @@ static int mvebu_gpio_get(struct gpio_chip *chip, unsigned pin)
|
|||
return (u >> pin) & 1;
|
||||
}
|
||||
|
||||
static void mvebu_gpio_blink(struct gpio_chip *chip, unsigned pin, int value)
|
||||
{
|
||||
struct mvebu_gpio_chip *mvchip =
|
||||
container_of(chip, struct mvebu_gpio_chip, chip);
|
||||
unsigned long flags;
|
||||
u32 u;
|
||||
|
||||
spin_lock_irqsave(&mvchip->lock, flags);
|
||||
u = readl_relaxed(mvebu_gpioreg_blink(mvchip));
|
||||
if (value)
|
||||
u |= 1 << pin;
|
||||
else
|
||||
u &= ~(1 << pin);
|
||||
writel_relaxed(u, mvebu_gpioreg_blink(mvchip));
|
||||
spin_unlock_irqrestore(&mvchip->lock, flags);
|
||||
}
|
||||
|
||||
static int mvebu_gpio_direction_input(struct gpio_chip *chip, unsigned pin)
|
||||
{
|
||||
struct mvebu_gpio_chip *mvchip =
|
||||
|
@ -244,6 +266,7 @@ static int mvebu_gpio_direction_output(struct gpio_chip *chip, unsigned pin,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
mvebu_gpio_blink(chip, pin, 0);
|
||||
mvebu_gpio_set(chip, pin, value);
|
||||
|
||||
spin_lock_irqsave(&mvchip->lock, flags);
|
||||
|
|
|
@ -49,13 +49,7 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
|
|||
if (chan->vblank.crtc != crtc)
|
||||
continue;
|
||||
|
||||
if (nv_device(priv)->chipset == 0x50) {
|
||||
nv_wr32(priv, 0x001704, chan->vblank.channel);
|
||||
nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
|
||||
bar->flush(bar);
|
||||
nv_wr32(priv, 0x001570, chan->vblank.offset);
|
||||
nv_wr32(priv, 0x001574, chan->vblank.value);
|
||||
} else {
|
||||
if (nv_device(priv)->chipset >= 0xc0) {
|
||||
nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel);
|
||||
bar->flush(bar);
|
||||
nv_wr32(priv, 0x06000c,
|
||||
|
@ -63,6 +57,17 @@ nv50_disp_intr_vblank(struct nv50_disp_priv *priv, int crtc)
|
|||
nv_wr32(priv, 0x060010,
|
||||
lower_32_bits(chan->vblank.offset));
|
||||
nv_wr32(priv, 0x060014, chan->vblank.value);
|
||||
} else {
|
||||
nv_wr32(priv, 0x001704, chan->vblank.channel);
|
||||
nv_wr32(priv, 0x001710, 0x80000000 | chan->vblank.ctxdma);
|
||||
bar->flush(bar);
|
||||
if (nv_device(priv)->chipset == 0x50) {
|
||||
nv_wr32(priv, 0x001570, chan->vblank.offset);
|
||||
nv_wr32(priv, 0x001574, chan->vblank.value);
|
||||
} else {
|
||||
nv_wr32(priv, 0x060010, chan->vblank.offset);
|
||||
nv_wr32(priv, 0x060014, chan->vblank.value);
|
||||
}
|
||||
}
|
||||
|
||||
list_del(&chan->vblank.head);
|
||||
|
|
|
@ -669,21 +669,27 @@ nv40_grctx_fill(struct nouveau_device *device, struct nouveau_gpuobj *mem)
|
|||
});
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
nv40_grctx_init(struct nouveau_device *device, u32 *size)
|
||||
{
|
||||
u32 ctxprog[256], i;
|
||||
u32 *ctxprog = kmalloc(256 * 4, GFP_KERNEL), i;
|
||||
struct nouveau_grctx ctx = {
|
||||
.device = device,
|
||||
.mode = NOUVEAU_GRCTX_PROG,
|
||||
.data = ctxprog,
|
||||
.ctxprog_max = ARRAY_SIZE(ctxprog)
|
||||
.ctxprog_max = 256,
|
||||
};
|
||||
|
||||
if (!ctxprog)
|
||||
return -ENOMEM;
|
||||
|
||||
nv40_grctx_generate(&ctx);
|
||||
|
||||
nv_wr32(device, 0x400324, 0);
|
||||
for (i = 0; i < ctx.ctxprog_len; i++)
|
||||
nv_wr32(device, 0x400328, ctxprog[i]);
|
||||
*size = ctx.ctxvals_pos * 4;
|
||||
|
||||
kfree(ctxprog);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -346,7 +346,9 @@ nv40_graph_init(struct nouveau_object *object)
|
|||
return ret;
|
||||
|
||||
/* generate and upload context program */
|
||||
nv40_grctx_init(nv_device(priv), &priv->size);
|
||||
ret = nv40_grctx_init(nv_device(priv), &priv->size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* No context present currently */
|
||||
nv_wr32(priv, NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
|
||||
|
|
|
@ -15,7 +15,7 @@ nv44_graph_class(void *priv)
|
|||
return !(0x0baf & (1 << (device->chipset & 0x0f)));
|
||||
}
|
||||
|
||||
void nv40_grctx_init(struct nouveau_device *, u32 *size);
|
||||
int nv40_grctx_init(struct nouveau_device *, u32 *size);
|
||||
void nv40_grctx_fill(struct nouveau_device *, struct nouveau_gpuobj *);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -175,14 +175,18 @@ nv_mo32(void *obj, u32 addr, u32 mask, u32 data)
|
|||
return temp;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
nv_strncmp(void *obj, u32 addr, u32 len, const char *str)
|
||||
static inline int
|
||||
nv_memcmp(void *obj, u32 addr, const char *str, u32 len)
|
||||
{
|
||||
unsigned char c1, c2;
|
||||
|
||||
while (len--) {
|
||||
if (nv_ro08(obj, addr++) != *(str++))
|
||||
return false;
|
||||
c1 = nv_ro08(obj, addr++);
|
||||
c2 = *(str++);
|
||||
if (c1 != c2)
|
||||
return c1 - c2;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -54,6 +54,7 @@ int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
|
|||
int clk, struct nouveau_pll_vals *);
|
||||
int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1,
|
||||
struct nouveau_pll_vals *);
|
||||
|
||||
int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
|
||||
int clk, struct nouveau_pll_vals *);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -64,7 +64,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
|
|||
}
|
||||
} else
|
||||
if (*ver >= 0x15) {
|
||||
if (!nv_strncmp(bios, dcb - 7, 7, "DEV_REC")) {
|
||||
if (!nv_memcmp(bios, dcb - 7, "DEV_REC", 7)) {
|
||||
u16 i2c = nv_ro16(bios, dcb + 2);
|
||||
*hdr = 4;
|
||||
*cnt = (i2c - dcb) / 10;
|
||||
|
|
|
@ -66,6 +66,24 @@ nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
|
||||
int clk, struct nouveau_pll_vals *pv)
|
||||
{
|
||||
int ret, N, M, P;
|
||||
|
||||
ret = nva3_pll_calc(clock, info, clk, &N, NULL, &M, &P);
|
||||
|
||||
if (ret > 0) {
|
||||
pv->refclk = info->refclk;
|
||||
pv->N1 = N;
|
||||
pv->M1 = M;
|
||||
pv->log2P = P;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
||||
struct nouveau_oclass *oclass, void *data, u32 size,
|
||||
|
@ -80,6 +98,7 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
return ret;
|
||||
|
||||
priv->base.pll_set = nva3_clock_pll_set;
|
||||
priv->base.pll_calc = nva3_clock_pll_calc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
return ret;
|
||||
|
||||
priv->base.pll_set = nvc0_clock_pll_set;
|
||||
priv->base.pll_calc = nva3_clock_pll_calc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -241,6 +241,10 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
|
|||
|
||||
if (unlikely(!abi16))
|
||||
return -ENOMEM;
|
||||
|
||||
if (!drm->channel)
|
||||
return nouveau_abi16_put(abi16, -ENODEV);
|
||||
|
||||
client = nv_client(abi16->client);
|
||||
|
||||
if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
|
||||
|
|
|
@ -129,7 +129,8 @@ nouveau_accel_init(struct nouveau_drm *drm)
|
|||
|
||||
/* initialise synchronisation routines */
|
||||
if (device->card_type < NV_10) ret = nv04_fence_create(drm);
|
||||
else if (device->chipset < 0x84) ret = nv10_fence_create(drm);
|
||||
else if (device->card_type < NV_50) ret = nv10_fence_create(drm);
|
||||
else if (device->chipset < 0x84) ret = nv50_fence_create(drm);
|
||||
else if (device->card_type < NV_C0) ret = nv84_fence_create(drm);
|
||||
else ret = nvc0_fence_create(drm);
|
||||
if (ret) {
|
||||
|
|
|
@ -1330,6 +1330,8 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav
|
|||
break;
|
||||
udelay(1);
|
||||
}
|
||||
} else {
|
||||
save->crtc_enabled[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,9 +69,12 @@ static struct radeon_agpmode_quirk radeon_agpmode_quirk_list[] = {
|
|||
/* Intel 82830 830 Chipset Host Bridge / Mobility M6 LY Needs AGPMode 2 (fdo #17360)*/
|
||||
{ PCI_VENDOR_ID_INTEL, 0x3575, PCI_VENDOR_ID_ATI, 0x4c59,
|
||||
PCI_VENDOR_ID_DELL, 0x00e3, 2},
|
||||
/* Intel 82852/82855 host bridge / Mobility FireGL 9000 R250 Needs AGPMode 1 (lp #296617) */
|
||||
/* Intel 82852/82855 host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 (lp #296617) */
|
||||
{ PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4c66,
|
||||
PCI_VENDOR_ID_DELL, 0x0149, 1},
|
||||
/* Intel 82855PM host bridge / Mobility FireGL 9000 RV250 Needs AGPMode 1 for suspend/resume */
|
||||
{ PCI_VENDOR_ID_INTEL, 0x3340, PCI_VENDOR_ID_ATI, 0x4c66,
|
||||
PCI_VENDOR_ID_IBM, 0x0531, 1},
|
||||
/* Intel 82852/82855 host bridge / Mobility 9600 M10 RV350 Needs AGPMode 1 (deb #467460) */
|
||||
{ PCI_VENDOR_ID_INTEL, 0x3580, PCI_VENDOR_ID_ATI, 0x4e50,
|
||||
0x1025, 0x0061, 1},
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#define AT91_TWI_STOP 0x0002 /* Send a Stop Condition */
|
||||
#define AT91_TWI_MSEN 0x0004 /* Master Transfer Enable */
|
||||
#define AT91_TWI_SVDIS 0x0020 /* Slave Transfer Disable */
|
||||
#define AT91_TWI_QUICK 0x0040 /* SMBus quick command */
|
||||
#define AT91_TWI_SWRST 0x0080 /* Software Reset */
|
||||
|
||||
#define AT91_TWI_MMR 0x0004 /* Master Mode Register */
|
||||
|
@ -212,7 +213,11 @@ static int at91_do_twi_transfer(struct at91_twi_dev *dev)
|
|||
|
||||
INIT_COMPLETION(dev->cmd_complete);
|
||||
dev->transfer_status = 0;
|
||||
if (dev->msg->flags & I2C_M_RD) {
|
||||
|
||||
if (!dev->buf_len) {
|
||||
at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_QUICK);
|
||||
at91_twi_write(dev, AT91_TWI_IER, AT91_TWI_TXCOMP);
|
||||
} else if (dev->msg->flags & I2C_M_RD) {
|
||||
unsigned start_flags = AT91_TWI_START;
|
||||
|
||||
if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) {
|
||||
|
|
|
@ -287,12 +287,14 @@ static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
|
|||
select_init_dma_fail:
|
||||
dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE);
|
||||
select_init_pio_fail:
|
||||
dmaengine_terminate_all(i2c->dmach);
|
||||
return -EINVAL;
|
||||
|
||||
/* Write failpath. */
|
||||
write_init_dma_fail:
|
||||
dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
|
||||
write_init_pio_fail:
|
||||
dmaengine_terminate_all(i2c->dmach);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/i2c-omap.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pm_qos.h>
|
||||
|
||||
/* I2C controller revisions */
|
||||
#define OMAP_I2C_OMAP1_REV_2 0x20
|
||||
|
@ -187,8 +186,9 @@ struct omap_i2c_dev {
|
|||
int reg_shift; /* bit shift for I2C register addresses */
|
||||
struct completion cmd_complete;
|
||||
struct resource *ioarea;
|
||||
u32 latency; /* maximum MPU wkup latency */
|
||||
struct pm_qos_request pm_qos_request;
|
||||
u32 latency; /* maximum mpu wkup latency */
|
||||
void (*set_mpu_wkup_lat)(struct device *dev,
|
||||
long latency);
|
||||
u32 speed; /* Speed of bus in kHz */
|
||||
u32 dtrev; /* extra revision from DT */
|
||||
u32 flags;
|
||||
|
@ -494,7 +494,9 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
|
|||
dev->b_hw = 1; /* Enable hardware fixes */
|
||||
|
||||
/* calculate wakeup latency constraint for MPU */
|
||||
dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8);
|
||||
if (dev->set_mpu_wkup_lat != NULL)
|
||||
dev->latency = (1000000 * dev->threshold) /
|
||||
(1000 * dev->speed / 8);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -522,6 +524,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
|
|||
dev->buf = msg->buf;
|
||||
dev->buf_len = msg->len;
|
||||
|
||||
/* make sure writes to dev->buf_len are ordered */
|
||||
barrier();
|
||||
|
||||
omap_i2c_write_reg(dev, OMAP_I2C_CNT_REG, dev->buf_len);
|
||||
|
||||
/* Clear the FIFO Buffers */
|
||||
|
@ -579,7 +584,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
|
|||
*/
|
||||
timeout = wait_for_completion_timeout(&dev->cmd_complete,
|
||||
OMAP_I2C_TIMEOUT);
|
||||
dev->buf_len = 0;
|
||||
if (timeout == 0) {
|
||||
dev_err(dev->dev, "controller timed out\n");
|
||||
omap_i2c_init(dev);
|
||||
|
@ -629,16 +633,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
|
|||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* When waiting for completion of a i2c transfer, we need to
|
||||
* set a wake up latency constraint for the MPU. This is to
|
||||
* ensure quick enough wakeup from idle, when transfer
|
||||
* completes.
|
||||
*/
|
||||
if (dev->latency)
|
||||
pm_qos_add_request(&dev->pm_qos_request,
|
||||
PM_QOS_CPU_DMA_LATENCY,
|
||||
dev->latency);
|
||||
if (dev->set_mpu_wkup_lat != NULL)
|
||||
dev->set_mpu_wkup_lat(dev->dev, dev->latency);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
|
||||
|
@ -646,8 +642,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
|
|||
break;
|
||||
}
|
||||
|
||||
if (dev->latency)
|
||||
pm_qos_remove_request(&dev->pm_qos_request);
|
||||
if (dev->set_mpu_wkup_lat != NULL)
|
||||
dev->set_mpu_wkup_lat(dev->dev, -1);
|
||||
|
||||
if (r == 0)
|
||||
r = num;
|
||||
|
@ -1104,6 +1100,7 @@ omap_i2c_probe(struct platform_device *pdev)
|
|||
} else if (pdata != NULL) {
|
||||
dev->speed = pdata->clkrate;
|
||||
dev->flags = pdata->flags;
|
||||
dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
|
||||
dev->dtrev = pdata->rev;
|
||||
}
|
||||
|
||||
|
@ -1159,8 +1156,9 @@ omap_i2c_probe(struct platform_device *pdev)
|
|||
dev->b_hw = 1; /* Enable hardware fixes */
|
||||
|
||||
/* calculate wakeup latency constraint for MPU */
|
||||
dev->latency = (1000000 * dev->fifo_size) /
|
||||
(1000 * dev->speed / 8);
|
||||
if (dev->set_mpu_wkup_lat != NULL)
|
||||
dev->latency = (1000000 * dev->fifo_size) /
|
||||
(1000 * dev->speed / 8);
|
||||
}
|
||||
|
||||
/* reset ASAP, clearing any IRQs */
|
||||
|
|
|
@ -806,6 +806,7 @@ static int s3c24xx_i2c_parse_dt_gpio(struct s3c24xx_i2c *i2c)
|
|||
dev_err(i2c->dev, "invalid gpio[%d]: %d\n", idx, gpio);
|
||||
goto free_gpio;
|
||||
}
|
||||
i2c->gpios[idx] = gpio;
|
||||
|
||||
ret = gpio_request(gpio, "i2c-bus");
|
||||
if (ret) {
|
||||
|
|
|
@ -26,10 +26,14 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src)
|
|||
* input_mt_init_slots() - initialize MT input slots
|
||||
* @dev: input device supporting MT events and finger tracking
|
||||
* @num_slots: number of slots used by the device
|
||||
* @flags: mt tasks to handle in core
|
||||
*
|
||||
* This function allocates all necessary memory for MT slot handling
|
||||
* in the input device, prepares the ABS_MT_SLOT and
|
||||
* ABS_MT_TRACKING_ID events for use and sets up appropriate buffers.
|
||||
* Depending on the flags set, it also performs pointer emulation and
|
||||
* frame synchronization.
|
||||
*
|
||||
* May be called repeatedly. Returns -EINVAL if attempting to
|
||||
* reinitialize with a different number of slots.
|
||||
*/
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#define MOUSEDEV_MINOR_BASE 32
|
||||
#define MOUSEDEV_MINORS 32
|
||||
#define MOUSEDEV_MIX 31
|
||||
#define MOUSEDEV_MINORS 31
|
||||
#define MOUSEDEV_MIX 63
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
|
|
|
@ -955,7 +955,8 @@ static int ads7846_resume(struct device *dev)
|
|||
|
||||
static SIMPLE_DEV_PM_OPS(ads7846_pm, ads7846_suspend, ads7846_resume);
|
||||
|
||||
static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads7846 *ts)
|
||||
static int __devinit ads7846_setup_pendown(struct spi_device *spi,
|
||||
struct ads7846 *ts)
|
||||
{
|
||||
struct ads7846_platform_data *pdata = spi->dev.platform_data;
|
||||
int err;
|
||||
|
@ -981,6 +982,9 @@ static int __devinit ads7846_setup_pendown(struct spi_device *spi, struct ads784
|
|||
|
||||
ts->gpio_pendown = pdata->gpio_pendown;
|
||||
|
||||
if (pdata->gpio_pendown_debounce)
|
||||
gpio_set_debounce(pdata->gpio_pendown,
|
||||
pdata->gpio_pendown_debounce);
|
||||
} else {
|
||||
dev_err(&spi->dev, "no get_pendown_state nor gpio_pendown?\n");
|
||||
return -EINVAL;
|
||||
|
|
|
@ -4108,7 +4108,7 @@ static void swap_pci_ref(struct pci_dev **from, struct pci_dev *to)
|
|||
static int intel_iommu_add_device(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct pci_dev *bridge, *dma_pdev;
|
||||
struct pci_dev *bridge, *dma_pdev = NULL;
|
||||
struct iommu_group *group;
|
||||
int ret;
|
||||
|
||||
|
@ -4122,7 +4122,7 @@ static int intel_iommu_add_device(struct device *dev)
|
|||
dma_pdev = pci_get_domain_bus_and_slot(
|
||||
pci_domain_nr(pdev->bus),
|
||||
bridge->subordinate->number, 0);
|
||||
else
|
||||
if (!dma_pdev)
|
||||
dma_pdev = pci_dev_get(bridge);
|
||||
} else
|
||||
dma_pdev = pci_dev_get(pdev);
|
||||
|
|
|
@ -1054,6 +1054,7 @@ static int smmu_debugfs_stats_show(struct seq_file *s, void *v)
|
|||
stats[i], val, offs);
|
||||
}
|
||||
seq_printf(s, "\n");
|
||||
dput(dent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -740,8 +740,14 @@ static void rq_completed(struct mapped_device *md, int rw, int run_queue)
|
|||
if (!md_in_flight(md))
|
||||
wake_up(&md->wait);
|
||||
|
||||
/*
|
||||
* Run this off this callpath, as drivers could invoke end_io while
|
||||
* inside their request_fn (and holding the queue lock). Calling
|
||||
* back into ->request_fn() could deadlock attempting to grab the
|
||||
* queue lock again.
|
||||
*/
|
||||
if (run_queue)
|
||||
blk_run_queue(md->queue);
|
||||
blk_run_queue_async(md->queue);
|
||||
|
||||
/*
|
||||
* dm_put() must be at the end of this function. See the comment above
|
||||
|
|
|
@ -1817,10 +1817,10 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev)
|
|||
memset(bbp, 0xff, PAGE_SIZE);
|
||||
|
||||
for (i = 0 ; i < bb->count ; i++) {
|
||||
u64 internal_bb = *p++;
|
||||
u64 internal_bb = p[i];
|
||||
u64 store_bb = ((BB_OFFSET(internal_bb) << 10)
|
||||
| BB_LEN(internal_bb));
|
||||
*bbp++ = cpu_to_le64(store_bb);
|
||||
bbp[i] = cpu_to_le64(store_bb);
|
||||
}
|
||||
bb->changed = 0;
|
||||
if (read_seqretry(&bb->lock, seq))
|
||||
|
@ -5294,7 +5294,7 @@ void md_stop_writes(struct mddev *mddev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(md_stop_writes);
|
||||
|
||||
void md_stop(struct mddev *mddev)
|
||||
static void __md_stop(struct mddev *mddev)
|
||||
{
|
||||
mddev->ready = 0;
|
||||
mddev->pers->stop(mddev);
|
||||
|
@ -5304,6 +5304,18 @@ void md_stop(struct mddev *mddev)
|
|||
mddev->pers = NULL;
|
||||
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
}
|
||||
|
||||
void md_stop(struct mddev *mddev)
|
||||
{
|
||||
/* stop the array and free an attached data structures.
|
||||
* This is called from dm-raid
|
||||
*/
|
||||
__md_stop(mddev);
|
||||
bitmap_destroy(mddev);
|
||||
if (mddev->bio_set)
|
||||
bioset_free(mddev->bio_set);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(md_stop);
|
||||
|
||||
static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
|
||||
|
@ -5364,7 +5376,7 @@ static int do_md_stop(struct mddev * mddev, int mode,
|
|||
set_disk_ro(disk, 0);
|
||||
|
||||
__md_stop_writes(mddev);
|
||||
md_stop(mddev);
|
||||
__md_stop(mddev);
|
||||
mddev->queue->merge_bvec_fn = NULL;
|
||||
mddev->queue->backing_dev_info.congested_fn = NULL;
|
||||
|
||||
|
@ -7936,9 +7948,9 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors,
|
|||
sector_t *first_bad, int *bad_sectors)
|
||||
{
|
||||
int hi;
|
||||
int lo = 0;
|
||||
int lo;
|
||||
u64 *p = bb->page;
|
||||
int rv = 0;
|
||||
int rv;
|
||||
sector_t target = s + sectors;
|
||||
unsigned seq;
|
||||
|
||||
|
@ -7953,7 +7965,8 @@ int md_is_badblock(struct badblocks *bb, sector_t s, int sectors,
|
|||
|
||||
retry:
|
||||
seq = read_seqbegin(&bb->lock);
|
||||
|
||||
lo = 0;
|
||||
rv = 0;
|
||||
hi = bb->count;
|
||||
|
||||
/* Binary search between lo and hi for 'target'
|
||||
|
|
|
@ -499,7 +499,7 @@ static void raid10_end_write_request(struct bio *bio, int error)
|
|||
*/
|
||||
one_write_done(r10_bio);
|
||||
if (dec_rdev)
|
||||
rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev);
|
||||
rdev_dec_pending(rdev, conf->mddev);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1334,18 +1334,21 @@ static void make_request(struct mddev *mddev, struct bio * bio)
|
|||
blocked_rdev = rrdev;
|
||||
break;
|
||||
}
|
||||
if (rdev && (test_bit(Faulty, &rdev->flags)
|
||||
|| test_bit(Unmerged, &rdev->flags)))
|
||||
rdev = NULL;
|
||||
if (rrdev && (test_bit(Faulty, &rrdev->flags)
|
||||
|| test_bit(Unmerged, &rrdev->flags)))
|
||||
rrdev = NULL;
|
||||
|
||||
r10_bio->devs[i].bio = NULL;
|
||||
r10_bio->devs[i].repl_bio = NULL;
|
||||
if (!rdev || test_bit(Faulty, &rdev->flags) ||
|
||||
test_bit(Unmerged, &rdev->flags)) {
|
||||
|
||||
if (!rdev && !rrdev) {
|
||||
set_bit(R10BIO_Degraded, &r10_bio->state);
|
||||
continue;
|
||||
}
|
||||
if (test_bit(WriteErrorSeen, &rdev->flags)) {
|
||||
if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) {
|
||||
sector_t first_bad;
|
||||
sector_t dev_sector = r10_bio->devs[i].addr;
|
||||
int bad_sectors;
|
||||
|
@ -1387,8 +1390,10 @@ static void make_request(struct mddev *mddev, struct bio * bio)
|
|||
max_sectors = good_sectors;
|
||||
}
|
||||
}
|
||||
r10_bio->devs[i].bio = bio;
|
||||
atomic_inc(&rdev->nr_pending);
|
||||
if (rdev) {
|
||||
r10_bio->devs[i].bio = bio;
|
||||
atomic_inc(&rdev->nr_pending);
|
||||
}
|
||||
if (rrdev) {
|
||||
r10_bio->devs[i].repl_bio = bio;
|
||||
atomic_inc(&rrdev->nr_pending);
|
||||
|
@ -1444,69 +1449,71 @@ static void make_request(struct mddev *mddev, struct bio * bio)
|
|||
for (i = 0; i < conf->copies; i++) {
|
||||
struct bio *mbio;
|
||||
int d = r10_bio->devs[i].devnum;
|
||||
if (!r10_bio->devs[i].bio)
|
||||
continue;
|
||||
if (r10_bio->devs[i].bio) {
|
||||
struct md_rdev *rdev = conf->mirrors[d].rdev;
|
||||
mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
|
||||
md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
|
||||
max_sectors);
|
||||
r10_bio->devs[i].bio = mbio;
|
||||
|
||||
mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
|
||||
md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
|
||||
max_sectors);
|
||||
r10_bio->devs[i].bio = mbio;
|
||||
mbio->bi_sector = (r10_bio->devs[i].addr+
|
||||
choose_data_offset(r10_bio,
|
||||
rdev));
|
||||
mbio->bi_bdev = rdev->bdev;
|
||||
mbio->bi_end_io = raid10_end_write_request;
|
||||
mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
|
||||
mbio->bi_private = r10_bio;
|
||||
|
||||
mbio->bi_sector = (r10_bio->devs[i].addr+
|
||||
choose_data_offset(r10_bio,
|
||||
conf->mirrors[d].rdev));
|
||||
mbio->bi_bdev = conf->mirrors[d].rdev->bdev;
|
||||
mbio->bi_end_io = raid10_end_write_request;
|
||||
mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
|
||||
mbio->bi_private = r10_bio;
|
||||
atomic_inc(&r10_bio->remaining);
|
||||
|
||||
atomic_inc(&r10_bio->remaining);
|
||||
cb = blk_check_plugged(raid10_unplug, mddev,
|
||||
sizeof(*plug));
|
||||
if (cb)
|
||||
plug = container_of(cb, struct raid10_plug_cb,
|
||||
cb);
|
||||
else
|
||||
plug = NULL;
|
||||
spin_lock_irqsave(&conf->device_lock, flags);
|
||||
if (plug) {
|
||||
bio_list_add(&plug->pending, mbio);
|
||||
plug->pending_cnt++;
|
||||
} else {
|
||||
bio_list_add(&conf->pending_bio_list, mbio);
|
||||
conf->pending_count++;
|
||||
}
|
||||
spin_unlock_irqrestore(&conf->device_lock, flags);
|
||||
if (!plug)
|
||||
md_wakeup_thread(mddev->thread);
|
||||
}
|
||||
|
||||
cb = blk_check_plugged(raid10_unplug, mddev, sizeof(*plug));
|
||||
if (cb)
|
||||
plug = container_of(cb, struct raid10_plug_cb, cb);
|
||||
else
|
||||
plug = NULL;
|
||||
spin_lock_irqsave(&conf->device_lock, flags);
|
||||
if (plug) {
|
||||
bio_list_add(&plug->pending, mbio);
|
||||
plug->pending_cnt++;
|
||||
} else {
|
||||
if (r10_bio->devs[i].repl_bio) {
|
||||
struct md_rdev *rdev = conf->mirrors[d].replacement;
|
||||
if (rdev == NULL) {
|
||||
/* Replacement just got moved to main 'rdev' */
|
||||
smp_mb();
|
||||
rdev = conf->mirrors[d].rdev;
|
||||
}
|
||||
mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
|
||||
md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
|
||||
max_sectors);
|
||||
r10_bio->devs[i].repl_bio = mbio;
|
||||
|
||||
mbio->bi_sector = (r10_bio->devs[i].addr +
|
||||
choose_data_offset(
|
||||
r10_bio, rdev));
|
||||
mbio->bi_bdev = rdev->bdev;
|
||||
mbio->bi_end_io = raid10_end_write_request;
|
||||
mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
|
||||
mbio->bi_private = r10_bio;
|
||||
|
||||
atomic_inc(&r10_bio->remaining);
|
||||
spin_lock_irqsave(&conf->device_lock, flags);
|
||||
bio_list_add(&conf->pending_bio_list, mbio);
|
||||
conf->pending_count++;
|
||||
spin_unlock_irqrestore(&conf->device_lock, flags);
|
||||
if (!mddev_check_plugged(mddev))
|
||||
md_wakeup_thread(mddev->thread);
|
||||
}
|
||||
spin_unlock_irqrestore(&conf->device_lock, flags);
|
||||
if (!plug)
|
||||
md_wakeup_thread(mddev->thread);
|
||||
|
||||
if (!r10_bio->devs[i].repl_bio)
|
||||
continue;
|
||||
|
||||
mbio = bio_clone_mddev(bio, GFP_NOIO, mddev);
|
||||
md_trim_bio(mbio, r10_bio->sector - bio->bi_sector,
|
||||
max_sectors);
|
||||
r10_bio->devs[i].repl_bio = mbio;
|
||||
|
||||
/* We are actively writing to the original device
|
||||
* so it cannot disappear, so the replacement cannot
|
||||
* become NULL here
|
||||
*/
|
||||
mbio->bi_sector = (r10_bio->devs[i].addr +
|
||||
choose_data_offset(
|
||||
r10_bio,
|
||||
conf->mirrors[d].replacement));
|
||||
mbio->bi_bdev = conf->mirrors[d].replacement->bdev;
|
||||
mbio->bi_end_io = raid10_end_write_request;
|
||||
mbio->bi_rw = WRITE | do_sync | do_fua | do_discard;
|
||||
mbio->bi_private = r10_bio;
|
||||
|
||||
atomic_inc(&r10_bio->remaining);
|
||||
spin_lock_irqsave(&conf->device_lock, flags);
|
||||
bio_list_add(&conf->pending_bio_list, mbio);
|
||||
conf->pending_count++;
|
||||
spin_unlock_irqrestore(&conf->device_lock, flags);
|
||||
if (!mddev_check_plugged(mddev))
|
||||
md_wakeup_thread(mddev->thread);
|
||||
}
|
||||
|
||||
/* Don't remove the bias on 'remaining' (one_write_done) until
|
||||
|
|
|
@ -2774,10 +2774,12 @@ static void handle_stripe_clean_event(struct r5conf *conf,
|
|||
dev = &sh->dev[i];
|
||||
if (!test_bit(R5_LOCKED, &dev->flags) &&
|
||||
(test_bit(R5_UPTODATE, &dev->flags) ||
|
||||
test_and_clear_bit(R5_Discard, &dev->flags))) {
|
||||
test_bit(R5_Discard, &dev->flags))) {
|
||||
/* We can return any write requests */
|
||||
struct bio *wbi, *wbi2;
|
||||
pr_debug("Return write for disc %d\n", i);
|
||||
if (test_and_clear_bit(R5_Discard, &dev->flags))
|
||||
clear_bit(R5_UPTODATE, &dev->flags);
|
||||
wbi = dev->written;
|
||||
dev->written = NULL;
|
||||
while (wbi && wbi->bi_sector <
|
||||
|
@ -2795,7 +2797,8 @@ static void handle_stripe_clean_event(struct r5conf *conf,
|
|||
!test_bit(STRIPE_DEGRADED, &sh->state),
|
||||
0);
|
||||
}
|
||||
}
|
||||
} else if (test_bit(R5_Discard, &sh->dev[i].flags))
|
||||
clear_bit(R5_Discard, &sh->dev[i].flags);
|
||||
|
||||
if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state))
|
||||
if (atomic_dec_and_test(&conf->pending_full_writes))
|
||||
|
@ -3490,40 +3493,6 @@ static void handle_stripe(struct stripe_head *sh)
|
|||
handle_failed_sync(conf, sh, &s);
|
||||
}
|
||||
|
||||
/*
|
||||
* might be able to return some write requests if the parity blocks
|
||||
* are safe, or on a failed drive
|
||||
*/
|
||||
pdev = &sh->dev[sh->pd_idx];
|
||||
s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx)
|
||||
|| (s.failed >= 2 && s.failed_num[1] == sh->pd_idx);
|
||||
qdev = &sh->dev[sh->qd_idx];
|
||||
s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx)
|
||||
|| (s.failed >= 2 && s.failed_num[1] == sh->qd_idx)
|
||||
|| conf->level < 6;
|
||||
|
||||
if (s.written &&
|
||||
(s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
|
||||
&& !test_bit(R5_LOCKED, &pdev->flags)
|
||||
&& (test_bit(R5_UPTODATE, &pdev->flags) ||
|
||||
test_bit(R5_Discard, &pdev->flags))))) &&
|
||||
(s.q_failed || ((test_bit(R5_Insync, &qdev->flags)
|
||||
&& !test_bit(R5_LOCKED, &qdev->flags)
|
||||
&& (test_bit(R5_UPTODATE, &qdev->flags) ||
|
||||
test_bit(R5_Discard, &qdev->flags))))))
|
||||
handle_stripe_clean_event(conf, sh, disks, &s.return_bi);
|
||||
|
||||
/* Now we might consider reading some blocks, either to check/generate
|
||||
* parity, or to satisfy requests
|
||||
* or to load a block that is being partially written.
|
||||
*/
|
||||
if (s.to_read || s.non_overwrite
|
||||
|| (conf->level == 6 && s.to_write && s.failed)
|
||||
|| (s.syncing && (s.uptodate + s.compute < disks))
|
||||
|| s.replacing
|
||||
|| s.expanding)
|
||||
handle_stripe_fill(sh, &s, disks);
|
||||
|
||||
/* Now we check to see if any write operations have recently
|
||||
* completed
|
||||
*/
|
||||
|
@ -3561,6 +3530,40 @@ static void handle_stripe(struct stripe_head *sh)
|
|||
s.dec_preread_active = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* might be able to return some write requests if the parity blocks
|
||||
* are safe, or on a failed drive
|
||||
*/
|
||||
pdev = &sh->dev[sh->pd_idx];
|
||||
s.p_failed = (s.failed >= 1 && s.failed_num[0] == sh->pd_idx)
|
||||
|| (s.failed >= 2 && s.failed_num[1] == sh->pd_idx);
|
||||
qdev = &sh->dev[sh->qd_idx];
|
||||
s.q_failed = (s.failed >= 1 && s.failed_num[0] == sh->qd_idx)
|
||||
|| (s.failed >= 2 && s.failed_num[1] == sh->qd_idx)
|
||||
|| conf->level < 6;
|
||||
|
||||
if (s.written &&
|
||||
(s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
|
||||
&& !test_bit(R5_LOCKED, &pdev->flags)
|
||||
&& (test_bit(R5_UPTODATE, &pdev->flags) ||
|
||||
test_bit(R5_Discard, &pdev->flags))))) &&
|
||||
(s.q_failed || ((test_bit(R5_Insync, &qdev->flags)
|
||||
&& !test_bit(R5_LOCKED, &qdev->flags)
|
||||
&& (test_bit(R5_UPTODATE, &qdev->flags) ||
|
||||
test_bit(R5_Discard, &qdev->flags))))))
|
||||
handle_stripe_clean_event(conf, sh, disks, &s.return_bi);
|
||||
|
||||
/* Now we might consider reading some blocks, either to check/generate
|
||||
* parity, or to satisfy requests
|
||||
* or to load a block that is being partially written.
|
||||
*/
|
||||
if (s.to_read || s.non_overwrite
|
||||
|| (conf->level == 6 && s.to_write && s.failed)
|
||||
|| (s.syncing && (s.uptodate + s.compute < disks))
|
||||
|| s.replacing
|
||||
|| s.expanding)
|
||||
handle_stripe_fill(sh, &s, disks);
|
||||
|
||||
/* Now to consider new write requests and what else, if anything
|
||||
* should be read. We do not handle new writes when:
|
||||
* 1/ A 'write' operation (copy+xor) is already in flight.
|
||||
|
@ -5529,6 +5532,10 @@ static int run(struct mddev *mddev)
|
|||
* discard data disk but write parity disk
|
||||
*/
|
||||
stripe = stripe * PAGE_SIZE;
|
||||
/* Round up to power of 2, as discard handling
|
||||
* currently assumes that */
|
||||
while ((stripe-1) & stripe)
|
||||
stripe = (stripe | (stripe-1)) + 1;
|
||||
mddev->queue->limits.discard_alignment = stripe;
|
||||
mddev->queue->limits.discard_granularity = stripe;
|
||||
/*
|
||||
|
|
|
@ -240,7 +240,7 @@ static int parse_cmdline(char *devname, char *szstart, char *szlength)
|
|||
|
||||
if (*(szlength) != '+') {
|
||||
devlength = simple_strtoul(szlength, &buffer, 0);
|
||||
devlength = handle_unit(devlength, buffer) - devstart;
|
||||
devlength = handle_unit(devlength, buffer);
|
||||
if (devlength < devstart)
|
||||
goto err_out;
|
||||
|
||||
|
|
|
@ -2983,13 +2983,15 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
|
|||
/*
|
||||
* Field definitions are in the following datasheets:
|
||||
* Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
|
||||
* New style (6 byte ID): Samsung K9GAG08U0F (p.44)
|
||||
* New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
|
||||
* Hynix MLC (6 byte ID): Hynix H27UBG8T2B (p.22)
|
||||
*
|
||||
* Check for ID length, cell type, and Hynix/Samsung ID to decide what
|
||||
* to do.
|
||||
* Check for ID length, non-zero 6th byte, cell type, and Hynix/Samsung
|
||||
* ID to decide what to do.
|
||||
*/
|
||||
if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) {
|
||||
if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG &&
|
||||
(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
|
||||
id_data[5] != 0x00) {
|
||||
/* Calc pagesize */
|
||||
mtd->writesize = 2048 << (extid & 0x03);
|
||||
extid >>= 2;
|
||||
|
|
|
@ -121,7 +121,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master,
|
|||
nr_parts = plen / sizeof(part[0]);
|
||||
|
||||
*pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL);
|
||||
if (!pparts)
|
||||
if (!*pparts)
|
||||
return -ENOMEM;
|
||||
|
||||
names = of_get_property(dp, "partition-names", &plen);
|
||||
|
|
|
@ -3694,7 +3694,7 @@ static int flexonenand_check_blocks_erased(struct mtd_info *mtd, int start, int
|
|||
* flexonenand_set_boundary - Writes the SLC boundary
|
||||
* @param mtd - mtd info structure
|
||||
*/
|
||||
int flexonenand_set_boundary(struct mtd_info *mtd, int die,
|
||||
static int flexonenand_set_boundary(struct mtd_info *mtd, int die,
|
||||
int boundary, int lock)
|
||||
{
|
||||
struct onenand_chip *this = mtd->priv;
|
||||
|
|
|
@ -1379,6 +1379,8 @@ static void bond_compute_features(struct bonding *bond)
|
|||
struct net_device *bond_dev = bond->dev;
|
||||
netdev_features_t vlan_features = BOND_VLAN_FEATURES;
|
||||
unsigned short max_hard_header_len = ETH_HLEN;
|
||||
unsigned int gso_max_size = GSO_MAX_SIZE;
|
||||
u16 gso_max_segs = GSO_MAX_SEGS;
|
||||
int i;
|
||||
unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE;
|
||||
|
||||
|
@ -1394,11 +1396,16 @@ static void bond_compute_features(struct bonding *bond)
|
|||
dst_release_flag &= slave->dev->priv_flags;
|
||||
if (slave->dev->hard_header_len > max_hard_header_len)
|
||||
max_hard_header_len = slave->dev->hard_header_len;
|
||||
|
||||
gso_max_size = min(gso_max_size, slave->dev->gso_max_size);
|
||||
gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs);
|
||||
}
|
||||
|
||||
done:
|
||||
bond_dev->vlan_features = vlan_features;
|
||||
bond_dev->hard_header_len = max_hard_header_len;
|
||||
bond_dev->gso_max_segs = gso_max_segs;
|
||||
netif_set_gso_max_size(bond_dev, gso_max_size);
|
||||
|
||||
flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE;
|
||||
bond_dev->priv_flags = flags | dst_release_flag;
|
||||
|
|
|
@ -813,6 +813,7 @@ static int __init ne_drv_probe(struct platform_device *pdev)
|
|||
dev->irq = irq[this_dev];
|
||||
dev->mem_end = bad[this_dev];
|
||||
}
|
||||
SET_NETDEV_DEV(dev, &pdev->dev);
|
||||
err = do_ne_probe(dev);
|
||||
if (err) {
|
||||
free_netdev(dev);
|
||||
|
|
|
@ -9706,10 +9706,13 @@ static int __devinit bnx2x_prev_unload_common(struct bnx2x *bp)
|
|||
*/
|
||||
static void __devinit bnx2x_prev_interrupted_dmae(struct bnx2x *bp)
|
||||
{
|
||||
u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS);
|
||||
if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) {
|
||||
BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing");
|
||||
REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, 1 << BP_FUNC(bp));
|
||||
if (!CHIP_IS_E1x(bp)) {
|
||||
u32 val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS);
|
||||
if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) {
|
||||
BNX2X_ERR("was error bit was found to be set in pglueb upon startup. Clearing");
|
||||
REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR,
|
||||
1 << BP_FUNC(bp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -979,17 +979,6 @@ static void cp_init_hw (struct cp_private *cp)
|
|||
cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
|
||||
cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4)));
|
||||
|
||||
cpw32_f(HiTxRingAddr, 0);
|
||||
cpw32_f(HiTxRingAddr + 4, 0);
|
||||
|
||||
ring_dma = cp->ring_dma;
|
||||
cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
|
||||
cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
|
||||
ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
|
||||
cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
|
||||
cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
|
||||
cp_start_hw(cp);
|
||||
cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */
|
||||
|
||||
|
@ -1003,6 +992,17 @@ static void cp_init_hw (struct cp_private *cp)
|
|||
|
||||
cpw8(Config5, cpr8(Config5) & PMEStatus);
|
||||
|
||||
cpw32_f(HiTxRingAddr, 0);
|
||||
cpw32_f(HiTxRingAddr + 4, 0);
|
||||
|
||||
ring_dma = cp->ring_dma;
|
||||
cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
|
||||
cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
|
||||
ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
|
||||
cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
|
||||
cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
|
||||
cpw16(MultiIntr, 0);
|
||||
|
||||
cpw8_f(Cfg9346, Cfg9346_Lock);
|
||||
|
|
|
@ -2479,7 +2479,7 @@ static int sis900_resume(struct pci_dev *pci_dev)
|
|||
netif_start_queue(net_dev);
|
||||
|
||||
/* Workaround for EDB */
|
||||
sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
|
||||
sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
|
||||
|
||||
/* Enable all known interrupts by setting the interrupt mask. */
|
||||
sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE);
|
||||
|
|
|
@ -894,6 +894,8 @@ static irqreturn_t axienet_rx_irq(int irq, void *_ndev)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void axienet_dma_err_handler(unsigned long data);
|
||||
|
||||
/**
|
||||
* axienet_open - Driver open routine.
|
||||
* @ndev: Pointer to net_device structure
|
||||
|
|
|
@ -1102,10 +1102,12 @@ static int init_queues(struct port *port)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (!ports_open)
|
||||
if (!(dma_pool = dma_pool_create(DRV_NAME, NULL,
|
||||
POOL_ALLOC_SIZE, 32, 0)))
|
||||
if (!ports_open) {
|
||||
dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev,
|
||||
POOL_ALLOC_SIZE, 32, 0);
|
||||
if (!dma_pool)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL,
|
||||
&port->desc_tab_phys)))
|
||||
|
|
|
@ -222,7 +222,7 @@ static void sirdev_config_fsm(struct work_struct *work)
|
|||
break;
|
||||
|
||||
case SIRDEV_STATE_DONGLE_SPEED:
|
||||
if (dev->dongle_drv->reset) {
|
||||
if (dev->dongle_drv->set_speed) {
|
||||
ret = dev->dongle_drv->set_speed(dev, fsm->param);
|
||||
if (ret < 0) {
|
||||
fsm->result = ret;
|
||||
|
|
|
@ -185,17 +185,20 @@ static int __devinit mdio_gpio_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct mdio_gpio_platform_data *pdata;
|
||||
struct mii_bus *new_bus;
|
||||
int ret;
|
||||
int ret, bus_id;
|
||||
|
||||
if (pdev->dev.of_node)
|
||||
if (pdev->dev.of_node) {
|
||||
pdata = mdio_gpio_of_get_data(pdev);
|
||||
else
|
||||
bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio");
|
||||
} else {
|
||||
pdata = pdev->dev.platform_data;
|
||||
bus_id = pdev->id;
|
||||
}
|
||||
|
||||
if (!pdata)
|
||||
return -ENODEV;
|
||||
|
||||
new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id);
|
||||
new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, bus_id);
|
||||
if (!new_bus)
|
||||
return -ENODEV;
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb)
|
|||
if (last) {
|
||||
skb2 = skb_clone(skb, GFP_ATOMIC);
|
||||
if (skb2) {
|
||||
ret = team_dev_queue_xmit(team, last,
|
||||
skb2);
|
||||
ret = !team_dev_queue_xmit(team, last,
|
||||
skb2);
|
||||
if (!sum_ret)
|
||||
sum_ret = ret;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ static bool bc_transmit(struct team *team, struct sk_buff *skb)
|
|||
}
|
||||
}
|
||||
if (last) {
|
||||
ret = team_dev_queue_xmit(team, last, skb);
|
||||
ret = !team_dev_queue_xmit(team, last, skb);
|
||||
if (!sum_ret)
|
||||
sum_ret = ret;
|
||||
}
|
||||
|
|
|
@ -969,10 +969,12 @@ static int init_hdlc_queues(struct port *port)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (!ports_open)
|
||||
if (!(dma_pool = dma_pool_create(DRV_NAME, NULL,
|
||||
POOL_ALLOC_SIZE, 32, 0)))
|
||||
if (!ports_open) {
|
||||
dma_pool = dma_pool_create(DRV_NAME, &port->netdev->dev,
|
||||
POOL_ALLOC_SIZE, 32, 0);
|
||||
if (!dma_pool)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!(port->desc_tab = dma_pool_alloc(dma_pool, GFP_KERNEL,
|
||||
&port->desc_tab_phys)))
|
||||
|
|
|
@ -1456,7 +1456,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
|
|||
switch (type) {
|
||||
case ATH9K_RESET_POWER_ON:
|
||||
ret = ath9k_hw_set_reset_power_on(ah);
|
||||
if (!ret)
|
||||
if (ret)
|
||||
ah->reset_power_on = true;
|
||||
break;
|
||||
case ATH9K_RESET_WARM:
|
||||
|
|
|
@ -1354,6 +1354,20 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
|
|||
vif_priv->ctx = ctx;
|
||||
ctx->vif = vif;
|
||||
|
||||
/*
|
||||
* In SNIFFER device type, the firmware reports the FCS to
|
||||
* the host, rather than snipping it off. Unfortunately,
|
||||
* mac80211 doesn't (yet) provide a per-packet flag for
|
||||
* this, so that we have to set the hardware flag based
|
||||
* on the interfaces added. As the monitor interface can
|
||||
* only be present by itself, and will be removed before
|
||||
* other interfaces are added, this is safe.
|
||||
*/
|
||||
if (vif->type == NL80211_IFTYPE_MONITOR)
|
||||
priv->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS;
|
||||
else
|
||||
priv->hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
|
||||
|
||||
err = iwl_setup_interface(priv, ctx);
|
||||
if (!err || reset)
|
||||
goto out;
|
||||
|
|
|
@ -890,9 +890,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
|
|||
return;
|
||||
}
|
||||
cmd_node = adapter->curr_cmd;
|
||||
if (cmd_node->wait_q_enabled)
|
||||
adapter->cmd_wait_q.status = -ETIMEDOUT;
|
||||
|
||||
if (cmd_node) {
|
||||
adapter->dbg.timeout_cmd_id =
|
||||
adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index];
|
||||
|
@ -941,6 +938,14 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
|
|||
|
||||
dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n",
|
||||
adapter->ps_mode, adapter->ps_state);
|
||||
|
||||
if (cmd_node->wait_q_enabled) {
|
||||
adapter->cmd_wait_q.status = -ETIMEDOUT;
|
||||
wake_up_interruptible(&adapter->cmd_wait_q.wait);
|
||||
mwifiex_cancel_pending_ioctl(adapter);
|
||||
/* reset cmd_sent flag to unblock new commands */
|
||||
adapter->cmd_sent = false;
|
||||
}
|
||||
}
|
||||
if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
|
||||
mwifiex_init_fw_complete(adapter);
|
||||
|
|
|
@ -161,7 +161,6 @@ static int mwifiex_sdio_suspend(struct device *dev)
|
|||
struct sdio_mmc_card *card;
|
||||
struct mwifiex_adapter *adapter;
|
||||
mmc_pm_flag_t pm_flag = 0;
|
||||
int hs_actived = 0;
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
||||
|
@ -188,12 +187,14 @@ static int mwifiex_sdio_suspend(struct device *dev)
|
|||
adapter = card->adapter;
|
||||
|
||||
/* Enable the Host Sleep */
|
||||
hs_actived = mwifiex_enable_hs(adapter);
|
||||
if (hs_actived) {
|
||||
pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n");
|
||||
ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
|
||||
if (!mwifiex_enable_hs(adapter)) {
|
||||
dev_err(adapter->dev, "cmd: failed to suspend\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
dev_dbg(adapter->dev, "cmd: suspend with MMC_PM_KEEP_POWER\n");
|
||||
ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
|
||||
|
||||
/* Indicate device suspended */
|
||||
adapter->is_suspended = true;
|
||||
|
||||
|
|
|
@ -297,6 +297,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
|
|||
/*=== Customer ID ===*/
|
||||
/****** 8188CU ********/
|
||||
{RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/
|
||||
{RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/
|
||||
{RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/
|
||||
{RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/
|
||||
{RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/
|
||||
|
|
|
@ -452,29 +452,85 @@ static void xennet_make_frags(struct sk_buff *skb, struct net_device *dev,
|
|||
/* Grant backend access to each skb fragment page. */
|
||||
for (i = 0; i < frags; i++) {
|
||||
skb_frag_t *frag = skb_shinfo(skb)->frags + i;
|
||||
struct page *page = skb_frag_page(frag);
|
||||
|
||||
tx->flags |= XEN_NETTXF_more_data;
|
||||
len = skb_frag_size(frag);
|
||||
offset = frag->page_offset;
|
||||
|
||||
id = get_id_from_freelist(&np->tx_skb_freelist, np->tx_skbs);
|
||||
np->tx_skbs[id].skb = skb_get(skb);
|
||||
tx = RING_GET_REQUEST(&np->tx, prod++);
|
||||
tx->id = id;
|
||||
ref = gnttab_claim_grant_reference(&np->gref_tx_head);
|
||||
BUG_ON((signed short)ref < 0);
|
||||
/* Data must not cross a page boundary. */
|
||||
BUG_ON(len + offset > PAGE_SIZE<<compound_order(page));
|
||||
|
||||
mfn = pfn_to_mfn(page_to_pfn(skb_frag_page(frag)));
|
||||
gnttab_grant_foreign_access_ref(ref, np->xbdev->otherend_id,
|
||||
mfn, GNTMAP_readonly);
|
||||
/* Skip unused frames from start of page */
|
||||
page += offset >> PAGE_SHIFT;
|
||||
offset &= ~PAGE_MASK;
|
||||
|
||||
tx->gref = np->grant_tx_ref[id] = ref;
|
||||
tx->offset = frag->page_offset;
|
||||
tx->size = skb_frag_size(frag);
|
||||
tx->flags = 0;
|
||||
while (len > 0) {
|
||||
unsigned long bytes;
|
||||
|
||||
BUG_ON(offset >= PAGE_SIZE);
|
||||
|
||||
bytes = PAGE_SIZE - offset;
|
||||
if (bytes > len)
|
||||
bytes = len;
|
||||
|
||||
tx->flags |= XEN_NETTXF_more_data;
|
||||
|
||||
id = get_id_from_freelist(&np->tx_skb_freelist,
|
||||
np->tx_skbs);
|
||||
np->tx_skbs[id].skb = skb_get(skb);
|
||||
tx = RING_GET_REQUEST(&np->tx, prod++);
|
||||
tx->id = id;
|
||||
ref = gnttab_claim_grant_reference(&np->gref_tx_head);
|
||||
BUG_ON((signed short)ref < 0);
|
||||
|
||||
mfn = pfn_to_mfn(page_to_pfn(page));
|
||||
gnttab_grant_foreign_access_ref(ref,
|
||||
np->xbdev->otherend_id,
|
||||
mfn, GNTMAP_readonly);
|
||||
|
||||
tx->gref = np->grant_tx_ref[id] = ref;
|
||||
tx->offset = offset;
|
||||
tx->size = bytes;
|
||||
tx->flags = 0;
|
||||
|
||||
offset += bytes;
|
||||
len -= bytes;
|
||||
|
||||
/* Next frame */
|
||||
if (offset == PAGE_SIZE && len) {
|
||||
BUG_ON(!PageCompound(page));
|
||||
page++;
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
np->tx.req_prod_pvt = prod;
|
||||
}
|
||||
|
||||
/*
|
||||
* Count how many ring slots are required to send the frags of this
|
||||
* skb. Each frag might be a compound page.
|
||||
*/
|
||||
static int xennet_count_skb_frag_slots(struct sk_buff *skb)
|
||||
{
|
||||
int i, frags = skb_shinfo(skb)->nr_frags;
|
||||
int pages = 0;
|
||||
|
||||
for (i = 0; i < frags; i++) {
|
||||
skb_frag_t *frag = skb_shinfo(skb)->frags + i;
|
||||
unsigned long size = skb_frag_size(frag);
|
||||
unsigned long offset = frag->page_offset;
|
||||
|
||||
/* Skip unused frames from start of page */
|
||||
offset &= ~PAGE_MASK;
|
||||
|
||||
pages += PFN_UP(offset + size);
|
||||
}
|
||||
|
||||
return pages;
|
||||
}
|
||||
|
||||
static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
unsigned short id;
|
||||
|
@ -487,23 +543,23 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
grant_ref_t ref;
|
||||
unsigned long mfn;
|
||||
int notify;
|
||||
int frags = skb_shinfo(skb)->nr_frags;
|
||||
int slots;
|
||||
unsigned int offset = offset_in_page(data);
|
||||
unsigned int len = skb_headlen(skb);
|
||||
unsigned long flags;
|
||||
|
||||
frags += DIV_ROUND_UP(offset + len, PAGE_SIZE);
|
||||
if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
|
||||
printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n",
|
||||
frags);
|
||||
dump_stack();
|
||||
slots = DIV_ROUND_UP(offset + len, PAGE_SIZE) +
|
||||
xennet_count_skb_frag_slots(skb);
|
||||
if (unlikely(slots > MAX_SKB_FRAGS + 1)) {
|
||||
net_alert_ratelimited(
|
||||
"xennet: skb rides the rocket: %d slots\n", slots);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&np->tx_lock, flags);
|
||||
|
||||
if (unlikely(!netif_carrier_ok(dev) ||
|
||||
(frags > 1 && !xennet_can_sg(dev)) ||
|
||||
(slots > 1 && !xennet_can_sg(dev)) ||
|
||||
netif_needs_gso(skb, netif_skb_features(skb)))) {
|
||||
spin_unlock_irqrestore(&np->tx_lock, flags);
|
||||
goto drop;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue