Commit 70f05366 authored by Jeff Garzik's avatar Jeff Garzik

Merge branch 'master' into upstream

parents c0bc8721 120bda20
VERSION = 2 VERSION = 2
PATCHLEVEL = 6 PATCHLEVEL = 6
SUBLEVEL = 17 SUBLEVEL = 18
EXTRAVERSION = EXTRAVERSION = -rc1
NAME=Crazed Snow-Weasel NAME=Crazed Snow-Weasel
# *DOCUMENTATION* # *DOCUMENTATION*
...@@ -528,7 +528,7 @@ export MODLIB ...@@ -528,7 +528,7 @@ export MODLIB
ifdef INSTALL_MOD_STRIP ifdef INSTALL_MOD_STRIP
ifeq ($(INSTALL_MOD_STRIP),1) ifeq ($(INSTALL_MOD_STRIP),1)
mod_strip_cmd = $STRIP) --strip-debug mod_strip_cmd = $(STRIP) --strip-debug
else else
mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP) mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP)
endif # INSTALL_MOD_STRIP=1 endif # INSTALL_MOD_STRIP=1
......
...@@ -107,3 +107,48 @@ void __init at91rm9200_map_io(void) ...@@ -107,3 +107,48 @@ void __init at91rm9200_map_io(void)
iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc));
} }
/*
* The default interrupt priority levels (0 = lowest, 7 = highest).
*/
static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
7, /* Advanced Interrupt Controller (FIQ) */
7, /* System Peripherals */
0, /* Parallel IO Controller A */
0, /* Parallel IO Controller B */
0, /* Parallel IO Controller C */
0, /* Parallel IO Controller D */
6, /* USART 0 */
6, /* USART 1 */
6, /* USART 2 */
6, /* USART 3 */
0, /* Multimedia Card Interface */
4, /* USB Device Port */
0, /* Two-Wire Interface */
6, /* Serial Peripheral Interface */
5, /* Serial Synchronous Controller 0 */
5, /* Serial Synchronous Controller 1 */
5, /* Serial Synchronous Controller 2 */
0, /* Timer Counter 0 */
0, /* Timer Counter 1 */
0, /* Timer Counter 2 */
0, /* Timer Counter 3 */
0, /* Timer Counter 4 */
0, /* Timer Counter 5 */
3, /* USB Host port */
3, /* Ethernet MAC */
0, /* Advanced Interrupt Controller (IRQ0) */
0, /* Advanced Interrupt Controller (IRQ1) */
0, /* Advanced Interrupt Controller (IRQ2) */
0, /* Advanced Interrupt Controller (IRQ3) */
0, /* Advanced Interrupt Controller (IRQ4) */
0, /* Advanced Interrupt Controller (IRQ5) */
0 /* Advanced Interrupt Controller (IRQ6) */
};
void __init at91rm9200_init_irq(unsigned int priority[NR_AIC_IRQS])
{
if (!priority)
priority = at91rm9200_default_irq_priority;
at91_aic_init(priority);
}
...@@ -8,13 +8,19 @@ ...@@ -8,13 +8,19 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
void at91_gpio_irq_setup(unsigned banks); /* Interrupts */
extern void __init at91rm9200_init_irq(unsigned int priority[]);
extern void __init at91_aic_init(unsigned int priority[]);
extern void __init at91_gpio_irq_setup(unsigned banks);
/* Timer */
struct sys_timer; struct sys_timer;
extern struct sys_timer at91rm9200_timer; extern struct sys_timer at91rm9200_timer;
/* Memory Map */
extern void __init at91rm9200_map_io(void); extern void __init at91rm9200_map_io(void);
/* Clocks */
extern int __init at91_clock_init(unsigned long main_clock); extern int __init at91_clock_init(unsigned long main_clock);
struct device; struct device;
extern void __init at91_clock_associate(const char *id, struct device *dev, const char *func); extern void __init at91_clock_associate(const char *id, struct device *dev, const char *func);
......
...@@ -36,58 +36,20 @@ ...@@ -36,58 +36,20 @@
#include "generic.h" #include "generic.h"
/*
* The default interrupt priority levels (0 = lowest, 7 = highest).
*/
static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = {
7, /* Advanced Interrupt Controller */
7, /* System Peripheral */
0, /* Parallel IO Controller A */
0, /* Parallel IO Controller B */
0, /* Parallel IO Controller C */
0, /* Parallel IO Controller D */
6, /* USART 0 */
6, /* USART 1 */
6, /* USART 2 */
6, /* USART 3 */
0, /* Multimedia Card Interface */
4, /* USB Device Port */
0, /* Two-Wire Interface */
6, /* Serial Peripheral Interface */
5, /* Serial Synchronous Controller */
5, /* Serial Synchronous Controller */
5, /* Serial Synchronous Controller */
0, /* Timer Counter 0 */
0, /* Timer Counter 1 */
0, /* Timer Counter 2 */
0, /* Timer Counter 3 */
0, /* Timer Counter 4 */
0, /* Timer Counter 5 */
3, /* USB Host port */
3, /* Ethernet MAC */
0, /* Advanced Interrupt Controller */
0, /* Advanced Interrupt Controller */
0, /* Advanced Interrupt Controller */
0, /* Advanced Interrupt Controller */
0, /* Advanced Interrupt Controller */
0, /* Advanced Interrupt Controller */
0 /* Advanced Interrupt Controller */
};
static void at91_aic_mask_irq(unsigned int irq)
static void at91rm9200_mask_irq(unsigned int irq)
{ {
/* Disable interrupt on AIC */ /* Disable interrupt on AIC */
at91_sys_write(AT91_AIC_IDCR, 1 << irq); at91_sys_write(AT91_AIC_IDCR, 1 << irq);
} }
static void at91rm9200_unmask_irq(unsigned int irq) static void at91_aic_unmask_irq(unsigned int irq)
{ {
/* Enable interrupt on AIC */ /* Enable interrupt on AIC */
at91_sys_write(AT91_AIC_IECR, 1 << irq); at91_sys_write(AT91_AIC_IECR, 1 << irq);
} }
static int at91rm9200_irq_type(unsigned irq, unsigned type) static int at91_aic_set_type(unsigned irq, unsigned type)
{ {
unsigned int smr, srctype; unsigned int smr, srctype;
...@@ -122,7 +84,7 @@ static int at91rm9200_irq_type(unsigned irq, unsigned type) ...@@ -122,7 +84,7 @@ static int at91rm9200_irq_type(unsigned irq, unsigned type)
static u32 wakeups; static u32 wakeups;
static u32 backups; static u32 backups;
static int at91rm9200_irq_set_wake(unsigned irq, unsigned value) static int at91_aic_set_wake(unsigned irq, unsigned value)
{ {
if (unlikely(irq >= 32)) if (unlikely(irq >= 32))
return -EINVAL; return -EINVAL;
...@@ -149,28 +111,24 @@ void at91_irq_resume(void) ...@@ -149,28 +111,24 @@ void at91_irq_resume(void)
} }
#else #else
#define at91rm9200_irq_set_wake NULL #define at91_aic_set_wake NULL
#endif #endif
static struct irqchip at91rm9200_irq_chip = { static struct irqchip at91_aic_chip = {
.ack = at91rm9200_mask_irq, .ack = at91_aic_mask_irq,
.mask = at91rm9200_mask_irq, .mask = at91_aic_mask_irq,
.unmask = at91rm9200_unmask_irq, .unmask = at91_aic_unmask_irq,
.set_type = at91rm9200_irq_type, .set_type = at91_aic_set_type,
.set_wake = at91rm9200_irq_set_wake, .set_wake = at91_aic_set_wake,
}; };
/* /*
* Initialize the AIC interrupt controller. * Initialize the AIC interrupt controller.
*/ */
void __init at91rm9200_init_irq(unsigned int priority[NR_AIC_IRQS]) void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
{ {
unsigned int i; unsigned int i;
/* No priority list specified for this board -> use defaults */
if (priority == NULL)
priority = at91rm9200_default_irq_priority;
/* /*
* The IVR is used by macro get_irqnr_and_base to read and verify. * The IVR is used by macro get_irqnr_and_base to read and verify.
* The irq number is NR_AIC_IRQS when a spurious interrupt has occurred. * The irq number is NR_AIC_IRQS when a spurious interrupt has occurred.
...@@ -178,10 +136,10 @@ void __init at91rm9200_init_irq(unsigned int priority[NR_AIC_IRQS]) ...@@ -178,10 +136,10 @@ void __init at91rm9200_init_irq(unsigned int priority[NR_AIC_IRQS])
for (i = 0; i < NR_AIC_IRQS; i++) { for (i = 0; i < NR_AIC_IRQS; i++) {
/* Put irq number in Source Vector Register: */ /* Put irq number in Source Vector Register: */
at91_sys_write(AT91_AIC_SVR(i), i); at91_sys_write(AT91_AIC_SVR(i), i);
/* Store the Source Mode Register as defined in table above */ /* Active Low interrupt, with the specified priority */
at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]);
set_irq_chip(i, &at91rm9200_irq_chip); set_irq_chip(i, &at91_aic_chip);
set_irq_handler(i, do_level_IRQ); set_irq_handler(i, do_level_IRQ);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE); set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -36,7 +35,6 @@ ...@@ -36,7 +35,6 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/irq.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/dma.h> #include <asm/dma.h>
#include <asm/dma-mapping.h> #include <asm/dma-mapping.h>
......
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/irq.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -96,26 +96,24 @@ void __init pnx4008_init_irq(void) ...@@ -96,26 +96,24 @@ void __init pnx4008_init_irq(void)
{ {
unsigned int i; unsigned int i;
/* configure and enable IRQ 0,1,30,31 (cascade interrupts) mask all others */ /* configure IRQ's */
for (i = 0; i < NR_IRQS; i++) {
set_irq_flags(i, IRQF_VALID);
set_irq_chip(i, &pnx4008_irq_chip);
pnx4008_set_irq_type(i, pnx4008_irq_type[i]);
}
/* configure and enable IRQ 0,1,30,31 (cascade interrupts) */
pnx4008_set_irq_type(SUB1_IRQ_N, pnx4008_irq_type[SUB1_IRQ_N]); pnx4008_set_irq_type(SUB1_IRQ_N, pnx4008_irq_type[SUB1_IRQ_N]);
pnx4008_set_irq_type(SUB2_IRQ_N, pnx4008_irq_type[SUB2_IRQ_N]); pnx4008_set_irq_type(SUB2_IRQ_N, pnx4008_irq_type[SUB2_IRQ_N]);
pnx4008_set_irq_type(SUB1_FIQ_N, pnx4008_irq_type[SUB1_FIQ_N]); pnx4008_set_irq_type(SUB1_FIQ_N, pnx4008_irq_type[SUB1_FIQ_N]);
pnx4008_set_irq_type(SUB2_FIQ_N, pnx4008_irq_type[SUB2_FIQ_N]); pnx4008_set_irq_type(SUB2_FIQ_N, pnx4008_irq_type[SUB2_FIQ_N]);
/* mask all others */
__raw_writel((1 << SUB2_FIQ_N) | (1 << SUB1_FIQ_N) | __raw_writel((1 << SUB2_FIQ_N) | (1 << SUB1_FIQ_N) |
(1 << SUB2_IRQ_N) | (1 << SUB1_IRQ_N), (1 << SUB2_IRQ_N) | (1 << SUB1_IRQ_N),
INTC_ER(MAIN_BASE_INT)); INTC_ER(MAIN_BASE_INT));
__raw_writel(0, INTC_ER(SIC1_BASE_INT)); __raw_writel(0, INTC_ER(SIC1_BASE_INT));
__raw_writel(0, INTC_ER(SIC2_BASE_INT)); __raw_writel(0, INTC_ER(SIC2_BASE_INT));
/* configure all other IRQ's */
for (i = 0; i < NR_IRQS; i++) {
if (i == SUB2_FIQ_N || i == SUB1_FIQ_N ||
i == SUB2_IRQ_N || i == SUB1_IRQ_N)
continue;
set_irq_flags(i, IRQF_VALID);
set_irq_chip(i, &pnx4008_irq_chip);
pnx4008_set_irq_type(i, pnx4008_irq_type[i]);
}
} }
...@@ -20,17 +20,15 @@ ...@@ -20,17 +20,15 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kallsyms.h> #include <linux/kallsyms.h>
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/irq.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/leds.h> #include <asm/leds.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <linux/time.h>
#include <linux/timex.h>
#include <asm/errno.h> #include <asm/errno.h>
/*! Note: all timers are UPCOUNTING */ /*! Note: all timers are UPCOUNTING */
......
...@@ -405,20 +405,22 @@ static void mpic_unmask_irq(unsigned int irq) ...@@ -405,20 +405,22 @@ static void mpic_unmask_irq(unsigned int irq)
unsigned int loops = 100000; unsigned int loops = 100000;
struct mpic *mpic = mpic_from_irq(irq); struct mpic *mpic = mpic_from_irq(irq);
unsigned int src = mpic_irq_to_hw(irq); unsigned int src = mpic_irq_to_hw(irq);
unsigned long flags;
DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src); DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
spin_lock_irqsave(&mpic_lock, flags);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
~MPIC_VECPRI_MASK); ~MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */ /* make sure mask gets to controller before we return to user */
do { do {
if (!loops--) { if (!loops--) {
printk(KERN_ERR "mpic_enable_irq timeout\n"); printk(KERN_ERR "mpic_enable_irq timeout\n");
break; break;
} }
} while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK); } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK);
spin_unlock_irqrestore(&mpic_lock, flags);
} }
static void mpic_mask_irq(unsigned int irq) static void mpic_mask_irq(unsigned int irq)
...@@ -426,9 +428,11 @@ static void mpic_mask_irq(unsigned int irq) ...@@ -426,9 +428,11 @@ static void mpic_mask_irq(unsigned int irq)
unsigned int loops = 100000; unsigned int loops = 100000;
struct mpic *mpic = mpic_from_irq(irq); struct mpic *mpic = mpic_from_irq(irq);
unsigned int src = mpic_irq_to_hw(irq); unsigned int src = mpic_irq_to_hw(irq);
unsigned long flags;
DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src); DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
spin_lock_irqsave(&mpic_lock, flags);
mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) | mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
MPIC_VECPRI_MASK); MPIC_VECPRI_MASK);
...@@ -440,6 +444,7 @@ static void mpic_mask_irq(unsigned int irq) ...@@ -440,6 +444,7 @@ static void mpic_mask_irq(unsigned int irq)
break; break;
} }
} while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK)); } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK));
spin_unlock_irqrestore(&mpic_lock, flags);
} }
static void mpic_end_irq(unsigned int irq) static void mpic_end_irq(unsigned int irq)
...@@ -624,9 +629,10 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, ...@@ -624,9 +629,10 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
struct irq_desc *desc = get_irq_desc(virq); struct irq_desc *desc = get_irq_desc(virq);
struct irq_chip *chip; struct irq_chip *chip;
struct mpic *mpic = h->host_data; struct mpic *mpic = h->host_data;
unsigned int vecpri = MPIC_VECPRI_SENSE_LEVEL | u32 v, vecpri = MPIC_VECPRI_SENSE_LEVEL |
MPIC_VECPRI_POLARITY_NEGATIVE; MPIC_VECPRI_POLARITY_NEGATIVE;
int level; int level;
unsigned long iflags;
pr_debug("mpic: map virq %d, hwirq 0x%lx, flags: 0x%x\n", pr_debug("mpic: map virq %d, hwirq 0x%lx, flags: 0x%x\n",
virq, hw, flags); virq, hw, flags);
...@@ -668,11 +674,21 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq, ...@@ -668,11 +674,21 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
} }
#endif #endif
/* Reconfigure irq */ /* Reconfigure irq. We must preserve the mask bit as we can be called
vecpri |= MPIC_VECPRI_MASK | hw | (8 << MPIC_VECPRI_PRIORITY_SHIFT); * while the interrupt is still active (This may change in the future
mpic_irq_write(hw, MPIC_IRQ_VECTOR_PRI, vecpri); * but for now, it is the case).
*/
pr_debug("mpic: mapping as IRQ\n"); spin_lock_irqsave(&mpic_lock, iflags);
v = mpic_irq_read(hw, MPIC_IRQ_VECTOR_PRI);
vecpri = (v &
~(MPIC_VECPRI_POLARITY_MASK | MPIC_VECPRI_SENSE_MASK)) |
vecpri;
if (vecpri != v)
mpic_irq_write(hw, MPIC_IRQ_VECTOR_PRI, vecpri);
spin_unlock_irqrestore(&mpic_lock, iflags);
pr_debug("mpic: mapping as IRQ, vecpri = 0x%08x (was 0x%08x)\n",
vecpri, v);
set_irq_chip_data(virq, mpic); set_irq_chip_data(virq, mpic);
set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq); set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq);
...@@ -904,8 +920,8 @@ void __init mpic_init(struct mpic *mpic) ...@@ -904,8 +920,8 @@ void __init mpic_init(struct mpic *mpic)
/* do senses munging */ /* do senses munging */
if (mpic->senses && i < mpic->senses_count) if (mpic->senses && i < mpic->senses_count)
vecpri = mpic_flags_to_vecpri(mpic->senses[i], vecpri |= mpic_flags_to_vecpri(mpic->senses[i],
&level); &level);
else else
vecpri |= MPIC_VECPRI_SENSE_LEVEL; vecpri |= MPIC_VECPRI_SENSE_LEVEL;
...@@ -955,14 +971,17 @@ void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio) ...@@ -955,14 +971,17 @@ void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio)
void __init mpic_set_serial_int(struct mpic *mpic, int enable) void __init mpic_set_serial_int(struct mpic *mpic, int enable)
{ {
unsigned long flags;
u32 v; u32 v;
spin_lock_irqsave(&mpic_lock, flags);
v = mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1); v = mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1);
if (enable) if (enable)
v |= MPIC_GREG_GLOBAL_CONF_1_SIE; v |= MPIC_GREG_GLOBAL_CONF_1_SIE;
else else
v &= ~MPIC_GREG_GLOBAL_CONF_1_SIE; v &= ~MPIC_GREG_GLOBAL_CONF_1_SIE;
mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1, v); mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_1, v);
spin_unlock_irqrestore(&mpic_lock, flags);
} }
void mpic_irq_set_priority(unsigned int irq, unsigned int pri) void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
......
...@@ -1032,7 +1032,9 @@ static void sun4v_vdev_irq_trans_init(struct device_node *dp) ...@@ -1032,7 +1032,9 @@ static void sun4v_vdev_irq_trans_init(struct device_node *dp)
static void irq_trans_init(struct device_node *dp) static void irq_trans_init(struct device_node *dp)
{ {
const char *model; const char *model;
#ifdef CONFIG_PCI
int i; int i;
#endif
model = of_get_property(dp, "model", NULL); model = of_get_property(dp, "model", NULL);
if (!model) if (!model)
......
...@@ -124,11 +124,6 @@ EXPORT_SYMBOL(__write_lock); ...@@ -124,11 +124,6 @@ EXPORT_SYMBOL(__write_lock);
EXPORT_SYMBOL(__write_unlock); EXPORT_SYMBOL(__write_unlock);
EXPORT_SYMBOL(__write_trylock); EXPORT_SYMBOL(__write_trylock);
#if defined(CONFIG_MCOUNT)
extern void _mcount(void);
EXPORT_SYMBOL(_mcount);
#endif
/* CPU online map and active count. */ /* CPU online map and active count. */
EXPORT_SYMBOL(cpu_online_map); EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL(phys_cpu_present_map); EXPORT_SYMBOL(phys_cpu_present_map);
...@@ -136,6 +131,11 @@ EXPORT_SYMBOL(phys_cpu_present_map); ...@@ -136,6 +131,11 @@ EXPORT_SYMBOL(phys_cpu_present_map);
EXPORT_SYMBOL(smp_call_function); EXPORT_SYMBOL(smp_call_function);
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
#if defined(CONFIG_MCOUNT)
extern void _mcount(void);
EXPORT_SYMBOL(_mcount);
#endif
EXPORT_SYMBOL(sparc64_get_clock_tick); EXPORT_SYMBOL(sparc64_get_clock_tick);
/* semaphores */ /* semaphores */
......
...@@ -788,12 +788,15 @@ static int __devinit clock_probe(struct of_device *op, const struct of_device_id ...@@ -788,12 +788,15 @@ static int __devinit clock_probe(struct of_device *op, const struct of_device_id
if (!regs) if (!regs)
return -ENOMEM; return -ENOMEM;
#ifdef CONFIG_PCI
if (!strcmp(model, "ds1287") || if (!strcmp(model, "ds1287") ||
!strcmp(model, "m5819") || !strcmp(model, "m5819") ||
!strcmp(model, "m5819p") || !strcmp(model, "m5819p") ||
!strcmp(model, "m5823")) { !strcmp(model, "m5823")) {
ds1287_regs = (unsigned long) regs; ds1287_regs = (unsigned long) regs;
} else if (model[5] == '0' && model[6] == '2') { } else
#endif
if (model[5] == '0' && model[6] == '2') {
mstk48t02_regs = regs; mstk48t02_regs = regs;
} else if(model[5] == '0' && model[6] == '8') { } else if(model[5] == '0' && model[6] == '8') {
mstk48t08_regs = regs; mstk48t08_regs = regs;
......
...@@ -1052,7 +1052,7 @@ static void ahci_thaw(struct ata_port *ap) ...@@ -1052,7 +1052,7 @@ static void ahci_thaw(struct ata_port *ap)
static void ahci_error_handler(struct ata_port *ap) static void ahci_error_handler(struct ata_port *ap)
{ {
if (!(ap->flags & ATA_FLAG_FROZEN)) { if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
/* restart engine */ /* restart engine */
ahci_stop_engine(ap); ahci_stop_engine(ap);
ahci_start_engine(ap); ahci_start_engine(ap);
...@@ -1323,6 +1323,17 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1323,6 +1323,17 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (!printed_version++) if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
/* JMicron-specific fixup: make sure we're in AHCI mode */
/* This is protected from races with ata_jmicron by the pci probe
locking */
if (pdev->vendor == PCI_VENDOR_ID_JMICRON) {
/* AHCI enable, AHCI on function 0 */
pci_write_config_byte(pdev, 0x41, 0xa1);
/* Function 1 is the PATA controller */
if (PCI_FUNC(pdev->devfn))
return -ENODEV;
}
rc = pci_enable_device(pdev); rc = pci_enable_device(pdev);
if (rc) if (rc)
return rc; return rc;
...@@ -1378,10 +1389,6 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1378,10 +1389,6 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (have_msi) if (have_msi)
hpriv->flags |= AHCI_FLAG_MSI; hpriv->flags |= AHCI_FLAG_MSI;
/* JMicron-specific fixup: make sure we're in AHCI mode */
if (pdev->vendor == 0x197b)
pci_write_config_byte(pdev, 0x41, 0xa1);
/* initialize adapter */ /* initialize adapter */
rc = ahci_host_init(probe_ent); rc = ahci_host_init(probe_ent);
if (rc) if (rc)
......
This diff is collapsed.
This diff is collapsed.
...@@ -397,20 +397,129 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf) ...@@ -397,20 +397,129 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf)
} }
} }
int ata_scsi_device_resume(struct scsi_device *sdev) /**
* ata_scsi_device_suspend - suspend ATA device associated with sdev
* @sdev: the SCSI device to suspend
* @state: target power management state
*
* Request suspend EH action on the ATA device associated with
* @sdev and wait for the operation to complete.
*
* LOCKING:
* Kernel thread context (may sleep).
*
* RETURNS:
* 0 on success, -errno otherwise.
*/
int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state)
{ {
struct ata_port *ap = ata_shost_to_port(sdev->host); struct ata_port *ap = ata_shost_to_port(sdev->host);
struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
unsigned long flags;
unsigned int action;
int rc = 0;
if (!dev)
goto out;
spin_lock_irqsave(ap->lock, flags);
/* wait for the previous resume to complete */
while (dev->flags & ATA_DFLAG_SUSPENDED) {
spin_unlock_irqrestore(ap->lock, flags);
ata_port_wait_eh(ap);
spin_lock_irqsave(ap->lock, flags);
}
/* if @sdev is already detached, nothing to do */
if (sdev->sdev_state == SDEV_OFFLINE ||
sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL)
goto out_unlock;
/* request suspend */
action = ATA_EH_SUSPEND;
if (state.event != PM_EVENT_SUSPEND)
action |= ATA_EH_PM_FREEZE;
ap->eh_info.dev_action[dev->devno] |= action;
ap->eh_info.flags |= ATA_EHI_QUIET;
ata_port_schedule_eh(ap);
spin_unlock_irqrestore(ap->lock, flags);
/* wait for EH to do the job */
ata_port_wait_eh(ap);
spin_lock_irqsave(ap->lock, flags);
/* If @sdev is still attached but the associated ATA device
* isn't suspended, the operation failed.
*/
if (sdev->sdev_state != SDEV_OFFLINE &&
sdev->sdev_state != SDEV_CANCEL && sdev->sdev_state != SDEV_DEL &&
!(dev->flags & ATA_DFLAG_SUSPENDED))
rc = -EIO;
return ata_device_resume(dev); out_unlock:
spin_unlock_irqrestore(ap->lock, flags);
out:
if (rc == 0)
sdev->sdev_gendev.power.power_state = state;
return rc;
} }
int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state) /**
* ata_scsi_device_resume - resume ATA device associated with sdev
* @sdev: the SCSI device to resume
*
* Request resume EH action on the ATA device associated with
* @sdev and return immediately. This enables parallel
* wakeup/spinup of devices.
*
* LOCKING:
* Kernel thread context (may sleep).
*
* RETURNS:
* 0.
*/
int ata_scsi_device_resume(struct scsi_device *sdev)
{ {
struct ata_port *ap = ata_shost_to_port(sdev->host); struct ata_port *ap = ata_shost_to_port(sdev->host);
struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
struct ata_eh_info *ehi = &ap->eh_info;
unsigned long flags;
unsigned int action;
if (!dev)
goto out;
spin_lock_irqsave(ap->lock, flags);
/* if @sdev is already detached, nothing to do */
if (sdev->sdev_state == SDEV_OFFLINE ||
sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL)
goto out_unlock;
return ata_device_suspend(dev, state); /* request resume */
action = ATA_EH_RESUME;
if (sdev->sdev_gendev.power.power_state.event == PM_EVENT_SUSPEND)
__ata_ehi_hotplugged(ehi);
else
action |= ATA_EH_PM_FREEZE | ATA_EH_SOFTRESET;
ehi->dev_action[dev->devno] |= action;
/* We don't want autopsy and verbose EH messages. Disable
* those if we're the only device on this link.
*/
if (ata_port_max_devices(ap) == 1)
ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
ata_port_schedule_eh(ap);
out_unlock:
spin_unlock_irqrestore(ap->lock, flags);
out:
sdev->sdev_gendev.power.power_state = PMSG_ON;
return 0;
} }
/** /**
...@@ -2930,7 +3039,7 @@ void ata_scsi_hotplug(void *data) ...@@ -2930,7 +3039,7 @@ void ata_scsi_hotplug(void *data)
struct ata_port *ap = data; struct ata_port *ap = data;
int i; int i;
if (ap->flags & ATA_FLAG_UNLOADING) { if (ap->pflags & ATA_PFLAG_UNLOADING) {
DPRINTK("ENTER/EXIT - unloading\n"); DPRINTK("ENTER/EXIT - unloading\n");
return; return;
} }
...@@ -3011,6 +3120,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, ...@@ -3011,6 +3120,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
if (dev) { if (dev) {
ap->eh_info.probe_mask |= 1 << dev->devno; ap->eh_info.probe_mask |= 1 << dev->devno;
ap->eh_info.action |= ATA_EH_SOFTRESET; ap->eh_info.action |= ATA_EH_SOFTRESET;
ap->eh_info.flags |= ATA_EHI_RESUME_LINK;
} else } else
rc = -EINVAL; rc = -EINVAL;
} }
......
...@@ -109,6 +109,7 @@ enum { ...@@ -109,6 +109,7 @@ enum {
}; };
static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
static int sil_pci_device_resume(struct pci_dev *pdev);
static void sil_dev_config(struct ata_port *ap, struct ata_device *dev); static void sil_dev_config(struct ata_port *ap, struct ata_device *dev);
static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg); static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
...@@ -160,6 +161,8 @@ static struct pci_driver sil_pci_driver = { ...@@ -160,6 +161,8 @@ static struct pci_driver sil_pci_driver = {
.id_table = sil_pci_tbl, .id_table = sil_pci_tbl,
.probe = sil_init_one, .probe = sil_init_one,
.remove = ata_pci_remove_one, .remove = ata_pci_remove_one,
.suspend = ata_pci_device_suspend,
.resume = sil_pci_device_resume,
}; };
static struct scsi_host_template sil_sht = { static struct scsi_host_template sil_sht = {
...@@ -178,6 +181,8 @@ static struct scsi_host_template sil_sht = { ...@@ -178,6 +181,8 @@ static struct scsi_host_template sil_sht = {
.slave_configure = ata_scsi_slave_config, .slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy, .slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param, .bios_param = ata_std_bios_param,
.suspend = ata_scsi_device_suspend,
.resume = ata_scsi_device_resume,
}; };
static const struct ata_port_operations sil_ops = { static const struct ata_port_operations sil_ops = {
...@@ -370,7 +375,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) ...@@ -370,7 +375,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
* during hardreset makes controllers with broken SIEN * during hardreset makes controllers with broken SIEN
* repeat probing needlessly. * repeat probing needlessly.
*/ */
if (!(ap->flags & ATA_FLAG_FROZEN)) { if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
ata_ehi_hotplugged(&ap->eh_info); ata_ehi_hotplugged(&ap->eh_info);
ap->eh_info.serror |= serror; ap->eh_info.serror |= serror;
} }
...@@ -561,6 +566,52 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) ...@@ -561,6 +566,52 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
} }
} }
static void sil_init_controller(struct pci_dev *pdev,
int n_ports, unsigned long host_flags,
void __iomem *mmio_base)
{
u8 cls;
u32 tmp;
int i;
/* Initialize FIFO PCI bus arbitration */
cls = sil_get_device_cache_line(pdev);
if (cls) {
cls >>= 3;
cls++; /* cls = (line_size/8)+1 */
for (i = 0; i < n_ports; i++)
writew(cls << 8 | cls,
mmio_base + sil_port[i].fifo_cfg);
} else
dev_printk(KERN_WARNING, &pdev->dev,
"cache line size not set. Driver may not function\n");
/* Apply R_ERR on DMA activate FIS errata workaround */
if (host_flags & SIL_FLAG_RERR_ON_DMA_ACT) {
int cnt;
for (i = 0, cnt = 0; i < n_ports; i++) {
tmp = readl(mmio_base + sil_port[i].sfis_cfg);
if ((tmp & 0x3) != 0x01)
continue;
if (!cnt)
dev_printk(KERN_INFO, &pdev->dev,
"Applying R_ERR on DMA activate "
"FIS errata fix\n");
writel(tmp & ~0x3, mmio_base + sil_port[i].sfis_cfg);
cnt++;
}
}
if (n_ports == 4) {
/* flip the magic "make 4 ports work" bit */
tmp = readl(mmio_base + sil_port[2].bmdma);
if ((tmp & SIL_INTR_STEERING) == 0)
writel(tmp | SIL_INTR_STEERING,
mmio_base + sil_port[2].bmdma);
}
}
static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{ {
static int printed_version; static int printed_version;
...@@ -570,8 +621,6 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -570,8 +621,6 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
int rc; int rc;
unsigned int i; unsigned int i;
int pci_dev_busy = 0; int pci_dev_busy = 0;
u32 tmp;
u8 cls;
if (!printed_version++) if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
...@@ -630,42 +679,8 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -630,42 +679,8 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
ata_std_ports(&probe_ent->port[i]); ata_std_ports(&probe_ent->port[i]);
} }
/* Initialize FIFO PCI bus arbitration */ sil_init_controller(pdev, probe_ent->n_ports, probe_ent->host_flags,
cls = sil_get_device_cache_line(pdev); mmio_base);
if (cls) {
cls >>= 3;
cls++; /* cls = (line_size/8)+1 */
for (i = 0; i < probe_ent->n_ports; i++)
writew(cls << 8 | cls,
mmio_base + sil_port[i].fifo_cfg);
} else
dev_printk(KERN_WARNING, &pdev->dev,
"cache line size not set. Driver may not function\n");
/* Apply R_ERR on DMA activate FIS errata workaround */
if (probe_ent->host_flags & SIL_FLAG_RERR_ON_DMA_ACT) {
int cnt;
for (i = 0, cnt = 0; i < probe_ent->n_ports; i++) {
tmp = readl(mmio_base + sil_port[i].sfis_cfg);
if ((tmp & 0x3) != 0x01)
continue;
if (!cnt)
dev_printk(KERN_INFO, &pdev->dev,
"Applying R_ERR on DMA activate "
"FIS errata fix\n");
writel(tmp & ~0x3, mmio_base + sil_port[i].sfis_cfg);
cnt++;
}
}
if (ent->driver_data == sil_3114) {
/* flip the magic "make 4 ports work" bit */
tmp = readl(mmio_base + sil_port[2].bmdma);
if ((tmp & SIL_INTR_STEERING) == 0)
writel(tmp | SIL_INTR_STEERING,
mmio_base + sil_port[2].bmdma);
}
pci_set_master(pdev); pci_set_master(pdev);
...@@ -685,6 +700,18 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -685,6 +700,18 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
return rc; return rc;
} }
static int sil_pci_device_resume(struct pci_dev *pdev)
{
struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev);
ata_pci_device_do_resume(pdev);
sil_init_controller(pdev, host_set->n_ports, host_set->ports[0]->flags,
host_set->mmio_base);
ata_host_set_resume(host_set);
return 0;
}
static int __init sil_init(void) static int __init sil_init(void)
{ {
return pci_module_init(&sil_pci_driver); return pci_module_init(&sil_pci_driver);
......
...@@ -92,6 +92,7 @@ enum { ...@@ -92,6 +92,7 @@ enum {
HOST_CTRL_STOP = (1 << 18), /* latched PCI STOP */ HOST_CTRL_STOP = (1 << 18), /* latched PCI STOP */
HOST_CTRL_DEVSEL = (1 << 19), /* latched PCI DEVSEL */ HOST_CTRL_DEVSEL = (1 << 19), /* latched PCI DEVSEL */
HOST_CTRL_REQ64 = (1 << 20), /* latched PCI REQ64 */ HOST_CTRL_REQ64 = (1 << 20), /* latched PCI REQ64 */
HOST_CTRL_GLOBAL_RST = (1 << 31), /* global reset */
/* /*
* Port registers * Port registers
...@@ -338,6 +339,7 @@ static int sil24_port_start(struct ata_port *ap); ...@@ -338,6 +339,7 @@ static int sil24_port_start(struct ata_port *ap);
static void sil24_port_stop(struct ata_port *ap); static void sil24_port_stop(struct ata_port *ap);
static void sil24_host_stop(struct ata_host_set *host_set); static void sil24_host_stop(struct ata_host_set *host_set);
static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static int sil24_pci_device_resume(struct pci_dev *pdev);
static const struct pci_device_id sil24_pci_tbl[] = { static const struct pci_device_id sil24_pci_tbl[] = {
{ 0x1095, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 }, { 0x1095, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 },
...@@ -353,6 +355,8 @@ static struct pci_driver sil24_pci_driver = { ...@@ -353,6 +355,8 @@ static struct pci_driver sil24_pci_driver = {
.id_table = sil24_pci_tbl, .id_table = sil24_pci_tbl,
.probe = sil24_init_one, .probe = sil24_init_one,
.remove = ata_pci_remove_one, /* safe? */ .remove = ata_pci_remove_one, /* safe? */
.suspend = ata_pci_device_suspend,
.resume = sil24_pci_device_resume,
}; };
static struct scsi_host_template sil24_sht = { static struct scsi_host_template sil24_sht = {
...@@ -372,6 +376,8 @@ static struct scsi_host_template sil24_sht = { ...@@ -372,6 +376,8 @@ static struct scsi_host_template sil24_sht = {
.slave_configure = ata_scsi_slave_config, .slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy, .slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param, .bios_param = ata_std_bios_param,
.suspend = ata_scsi_device_suspend,
.resume = ata_scsi_device_resume,
}; };
static const struct ata_port_operations sil24_ops = { static const struct ata_port_operations sil24_ops = {
...@@ -607,7 +613,7 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class) ...@@ -607,7 +613,7 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
/* SStatus oscillates between zero and valid status after /* SStatus oscillates between zero and valid status after
* DEV_RST, debounce it. * DEV_RST, debounce it.
*/ */
rc = sata_phy_debounce(ap, sata_deb_timing_before_fsrst); rc = sata_phy_debounce(ap, sata_deb_timing_long);
if (rc) { if (rc) {
reason = "PHY debouncing failed"; reason = "PHY debouncing failed";
goto err; goto err;
...@@ -988,6 +994,64 @@ static void sil24_host_stop(struct ata_host_set *host_set) ...@@ -988,6 +994,64 @@ static void sil24_host_stop(struct ata_host_set *host_set)
kfree(hpriv); kfree(hpriv);
} }
static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
unsigned long host_flags,
void __iomem *host_base,
void __iomem *port_base)
{
u32 tmp;
int i;
/* GPIO off */
writel(0, host_base + HOST_FLASH_CMD);
/* clear global reset & mask interrupts during initialization */
writel(0, host_base + HOST_CTRL);
/* init ports */
for (i = 0; i < n_ports; i++) {
void __iomem *port = port_base + i * PORT_REGS_SIZE;
/* Initial PHY setting */
writel(0x20c, port + PORT_PHY_CFG);
/* Clear port RST */
tmp = readl(port + PORT_CTRL_STAT);
if (tmp & PORT_CS_PORT_RST) {
writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
tmp = ata_wait_register(port + PORT_CTRL_STAT,
PORT_CS_PORT_RST,
PORT_CS_PORT_RST, 10, 100);
if (tmp & PORT_CS_PORT_RST)
dev_printk(KERN_ERR, &pdev->dev,
"failed to clear port RST\n");
}
/* Configure IRQ WoC */
if (host_flags & SIL24_FLAG_PCIX_IRQ_WOC)
writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT);
else
writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
/* Zero error counters. */
writel(0x8000, port + PORT_DECODE_ERR_THRESH);
writel(0x8000, port + PORT_CRC_ERR_THRESH);
writel(0x8000, port + PORT_HSHK_ERR_THRESH);
writel(0x0000, port + PORT_DECODE_ERR_CNT);
writel(0x0000, port + PORT_CRC_ERR_CNT);
writel(0x0000, port + PORT_HSHK_ERR_CNT);
/* Always use 64bit activation */
writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR);
/* Clear port multiplier enable and resume bits */
writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR);
}
/* Turn on interrupts */
writel(IRQ_STAT_4PORTS, host_base + HOST_CTRL);
}
static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{ {
static int printed_version = 0; static int printed_version = 0;
...@@ -1076,9 +1140,6 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1076,9 +1140,6 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
} }
} }
/* GPIO off */
writel(0, host_base + HOST_FLASH_CMD);
/* Apply workaround for completion IRQ loss on PCI-X errata */ /* Apply workaround for completion IRQ loss on PCI-X errata */
if (probe_ent->host_flags & SIL24_FLAG_PCIX_IRQ_WOC) { if (probe_ent->host_flags & SIL24_FLAG_PCIX_IRQ_WOC) {
tmp = readl(host_base + HOST_CTRL); tmp = readl(host_base + HOST_CTRL);
...@@ -1090,56 +1151,18 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1090,56 +1151,18 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->host_flags &= ~SIL24_FLAG_PCIX_IRQ_WOC; probe_ent->host_flags &= ~SIL24_FLAG_PCIX_IRQ_WOC;
} }
/* clear global reset & mask interrupts during initialization */
writel(0, host_base + HOST_CTRL);
for (i = 0; i < probe_ent->n_ports; i++) { for (i = 0; i < probe_ent->n_ports; i++) {
void __iomem *port = port_base + i * PORT_REGS_SIZE; unsigned long portu =
unsigned long portu = (unsigned long)port; (unsigned long)port_base + i * PORT_REGS_SIZE;
probe_ent->port[i].cmd_addr = portu; probe_ent->port[i].cmd_addr = portu;
probe_ent->port[i].scr_addr = portu + PORT_SCONTROL; probe_ent->port[i].scr_addr = portu + PORT_SCONTROL;
ata_std_ports(&probe_ent->port[i]); ata_std_ports(&probe_ent->port[i]);
/* Initial PHY setting */
writel(0x20c, port + PORT_PHY_CFG);
/* Clear port RST */
tmp = readl(port + PORT_CTRL_STAT);
if (tmp & PORT_CS_PORT_RST) {
writel(PORT_CS_PORT_RST, port + PORT_CTRL_CLR);
tmp = ata_wait_register(port + PORT_CTRL_STAT,
PORT_CS_PORT_RST,
PORT_CS_PORT_RST, 10, 100);
if (tmp & PORT_CS_PORT_RST)
dev_printk(KERN_ERR, &pdev->dev,
"failed to clear port RST\n");
}
/* Configure IRQ WoC */
if (probe_ent->host_flags & SIL24_FLAG_PCIX_IRQ_WOC)
writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_STAT);
else
writel(PORT_CS_IRQ_WOC, port + PORT_CTRL_CLR);
/* Zero error counters. */
writel(0x8000, port + PORT_DECODE_ERR_THRESH);
writel(0x8000, port + PORT_CRC_ERR_THRESH);
writel(0x8000, port + PORT_HSHK_ERR_THRESH);
writel(0x0000, port + PORT_DECODE_ERR_CNT);
writel(0x0000, port + PORT_CRC_ERR_CNT);
writel(0x0000, port + PORT_HSHK_ERR_CNT);
/* Always use 64bit activation */
writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR);
/* Clear port multiplier enable and resume bits */
writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR);
} }
/* Turn on interrupts */ sil24_init_controller(pdev, probe_ent->n_ports, probe_ent->host_flags,
writel(IRQ_STAT_4PORTS, host_base + HOST_CTRL); host_base, port_base);
pci_set_master(pdev); pci_set_master(pdev);
...@@ -1162,6 +1185,25 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1162,6 +1185,25 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return rc; return rc;
} }
static int sil24_pci_device_resume(struct pci_dev *pdev)
{
struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev);
struct sil24_host_priv *hpriv = host_set->private_data;
ata_pci_device_do_resume(pdev);
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND)
writel(HOST_CTRL_GLOBAL_RST, hpriv->host_base + HOST_CTRL);
sil24_init_controller(pdev, host_set->n_ports,
host_set->ports[0]->flags,
hpriv->host_base, hpriv->port_base);
ata_host_set_resume(host_set);
return 0;
}
static int __init sil24_init(void) static int __init sil24_init(void)
{ {
return pci_module_init(&sil24_pci_driver); return pci_module_init(&sil24_pci_driver);
......
...@@ -297,7 +297,7 @@ static const struct ata_port_operations vsc_sata_ops = { ...@@ -297,7 +297,7 @@ static const struct ata_port_operations vsc_sata_ops = {
.bmdma_status = ata_bmdma_status, .bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep, .qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot, .qc_issue = ata_qc_issue_prot,
.data_xfer = ata_pio_data_xfer, .data_xfer = ata_mmio_data_xfer,
.freeze = ata_bmdma_freeze, .freeze = ata_bmdma_freeze,
.thaw = ata_bmdma_thaw, .thaw = ata_bmdma_thaw,
.error_handler = ata_bmdma_error_handler, .error_handler = ata_bmdma_error_handler,
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <asm/mach/serial_at91.h> #include <asm/mach/serial_at91.h>
#include <asm/arch/board.h> #include <asm/arch/board.h>
#include <asm/arch/system.h> #include <asm/arch/system.h>
#include <asm/arch/gpio.h>
#if defined(CONFIG_SERIAL_AT91_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) #if defined(CONFIG_SERIAL_AT91_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ #define SUPPORT_SYSRQ
...@@ -140,9 +141,9 @@ static void at91_set_mctrl(struct uart_port *port, u_int mctrl) ...@@ -140,9 +141,9 @@ static void at91_set_mctrl(struct uart_port *port, u_int mctrl)
*/ */
if (port->mapbase == AT91_BASE_US0) { if (port->mapbase == AT91_BASE_US0) {
if (mctrl & TIOCM_RTS) if (mctrl & TIOCM_RTS)
at91_sys_write(AT91_PIOA + PIO_CODR, AT91_PA21_RTS0); at91_set_gpio_value(AT91_PIN_PA21, 0);
else else
at91_sys_write(AT91_PIOA + PIO_SODR, AT91_PA21_RTS0); at91_set_gpio_value(AT91_PIN_PA21, 1);
} }
} }
......
...@@ -454,7 +454,7 @@ static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *ho ...@@ -454,7 +454,7 @@ static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *ho
fl->fl_ops = &nlmclnt_lock_ops; fl->fl_ops = &nlmclnt_lock_ops;
} }
static void do_vfs_lock(struct file_lock *fl) static int do_vfs_lock(struct file_lock *fl)
{ {
int res = 0; int res = 0;
switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) { switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) {
...@@ -467,9 +467,7 @@ static void do_vfs_lock(struct file_lock *fl) ...@@ -467,9 +467,7 @@ static void do_vfs_lock(struct file_lock *fl)
default: default:
BUG(); BUG();
} }
if (res < 0) return res;
printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n",
__FUNCTION__);
} }
/* /*
...@@ -498,6 +496,7 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl) ...@@ -498,6 +496,7 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
struct nlm_host *host = req->a_host; struct nlm_host *host = req->a_host;
struct nlm_res *resp = &req->a_res; struct nlm_res *resp = &req->a_res;
struct nlm_wait *block = NULL; struct nlm_wait *block = NULL;
unsigned char fl_flags = fl->fl_flags;
int status = -ENOLCK; int status = -ENOLCK;
if (!host->h_monitored && nsm_monitor(host) < 0) { if (!host->h_monitored && nsm_monitor(host) < 0) {
...@@ -505,6 +504,10 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl) ...@@ -505,6 +504,10 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
host->h_name); host->h_name);
goto out; goto out;
} }
fl->fl_flags |= FL_ACCESS;
status = do_vfs_lock(fl);
if (status < 0)
goto out;
block = nlmclnt_prepare_block(host, fl); block = nlmclnt_prepare_block(host, fl);
again: again:
...@@ -539,9 +542,10 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl) ...@@ -539,9 +542,10 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
up_read(&host->h_rwsem); up_read(&host->h_rwsem);
goto again; goto again;
} }
fl->fl_flags |= FL_SLEEP;
/* Ensure the resulting lock will get added to granted list */ /* Ensure the resulting lock will get added to granted list */
do_vfs_lock(fl); fl->fl_flags = fl_flags | FL_SLEEP;
if (do_vfs_lock(fl) < 0)
printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
up_read(&host->h_rwsem); up_read(&host->h_rwsem);
} }
status = nlm_stat_to_errno(resp->status); status = nlm_stat_to_errno(resp->status);
...@@ -552,6 +556,7 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl) ...@@ -552,6 +556,7 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
nlmclnt_cancel(host, req->a_args.block, fl); nlmclnt_cancel(host, req->a_args.block, fl);
out: out:
nlm_release_call(req); nlm_release_call(req);
fl->fl_flags = fl_flags;
return status; return status;
} }
...@@ -606,15 +611,19 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl) ...@@ -606,15 +611,19 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
{ {
struct nlm_host *host = req->a_host; struct nlm_host *host = req->a_host;
struct nlm_res *resp = &req->a_res; struct nlm_res *resp = &req->a_res;
int status; int status = 0;
/* /*
* Note: the server is supposed to either grant us the unlock * Note: the server is supposed to either grant us the unlock
* request, or to deny it with NLM_LCK_DENIED_GRACE_PERIOD. In either * request, or to deny it with NLM_LCK_DENIED_GRACE_PERIOD. In either
* case, we want to unlock. * case, we want to unlock.
*/ */
fl->fl_flags |= FL_EXISTS;
down_read(&host->h_rwsem); down_read(&host->h_rwsem);
do_vfs_lock(fl); if (do_vfs_lock(fl) == -ENOENT) {
up_read(&host->h_rwsem);
goto out;
}
up_read(&host->h_rwsem); up_read(&host->h_rwsem);
if (req->a_flags & RPC_TASK_ASYNC) if (req->a_flags & RPC_TASK_ASYNC)
...@@ -624,7 +633,6 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl) ...@@ -624,7 +633,6 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
if (status < 0) if (status < 0)
goto out; goto out;
status = 0;
if (resp->status == NLM_LCK_GRANTED) if (resp->status == NLM_LCK_GRANTED)
goto out; goto out;
......
...@@ -725,6 +725,10 @@ static int posix_locks_deadlock(struct file_lock *caller_fl, ...@@ -725,6 +725,10 @@ static int posix_locks_deadlock(struct file_lock *caller_fl,
/* Try to create a FLOCK lock on filp. We always insert new FLOCK locks /* Try to create a FLOCK lock on filp. We always insert new FLOCK locks
* at the head of the list, but that's secret knowledge known only to * at the head of the list, but that's secret knowledge known only to
* flock_lock_file and posix_lock_file. * flock_lock_file and posix_lock_file.
*
* Note that if called with an FL_EXISTS argument, the caller may determine
* whether or not a lock was successfully freed by testing the return
* value for -ENOENT.
*/ */
static int flock_lock_file(struct file *filp, struct file_lock *request) static int flock_lock_file(struct file *filp, struct file_lock *request)
{ {
...@@ -735,6 +739,8 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) ...@@ -735,6 +739,8 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
int found = 0; int found = 0;
lock_kernel(); lock_kernel();
if (request->fl_flags & FL_ACCESS)
goto find_conflict;
for_each_lock(inode, before) { for_each_lock(inode, before) {
struct file_lock *fl = *before; struct file_lock *fl = *before;
if (IS_POSIX(fl)) if (IS_POSIX(fl))
...@@ -750,8 +756,11 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) ...@@ -750,8 +756,11 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
break; break;
} }
if (request->fl_type == F_UNLCK) if (request->fl_type == F_UNLCK) {
if ((request->fl_flags & FL_EXISTS) && !found)
error = -ENOENT;
goto out; goto out;
}
error = -ENOMEM; error = -ENOMEM;
new_fl = locks_alloc_lock(); new_fl = locks_alloc_lock();
...@@ -764,6 +773,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) ...@@ -764,6 +773,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
if (found) if (found)
cond_resched(); cond_resched();
find_conflict:
for_each_lock(inode, before) { for_each_lock(inode, before) {
struct file_lock *fl = *before; struct file_lock *fl = *before;
if (IS_POSIX(fl)) if (IS_POSIX(fl))
...@@ -777,6 +787,8 @@ static int flock_lock_file(struct file *filp, struct file_lock *request) ...@@ -777,6 +787,8 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
locks_insert_block(fl, request); locks_insert_block(fl, request);
goto out; goto out;
} }
if (request->fl_flags & FL_ACCESS)
goto out;
locks_copy_lock(new_fl, request); locks_copy_lock(new_fl, request);
locks_insert_lock(&inode->i_flock, new_fl); locks_insert_lock(&inode->i_flock, new_fl);
new_fl = NULL; new_fl = NULL;
...@@ -948,8 +960,11 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request ...@@ -948,8 +960,11 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
error = 0; error = 0;
if (!added) { if (!added) {
if (request->fl_type == F_UNLCK) if (request->fl_type == F_UNLCK) {
if (request->fl_flags & FL_EXISTS)
error = -ENOENT;
goto out; goto out;
}
if (!new_fl) { if (!new_fl) {
error = -ENOLCK; error = -ENOLCK;
...@@ -996,6 +1011,10 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request ...@@ -996,6 +1011,10 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
* Add a POSIX style lock to a file. * Add a POSIX style lock to a file.
* We merge adjacent & overlapping locks whenever possible. * We merge adjacent & overlapping locks whenever possible.
* POSIX locks are sorted by owner task, then by starting address * POSIX locks are sorted by owner task, then by starting address
*
* Note that if called with an FL_EXISTS argument, the caller may determine
* whether or not a lock was successfully freed by testing the return
* value for -ENOENT.
*/ */
int posix_lock_file(struct file *filp, struct file_lock *fl) int posix_lock_file(struct file *filp, struct file_lock *fl)
{ {
......
...@@ -690,7 +690,9 @@ int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd) ...@@ -690,7 +690,9 @@ int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
goto out_force; goto out_force;
/* This is an open(2) */ /* This is an open(2) */
if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 && if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 &&
!(server->flags & NFS_MOUNT_NOCTO)) !(server->flags & NFS_MOUNT_NOCTO) &&
(S_ISREG(inode->i_mode) ||
S_ISDIR(inode->i_mode)))
goto out_force; goto out_force;
} }
return nfs_revalidate_inode(server, inode); return nfs_revalidate_inode(server, inode);
......
This diff is collapsed.
...@@ -3144,9 +3144,6 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl) ...@@ -3144,9 +3144,6 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl)
default: default:
BUG(); BUG();
} }
if (res < 0)
printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n",
__FUNCTION__);
return res; return res;
} }
...@@ -3258,8 +3255,6 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl, ...@@ -3258,8 +3255,6 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
/* Unlock _before_ we do the RPC call */
do_vfs_lock(fl->fl_file, fl);
return rpc_run_task(NFS_CLIENT(lsp->ls_state->inode), RPC_TASK_ASYNC, &nfs4_locku_ops, data); return rpc_run_task(NFS_CLIENT(lsp->ls_state->inode), RPC_TASK_ASYNC, &nfs4_locku_ops, data);
} }
...@@ -3270,30 +3265,28 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock * ...@@ -3270,30 +3265,28 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
struct rpc_task *task; struct rpc_task *task;
int status = 0; int status = 0;
/* Is this a delegated lock? */
if (test_bit(NFS_DELEGATED_STATE, &state->flags))
goto out_unlock;
/* Is this open_owner holding any locks on the server? */
if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
goto out_unlock;
status = nfs4_set_lock_state(state, request); status = nfs4_set_lock_state(state, request);
/* Unlock _before_ we do the RPC call */
request->fl_flags |= FL_EXISTS;
if (do_vfs_lock(request->fl_file, request) == -ENOENT)
goto out;
if (status != 0) if (status != 0)
goto out_unlock; goto out;
/* Is this a delegated lock? */
if (test_bit(NFS_DELEGATED_STATE, &state->flags))
goto out;
lsp = request->fl_u.nfs4_fl.owner; lsp = request->fl_u.nfs4_fl.owner;
status = -ENOMEM;
seqid = nfs_alloc_seqid(&lsp->ls_seqid); seqid = nfs_alloc_seqid(&lsp->ls_seqid);
status = -ENOMEM;
if (seqid == NULL) if (seqid == NULL)
goto out_unlock; goto out;
task = nfs4_do_unlck(request, request->fl_file->private_data, lsp, seqid); task = nfs4_do_unlck(request, request->fl_file->private_data, lsp, seqid);
status = PTR_ERR(task); status = PTR_ERR(task);
if (IS_ERR(task)) if (IS_ERR(task))
goto out_unlock; goto out;
status = nfs4_wait_for_completion_rpc_task(task); status = nfs4_wait_for_completion_rpc_task(task);
rpc_release_task(task); rpc_release_task(task);
return status; out:
out_unlock:
do_vfs_lock(request->fl_file, request);
return status; return status;
} }
...@@ -3461,10 +3454,10 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request ...@@ -3461,10 +3454,10 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
struct nfs4_exception exception = { }; struct nfs4_exception exception = { };
int err; int err;
/* Cache the lock if possible... */
if (test_bit(NFS_DELEGATED_STATE, &state->flags))
return 0;
do { do {
/* Cache the lock if possible... */
if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
return 0;
err = _nfs4_do_setlk(state, F_SETLK, request, 1); err = _nfs4_do_setlk(state, F_SETLK, request, 1);
if (err != -NFS4ERR_DELAY) if (err != -NFS4ERR_DELAY)
break; break;
...@@ -3483,6 +3476,8 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request ...@@ -3483,6 +3476,8 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
if (err != 0) if (err != 0)
return err; return err;
do { do {
if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
return 0;
err = _nfs4_do_setlk(state, F_SETLK, request, 0); err = _nfs4_do_setlk(state, F_SETLK, request, 0);
if (err != -NFS4ERR_DELAY) if (err != -NFS4ERR_DELAY)
break; break;
...@@ -3494,29 +3489,42 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request ...@@ -3494,29 +3489,42 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
{ {
struct nfs4_client *clp = state->owner->so_client; struct nfs4_client *clp = state->owner->so_client;
unsigned char fl_flags = request->fl_flags;
int status; int status;
/* Is this a delegated open? */ /* Is this a delegated open? */
if (NFS_I(state->inode)->delegation_state != 0) {
/* Yes: cache locks! */
status = do_vfs_lock(request->fl_file, request);
/* ...but avoid races with delegation recall... */
if (status < 0 || test_bit(NFS_DELEGATED_STATE, &state->flags))
return status;
}
down_read(&clp->cl_sem);
status = nfs4_set_lock_state(state, request); status = nfs4_set_lock_state(state, request);
if (status != 0) if (status != 0)
goto out; goto out;
request->fl_flags |= FL_ACCESS;
status = do_vfs_lock(request->fl_file, request);
if (status < 0)
goto out;
down_read(&clp->cl_sem);
if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
struct nfs_inode *nfsi = NFS_I(state->inode);
/* Yes: cache locks! */
down_read(&nfsi->rwsem);
/* ...but avoid races with delegation recall... */
if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
request->fl_flags = fl_flags & ~FL_SLEEP;
status = do_vfs_lock(request->fl_file, request);
up_read(&nfsi->rwsem);
goto out_unlock;
}
up_read(&nfsi->rwsem);
}
status = _nfs4_do_setlk(state, cmd, request, 0); status = _nfs4_do_setlk(state, cmd, request, 0);
if (status != 0) if (status != 0)
goto out; goto out_unlock;
/* Note: we always want to sleep here! */ /* Note: we always want to sleep here! */
request->fl_flags |= FL_SLEEP; request->fl_flags = fl_flags | FL_SLEEP;
if (do_vfs_lock(request->fl_file, request) < 0) if (do_vfs_lock(request->fl_file, request) < 0)
printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__); printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
out: out_unlock:
up_read(&clp->cl_sem); up_read(&clp->cl_sem);
out:
request->fl_flags = fl_flags;
return status; return status;
} }
......
...@@ -578,7 +578,7 @@ static int nfs_wait_on_requests(struct inode *inode, unsigned long idx_start, un ...@@ -578,7 +578,7 @@ static int nfs_wait_on_requests(struct inode *inode, unsigned long idx_start, un
return ret; return ret;
} }
static void nfs_cancel_requests(struct list_head *head) static void nfs_cancel_dirty_list(struct list_head *head)
{ {
struct nfs_page *req; struct nfs_page *req;
while(!list_empty(head)) { while(!list_empty(head)) {
...@@ -589,6 +589,19 @@ static void nfs_cancel_requests(struct list_head *head) ...@@ -589,6 +589,19 @@ static void nfs_cancel_requests(struct list_head *head)
} }
} }
static void nfs_cancel_commit_list(struct list_head *head)
{
struct nfs_page *req;
while(!list_empty(head)) {
req = nfs_list_entry(head->next);
nfs_list_remove_request(req);
nfs_inode_remove_request(req);
nfs_clear_page_writeback(req);
dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
}
}
/* /*
* nfs_scan_dirty - Scan an inode for dirty requests * nfs_scan_dirty - Scan an inode for dirty requests
* @inode: NFS inode to scan * @inode: NFS inode to scan
...@@ -1381,6 +1394,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how) ...@@ -1381,6 +1394,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
nfs_list_remove_request(req); nfs_list_remove_request(req);
nfs_mark_request_commit(req); nfs_mark_request_commit(req);
nfs_clear_page_writeback(req); nfs_clear_page_writeback(req);
dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
} }
return -ENOMEM; return -ENOMEM;
} }
...@@ -1499,7 +1513,7 @@ int nfs_sync_inode_wait(struct inode *inode, unsigned long idx_start, ...@@ -1499,7 +1513,7 @@ int nfs_sync_inode_wait(struct inode *inode, unsigned long idx_start,
if (pages != 0) { if (pages != 0) {
spin_unlock(&nfsi->req_lock); spin_unlock(&nfsi->req_lock);
if (how & FLUSH_INVALIDATE) if (how & FLUSH_INVALIDATE)
nfs_cancel_requests(&head); nfs_cancel_dirty_list(&head);
else else
ret = nfs_flush_list(inode, &head, pages, how); ret = nfs_flush_list(inode, &head, pages, how);
spin_lock(&nfsi->req_lock); spin_lock(&nfsi->req_lock);
...@@ -1512,7 +1526,7 @@ int nfs_sync_inode_wait(struct inode *inode, unsigned long idx_start, ...@@ -1512,7 +1526,7 @@ int nfs_sync_inode_wait(struct inode *inode, unsigned long idx_start,
break; break;
if (how & FLUSH_INVALIDATE) { if (how & FLUSH_INVALIDATE) {
spin_unlock(&nfsi->req_lock); spin_unlock(&nfsi->req_lock);
nfs_cancel_requests(&head); nfs_cancel_commit_list(&head);
spin_lock(&nfsi->req_lock); spin_lock(&nfsi->req_lock);
continue; continue;
} }
......
...@@ -39,12 +39,4 @@ ...@@ -39,12 +39,4 @@
*/ */
#define NR_IRQS (NR_AIC_IRQS + (4 * 32)) #define NR_IRQS (NR_AIC_IRQS + (4 * 32))
#ifndef __ASSEMBLY__
/*
* Initialize the IRQ controller.
*/
extern void at91rm9200_init_irq(unsigned int priority[]);
#endif
#endif #endif
...@@ -43,6 +43,7 @@ typedef u64 cputime64_t; ...@@ -43,6 +43,7 @@ typedef u64 cputime64_t;
#define cputime64_zero ((cputime64_t)0) #define cputime64_zero ((cputime64_t)0)
#define cputime64_add(__a, __b) ((__a) + (__b)) #define cputime64_add(__a, __b) ((__a) + (__b))
#define cputime64_sub(__a, __b) ((__a) - (__b))
#define cputime_to_cputime64(__ct) (__ct) #define cputime_to_cputime64(__ct) (__ct)
#ifdef __KERNEL__ #ifdef __KERNEL__
...@@ -74,6 +75,23 @@ static inline cputime_t jiffies_to_cputime(const unsigned long jif) ...@@ -74,6 +75,23 @@ static inline cputime_t jiffies_to_cputime(const unsigned long jif)
return ct; return ct;
} }
static inline cputime64_t jiffies64_to_cputime64(const u64 jif)
{
cputime_t ct;
u64 sec;
/* have to be a little careful about overflow */
ct = jif % HZ;
sec = jif / HZ;
if (ct) {
ct *= tb_ticks_per_sec;
do_div(ct, HZ);
}
if (sec)
ct += (cputime_t) sec * tb_ticks_per_sec;
return ct;
}
static inline u64 cputime64_to_jiffies64(const cputime_t ct) static inline u64 cputime64_to_jiffies64(const cputime_t ct)
{ {
return mulhdu(ct, __cputime_jiffies_factor); return mulhdu(ct, __cputime_jiffies_factor);
......
...@@ -160,6 +160,20 @@ static inline void dma_free_coherent(struct device *dev, size_t size, ...@@ -160,6 +160,20 @@ static inline void dma_free_coherent(struct device *dev, size_t size,
BUG(); BUG();
} }
static inline void
dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
{
BUG();
}
static inline void
dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
{
BUG();
}
#endif /* PCI */ #endif /* PCI */
......
...@@ -716,6 +716,7 @@ extern spinlock_t files_lock; ...@@ -716,6 +716,7 @@ extern spinlock_t files_lock;
#define FL_POSIX 1 #define FL_POSIX 1
#define FL_FLOCK 2 #define FL_FLOCK 2
#define FL_ACCESS 8 /* not trying to lock, just looking */ #define FL_ACCESS 8 /* not trying to lock, just looking */
#define FL_EXISTS 16 /* when unlocking, test for existence */
#define FL_LEASE 32 /* lease held on this file */ #define FL_LEASE 32 /* lease held on this file */
#define FL_CLOSE 64 /* unlock on close */ #define FL_CLOSE 64 /* unlock on close */
#define FL_SLEEP 128 /* A blocking lock */ #define FL_SLEEP 128 /* A blocking lock */
......
...@@ -131,6 +131,7 @@ enum { ...@@ -131,6 +131,7 @@ enum {
ATA_DFLAG_CFG_MASK = (1 << 8) - 1, ATA_DFLAG_CFG_MASK = (1 << 8) - 1,
ATA_DFLAG_PIO = (1 << 8), /* device currently in PIO mode */ ATA_DFLAG_PIO = (1 << 8), /* device currently in PIO mode */
ATA_DFLAG_SUSPENDED = (1 << 9), /* device suspended */
ATA_DFLAG_INIT_MASK = (1 << 16) - 1, ATA_DFLAG_INIT_MASK = (1 << 16) - 1,
ATA_DFLAG_DETACH = (1 << 16), ATA_DFLAG_DETACH = (1 << 16),
...@@ -160,22 +161,28 @@ enum { ...@@ -160,22 +161,28 @@ enum {
ATA_FLAG_HRST_TO_RESUME = (1 << 11), /* hardreset to resume phy */ ATA_FLAG_HRST_TO_RESUME = (1 << 11), /* hardreset to resume phy */
ATA_FLAG_SKIP_D2H_BSY = (1 << 12), /* can't wait for the first D2H ATA_FLAG_SKIP_D2H_BSY = (1 << 12), /* can't wait for the first D2H
* Register FIS clearing BSY */ * Register FIS clearing BSY */
ATA_FLAG_DEBUGMSG = (1 << 13), ATA_FLAG_DEBUGMSG = (1 << 13),
ATA_FLAG_FLUSH_PORT_TASK = (1 << 14), /* flush port task */
ATA_FLAG_EH_PENDING = (1 << 15), /* EH pending */ /* The following flag belongs to ap->pflags but is kept in
ATA_FLAG_EH_IN_PROGRESS = (1 << 16), /* EH in progress */ * ap->flags because it's referenced in many LLDs and will be
ATA_FLAG_FROZEN = (1 << 17), /* port is frozen */ * removed in not-too-distant future.
ATA_FLAG_RECOVERED = (1 << 18), /* recovery action performed */ */
ATA_FLAG_LOADING = (1 << 19), /* boot/loading probe */ ATA_FLAG_DISABLED = (1 << 23), /* port is disabled, ignore it */
ATA_FLAG_UNLOADING = (1 << 20), /* module is unloading */
ATA_FLAG_SCSI_HOTPLUG = (1 << 21), /* SCSI hotplug scheduled */ /* bits 24:31 of ap->flags are reserved for LLD specific flags */
ATA_FLAG_DISABLED = (1 << 22), /* port is disabled, ignore it */ /* struct ata_port pflags */
ATA_FLAG_SUSPENDED = (1 << 23), /* port is suspended (power) */ ATA_PFLAG_EH_PENDING = (1 << 0), /* EH pending */
ATA_PFLAG_EH_IN_PROGRESS = (1 << 1), /* EH in progress */
ATA_PFLAG_FROZEN = (1 << 2), /* port is frozen */
ATA_PFLAG_RECOVERED = (1 << 3), /* recovery action performed */
ATA_PFLAG_LOADING = (1 << 4), /* boot/loading probe */
ATA_PFLAG_UNLOADING = (1 << 5), /* module is unloading */
ATA_PFLAG_SCSI_HOTPLUG = (1 << 6), /* SCSI hotplug scheduled */
/* bits 24:31 of ap->flags are reserved for LLDD specific flags */ ATA_PFLAG_FLUSH_PORT_TASK = (1 << 16), /* flush port task */
ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */
ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */
/* struct ata_queued_cmd flags */ /* struct ata_queued_cmd flags */
ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */
...@@ -248,12 +255,19 @@ enum { ...@@ -248,12 +255,19 @@ enum {
ATA_EH_REVALIDATE = (1 << 0), ATA_EH_REVALIDATE = (1 << 0),
ATA_EH_SOFTRESET = (1 << 1), ATA_EH_SOFTRESET = (1 << 1),
ATA_EH_HARDRESET = (1 << 2), ATA_EH_HARDRESET = (1 << 2),
ATA_EH_SUSPEND = (1 << 3),
ATA_EH_RESUME = (1 << 4),
ATA_EH_PM_FREEZE = (1 << 5),
ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE, ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_SUSPEND |
ATA_EH_RESUME | ATA_EH_PM_FREEZE,
/* ata_eh_info->flags */ /* ata_eh_info->flags */
ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */
ATA_EHI_RESUME_LINK = (1 << 1), /* need to resume link */
ATA_EHI_NO_AUTOPSY = (1 << 2), /* no autopsy */
ATA_EHI_QUIET = (1 << 3), /* be quiet */
ATA_EHI_DID_RESET = (1 << 16), /* already reset this port */ ATA_EHI_DID_RESET = (1 << 16), /* already reset this port */
...@@ -486,6 +500,7 @@ struct ata_port { ...@@ -486,6 +500,7 @@ struct ata_port {
const struct ata_port_operations *ops; const struct ata_port_operations *ops;
spinlock_t *lock; spinlock_t *lock;
unsigned long flags; /* ATA_FLAG_xxx */ unsigned long flags; /* ATA_FLAG_xxx */
unsigned int pflags; /* ATA_PFLAG_xxx */
unsigned int id; /* unique id req'd by scsi midlyr */ unsigned int id; /* unique id req'd by scsi midlyr */
unsigned int port_no; /* unique port #; from zero */ unsigned int port_no; /* unique port #; from zero */
unsigned int hard_port_no; /* hardware port #; from zero */ unsigned int hard_port_no; /* hardware port #; from zero */
...@@ -535,6 +550,9 @@ struct ata_port { ...@@ -535,6 +550,9 @@ struct ata_port {
struct list_head eh_done_q; struct list_head eh_done_q;
wait_queue_head_t eh_wait_q; wait_queue_head_t eh_wait_q;
pm_message_t pm_mesg;
int *pm_result;
void *private_data; void *private_data;
u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */ u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */
...@@ -589,6 +607,9 @@ struct ata_port_operations { ...@@ -589,6 +607,9 @@ struct ata_port_operations {
void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
u32 val); u32 val);
int (*port_suspend) (struct ata_port *ap, pm_message_t mesg);
int (*port_resume) (struct ata_port *ap);
int (*port_start) (struct ata_port *ap); int (*port_start) (struct ata_port *ap);
void (*port_stop) (struct ata_port *ap); void (*port_stop) (struct ata_port *ap);
...@@ -622,9 +643,18 @@ struct ata_timing { ...@@ -622,9 +643,18 @@ struct ata_timing {
#define FIT(v,vmin,vmax) max_t(short,min_t(short,v,vmax),vmin) #define FIT(v,vmin,vmax) max_t(short,min_t(short,v,vmax),vmin)
extern const unsigned long sata_deb_timing_boot[]; extern const unsigned long sata_deb_timing_normal[];
extern const unsigned long sata_deb_timing_eh[]; extern const unsigned long sata_deb_timing_hotplug[];
extern const unsigned long sata_deb_timing_before_fsrst[]; extern const unsigned long sata_deb_timing_long[];
static inline const unsigned long *
sata_ehc_deb_timing(struct ata_eh_context *ehc)
{
if (ehc->i.flags & ATA_EHI_HOTPLUGGED)
return sata_deb_timing_hotplug;
else
return sata_deb_timing_normal;
}
extern void ata_port_probe(struct ata_port *); extern void ata_port_probe(struct ata_port *);
extern void __sata_phy_reset(struct ata_port *ap); extern void __sata_phy_reset(struct ata_port *ap);
...@@ -644,6 +674,8 @@ extern void ata_std_ports(struct ata_ioports *ioaddr); ...@@ -644,6 +674,8 @@ extern void ata_std_ports(struct ata_ioports *ioaddr);
extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
unsigned int n_ports); unsigned int n_ports);
extern void ata_pci_remove_one (struct pci_dev *pdev); extern void ata_pci_remove_one (struct pci_dev *pdev);
extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t state);
extern void ata_pci_device_do_resume(struct pci_dev *pdev);
extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state); extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state);
extern int ata_pci_device_resume(struct pci_dev *pdev); extern int ata_pci_device_resume(struct pci_dev *pdev);
extern int ata_pci_clear_simplex(struct pci_dev *pdev); extern int ata_pci_clear_simplex(struct pci_dev *pdev);
...@@ -664,8 +696,9 @@ extern int ata_port_online(struct ata_port *ap); ...@@ -664,8 +696,9 @@ extern int ata_port_online(struct ata_port *ap);
extern int ata_port_offline(struct ata_port *ap); extern int ata_port_offline(struct ata_port *ap);
extern int ata_scsi_device_resume(struct scsi_device *); extern int ata_scsi_device_resume(struct scsi_device *);
extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t state); extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t state);
extern int ata_device_resume(struct ata_device *); extern int ata_host_set_suspend(struct ata_host_set *host_set,
extern int ata_device_suspend(struct ata_device *, pm_message_t state); pm_message_t mesg);
extern void ata_host_set_resume(struct ata_host_set *host_set);
extern int ata_ratelimit(void); extern int ata_ratelimit(void);
extern unsigned int ata_busy_sleep(struct ata_port *ap, extern unsigned int ata_busy_sleep(struct ata_port *ap,
unsigned long timeout_pat, unsigned long timeout_pat,
...@@ -825,19 +858,24 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ...@@ -825,19 +858,24 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
(ehi)->desc_len = 0; \ (ehi)->desc_len = 0; \
} while (0) } while (0)
static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi) static inline void __ata_ehi_hotplugged(struct ata_eh_info *ehi)
{ {
if (ehi->flags & ATA_EHI_HOTPLUGGED) if (ehi->flags & ATA_EHI_HOTPLUGGED)
return; return;
ehi->flags |= ATA_EHI_HOTPLUGGED; ehi->flags |= ATA_EHI_HOTPLUGGED | ATA_EHI_RESUME_LINK;
ehi->hotplug_timestamp = jiffies; ehi->hotplug_timestamp = jiffies;
ehi->err_mask |= AC_ERR_ATA_BUS;
ehi->action |= ATA_EH_SOFTRESET; ehi->action |= ATA_EH_SOFTRESET;
ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1; ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1;
} }
static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi)
{
__ata_ehi_hotplugged(ehi);
ehi->err_mask |= AC_ERR_ATA_BUS;
}
/* /*
* qc helpers * qc helpers
*/ */
...@@ -921,6 +959,11 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev) ...@@ -921,6 +959,11 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev)
return ata_class_absent(dev->class); return ata_class_absent(dev->class);
} }
static inline unsigned int ata_dev_ready(const struct ata_device *dev)
{
return ata_dev_enabled(dev) && !(dev->flags & ATA_DFLAG_SUSPENDED);
}
/* /*
* port helpers * port helpers
*/ */
......
...@@ -729,6 +729,7 @@ struct nfs_read_data { ...@@ -729,6 +729,7 @@ struct nfs_read_data {
struct list_head pages; /* Coalesced read requests */ struct list_head pages; /* Coalesced read requests */
struct nfs_page *req; /* multi ops per nfs_page */ struct nfs_page *req; /* multi ops per nfs_page */
struct page **pagevec; struct page **pagevec;
unsigned int npages; /* active pages in pagevec */
struct nfs_readargs args; struct nfs_readargs args;
struct nfs_readres res; struct nfs_readres res;
#ifdef CONFIG_NFS_V4 #ifdef CONFIG_NFS_V4
...@@ -747,6 +748,7 @@ struct nfs_write_data { ...@@ -747,6 +748,7 @@ struct nfs_write_data {
struct list_head pages; /* Coalesced requests we wish to flush */ struct list_head pages; /* Coalesced requests we wish to flush */
struct nfs_page *req; /* multi ops per nfs_page */ struct nfs_page *req; /* multi ops per nfs_page */
struct page **pagevec; struct page **pagevec;
unsigned int npages; /* active pages in pagevec */
struct nfs_writeargs args; /* argument struct */ struct nfs_writeargs args; /* argument struct */
struct nfs_writeres res; /* result struct */ struct nfs_writeres res; /* result struct */
#ifdef CONFIG_NFS_V4 #ifdef CONFIG_NFS_V4
......
...@@ -2019,6 +2019,13 @@ ...@@ -2019,6 +2019,13 @@
#define PCI_VENDOR_ID_TDI 0x192E #define PCI_VENDOR_ID_TDI 0x192E
#define PCI_DEVICE_ID_TDI_EHCI 0x0101 #define PCI_DEVICE_ID_TDI_EHCI 0x0101
#define PCI_VENDOR_ID_JMICRON 0x197B
#define PCI_DEVICE_ID_JMICRON_JMB360 0x2360
#define PCI_DEVICE_ID_JMICRON_JMB361 0x2361
#define PCI_DEVICE_ID_JMICRON_JMB363 0x2363
#define PCI_DEVICE_ID_JMICRON_JMB365 0x2365
#define PCI_DEVICE_ID_JMICRON_JMB366 0x2366
#define PCI_DEVICE_ID_JMICRON_JMB368 0x2368
#define PCI_VENDOR_ID_TEKRAM 0x1de1 #define PCI_VENDOR_ID_TEKRAM 0x1de1
#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
......
...@@ -250,15 +250,17 @@ tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref) ...@@ -250,15 +250,17 @@ tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int ref)
RTA_PUT(skb, a->order, 0, NULL); RTA_PUT(skb, a->order, 0, NULL);
err = tcf_action_dump_1(skb, a, bind, ref); err = tcf_action_dump_1(skb, a, bind, ref);
if (err < 0) if (err < 0)
goto rtattr_failure; goto errout;
r->rta_len = skb->tail - (u8*)r; r->rta_len = skb->tail - (u8*)r;
} }
return 0; return 0;
rtattr_failure: rtattr_failure:
err = -EINVAL;
errout:
skb_trim(skb, b - skb->data); skb_trim(skb, b - skb->data);
return -err; return err;
} }
struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est,
...@@ -305,6 +307,7 @@ struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, ...@@ -305,6 +307,7 @@ struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est,
goto err_mod; goto err_mod;
} }
#endif #endif
*err = -ENOENT;
goto err_out; goto err_out;
} }
...@@ -776,7 +779,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) ...@@ -776,7 +779,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
return ret; return ret;
} }
static char * static struct rtattr *
find_dump_kind(struct nlmsghdr *n) find_dump_kind(struct nlmsghdr *n)
{ {
struct rtattr *tb1, *tb2[TCA_ACT_MAX+1]; struct rtattr *tb1, *tb2[TCA_ACT_MAX+1];
...@@ -804,7 +807,7 @@ find_dump_kind(struct nlmsghdr *n) ...@@ -804,7 +807,7 @@ find_dump_kind(struct nlmsghdr *n)
return NULL; return NULL;
kind = tb2[TCA_ACT_KIND-1]; kind = tb2[TCA_ACT_KIND-1];
return (char *) RTA_DATA(kind); return kind;
} }
static int static int
...@@ -817,16 +820,15 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -817,16 +820,15 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
struct tc_action a; struct tc_action a;
int ret = 0; int ret = 0;
struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh); struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
char *kind = find_dump_kind(cb->nlh); struct rtattr *kind = find_dump_kind(cb->nlh);
if (kind == NULL) { if (kind == NULL) {
printk("tc_dump_action: action bad kind\n"); printk("tc_dump_action: action bad kind\n");
return 0; return 0;
} }
a_o = tc_lookup_action_n(kind); a_o = tc_lookup_action(kind);
if (a_o == NULL) { if (a_o == NULL) {
printk("failed to find %s\n", kind);
return 0; return 0;
} }
...@@ -834,7 +836,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -834,7 +836,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
a.ops = a_o; a.ops = a_o;
if (a_o->walk == NULL) { if (a_o->walk == NULL) {
printk("tc_dump_action: %s !capable of dumping table\n", kind); printk("tc_dump_action: %s !capable of dumping table\n", a_o->kind);
goto rtattr_failure; goto rtattr_failure;
} }
......
...@@ -191,7 +191,6 @@ _shift_data_right_pages(struct page **pages, size_t pgto_base, ...@@ -191,7 +191,6 @@ _shift_data_right_pages(struct page **pages, size_t pgto_base,
do { do {
/* Are any pointers crossing a page boundary? */ /* Are any pointers crossing a page boundary? */
if (pgto_base == 0) { if (pgto_base == 0) {
flush_dcache_page(*pgto);
pgto_base = PAGE_CACHE_SIZE; pgto_base = PAGE_CACHE_SIZE;
pgto--; pgto--;
} }
...@@ -211,11 +210,11 @@ _shift_data_right_pages(struct page **pages, size_t pgto_base, ...@@ -211,11 +210,11 @@ _shift_data_right_pages(struct page **pages, size_t pgto_base,
vto = kmap_atomic(*pgto, KM_USER0); vto = kmap_atomic(*pgto, KM_USER0);
vfrom = kmap_atomic(*pgfrom, KM_USER1); vfrom = kmap_atomic(*pgfrom, KM_USER1);
memmove(vto + pgto_base, vfrom + pgfrom_base, copy); memmove(vto + pgto_base, vfrom + pgfrom_base, copy);
flush_dcache_page(*pgto);
kunmap_atomic(vfrom, KM_USER1); kunmap_atomic(vfrom, KM_USER1);
kunmap_atomic(vto, KM_USER0); kunmap_atomic(vto, KM_USER0);
} while ((len -= copy) != 0); } while ((len -= copy) != 0);
flush_dcache_page(*pgto);
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment