diff options
155 files changed, 1633 insertions, 2257 deletions
diff --git a/Documentation/arm/Samsung-S3C24XX/Suspend.txt b/Documentation/arm/Samsung-S3C24XX/Suspend.txt index e12bc3284a2..0dab6e32c13 100644 --- a/Documentation/arm/Samsung-S3C24XX/Suspend.txt +++ b/Documentation/arm/Samsung-S3C24XX/Suspend.txt @@ -5,10 +5,10 @@ Introduction ------------ - The S3C2410 supports a low-power suspend mode, where the SDRAM is kept + The S3C24XX supports a low-power suspend mode, where the SDRAM is kept in Self-Refresh mode, and all but the essential peripheral blocks are powered down. For more information on how this works, please look - at the S3C2410 datasheets from Samsung. + at the relevant CPU datasheet from Samsung. Requirements @@ -56,6 +56,27 @@ Machine Support Note, the original method of adding an late_initcall() is wrong, and will end up initialising all compiled machines' pm init! + The following is an example of code used for testing wakeup from + an falling edge on IRQ_EINT0: + + +static irqreturn_t button_irq(int irq, void *pw) +{ + return IRQ_HANDLED; +} + +statuc void __init machine_init(void) +{ + ... + + request_irq(IRQ_EINT0, button_irq, IRQF_TRIGGER_FALLING, + "button-irq-eint0", NULL); + + enable_irq_wake(IRQ_EINT0); + + s3c2410_pm_init(); +} + Debugging --------- @@ -70,6 +91,12 @@ Debugging care should be taken that any external clock sources that the UARTs rely on are still enabled at that point. + 3) If any debugging is placed in the resume path, then it must have the + relevant clocks and peripherals setup before use (ie, bootloader). + + For example, if you transmit a character from the UART, the baud + rate and uart controls must be setup beforehand. + Configuration ------------- @@ -89,6 +116,10 @@ Configuration Allows the entire memory to be checksummed before and after the suspend to see if there has been any corruption of the contents. + Note, the time to calculate the CRC is dependant on the CPU speed + and the size of memory. For an 64Mbyte RAM area on an 200MHz + S3C2410, this can take approximately 4 seconds to complete. + This support requires the CRC32 function to be enabled. diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d75879d9dde..ac2ffdcfbbb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -190,6 +190,7 @@ config ARCH_CO285 config ARCH_EBSA110 bool "EBSA-110" select ISA + select NO_IOPORT help This is an evaluation board for the StrongARM processor available from Digital. It has limited hardware on-board, including an diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index cbe909bad79..70014f751bc 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -16,6 +16,8 @@ #include <linux/spi/spi.h> #include <linux/spi/ads7846.h> +#include <linux/workqueue.h> +#include <linux/delay.h> #include <asm/hardware.h> #include <asm/mach-types.h> @@ -103,7 +105,7 @@ static struct ads7846_platform_data nokia770_ads7846_platform_data __initdata = static struct spi_board_info nokia770_spi_board_info[] __initdata = { [0] = { - .modalias = "lcd_lph8923", + .modalias = "lcd_mipid", .bus_num = 2, .chip_select = 3, .max_speed_hz = 12000000, diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 638490e62d5..f625f6dd228 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -432,8 +432,7 @@ static int omap1_clk_enable(struct clk *clk) } if (clk->flags & CLOCK_NO_IDLE_PARENT) - if (!cpu_is_omap24xx()) - omap1_clk_deny_idle(clk->parent); + omap1_clk_deny_idle(clk->parent); } ret = clk->enable(clk); @@ -454,8 +453,7 @@ static void omap1_clk_disable(struct clk *clk) if (likely(clk->parent)) { omap1_clk_disable(clk->parent); if (clk->flags & CLOCK_NO_IDLE_PARENT) - if (!cpu_is_omap24xx()) - omap1_clk_allow_idle(clk->parent); + omap1_clk_allow_idle(clk->parent); } } } @@ -471,7 +469,7 @@ static int omap1_clk_enable_generic(struct clk *clk) if (unlikely(clk->enable_reg == 0)) { printk(KERN_ERR "clock.c: Enable for %s without enable code\n", clk->name); - return 0; + return -EINVAL; } if (clk->flags & ENABLE_REG_32BIT) { @@ -651,10 +649,18 @@ int __init omap1_clk_init(void) int crystal_type = 0; /* Default 12 MHz */ u32 reg; +#ifdef CONFIG_DEBUG_LL + /* Resets some clocks that may be left on from bootloader, + * but leaves serial clocks on. + */ + omap_writel(0x3 << 29, MOD_CONF_CTRL_0); +#endif + /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ reg = omap_readw(SOFT_REQ_REG) & (1 << 4); omap_writew(reg, SOFT_REQ_REG); - omap_writew(0, SOFT_REQ_REG2); + if (!cpu_is_omap15xx()) + omap_writew(0, SOFT_REQ_REG2); clk_init(&omap1_clk_functions); @@ -685,7 +691,7 @@ int __init omap1_clk_init(void) info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); if (info != NULL) { - if (!cpu_is_omap1510()) + if (!cpu_is_omap15xx()) crystal_type = info->system_clock_type; } diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index 6383a12ad97..410d3e78dd0 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c @@ -238,7 +238,7 @@ void __init omap_init_irq(void) if (cpu_is_omap730()) omap_unmask_irq(INT_730_IH2_IRQ); - else if (cpu_is_omap1510()) + else if (cpu_is_omap15xx()) omap_unmask_irq(INT_1510_IH2_IRQ); else if (cpu_is_omap16xx()) omap_unmask_irq(INT_1610_IH2_IRQ); diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index 4834758d340..49efe903dac 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -256,7 +256,8 @@ void omap_pm_suspend(void) tps65010_set_led(LED1, OFF); } - omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG); + if (!cpu_is_omap15xx()) + omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG); /* * Step 1: turn off interrupts (FIXME: NOTE: already disabled) @@ -434,7 +435,8 @@ void omap_pm_suspend(void) MPUI1610_RESTORE(OMAP_IH2_3_MIR); } - omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG); + if (!cpu_is_omap15xx()) + omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG); /* * Reenable interrupts @@ -704,6 +706,8 @@ static struct pm_ops omap_pm_ops ={ static int __init omap_pm_init(void) { + int error; + printk("Power Management for TI OMAP.\n"); /* @@ -760,7 +764,9 @@ static int __init omap_pm_init(void) omap_pm_init_proc(); #endif - subsys_create_file(&power_subsys, &sleep_while_idle_attr); + error = subsys_create_file(&power_subsys, &sleep_while_idle_attr); + if (error) + printk(KERN_ERR "subsys_create_file failed: %d\n", error); if (cpu_is_omap16xx()) { /* configure LOW_PWR pin */ diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c index 4cc98a578e4..10a4fe88b2f 100644 --- a/arch/arm/mach-omap1/serial.c +++ b/arch/arm/mach-omap1/serial.c @@ -1,7 +1,7 @@ /* * linux/arch/arm/mach-omap1/serial.c * - * OMAP1 CPU identification code + * OMAP1 serial support. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -59,7 +59,7 @@ static void __init omap_serial_reset(struct plat_serial8250_port *p) omap_serial_outp(p, UART_OMAP_SCR, 0x08); /* TX watermark */ omap_serial_outp(p, UART_OMAP_MDR1, 0x00); /* enable UART */ - if (!cpu_is_omap1510()) { + if (!cpu_is_omap15xx()) { omap_serial_outp(p, UART_OMAP_SYSC, 0x01); while (!(omap_serial_in(p, UART_OMAP_SYSC) & 0x01)); } @@ -121,7 +121,7 @@ void __init omap_serial_init(void) serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2; } - if (cpu_is_omap1510()) { + if (cpu_is_omap15xx()) { serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16; serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16; serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16; @@ -147,10 +147,10 @@ void __init omap_serial_init(void) printk("Could not get uart1_ck\n"); else { clk_enable(uart1_ck); - if (cpu_is_omap1510()) + if (cpu_is_omap15xx()) clk_set_rate(uart1_ck, 12000000); } - if (cpu_is_omap1510()) { + if (cpu_is_omap15xx()) { omap_cfg_reg(UART1_TX); omap_cfg_reg(UART1_RTS); if (machine_is_omap_innovator()) { @@ -167,12 +167,12 @@ void __init omap_serial_init(void) printk("Could not get uart2_ck\n"); else { clk_enable(uart2_ck); - if (cpu_is_omap1510()) + if (cpu_is_omap15xx()) clk_set_rate(uart2_ck, 12000000); else clk_set_rate(uart2_ck, 48000000); } - if (cpu_is_omap1510()) { + if (cpu_is_omap15xx()) { omap_cfg_reg(UART2_TX); omap_cfg_reg(UART2_RTS); if (machine_is_omap_innovator()) { @@ -189,10 +189,10 @@ void __init omap_serial_init(void) printk("Could not get uart3_ck\n"); else { clk_enable(uart3_ck); - if (cpu_is_omap1510()) + if (cpu_is_omap15xx()) clk_set_rate(uart3_ck, 12000000); } - if (cpu_is_omap1510()) { + if (cpu_is_omap15xx()) { omap_cfg_reg(UART3_TX); omap_cfg_reg(UART3_RX); } diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 3b1ad1d981a..1e7ed6d22ca 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -39,7 +39,6 @@ #include "prcm-regs.h" #include <asm/io.h> -#include <asm/delay.h> static unsigned int row_gpios[6] = { 88, 89, 124, 11, 6, 96 }; static unsigned int col_gpios[7] = { 90, 91, 100, 36, 12, 97, 98 }; @@ -179,9 +178,11 @@ static int h4_select_irda(struct device *dev, int state) return err; } -static void set_trans_mode(void *data) +static void set_trans_mode(struct work_struct *work) { - int *mode = data; + struct omap_irda_config *irda_config = + container_of(work, struct omap_irda_config, gpio_expa.work); + int mode = irda_config->mode; unsigned char expa; int err = 0; @@ -191,7 +192,7 @@ static void set_trans_mode(void *data) expa &= ~0x01; - if (!(*mode & IR_SIRMODE)) { /* MIR/FIR */ + if (!(mode & IR_SIRMODE)) { /* MIR/FIR */ expa |= 0x01; } @@ -204,9 +205,9 @@ static int h4_transceiver_mode(struct device *dev, int mode) { struct omap_irda_config *irda_config = dev->platform_data; + irda_config->mode = mode; cancel_delayed_work(&irda_config->gpio_expa); - PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); -#error this is not permitted - mode is an argument variable + PREPARE_DELAYED_WORK(&irda_config->gpio_expa, set_trans_mode); schedule_delayed_work(&irda_config->gpio_expa, 0); return 0; diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c index 973189cd976..45d1aaa51b5 100644 --- a/arch/arm/mach-omap2/timer-gp.c +++ b/arch/arm/mach-omap2/timer-gp.c @@ -24,6 +24,7 @@ #include <linux/err.h> #include <linux/clk.h> #include <linux/delay.h> +#include <linux/irq.h> #include <asm/mach/time.h> #include <asm/arch/dmtimer.h> @@ -64,7 +65,7 @@ static void __init omap2_gp_timer_init(void) BUG_ON(gptimer == NULL); omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_SYS_CLK); - tick_period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / 100; + tick_period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / HZ; tick_period -= 1; setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq); diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index 165017de8d0..392c3871736 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -16,7 +16,8 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/platform_device.h> -#include <asm/apm-emulation.h> +#include <linux/apm-emulation.h> + #include <asm/irq.h> #include <asm/mach-types.h> #include <asm/hardware.h> diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index b97d543d936..745a4dc7acd 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -16,7 +16,8 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/platform_device.h> -#include <asm/apm-emulation.h> +#include <linux/apm-emulation.h> + #include <asm/irq.h> #include <asm/mach-types.h> #include <asm/hardware.h> diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 0a007b931f6..a9de727c932 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c @@ -131,6 +131,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) struct op_arm_model_spec *spec = NULL; int ret = -ENODEV; + ops->backtrace = arm_backtrace; + #ifdef CONFIG_CPU_XSCALE spec = &op_xscale_spec; #endif @@ -161,7 +163,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ops->start = op_arm_start; ops->stop = op_arm_stop; ops->cpu_type = op_arm_model->name; - ops->backtrace = arm_backtrace; printk(KERN_INFO "oprofile: using %s\n", spec->name); } diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index bb045e5ddbd..f3f84fbf8b8 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -557,7 +557,7 @@ int omap_request_dma(int dev_id, const char *dev_name, omap_enable_channel_irq(free_ch); /* Clear the CSR register and IRQ status register */ OMAP_DMA_CSR_REG(free_ch) = OMAP2_DMA_CSR_CLEAR_MASK; - omap_writel(~0x0, OMAP_DMA4_IRQSTATUS_L0); + omap_writel(1 << free_ch, OMAP_DMA4_IRQSTATUS_L0); } *dma_ch_out = free_ch; @@ -597,10 +597,7 @@ void omap_free_dma(int lch) /* Clear the CSR register and IRQ status register */ OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK; - - val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); - val |= 1 << lch; - omap_writel(val, OMAP_DMA4_IRQSTATUS_L0); + omap_writel(1 << lch, OMAP_DMA4_IRQSTATUS_L0); /* Disable all DMA interrupts for the channel. */ OMAP_DMA_CICR_REG(lch) = 0; @@ -927,7 +924,6 @@ static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id) static int omap2_dma_handle_ch(int ch) { u32 status = OMAP_DMA_CSR_REG(ch); - u32 val; if (!status) return 0; @@ -948,11 +944,7 @@ static int omap2_dma_handle_ch(int ch) dma_chan[ch].dev_id); OMAP_DMA_CSR_REG(ch) = OMAP2_DMA_CSR_CLEAR_MASK; - - val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); - /* ch in this function is from 0-31 while in register it is 1-32 */ - val = 1 << (ch); - omap_writel(val, OMAP_DMA4_IRQSTATUS_L0); + omap_writel(1 << ch, OMAP_DMA4_IRQSTATUS_L0); if (likely(dma_chan[ch].callback != NULL)) dma_chan[ch].callback(ch, status, dma_chan[ch].data); diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index bcbb8d7392b..45f0439bffb 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -90,8 +90,8 @@ static struct omap_dm_timer dm_timers[] = { { .phys_base = 0xfffb2c00, .irq = INT_1610_GPTIMER4 }, { .phys_base = 0xfffb3400, .irq = INT_1610_GPTIMER5 }, { .phys_base = 0xfffb3c00, .irq = INT_1610_GPTIMER6 }, - { .phys_base = 0xfffb4400, .irq = INT_1610_GPTIMER7 }, - { .phys_base = 0xfffb4c00, .irq = INT_1610_GPTIMER8 }, + { .phys_base = 0xfffb7400, .irq = INT_1610_GPTIMER7 }, + { .phys_base = 0xfffbd400, .irq = INT_1610_GPTIMER8 }, }; #elif defined(CONFIG_ARCH_OMAP2) @@ -314,6 +314,8 @@ struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) { BUG(); + + return 0; } #endif diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 4f2fd559133..b8c01de208b 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -974,10 +974,11 @@ static struct irq_chip gpio_irq_chip = { }; static struct irq_chip mpuio_irq_chip = { - .name = "MPUIO", - .ack = mpuio_ack_irq, - .mask = mpuio_mask_irq, - .unmask = mpuio_unmask_irq + .name = "MPUIO", + .ack = mpuio_ack_irq, + .mask = mpuio_mask_irq, + .unmask = mpuio_unmask_irq, + .set_type = gpio_irq_type, }; static int initialized; diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index ec50008a2df..b8d6f17ff58 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -20,8 +20,8 @@ #include <linux/interrupt.h> #include <linux/err.h> #include <linux/clk.h> +#include <linux/delay.h> -#include <asm/delay.h> #include <asm/io.h> #include <asm/irq.h> diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c index 042105ac30b..6c798d28868 100644 --- a/arch/arm/plat-omap/mux.c +++ b/arch/arm/plat-omap/mux.c @@ -116,7 +116,7 @@ int __init_or_module omap_cfg_reg(const unsigned long index) } /* Check for pull up or pull down selection on 1610 */ - if (!cpu_is_omap1510()) { + if (!cpu_is_omap15xx()) { if (cfg->pu_pd_reg && cfg->pull_val) { spin_lock_irqsave(&mux_spin_lock, flags); pu_pd_orig = omap_readl(cfg->pu_pd_reg); @@ -172,7 +172,7 @@ int __init_or_module omap_cfg_reg(const unsigned long index) printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg); - if (!cpu_is_omap1510()) { + if (!cpu_is_omap15xx()) { if (cfg->pu_pd_reg && cfg->pull_val) { printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", cfg->pu_pd_name, cfg->pu_pd_reg, diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index 860869528f4..b972f36d547 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig @@ -58,6 +58,11 @@ config S3C2410_PM_CHECK going to sleep. The blocks are then checked on resume for any errors. + Note, this can take several seconds depending on memory size + and CPU speed. + + See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> + config S3C2410_PM_CHECK_CHUNKSIZE int "S3C2410 PM Suspend CRC Chunksize (KiB)" depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK @@ -68,6 +73,8 @@ config S3C2410_PM_CHECK_CHUNKSIZE the CRC data block will take more memory, but wil identify any faults with better precision. + See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt> + config S3C2410_LOWLEVEL_UART_PORT int "S3C2410 UART to use for low-level messages" default 0 diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 71729d0f013..4ec2dd5455f 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -176,7 +176,7 @@ config MACH_DECSTATION bool "DECstations" select BOOT_ELF32 select DMA_NONCOHERENT - select EARLY_PRINTK + select SYS_HAS_EARLY_PRINTK select IRQ_CPU select SYS_HAS_CPU_R3000 select SYS_HAS_CPU_R4X00 @@ -242,6 +242,7 @@ config MACH_JAZZ config LASAT bool "LASAT Networks platforms" select DMA_NONCOHERENT + select SYS_HAS_EARLY_PRINTK select HW_HAS_PCI select MIPS_GT64120 select MIPS_NILE4 @@ -256,6 +257,7 @@ config MIPS_ATLAS bool "MIPS Atlas board" select BOOT_ELF32 select DMA_NONCOHERENT + select SYS_HAS_EARLY_PRINTK select IRQ_CPU select HW_HAS_PCI select MIPS_BOARDS_GEN @@ -301,6 +303,7 @@ config MIPS_MALTA select SYS_HAS_CPU_MIPS64_R1 select SYS_HAS_CPU_NEVADA select SYS_HAS_CPU_RM7000 + select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN @@ -316,6 +319,7 @@ config MIPS_SEAD depends on EXPERIMENTAL select IRQ_CPU select DMA_NONCOHERENT + select SYS_HAS_EARLY_PRINTK select MIPS_BOARDS_GEN select SYS_HAS_CPU_MIPS32_R1 select SYS_HAS_CPU_MIPS32_R2 @@ -353,9 +357,11 @@ config WR_PPMC config MIPS_SIM bool 'MIPS simulator (MIPSsim)' select DMA_NONCOHERENT + select SYS_HAS_EARLY_PRINTK select IRQ_CPU select SYS_HAS_CPU_MIPS32_R1 select SYS_HAS_CPU_MIPS32_R2 + select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN @@ -376,6 +382,7 @@ config MOMENCO_JAGUAR_ATX select RM7000_CPU_SCACHE select SWAP_IO_SPACE select SYS_HAS_CPU_RM9000 + select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN @@ -513,6 +520,7 @@ config PMC_YOSEMITE select IRQ_CPU_RM9K select SWAP_IO_SPACE select SYS_HAS_CPU_RM9000 + select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN @@ -573,6 +581,7 @@ config SGI_IP22 select SWAP_IO_SPACE select SYS_HAS_CPU_R4X00 select SYS_HAS_CPU_R5000 + select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN @@ -587,7 +596,7 @@ config SGI_IP27 select ARC64 select BOOT_ELF64 select DMA_IP27 - select EARLY_PRINTK + select SYS_HAS_EARLY_PRINTK select HW_HAS_PCI select NR_CPUS_DEFAULT_64 select PCI_DOMAINS @@ -749,6 +758,7 @@ config SNI_RM select SYS_HAS_CPU_R5000 select SYS_HAS_CPU_R10000 select R5000_CPU_SCACHE + select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL select SYS_SUPPORTS_BIG_ENDIAN @@ -897,6 +907,20 @@ config DMA_NEED_PCI_MAP_STATE bool config EARLY_PRINTK + bool "Early printk" if EMBEDDED && DEBUG_KERNEL + depends on SYS_HAS_EARLY_PRINTK + default y + help + This option enables special console drivers which allow the kernel + to print messages very early in the bootup process. + + This is useful for kernel debugging when your machine crashes very + early before the console code is initialized. For normal operation + it is not recommended because it looks on some machines ugly and + oesn't cooperate with an X server. You should normally N here, + unless you want to debug such a crash. + +config SYS_HAS_EARLY_PRINTK bool config GENERIC_ISA_DMA @@ -1033,6 +1057,7 @@ config SOC_PNX8550 select DMA_NONCOHERENT select HW_HAS_PCI select SYS_HAS_CPU_MIPS32_R1 + select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_32BIT_KERNEL select GENERIC_HARDIRQS_NO__DO_IRQ select SYS_SUPPORTS_KGDB @@ -1093,7 +1118,7 @@ config HAVE_STD_PC_SERIAL_PORT config ARC_CONSOLE bool "ARC console support" - depends on SGI_IP22 || SNI_RM + depends on SGI_IP22 || (SNI_RM && CPU_LITTLE_ENDIAN) config ARC_MEMORY bool @@ -1895,10 +1920,6 @@ config HZ source "kernel/Kconfig.preempt" -config RTC_DS1742 - bool "DS1742 BRAM/RTC support" - depends on TOSHIBA_JMR3927 || TOSHIBA_RBTX4927 - config MIPS_INSANE_LARGE bool "Support for large 64-bit configurations" depends on CPU_R10000 && 64BIT diff --git a/arch/mips/arc/console.c b/arch/mips/arc/console.c index 6a9d144512c..0fe6032999c 100644 --- a/arch/mips/arc/console.c +++ b/arch/mips/arc/console.c @@ -29,35 +29,3 @@ void prom_putchar(char c) ArcWrite(1, &it, 1, &cnt); bc_enable(); } - -char prom_getchar(void) -{ - ULONG cnt; - CHAR c; - - bc_disable(); - ArcRead(0, &c, 1, &cnt); - bc_enable(); - - return c; -} - -void prom_printf(char *fmt, ...) -{ - va_list args; - char ppbuf[1024]; - char *bptr; - - va_start(args, fmt); - vsprintf(ppbuf, fmt, args); - - bptr = ppbuf; - - while (*bptr != 0) { - if (*bptr == '\n') - prom_putchar('\r'); - - prom_putchar(*bptr++); - } - va_end(args); -} diff --git a/arch/mips/arc/init.c b/arch/mips/arc/init.c index 76ab505ca69..0ac8f42d375 100644 --- a/arch/mips/arc/init.c +++ b/arch/mips/arc/init.c @@ -24,12 +24,15 @@ void __init prom_init(void) { PSYSTEM_PARAMETER_BLOCK pb = PROMBLOCK; romvec = ROMVECTOR; + ULONG cnt; + CHAR c; + prom_argc = fw_arg0; _prom_argv = (LONG *) fw_arg1; _prom_envp = (LONG *) fw_arg2; if (pb->magic != 0x53435241) { - prom_printf("Aieee, bad prom vector magic %08lx\n", pb->magic); + printk(KERN_CRIT "Aieee, bad prom vector magic %08lx\n", pb->magic); while(1) ; } @@ -41,8 +44,8 @@ void __init prom_init(void) prom_meminit(); #ifdef DEBUG_PROM_INIT - prom_printf("Press a key to reboot\n"); - prom_getchar(); + pr_info("Press a key to reboot\n"); + ArcRead(0, &c, 1, &cnt); ArcEnterInteractiveMode(); #endif } diff --git a/arch/mips/arc/memory.c b/arch/mips/arc/memory.c index 456cb81a32d..83d15791ef6 100644 --- a/arch/mips/arc/memory.c +++ b/arch/mips/arc/memory.c @@ -118,11 +118,11 @@ void __init prom_meminit(void) #ifdef DEBUG int i = 0; - prom_printf("ARCS MEMORY DESCRIPTOR dump:\n"); + printk("ARCS MEMORY DESCRIPTOR dump:\n"); p = ArcGetMemoryDescriptor(PROM_NULL_MDESC); while(p) { - prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n", - i, p, p->base, p->pages, mtypes(p->type)); + printk("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n", + i, p, p->base, p->pages, mtypes(p->type)); p = ArcGetMemoryDescriptor(p); i++; } diff --git a/arch/mips/arc/tree.c b/arch/mips/arc/tree.c index 2aedd4f5283..abd1786ea09 100644 --- a/arch/mips/arc/tree.c +++ b/arch/mips/arc/tree.c @@ -93,11 +93,11 @@ static char *iflags[] = { static void __init dump_component(pcomponent *p) { - prom_printf("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>", - p, classes[p->class], types[p->type], - iflags[p->iflags], p->vers, p->rev); - prom_printf("key<%08lx>\n\tamask<%08lx>cdsize<%d>ilen<%d>iname<%s>\n", - p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname); + printk("[%p]:class<%s>type<%s>flags<%s>ver<%d>rev<%d>", + p, classes[p->class], types[p->type], + iflags[p->iflags], p->vers, p->rev); + printk("key<%08lx>\n\tamask<%08lx>cdsize<%d>ilen<%d>iname<%s>\n", + p->key, p->amask, (int)p->cdsize, (int)p->ilen, p->iname); } static void __init diff --git a/arch/mips/au1000/mtx-1/board_setup.c b/arch/mips/au1000/mtx-1/board_setup.c index 13f9bf5f91a..7bc5af8917d 100644 --- a/arch/mips/au1000/mtx-1/board_setup.c +++ b/arch/mips/au1000/mtx-1/board_setup.c @@ -43,6 +43,9 @@ #include <asm/pgtable.h> #include <asm/mach-au1x00/au1000.h> +extern int (*board_pci_idsel)(unsigned int devsel, int assert); +int mtx1_pci_idsel(unsigned int devsel, int assert); + void board_reset (void) { /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ @@ -66,19 +69,43 @@ void __init board_setup(void) #endif // initialize sys_pinfunc: - // disable second ethernet port (SYS_PF_NI2) - // set U3/GPIO23 to GPIO23 (SYS_PF_U3) - au_writel( SYS_PF_NI2 | SYS_PF_U3, SYS_PINFUNC ); + au_writel( SYS_PF_NI2, SYS_PINFUNC ); // initialize GPIO au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR ); au_writel( 0x00000001, SYS_OUTPUTCLR ); // set M66EN (PCI 66MHz) to OFF au_writel( 0x00000008, SYS_OUTPUTSET ); // set PCI CLKRUN# to OFF + au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON au_writel( 0x00000020, SYS_OUTPUTCLR ); // set eth PHY TX_ER to OFF // enable LED and set it to green au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR ); au_writel( 0x18000800, GPIO2_OUTPUT ); + board_pci_idsel = mtx1_pci_idsel; + printk("4G Systems MTX-1 Board\n"); } + +int +mtx1_pci_idsel(unsigned int devsel, int assert) +{ +#define MTX_IDSEL_ONLY_0_AND_3 0 +#if MTX_IDSEL_ONLY_0_AND_3 + if (devsel != 0 && devsel != 3) { + printk("*** not 0 or 3\n"); + return 0; + } +#endif + + if (assert && devsel != 0) { + // supress signal to cardbus + au_writel( 0x00000002, SYS_OUTPUTCLR ); // set EXT_IO3 OFF + } + else { + au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON + } + au_sync_udelay(1); + return 1; +} + diff --git a/arch/mips/au1000/mtx-1/irqmap.c b/arch/mips/au1000/mtx-1/irqmap.c index 4693a4eb2b8..a4fa0f227e4 100644 --- a/arch/mips/au1000/mtx-1/irqmap.c +++ b/arch/mips/au1000/mtx-1/irqmap.c @@ -48,7 +48,7 @@ #include <asm/mach-au1x00/au1000.h> char irq_tab_alchemy[][5] __initdata = { - [0] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 00 - AdapterA-Slot0 (top) */ + [0] = { -1, INTA, INTA, INTX, INTX}, /* IDSEL 00 - AdapterA-Slot0 (top) */ [1] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 01 - AdapterA-Slot1 (bottom) */ [2] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 02 - AdapterB-Slot0 (top) */ [3] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 03 - AdapterB-Slot1 (bottom) */ diff --git a/arch/mips/cobalt/console.c b/arch/mips/cobalt/console.c index 46c23b66bc1..fff20d28114 100644 --- a/arch/mips/cobalt/console.c +++ b/arch/mips/cobalt/console.c @@ -19,29 +19,3 @@ static void putchar(int c) COBALT_UART[UART_TX] = c; } - -static void cons_write(struct console *c, const char *s, unsigned n) -{ - while(n-- && *s) - putchar(*s++); -} - -static struct console cons_info = -{ - .name = "uart", - .write = cons_write, - .flags = CON_PRINTBUFFER | CON_BOOT, - .index = -1, -}; - -void __init cobalt_early_console(void) -{ - register_console(&cons_info); - - printk("Cobalt: early console registered\n"); -} - -void __init disable_early_printk(void) -{ - unregister_console(&cons_info); -} diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c index 415ff8710b5..88d34f11385 100644 --- a/arch/mips/cobalt/setup.c +++ b/arch/mips/cobalt/setup.c @@ -79,37 +79,38 @@ static struct resource cobalt_io_resource = { .flags = IORESOURCE_IO }; -static struct resource cobalt_io_resources[] = { - { +/* + * Cobalt doesn't have PS/2 keyboard/mouse interfaces, + * keyboard conntroller is never used. + * Also PCI-ISA bridge DMA contoroller is never used. + */ +static struct resource cobalt_reserved_resources[] = { + { /* dma1 */ .start = 0x00, .end = 0x1f, - .name = "dma1", - .flags = IORESOURCE_BUSY - }, { - .start = 0x40, - .end = 0x5f, - .name = "timer", - .flags = IORESOURCE_BUSY - }, { + .name = "reserved", + .flags = IORESOURCE_BUSY | IORESOURCE_IO, + }, + { /* keyboard */ .start = 0x60, .end = 0x6f, - .name = "keyboard", - .flags = IORESOURCE_BUSY - }, { + .name = "reserved", + .flags = IORESOURCE_BUSY | IORESOURCE_IO, + }, + { /* dma page reg */ .start = 0x80, .end = 0x8f, - .name = "dma page reg", - .flags = IORESOURCE_BUSY - }, { + .name = "reserved", + .flags = IORESOURCE_BUSY | IORESOURCE_IO, + }, + { /* dma2 */ .start = 0xc0, .end = 0xdf, - .name = "dma2", - .flags = IORESOURCE_BUSY + .name = "reserved", + .flags = IORESOURCE_BUSY | IORESOURCE_IO, }, }; -#define COBALT_IO_RESOURCES (sizeof(cobalt_io_resources)/sizeof(struct resource)) - static struct pci_controller cobalt_pci_controller = { .pci_ops = >64111_pci_ops, .mem_resource = &cobalt_mem_resource, @@ -133,9 +134,9 @@ void __init plat_mem_setup(void) /* I/O port resource must include LCD/buttons */ ioport_resource.end = 0x0fffffff; - /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < COBALT_IO_RESOURCES; i++) - request_resource(&ioport_resource, cobalt_io_resources + i); + /* These resources have been reserved by VIA SuperI/O chip. */ + for (i = 0; i < ARRAY_SIZE(cobalt_reserved_resources); i++) + request_resource(&ioport_resource, cobalt_reserved_resources + i); /* Read the cobalt id register out of the PCI config space */ PCI_CFG_SET(devfn, (VIA_COBALT_BRD_ID_REG & ~0x3)); @@ -150,10 +151,6 @@ void __init plat_mem_setup(void) #endif if (cobalt_board_id > COBALT_BRD_ID_RAQ1) { -#ifdef CONFIG_EARLY_PRINTK - cobalt_early_console(); -#endif - #ifdef CONFIG_SERIAL_8250 uart.line = 0; uart.type = PORT_UNKNOWN; diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index 9ebb522fbbb..98b9fbc042f 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -148,7 +148,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_RTC_DS1742=y # CONFIG_KEXEC is not set CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y @@ -802,7 +801,28 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # Real Time Clock # -# CONFIG_RTC_CLASS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set + +# +# RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +CONFIG_RTC_DRV_DS1742=y +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set # # DMA Engine support diff --git a/arch/mips/dec/prom/console.c b/arch/mips/dec/prom/console.c index cade16ec7e5..65419bf3244 100644 --- a/arch/mips/dec/prom/console.c +++ b/arch/mips/dec/prom/console.c @@ -16,40 +16,12 @@ #include <asm/dec/prom.h> -static void __init prom_console_write(struct console *con, const char *s, - unsigned int c) +void prom_putchar(char c) { - static char sfmt[] __initdata = "%%%us"; - char fmt[13]; + char s[2]; - snprintf(fmt, sizeof(fmt), sfmt, c); - prom_printf(fmt, s); -} - -static struct console promcons __initdata = { - .name = "prom", - .write = prom_console_write, - .flags = CON_PRINTBUFFER, - .index = -1, -}; - -static int promcons_output __initdata = 0; - -void __init register_prom_console(void) -{ - if (!promcons_output) { - promcons_output = 1; - register_console(&promcons); - } -} + s[0] = c; + s[1] = '\0'; -void __init unregister_prom_console(void) -{ - if (promcons_output) { - unregister_console(&promcons); - promcons_output = 0; - } + prom_printf( s); } - -void disable_early_printk(void) - __attribute__((alias("unregister_prom_console"))); diff --git a/arch/mips/dec/prom/identify.c b/arch/mips/dec/prom/identify.c index c4e3c1ea0d4..cd85924e257 100644 --- a/arch/mips/dec/prom/identify.c +++ b/arch/mips/dec/prom/identify.c @@ -26,9 +26,6 @@ #include "dectypes.h" -extern unsigned long mips_machgroup; -extern unsigned long mips_machtype; - static const char *dec_system_strings[] = { [MACH_DSUNKNOWN] "unknown DECstation", [MACH_DS23100] "DECstation 2100/3100", diff --git a/arch/mips/gt64120/ev64120/promcon.c b/arch/mips/gt64120/ev64120/promcon.c index b5937c4ba7d..6e0ecfed964 100644 --- a/arch/mips/gt64120/ev64120/promcon.c +++ b/arch/mips/gt64120/ev64120/promcon.c @@ -24,11 +24,6 @@ static void prom_console_write(struct console *co, const char *s, } } -int prom_getchar(void) -{ - return 0; -} - static struct console sercons = { .name = "ttyS", .write = prom_console_write, diff --git a/arch/mips/jmr3927/common/Makefile b/arch/mips/jmr3927/common/Makefile index cb09a8eede1..01e7db19bcb 100644 --- a/arch/mips/jmr3927/common/Makefile +++ b/arch/mips/jmr3927/common/Makefile @@ -2,4 +2,4 @@ # Makefile for the common code of TOSHIBA JMR-TX3927 board # -obj-y += prom.o puts.o rtc_ds1742.o +obj-y += prom.o puts.o diff --git a/arch/mips/jmr3927/common/rtc_ds1742.c b/arch/mips/jmr3927/common/rtc_ds1742.c deleted file mode 100644 index e6561345d12..00000000000 --- a/arch/mips/jmr3927/common/rtc_ds1742.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ahennessy@mvista.com - * - * arch/mips/jmr3927/common/rtc_ds1742.c - * Based on arch/mips/ddb5xxx/common/rtc_ds1386.c - * low-level RTC hookups for s for Dallas 1742 chip. - * - * Copyright (C) 2000-2001 Toshiba Corporation - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - - -/* - * This file exports a function, rtc_ds1386_init(), which expects an - * uncached base address as the argument. It will set the two function - * pointers expected by the MIPS generic timer code. - */ - -#include <linux/bcd.h> -#include <linux/types.h> -#include <linux/time.h> -#include <linux/rtc.h> -#include <linux/ds1742rtc.h> - -#include <asm/time.h> -#include <asm/addrspace.h> - -#include <asm/debug.h> - -#define EPOCH 2000 - -static unsigned long rtc_base; - -static unsigned long -rtc_ds1742_get_time(void) -{ - unsigned int year, month, day, hour, minute, second; - unsigned int century; - unsigned long flags; - - spin_lock_irqsave(&rtc_lock, flags); - rtc_write(RTC_READ, RTC_CONTROL); - second = BCD2BIN(rtc_read(RTC_SECONDS) & RTC_SECONDS_MASK); - minute = BCD2BIN(rtc_read(RTC_MINUTES)); - hour = BCD2BIN(rtc_read(RTC_HOURS)); - day = BCD2BIN(rtc_read(RTC_DATE)); - month = BCD2BIN(rtc_read(RTC_MONTH)); - year = BCD2BIN(rtc_read(RTC_YEAR)); - century = BCD2BIN(rtc_read(RTC_CENTURY) & RTC_CENTURY_MASK); - rtc_write(0, RTC_CONTROL); - spin_unlock_irqrestore(&rtc_lock, flags); - - year += century * 100; - - return mktime(year, month, day, hour, minute, second); -} -extern void to_tm(unsigned long tim, struct rtc_time * tm); - -static int -rtc_ds1742_set_time(unsigned long t) -{ - struct rtc_time tm; - u8 year, month, day, hour, minute, second; - u8 cmos_year, cmos_month, cmos_day, cmos_hour, cmos_minute, cmos_second; - int cmos_century; - unsigned long flags; - - spin_lock_irqsave(&rtc_lock, flags); - rtc_write(RTC_READ, RTC_CONTROL); - cmos_second = (u8)(rtc_read(RTC_SECONDS) & RTC_SECONDS_MASK); - cmos_minute = (u8)rtc_read(RTC_MINUTES); - cmos_hour = (u8)rtc_read(RTC_HOURS); - cmos_day = (u8)rtc_read(RTC_DATE); - cmos_month = (u8)rtc_read(RTC_MONTH); - cmos_year = (u8)rtc_read(RTC_YEAR); - cmos_century = rtc_read(RTC_CENTURY) & RTC_CENTURY_MASK; - - rtc_write(RTC_WRITE, RTC_CONTROL); - - /* convert */ - to_tm(t, &tm); - - /* check each field one by one */ - year = BIN2BCD(tm.tm_year - EPOCH); - if (year != cmos_year) { - rtc_write(year,RTC_YEAR); - } - - month = BIN2BCD(tm.tm_mon); - if (month != (cmos_month & 0x1f)) { - rtc_write((month & 0x1f) | (cmos_month & ~0x1f),RTC_MONTH); - } - - day = BIN2BCD(tm.tm_mday); - if (day != cmos_day) { - - rtc_write(day, RTC_DATE); - } - - if (cmos_hour & 0x40) { - /* 12 hour format */ - hour = 0x40; - if (tm.tm_hour > 12) { - hour |= 0x20 | (BIN2BCD(hour-12) & 0x1f); - } else { - hour |= BIN2BCD(tm.tm_hour); - } - } else { - /* 24 hour format */ - hour = BIN2BCD(tm.tm_hour) & 0x3f; - } - if (hour != cmos_hour) rtc_write(hour, RTC_HOURS); - - minute = BIN2BCD(tm.tm_min); - if (minute != cmos_minute) { - rtc_write(minute, RTC_MINUTES); - } - - second = BIN2BCD(tm.tm_sec); - if (second != cmos_second) { - rtc_write(second & RTC_SECONDS_MASK,RTC_SECONDS); - } - - /* RTC_CENTURY and RTC_CONTROL share same address... */ - rtc_write(cmos_century, RTC_CONTROL); - spin_unlock_irqrestore(&rtc_lock, flags); - - return 0; -} - -void -rtc_ds1742_init(unsigned long base) -{ - u8 cmos_second; - - /* remember the base */ - rtc_base = base; - db_assert((rtc_base & 0xe0000000) == KSEG1); - - /* set the function pointers */ - rtc_mips_get_time = rtc_ds1742_get_time; - rtc_mips_set_time = rtc_ds1742_set_time; - - /* clear oscillator stop bit */ - rtc_write(RTC_READ, RTC_CONTROL); - cmos_second = (u8)(rtc_read(RTC_SECONDS) & RTC_SECONDS_MASK); - rtc_write(RTC_WRITE, RTC_CONTROL); - rtc_write(cmos_second, RTC_SECONDS); /* clear msb */ - rtc_write(0, RTC_CONTROL); -} diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c index ecabe5b0848..fc523bda068 100644 --- a/arch/mips/jmr3927/rbhma3100/setup.c +++ b/arch/mips/jmr3927/rbhma3100/setup.c @@ -45,6 +45,7 @@ #include <linux/param.h> /* for HZ */ #include <linux/delay.h> #include <linux/pm.h> +#include <linux/platform_device.h> #ifdef CONFIG_SERIAL_TXX9 #include <linux/tty.h> #include <linux/serial.h> @@ -172,19 +173,10 @@ static cycle_t jmr3927_hpt_read(void) return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr; } -#define USE_RTC_DS1742 -#ifdef USE_RTC_DS1742 -extern void rtc_ds1742_init(unsigned long base); -#endif static void __init jmr3927_time_init(void) { clocksource_mips.read = jmr3927_hpt_read; mips_hpt_frequency = JMR3927_TIMER_CLK; -#ifdef USE_RTC_DS1742 - if (jmr3927_have_nvram()) { - rtc_ds1742_init(JMR3927_IOC_NVRAMB_ADDR); - } -#endif } void __init plat_timer_setup(struct irqaction *irq) @@ -540,3 +532,32 @@ void __init tx3927_setup(void) printk("TX3927 D-Cache WriteBack (CWF) .\n"); } } + +/* This trick makes rtc-ds1742 driver usable as is. */ +unsigned long __swizzle_addr_b(unsigned long port) +{ + if ((port & 0xffff0000) != JMR3927_IOC_NVRAMB_ADDR) + return port; + port = (port & 0xffff0000) | (port & 0x7fff << 1); +#ifdef __BIG_ENDIAN + return port; +#else + return port | 1; +#endif +} +EXPORT_SYMBOL(__swizzle_addr_b); + +static int __init jmr3927_rtc_init(void) +{ + struct resource res = { + .start = JMR3927_IOC_NVRAMB_ADDR - IO_BASE, + .end = JMR3927_IOC_NVRAMB_ADDR - IO_BASE + 0x800 - 1, + .flags = IORESOURCE_MEM, + }; + struct platform_device *dev; + if (!jmr3927_have_nvram()) + return -ENODEV; + dev = platform_device_register_simple("ds1742", -1, &res, 1); + return IS_ERR(dev) ? PTR_ERR(dev) : 0; +} +device_initcall(jmr3927_rtc_init); diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index a3dad394acb..49246264cc7 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -65,5 +65,6 @@ obj-$(CONFIG_64BIT) += cpu-bugs64.o obj-$(CONFIG_I8253) += i8253.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o +obj-$(CONFIG_EARLY_PRINTK) += early_printk.o CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) diff --git a/arch/mips/kernel/early_printk.c b/arch/mips/kernel/early_printk.c new file mode 100644 index 00000000000..304efdc5682 --- /dev/null +++ b/arch/mips/kernel/early_printk.c @@ -0,0 +1,40 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2002, 2003, 06, 07 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2007 MIPS Technologies, Inc. + * written by Ralf Baechle (ralf@linux-mips.org) + */ +#include <linux/console.h> +#include <linux/init.h> + +extern void prom_putchar(char); + +static void early_console_write(struct console *con, const char *s, unsigned n) +{ + while (n-- && *s) { + if (*s == '\n') + prom_putchar('\r'); + prom_putchar(*s); + s++; + } +} + +static struct console early_console = { + .name = "early", + .write = early_console_write, + .flags = CON_PRINTBUFFER | CON_BOOT, + .index = -1 +}; + +void __init setup_early_printk(void) +{ + register_console(&early_console); +} + +void __init disable_early_printk(void) +{ + unregister_console(&early_console); +} diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index fc4dd6c9dd8..30d433f14f9 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -166,34 +166,6 @@ out: return error; } -asmlinkage long -sysn32_waitid(int which, compat_pid_t pid, - siginfo_t __user *uinfo, int options, - struct compat_rusage __user *uru) -{ - struct rusage ru; - long ret; - mm_segment_t old_fs = get_fs(); - int si_signo; - - if (!access_ok(VERIFY_WRITE, uinfo, sizeof(*uinfo))) - return -EFAULT; - - set_fs (KERNEL_DS); - ret = sys_waitid(which, pid, uinfo, options, - uru ? (struct rusage __user *) &ru : NULL); - set_fs (old_fs); - - if (__get_user(si_signo, &uinfo->si_signo)) - return -EFAULT; - if (ret < 0 || si_signo == 0) - return ret; - - if (uru) - ret = put_compat_rusage(&ru, uru); - return ret; -} - #define RLIM_INFINITY32 0x7fffffff #define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x) @@ -572,151 +544,6 @@ asmlinkage long sys32_sync_file_range(int fd, int __pad, flags); } -/* Argument list sizes for sys_socketcall */ -#define AL(x) ((x) * sizeof(unsigned int)) -static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), - AL(3),AL(3),AL(4),AL(4),AL(4),AL(6), - AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)}; -#undef AL - -/* - * System call vectors. - * - * Argument checking cleaned up. Saved 20% in size. - * This function doesn't need to set the kernel lock because - * it is set by the callees. - */ - -asmlinkage long sys32_socketcall(int call, unsigned int __user *args32) -{ - unsigned int a[6]; - unsigned int a0,a1; - int err; - - extern asmlinkage long sys_socket(int family, int type, int protocol); - extern asmlinkage long sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen); - extern asmlinkage long sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen); - extern asmlinkage long sys_listen(int fd, int backlog); - extern asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen); - extern asmlinkage long sys_getsockname(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len); - extern asmlinkage long sys_getpeername(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len); - extern asmlinkage long sys_socketpair(int family, int type, int protocol, int __user *usockvec); - extern asmlinkage long sys_send(int fd, void __user * buff, size_t len, unsigned flags); - extern asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flags, - struct sockaddr __user *addr, int addr_len); - extern asmlinkage long sys_recv(int fd, void __user * ubuf, size_t size, unsigned flags); - extern asmlinkage long sys_recvfrom(int fd, void __user * ubuf, size_t size, unsigned flags, - struct sockaddr __user *addr, int __user *addr_len); - extern asmlinkage long sys_shutdown(int fd, int how); - extern asmlinkage long sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen); - extern asmlinkage long sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen); - extern asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); - extern asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned int flags); - - - if(call<1||call>SYS_RECVMSG) - return -EINVAL; - - /* copy_from_user should be SMP safe. */ - if (copy_from_user(a, args32, socketcall_nargs[call])) - return -EFAULT; - - a0=a[0]; - a1=a[1]; - - switch(call) - { - case SYS_SOCKET: - err = sys_socket(a0,a1,a[2]); - break; - case SYS_BIND: - err = sys_bind(a0,(struct sockaddr __user *)A(a1), a[2]); - break; - case SYS_CONNECT: - err = sys_connect(a0, (struct sockaddr __user *)A(a1), a[2]); - break; - case SYS_LISTEN: - err = sys_listen(a0,a1); - break; - case SYS_ACCEPT: - err = sys_accept(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2])); - break; - case SYS_GETSOCKNAME: - err = sys_getsockname(a0,(struct sockaddr __user *)A(a1), (int __user *)A(a[2])); - break; - case SYS_GETPEERNAME: - err = sys_getpeername(a0, (struct sockaddr __user *)A(a1), (int __user *)A(a[2])); - break; - case SYS_SOCKETPAIR: - err = sys_socketpair(a0,a1, a[2], (int __user *)A(a[3])); - break; - case SYS_SEND: - err = sys_send(a0, (void __user *)A(a1), a[2], a[3]); - break; - case SYS_SENDTO: - err = sys_sendto(a0,(void __user *)A(a1), a[2], a[3], - (struct sockaddr __user *)A(a[4]), a[5]); - break; - case SYS_RECV: - err = sys_recv(a0, (void __user *)A(a1), a[2], a[3]); - break; - case SYS_RECVFROM: - err = sys_recvfrom(a0, (void __user *)A(a1), a[2], a[3], - (struct sockaddr __user *)A(a[4]), (int __user *)A(a[5])); - break; - case SYS_SHUTDOWN: - err = sys_shutdown(a0,a1); - break; - case SYS_SETSOCKOPT: - err = sys_setsockopt(a0, a1, a[2], (char __user *)A(a[3]), a[4]); - break; - case SYS_GETSOCKOPT: - err = sys_getsockopt(a0, a1, a[2], (char __user *)A(a[3]), (int __user *)A(a[4])); - break; - case SYS_SENDMSG: - err = sys_sendmsg(a0, (struct msghdr __user *) A(a1), a[2]); - break; - case SYS_RECVMSG: - err = sys_recvmsg(a0, (struct msghdr __user *) A(a1), a[2]); - break; - default: - err = -EINVAL; - break; - } - return err; -} - -struct sigevent32 { - u32 sigev_value; - u32 sigev_signo; - u32 sigev_notify; - u32 payload[(64 / 4) - 3]; -}; - -extern asmlinkage long -sys_timer_create(clockid_t which_clock, - struct sigevent __user *timer_event_spec, - timer_t __user * created_timer_id); - -long -sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id) -{ - struct sigevent __user *p = NULL; - if (se32) { - struct sigevent se; - p = compat_alloc_user_space(sizeof(struct sigevent)); - memset(&se, 0, sizeof(struct sigevent)); - if (get_user(se.sigev_value.sival_int, &se32->sigev_value) || - __get_user(se.sigev_signo, &se32->sigev_signo) || - __get_user(se.sigev_notify, &se32->sigev_notify) || - __copy_from_user(&se._sigev_un._pad, &se32->payload, - sizeof(se32->payload)) || - copy_to_user(p, &se, sizeof(se))) - return -EFAULT; - } - return sys_timer_create(clock, p, timer_id); -} - save_static_function(sys32_clone); __attribute_used__ noinline static int _sys32_clone(nabi_no_regargs struct pt_regs regs) diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 2ceda4644a4..f17e31e3bff 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -340,7 +340,7 @@ EXPORT(sysn32_call_table) PTR compat_sys_statfs64 PTR compat_sys_fstatfs64 PTR sys_sendfile64 - PTR sys32_timer_create /* 6220 */ + PTR compat_sys_timer_create /* 6220 */ PTR compat_sys_timer_settime PTR compat_sys_timer_gettime PTR sys_timer_getoverrun @@ -361,7 +361,7 @@ EXPORT(sysn32_call_table) PTR compat_sys_mq_notify PTR compat_sys_mq_getsetattr PTR sys_ni_syscall /* 6240, sys_vserver */ - PTR sysn32_waitid + PTR compat_sys_waitid PTR sys_ni_syscall /* available, was setaltroot */ PTR sys_add_key PTR sys_request_key diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index bcc42489dc3..142c9b70c02 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -307,7 +307,7 @@ sys_call_table: PTR compat_sys_statfs PTR compat_sys_fstatfs /* 4100 */ PTR sys_ni_syscall /* sys_ioperm */ - PTR sys32_socketcall + PTR compat_sys_socketcall PTR sys_syslog PTR compat_sys_setitimer PTR compat_sys_getitimer /* 4105 */ @@ -462,7 +462,7 @@ sys_call_table: PTR sys_fadvise64_64 PTR compat_sys_statfs64 /* 4255 */ PTR compat_sys_fstatfs64 - PTR sys32_timer_create + PTR compat_sys_timer_create PTR compat_sys_timer_settime PTR compat_sys_timer_gettime PTR sys_timer_getoverrun /* 4260 */ diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 11ab222a2e9..4975da0bfb6 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -525,6 +525,14 @@ void __init setup_arch(char **cmdline_p) { cpu_probe(); prom_init(); + +#ifdef CONFIG_EARLY_PRINTK + { + extern void setup_early_printk(void); + + setup_early_printk(); + } +#endif cpu_report(); #if defined(CONFIG_VT) diff --git a/arch/mips/lasat/lasat_board.c b/arch/mips/lasat/lasat_board.c index d425120b028..fbe9a87bd0a 100644 --- a/arch/mips/lasat/lasat_board.c +++ b/arch/mips/lasat/lasat_board.c @@ -110,12 +110,13 @@ int lasat_init_board_info(void) sizeof(struct lasat_eeprom_struct) - 4); if (crc != lasat_board_info.li_eeprom_info.crc32) { - prom_printf("WARNING...\nWARNING...\nEEPROM CRC does not match calculated, attempting to soldier on...\n"); + printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM CRC does " + "not match calculated, attempting to soldier on...\n"); } - if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION) - { - prom_printf("WARNING...\nWARNING...\nEEPROM version %d, wanted version %d, attempting to soldier on...\n", + if (lasat_board_info.li_eeprom_info.version != LASAT_EEPROM_VERSION) { + printk(KERN_WARNING "WARNING...\nWARNING...\nEEPROM version " + "%d, wanted version %d, attempting to soldier on...\n", (unsigned int)lasat_board_info.li_eeprom_info.version, LASAT_EEPROM_VERSION); } @@ -124,7 +125,9 @@ int lasat_init_board_info(void) cfg1 = lasat_board_info.li_eeprom_info.cfg[1]; if ( LASAT_W0_DSCTYPE(cfg0) != 1) { - prom_printf("WARNING...\nWARNING...\nInvalid configuration read from EEPROM, attempting to soldier on..."); + printk(KERN_WARNING "WARNING...\nWARNING...\n" + "Invalid configuration read from EEPROM, attempting to " + "soldier on..."); } /* We have a valid configuration */ diff --git a/arch/mips/lasat/prom.c b/arch/mips/lasat/prom.c index d47692f73a2..812c6ac366b 100644 --- a/arch/mips/lasat/prom.c +++ b/arch/mips/lasat/prom.c @@ -23,10 +23,6 @@ #define PROM_PUTC_ADDR PROM_JUMP_TABLE_ENTRY(1) #define PROM_MONITOR_ADDR PROM_JUMP_TABLE_ENTRY(2) -static void null_prom_printf(const char * fmt, ...) -{ -} - static void null_prom_display(const char *string, int pos, int clear) { } @@ -40,50 +36,29 @@ static void null_prom_putc(char c) } /* these are functions provided by the bootloader */ -static void (* prom_putc)(char c) = null_prom_putc; -void (* prom_printf)(const char * fmt, ...) = null_prom_printf; +static void (* __prom_putc)(char c) = null_prom_putc; + +void prom_putchar(char c) +{ + __prom_putc(c); +} + void (* prom_display)(const char *string, int pos, int clear) = null_prom_display; void (* prom_monitor)(void) = null_prom_monitor; unsigned int lasat_ndelay_divider; -#define PROM_PRINTFBUF_SIZE 256 -static char prom_printfbuf[PROM_PRINTFBUF_SIZE]; - -static void real_prom_printf(const char * fmt, ...) -{ - va_list ap; - int len; - char *c = prom_printfbuf; - int i; - - va_start(ap, fmt); - len = vsnprintf(prom_printfbuf, PROM_PRINTFBUF_SIZE, fmt, ap); - va_end(ap); - - /* output overflowed the buffer */ - if (len < 0 || len > PROM_PRINTFBUF_SIZE) - len = PROM_PRINTFBUF_SIZE; - - for (i=0; i < len; i++) { - if (*c == '\n') - prom_putc('\r'); - prom_putc(*c++); - } -} - static void setup_prom_vectors(void) { u32 version = *(u32 *)(RESET_VECTOR + 0x90); if (version >= 307) { prom_display = (void *)PROM_DISPLAY_ADDR; - prom_putc = (void *)PROM_PUTC_ADDR; - prom_printf = real_prom_printf; + __prom_putc = (void *)PROM_PUTC_ADDR; prom_monitor = (void *)PROM_MONITOR_ADDR; } - prom_printf("prom vectors set up\n"); + printk("prom vectors set up\n"); } static struct at93c_defs at93c_defs[N_MACHTYPES] = { @@ -101,11 +76,11 @@ void __init prom_init(void) setup_prom_vectors(); if (current_cpu_data.cputype == CPU_R5000) { - prom_printf("LASAT 200 board\n"); + printk("LASAT 200 board\n"); mips_machtype = MACH_LASAT_200; lasat_ndelay_divider = LASAT_200_DIVIDER; } else { - prom_printf("LASAT 100 board\n"); + printk("LASAT 100 board\n"); mips_machtype = MACH_LASAT_100; lasat_ndelay_divider = LASAT_100_DIVIDER; } diff --git a/arch/mips/lasat/prom.h b/arch/mips/lasat/prom.h index 07be7bf1e4a..019d45fbd26 100644 --- a/arch/mips/lasat/prom.h +++ b/arch/mips/lasat/prom.h @@ -2,5 +2,4 @@ #define PROM_H extern void (* prom_display)(const char *string, int pos, int clear); extern void (* prom_monitor)(void); -extern void (* prom_printf)(const char * fmt, ...); #endif diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c index 14c55168f1f..488007f1398 100644 --- a/arch/mips/lasat/setup.c +++ b/arch/mips/lasat/setup.c @@ -116,7 +116,6 @@ static void lasat_time_init(void) void __init plat_timer_setup(struct irqaction *irq) { - write_c0_compare( read_c0_count() + mips_hpt_frequency / HZ); change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5); } @@ -179,5 +178,5 @@ void __init plat_mem_setup(void) /* Switch from prom exception handler to normal mode */ change_c0_status(ST0_BEV,0); - prom_printf("Lasat specific initialization complete\n"); + pr_info("Lasat specific initialization complete\n"); } diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 52e0ec8bcb1..d7d3b14dcfb 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -2,8 +2,8 @@ # Makefile for MIPS-specific library files.. # -lib-y += csum_partial.o memcpy.o memcpy-inatomic.o memset.o promlib.o \ - strlen_user.o strncpy_user.o strnlen_user.o uncached.o +lib-y += csum_partial.o memcpy.o memcpy-inatomic.o memset.o strlen_user.o \ + strncpy_user.o strnlen_user.o uncached.o obj-y += iomap.o obj-$(CONFIG_PCI) += iomap-pci.o diff --git a/arch/mips/lib/promlib.c b/arch/mips/lib/promlib.c deleted file mode 100644 index dddfe98b4de..00000000000 --- a/arch/mips/lib/promlib.c +++ /dev/null @@ -1,24 +0,0 @@ -#include <stdarg.h> -#include <linux/kernel.h> - -extern void prom_putchar(char); - -void prom_printf(char *fmt, ...) -{ - va_list args; - char ppbuf[1024]; - char *bptr; - - va_start(args, fmt); - vsprintf(ppbuf, fmt, args); - - bptr = ppbuf; - - while (*bptr != 0) { - if (*bptr == '\n') - prom_putchar('\r'); - - prom_putchar(*bptr++); - } - va_end(args); -} diff --git a/arch/mips/mips-boards/generic/Makefile b/arch/mips/mips-boards/generic/Makefile index 0a30f5dc9b7..aade36d7878 100644 --- a/arch/mips/mips-boards/generic/Makefile +++ b/arch/mips/mips-boards/generic/Makefile @@ -18,7 +18,9 @@ # Makefile for the MIPS boards generic routines under Linux. # -obj-y := reset.o display.o init.o memory.o printf.o \ +obj-y := reset.o display.o init.o memory.o \ cmdline.o time.o + +obj-$(CONFIG_EARLY_PRINTK) += console.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_KGDB) += gdb_hook.o diff --git a/arch/mips/mips-boards/generic/printf.c b/arch/mips/mips-boards/generic/console.c index 1a711bd79b5..4d8ab99e415 100644 --- a/arch/mips/mips-boards/generic/printf.c +++ b/arch/mips/mips-boards/generic/console.c @@ -17,10 +17,9 @@ * * Putting things on the screen/serial line using YAMONs facilities. */ +#include <linux/console.h> #include <linux/init.h> -#include <linux/kernel.h> #include <linux/serial_reg.h> -#include <linux/spinlock.h> #include <asm/io.h> #ifdef CONFIG_MIPS_ATLAS @@ -67,12 +66,3 @@ int prom_putchar(char c) return 1; } - -char prom_getchar(void) -{ - while (!(serial_in(UART_LSR) & UART_LSR_DR)) - ; - - return serial_in(UART_RX); -} - diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c index 58a0fe88359..b1133760012 100644 --- a/arch/mips/mips-boards/generic/init.c +++ b/arch/mips/mips-boards/generic/init.c @@ -167,7 +167,7 @@ static void __init console_config(void) flow = 'r'; sprintf (console_string, " console=ttyS0,%d%c%c%c", baud, parity, bits, flow); strcat (prom_getcmdline(), console_string); - prom_printf("Config serial console:%s\n", console_string); + pr_info("Config serial console:%s\n", console_string); } } #endif @@ -210,8 +210,9 @@ void __init kgdb_config (void) generic_getDebugChar = rs_getDebugChar; } - prom_printf("KGDB: Using serial line /dev/ttyS%d at %d for session, " - "please connect your debugger\n", line ? 1 : 0, speed); + pr_info("KGDB: Using serial line /dev/ttyS%d at %d for " + "session, please connect your debugger\n", + line ? 1 : 0, speed); { char *s; @@ -382,7 +383,7 @@ void __init prom_init(void) board_nmi_handler_setup = mips_nmi_setup; board_ejtag_handler_setup = mips_ejtag_setup; - prom_printf("\nLINUX started...\n"); + pr_info("\nLINUX started...\n"); prom_init_cmdline(); prom_meminit(); #ifdef CONFIG_SERIAL_8250_CONSOLE diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c index ebf0e16c5a0..ae39953da2c 100644 --- a/arch/mips/mips-boards/generic/memory.c +++ b/arch/mips/mips-boards/generic/memory.c @@ -59,11 +59,12 @@ struct prom_pmemblock * __init prom_getmdesc(void) /* otherwise look in the environment */ memsize_str = prom_getenv("memsize"); if (!memsize_str) { - prom_printf("memsize not set in boot prom, set to default (32Mb)\n"); + printk(KERN_WARNING + "memsize not set in boot prom, set to default (32Mb)\n"); physical_memsize = 0x02000000; } else { #ifdef DEBUG - prom_printf("prom_memsize = %s\n", memsize_str); + pr_debug("prom_memsize = %s\n", memsize_str); #endif physical_memsize = simple_strtol(memsize_str, NULL, 0); } @@ -141,12 +142,12 @@ void __init prom_meminit(void) struct prom_pmemblock *p; #ifdef DEBUG - prom_printf("YAMON MEMORY DESCRIPTOR dump:\n"); + pr_debug("YAMON MEMORY DESCRIPTOR dump:\n"); p = prom_getmdesc(); while (p->size) { int i = 0; - prom_printf("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n", - i, p, p->base, p->size, mtypes[p->type]); + pr_debug("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n", + i, p, p->base, p->size, mtypes[p->type]); p++; i++; } diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index a3c3a1d462b..df2a2bd3aa5 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c @@ -295,7 +295,4 @@ void __init plat_timer_setup(struct irqaction *irq) irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU; set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); #endif - - /* to generate the first timer interrupt */ - write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ); } diff --git a/arch/mips/mips-boards/sim/Makefile b/arch/mips/mips-boards/sim/Makefile index a12e32aafde..6aeebc9122f 100644 --- a/arch/mips/mips-boards/sim/Makefile +++ b/arch/mips/mips-boards/sim/Makefile @@ -1,5 +1,7 @@ # # Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. +# Copyright (C) 2007 MIPS Technologies, Inc. +# written by Ralf Baechle (ralf@linux-mips.org) # # This program is free software; you can distribute it and/or modify it # under the terms of the GNU General Public License (Version 2) as @@ -15,5 +17,7 @@ # 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # -obj-y := sim_setup.o sim_mem.o sim_time.o sim_printf.o sim_int.o sim_cmdline.o +obj-y := sim_setup.o sim_mem.o sim_time.o sim_int.o sim_cmdline.o + +obj-$(CONFIG_EARLY_PRINTK) += sim_console.o obj-$(CONFIG_SMP) += sim_smp.o diff --git a/arch/mips/mips-boards/sim/sim_printf.c b/arch/mips/mips-boards/sim/sim_console.c index 3ee5a0b501a..de595a9ccb2 100644 --- a/arch/mips/mips-boards/sim/sim_printf.c +++ b/arch/mips/mips-boards/sim/sim_console.c @@ -1,7 +1,4 @@ /* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. - * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. @@ -15,14 +12,14 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * - * Putting things on the screen/serial line using YAMONs facilities. + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 2007 MIPS Technologies, Inc. + * written by Ralf Baechle */ #include <linux/init.h> -#include <linux/kernel.h> #include <linux/serial_reg.h> -#include <linux/spinlock.h> #include <asm/io.h> -#include <asm/system.h> static inline unsigned int serial_in(int offset) { @@ -34,41 +31,10 @@ static inline void serial_out(int offset, int value) outb(value, 0x3f8 + offset); } -int putPromChar(char c) +void __init prom_putchar(char c) { while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) ; serial_out(UART_TX, c); - - return 1; -} - -char getPromChar(void) -{ - while (!(serial_in(UART_LSR) & 1)) - ; - - return serial_in(UART_RX); -} - -void prom_printf(char *fmt, ...) -{ - va_list args; - int l; - char *p, *buf_end; - char buf[1024]; - - va_start(args, fmt); - l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */ - va_end(args); - - buf_end = buf + l; - - for (p = buf; p < buf_end; p++) { - /* Crude cr/nl handling is better than none */ - if (*p == '\n') - putPromChar('\r'); - putPromChar(*p); - } } diff --git a/arch/mips/mips-boards/sim/sim_mem.c b/arch/mips/mips-boards/sim/sim_mem.c index 46bc16f8b15..e408ef0bcd6 100644 --- a/arch/mips/mips-boards/sim/sim_mem.c +++ b/arch/mips/mips-boards/sim/sim_mem.c @@ -46,7 +46,7 @@ struct prom_pmemblock * __init prom_getmdesc(void) unsigned int memsize; memsize = 0x02000000; - prom_printf("Setting default memory size 0x%08x\n", memsize); + pr_info("Setting default memory size 0x%08x\n", memsize); memset(mdesc, 0, sizeof(mdesc)); diff --git a/arch/mips/mips-boards/sim/sim_setup.c b/arch/mips/mips-boards/sim/sim_setup.c index ea2066c3a1f..b705f09e57c 100644 --- a/arch/mips/mips-boards/sim/sim_setup.c +++ b/arch/mips/mips-boards/sim/sim_setup.c @@ -55,7 +55,7 @@ void __init plat_mem_setup(void) serial_init(); board_time_init = sim_time_init; - prom_printf("Linux started...\n"); + pr_info("Linux started...\n"); #ifdef CONFIG_MIPS_MT_SMP sanitize_tlb_entries(); @@ -66,7 +66,7 @@ void prom_init(void) { set_io_port_base(0xbfd00000); - prom_printf("\nLINUX started...\n"); + pr_info("\nLINUX started...\n"); prom_init_cmdline(); prom_meminit(); } @@ -91,7 +91,7 @@ static void __init serial_init(void) s.timeout = 4; if (early_serial_setup(&s) != 0) { - prom_printf(KERN_ERR "Serial setup failed!\n"); + printk(KERN_ERR "Serial setup failed!\n"); } #endif diff --git a/arch/mips/mips-boards/sim/sim_time.c b/arch/mips/mips-boards/sim/sim_time.c index 30711d016fe..d3a21c74151 100644 --- a/arch/mips/mips-boards/sim/sim_time.c +++ b/arch/mips/mips-boards/sim/sim_time.c @@ -199,7 +199,4 @@ void __init plat_timer_setup(struct irqaction *irq) irq_desc[mips_cpu_timer_irq].flags |= IRQ_PER_CPU; set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); #endif - - /* to generate the first timer interrupt */ - write_c0_compare(read_c0_count() + (mips_hpt_frequency/HZ)); } diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c index e19fbb9ee47..11a916629d3 100644 --- a/arch/mips/mm/cerr-sb1.c +++ b/arch/mips/mm/cerr-sb1.c @@ -77,66 +77,66 @@ static uint32_t extract_dc(unsigned short addr, int data); static inline void breakout_errctl(unsigned int val) { if (val & CP0_ERRCTL_RECOVERABLE) - prom_printf(" recoverable"); + printk(" recoverable"); if (val & CP0_ERRCTL_DCACHE) - prom_printf(" dcache"); + printk(" dcache"); if (val & CP0_ERRCTL_ICACHE) - prom_printf(" icache"); + printk(" icache"); if (val & CP0_ERRCTL_MULTIBUS) - prom_printf(" multiple-buserr"); - prom_printf("\n"); + printk(" multiple-buserr"); + printk("\n"); } static inline void breakout_cerri(unsigned int val) { if (val & CP0_CERRI_TAG_PARITY) - prom_printf(" tag-parity"); + printk(" tag-parity"); if (val & CP0_CERRI_DATA_PARITY) - prom_printf(" data-parity"); + printk(" data-parity"); if (val & CP0_CERRI_EXTERNAL) - prom_printf(" external"); - prom_printf("\n"); + printk(" external"); + printk("\n"); } static inline void breakout_cerrd(unsigned int val) { switch (val & CP0_CERRD_CAUSES) { case CP0_CERRD_LOAD: - prom_printf(" load,"); + printk(" load,"); break; case CP0_CERRD_STORE: - prom_printf(" store,"); + printk(" store,"); break; case CP0_CERRD_FILLWB: - prom_printf(" fill/wb,"); + printk(" fill/wb,"); break; case CP0_CERRD_COHERENCY: - prom_printf(" coherency,"); + printk(" coherency,"); break; case CP0_CERRD_DUPTAG: - prom_printf(" duptags,"); + printk(" duptags,"); break; default: - prom_printf(" NO CAUSE,"); + printk(" NO CAUSE,"); break; } if (!(val & CP0_CERRD_TYPES)) - prom_printf(" NO TYPE"); + printk(" NO TYPE"); else { if (val & CP0_CERRD_MULTIPLE) - prom_printf(" multi-err"); + printk(" multi-err"); if (val & CP0_CERRD_TAG_STATE) - prom_printf(" tag-state"); + printk(" tag-state"); if (val & CP0_CERRD_TAG_ADDRESS) - prom_printf(" tag-address"); + printk(" tag-address"); if (val & CP0_CERRD_DATA_SBE) - prom_printf(" data-SBE"); + printk(" data-SBE"); if (val & CP0_CERRD_DATA_DBE) - prom_printf(" data-DBE"); + printk(" data-DBE"); if (val & CP0_CERRD_EXTERNAL) - prom_printf(" external"); + printk(" external"); } - prom_printf("\n"); + printk("\n"); } #ifndef CONFIG_SIBYTE_BUS_WATCHER @@ -157,18 +157,18 @@ static void check_bus_watcher(void) l2_tag = in64(IO_SPACE_BASE | A_L2_ECC_TAG); #endif memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS)); - prom_printf("Bus watcher error counters: %08x %08x\n", l2_err, memio_err); - prom_printf("\nLast recorded signature:\n"); - prom_printf("Request %02x from %d, answered by %d with Dcode %d\n", + printk("Bus watcher error counters: %08x %08x\n", l2_err, memio_err); + printk("\nLast recorded signature:\n"); + printk("Request %02x from %d, answered by %d with Dcode %d\n", (unsigned int)(G_SCD_BERR_TID(status) & 0x3f), (int)(G_SCD_BERR_TID(status) >> 6), (int)G_SCD_BERR_RID(status), (int)G_SCD_BERR_DCODE(status)); #ifdef DUMP_L2_ECC_TAG_ON_ERROR - prom_printf("Last L2 tag w/ bad ECC: %016llx\n", l2_tag); + printk("Last L2 tag w/ bad ECC: %016llx\n", l2_tag); #endif } else { - prom_printf("Bus watcher indicates no error\n"); + printk("Bus watcher indicates no error\n"); } } #else @@ -187,11 +187,11 @@ asmlinkage void sb1_cache_error(void) #else csr_out32(M_SCD_TRACE_CFG_FREEZE, IO_SPACE_BASE | A_SCD_TRACE_CFG); #endif - prom_printf("Trace buffer frozen\n"); + printk("Trace buffer frozen\n"); #endif - prom_printf("Cache error exception on CPU %x:\n", - (read_c0_prid() >> 25) & 0x7); + printk("Cache error exception on CPU %x:\n", + (read_c0_prid() >> 25) & 0x7); __asm__ __volatile__ ( " .set push\n\t" @@ -209,43 +209,43 @@ asmlinkage void sb1_cache_error(void) "=r" (dpahi), "=r" (dpalo), "=r" (eepc)); cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo; - prom_printf(" c0_errorepc == %08x\n", eepc); - prom_printf(" c0_errctl == %08x", errctl); + printk(" c0_errorepc == %08x\n", eepc); + printk(" c0_errctl == %08x", errctl); breakout_errctl(errctl); if (errctl & CP0_ERRCTL_ICACHE) { - prom_printf(" c0_cerr_i == %08x", cerr_i); + printk(" c0_cerr_i == %08x", cerr_i); breakout_cerri(cerr_i); if (CP0_CERRI_IDX_VALID(cerr_i)) { /* Check index of EPC, allowing for delay slot */ if (((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) && ((eepc & SB1_CACHE_INDEX_MASK) != ((cerr_i & SB1_CACHE_INDEX_MASK) - 4))) - prom_printf(" cerr_i idx doesn't match eepc\n"); + printk(" cerr_i idx doesn't match eepc\n"); else { res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK, (cerr_i & CP0_CERRI_DATA) != 0); if (!(res & cerr_i)) - prom_printf("...didn't see indicated icache problem\n"); + printk("...didn't see indicated icache problem\n"); } } } if (errctl & CP0_ERRCTL_DCACHE) { - prom_printf(" c0_cerr_d == %08x", cerr_d); + printk(" c0_cerr_d == %08x", cerr_d); breakout_cerrd(cerr_d); if (CP0_CERRD_DPA_VALID(cerr_d)) { - prom_printf(" c0_cerr_dpa == %010llx\n", cerr_dpa); + printk(" c0_cerr_dpa == %010llx\n", cerr_dpa); if (!CP0_CERRD_IDX_VALID(cerr_d)) { res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK, (cerr_d & CP0_CERRD_DATA) != 0); if (!(res & cerr_d)) - prom_printf("...didn't see indicated dcache problem\n"); + printk("...didn't see indicated dcache problem\n"); } else { if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK)) - prom_printf(" cerr_d idx doesn't match cerr_dpa\n"); + printk(" cerr_d idx doesn't match cerr_dpa\n"); else { res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK, (cerr_d & CP0_CERRD_DATA) != 0); if (!(res & cerr_d)) - prom_printf("...didn't see indicated problem\n"); + printk("...didn't see indicated problem\n"); } } } @@ -334,7 +334,7 @@ static uint32_t extract_ic(unsigned short addr, int data) uint8_t lru; int res = 0; - prom_printf("Icache index 0x%04x ", addr); + printk("Icache index 0x%04x ", addr); for (way = 0; way < 4; way++) { /* Index-load-tag-I */ __asm__ __volatile__ ( @@ -354,7 +354,7 @@ static uint32_t extract_ic(unsigned short addr, int data) taglo = ((unsigned long long)taglohi << 32) | taglolo; if (way == 0) { lru = (taghi >> 14) & 0xff; - prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", + printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", ((addr >> 5) & 0x3), /* bank */ ((addr >> 7) & 0x3f), /* index */ (lru & 0x3), @@ -369,19 +369,19 @@ static uint32_t extract_ic(unsigned short addr, int data) if (valid) { tlo_tmp = taglo & 0xfff3ff; if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) { - prom_printf(" ** bad parity in VTag0/G/ASID\n"); + printk(" ** bad parity in VTag0/G/ASID\n"); res |= CP0_CERRI_TAG_PARITY; } if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) { - prom_printf(" ** bad parity in R/VTag1\n"); + printk(" ** bad parity in R/VTag1\n"); res |= CP0_CERRI_TAG_PARITY; } } if (valid ^ ((taghi >> 27) & 1)) { - prom_printf(" ** bad parity for valid bit\n"); + printk(" ** bad parity for valid bit\n"); res |= CP0_CERRI_TAG_PARITY; } - prom_printf(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n", + printk(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n", way, va, valid, taghi, taglo); if (data) { @@ -407,21 +407,21 @@ static uint32_t extract_ic(unsigned short addr, int data) : "r" ((way << 13) | addr | (offset << 3))); predecode = (datahi >> 8) & 0xff; if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) { - prom_printf(" ** bad parity in predecode\n"); + printk(" ** bad parity in predecode\n"); res |= CP0_CERRI_DATA_PARITY; } /* XXXKW should/could check predecode bits themselves */ if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) { - prom_printf(" ** bad parity in instruction a\n"); + printk(" ** bad parity in instruction a\n"); res |= CP0_CERRI_DATA_PARITY; } if ((datahi & 0xf) ^ inst_parity(instb)) { - prom_printf(" ** bad parity in instruction b\n"); + printk(" ** bad parity in instruction b\n"); res |= CP0_CERRI_DATA_PARITY; } - prom_printf(" %05X-%08X%08X", datahi, insta, instb); + printk(" %05X-%08X%08X", datahi, insta, instb); } - prom_printf("\n"); + printk("\n"); } } return res; @@ -489,7 +489,7 @@ static uint32_t extract_dc(unsigned short addr, int data) uint8_t ecc, lru; int res = 0; - prom_printf("Dcache index 0x%04x ", addr); + printk("Dcache index 0x%04x ", addr); for (way = 0; way < 4; way++) { __asm__ __volatile__ ( " .set push\n\t" @@ -509,7 +509,7 @@ static uint32_t extract_dc(unsigned short addr, int data) pa = (taglo & 0xFFFFFFE000ULL) | addr; if (way == 0) { lru = (taghi >> 14) & 0xff; - prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", + printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n", ((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */ ((addr >> 6) & 0x3f), /* index */ (lru & 0x3), @@ -519,15 +519,15 @@ static uint32_t extract_dc(unsigned short addr, int data) } state = (taghi >> 25) & 0x1f; valid = DC_TAG_VALID(state); - prom_printf(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n", + printk(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n", way, pa, dc_state_str(state), state, taghi, taglo); if (valid) { if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) { - prom_printf(" ** bad parity in PTag1\n"); + printk(" ** bad parity in PTag1\n"); res |= CP0_CERRD_TAG_ADDRESS; } if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) { - prom_printf(" ** bad parity in PTag0\n"); + printk(" ** bad parity in PTag0\n"); res |= CP0_CERRD_TAG_ADDRESS; } } else { @@ -567,13 +567,13 @@ static uint32_t extract_dc(unsigned short addr, int data) } res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE; } - prom_printf(" %02X-%016llX", datahi, datalo); + printk(" %02X-%016llX", datahi, datalo); } - prom_printf("\n"); + printk("\n"); if (bad_ecc) - prom_printf(" dwords w/ bad ECC: %d %d %d %d\n", - !!(bad_ecc & 8), !!(bad_ecc & 4), - !!(bad_ecc & 2), !!(bad_ecc & 1)); + printk(" dwords w/ bad ECC: %d %d %d %d\n", + !!(bad_ecc & 8), !!(bad_ecc & 4), + !!(bad_ecc & 2), !!(bad_ecc & 1)); } } return res; diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index a72093ad105..f503d02e403 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -295,7 +295,7 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, /* Make sure that gcc doesn't leave the empty loop body. */ for (i = 0; i < nelems; i++, sg++) { - if (!plat_device_is_coherent(dev)) + if (cpu_is_noncoherent_r10000(dev)) __dma_sync((unsigned long)page_address(sg->page), sg->length, direction); plat_unmap_dma_mem(sg->dma_address); diff --git a/arch/mips/momentum/jaguar_atx/ja-console.c b/arch/mips/momentum/jaguar_atx/ja-console.c index 2292d0ec47f..2c30b4f5624 100644 --- a/arch/mips/momentum/jaguar_atx/ja-console.c +++ b/arch/mips/momentum/jaguar_atx/ja-console.c @@ -74,11 +74,6 @@ void prom_putchar(char c) uart->iu_thr = c; } -char __init prom_getchar(void) -{ - return 0; -} - static void inline ja_console_probe(void) { struct uart_port up; diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 455d76ad06d..9d08608aaa5 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -223,10 +223,12 @@ static inline int n_counters(void) switch (current_cpu_data.cputype) { case CPU_R10000: counters = 2; + break; case CPU_R12000: case CPU_R14000: counters = 4; + break; default: counters = __n_counters(); diff --git a/arch/mips/pci/fixup-jmr3927.c b/arch/mips/pci/fixup-jmr3927.c index f8696081c5b..6e72d213f4c 100644 --- a/arch/mips/pci/fixup-jmr3927.c +++ b/arch/mips/pci/fixup-jmr3927.c @@ -38,6 +38,10 @@ int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { unsigned char irq = pin; + /* SMSC SLC90E66 IDE uses irq 14, 15 (default) */ + if (dev->vendor == PCI_VENDOR_ID_EFAR && + dev->device == PCI_DEVICE_ID_EFAR_SLC90E66_1) + return irq; /* IRQ rotation (PICMG) */ irq--; /* 0-3 */ if (dev->bus->parent == NULL && @@ -93,13 +97,3 @@ int pcibios_plat_dev_init(struct pci_dev *dev) { return 0; } - -int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - /* SMSC SLC90E66 IDE uses irq 14, 15 (default) */ - if (!(dev->vendor == PCI_VENDOR_ID_EFAR && - dev->device == PCI_DEVICE_ID_EFAR_SLC90E66_1)) - return pci_get_irq(dev, pin); - - dev->irq = irq; -} diff --git a/arch/mips/pci/fixup-sni.c b/arch/mips/pci/fixup-sni.c index 0c9a4732d45..36e5fb1b378 100644 --- a/arch/mips/pci/fixup-sni.c +++ b/arch/mips/pci/fixup-sni.c @@ -14,6 +14,8 @@ #include <asm/mipsregs.h> #include <asm/sni.h> +#include <irq.h> + /* * PCIMT Shortcuts ... */ diff --git a/arch/mips/pci/ops-au1000.c b/arch/mips/pci/ops-au1000.c index 8ae46481fcb..7932dfe5eb9 100644 --- a/arch/mips/pci/ops-au1000.c +++ b/arch/mips/pci/ops-au1000.c @@ -172,7 +172,11 @@ static int config_access(unsigned char access_type, struct pci_bus *bus, error = -1; DBG("Au1x Master Abort\n"); } else if ((status >> 28) & 0xf) { - DBG("PCI ERR detected: status %x\n", status); + DBG("PCI ERR detected: device %d, status %x\n", device, ((status >> 28) & 0xf)); + + /* clear errors */ + au_writel(status & 0xf000ffff, Au1500_PCI_STATCMD); + *data = 0xffffffff; error = -1; } diff --git a/arch/mips/philips/pnx8550/common/prom.c b/arch/mips/philips/pnx8550/common/prom.c index 8aeed6c2b8c..2f567452e7a 100644 --- a/arch/mips/philips/pnx8550/common/prom.c +++ b/arch/mips/philips/pnx8550/common/prom.c @@ -112,7 +112,7 @@ void __init prom_free_prom_memory(void) extern int pnx8550_console_port; -/* used by prom_printf */ +/* used by early printk */ void prom_putchar(char c) { if (pnx8550_console_port != -1) { diff --git a/arch/mips/philips/pnx8550/common/setup.c b/arch/mips/philips/pnx8550/common/setup.c index e62123ca9b6..5bd73747768 100644 --- a/arch/mips/philips/pnx8550/common/setup.c +++ b/arch/mips/philips/pnx8550/common/setup.c @@ -41,8 +41,6 @@ #include <uart.h> #include <nand.h> -extern void prom_printf(char *fmt, ...); - extern void __init board_setup(void); extern void pnx8550_machine_restart(char *); extern void pnx8550_machine_halt(void); @@ -51,7 +49,6 @@ extern struct resource ioport_resource; extern struct resource iomem_resource; extern void pnx8550_time_init(void); extern void rs_kgdb_hook(int tty_no); -extern void prom_printf(char *fmt, ...); extern char *prom_getcmdline(void); struct resource standard_io_resources[] = { @@ -141,7 +138,7 @@ void __init plat_mem_setup(void) argptr += strlen("console=ttyS"); pnx8550_console_port = *argptr == '0' ? 0 : 1; - /* We must initialize the UART (console) before prom_printf */ + /* We must initialize the UART (console) before early printk */ /* Set LCR to 8-bit and BAUD to 38400 (no 5) */ ip3106_lcr(UART_BASE, pnx8550_console_port) = PNX8XXX_UART_LCR_8BIT; @@ -155,8 +152,8 @@ void __init plat_mem_setup(void) argptr += strlen("kgdb=ttyS"); line = *argptr == '0' ? 0 : 1; rs_kgdb_hook(line); - prom_printf("KGDB: Using ttyS%i for session, " - "please connect your debugger\n", line ? 1 : 0); + pr_info("KGDB: Using ttyS%i for session, " + "please connect your debugger\n", line ? 1 : 0); } #endif return; diff --git a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c index 757e605693f..b7f1d9c4a8a 100644 --- a/arch/mips/pmc-sierra/yosemite/py-console.c +++ b/arch/mips/pmc-sierra/yosemite/py-console.c @@ -107,8 +107,3 @@ void prom_putchar(char c) while ((readb_outer_space(lsr) & 0x20) == 0); writeb_outer_space(thr, c); } - -char __init prom_getchar(void) -{ - return 0; -} diff --git a/arch/mips/sgi-ip27/ip27-console.c b/arch/mips/sgi-ip27/ip27-console.c index 14211e38237..3ba830651c5 100644 --- a/arch/mips/sgi-ip27/ip27-console.c +++ b/arch/mips/sgi-ip27/ip27-console.c @@ -6,12 +6,6 @@ * Copyright (C) 2001, 2002 Ralf Baechle */ #include <linux/init.h> -#include <linux/console.h> -#include <linux/kdev_t.h> -#include <linux/major.h> -#include <linux/termios.h> -#include <linux/sched.h> -#include <linux/tty.h> #include <asm/page.h> #include <asm/semaphore.h> @@ -38,37 +32,10 @@ static inline struct ioc3_uartregs *console_uart(void) return &ioc3->sregs.uarta; } -void prom_putchar(char c) +void __init prom_putchar(char c) { struct ioc3_uartregs *uart = console_uart(); while ((uart->iu_lsr & 0x20) == 0); uart->iu_thr = c; } - -static void ioc3_console_write(struct console *con, const char *s, unsigned n) -{ - while (n-- && *s) { - if (*s == '\n') - prom_putchar('\r'); - prom_putchar(*s); - s++; - } -} - -static struct console ioc3_console = { - .name = "ioc3", - .write = ioc3_console_write, - .flags = CON_PRINTBUFFER | CON_BOOT, - .index = -1 -}; - -__init void ip27_setup_console(void) -{ - register_console(&ioc3_console); -} - -void __init disable_early_printk(void) -{ - unregister_console(&ioc3_console); -} diff --git a/arch/mips/sibyte/Kconfig b/arch/mips/sibyte/Kconfig index ec7a2cffacf..67dac6204b6 100644 --- a/arch/mips/sibyte/Kconfig +++ b/arch/mips/sibyte/Kconfig @@ -116,6 +116,7 @@ config SB1_CERR_STALL config SIBYTE_CFE bool "Booting from CFE" depends on SIBYTE_SB1xxx_SOC + select SYS_HAS_EARLY_PRINTK help Make use of the CFE API for enumerating available memory, controlling secondary CPUs, and possibly console output. @@ -131,6 +132,7 @@ config SIBYTE_CFE_CONSOLE config SIBYTE_STANDALONE bool depends on SIBYTE_SB1xxx_SOC && !SIBYTE_CFE + select SYS_HAS_EARLY_PRINTK default y config SIBYTE_STANDALONE_RAM_SIZE diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index 1dc5d05d896..20af0f1bb7b 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c @@ -420,7 +420,7 @@ void __init arch_init_irq(void) #ifdef CONFIG_GDB_CONSOLE register_gdb_console(); #endif - prom_printf("Waiting for GDB on UART port %d\n", kgdb_port); + printk("Waiting for GDB on UART port %d\n", kgdb_port); set_debug_traps(); breakpoint(); } diff --git a/arch/mips/sibyte/bcm1480/setup.c b/arch/mips/sibyte/bcm1480/setup.c index 8236d0c4854..bdaac34ae70 100644 --- a/arch/mips/sibyte/bcm1480/setup.c +++ b/arch/mips/sibyte/bcm1480/setup.c @@ -69,7 +69,7 @@ static inline int sys_rev_decode(void) break; default: - prom_printf("Unknown part type %x\n", part_type); + printk("Unknown part type %x\n", part_type); ret = 1; break; } @@ -102,7 +102,7 @@ static inline int setup_bcm1x80_bcm1x55(void) pass_str = "B0 (pass2)"; break; default: - prom_printf("Unknown %s rev %x\n", soc_str, soc_pass); + printk("Unknown %s rev %x\n", soc_str, soc_pass); periph_rev = 1; pass_str = "Unknown Revision"; break; @@ -122,14 +122,14 @@ void bcm1480_setup(void) soc_pass = G_SYS_REVISION(sys_rev); if (sys_rev_decode()) { - prom_printf("Restart after failure to identify SiByte chip\n"); + printk("Restart after failure to identify SiByte chip\n"); machine_restart(NULL); } plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG))); zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25); - prom_printf("Broadcom SiByte %s %s @ %d MHz (SB-1A rev %d)\n", + printk("Broadcom SiByte %s %s @ %d MHz (SB-1A rev %d)\n", soc_str, pass_str, zbbus_mhz * 2, sb1_pass); - prom_printf("Board type: %s\n", get_system_type()); + printk("Board type: %s\n", get_system_type()); } diff --git a/arch/mips/sibyte/cfe/setup.c b/arch/mips/sibyte/cfe/setup.c index 9e6099e6962..ae4a92c3e52 100644 --- a/arch/mips/sibyte/cfe/setup.c +++ b/arch/mips/sibyte/cfe/setup.c @@ -221,10 +221,10 @@ static int __init initrd_setup(char *str) goto fail; } initrd_end = initrd_start + initrd_size; - prom_printf("Found initrd of %lx@%lx\n", initrd_size, initrd_start); + printk("Found initrd of %lx@%lx\n", initrd_size, initrd_start); return 1; fail: - prom_printf("Bad initrd argument. Disabling initrd\n"); + printk("Bad initrd argument. Disabling initrd\n"); initrd_start = 0; initrd_end = 0; return 1; @@ -281,7 +281,7 @@ void __init prom_init(void) } if (cfe_eptseal != CFE_EPTSEAL) { /* too early for panic to do any good */ - prom_printf("CFE's entrypoint seal doesn't match. Spinning."); + printk("CFE's entrypoint seal doesn't match. Spinning."); while (1) ; } cfe_init(cfe_handle, cfe_ept); @@ -303,7 +303,7 @@ void __init prom_init(void) } else { /* The loader should have set the command line */ /* too early for panic to do any good */ - prom_printf("LINUX_CMDLINE not defined in cfe."); + printk("LINUX_CMDLINE not defined in cfe."); while (1) ; } } diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c index d0ee1d5b822..1cb042eab72 100644 --- a/arch/mips/sibyte/sb1250/setup.c +++ b/arch/mips/sibyte/sb1250/setup.c @@ -67,7 +67,7 @@ static int __init sys_rev_decode(void) ret = setup_bcm112x(); break; default: - prom_printf("Unknown SOC type %x\n", soc_type); + printk("Unknown SOC type %x\n", soc_type); ret = 1; break; } @@ -112,7 +112,7 @@ static int __init setup_bcm1250(void) pass_str = "A0-A6"; war_pass = K_SYS_REVISION_BCM1250_PASS2; } else { - prom_printf("Unknown BCM1250 rev %x\n", soc_pass); + printk("Unknown BCM1250 rev %x\n", soc_pass); ret = 1; } break; @@ -140,7 +140,7 @@ static int __init setup_bcm112x(void) pass_str = "A2"; break; default: - prom_printf("Unknown %s rev %x\n", soc_str, soc_pass); + printk("Unknown %s rev %x\n", soc_str, soc_pass); ret = 1; } return ret; @@ -158,21 +158,21 @@ void __init sb1250_setup(void) soc_pass = G_SYS_REVISION(sys_rev); if (sys_rev_decode()) { - prom_printf("Restart after failure to identify SiByte chip\n"); + printk("Restart after failure to identify SiByte chip\n"); machine_restart(NULL); } plldiv = G_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG))); zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25); - prom_printf("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n", + printk("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n", soc_str, pass_str, zbbus_mhz * 2, sb1_pass); - prom_printf("Board type: %s\n", get_system_type()); + printk("Board type: %s\n", get_system_type()); switch (war_pass) { case K_SYS_REVISION_BCM1250_PASS1: #ifndef CONFIG_SB1_PASS_1_WORKAROUNDS - prom_printf("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, " + printk("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, " "and the kernel doesn't have the proper " "workarounds compiled in. @@@@\n"); bad_config = 1; @@ -182,27 +182,27 @@ void __init sb1250_setup(void) /* Pass 2 - easiest as default for now - so many numbers */ #if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || \ !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) - prom_printf("@@@@ This is a BCM1250 A3-A10 board, and the " + printk("@@@@ This is a BCM1250 A3-A10 board, and the " "kernel doesn't have the proper workarounds " "compiled in. @@@@\n"); bad_config = 1; #endif #ifdef CONFIG_CPU_HAS_PREFETCH - prom_printf("@@@@ Prefetches may be enabled in this kernel, " + printk("@@@@ Prefetches may be enabled in this kernel, " "but are buggy on this board. @@@@\n"); bad_config = 1; #endif break; case K_SYS_REVISION_BCM1250_PASS2_2: #ifndef CONFIG_SB1_PASS_2_WORKAROUNDS - prom_printf("@@@@ This is a BCM1250 B1/B2. board, and the " + printk("@@@@ This is a BCM1250 B1/B2. board, and the " "kernel doesn't have the proper workarounds " "compiled in. @@@@\n"); bad_config = 1; #endif #if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || \ !defined(CONFIG_CPU_HAS_PREFETCH) - prom_printf("@@@@ This is a BCM1250 B1/B2, but the kernel is " + printk("@@@@ This is a BCM1250 B1/B2, but the kernel is " "conservatively configured for an 'A' stepping. " "@@@@\n"); #endif @@ -211,7 +211,7 @@ void __init sb1250_setup(void) break; } if (bad_config) { - prom_printf("Invalid configuration for this chip.\n"); + printk("Invalid configuration for this chip.\n"); machine_restart(NULL); } } diff --git a/arch/mips/sni/sniprom.c b/arch/mips/sni/sniprom.c index 6a44bbf0b73..643366eb854 100644 --- a/arch/mips/sni/sniprom.c +++ b/arch/mips/sni/sniprom.c @@ -9,6 +9,8 @@ * Copyright (C) 2005-2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de) */ +#define DEBUG + #include <linux/kernel.h> #include <linux/init.h> #include <linux/string.h> @@ -32,14 +34,13 @@ #define PROM_ENTRY(x) (PROM_VEC + (x)) -#define DEBUG -#ifdef DEBUG -#define DBG_PRINTF(x...) prom_printf(x) -#else -#define DBG_PRINTF(x...) -#endif - static int *(*__prom_putchar)(int) = (int *(*)(int))PROM_ENTRY(PROM_PUTCHAR); + +void prom_putchar(char c) +{ + __prom_putchar(c); +} + static char *(*__prom_getenv)(char *) = (char *(*)(char *))PROM_ENTRY(PROM_GETENV); static void (*__prom_get_memconf)(void *) = (void (*)(void *))PROM_ENTRY(PROM_GET_MEMCONF); @@ -48,26 +49,6 @@ char *prom_getenv (char *s) return __prom_getenv(s); } -void prom_printf(char *fmt, ...) -{ - va_list args; - char ppbuf[1024]; - char *bptr; - - va_start(args, fmt); - vsprintf(ppbuf, fmt, args); - - bptr = ppbuf; - - while (*bptr != 0) { - if (*bptr == '\n') - __prom_putchar('\r'); - - __prom_putchar(*bptr++); - } - va_end(args); -} - void __init prom_free_prom_memory(void) { } @@ -94,15 +75,15 @@ static void sni_idprom_dump(void) { int i; - prom_printf("SNI IDProm dump:\n"); + pr_debug("SNI IDProm dump:\n"); for (i = 0; i < 256; i++) { if (i%16 == 0) - prom_printf("%04x ", i); + pr_debug("%04x ", i); - prom_printf("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i)); + printk("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i)); if (i % 16 == 15) - prom_printf("\n"); + printk("\n"); } } #endif @@ -121,12 +102,12 @@ static void sni_mem_init(void ) /* MemSIZE from prom in 16MByte chunks */ memsize = *((unsigned char *) SNI_IDPROM_MEMSIZE) * 16; - DBG_PRINTF("IDProm memsize: %lu MByte\n", memsize); + pr_debug("IDProm memsize: %lu MByte\n", memsize); /* get memory bank layout from prom */ __prom_get_memconf(&memconf); - DBG_PRINTF("prom_get_mem_conf memory configuration:\n"); + pr_debug("prom_get_mem_conf memory configuration:\n"); for (i = 0;i < 8 && memconf[i].size; i++) { if (sni_brd_type == SNI_BRD_PCI_TOWER || sni_brd_type == SNI_BRD_PCI_TOWER_CPLUS) { @@ -135,7 +116,7 @@ static void sni_mem_init(void ) memconf[i].base -= 0x20000000; } } - DBG_PRINTF("Bank%d: %08x @ %08x\n", i, + pr_debug("Bank%d: %08x @ %08x\n", i, memconf[i].size, memconf[i].base); add_memory_region(memconf[i].base, memconf[i].size, BOOT_MEM_RAM); } @@ -248,7 +229,7 @@ void __init prom_init(void) systype = "RM300-Exx"; break; } - DBG_PRINTF("Found SNI brdtype %02x name %s\n", sni_brd_type,systype); + pr_debug("Found SNI brdtype %02x name %s\n", sni_brd_type,systype); #ifdef DEBUG sni_idprom_dump(); diff --git a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c index 941c441729b..c8e49feb345 100644 --- a/arch/mips/tx4927/common/tx4927_setup.c +++ b/arch/mips/tx4927/common/tx4927_setup.c @@ -81,18 +81,8 @@ void __init tx4927_time_init(void) void __init plat_timer_setup(struct irqaction *irq) { - u32 count; - u32 c1; - u32 c2; - setup_irq(TX4927_IRQ_CPU_TIMER, irq); - /* to generate the first timer interrupt */ - c1 = read_c0_count(); - count = c1 + (mips_hpt_frequency / HZ); - write_c0_compare(count); - c2 = read_c0_count(); - #ifdef CONFIG_TOSHIBA_RBTX4927 { extern void toshiba_rbtx4927_timer_setup(struct irqaction diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c index dcce88f403c..5cc30c10e74 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c @@ -132,9 +132,6 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB #include <asm/wbflush.h> #include <linux/bootmem.h> #include <linux/blkdev.h> -#ifdef CONFIG_RTC_DS1742 -#include <linux/ds1742rtc.h> -#endif #ifdef CONFIG_TOSHIBA_FPCIB0 #include <asm/tx4927/smsc_fdc37m81x.h> #endif diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c index 7316a78fdd6..0f7576dfd14 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c @@ -53,6 +53,7 @@ #include <linux/pci.h> #include <linux/timex.h> #include <linux/pm.h> +#include <linux/platform_device.h> #include <asm/bootinfo.h> #include <asm/page.h> @@ -64,9 +65,6 @@ #include <asm/time.h> #include <linux/bootmem.h> #include <linux/blkdev.h> -#ifdef CONFIG_RTC_DS1742 -#include <linux/ds1742rtc.h> -#endif #ifdef CONFIG_TOSHIBA_FPCIB0 #include <asm/tx4927/smsc_fdc37m81x.h> #endif @@ -1020,69 +1018,12 @@ void __init toshiba_rbtx4927_setup(void) "+\n"); } -#ifdef CONFIG_RTC_DS1742 -extern unsigned long rtc_ds1742_get_time(void); -extern int rtc_ds1742_set_time(unsigned long); -extern void rtc_ds1742_wait(void); -#endif - void __init toshiba_rbtx4927_time_init(void) { - u32 c1; - u32 c2; - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "-\n"); -#ifdef CONFIG_RTC_DS1742 - - rtc_mips_get_time = rtc_ds1742_get_time; - rtc_mips_set_time = rtc_ds1742_set_time; - - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, - ":rtc_ds1742_init()-\n"); - rtc_ds1742_init(0xbc010000); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, - ":rtc_ds1742_init()+\n"); - - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, - ":Calibrate mips_hpt_frequency-\n"); - rtc_ds1742_wait(); - - /* get the count */ - c1 = read_c0_count(); - - /* wait for the seconds to change again */ - rtc_ds1742_wait(); - - /* get the count again */ - c2 = read_c0_count(); - - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, - ":Calibrate mips_hpt_frequency+\n"); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, - ":c1=%12u\n", c1); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, - ":c2=%12u\n", c2); - - /* this diff is as close as we are going to get to counter ticks per sec */ - mips_hpt_frequency = abs(c2 - c1); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, - ":f1=%12u\n", mips_hpt_frequency); - - /* round to 1/10th of a MHz */ - mips_hpt_frequency /= (100 * 1000); - mips_hpt_frequency *= (100 * 1000); - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, - ":f2=%12u\n", mips_hpt_frequency); - - TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_INFO, - ":mips_hpt_frequency=%uHz (%uMHz)\n", - mips_hpt_frequency, - mips_hpt_frequency / 1000000); -#else - mips_hpt_frequency = 100000000; -#endif + mips_hpt_frequency = tx4927_cpu_clock / 2; TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "+\n"); @@ -1095,3 +1036,16 @@ void __init toshiba_rbtx4927_timer_setup(struct irqaction *irq) TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP, "+\n"); } + +static int __init toshiba_rbtx4927_rtc_init(void) +{ + struct resource res = { + .start = 0x1c010000, + .end = 0x1c010000 + 0x800 - 1, + .flags = IORESOURCE_MEM, + }; + struct platform_device *dev = + platform_device_register_simple("ds1742", -1, &res, 1); + return IS_ERR(dev) ? PTR_ERR(dev) : 0; +} +device_initcall(toshiba_rbtx4927_rtc_init); diff --git a/arch/mips/tx4938/common/setup.c b/arch/mips/tx4938/common/setup.c index dc87d92bb08..142abf453e4 100644 --- a/arch/mips/tx4938/common/setup.c +++ b/arch/mips/tx4938/common/setup.c @@ -55,14 +55,5 @@ tx4938_time_init(void) void __init plat_timer_setup(struct irqaction *irq) { - u32 count; - u32 c1; - u32 c2; - setup_irq(TX4938_IRQ_CPU_TIMER, irq); - - c1 = read_c0_count(); - count = c1 + (mips_hpt_frequency / HZ); - write_c0_compare(count); - c2 = read_c0_count(); } diff --git a/drivers/acorn/char/Makefile b/drivers/acorn/char/Makefile index 2fa9a8bf48a..d006c9f168d 100644 --- a/drivers/acorn/char/Makefile +++ b/drivers/acorn/char/Makefile @@ -2,5 +2,4 @@ # Makefile for the acorn character device drivers. # -obj-$(CONFIG_ARCH_ACORN) += i2c.o pcf8583.o obj-$(CONFIG_L7200_KEYB) += defkeymap-l7200.o keyb_l7200.o diff --git a/drivers/acorn/char/i2c.c b/drivers/acorn/char/i2c.c deleted file mode 100644 index d276fd14d63..00000000000 --- a/drivers/acorn/char/i2c.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * linux/drivers/acorn/char/i2c.c - * - * Copyright (C) 2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * ARM IOC/IOMD i2c driver. - * - * On Acorn machines, the following i2c devices are on the bus: - * - PCF8583 real time clock & static RAM - */ -#include <linux/capability.h> -#include <linux/init.h> -#include <linux/time.h> -#include <linux/miscdevice.h> -#include <linux/rtc.h> -#include <linux/i2c.h> -#include <linux/i2c-algo-bit.h> -#include <linux/fs.h> - -#include <asm/hardware.h> -#include <asm/io.h> -#include <asm/hardware/ioc.h> -#include <asm/system.h> -#include <asm/uaccess.h> - -#include "pcf8583.h" - -extern int (*set_rtc)(void); - -static struct i2c_client *rtc_client; -static const unsigned char days_in_mon[] = - { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - -#define CMOS_CHECKSUM (63) - -/* - * Acorn machines store the year in the static RAM at - * location 128. - */ -#define CMOS_YEAR (64 + 128) - -static inline int rtc_command(int cmd, void *data) -{ - int ret = -EIO; - - if (rtc_client) - ret = rtc_client->driver->command(rtc_client, cmd, data); - - return ret; -} - -/* - * Update the century + year bytes in the CMOS RAM, ensuring - * that the check byte is correctly adjusted for the change. - */ -static int rtc_update_year(unsigned int new_year) -{ - unsigned char yr[2], chk; - struct mem cmos_year = { CMOS_YEAR, sizeof(yr), yr }; - struct mem cmos_check = { CMOS_CHECKSUM, 1, &chk }; - int ret; - - ret = rtc_command(MEM_READ, &cmos_check); - if (ret) - goto out; - ret = rtc_command(MEM_READ, &cmos_year); - if (ret) - goto out; - - chk -= yr[1] + yr[0]; - - yr[1] = new_year / 100; - yr[0] = new_year % 100; - - chk += yr[1] + yr[0]; - - ret = rtc_command(MEM_WRITE, &cmos_year); - if (ret == 0) - ret = rtc_command(MEM_WRITE, &cmos_check); - out: - return ret; -} - -/* - * Read the current RTC time and date, and update xtime. - */ -static void get_rtc_time(struct rtc_tm *rtctm, unsigned int *year) -{ - unsigned char ctrl, yr[2]; - struct mem rtcmem = { CMOS_YEAR, sizeof(yr), yr }; - int real_year, year_offset; - - /* - * Ensure that the RTC is running. - */ - rtc_command(RTC_GETCTRL, &ctrl); - if (ctrl & 0xc0) { - unsigned char new_ctrl = ctrl & ~0xc0; - - printk(KERN_WARNING "RTC: resetting control %02x -> %02x\n", - ctrl, new_ctrl); - - rtc_command(RTC_SETCTRL, &new_ctrl); - } - - if (rtc_command(RTC_GETDATETIME, rtctm) || - rtc_command(MEM_READ, &rtcmem)) - return; - - real_year = yr[0]; - - /* - * The RTC year holds the LSB two bits of the current - * year, which should reflect the LSB two bits of the - * CMOS copy of the year. Any difference indicates - * that we have to correct the CMOS version. - */ - year_offset = rtctm->year_off - (real_year & 3); - if (year_offset < 0) - /* - * RTC year wrapped. Adjust it appropriately. - */ - year_offset += 4; - - *year = real_year + year_offset + yr[1] * 100; -} - -static int set_rtc_time(struct rtc_tm *rtctm, unsigned int year) -{ - unsigned char leap; - int ret; - - leap = (!(year % 4) && (year % 100)) || !(year % 400); - - if (rtctm->mon > 12 || rtctm->mon == 0 || rtctm->mday == 0) - return -EINVAL; - - if (rtctm->mday > (days_in_mon[rtctm->mon] + (rtctm->mon == 2 && leap))) - return -EINVAL; - - if (rtctm->hours >= 24 || rtctm->mins >= 60 || rtctm->secs >= 60) - return -EINVAL; - - /* - * The RTC's own 2-bit year must reflect the least - * significant two bits of the CMOS year. - */ - rtctm->year_off = (year % 100) & 3; - - ret = rtc_command(RTC_SETDATETIME, rtctm); - if (ret == 0) - ret = rtc_update_year(year); - - return ret; -} - -/* - * Set the RTC time only. Note that - * we do not touch the date. - */ -static int k_set_rtc_time(void) -{ - struct rtc_tm new_rtctm, old_rtctm; - unsigned long nowtime = xtime.tv_sec; - - if (rtc_command(RTC_GETDATETIME, &old_rtctm)) - return 0; - - new_rtctm.cs = xtime.tv_nsec / 10000000; - new_rtctm.secs = nowtime % 60; nowtime /= 60; - new_rtctm.mins = nowtime % 60; nowtime /= 60; - new_rtctm.hours = nowtime % 24; - - /* - * avoid writing when we're going to change the day - * of the month. We will retry in the next minute. - * This basically means that if the RTC must not drift - * by more than 1 minute in 11 minutes. - * - * [ rtc: 1/1/2000 23:58:00, real 2/1/2000 00:01:00, - * rtc gets set to 1/1/2000 00:01:00 ] - */ - if ((old_rtctm.hours == 23 && old_rtctm.mins == 59) || - (new_rtctm.hours == 23 && new_rtctm.mins == 59)) - return 1; - - return rtc_command(RTC_SETTIME, &new_rtctm); -} - -static int rtc_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - unsigned int year; - struct rtc_time rtctm; - struct rtc_tm rtc_raw; - - switch (cmd) { - case RTC_ALM_READ: - case RTC_ALM_SET: - break; - - case RTC_RD_TIME: - memset(&rtctm, 0, sizeof(struct rtc_time)); - get_rtc_time(&rtc_raw, &year); - rtctm.tm_sec = rtc_raw.secs; - rtctm.tm_min = rtc_raw.mins; - rtctm.tm_hour = rtc_raw.hours; - rtctm.tm_mday = rtc_raw.mday; - rtctm.tm_mon = rtc_raw.mon - 1; /* month starts at 0 */ - rtctm.tm_year = year - 1900; /* starts at 1900 */ - return copy_to_user((void *)arg, &rtctm, sizeof(rtctm)) - ? -EFAULT : 0; - - case RTC_SET_TIME: - if (!capable(CAP_SYS_TIME)) - return -EACCES; - - if (copy_from_user(&rtctm, (void *)arg, sizeof(rtctm))) - return -EFAULT; - rtc_raw.secs = rtctm.tm_sec; - rtc_raw.mins = rtctm.tm_min; - rtc_raw.hours = rtctm.tm_hour; - rtc_raw.mday = rtctm.tm_mday; - rtc_raw.mon = rtctm.tm_mon + 1; - year = rtctm.tm_year + 1900; - return set_rtc_time(&rtc_raw, year); - break; - - case RTC_EPOCH_READ: - return put_user(1900, (unsigned long *)arg); - - } - return -EINVAL; -} - -static const struct file_operations rtc_fops = { - .ioctl = rtc_ioctl, -}; - -static struct miscdevice rtc_dev = { - .minor = RTC_MINOR, - .name = "rtc", - .fops = &rtc_fops, -}; - -/* IOC / IOMD i2c driver */ - -#define FORCE_ONES 0xdc -#define SCL 0x02 -#define SDA 0x01 - -/* - * We must preserve all non-i2c output bits in IOC_CONTROL. - * Note also that we need to preserve the value of SCL and - * SDA outputs as well (which may be different from the - * values read back from IOC_CONTROL). - */ -static u_int force_ones; - -static void ioc_setscl(void *data, int state) -{ - u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA); - u_int ones = force_ones; - - if (state) - ones |= SCL; - else - ones &= ~SCL; - - force_ones = ones; - - ioc_writeb(ioc_control | ones, IOC_CONTROL); -} - -static void ioc_setsda(void *data, int state) -{ - u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA); - u_int ones = force_ones; - - if (state) - ones |= SDA; - else - ones &= ~SDA; - - force_ones = ones; - - ioc_writeb(ioc_control | ones, IOC_CONTROL); -} - -static int ioc_getscl(void *data) -{ - return (ioc_readb(IOC_CONTROL) & SCL) != 0; -} - -static int ioc_getsda(void *data) -{ - return (ioc_readb(IOC_CONTROL) & SDA) != 0; -} - -static struct i2c_algo_bit_data ioc_data = { - .setsda = ioc_setsda, - .setscl = ioc_setscl, - .getsda = ioc_getsda, - .getscl = ioc_getscl, - .udelay = 80, - .timeout = 100 -}; - -static int ioc_client_reg(struct i2c_client *client) -{ - if (client->driver->id == I2C_DRIVERID_PCF8583 && - client->addr == 0x50) { - struct rtc_tm rtctm; - unsigned int year; - struct timespec tv; - - rtc_client = client; - get_rtc_time(&rtctm, &year); - - tv.tv_nsec = rtctm.cs * 10000000; - tv.tv_sec = mktime(year, rtctm.mon, rtctm.mday, - rtctm.hours, rtctm.mins, rtctm.secs); - do_settimeofday(&tv); - set_rtc = k_set_rtc_time; - } - - return 0; -} - -static int ioc_client_unreg(struct i2c_client *client) -{ - if (client == rtc_client) { - set_rtc = NULL; - rtc_client = NULL; - } - - return 0; -} - -static struct i2c_adapter ioc_ops = { - .id = I2C_HW_B_IOC, - .algo_data = &ioc_data, - .client_register = ioc_client_reg, - .client_unregister = ioc_client_unreg, -}; - -static int __init i2c_ioc_init(void) -{ - int ret; - - force_ones = FORCE_ONES | SCL | SDA; - - ret = i2c_bit_add_bus(&ioc_ops); - - if (ret >= 0){ - ret = misc_register(&rtc_dev); - if(ret < 0) - i2c_del_adapter(&ioc_ops); - } - - return ret; -} - -__initcall(i2c_ioc_init); diff --git a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c deleted file mode 100644 index 9b49f316ae9..00000000000 --- a/drivers/acorn/char/pcf8583.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * linux/drivers/acorn/char/pcf8583.c - * - * Copyright (C) 2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Driver for PCF8583 RTC & RAM chip - */ -#include <linux/module.h> -#include <linux/i2c.h> -#include <linux/slab.h> -#include <linux/string.h> -#include <linux/mc146818rtc.h> -#include <linux/init.h> -#include <linux/errno.h> -#include <linux/bcd.h> - -#include "pcf8583.h" - -static struct i2c_driver pcf8583_driver; - -static unsigned short ignore[] = { I2C_CLIENT_END }; -static unsigned short normal_addr[] = { 0x50, I2C_CLIENT_END }; -static unsigned short *forces[] = { NULL }; - -static struct i2c_client_address_data addr_data = { - .normal_i2c = normal_addr, - .probe = ignore, - .ignore = ignore, - .forces = forces, -}; - -#define set_ctrl(x, v) i2c_set_clientdata(x, (void *)(unsigned int)(v)) -#define get_ctrl(x) ((unsigned int)i2c_get_clientdata(x)) - -static int -pcf8583_attach(struct i2c_adapter *adap, int addr, int kind) -{ - struct i2c_client *c; - unsigned char buf[1], ad[1] = { 0 }; - struct i2c_msg msgs[2] = { - { - .addr = addr, - .flags = 0, - .len = 1, - .buf = ad, - }, { - .addr = addr, - .flags = I2C_M_RD, - .len = 1, - .buf = buf, - } - }; - - c = kmalloc(sizeof(*c), GFP_KERNEL); - if (!c) - return -ENOMEM; - - memset(c, 0, sizeof(*c)); - c->addr = addr; - c->adapter = adap; - c->driver = &pcf8583_driver; - - if (i2c_transfer(c->adapter, msgs, 2) == 2) - set_ctrl(c, buf[0]); - - return i2c_attach_client(c); -} - -static int -pcf8583_probe(struct i2c_adapter *adap) -{ - return i2c_probe(adap, &addr_data, pcf8583_attach); -} - -static int -pcf8583_detach(struct i2c_client *client) -{ - i2c_detach_client(client); - kfree(client); - return 0; -} - -static int -pcf8583_get_datetime(struct i2c_client *client, struct rtc_tm *dt) -{ - unsigned char buf[8], addr[1] = { 1 }; - struct i2c_msg msgs[2] = { - { - .addr = client->addr, - .flags = 0, - .len = 1, - .buf = addr, - }, { - .addr = client->addr, - .flags = I2C_M_RD, - .len = 6, - .buf = buf, - } - }; - int ret = -EIO; - - memset(buf, 0, sizeof(buf)); - - ret = i2c_transfer(client->adapter, msgs, 2); - if (ret == 2) { - dt->year_off = buf[4] >> 6; - dt->wday = buf[5] >> 5; - - buf[4] &= 0x3f; - buf[5] &= 0x1f; - - dt->cs = BCD_TO_BIN(buf[0]); - dt->secs = BCD_TO_BIN(buf[1]); - dt->mins = BCD_TO_BIN(buf[2]); - dt->hours = BCD_TO_BIN(buf[3]); - dt->mday = BCD_TO_BIN(buf[4]); - dt->mon = BCD_TO_BIN(buf[5]); - - ret = 0; - } - - return ret; -} - -static int -pcf8583_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo) -{ - unsigned char buf[8]; - int ret, len = 6; - - buf[0] = 0; - buf[1] = get_ctrl(client) | 0x80; - buf[2] = BIN_TO_BCD(dt->cs); - buf[3] = BIN_TO_BCD(dt->secs); - buf[4] = BIN_TO_BCD(dt->mins); - buf[5] = BIN_TO_BCD(dt->hours); - - if (datetoo) { - len = 8; - buf[6] = BIN_TO_BCD(dt->mday) | (dt->year_off << 6); - buf[7] = BIN_TO_BCD(dt->mon) | (dt->wday << 5); - } - - ret = i2c_master_send(client, (char *)buf, len); - if (ret == len) - ret = 0; - - buf[1] = get_ctrl(client); - i2c_master_send(client, (char *)buf, 2); - - return ret; -} - -static int -pcf8583_get_ctrl(struct i2c_client *client, unsigned char *ctrl) -{ - *ctrl = get_ctrl(client); - return 0; -} - -static int -pcf8583_set_ctrl(struct i2c_client *client, unsigned char *ctrl) -{ - unsigned char buf[2]; - - buf[0] = 0; - buf[1] = *ctrl; - set_ctrl(client, *ctrl); - - return i2c_master_send(client, (char *)buf, 2); -} - -static int -pcf8583_read_mem(struct i2c_client *client, struct mem *mem) -{ - unsigned char addr[1]; - struct i2c_msg msgs[2] = { - { - .addr = client->addr, - .flags = 0, - .len = 1, - .buf = addr, - }, { - .addr = client->addr, - .flags = I2C_M_RD, - .len = mem->nr, - .buf = mem->data, - } - }; - - if (mem->loc < 8) - return -EINVAL; - - addr[0] = mem->loc; - - return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO; -} - -static int -pcf8583_write_mem(struct i2c_client *client, struct mem *mem) -{ - unsigned char addr[1]; - struct i2c_msg msgs[2] = { - { - .addr = client->addr, - .flags = 0, - .len = 1, - .buf = addr, - }, { - .addr = client->addr, - .flags = I2C_M_NOSTART, - .len = mem->nr, - .buf = mem->data, - } - }; - - if (mem->loc < 8) - return -EINVAL; - - addr[0] = mem->loc; - - return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO; -} - -static int -pcf8583_command(struct i2c_client *client, unsigned int cmd, void *arg) -{ - switch (cmd) { - case RTC_GETDATETIME: - return pcf8583_get_datetime(client, arg); - - case RTC_SETTIME: - return pcf8583_set_datetime(client, arg, 0); - - case RTC_SETDATETIME: - return pcf8583_set_datetime(client, arg, 1); - - case RTC_GETCTRL: - return pcf8583_get_ctrl(client, arg); - - case RTC_SETCTRL: - return pcf8583_set_ctrl(client, arg); - - case MEM_READ: - return pcf8583_read_mem(client, arg); - - case MEM_WRITE: - return pcf8583_write_mem(client, arg); - - default: - return -EINVAL; - } -} - -static struct i2c_driver pcf8583_driver = { - .driver = { - .name = "PCF8583", - }, - .id = I2C_DRIVERID_PCF8583, - .attach_adapter = pcf8583_probe, - .detach_client = pcf8583_detach, - .command = pcf8583_command -}; - -static __init int pcf8583_init(void) -{ - return i2c_add_driver(&pcf8583_driver); -} - -static __exit void pcf8583_exit(void) -{ - i2c_del_driver(&pcf8583_driver); -} - -module_init(pcf8583_init); -module_exit(pcf8583_exit); - -MODULE_AUTHOR("Russell King"); -MODULE_DESCRIPTION("PCF8583 I2C RTC driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/acorn/char/pcf8583.h b/drivers/acorn/char/pcf8583.h deleted file mode 100644 index 847f7fdb876..00000000000 --- a/drivers/acorn/char/pcf8583.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * linux/drivers/acorn/char/pcf8583.h - * - * Copyright (C) 2000 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -struct rtc_tm { - unsigned char cs; - unsigned char secs; - unsigned char mins; - unsigned char hours; - unsigned char mday; - unsigned char mon; - unsigned char year_off; - unsigned char wday; -}; - -struct mem { - unsigned int loc; - unsigned int nr; - unsigned char *data; -}; - -#define RTC_GETDATETIME 0 -#define RTC_SETTIME 1 -#define RTC_SETDATETIME 2 -#define RTC_GETCTRL 3 -#define RTC_SETCTRL 4 -#define MEM_READ 5 -#define MEM_WRITE 6 - -#define CTRL_STOP 0x80 -#define CTRL_HOLD 0x40 -#define CTRL_32KHZ 0x00 -#define CTRL_MASK 0x08 -#define CTRL_ALARMEN 0x04 -#define CTRL_ALARM 0x02 -#define CTRL_TIMER 0x01 diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c index 033319e8b6c..43763c99ea0 100644 --- a/drivers/ata/pata_jmicron.c +++ b/drivers/ata/pata_jmicron.c @@ -244,7 +244,6 @@ static void __exit jmicron_exit(void) { pci_unregister_driver(&jmicron_pci_driver); } -#endif module_init(jmicron_init); module_exit(jmicron_exit); diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 4d44a2db29d..fb19dbb31e4 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -495,6 +495,16 @@ config I2C_VERSATILE This driver can also be built as a module. If so, the module will be called i2c-versatile. +config I2C_ACORN + bool "Acorn IOC/IOMD I2C bus support" + depends on I2C && ARCH_ACORN + default y + select I2C_ALGOBIT + help + Say yes if you want to support the I2C bus on Acorn platforms. + + If you don't know, say Y. + config I2C_VIA tristate "VIA 82C586B" depends on I2C && PCI && EXPERIMENTAL diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 03505aa44bb..290b5401835 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_I2C_SIS630) += i2c-sis630.o obj-$(CONFIG_I2C_SIS96X) += i2c-sis96x.o obj-$(CONFIG_I2C_STUB) += i2c-stub.o obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o +obj-$(CONFIG_I2C_ACORN) += i2c-acorn.o obj-$(CONFIG_I2C_VIA) += i2c-via.o obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o diff --git a/drivers/i2c/busses/i2c-acorn.c b/drivers/i2c/busses/i2c-acorn.c new file mode 100644 index 00000000000..09bd7f40b90 --- /dev/null +++ b/drivers/i2c/busses/i2c-acorn.c @@ -0,0 +1,97 @@ +/* + * linux/drivers/acorn/char/i2c.c + * + * Copyright (C) 2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * ARM IOC/IOMD i2c driver. + * + * On Acorn machines, the following i2c devices are on the bus: + * - PCF8583 real time clock & static RAM + */ +#include <linux/init.h> +#include <linux/i2c.h> +#include <linux/i2c-algo-bit.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/hardware/ioc.h> +#include <asm/system.h> + +#define FORCE_ONES 0xdc +#define SCL 0x02 +#define SDA 0x01 + +/* + * We must preserve all non-i2c output bits in IOC_CONTROL. + * Note also that we need to preserve the value of SCL and + * SDA outputs as well (which may be different from the + * values read back from IOC_CONTROL). + */ +static u_int force_ones; + +static void ioc_setscl(void *data, int state) +{ + u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA); + u_int ones = force_ones; + + if (state) + ones |= SCL; + else + ones &= ~SCL; + + force_ones = ones; + + ioc_writeb(ioc_control | ones, IOC_CONTROL); +} + +static void ioc_setsda(void *data, int state) +{ + u_int ioc_control = ioc_readb(IOC_CONTROL) & ~(SCL | SDA); + u_int ones = force_ones; + + if (state) + ones |= SDA; + else + ones &= ~SDA; + + force_ones = ones; + + ioc_writeb(ioc_control | ones, IOC_CONTROL); +} + +static int ioc_getscl(void *data) +{ + return (ioc_readb(IOC_CONTROL) & SCL) != 0; +} + +static int ioc_getsda(void *data) +{ + return (ioc_readb(IOC_CONTROL) & SDA) != 0; +} + +static struct i2c_algo_bit_data ioc_data = { + .setsda = ioc_setsda, + .setscl = ioc_setscl, + .getsda = ioc_getsda, + .getscl = ioc_getscl, + .udelay = 80, + .timeout = 100 +}; + +static struct i2c_adapter ioc_ops = { + .id = I2C_HW_B_IOC, + .algo_data = &ioc_data, +}; + +static int __init i2c_ioc_init(void) +{ + force_ones = FORCE_ONES | SCL | SDA; + + return i2c_bit_add_bus(&ioc_ops); +} + +__initcall(i2c_ioc_init); diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index 04574a9d443..0d122bf889d 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h @@ -14,6 +14,7 @@ #include "vmx.h" #include <linux/kvm.h> +#include <linux/kvm_para.h> #define CR0_PE_MASK (1ULL << 0) #define CR0_TS_MASK (1ULL << 3) @@ -237,6 +238,9 @@ struct kvm_vcpu { unsigned long cr0; unsigned long cr2; unsigned long cr3; + gpa_t para_state_gpa; + struct page *para_state_page; + gpa_t hypercall_gpa; unsigned long cr4; unsigned long cr8; u64 pdptrs[4]; /* pae */ @@ -305,6 +309,7 @@ struct kvm { int busy; unsigned long rmap_overflow; struct list_head vm_list; + struct file *filp; }; struct kvm_stat { @@ -339,7 +344,7 @@ struct kvm_arch_ops { int (*vcpu_create)(struct kvm_vcpu *vcpu); void (*vcpu_free)(struct kvm_vcpu *vcpu); - struct kvm_vcpu *(*vcpu_load)(struct kvm_vcpu *vcpu); + void (*vcpu_load)(struct kvm_vcpu *vcpu); void (*vcpu_put)(struct kvm_vcpu *vcpu); void (*vcpu_decache)(struct kvm_vcpu *vcpu); @@ -382,6 +387,8 @@ struct kvm_arch_ops { int (*run)(struct kvm_vcpu *vcpu, struct kvm_run *run); int (*vcpu_setup)(struct kvm_vcpu *vcpu); void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu); + void (*patch_hypercall)(struct kvm_vcpu *vcpu, + unsigned char *hypercall_addr); }; extern struct kvm_stat kvm_stat; @@ -476,6 +483,8 @@ void kvm_mmu_post_write(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes); int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva); void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu); +int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run); + static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code) { @@ -523,7 +532,7 @@ static inline struct kvm_mmu_page *page_header(hpa_t shadow_page) { struct page *page = pfn_to_page(shadow_page >> PAGE_SHIFT); - return (struct kvm_mmu_page *)page->private; + return (struct kvm_mmu_page *)page_private(page); } static inline u16 read_fs(void) diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index af866147ff2..a163bca3897 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -20,6 +20,7 @@ #include <linux/kvm.h> #include <linux/module.h> #include <linux/errno.h> +#include <linux/magic.h> #include <asm/processor.h> #include <linux/percpu.h> #include <linux/gfp.h> @@ -36,6 +37,9 @@ #include <asm/desc.h> #include <linux/sysdev.h> #include <linux/cpu.h> +#include <linux/file.h> +#include <linux/fs.h> +#include <linux/mount.h> #include "x86_emulate.h" #include "segment_descriptor.h" @@ -72,6 +76,8 @@ static struct kvm_stats_debugfs_item { static struct dentry *debugfs_dir; +struct vfsmount *kvmfs_mnt; + #define MAX_IO_MSRS 256 #define CR0_RESEVED_BITS 0xffffffff1ffaffc0ULL @@ -90,6 +96,58 @@ struct segment_descriptor_64 { #endif +static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl, + unsigned long arg); + +static struct inode *kvmfs_inode(struct file_operations *fops) +{ + int error = -ENOMEM; + struct inode *inode = new_inode(kvmfs_mnt->mnt_sb); + + if (!inode) + goto eexit_1; + + inode->i_fop = fops; + + /* + * Mark the inode dirty from the very beginning, + * that way it will never be moved to the dirty + * list because mark_inode_dirty() will think + * that it already _is_ on the dirty list. + */ + inode->i_state = I_DIRTY; + inode->i_mode = S_IRUSR | S_IWUSR; + inode->i_uid = current->fsuid; + inode->i_gid = current->fsgid; + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + return inode; + +eexit_1: + return ERR_PTR(error); +} + +static struct file *kvmfs_file(struct inode *inode, void *private_data) +{ + struct file *file = get_empty_filp(); + + if (!file) + return ERR_PTR(-ENFILE); + + file->f_path.mnt = mntget(kvmfs_mnt); + file->f_path.dentry = d_alloc_anon(inode); + if (!file->f_path.dentry) + return ERR_PTR(-ENOMEM); + file->f_mapping = inode->i_mapping; + + file->f_pos = 0; + file->f_flags = O_RDWR; + file->f_op = inode->i_fop; + file->f_mode = FMODE_READ | FMODE_WRITE; + file->f_version = 0; + file->private_data = private_data; + return file; +} + unsigned long segment_base(u16 selector) { struct descriptor_table gdt; @@ -126,10 +184,8 @@ static inline int valid_vcpu(int n) return likely(n >= 0 && n < KVM_MAX_VCPUS); } -int kvm_read_guest(struct kvm_vcpu *vcpu, - gva_t addr, - unsigned long size, - void *dest) +int kvm_read_guest(struct kvm_vcpu *vcpu, gva_t addr, unsigned long size, + void *dest) { unsigned char *host_buf = dest; unsigned long req_size = size; @@ -161,10 +217,8 @@ int kvm_read_guest(struct kvm_vcpu *vcpu, } EXPORT_SYMBOL_GPL(kvm_read_guest); -int kvm_write_guest(struct kvm_vcpu *vcpu, - gva_t addr, - unsigned long size, - void *data) +int kvm_write_guest(struct kvm_vcpu *vcpu, gva_t addr, unsigned long size, + void *data) { unsigned char *host_buf = data; unsigned long req_size = size; @@ -174,12 +228,15 @@ int kvm_write_guest(struct kvm_vcpu *vcpu, unsigned now; unsigned offset; hva_t guest_buf; + gfn_t gfn; paddr = gva_to_hpa(vcpu, addr); if (is_error_hpa(paddr)) break; + gfn = vcpu->mmu.gva_to_gpa(vcpu, addr) >> PAGE_SHIFT; + mark_page_dirty(vcpu->kvm, gfn); guest_buf = (hva_t)kmap_atomic( pfn_to_page(paddr >> PAGE_SHIFT), KM_USER0); offset = addr & ~PAGE_MASK; @@ -195,24 +252,30 @@ int kvm_write_guest(struct kvm_vcpu *vcpu, } EXPORT_SYMBOL_GPL(kvm_write_guest); -static int vcpu_slot(struct kvm_vcpu *vcpu) +/* + * Switches to specified vcpu, until a matching vcpu_put() + */ +static void vcpu_load(struct kvm_vcpu *vcpu) { - return vcpu - vcpu->kvm->vcpus; + mutex_lock(&vcpu->mutex); + kvm_arch_ops->vcpu_load(vcpu); } /* - * Switches to specified vcpu, until a matching vcpu_put() + * Switches to specified vcpu, until a matching vcpu_put(). Will return NULL + * if the slot is not populated. */ -static struct kvm_vcpu *vcpu_load(struct kvm *kvm, int vcpu_slot) +static struct kvm_vcpu *vcpu_load_slot(struct kvm *kvm, int slot) { - struct kvm_vcpu *vcpu = &kvm->vcpus[vcpu_slot]; + struct kvm_vcpu *vcpu = &kvm->vcpus[slot]; mutex_lock(&vcpu->mutex); - if (unlikely(!vcpu->vmcs)) { + if (!vcpu->vmcs) { mutex_unlock(&vcpu->mutex); return NULL; } - return kvm_arch_ops->vcpu_load(vcpu); + kvm_arch_ops->vcpu_load(vcpu); + return vcpu; } static void vcpu_put(struct kvm_vcpu *vcpu) @@ -221,13 +284,13 @@ static void vcpu_put(struct kvm_vcpu *vcpu) mutex_unlock(&vcpu->mutex); } -static int kvm_dev_open(struct inode *inode, struct file *filp) +static struct kvm *kvm_create_vm(void) { struct kvm *kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL); int i; if (!kvm) - return -ENOMEM; + return ERR_PTR(-ENOMEM); spin_lock_init(&kvm->lock); INIT_LIST_HEAD(&kvm->active_mmu_pages); @@ -243,7 +306,11 @@ static int kvm_dev_open(struct inode *inode, struct file *filp) list_add(&kvm->vm_list, &vm_list); spin_unlock(&kvm_lock); } - filp->private_data = kvm; + return kvm; +} + +static int kvm_dev_open(struct inode *inode, struct file *filp) +{ return 0; } @@ -281,9 +348,10 @@ static void kvm_free_physmem(struct kvm *kvm) static void kvm_free_vcpu(struct kvm_vcpu *vcpu) { - if (!vcpu_load(vcpu->kvm, vcpu_slot(vcpu))) + if (!vcpu->vmcs) return; + vcpu_load(vcpu); kvm_mmu_destroy(vcpu); vcpu_put(vcpu); kvm_arch_ops->vcpu_free(vcpu); @@ -299,14 +367,24 @@ static void kvm_free_vcpus(struct kvm *kvm) static int kvm_dev_release(struct inode *inode, struct file *filp) { - struct kvm *kvm = filp->private_data; + return 0; +} +static void kvm_destroy_vm(struct kvm *kvm) +{ spin_lock(&kvm_lock); list_del(&kvm->vm_list); spin_unlock(&kvm_lock); kvm_free_vcpus(kvm); kvm_free_physmem(kvm); kfree(kvm); +} + +static int kvm_vm_release(struct inode *inode, struct file *filp) +{ + struct kvm *kvm = filp->private_data; + + kvm_destroy_vm(kvm); return 0; } @@ -457,7 +535,7 @@ EXPORT_SYMBOL_GPL(set_cr4); void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) { if (is_long_mode(vcpu)) { - if ( cr3 & CR3_L_MODE_RESEVED_BITS) { + if (cr3 & CR3_L_MODE_RESEVED_BITS) { printk(KERN_DEBUG "set_cr3: #GP, reserved bits\n"); inject_gp(vcpu); return; @@ -533,55 +611,11 @@ void fx_init(struct kvm_vcpu *vcpu) } EXPORT_SYMBOL_GPL(fx_init); -/* - * Creates some virtual cpus. Good luck creating more than one. - */ -static int kvm_dev_ioctl_create_vcpu(struct kvm *kvm, int n) +static void do_remove_write_access(struct kvm_vcpu *vcpu, int slot) { - int r; - struct kvm_vcpu *vcpu; - - r = -EINVAL; - if (!valid_vcpu(n)) - goto out; - - vcpu = &kvm->vcpus[n]; - - mutex_lock(&vcpu->mutex); - - if (vcpu->vmcs) { - mutex_unlock(&vcpu->mutex); - return -EEXIST; - } - - vcpu->host_fx_image = (char*)ALIGN((hva_t)vcpu->fx_buf, - FX_IMAGE_ALIGN); - vcpu->guest_fx_image = vcpu->host_fx_image + FX_IMAGE_SIZE; - - r = kvm_arch_ops->vcpu_create(vcpu); - if (r < 0) - goto out_free_vcpus; - - r = kvm_mmu_create(vcpu); - if (r < 0) - goto out_free_vcpus; - - kvm_arch_ops->vcpu_load(vcpu); - r = kvm_mmu_setup(vcpu); - if (r >= 0) - r = kvm_arch_ops->vcpu_setup(vcpu); - vcpu_put(vcpu); - - if (r < 0) - goto out_free_vcpus; - - return 0; - -out_free_vcpus: - kvm_free_vcpu(vcpu); - mutex_unlock(&vcpu->mutex); -out: - return r; + spin_lock(&vcpu->kvm->lock); + kvm_mmu_slot_remove_write_access(vcpu, slot); + spin_unlock(&vcpu->kvm->lock); } /* @@ -590,8 +624,8 @@ out: * * Discontiguous memory is allowed, mostly for framebuffers. */ -static int kvm_dev_ioctl_set_memory_region(struct kvm *kvm, - struct kvm_memory_region *mem) +static int kvm_vm_ioctl_set_memory_region(struct kvm *kvm, + struct kvm_memory_region *mem) { int r; gfn_t base_gfn; @@ -674,7 +708,7 @@ raced: | __GFP_ZERO); if (!new.phys_mem[i]) goto out_free; - new.phys_mem[i]->private = 0; + set_page_private(new.phys_mem[i],0); } } @@ -711,9 +745,11 @@ raced: for (i = 0; i < KVM_MAX_VCPUS; ++i) { struct kvm_vcpu *vcpu; - vcpu = vcpu_load(kvm, i); + vcpu = vcpu_load_slot(kvm, i); if (!vcpu) continue; + if (new.flags & KVM_MEM_LOG_DIRTY_PAGES) + do_remove_write_access(vcpu, mem->slot); kvm_mmu_reset_context(vcpu); vcpu_put(vcpu); } @@ -729,18 +765,11 @@ out: return r; } -static void do_remove_write_access(struct kvm_vcpu *vcpu, int slot) -{ - spin_lock(&vcpu->kvm->lock); - kvm_mmu_slot_remove_write_access(vcpu, slot); - spin_unlock(&vcpu->kvm->lock); -} - /* * Get (and clear) the dirty memory log for a memory slot. */ -static int kvm_dev_ioctl_get_dirty_log(struct kvm *kvm, - struct kvm_dirty_log *log) +static int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, + struct kvm_dirty_log *log) { struct kvm_memory_slot *memslot; int r, i; @@ -765,21 +794,21 @@ static int kvm_dev_ioctl_get_dirty_log(struct kvm *kvm, if (!memslot->dirty_bitmap) goto out; - n = ALIGN(memslot->npages, 8) / 8; + n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; - for (i = 0; !any && i < n; ++i) + for (i = 0; !any && i < n/sizeof(long); ++i) any = memslot->dirty_bitmap[i]; r = -EFAULT; if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n)) goto out; - if (any) { cleared = 0; for (i = 0; i < KVM_MAX_VCPUS; ++i) { - struct kvm_vcpu *vcpu = vcpu_load(kvm, i); + struct kvm_vcpu *vcpu; + vcpu = vcpu_load_slot(kvm, i); if (!vcpu) continue; if (!cleared) { @@ -903,8 +932,9 @@ static int emulator_read_emulated(unsigned long addr, return X86EMUL_CONTINUE; else { gpa_t gpa = vcpu->mmu.gva_to_gpa(vcpu, addr); + if (gpa == UNMAPPED_GVA) - return vcpu_printf(vcpu, "not present\n"), X86EMUL_PROPAGATE_FAULT; + return X86EMUL_PROPAGATE_FAULT; vcpu->mmio_needed = 1; vcpu->mmio_phys_addr = gpa; vcpu->mmio_size = bytes; @@ -928,6 +958,7 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, return 0; page = gfn_to_page(m, gpa >> PAGE_SHIFT); kvm_mmu_pre_write(vcpu, gpa, bytes); + mark_page_dirty(vcpu->kvm, gpa >> PAGE_SHIFT); virt = kmap_atomic(page, KM_USER0); memcpy(virt + offset_in_page(gpa), &val, bytes); kunmap_atomic(virt, KM_USER0); @@ -1142,6 +1173,42 @@ int emulate_instruction(struct kvm_vcpu *vcpu, } EXPORT_SYMBOL_GPL(emulate_instruction); +int kvm_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + unsigned long nr, a0, a1, a2, a3, a4, a5, ret; + + kvm_arch_ops->decache_regs(vcpu); + ret = -KVM_EINVAL; +#ifdef CONFIG_X86_64 + if (is_long_mode(vcpu)) { + nr = vcpu->regs[VCPU_REGS_RAX]; + a0 = vcpu->regs[VCPU_REGS_RDI]; + a1 = vcpu->regs[VCPU_REGS_RSI]; + a2 = vcpu->regs[VCPU_REGS_RDX]; + a3 = vcpu->regs[VCPU_REGS_RCX]; + a4 = vcpu->regs[VCPU_REGS_R8]; + a5 = vcpu->regs[VCPU_REGS_R9]; + } else +#endif + { + nr = vcpu->regs[VCPU_REGS_RBX] & -1u; + a0 = vcpu->regs[VCPU_REGS_RAX] & -1u; + a1 = vcpu->regs[VCPU_REGS_RCX] & -1u; + a2 = vcpu->regs[VCPU_REGS_RDX] & -1u; + a3 = vcpu->regs[VCPU_REGS_RSI] & -1u; + a4 = vcpu->regs[VCPU_REGS_RDI] & -1u; + a5 = vcpu->regs[VCPU_REGS_RBP] & -1u; + } + switch (nr) { + default: + ; + } + vcpu->regs[VCPU_REGS_RAX] = ret; + kvm_arch_ops->cache_regs(vcpu); + return 1; +} +EXPORT_SYMBOL_GPL(kvm_hypercall); + static u64 mk_cr_64(u64 curr_cr, u32 new_val) { return (curr_cr & ~((1ULL << 32) - 1)) | new_val; @@ -1208,6 +1275,75 @@ void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val, } } +/* + * Register the para guest with the host: + */ +static int vcpu_register_para(struct kvm_vcpu *vcpu, gpa_t para_state_gpa) +{ + struct kvm_vcpu_para_state *para_state; + hpa_t para_state_hpa, hypercall_hpa; + struct page *para_state_page; + unsigned char *hypercall; + gpa_t hypercall_gpa; + + printk(KERN_DEBUG "kvm: guest trying to enter paravirtual mode\n"); + printk(KERN_DEBUG ".... para_state_gpa: %08Lx\n", para_state_gpa); + + /* + * Needs to be page aligned: + */ + if (para_state_gpa != PAGE_ALIGN(para_state_gpa)) + goto err_gp; + + para_state_hpa = gpa_to_hpa(vcpu, para_state_gpa); + printk(KERN_DEBUG ".... para_state_hpa: %08Lx\n", para_state_hpa); + if (is_error_hpa(para_state_hpa)) + goto err_gp; + + mark_page_dirty(vcpu->kvm, para_state_gpa >> PAGE_SHIFT); + para_state_page = pfn_to_page(para_state_hpa >> PAGE_SHIFT); + para_state = kmap_atomic(para_state_page, KM_USER0); + + printk(KERN_DEBUG ".... guest version: %d\n", para_state->guest_version); + printk(KERN_DEBUG ".... size: %d\n", para_state->size); + + para_state->host_version = KVM_PARA_API_VERSION; + /* + * We cannot support guests that try to register themselves + * with a newer API version than the host supports: + */ + if (para_state->guest_version > KVM_PARA_API_VERSION) { + para_state->ret = -KVM_EINVAL; + goto err_kunmap_skip; + } + + hypercall_gpa = para_state->hypercall_gpa; + hypercall_hpa = gpa_to_hpa(vcpu, hypercall_gpa); + printk(KERN_DEBUG ".... hypercall_hpa: %08Lx\n", hypercall_hpa); + if (is_error_hpa(hypercall_hpa)) { + para_state->ret = -KVM_EINVAL; + goto err_kunmap_skip; + } + + printk(KERN_DEBUG "kvm: para guest successfully registered.\n"); + vcpu->para_state_page = para_state_page; + vcpu->para_state_gpa = para_state_gpa; + vcpu->hypercall_gpa = hypercall_gpa; + + mark_page_dirty(vcpu->kvm, hypercall_gpa >> PAGE_SHIFT); + hypercall = kmap_atomic(pfn_to_page(hypercall_hpa >> PAGE_SHIFT), + KM_USER1) + (hypercall_hpa & ~PAGE_MASK); + kvm_arch_ops->patch_hypercall(vcpu, hypercall); + kunmap_atomic(hypercall, KM_USER1); + + para_state->ret = 0; +err_kunmap_skip: + kunmap_atomic(para_state, KM_USER0); + return 0; +err_gp: + return 1; +} + int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) { u64 data; @@ -1316,6 +1452,12 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) case MSR_IA32_MISC_ENABLE: vcpu->ia32_misc_enable_msr = data; break; + /* + * This is the 'probe whether the host is KVM' logic: + */ + case MSR_KVM_API_MAGIC: + return vcpu_register_para(vcpu, data); + default: printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr); return 1; @@ -1338,8 +1480,7 @@ void kvm_resched(struct kvm_vcpu *vcpu) { vcpu_put(vcpu); cond_resched(); - /* Cannot fail - no vcpu unplug yet. */ - vcpu_load(vcpu->kvm, vcpu_slot(vcpu)); + vcpu_load(vcpu); } EXPORT_SYMBOL_GPL(kvm_resched); @@ -1361,17 +1502,11 @@ void save_msrs(struct vmx_msr_entry *e, int n) } EXPORT_SYMBOL_GPL(save_msrs); -static int kvm_dev_ioctl_run(struct kvm *kvm, struct kvm_run *kvm_run) +static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { - struct kvm_vcpu *vcpu; int r; - if (!valid_vcpu(kvm_run->vcpu)) - return -EINVAL; - - vcpu = vcpu_load(kvm, kvm_run->vcpu); - if (!vcpu) - return -ENOENT; + vcpu_load(vcpu); /* re-sync apic's tpr */ vcpu->cr8 = kvm_run->cr8; @@ -1394,16 +1529,10 @@ static int kvm_dev_ioctl_run(struct kvm *kvm, struct kvm_run *kvm_run) return r; } -static int kvm_dev_ioctl_get_regs(struct kvm *kvm, struct kvm_regs *regs) +static int kvm_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, + struct kvm_regs *regs) { - struct kvm_vcpu *vcpu; - - if (!valid_vcpu(regs->vcpu)) - return -EINVAL; - - vcpu = vcpu_load(kvm, regs->vcpu); - if (!vcpu) - return -ENOENT; + vcpu_load(vcpu); kvm_arch_ops->cache_regs(vcpu); @@ -1440,16 +1569,10 @@ static int kvm_dev_ioctl_get_regs(struct kvm *kvm, struct kvm_regs *regs) return 0; } -static int kvm_dev_ioctl_set_regs(struct kvm *kvm, struct kvm_regs *regs) +static int kvm_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, + struct kvm_regs *regs) { - struct kvm_vcpu *vcpu; - - if (!valid_vcpu(regs->vcpu)) - return -EINVAL; - - vcpu = vcpu_load(kvm, regs->vcpu); - if (!vcpu) - return -ENOENT; + vcpu_load(vcpu); vcpu->regs[VCPU_REGS_RAX] = regs->rax; vcpu->regs[VCPU_REGS_RBX] = regs->rbx; @@ -1486,16 +1609,12 @@ static void get_segment(struct kvm_vcpu *vcpu, return kvm_arch_ops->get_segment(vcpu, var, seg); } -static int kvm_dev_ioctl_get_sregs(struct kvm *kvm, struct kvm_sregs *sregs) +static int kvm_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) { - struct kvm_vcpu *vcpu; struct descriptor_table dt; - if (!valid_vcpu(sregs->vcpu)) - return -EINVAL; - vcpu = vcpu_load(kvm, sregs->vcpu); - if (!vcpu) - return -ENOENT; + vcpu_load(vcpu); get_segment(vcpu, &sregs->cs, VCPU_SREG_CS); get_segment(vcpu, &sregs->ds, VCPU_SREG_DS); @@ -1537,18 +1656,14 @@ static void set_segment(struct kvm_vcpu *vcpu, return kvm_arch_ops->set_segment(vcpu, var, seg); } -static int kvm_dev_ioctl_set_sregs(struct kvm *kvm, struct kvm_sregs *sregs) +static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, + struct kvm_sregs *sregs) { - struct kvm_vcpu *vcpu; int mmu_reset_needed = 0; int i; struct descriptor_table dt; - if (!valid_vcpu(sregs->vcpu)) - return -EINVAL; - vcpu = vcpu_load(kvm, sregs->vcpu); - if (!vcpu) - return -ENOENT; + vcpu_load(vcpu); set_segment(vcpu, &sregs->cs, VCPU_SREG_CS); set_segment(vcpu, &sregs->ds, VCPU_SREG_DS); @@ -1654,20 +1769,14 @@ static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data) * * @return number of msrs set successfully. */ -static int __msr_io(struct kvm *kvm, struct kvm_msrs *msrs, +static int __msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs, struct kvm_msr_entry *entries, int (*do_msr)(struct kvm_vcpu *vcpu, unsigned index, u64 *data)) { - struct kvm_vcpu *vcpu; int i; - if (!valid_vcpu(msrs->vcpu)) - return -EINVAL; - - vcpu = vcpu_load(kvm, msrs->vcpu); - if (!vcpu) - return -ENOENT; + vcpu_load(vcpu); for (i = 0; i < msrs->nmsrs; ++i) if (do_msr(vcpu, entries[i].index, &entries[i].data)) @@ -1683,7 +1792,7 @@ static int __msr_io(struct kvm *kvm, struct kvm_msrs *msrs, * * @return number of msrs set successfully. */ -static int msr_io(struct kvm *kvm, struct kvm_msrs __user *user_msrs, +static int msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs, int (*do_msr)(struct kvm_vcpu *vcpu, unsigned index, u64 *data), int writeback) @@ -1711,7 +1820,7 @@ static int msr_io(struct kvm *kvm, struct kvm_msrs __user *user_msrs, if (copy_from_user(entries, user_msrs->entries, size)) goto out_free; - r = n = __msr_io(kvm, &msrs, entries, do_msr); + r = n = __msr_io(vcpu, &msrs, entries, do_msr); if (r < 0) goto out_free; @@ -1730,38 +1839,31 @@ out: /* * Translate a guest virtual address to a guest physical address. */ -static int kvm_dev_ioctl_translate(struct kvm *kvm, struct kvm_translation *tr) +static int kvm_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, + struct kvm_translation *tr) { unsigned long vaddr = tr->linear_address; - struct kvm_vcpu *vcpu; gpa_t gpa; - vcpu = vcpu_load(kvm, tr->vcpu); - if (!vcpu) - return -ENOENT; - spin_lock(&kvm->lock); + vcpu_load(vcpu); + spin_lock(&vcpu->kvm->lock); gpa = vcpu->mmu.gva_to_gpa(vcpu, vaddr); tr->physical_address = gpa; tr->valid = gpa != UNMAPPED_GVA; tr->writeable = 1; tr->usermode = 0; - spin_unlock(&kvm->lock); + spin_unlock(&vcpu->kvm->lock); vcpu_put(vcpu); return 0; } -static int kvm_dev_ioctl_interrupt(struct kvm *kvm, struct kvm_interrupt *irq) +static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, + struct kvm_interrupt *irq) { - struct kvm_vcpu *vcpu; - - if (!valid_vcpu(irq->vcpu)) - return -EINVAL; if (irq->irq < 0 || irq->irq >= 256) return -EINVAL; - vcpu = vcpu_load(kvm, irq->vcpu); - if (!vcpu) - return -ENOENT; + vcpu_load(vcpu); set_bit(irq->irq, vcpu->irq_pending); set_bit(irq->irq / BITS_PER_LONG, &vcpu->irq_summary); @@ -1771,17 +1873,12 @@ static int kvm_dev_ioctl_interrupt(struct kvm *kvm, struct kvm_interrupt *irq) return 0; } -static int kvm_dev_ioctl_debug_guest(struct kvm *kvm, - struct kvm_debug_guest *dbg) +static int kvm_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu, + struct kvm_debug_guest *dbg) { - struct kvm_vcpu *vcpu; int r; - if (!valid_vcpu(dbg->vcpu)) - return -EINVAL; - vcpu = vcpu_load(kvm, dbg->vcpu); - if (!vcpu) - return -ENOENT; + vcpu_load(vcpu); r = kvm_arch_ops->set_guest_debug(vcpu, dbg); @@ -1790,30 +1887,129 @@ static int kvm_dev_ioctl_debug_guest(struct kvm *kvm, return r; } -static long kvm_dev_ioctl(struct file *filp, - unsigned int ioctl, unsigned long arg) +static int kvm_vcpu_release(struct inode *inode, struct file *filp) { - struct kvm *kvm = filp->private_data; + struct kvm_vcpu *vcpu = filp->private_data; + + fput(vcpu->kvm->filp); + return 0; +} + +static struct file_operations kvm_vcpu_fops = { + .release = kvm_vcpu_release, + .unlocked_ioctl = kvm_vcpu_ioctl, + .compat_ioctl = kvm_vcpu_ioctl, +}; + +/* + * Allocates an inode for the vcpu. + */ +static int create_vcpu_fd(struct kvm_vcpu *vcpu) +{ + int fd, r; + struct inode *inode; + struct file *file; + + atomic_inc(&vcpu->kvm->filp->f_count); + inode = kvmfs_inode(&kvm_vcpu_fops); + if (IS_ERR(inode)) { + r = PTR_ERR(inode); + goto out1; + } + + file = kvmfs_file(inode, vcpu); + if (IS_ERR(file)) { + r = PTR_ERR(file); + goto out2; + } + + r = get_unused_fd(); + if (r < 0) + goto out3; + fd = r; + fd_install(fd, file); + + return fd; + +out3: + fput(file); +out2: + iput(inode); +out1: + fput(vcpu->kvm->filp); + return r; +} + +/* + * Creates some virtual cpus. Good luck creating more than one. + */ +static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n) +{ + int r; + struct kvm_vcpu *vcpu; + + r = -EINVAL; + if (!valid_vcpu(n)) + goto out; + + vcpu = &kvm->vcpus[n]; + + mutex_lock(&vcpu->mutex); + + if (vcpu->vmcs) { + mutex_unlock(&vcpu->mutex); + return -EEXIST; + } + + vcpu->host_fx_image = (char*)ALIGN((hva_t)vcpu->fx_buf, + FX_IMAGE_ALIGN); + vcpu->guest_fx_image = vcpu->host_fx_image + FX_IMAGE_SIZE; + + r = kvm_arch_ops->vcpu_create(vcpu); + if (r < 0) + goto out_free_vcpus; + + r = kvm_mmu_create(vcpu); + if (r < 0) + goto out_free_vcpus; + + kvm_arch_ops->vcpu_load(vcpu); + r = kvm_mmu_setup(vcpu); + if (r >= 0) + r = kvm_arch_ops->vcpu_setup(vcpu); + vcpu_put(vcpu); + + if (r < 0) + goto out_free_vcpus; + + r = create_vcpu_fd(vcpu); + if (r < 0) + goto out_free_vcpus; + + return r; + +out_free_vcpus: + kvm_free_vcpu(vcpu); + mutex_unlock(&vcpu->mutex); +out: + return r; +} + +static long kvm_vcpu_ioctl(struct file *filp, + unsigned int ioctl, unsigned long arg) +{ + struct kvm_vcpu *vcpu = filp->private_data; void __user *argp = (void __user *)arg; int r = -EINVAL; switch (ioctl) { - case KVM_GET_API_VERSION: - r = KVM_API_VERSION; - break; - case KVM_CREATE_VCPU: { - r = kvm_dev_ioctl_create_vcpu(kvm, arg); - if (r) - goto out; - break; - } case KVM_RUN: { struct kvm_run kvm_run; r = -EFAULT; if (copy_from_user(&kvm_run, argp, sizeof kvm_run)) goto out; - r = kvm_dev_ioctl_run(kvm, &kvm_run); + r = kvm_vcpu_ioctl_run(vcpu, &kvm_run); if (r < 0 && r != -EINTR) goto out; if (copy_to_user(argp, &kvm_run, sizeof kvm_run)) { @@ -1825,10 +2021,8 @@ static long kvm_dev_ioctl(struct file *filp, case KVM_GET_REGS: { struct kvm_regs kvm_regs; - r = -EFAULT; - if (copy_from_user(&kvm_regs, argp, sizeof kvm_regs)) - goto out; - r = kvm_dev_ioctl_get_regs(kvm, &kvm_regs); + memset(&kvm_regs, 0, sizeof kvm_regs); + r = kvm_vcpu_ioctl_get_regs(vcpu, &kvm_regs); if (r) goto out; r = -EFAULT; @@ -1843,7 +2037,7 @@ static long kvm_dev_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(&kvm_regs, argp, sizeof kvm_regs)) goto out; - r = kvm_dev_ioctl_set_regs(kvm, &kvm_regs); + r = kvm_vcpu_ioctl_set_regs(vcpu, &kvm_regs); if (r) goto out; r = 0; @@ -1852,10 +2046,8 @@ static long kvm_dev_ioctl(struct file *filp, case KVM_GET_SREGS: { struct kvm_sregs kvm_sregs; - r = -EFAULT; - if (copy_from_user(&kvm_sregs, argp, sizeof kvm_sregs)) - goto out; - r = kvm_dev_ioctl_get_sregs(kvm, &kvm_sregs); + memset(&kvm_sregs, 0, sizeof kvm_sregs); + r = kvm_vcpu_ioctl_get_sregs(vcpu, &kvm_sregs); if (r) goto out; r = -EFAULT; @@ -1870,7 +2062,7 @@ static long kvm_dev_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(&kvm_sregs, argp, sizeof kvm_sregs)) goto out; - r = kvm_dev_ioctl_set_sregs(kvm, &kvm_sregs); + r = kvm_vcpu_ioctl_set_sregs(vcpu, &kvm_sregs); if (r) goto out; r = 0; @@ -1882,7 +2074,7 @@ static long kvm_dev_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(&tr, argp, sizeof tr)) goto out; - r = kvm_dev_ioctl_translate(kvm, &tr); + r = kvm_vcpu_ioctl_translate(vcpu, &tr); if (r) goto out; r = -EFAULT; @@ -1897,7 +2089,7 @@ static long kvm_dev_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(&irq, argp, sizeof irq)) goto out; - r = kvm_dev_ioctl_interrupt(kvm, &irq); + r = kvm_vcpu_ioctl_interrupt(vcpu, &irq); if (r) goto out; r = 0; @@ -1909,19 +2101,45 @@ static long kvm_dev_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(&dbg, argp, sizeof dbg)) goto out; - r = kvm_dev_ioctl_debug_guest(kvm, &dbg); + r = kvm_vcpu_ioctl_debug_guest(vcpu, &dbg); if (r) goto out; r = 0; break; } + case KVM_GET_MSRS: + r = msr_io(vcpu, argp, get_msr, 1); + break; + case KVM_SET_MSRS: + r = msr_io(vcpu, argp, do_set_msr, 0); + break; + default: + ; + } +out: + return r; +} + +static long kvm_vm_ioctl(struct file *filp, + unsigned int ioctl, unsigned long arg) +{ + struct kvm *kvm = filp->private_data; + void __user *argp = (void __user *)arg; + int r = -EINVAL; + + switch (ioctl) { + case KVM_CREATE_VCPU: + r = kvm_vm_ioctl_create_vcpu(kvm, arg); + if (r < 0) + goto out; + break; case KVM_SET_MEMORY_REGION: { struct kvm_memory_region kvm_mem; r = -EFAULT; if (copy_from_user(&kvm_mem, argp, sizeof kvm_mem)) goto out; - r = kvm_dev_ioctl_set_memory_region(kvm, &kvm_mem); + r = kvm_vm_ioctl_set_memory_region(kvm, &kvm_mem); if (r) goto out; break; @@ -1932,16 +2150,112 @@ static long kvm_dev_ioctl(struct file *filp, r = -EFAULT; if (copy_from_user(&log, argp, sizeof log)) goto out; - r = kvm_dev_ioctl_get_dirty_log(kvm, &log); + r = kvm_vm_ioctl_get_dirty_log(kvm, &log); if (r) goto out; break; } - case KVM_GET_MSRS: - r = msr_io(kvm, argp, get_msr, 1); + default: + ; + } +out: + return r; +} + +static struct page *kvm_vm_nopage(struct vm_area_struct *vma, + unsigned long address, + int *type) +{ + struct kvm *kvm = vma->vm_file->private_data; + unsigned long pgoff; + struct kvm_memory_slot *slot; + struct page *page; + + *type = VM_FAULT_MINOR; + pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; + slot = gfn_to_memslot(kvm, pgoff); + if (!slot) + return NOPAGE_SIGBUS; + page = gfn_to_page(slot, pgoff); + if (!page) + return NOPAGE_SIGBUS; + get_page(page); + return page; +} + +static struct vm_operations_struct kvm_vm_vm_ops = { + .nopage = kvm_vm_nopage, +}; + +static int kvm_vm_mmap(struct file *file, struct vm_area_struct *vma) +{ + vma->vm_ops = &kvm_vm_vm_ops; + return 0; +} + +static struct file_operations kvm_vm_fops = { + .release = kvm_vm_release, + .unlocked_ioctl = kvm_vm_ioctl, + .compat_ioctl = kvm_vm_ioctl, + .mmap = kvm_vm_mmap, +}; + +static int kvm_dev_ioctl_create_vm(void) +{ + int fd, r; + struct inode *inode; + struct file *file; + struct kvm *kvm; + + inode = kvmfs_inode(&kvm_vm_fops); + if (IS_ERR(inode)) { + r = PTR_ERR(inode); + goto out1; + } + + kvm = kvm_create_vm(); + if (IS_ERR(kvm)) { + r = PTR_ERR(kvm); + goto out2; + } + + file = kvmfs_file(inode, kvm); + if (IS_ERR(file)) { + r = PTR_ERR(file); + goto out3; + } + kvm->filp = file; + + r = get_unused_fd(); + if (r < 0) + goto out4; + fd = r; + fd_install(fd, file); + + return fd; + +out4: + fput(file); +out3: + kvm_destroy_vm(kvm); +out2: + iput(inode); +out1: + return r; +} + +static long kvm_dev_ioctl(struct file *filp, + unsigned int ioctl, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + int r = -EINVAL; + + switch (ioctl) { + case KVM_GET_API_VERSION: + r = KVM_API_VERSION; break; - case KVM_SET_MSRS: - r = msr_io(kvm, argp, do_set_msr, 0); + case KVM_CREATE_VM: + r = kvm_dev_ioctl_create_vm(); break; case KVM_GET_MSR_INDEX_LIST: { struct kvm_msr_list __user *user_msr_list = argp; @@ -1977,43 +2291,11 @@ out: return r; } -static struct page *kvm_dev_nopage(struct vm_area_struct *vma, - unsigned long address, - int *type) -{ - struct kvm *kvm = vma->vm_file->private_data; - unsigned long pgoff; - struct kvm_memory_slot *slot; - struct page *page; - - *type = VM_FAULT_MINOR; - pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; - slot = gfn_to_memslot(kvm, pgoff); - if (!slot) - return NOPAGE_SIGBUS; - page = gfn_to_page(slot, pgoff); - if (!page) - return NOPAGE_SIGBUS; - get_page(page); - return page; -} - -static struct vm_operations_struct kvm_dev_vm_ops = { - .nopage = kvm_dev_nopage, -}; - -static int kvm_dev_mmap(struct file *file, struct vm_area_struct *vma) -{ - vma->vm_ops = &kvm_dev_vm_ops; - return 0; -} - static struct file_operations kvm_chardev_ops = { .open = kvm_dev_open, .release = kvm_dev_release, .unlocked_ioctl = kvm_dev_ioctl, .compat_ioctl = kvm_dev_ioctl, - .mmap = kvm_dev_mmap, }; static struct miscdevice kvm_dev = { @@ -2080,13 +2362,17 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val, int cpu = (long)v; switch (val) { - case CPU_DEAD: + case CPU_DOWN_PREPARE: case CPU_UP_CANCELED: + printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", + cpu); decache_vcpus_on_cpu(cpu); smp_call_function_single(cpu, kvm_arch_ops->hardware_disable, NULL, 0, 1); break; - case CPU_UP_PREPARE: + case CPU_ONLINE: + printk(KERN_INFO "kvm: enabling virtualization on CPU%d\n", + cpu); smp_call_function_single(cpu, kvm_arch_ops->hardware_enable, NULL, 0, 1); break; @@ -2121,13 +2407,13 @@ static void kvm_exit_debug(void) static int kvm_suspend(struct sys_device *dev, pm_message_t state) { decache_vcpus_on_cpu(raw_smp_processor_id()); - on_each_cpu(kvm_arch_ops->hardware_disable, 0, 0, 1); + on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1); return 0; } static int kvm_resume(struct sys_device *dev) { - on_each_cpu(kvm_arch_ops->hardware_enable, 0, 0, 1); + on_each_cpu(kvm_arch_ops->hardware_enable, NULL, 0, 1); return 0; } @@ -2144,6 +2430,18 @@ static struct sys_device kvm_sysdev = { hpa_t bad_page_address; +static int kvmfs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) +{ + return get_sb_pseudo(fs_type, "kvm:", NULL, KVMFS_SUPER_MAGIC, mnt); +} + +static struct file_system_type kvm_fs_type = { + .name = "kvmfs", + .get_sb = kvmfs_get_sb, + .kill_sb = kill_anon_super, +}; + int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module) { int r; @@ -2220,8 +2518,16 @@ void kvm_exit_arch(void) static __init int kvm_init(void) { static struct page *bad_page; - int r = 0; + int r; + + r = register_filesystem(&kvm_fs_type); + if (r) + goto out3; + kvmfs_mnt = kern_mount(&kvm_fs_type); + r = PTR_ERR(kvmfs_mnt); + if (IS_ERR(kvmfs_mnt)) + goto out2; kvm_init_debug(); kvm_init_msr_list(); @@ -2234,10 +2540,14 @@ static __init int kvm_init(void) bad_page_address = page_to_pfn(bad_page) << PAGE_SHIFT; memset(__va(bad_page_address), 0, PAGE_SIZE); - return r; + return 0; out: kvm_exit_debug(); + mntput(kvmfs_mnt); +out2: + unregister_filesystem(&kvm_fs_type); +out3: return r; } @@ -2245,6 +2555,8 @@ static __exit void kvm_exit(void) { kvm_exit_debug(); __free_page(pfn_to_page(bad_page_address >> PAGE_SHIFT)); + mntput(kvmfs_mnt); + unregister_filesystem(&kvm_fs_type); } module_init(kvm_init) diff --git a/drivers/kvm/kvm_svm.h b/drivers/kvm/kvm_svm.h index 74cc862f493..624f1ca4865 100644 --- a/drivers/kvm/kvm_svm.h +++ b/drivers/kvm/kvm_svm.h @@ -1,6 +1,7 @@ #ifndef __KVM_SVM_H #define __KVM_SVM_H +#include <linux/kernel.h> #include <linux/types.h> #include <linux/list.h> #include <asm/msr.h> @@ -18,7 +19,7 @@ static const u32 host_save_msrs[] = { MSR_IA32_LASTBRANCHTOIP, MSR_IA32_LASTINTFROMIP,MSR_IA32_LASTINTTOIP,*/ }; -#define NR_HOST_SAVE_MSRS (sizeof(host_save_msrs) / sizeof(*host_save_msrs)) +#define NR_HOST_SAVE_MSRS ARRAY_SIZE(host_save_msrs) #define NUM_DB_REGS 4 struct vcpu_svm { diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c index be793770f31..a1a93368f31 100644 --- a/drivers/kvm/mmu.c +++ b/drivers/kvm/mmu.c @@ -298,18 +298,18 @@ static void rmap_add(struct kvm_vcpu *vcpu, u64 *spte) if (!is_rmap_pte(*spte)) return; page = pfn_to_page((*spte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT); - if (!page->private) { + if (!page_private(page)) { rmap_printk("rmap_add: %p %llx 0->1\n", spte, *spte); - page->private = (unsigned long)spte; - } else if (!(page->private & 1)) { + set_page_private(page,(unsigned long)spte); + } else if (!(page_private(page) & 1)) { rmap_printk("rmap_add: %p %llx 1->many\n", spte, *spte); desc = mmu_alloc_rmap_desc(vcpu); - desc->shadow_ptes[0] = (u64 *)page->private; + desc->shadow_ptes[0] = (u64 *)page_private(page); desc->shadow_ptes[1] = spte; - page->private = (unsigned long)desc | 1; + set_page_private(page,(unsigned long)desc | 1); } else { rmap_printk("rmap_add: %p %llx many->many\n", spte, *spte); - desc = (struct kvm_rmap_desc *)(page->private & ~1ul); + desc = (struct kvm_rmap_desc *)(page_private(page) & ~1ul); while (desc->shadow_ptes[RMAP_EXT-1] && desc->more) desc = desc->more; if (desc->shadow_ptes[RMAP_EXT-1]) { @@ -337,12 +337,12 @@ static void rmap_desc_remove_entry(struct kvm_vcpu *vcpu, if (j != 0) return; if (!prev_desc && !desc->more) - page->private = (unsigned long)desc->shadow_ptes[0]; + set_page_private(page,(unsigned long)desc->shadow_ptes[0]); else if (prev_desc) prev_desc->more = desc->more; else - page->private = (unsigned long)desc->more | 1; + set_page_private(page,(unsigned long)desc->more | 1); mmu_free_rmap_desc(vcpu, desc); } @@ -356,20 +356,20 @@ static void rmap_remove(struct kvm_vcpu *vcpu, u64 *spte) if (!is_rmap_pte(*spte)) return; page = pfn_to_page((*spte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT); - if (!page->private) { + if (!page_private(page)) { printk(KERN_ERR "rmap_remove: %p %llx 0->BUG\n", spte, *spte); BUG(); - } else if (!(page->private & 1)) { + } else if (!(page_private(page) & 1)) { rmap_printk("rmap_remove: %p %llx 1->0\n", spte, *spte); - if ((u64 *)page->private != spte) { + if ((u64 *)page_private(page) != spte) { printk(KERN_ERR "rmap_remove: %p %llx 1->BUG\n", spte, *spte); BUG(); } - page->private = 0; + set_page_private(page,0); } else { rmap_printk("rmap_remove: %p %llx many->many\n", spte, *spte); - desc = (struct kvm_rmap_desc *)(page->private & ~1ul); + desc = (struct kvm_rmap_desc *)(page_private(page) & ~1ul); prev_desc = NULL; while (desc) { for (i = 0; i < RMAP_EXT && desc->shadow_ptes[i]; ++i) @@ -398,11 +398,11 @@ static void rmap_write_protect(struct kvm_vcpu *vcpu, u64 gfn) BUG_ON(!slot); page = gfn_to_page(slot, gfn); - while (page->private) { - if (!(page->private & 1)) - spte = (u64 *)page->private; + while (page_private(page)) { + if (!(page_private(page) & 1)) + spte = (u64 *)page_private(page); else { - desc = (struct kvm_rmap_desc *)(page->private & ~1ul); + desc = (struct kvm_rmap_desc *)(page_private(page) & ~1ul); spte = desc->shadow_ptes[0]; } BUG_ON(!spte); @@ -1218,7 +1218,7 @@ static int alloc_mmu_pages(struct kvm_vcpu *vcpu) INIT_LIST_HEAD(&page_header->link); if ((page = alloc_page(GFP_KERNEL)) == NULL) goto error_1; - page->private = (unsigned long)page_header; + set_page_private(page, (unsigned long)page_header); page_header->page_hpa = (hpa_t)page_to_pfn(page) << PAGE_SHIFT; memset(__va(page_header->page_hpa), 0, PAGE_SIZE); list_add(&page_header->link, &vcpu->free_pages); diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h index b6b90e9e130..f3bcee90465 100644 --- a/drivers/kvm/paging_tmpl.h +++ b/drivers/kvm/paging_tmpl.h @@ -128,8 +128,10 @@ static int FNAME(walk_addr)(struct guest_walker *walker, goto access_error; #endif - if (!(*ptep & PT_ACCESSED_MASK)) - *ptep |= PT_ACCESSED_MASK; /* avoid rmw */ + if (!(*ptep & PT_ACCESSED_MASK)) { + mark_page_dirty(vcpu->kvm, table_gfn); + *ptep |= PT_ACCESSED_MASK; + } if (walker->level == PT_PAGE_TABLE_LEVEL) { walker->gfn = (*ptep & PT_BASE_ADDR_MASK) @@ -185,6 +187,12 @@ static void FNAME(release_walker)(struct guest_walker *walker) kunmap_atomic(walker->table, KM_USER0); } +static void FNAME(mark_pagetable_dirty)(struct kvm *kvm, + struct guest_walker *walker) +{ + mark_page_dirty(kvm, walker->table_gfn[walker->level - 1]); +} + static void FNAME(set_pte)(struct kvm_vcpu *vcpu, u64 guest_pte, u64 *shadow_pte, u64 access_bits, gfn_t gfn) { @@ -348,12 +356,15 @@ static int FNAME(fix_write_pf)(struct kvm_vcpu *vcpu, } else if (kvm_mmu_lookup_page(vcpu, gfn)) { pgprintk("%s: found shadow page for %lx, marking ro\n", __FUNCTION__, gfn); + mark_page_dirty(vcpu->kvm, gfn); + FNAME(mark_pagetable_dirty)(vcpu->kvm, walker); *guest_ent |= PT_DIRTY_MASK; *write_pt = 1; return 0; } mark_page_dirty(vcpu->kvm, gfn); *shadow_ent |= PT_WRITABLE_MASK; + FNAME(mark_pagetable_dirty)(vcpu->kvm, walker); *guest_ent |= PT_DIRTY_MASK; rmap_add(vcpu, shadow_ent); @@ -430,9 +441,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, /* * mmio: emulate if accessible, otherwise its a guest fault. */ - if (is_io_pte(*shadow_pte)) { + if (is_io_pte(*shadow_pte)) return 1; - } ++kvm_stat.pf_fixed; kvm_mmu_audit(vcpu, "post page fault (fixed)"); diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index 83da4ea150a..3d8ea7ac2ec 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c @@ -15,6 +15,7 @@ */ #include <linux/module.h> +#include <linux/kernel.h> #include <linux/vmalloc.h> #include <linux/highmem.h> #include <linux/profile.h> @@ -75,7 +76,7 @@ struct svm_init_data { static u32 msrpm_ranges[] = {0, 0xc0000000, 0xc0010000}; -#define NUM_MSR_MAPS (sizeof(msrpm_ranges) / sizeof(*msrpm_ranges)) +#define NUM_MSR_MAPS ARRAY_SIZE(msrpm_ranges) #define MSRS_RANGE_SIZE 2048 #define MSRS_IN_RANGE (MSRS_RANGE_SIZE * 8 / 2) @@ -485,6 +486,7 @@ static void init_vmcb(struct vmcb *vmcb) control->intercept = (1ULL << INTERCEPT_INTR) | (1ULL << INTERCEPT_NMI) | + (1ULL << INTERCEPT_SMI) | /* * selective cr0 intercept bug? * 0: 0f 22 d8 mov %eax,%cr3 @@ -553,7 +555,7 @@ static void init_vmcb(struct vmcb *vmcb) * cr0 val on cpu init should be 0x60000010, we enable cpu * cache by default. the orderly way is to enable cache in bios. */ - save->cr0 = 0x00000010 | CR0_PG_MASK; + save->cr0 = 0x00000010 | CR0_PG_MASK | CR0_WP_MASK; save->cr4 = CR4_PAE_MASK; /* rdx = ?? */ } @@ -598,10 +600,9 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu) kfree(vcpu->svm); } -static struct kvm_vcpu *svm_vcpu_load(struct kvm_vcpu *vcpu) +static void svm_vcpu_load(struct kvm_vcpu *vcpu) { get_cpu(); - return vcpu; } static void svm_vcpu_put(struct kvm_vcpu *vcpu) @@ -1042,22 +1043,22 @@ static int io_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) addr_mask = io_adress(vcpu, _in, &kvm_run->io.address); if (!addr_mask) { - printk(KERN_DEBUG "%s: get io address failed\n", __FUNCTION__); + printk(KERN_DEBUG "%s: get io address failed\n", + __FUNCTION__); return 1; } if (kvm_run->io.rep) { - kvm_run->io.count = vcpu->regs[VCPU_REGS_RCX] & addr_mask; + kvm_run->io.count + = vcpu->regs[VCPU_REGS_RCX] & addr_mask; kvm_run->io.string_down = (vcpu->svm->vmcb->save.rflags & X86_EFLAGS_DF) != 0; } - } else { + } else kvm_run->io.value = vcpu->svm->vmcb->save.rax; - } return 0; } - static int nop_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { return 1; @@ -1075,6 +1076,12 @@ static int halt_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 0; } +static int vmmcall_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + vcpu->svm->vmcb->save.rip += 3; + return kvm_hypercall(vcpu, kvm_run); +} + static int invalid_op_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { inject_ud(vcpu); @@ -1275,7 +1282,7 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu, [SVM_EXIT_TASK_SWITCH] = task_switch_interception, [SVM_EXIT_SHUTDOWN] = shutdown_interception, [SVM_EXIT_VMRUN] = invalid_op_interception, - [SVM_EXIT_VMMCALL] = invalid_op_interception, + [SVM_EXIT_VMMCALL] = vmmcall_interception, [SVM_EXIT_VMLOAD] = invalid_op_interception, [SVM_EXIT_VMSAVE] = invalid_op_interception, [SVM_EXIT_STGI] = invalid_op_interception, @@ -1297,7 +1304,7 @@ static int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) __FUNCTION__, vcpu->svm->vmcb->control.exit_int_info, exit_code); - if (exit_code >= sizeof(svm_exit_handlers) / sizeof(*svm_exit_handlers) + if (exit_code >= ARRAY_SIZE(svm_exit_handlers) || svm_exit_handlers[exit_code] == 0) { kvm_run->exit_reason = KVM_EXIT_UNKNOWN; printk(KERN_ERR "%s: 0x%x @ 0x%llx cr0 0x%lx rflags 0x%llx\n", @@ -1668,6 +1675,18 @@ static int is_disabled(void) return 0; } +static void +svm_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall) +{ + /* + * Patch in the VMMCALL instruction: + */ + hypercall[0] = 0x0f; + hypercall[1] = 0x01; + hypercall[2] = 0xd9; + hypercall[3] = 0xc3; +} + static struct kvm_arch_ops svm_arch_ops = { .cpu_has_kvm_support = has_svm, .disabled_by_bios = is_disabled, @@ -1716,6 +1735,7 @@ static struct kvm_arch_ops svm_arch_ops = { .run = svm_vcpu_run, .skip_emulated_instruction = skip_emulated_instruction, .vcpu_setup = svm_vcpu_setup, + .patch_hypercall = svm_patch_hypercall, }; static int __init svm_init(void) diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index fd4e9173438..c07178e6112 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c @@ -19,6 +19,7 @@ #include "vmx.h" #include "kvm_vmx.h" #include <linux/module.h> +#include <linux/kernel.h> #include <linux/mm.h> #include <linux/highmem.h> #include <linux/profile.h> @@ -27,7 +28,6 @@ #include "segment_descriptor.h" - MODULE_AUTHOR("Qumranet"); MODULE_LICENSE("GPL"); @@ -76,7 +76,7 @@ static const u32 vmx_msr_index[] = { #endif MSR_EFER, MSR_K6_STAR, }; -#define NR_VMX_MSR (sizeof(vmx_msr_index) / sizeof(*vmx_msr_index)) +#define NR_VMX_MSR ARRAY_SIZE(vmx_msr_index) static inline int is_page_fault(u32 intr_info) { @@ -204,7 +204,7 @@ static void vmcs_write64(unsigned long field, u64 value) * Switches to specified vcpu, until a matching vcpu_put(), but assumes * vcpu mutex is already taken. */ -static struct kvm_vcpu *vmx_vcpu_load(struct kvm_vcpu *vcpu) +static void vmx_vcpu_load(struct kvm_vcpu *vcpu) { u64 phys_addr = __pa(vcpu->vmcs); int cpu; @@ -242,7 +242,6 @@ static struct kvm_vcpu *vmx_vcpu_load(struct kvm_vcpu *vcpu) rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ } - return vcpu; } static void vmx_vcpu_put(struct kvm_vcpu *vcpu) @@ -418,10 +417,9 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) case MSR_IA32_SYSENTER_ESP: vmcs_write32(GUEST_SYSENTER_ESP, data); break; - case MSR_IA32_TIME_STAMP_COUNTER: { + case MSR_IA32_TIME_STAMP_COUNTER: guest_write_tsc(data); break; - } default: msr = find_msr_entry(vcpu, msr_index); if (msr) { @@ -793,6 +791,9 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) */ static void vmx_set_cr0_no_modeswitch(struct kvm_vcpu *vcpu, unsigned long cr0) { + if (!vcpu->rmode.active && !(cr0 & CR0_PE_MASK)) + enter_rmode(vcpu); + vcpu->rmode.active = ((cr0 & CR0_PE_MASK) == 0); update_exception_bitmap(vcpu); vmcs_writel(CR0_READ_SHADOW, cr0); @@ -1467,6 +1468,18 @@ static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 0; } +static void +vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall) +{ + /* + * Patch in the VMCALL instruction: + */ + hypercall[0] = 0x0f; + hypercall[1] = 0x01; + hypercall[2] = 0xc1; + hypercall[3] = 0xc3; +} + static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) { u64 exit_qualification; @@ -1643,6 +1656,12 @@ static int handle_halt(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 0; } +static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + vmcs_writel(GUEST_RIP, vmcs_readl(GUEST_RIP)+3); + return kvm_hypercall(vcpu, kvm_run); +} + /* * The exit handlers return 1 if the exit was handled fully and guest execution * may resume. Otherwise they set the kvm_run parameter to indicate what needs @@ -1661,6 +1680,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu, [EXIT_REASON_MSR_WRITE] = handle_wrmsr, [EXIT_REASON_PENDING_INTERRUPT] = handle_interrupt_window, [EXIT_REASON_HLT] = handle_halt, + [EXIT_REASON_VMCALL] = handle_vmcall, }; static const int kvm_vmx_max_exit_handlers = @@ -2062,6 +2082,7 @@ static struct kvm_arch_ops vmx_arch_ops = { .run = vmx_vcpu_run, .skip_emulated_instruction = skip_emulated_instruction, .vcpu_setup = vmx_vcpu_setup, + .patch_hypercall = vmx_patch_hypercall, }; static int __init vmx_init(void) diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index a1be1e279df..b0466b88f52 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -56,7 +56,8 @@ MODULE_PARM_DESC(debug,"enable debug messages [blackbird]"); /* ------------------------------------------------------------------ */ -#define BLACKBIRD_FIRM_IMAGE_SIZE 256*1024 +#define OLD_BLACKBIRD_FIRM_IMAGE_SIZE 262144 +#define BLACKBIRD_FIRM_IMAGE_SIZE 376836 /* defines below are from ivtv-driver.h */ @@ -404,7 +405,7 @@ static int blackbird_find_mailbox(struct cx8802_dev *dev) u32 value; int i; - for (i = 0; i < BLACKBIRD_FIRM_IMAGE_SIZE; i++) { + for (i = 0; i < dev->fw_size; i++) { memory_read(dev->core, i, &value); if (value == signature[signaturecnt]) signaturecnt++; @@ -452,12 +453,15 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) return -1; } - if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) { - dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d)\n", - firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE); + if ((firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) && + (firmware->size != OLD_BLACKBIRD_FIRM_IMAGE_SIZE)) { + dprintk(0, "ERROR: Firmware size mismatch (have %zd, expected %d or %d)\n", + firmware->size, BLACKBIRD_FIRM_IMAGE_SIZE, + OLD_BLACKBIRD_FIRM_IMAGE_SIZE); release_firmware(firmware); return -1; } + dev->fw_size = firmware->size; if (0 != memcmp(firmware->data, magic, 8)) { dprintk(0, "ERROR: Firmware magic mismatch, wrong file?\n"); diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index d2ecfba9bb4..a4f7befda5b 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -463,6 +463,7 @@ struct cx8802_dev { u32 mailbox; int width; int height; + int fw_size; #if defined(CONFIG_VIDEO_BUF_DVB) || defined(CONFIG_VIDEO_BUF_DVB_MODULE) /* for dvb only */ diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 1cd4bb3ae26..1ff5138e4bb 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1268,7 +1268,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) if (fw_len % sizeof(u32)) { pvr2_trace(PVR2_TRACE_ERROR_LEGS, "size of %s firmware" - " must be a multiple of %u bytes", + " must be a multiple of %zu bytes", fw_files[fwidx],sizeof(u32)); release_firmware(fw_entry); return -1; diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 6f93a765e56..12c8453f44b 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -448,8 +448,7 @@ static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) spin_lock_irqsave(&cp->lock, flags); cp->cpcmd &= ~RxVlanOn; cpw16(CpCmd, cp->cpcmd); - if (cp->vlgrp) - cp->vlgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(cp->vlgrp, vid, NULL); spin_unlock_irqrestore(&cp->lock, flags); } #endif /* CP_VLAN_TAG_USED */ diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index 33c6645455a..7138e0e025b 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -2293,10 +2293,7 @@ static void ace_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) local_irq_save(flags); ace_mask_irq(dev); - - if (ap->vlgrp) - ap->vlgrp->vlan_devices[vid] = NULL; - + vlan_group_set_device(ap->vlgrp, vid, NULL); ace_unmask_irq(dev); local_irq_restore(flags); } diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index 9c399aaefbd..962c954c2d5 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -1737,8 +1737,7 @@ static void amd8111e_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid { struct amd8111e_priv *lp = netdev_priv(dev); spin_lock_irq(&lp->lock); - if (lp->vlgrp) - lp->vlgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(lp->vlgrp, vid, NULL); spin_unlock_irq(&lp->lock); } #endif diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c index 65673485bb6..88d4f70035b 100644 --- a/drivers/net/atl1/atl1_main.c +++ b/drivers/net/atl1/atl1_main.c @@ -1252,8 +1252,7 @@ static void atl1_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) spin_lock_irqsave(&adapter->lock, flags); /* atl1_irq_disable(adapter); */ - if (adapter->vlgrp) - adapter->vlgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(adapter->vlgrp, vid, NULL); /* atl1_irq_enable(adapter); */ spin_unlock_irqrestore(&adapter->lock, flags); /* We don't do Vlan filtering */ @@ -1266,7 +1265,7 @@ static void atl1_restore_vlan(struct atl1_adapter *adapter) if (adapter->vlgrp) { u16 vid; for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { - if (!adapter->vlgrp->vlan_devices[vid]) + if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; atl1_vlan_rx_add_vid(adapter->netdev, vid); } diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 5a96d7611af..c12e5ea6181 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -4467,9 +4467,7 @@ bnx2_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) struct bnx2 *bp = netdev_priv(dev); bnx2_netif_stop(bp); - - if (bp->vlgrp) - bp->vlgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(bp->vlgrp, vid, NULL); bnx2_set_rx_mode(dev); bnx2_netif_start(bp); diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index a7c8f98a890..ea73ebff438 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -488,9 +488,9 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid) /* Save and then restore vlan_dev in the grp array, * since the slave's driver might clear it. */ - vlan_dev = bond->vlgrp->vlan_devices[vid]; + vlan_dev = vlan_group_get_device(bond->vlgrp, vid); slave_dev->vlan_rx_kill_vid(slave_dev, vid); - bond->vlgrp->vlan_devices[vid] = vlan_dev; + vlan_group_set_device(bond->vlgrp, vid, vlan_dev); } } @@ -550,9 +550,9 @@ static void bond_del_vlans_from_slave(struct bonding *bond, struct net_device *s /* Save and then restore vlan_dev in the grp array, * since the slave's driver might clear it. */ - vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id]; + vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); slave_dev->vlan_rx_kill_vid(slave_dev, vlan->vlan_id); - bond->vlgrp->vlan_devices[vlan->vlan_id] = vlan_dev; + vlan_group_set_device(bond->vlgrp, vlan->vlan_id, vlan_dev); } unreg: @@ -2397,7 +2397,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) vlan_id = 0; list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list, vlan_list) { - vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id]; + vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); if (vlan_dev == rt->u.dst.dev) { vlan_id = vlan->vlan_id; dprintk("basa: vlan match on %s %d\n", @@ -2444,7 +2444,7 @@ static void bond_send_gratuitous_arp(struct bonding *bond) } list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { - vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id]; + vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); if (vlan->vlan_ip) { bond_arp_send(slave->dev, ARPOP_REPLY, vlan->vlan_ip, vlan->vlan_ip, vlan->vlan_id); @@ -3371,7 +3371,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list, vlan_list) { - vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id]; + vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); if (vlan_dev == event_dev) { switch (event) { case NETDEV_UP: diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c index 7d0f24f6977..125c9b10586 100644 --- a/drivers/net/chelsio/cxgb2.c +++ b/drivers/net/chelsio/cxgb2.c @@ -889,8 +889,7 @@ static void vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) struct adapter *adapter = dev->priv; spin_lock_irq(&adapter->async_lock); - if (adapter->vlan_grp) - adapter->vlan_grp->vlan_devices[vid] = NULL; + vlan_group_set_device(adapter->vlan_grp, vid, NULL); spin_unlock_irq(&adapter->async_lock); } #endif diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index b2cf5f6feb4..f6ed033efb5 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -160,14 +160,16 @@ static struct net_device *get_iff_from_mac(struct adapter *adapter, int i; for_each_port(adapter, i) { - const struct vlan_group *grp; + struct vlan_group *grp; struct net_device *dev = adapter->port[i]; const struct port_info *p = netdev_priv(dev); if (!memcmp(dev->dev_addr, mac, ETH_ALEN)) { if (vlan && vlan != VLAN_VID_MASK) { grp = p->vlan_grp; - dev = grp ? grp->vlan_devices[vlan] : NULL; + dev = NULL; + if (grp) + dev = vlan_group_get_device(grp, vlan); } else while (dev->master) dev = dev->master; diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 98215fdd7d1..1d08e937af8 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -376,7 +376,7 @@ e1000_update_mng_vlan(struct e1000_adapter *adapter) uint16_t vid = adapter->hw.mng_cookie.vlan_id; uint16_t old_vid = adapter->mng_vlan_id; if (adapter->vlgrp) { - if (!adapter->vlgrp->vlan_devices[vid]) { + if (!vlan_group_get_device(adapter->vlgrp, vid)) { if (adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) { e1000_vlan_rx_add_vid(netdev, vid); @@ -386,7 +386,7 @@ e1000_update_mng_vlan(struct e1000_adapter *adapter) if ((old_vid != (uint16_t)E1000_MNG_VLAN_NONE) && (vid != old_vid) && - !adapter->vlgrp->vlan_devices[old_vid]) + !vlan_group_get_device(adapter->vlgrp, old_vid)) e1000_vlan_rx_kill_vid(netdev, old_vid); } else adapter->mng_vlan_id = vid; @@ -1482,7 +1482,7 @@ e1000_close(struct net_device *netdev) if ((adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) && !(adapter->vlgrp && - adapter->vlgrp->vlan_devices[adapter->mng_vlan_id])) { + vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) { e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); } @@ -4998,10 +4998,7 @@ e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid) uint32_t vfta, index; e1000_irq_disable(adapter); - - if (adapter->vlgrp) - adapter->vlgrp->vlan_devices[vid] = NULL; - + vlan_group_set_device(adapter->vlgrp, vid, NULL); e1000_irq_enable(adapter); if ((adapter->hw.mng_cookie.status & @@ -5027,7 +5024,7 @@ e1000_restore_vlan(struct e1000_adapter *adapter) if (adapter->vlgrp) { uint16_t vid; for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { - if (!adapter->vlgrp->vlan_devices[vid]) + if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; e1000_vlan_rx_add_vid(adapter->netdev, vid); } diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 88ad1c8bcee..0e4042bc0a4 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -1939,8 +1939,7 @@ static void ehea_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) int index; u64 hret; - if (port->vgrp) - port->vgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(port->vgrp, vid, NULL); cb1 = kzalloc(PAGE_SIZE, GFP_KERNEL); if (!cb1) { diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 1f83988a6a6..02b61b85b62 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1132,8 +1132,7 @@ static void gfar_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) spin_lock_irqsave(&priv->rxlock, flags); - if (priv->vlgrp) - priv->vlgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(priv->vgrp, vid, NULL); spin_unlock_irqrestore(&priv->rxlock, flags); } diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 0c368288934..afc2ec72529 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -2213,8 +2213,7 @@ ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid) ixgb_irq_disable(adapter); - if(adapter->vlgrp) - adapter->vlgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(adapter->vlgrp, vid, NULL); ixgb_irq_enable(adapter); @@ -2234,7 +2233,7 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter) if(adapter->vlgrp) { uint16_t vid; for(vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { - if(!adapter->vlgrp->vlan_devices[vid]) + if(!vlan_group_get_device(adapter->vlgrp, vid)) continue; ixgb_vlan_rx_add_vid(adapter->netdev, vid); } diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 568daeb3e9d..9ec6e9e54f4 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -514,8 +514,7 @@ static void ns83820_vlan_rx_kill_vid(struct net_device *ndev, unsigned short vid spin_lock_irq(&dev->misc_lock); spin_lock(&dev->tx_lock); - if (dev->vlgrp) - dev->vlgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(dev->vlgrp, vid, NULL); spin_unlock(&dev->tx_lock); spin_unlock_irq(&dev->misc_lock); } diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 860bb0f60f6..86e56f1f2f0 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -7,6 +7,12 @@ * * Version: 0.7.0 * + * 070228 : Fix to allow multiple sessions with same remote MAC and same + * session id by including the local device ifindex in the + * tuple identifying a session. This also ensures packets can't + * be injected into a session from interfaces other than the one + * specified by userspace. Florian Zumbiehl <florz@florz.de> + * (Oh, BTW, this one is YYMMDD, in case you were wondering ...) * 220102 : Fix module use count on failure in pppoe_create, pppox_sk -acme * 030700 : Fixed connect logic to allow for disconnect. * 270700 : Fixed potential SMP problems; we must protect against @@ -127,14 +133,14 @@ static struct pppox_sock *item_hash_table[PPPOE_HASH_SIZE]; * Set/get/delete/rehash items (internal versions) * **********************************************************************/ -static struct pppox_sock *__get_item(unsigned long sid, unsigned char *addr) +static struct pppox_sock *__get_item(unsigned long sid, unsigned char *addr, int ifindex) { int hash = hash_item(sid, addr); struct pppox_sock *ret; ret = item_hash_table[hash]; - while (ret && !cmp_addr(&ret->pppoe_pa, sid, addr)) + while (ret && !(cmp_addr(&ret->pppoe_pa, sid, addr) && ret->pppoe_dev->ifindex == ifindex)) ret = ret->next; return ret; @@ -147,21 +153,19 @@ static int __set_item(struct pppox_sock *po) ret = item_hash_table[hash]; while (ret) { - if (cmp_2_addr(&ret->pppoe_pa, &po->pppoe_pa)) + if (cmp_2_addr(&ret->pppoe_pa, &po->pppoe_pa) && ret->pppoe_dev->ifindex == po->pppoe_dev->ifindex) return -EALREADY; ret = ret->next; } - if (!ret) { - po->next = item_hash_table[hash]; - item_hash_table[hash] = po; - } + po->next = item_hash_table[hash]; + item_hash_table[hash] = po; return 0; } -static struct pppox_sock *__delete_item(unsigned long sid, char *addr) +static struct pppox_sock *__delete_item(unsigned long sid, char *addr, int ifindex) { int hash = hash_item(sid, addr); struct pppox_sock *ret, **src; @@ -170,7 +174,7 @@ static struct pppox_sock *__delete_item(unsigned long sid, char *addr) src = &item_hash_table[hash]; while (ret) { - if (cmp_addr(&ret->pppoe_pa, sid, addr)) { + if (cmp_addr(&ret->pppoe_pa, sid, addr) && ret->pppoe_dev->ifindex == ifindex) { *src = ret->next; break; } @@ -188,12 +192,12 @@ static struct pppox_sock *__delete_item(unsigned long sid, char *addr) * **********************************************************************/ static inline struct pppox_sock *get_item(unsigned long sid, - unsigned char *addr) + unsigned char *addr, int ifindex) { struct pppox_sock *po; read_lock_bh(&pppoe_hash_lock); - po = __get_item(sid, addr); + po = __get_item(sid, addr, ifindex); if (po) sock_hold(sk_pppox(po)); read_unlock_bh(&pppoe_hash_lock); @@ -203,7 +207,15 @@ static inline struct pppox_sock *get_item(unsigned long sid, static inline struct pppox_sock *get_item_by_addr(struct sockaddr_pppox *sp) { - return get_item(sp->sa_addr.pppoe.sid, sp->sa_addr.pppoe.remote); + struct net_device *dev = NULL; + int ifindex; + + dev = dev_get_by_name(sp->sa_addr.pppoe.dev); + if(!dev) + return NULL; + ifindex = dev->ifindex; + dev_put(dev); + return get_item(sp->sa_addr.pppoe.sid, sp->sa_addr.pppoe.remote, ifindex); } static inline int set_item(struct pppox_sock *po) @@ -220,12 +232,12 @@ static inline int set_item(struct pppox_sock *po) return i; } -static inline struct pppox_sock *delete_item(unsigned long sid, char *addr) +static inline struct pppox_sock *delete_item(unsigned long sid, char *addr, int ifindex) { struct pppox_sock *ret; write_lock_bh(&pppoe_hash_lock); - ret = __delete_item(sid, addr); + ret = __delete_item(sid, addr, ifindex); write_unlock_bh(&pppoe_hash_lock); return ret; @@ -391,7 +403,7 @@ static int pppoe_rcv(struct sk_buff *skb, ph = (struct pppoe_hdr *) skb->nh.raw; - po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source); + po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source, dev->ifindex); if (po != NULL) return sk_receive_skb(sk_pppox(po), skb, 0); drop: @@ -425,7 +437,7 @@ static int pppoe_disc_rcv(struct sk_buff *skb, if (ph->code != PADT_CODE) goto abort; - po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source); + po = get_item((unsigned long) ph->sid, eth_hdr(skb)->h_source, dev->ifindex); if (po) { struct sock *sk = sk_pppox(po); @@ -517,7 +529,7 @@ static int pppoe_release(struct socket *sock) po = pppox_sk(sk); if (po->pppoe_pa.sid) { - delete_item(po->pppoe_pa.sid, po->pppoe_pa.remote); + delete_item(po->pppoe_pa.sid, po->pppoe_pa.remote, po->pppoe_dev->ifindex); } if (po->pppoe_dev) @@ -539,7 +551,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, int sockaddr_len, int flags) { struct sock *sk = sock->sk; - struct net_device *dev = NULL; + struct net_device *dev; struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr; struct pppox_sock *po = pppox_sk(sk); int error; @@ -565,7 +577,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, pppox_unbind_sock(sk); /* Delete the old binding */ - delete_item(po->pppoe_pa.sid,po->pppoe_pa.remote); + delete_item(po->pppoe_pa.sid,po->pppoe_pa.remote,po->pppoe_dev->ifindex); if(po->pppoe_dev) dev_put(po->pppoe_dev); @@ -705,7 +717,7 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd, break; /* PPPoE address from the user specifies an outbound - PPPoE address to which frames are forwarded to */ + PPPoE address which frames are forwarded to */ err = -EFAULT; if (copy_from_user(&po->pppoe_relay, (void __user *)arg, diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 13cf06ee97f..15d954e50ca 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -890,8 +890,7 @@ static void rtl8169_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) unsigned long flags; spin_lock_irqsave(&tp->lock, flags); - if (tp->vlgrp) - tp->vlgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(tp->vlgrp, vid, NULL); spin_unlock_irqrestore(&tp->lock, flags); } diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 44bb2395af8..46ebf141ee5 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -325,8 +325,7 @@ static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid) unsigned long flags; spin_lock_irqsave(&nic->tx_lock, flags); - if (nic->vlgrp) - nic->vlgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(nic->vlgrp, vid, NULL); spin_unlock_irqrestore(&nic->tx_lock, flags); } diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 52edbd7ac17..53839979cfb 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1053,8 +1053,7 @@ static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), RX_VLAN_STRIP_OFF); sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_VLAN_TAG_OFF); - if (sky2->vlgrp) - sky2->vlgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(sky2->vlgrp, vid, NULL); netif_tx_unlock_bh(dev); } diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index bf873ea2579..8bba2e3da7e 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -677,8 +677,7 @@ static void netdev_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) spin_lock(&np->lock); if (debug > 1) printk("%s: removing vlanid %d from vlan filter\n", dev->name, vid); - if (np->vlgrp) - np->vlgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(np->vlgrp, vid, NULL); set_rx_mode(dev); spin_unlock(&np->lock); } @@ -1738,7 +1737,7 @@ static void set_rx_mode(struct net_device *dev) int vlan_count = 0; void __iomem *filter_addr = ioaddr + HashTable + 8; for (i = 0; i < VLAN_VID_MASK; i++) { - if (np->vlgrp->vlan_devices[i]) { + if (vlan_group_get_device(np->vlgrp, i)) { if (vlan_count >= 32) break; writew(cpu_to_be16(i), filter_addr); diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 26c6ac48288..8c8f9f4d47a 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -9114,8 +9114,7 @@ static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) tg3_netif_stop(tp); tg3_full_lock(tp, 0); - if (tp->vlgrp) - tp->vlgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(tp->vlgrp, vid, NULL); tg3_full_unlock(tp); if (netif_running(dev)) diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 9781b16bb8b..0d91d094edd 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -746,8 +746,7 @@ typhoon_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) { struct typhoon *tp = netdev_priv(dev); spin_lock_bh(&tp->state_lock); - if(tp->vlgrp) - tp->vlgrp->vlan_devices[vid] = NULL; + vlan_group_set_device(tp->vlgrp, vid, NULL); spin_unlock_bh(&tp->state_lock); } diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c index 9040d7cf651..65ad2e24caf 100644 --- a/drivers/net/wan/hdlc.c +++ b/drivers/net/wan/hdlc.c @@ -38,7 +38,7 @@ #include <linux/hdlc.h> -static const char* version = "HDLC support module revision 1.20"; +static const char* version = "HDLC support module revision 1.21"; #undef DEBUG_LINK @@ -222,19 +222,31 @@ int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return -EINVAL; } +static void hdlc_setup_dev(struct net_device *dev) +{ + /* Re-init all variables changed by HDLC protocol drivers, + * including ether_setup() called from hdlc_raw_eth.c. + */ + dev->get_stats = hdlc_get_stats; + dev->flags = IFF_POINTOPOINT | IFF_NOARP; + dev->mtu = HDLC_MAX_MTU; + dev->type = ARPHRD_RAWHDLC; + dev->hard_header_len = 16; + dev->addr_len = 0; + dev->hard_header = NULL; + dev->rebuild_header = NULL; + dev->set_mac_address = NULL; + dev->hard_header_cache = NULL; + dev->header_cache_update = NULL; + dev->change_mtu = hdlc_change_mtu; + dev->hard_header_parse = NULL; +} + static void hdlc_setup(struct net_device *dev) { hdlc_device *hdlc = dev_to_hdlc(dev); - dev->get_stats = hdlc_get_stats; - dev->change_mtu = hdlc_change_mtu; - dev->mtu = HDLC_MAX_MTU; - - dev->type = ARPHRD_RAWHDLC; - dev->hard_header_len = 16; - - dev->flags = IFF_POINTOPOINT | IFF_NOARP; - + hdlc_setup_dev(dev); hdlc->carrier = 1; hdlc->open = 0; spin_lock_init(&hdlc->state_lock); @@ -294,6 +306,7 @@ void detach_hdlc_protocol(struct net_device *dev) } kfree(hdlc->state); hdlc->state = NULL; + hdlc_setup_dev(dev); } diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index b0bc5ddcf1b..c9664fd8a91 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c @@ -365,10 +365,7 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr) memcpy(&state(hdlc)->settings, &new_settings, size); dev->hard_start_xmit = hdlc->xmit; dev->hard_header = cisco_hard_header; - dev->hard_header_cache = NULL; dev->type = ARPHRD_CISCO; - dev->flags = IFF_POINTOPOINT | IFF_NOARP; - dev->addr_len = 0; netif_dormant_on(dev); return 0; } diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index b45ab680d2d..c6c3c757d6f 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c @@ -1289,10 +1289,7 @@ static int fr_ioctl(struct net_device *dev, struct ifreq *ifr) memcpy(&state(hdlc)->settings, &new_settings, size); dev->hard_start_xmit = hdlc->xmit; - dev->hard_header = NULL; dev->type = ARPHRD_FRAD; - dev->flags = IFF_POINTOPOINT | IFF_NOARP; - dev->addr_len = 0; return 0; case IF_PROTO_FR_ADD_PVC: diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c index e9f717070fd..4591437dd2f 100644 --- a/drivers/net/wan/hdlc_ppp.c +++ b/drivers/net/wan/hdlc_ppp.c @@ -127,9 +127,7 @@ static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr) if (result) return result; dev->hard_start_xmit = hdlc->xmit; - dev->hard_header = NULL; dev->type = ARPHRD_PPP; - dev->addr_len = 0; netif_dormant_off(dev); return 0; } diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c index fe3cae5c6b9..e23bc665626 100644 --- a/drivers/net/wan/hdlc_raw.c +++ b/drivers/net/wan/hdlc_raw.c @@ -88,10 +88,7 @@ static int raw_ioctl(struct net_device *dev, struct ifreq *ifr) return result; memcpy(hdlc->state, &new_settings, size); dev->hard_start_xmit = hdlc->xmit; - dev->hard_header = NULL; dev->type = ARPHRD_RAWHDLC; - dev->flags = IFF_POINTOPOINT | IFF_NOARP; - dev->addr_len = 0; netif_dormant_off(dev); return 0; } diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c index e4bb9f8ad43..cd7b22f50ed 100644 --- a/drivers/net/wan/hdlc_x25.c +++ b/drivers/net/wan/hdlc_x25.c @@ -215,9 +215,7 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr) x25_rx, 0)) != 0) return result; dev->hard_start_xmit = x25_xmit; - dev->hard_header = NULL; dev->type = ARPHRD_X25; - dev->addr_len = 0; netif_dormant_off(dev); return 0; } diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index deef29646e0..95826b92ca4 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -207,10 +207,12 @@ config RTC_DRV_PCF8563 config RTC_DRV_PCF8583 tristate "Philips PCF8583" - depends on RTC_CLASS && I2C + depends on RTC_CLASS && I2C && ARCH_RPC help - If you say yes here you get support for the - Philips PCF8583 RTC chip. + If you say yes here you get support for the Philips PCF8583 + RTC chip found on Acorn RiscPCs. This driver supports the + platform specific method of retrieving the current year from + the RTC's SRAM. This driver can also be built as a module. If so, the module will be called rtc-pcf8583. diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index 5875ebb8c79..d48b0337458 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c @@ -40,7 +40,7 @@ struct pcf8583 { #define CTRL_ALARM 0x02 #define CTRL_TIMER 0x01 -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; +static unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END }; /* Module parameters */ I2C_CLIENT_INSMOD; @@ -81,11 +81,11 @@ static int pcf8583_get_datetime(struct i2c_client *client, struct rtc_time *dt) buf[4] &= 0x3f; buf[5] &= 0x1f; - dt->tm_sec = BCD_TO_BIN(buf[1]); - dt->tm_min = BCD_TO_BIN(buf[2]); - dt->tm_hour = BCD_TO_BIN(buf[3]); - dt->tm_mday = BCD_TO_BIN(buf[4]); - dt->tm_mon = BCD_TO_BIN(buf[5]); + dt->tm_sec = BCD2BIN(buf[1]); + dt->tm_min = BCD2BIN(buf[2]); + dt->tm_hour = BCD2BIN(buf[3]); + dt->tm_mday = BCD2BIN(buf[4]); + dt->tm_mon = BCD2BIN(buf[5]) - 1; } return ret == 2 ? 0 : -EIO; @@ -99,14 +99,14 @@ static int pcf8583_set_datetime(struct i2c_client *client, struct rtc_time *dt, buf[0] = 0; buf[1] = get_ctrl(client) | 0x80; buf[2] = 0; - buf[3] = BIN_TO_BCD(dt->tm_sec); - buf[4] = BIN_TO_BCD(dt->tm_min); - buf[5] = BIN_TO_BCD(dt->tm_hour); + buf[3] = BIN2BCD(dt->tm_sec); + buf[4] = BIN2BCD(dt->tm_min); + buf[5] = BIN2BCD(dt->tm_hour); if (datetoo) { len = 8; - buf[6] = BIN_TO_BCD(dt->tm_mday) | (dt->tm_year << 6); - buf[7] = BIN_TO_BCD(dt->tm_mon) | (dt->tm_wday << 5); + buf[6] = BIN2BCD(dt->tm_mday) | (dt->tm_year << 6); + buf[7] = BIN2BCD(dt->tm_mon + 1) | (dt->tm_wday << 5); } ret = i2c_master_send(client, (char *)buf, len); @@ -226,7 +226,7 @@ static int pcf8583_rtc_read_time(struct device *dev, struct rtc_time *tm) */ year_offset += 4; - tm->tm_year = real_year + year_offset + year[1] * 100; + tm->tm_year = (real_year + year_offset + year[1] * 100) - 1900; return 0; } @@ -237,6 +237,7 @@ static int pcf8583_rtc_set_time(struct device *dev, struct rtc_time *tm) unsigned char year[2], chk; struct rtc_mem cmos_year = { CMOS_YEAR, sizeof(year), year }; struct rtc_mem cmos_check = { CMOS_CHECKSUM, 1, &chk }; + unsigned int proper_year = tm->tm_year + 1900; int ret; /* @@ -258,8 +259,8 @@ static int pcf8583_rtc_set_time(struct device *dev, struct rtc_time *tm) chk -= year[1] + year[0]; - year[1] = tm->tm_year / 100; - year[0] = tm->tm_year % 100; + year[1] = proper_year / 100; + year[0] = proper_year % 100; chk += year[1] + year[0]; diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 2257e45594b..d8a86f5af37 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -3654,7 +3654,7 @@ qeth_verify_vlan_dev(struct net_device *dev, struct qeth_card *card) return rc; for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++){ - if (vg->vlan_devices[i] == dev){ + if (vlan_group_get_device(vg, i) == dev){ rc = QETH_VLAN_CARD; break; } @@ -5261,7 +5261,7 @@ qeth_free_vlan_addresses4(struct qeth_card *card, unsigned short vid) QETH_DBF_TEXT(trace, 4, "frvaddr4"); rcu_read_lock(); - in_dev = __in_dev_get_rcu(card->vlangrp->vlan_devices[vid]); + in_dev = __in_dev_get_rcu(vlan_group_get_device(card->vlangrp, vid)); if (!in_dev) goto out; for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { @@ -5288,7 +5288,7 @@ qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid) QETH_DBF_TEXT(trace, 4, "frvaddr6"); - in6_dev = in6_dev_get(card->vlangrp->vlan_devices[vid]); + in6_dev = in6_dev_get(vlan_group_get_device(card->vlangrp, vid)); if (!in6_dev) return; for (ifa = in6_dev->addr_list; ifa; ifa = ifa->lst_next){ @@ -5360,7 +5360,7 @@ qeth_layer2_process_vlans(struct qeth_card *card, int clear) if (!card->vlangrp) return; for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { - if (card->vlangrp->vlan_devices[i] == NULL) + if (vlan_group_get_device(card->vlangrp, i) == NULL) continue; if (clear) qeth_layer2_send_setdelvlan(card, i, IPA_CMD_DELVLAN); @@ -5398,8 +5398,7 @@ qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) spin_lock_irqsave(&card->vlanlock, flags); /* unregister IP addresses of vlan device */ qeth_free_vlan_addresses(card, vid); - if (card->vlangrp) - card->vlangrp->vlan_devices[vid] = NULL; + vlan_group_set_device(card->vlangrp, vid, NULL); spin_unlock_irqrestore(&card->vlanlock, flags); if (card->options.layer2) qeth_layer2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN); @@ -5662,10 +5661,11 @@ qeth_add_vlan_mc(struct qeth_card *card) vg = card->vlangrp; for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { - if (vg->vlan_devices[i] == NULL || - !(vg->vlan_devices[i]->flags & IFF_UP)) + struct net_device *netdev = vlan_group_get_device(vg, i); + if (netdev == NULL || + !(netdev->flags & IFF_UP)) continue; - in_dev = in_dev_get(vg->vlan_devices[i]); + in_dev = in_dev_get(netdev); if (!in_dev) continue; read_lock(&in_dev->mc_list_lock); @@ -5749,10 +5749,11 @@ qeth_add_vlan_mc6(struct qeth_card *card) vg = card->vlangrp; for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { - if (vg->vlan_devices[i] == NULL || - !(vg->vlan_devices[i]->flags & IFF_UP)) + struct net_device *netdev = vlan_group_get_device(vg, i); + if (netdev == NULL || + !(netdev->flags & IFF_UP)) continue; - in_dev = in6_dev_get(vg->vlan_devices[i]); + in_dev = in6_dev_get(netdev); if (!in_dev) continue; read_lock(&in_dev->lock); diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c index d2d51dc51ab..82add77ad13 100644 --- a/drivers/scsi/arm/cumana_2.c +++ b/drivers/scsi/arm/cumana_2.c @@ -178,10 +178,10 @@ cumanascsi_2_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp, dma_dir = DMA_MODE_READ, alatch_dir = ALATCH_DMA_IN; - dma_map_sg(dev, info->sg, bufs + 1, map_dir); + dma_map_sg(dev, info->sg, bufs, map_dir); disable_dma(dmach); - set_dma_sg(dmach, info->sg, bufs + 1); + set_dma_sg(dmach, info->sg, bufs); writeb(alatch_dir, info->base + CUMANASCSI2_ALATCH); set_dma_mode(dmach, dma_dir); enable_dma(dmach); diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c index d4136524fc4..ed06a8c19ad 100644 --- a/drivers/scsi/arm/eesox.c +++ b/drivers/scsi/arm/eesox.c @@ -175,10 +175,10 @@ eesoxscsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp, map_dir = DMA_FROM_DEVICE, dma_dir = DMA_MODE_READ; - dma_map_sg(dev, info->sg, bufs + 1, map_dir); + dma_map_sg(dev, info->sg, bufs, map_dir); disable_dma(dmach); - set_dma_sg(dmach, info->sg, bufs + 1); + set_dma_sg(dmach, info->sg, bufs); set_dma_mode(dmach, dma_dir); enable_dma(dmach); return fasdma_real_all; diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index 2969cc0ff25..fb5f2028438 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c @@ -633,7 +633,7 @@ static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred) BUG_ON(bytes_transferred < 0); - info->SCpnt->request_bufflen -= bytes_transferred; + SCp->phase -= bytes_transferred; while (bytes_transferred != 0) { if (SCp->this_residual > bytes_transferred) @@ -715,7 +715,7 @@ static void fas216_cleanuptransfer(FAS216_Info *info) return; if (dmatype == fasdma_real_all) - total = info->SCpnt->request_bufflen; + total = info->scsi.SCp.phase; else total = info->scsi.SCp.this_residual; @@ -753,7 +753,7 @@ static void fas216_transfer(FAS216_Info *info) fas216_log(info, LOG_BUFFER, "starttransfer: buffer %p length 0x%06x reqlen 0x%06x", info->scsi.SCp.ptr, info->scsi.SCp.this_residual, - info->SCpnt->request_bufflen); + info->scsi.SCp.phase); if (!info->scsi.SCp.ptr) { fas216_log(info, LOG_ERROR, "null buffer passed to " @@ -784,7 +784,7 @@ static void fas216_transfer(FAS216_Info *info) info->dma.transfer_type = dmatype; if (dmatype == fasdma_real_all) - fas216_set_stc(info, info->SCpnt->request_bufflen); + fas216_set_stc(info, info->scsi.SCp.phase); else fas216_set_stc(info, info->scsi.SCp.this_residual); @@ -2114,6 +2114,7 @@ request_sense: SCpnt->SCp.buffers_residual = 0; SCpnt->SCp.ptr = (char *)SCpnt->sense_buffer; SCpnt->SCp.this_residual = sizeof(SCpnt->sense_buffer); + SCpnt->SCp.phase = sizeof(SCpnt->sense_buffer); SCpnt->SCp.Message = 0; SCpnt->SCp.Status = 0; SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer); diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c index f9cd20bfb95..159047a3499 100644 --- a/drivers/scsi/arm/powertec.c +++ b/drivers/scsi/arm/powertec.c @@ -148,10 +148,10 @@ powertecscsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp, map_dir = DMA_FROM_DEVICE, dma_dir = DMA_MODE_READ; - dma_map_sg(dev, info->sg, bufs + 1, map_dir); + dma_map_sg(dev, info->sg, bufs, map_dir); disable_dma(dmach); - set_dma_sg(dmach, info->sg, bufs + 1); + set_dma_sg(dmach, info->sg, bufs); set_dma_mode(dmach, dma_dir); enable_dma(dmach); return fasdma_real_all; @@ -342,6 +342,7 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id) info->base = base; powertecscsi_terminator_ctl(host, term[ec->slot_no]); + info->ec = ec; info->info.scsi.io_base = base + POWERTEC_FAS216_OFFSET; info->info.scsi.io_shift = POWERTEC_FAS216_SHIFT; info->info.scsi.irq = ec->irq; diff --git a/drivers/scsi/arm/scsi.h b/drivers/scsi/arm/scsi.h index 3a39579bd08..21ba57155be 100644 --- a/drivers/scsi/arm/scsi.h +++ b/drivers/scsi/arm/scsi.h @@ -80,6 +80,7 @@ static inline void init_SCp(struct scsi_cmnd *SCpnt) (page_address(SCpnt->SCp.buffer->page) + SCpnt->SCp.buffer->offset); SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; + SCpnt->SCp.phase = SCpnt->request_bufflen; #ifdef BELT_AND_BRACES /* @@ -98,6 +99,7 @@ static inline void init_SCp(struct scsi_cmnd *SCpnt) } else { SCpnt->SCp.ptr = (unsigned char *)SCpnt->request_buffer; SCpnt->SCp.this_residual = SCpnt->request_bufflen; + SCpnt->SCp.phase = SCpnt->request_bufflen; } /* diff --git a/include/asm-arm/arch-omap/entry-macro.S b/include/asm-arm/arch-omap/entry-macro.S index c90dff4828f..f6967c8df32 100644 --- a/include/asm-arm/arch-omap/entry-macro.S +++ b/include/asm-arm/arch-omap/entry-macro.S @@ -61,6 +61,12 @@ .macro disable_fiq .endm + .macro get_irqnr_preamble, base, tmp + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp ldr \base, =VA_IC_BASE ldr \irqnr, [\base, #0x98] /* IRQ pending reg 1 */ diff --git a/include/asm-arm/arch-omap/memory.h b/include/asm-arm/arch-omap/memory.h index df50dd53e1d..48fabc49316 100644 --- a/include/asm-arm/arch-omap/memory.h +++ b/include/asm-arm/arch-omap/memory.h @@ -70,7 +70,7 @@ #define virt_to_lbus(x) ((x) - PAGE_OFFSET + OMAP1510_LB_OFFSET) #define lbus_to_virt(x) ((x) - OMAP1510_LB_OFFSET + PAGE_OFFSET) -#define is_lbus_device(dev) (cpu_is_omap1510() && dev && (strncmp(dev->bus_id, "ohci", 4) == 0)) +#define is_lbus_device(dev) (cpu_is_omap15xx() && dev && (strncmp(dev->bus_id, "ohci", 4) == 0)) #define __arch_page_to_dma(dev, page) ({is_lbus_device(dev) ? \ (dma_addr_t)virt_to_lbus(page_address(page)) : \ diff --git a/include/asm-arm/arch-omap/omap-alsa.h b/include/asm-arm/arch-omap/omap-alsa.h index df4695474e3..fcaf44c1471 100644 --- a/include/asm-arm/arch-omap/omap-alsa.h +++ b/include/asm-arm/arch-omap/omap-alsa.h @@ -65,7 +65,7 @@ struct audio_stream { int period; /* current transfer period */ int periods; /* current count of periods registerd in the DMA engine */ spinlock_t dma_lock; /* for locking in DMA operations */ - snd_pcm_substream_t *stream; /* the pcm stream */ + struct snd_pcm_substream *stream; /* the pcm stream */ unsigned linked:1; /* dma channels linked */ int offset; /* store start position of the last period in the alsa buffer */ int (*hw_start)(void); /* interface to start HW interface, e.g. McBSP */ @@ -76,8 +76,8 @@ struct audio_stream { * Alsa card structure for aic23 */ struct snd_card_omap_codec { - snd_card_t *card; - snd_pcm_t *pcm; + struct snd_card *card; + struct snd_pcm *pcm; long samplerate; struct audio_stream s[2]; /* playback & capture */ }; @@ -89,9 +89,9 @@ struct snd_card_omap_codec { struct omap_alsa_codec_config { char *name; struct omap_mcbsp_reg_cfg *mcbsp_regs_alsa; - snd_pcm_hw_constraint_list_t *hw_constraints_rates; - snd_pcm_hardware_t *snd_omap_alsa_playback; - snd_pcm_hardware_t *snd_omap_alsa_capture; + struct snd_pcm_hw_constraint_list *hw_constraints_rates; + struct snd_pcm_hardware *snd_omap_alsa_playback; + struct snd_pcm_hardware *snd_omap_alsa_capture; void (*codec_configure_dev)(void); void (*codec_set_samplerate)(long); void (*codec_clock_setup)(void); diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index f4386906b20..f06d8a43fde 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -167,11 +167,25 @@ extern unsigned int user_debug; : : "r" (0) : "memory") #define dmb() __asm__ __volatile__ ("" : : : "memory") #endif -#define mb() dmb() -#define rmb() mb() -#define wmb() mb() -#define read_barrier_depends() do { } while(0) -#define set_mb(var, value) do { var = value; mb(); } while (0) + +#define mb() barrier() +#define rmb() barrier() +#define wmb() barrier() +#define read_barrier_depends() do { } while(0) + +#ifdef CONFIG_SMP +#define smp_mb() dmb() +#define smp_rmb() dmb() +#define smp_wmb() dmb() +#define smp_read_barrier_depends() read_barrier_depends() +#else +#define smp_mb() barrier() +#define smp_rmb() barrier() +#define smp_wmb() barrier() +#define smp_read_barrier_depends() read_barrier_depends() +#endif /* CONFIG_SMP */ + +#define set_mb(var, value) do { var = value; smp_mb(); } while (0) #define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t"); extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ @@ -243,22 +257,6 @@ static inline void sched_cacheflush(void) { } -#ifdef CONFIG_SMP - -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#define smp_read_barrier_depends() read_barrier_depends() - -#else - -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#define smp_read_barrier_depends() do { } while(0) - -#endif /* CONFIG_SMP */ - #if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) /* * On the StrongARM, "swp" is terminally broken since it bypasses the diff --git a/include/asm-mips/ds1742.h b/include/asm-mips/ds1742.h deleted file mode 100644 index c2f2c32da63..00000000000 --- a/include/asm-mips/ds1742.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006 by Ralf Baechle (ralf@linux-mips.org) - */ -#ifndef _ASM_DS1742_H -#define _ASM_DS1742_H - -#include <ds1742.h> - -#endif /* _ASM_DS1742_H */ diff --git a/include/asm-mips/jmr3927/jmr3927.h b/include/asm-mips/jmr3927/jmr3927.h index baf412967af..c50e68ffa3a 100644 --- a/include/asm-mips/jmr3927/jmr3927.h +++ b/include/asm-mips/jmr3927/jmr3927.h @@ -179,12 +179,6 @@ static inline int jmr3927_have_isac(void) #define jmr3927_have_nvram() \ ((jmr3927_ioc_reg_in(JMR3927_IOC_REV_ADDR) & JMR3927_IDT_MASK) == JMR3927_IOC_IDT) -/* NVRAM macro */ -#define jmr3927_nvram_in(ofs) \ - jmr3927_ioc_reg_in(JMR3927_IOC_NVRAMB_ADDR + ((ofs) << 1)) -#define jmr3927_nvram_out(d, ofs) \ - jmr3927_ioc_reg_out(d, JMR3927_IOC_NVRAMB_ADDR + ((ofs) << 1)) - /* LED macro */ #define jmr3927_led_set(n/*0-16*/) jmr3927_ioc_reg_out(~(n), JMR3927_IOC_LED_ADDR) #define jmr3927_io_led_set(n/*0-3*/) jmr3927_isac_reg_out((n), JMR3927_ISAC_LED_ADDR) diff --git a/include/asm-mips/lasat/lasat.h b/include/asm-mips/lasat/lasat.h index 181afc5c0f1..42077e367a5 100644 --- a/include/asm-mips/lasat/lasat.h +++ b/include/asm-mips/lasat/lasat.h @@ -237,8 +237,6 @@ static inline void lasat_ndelay(unsigned int ns) __delay(ns / lasat_ndelay_divider); } -extern void (* prom_printf)(const char *fmt, ...); - #endif /* !defined (_LANGUAGE_ASSEMBLY) */ #define LASAT_SERVICEMODE_MAGIC_1 0xdeadbeef diff --git a/include/asm-mips/mach-atlas/mc146818rtc.h b/include/asm-mips/mach-atlas/mc146818rtc.h index a73a5698420..51d337e1bbd 100644 --- a/include/asm-mips/mach-atlas/mc146818rtc.h +++ b/include/asm-mips/mach-atlas/mc146818rtc.h @@ -55,6 +55,6 @@ static inline void CMOS_WRITE(unsigned char data, unsigned long addr) #define RTC_ALWAYS_BCD 0 -#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970) +#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1900) #endif /* __ASM_MACH_ATLAS_MC146818RTC_H */ diff --git a/include/asm-mips/mach-generic/dma-coherence.h b/include/asm-mips/mach-generic/dma-coherence.h index df71822fd27..76e04e7feb8 100644 --- a/include/asm-mips/mach-generic/dma-coherence.h +++ b/include/asm-mips/mach-generic/dma-coherence.h @@ -11,22 +11,24 @@ struct device; -static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) +static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, + size_t size) { return virt_to_phys(addr); } -static dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) +static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, + struct page *page) { return page_to_phys(page); } -static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr) +static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr) { return dma_addr; } -static void plat_unmap_dma_mem(dma_addr_t dma_addr) +static inline void plat_unmap_dma_mem(dma_addr_t dma_addr) { } diff --git a/include/asm-mips/mach-generic/mc146818rtc.h b/include/asm-mips/mach-generic/mc146818rtc.h index 90c2e6f77fa..0b9a942f079 100644 --- a/include/asm-mips/mach-generic/mc146818rtc.h +++ b/include/asm-mips/mach-generic/mc146818rtc.h @@ -30,7 +30,7 @@ static inline void CMOS_WRITE(unsigned char data, unsigned long addr) #define RTC_ALWAYS_BCD 1 #ifndef mc146818_decode_year -#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970) +#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1900) #endif #endif /* __ASM_MACH_GENERIC_MC146818RTC_H */ diff --git a/include/asm-mips/mach-jmr3927/ds1742.h b/include/asm-mips/mach-jmr3927/ds1742.h deleted file mode 100644 index 8a8fef6d07f..00000000000 --- a/include/asm-mips/mach-jmr3927/ds1742.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2003, 06 by Ralf Baechle - */ -#ifndef __ASM_MACH_JMR3927_DS1742_H -#define __ASM_MACH_JMR3927_DS1742_H - -#include <asm/jmr3927/jmr3927.h> - -#define rtc_read(reg) (jmr3927_nvram_in(reg)) -#define rtc_write(data, reg) (jmr3927_nvram_out((data),(reg))) - -#endif /* __ASM_MACH_JMR3927_DS1742_H */ diff --git a/include/asm-mips/mach-jmr3927/mangle-port.h b/include/asm-mips/mach-jmr3927/mangle-port.h new file mode 100644 index 00000000000..501a202631b --- /dev/null +++ b/include/asm-mips/mach-jmr3927/mangle-port.h @@ -0,0 +1,18 @@ +#ifndef __ASM_MACH_JMR3927_MANGLE_PORT_H +#define __ASM_MACH_JMR3927_MANGLE_PORT_H + +extern unsigned long __swizzle_addr_b(unsigned long port); +#define __swizzle_addr_w(port) (port) +#define __swizzle_addr_l(port) (port) +#define __swizzle_addr_q(port) (port) + +#define ioswabb(a,x) (x) +#define __mem_ioswabb(a,x) (x) +#define ioswabw(a,x) le16_to_cpu(x) +#define __mem_ioswabw(a,x) (x) +#define ioswabl(a,x) le32_to_cpu(x) +#define __mem_ioswabl(a,x) (x) +#define ioswabq(a,x) le64_to_cpu(x) +#define __mem_ioswabq(a,x) (x) + +#endif /* __ASM_MACH_JMR3927_MANGLE_PORT_H */ diff --git a/include/asm-mips/mach-mips/mc146818rtc.h b/include/asm-mips/mach-mips/mc146818rtc.h index 6730ba06657..ea612f37f61 100644 --- a/include/asm-mips/mach-mips/mc146818rtc.h +++ b/include/asm-mips/mach-mips/mc146818rtc.h @@ -43,6 +43,6 @@ static inline void CMOS_WRITE(unsigned char data, unsigned long addr) #define RTC_ALWAYS_BCD 0 -#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970) +#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1900) #endif /* __ASM_MACH_MALTA_MC146818RTC_H */ diff --git a/include/asm-mips/mach-rm/mc146818rtc.h b/include/asm-mips/mach-rm/mc146818rtc.h index d37ae68dc6a..145bce096fe 100644 --- a/include/asm-mips/mach-rm/mc146818rtc.h +++ b/include/asm-mips/mach-rm/mc146818rtc.h @@ -7,11 +7,15 @@ * * RTC routines for PC style attached Dallas chip with ARC epoch. */ -#ifndef __ASM_MACH_RM200_MC146818RTC_H -#define __ASM_MACH_RM200_MC146818RTC_H +#ifndef __ASM_MACH_RM_MC146818RTC_H +#define __ASM_MACH_RM_MC146818RTC_H +#ifdef CONFIG_CPU_BIG_ENDIAN +#define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1900) +#else #define mc146818_decode_year(year) ((year) + 1980) +#endif #include_next <mc146818rtc.h> -#endif /* __ASM_MACH_RM200_MC146818RTC_H */ +#endif /* __ASM_MACH_RM_MC146818RTC_H */ diff --git a/include/asm-mips/mips-boards/prom.h b/include/asm-mips/mips-boards/prom.h index 7bf6f5f6ab9..daaf9f98fc6 100644 --- a/include/asm-mips/mips-boards/prom.h +++ b/include/asm-mips/mips-boards/prom.h @@ -28,8 +28,6 @@ extern char *prom_getcmdline(void); extern char *prom_getenv(char *name); -extern void setup_prom_printf(int tty_no); -extern void prom_printf(char *fmt, ...); extern void prom_init_cmdline(void); extern void prom_meminit(void); extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem); diff --git a/include/asm-mips/sgialib.h b/include/asm-mips/sgialib.h index 73f09731550..bfce5c786f1 100644 --- a/include/asm-mips/sgialib.h +++ b/include/asm-mips/sgialib.h @@ -33,9 +33,6 @@ extern int prom_flags; extern void prom_putchar(char c); extern char prom_getchar(void); -/* Generic printf() using ARCS console I/O. */ -extern void prom_printf(char *fmt, ...); - /* Memory descriptor management. */ #define PROM_MAX_PMEMBLOCKS 32 struct prom_pmemblock { diff --git a/include/asm-mips/sibyte/sb1250.h b/include/asm-mips/sibyte/sb1250.h index 2ba6988ddc8..dfb29e13bce 100644 --- a/include/asm-mips/sibyte/sb1250.h +++ b/include/asm-mips/sibyte/sb1250.h @@ -57,8 +57,6 @@ extern void bcm1480_mask_irq(int cpu, int irq); extern void bcm1480_unmask_irq(int cpu, int irq); extern void bcm1480_smp_finish(void); -extern void prom_printf(char *fmt, ...); - #define AT_spin \ __asm__ __volatile__ ( \ ".set noat\n" \ diff --git a/include/linux/ds1742rtc.h b/include/linux/ds1742rtc.h deleted file mode 100644 index a83cdd1cafc..00000000000 --- a/include/linux/ds1742rtc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * ds1742rtc.h - register definitions for the Real-Time-Clock / CMOS RAM - * - * Copyright (C) 1999-2001 Toshiba Corporation - * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org) - * - * Permission is hereby granted to copy, modify and redistribute this code - * in terms of the GNU Library General Public License, Version 2 or later, - * at your option. - */ -#ifndef __LINUX_DS1742RTC_H -#define __LINUX_DS1742RTC_H - -#include <asm/ds1742.h> - -#define RTC_BRAM_SIZE 0x800 -#define RTC_OFFSET 0x7f8 - -/* - * Register summary - */ -#define RTC_CONTROL (RTC_OFFSET + 0) -#define RTC_CENTURY (RTC_OFFSET + 0) -#define RTC_SECONDS (RTC_OFFSET + 1) -#define RTC_MINUTES (RTC_OFFSET + 2) -#define RTC_HOURS (RTC_OFFSET + 3) -#define RTC_DAY (RTC_OFFSET + 4) -#define RTC_DATE (RTC_OFFSET + 5) -#define RTC_MONTH (RTC_OFFSET + 6) -#define RTC_YEAR (RTC_OFFSET + 7) - -#define RTC_CENTURY_MASK 0x3f -#define RTC_SECONDS_MASK 0x7f -#define RTC_DAY_MASK 0x07 - -/* - * Bits in the Control/Century register - */ -#define RTC_WRITE 0x80 -#define RTC_READ 0x40 - -/* - * Bits in the Seconds register - */ -#define RTC_STOP 0x80 - -/* - * Bits in the Day register - */ -#define RTC_BATT_FLAG 0x80 -#define RTC_FREQ_TEST 0x40 - -#endif /* __LINUX_DS1742RTC_H */ diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 35cb3857358..d103580c72d 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -70,15 +70,34 @@ extern void vlan_ioctl_set(int (*hook)(void __user *)); * depends on completely exhausting the VLAN identifier space. Thus * it gives constant time look-up, but in many cases it wastes memory. */ -#define VLAN_GROUP_ARRAY_LEN 4096 +#define VLAN_GROUP_ARRAY_LEN 4096 +#define VLAN_GROUP_ARRAY_SPLIT_PARTS 8 +#define VLAN_GROUP_ARRAY_PART_LEN (VLAN_GROUP_ARRAY_LEN/VLAN_GROUP_ARRAY_SPLIT_PARTS) struct vlan_group { int real_dev_ifindex; /* The ifindex of the ethernet(like) device the vlan is attached to. */ struct hlist_node hlist; /* linked list */ - struct net_device *vlan_devices[VLAN_GROUP_ARRAY_LEN]; + struct net_device **vlan_devices_arrays[VLAN_GROUP_ARRAY_SPLIT_PARTS]; struct rcu_head rcu; }; +static inline struct net_device *vlan_group_get_device(struct vlan_group *vg, int vlan_id) +{ + struct net_device **array; + array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; + return array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN]; +} + +static inline void vlan_group_set_device(struct vlan_group *vg, int vlan_id, + struct net_device *dev) +{ + struct net_device **array; + if (!vg) + return; + array = vg->vlan_devices_arrays[vlan_id / VLAN_GROUP_ARRAY_PART_LEN]; + array[vlan_id % VLAN_GROUP_ARRAY_PART_LEN] = dev; +} + struct vlan_priority_tci_mapping { unsigned long priority; unsigned short vlan_qos; /* This should be shifted when first set, so we only do it @@ -160,7 +179,7 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, return NET_RX_DROP; } - skb->dev = grp->vlan_devices[vlan_tag & VLAN_VID_MASK]; + skb->dev = vlan_group_get_device(grp, vlan_tag & VLAN_VID_MASK); if (skb->dev == NULL) { dev_kfree_skb_any(skb); diff --git a/include/linux/kvm.h b/include/linux/kvm.h index f3604593fb7..275354ffa1c 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -11,7 +11,7 @@ #include <asm/types.h> #include <linux/ioctl.h> -#define KVM_API_VERSION 3 +#define KVM_API_VERSION 4 /* * Architectural interrupt line count, and the size of the bitmap needed @@ -52,11 +52,10 @@ enum kvm_exit_reason { /* for KVM_RUN */ struct kvm_run { /* in */ - __u32 vcpu; __u32 emulated; /* skip current instruction */ __u32 mmio_completed; /* mmio request completed */ __u8 request_interrupt_window; - __u8 padding1[3]; + __u8 padding1[7]; /* out */ __u32 exit_type; @@ -111,10 +110,6 @@ struct kvm_run { /* for KVM_GET_REGS and KVM_SET_REGS */ struct kvm_regs { - /* in */ - __u32 vcpu; - __u32 padding; - /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */ __u64 rax, rbx, rcx, rdx; __u64 rsi, rdi, rsp, rbp; @@ -141,10 +136,6 @@ struct kvm_dtable { /* for KVM_GET_SREGS and KVM_SET_SREGS */ struct kvm_sregs { - /* in */ - __u32 vcpu; - __u32 padding; - /* out (KVM_GET_SREGS) / in (KVM_SET_SREGS) */ struct kvm_segment cs, ds, es, fs, gs, ss; struct kvm_segment tr, ldt; @@ -163,8 +154,8 @@ struct kvm_msr_entry { /* for KVM_GET_MSRS and KVM_SET_MSRS */ struct kvm_msrs { - __u32 vcpu; __u32 nmsrs; /* number of msrs in entries */ + __u32 pad; struct kvm_msr_entry entries[0]; }; @@ -179,8 +170,6 @@ struct kvm_msr_list { struct kvm_translation { /* in */ __u64 linear_address; - __u32 vcpu; - __u32 padding; /* out */ __u64 physical_address; @@ -193,7 +182,6 @@ struct kvm_translation { /* for KVM_INTERRUPT */ struct kvm_interrupt { /* in */ - __u32 vcpu; __u32 irq; }; @@ -206,8 +194,8 @@ struct kvm_breakpoint { /* for KVM_DEBUG_GUEST */ struct kvm_debug_guest { /* int */ - __u32 vcpu; __u32 enabled; + __u32 pad; struct kvm_breakpoint breakpoints[4]; __u32 singlestep; }; @@ -224,20 +212,36 @@ struct kvm_dirty_log { #define KVMIO 0xAE +/* + * ioctls for /dev/kvm fds: + */ #define KVM_GET_API_VERSION _IO(KVMIO, 1) +#define KVM_CREATE_VM _IO(KVMIO, 2) /* returns a VM fd */ +#define KVM_GET_MSR_INDEX_LIST _IOWR(KVMIO, 15, struct kvm_msr_list) + +/* + * ioctls for VM fds + */ +#define KVM_SET_MEMORY_REGION _IOW(KVMIO, 10, struct kvm_memory_region) +/* + * KVM_CREATE_VCPU receives as a parameter the vcpu slot, and returns + * a vcpu fd. + */ +#define KVM_CREATE_VCPU _IOW(KVMIO, 11, int) +#define KVM_GET_DIRTY_LOG _IOW(KVMIO, 12, struct kvm_dirty_log) + +/* + * ioctls for vcpu fds + */ #define KVM_RUN _IOWR(KVMIO, 2, struct kvm_run) -#define KVM_GET_REGS _IOWR(KVMIO, 3, struct kvm_regs) +#define KVM_GET_REGS _IOR(KVMIO, 3, struct kvm_regs) #define KVM_SET_REGS _IOW(KVMIO, 4, struct kvm_regs) -#define KVM_GET_SREGS _IOWR(KVMIO, 5, struct kvm_sregs) +#define KVM_GET_SREGS _IOR(KVMIO, 5, struct kvm_sregs) #define KVM_SET_SREGS _IOW(KVMIO, 6, struct kvm_sregs) #define KVM_TRANSLATE _IOWR(KVMIO, 7, struct kvm_translation) #define KVM_INTERRUPT _IOW(KVMIO, 8, struct kvm_interrupt) #define KVM_DEBUG_GUEST _IOW(KVMIO, 9, struct kvm_debug_guest) -#define KVM_SET_MEMORY_REGION _IOW(KVMIO, 10, struct kvm_memory_region) -#define KVM_CREATE_VCPU _IOW(KVMIO, 11, int /* vcpu_slot */) -#define KVM_GET_DIRTY_LOG _IOW(KVMIO, 12, struct kvm_dirty_log) #define KVM_GET_MSRS _IOWR(KVMIO, 13, struct kvm_msrs) -#define KVM_SET_MSRS _IOWR(KVMIO, 14, struct kvm_msrs) -#define KVM_GET_MSR_INDEX_LIST _IOWR(KVMIO, 15, struct kvm_msr_list) +#define KVM_SET_MSRS _IOW(KVMIO, 14, struct kvm_msrs) #endif diff --git a/include/linux/kvm_para.h b/include/linux/kvm_para.h new file mode 100644 index 00000000000..3b292565a69 --- /dev/null +++ b/include/linux/kvm_para.h @@ -0,0 +1,73 @@ +#ifndef __LINUX_KVM_PARA_H +#define __LINUX_KVM_PARA_H + +/* + * Guest OS interface for KVM paravirtualization + * + * Note: this interface is totally experimental, and is certain to change + * as we make progress. + */ + +/* + * Per-VCPU descriptor area shared between guest and host. Writable to + * both guest and host. Registered with the host by the guest when + * a guest acknowledges paravirtual mode. + * + * NOTE: all addresses are guest-physical addresses (gpa), to make it + * easier for the hypervisor to map between the various addresses. + */ +struct kvm_vcpu_para_state { + /* + * API version information for compatibility. If there's any support + * mismatch (too old host trying to execute too new guest) then + * the host will deny entry into paravirtual mode. Any other + * combination (new host + old guest and new host + new guest) + * is supposed to work - new host versions will support all old + * guest API versions. + */ + u32 guest_version; + u32 host_version; + u32 size; + u32 ret; + + /* + * The address of the vm exit instruction (VMCALL or VMMCALL), + * which the host will patch according to the CPU model the + * VM runs on: + */ + u64 hypercall_gpa; + +} __attribute__ ((aligned(PAGE_SIZE))); + +#define KVM_PARA_API_VERSION 1 + +/* + * This is used for an RDMSR's ECX parameter to probe for a KVM host. + * Hopefully no CPU vendor will use up this number. This is placed well + * out of way of the typical space occupied by CPU vendors' MSR indices, + * and we think (or at least hope) it wont be occupied in the future + * either. + */ +#define MSR_KVM_API_MAGIC 0x87655678 + +#define KVM_EINVAL 1 + +/* + * Hypercall calling convention: + * + * Each hypercall may have 0-6 parameters. + * + * 64-bit hypercall index is in RAX, goes from 0 to __NR_hypercalls-1 + * + * 64-bit parameters 1-6 are in the standard gcc x86_64 calling convention + * order: RDI, RSI, RDX, RCX, R8, R9. + * + * 32-bit index is EBX, parameters are: EAX, ECX, EDX, ESI, EDI, EBP. + * (the first 3 are according to the gcc regparm calling convention) + * + * No registers are clobbered by the hypercall, except that the + * return value is in RAX. + */ +#define __NR_hypercalls 0 + +#endif diff --git a/include/linux/magic.h b/include/linux/magic.h index b32c8a97fce..a9c6567fe70 100644 --- a/include/linux/magic.h +++ b/include/linux/magic.h @@ -13,6 +13,7 @@ #define HPFS_SUPER_MAGIC 0xf995e849 #define ISOFS_SUPER_MAGIC 0x9660 #define JFFS2_SUPER_MAGIC 0x72b6 +#define KVMFS_SUPER_MAGIC 0x19700426 #define MINIX_SUPER_MAGIC 0x137F /* original minix fs */ #define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */ diff --git a/include/net/sock.h b/include/net/sock.h index 2c7d60ca354..849c7df2318 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -426,7 +426,7 @@ static inline void sk_acceptq_added(struct sock *sk) static inline int sk_acceptq_is_full(struct sock *sk) { - return sk->sk_ack_backlog > sk->sk_max_ack_backlog; + return sk->sk_ack_backlog >= sk->sk_max_ack_backlog; } /* diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index c1c205fad4f..eb1c71ed7df 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -184,14 +184,23 @@ struct net_device *__find_vlan_dev(struct net_device *real_dev, struct vlan_group *grp = __vlan_find_group(real_dev->ifindex); if (grp) - return grp->vlan_devices[VID]; + return vlan_group_get_device(grp, VID); return NULL; } +static void vlan_group_free(struct vlan_group *grp) +{ + int i; + + for (i=0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) + kfree(grp->vlan_devices_arrays[i]); + kfree(grp); +} + static void vlan_rcu_free(struct rcu_head *rcu) { - kfree(container_of(rcu, struct vlan_group, rcu)); + vlan_group_free(container_of(rcu, struct vlan_group, rcu)); } @@ -223,7 +232,7 @@ static int unregister_vlan_dev(struct net_device *real_dev, ret = 0; if (grp) { - dev = grp->vlan_devices[vlan_id]; + dev = vlan_group_get_device(grp, vlan_id); if (dev) { /* Remove proc entry */ vlan_proc_rem_dev(dev); @@ -237,7 +246,7 @@ static int unregister_vlan_dev(struct net_device *real_dev, real_dev->vlan_rx_kill_vid(real_dev, vlan_id); } - grp->vlan_devices[vlan_id] = NULL; + vlan_group_set_device(grp, vlan_id, NULL); synchronize_net(); @@ -251,7 +260,7 @@ static int unregister_vlan_dev(struct net_device *real_dev, * group. */ for (i = 0; i < VLAN_VID_MASK; i++) - if (grp->vlan_devices[i]) + if (vlan_group_get_device(grp, i)) break; if (i == VLAN_VID_MASK) { @@ -379,6 +388,7 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, struct net_device *new_dev; struct net_device *real_dev; /* the ethernet device */ char name[IFNAMSIZ]; + int i; #ifdef VLAN_DEBUG printk(VLAN_DBG "%s: if_name -:%s:- vid: %i\n", @@ -544,6 +554,15 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, if (!grp) goto out_free_unregister; + for (i=0; i < VLAN_GROUP_ARRAY_SPLIT_PARTS; i++) { + grp->vlan_devices_arrays[i] = kzalloc( + sizeof(struct net_device *)*VLAN_GROUP_ARRAY_PART_LEN, + GFP_KERNEL); + + if (!grp->vlan_devices_arrays[i]) + goto out_free_arrays; + } + /* printk(KERN_ALERT "VLAN REGISTER: Allocated new group.\n"); */ grp->real_dev_ifindex = real_dev->ifindex; @@ -554,7 +573,7 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, real_dev->vlan_rx_register(real_dev, grp); } - grp->vlan_devices[VLAN_ID] = new_dev; + vlan_group_set_device(grp, VLAN_ID, new_dev); if (vlan_proc_add_dev(new_dev)<0)/* create it's proc entry */ printk(KERN_WARNING "VLAN: failed to add proc entry for %s\n", @@ -571,6 +590,9 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, #endif return new_dev; +out_free_arrays: + vlan_group_free(grp); + out_free_unregister: unregister_netdev(new_dev); goto out_unlock; @@ -606,7 +628,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_CHANGE: /* Propagate real device state to vlan devices */ for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { - vlandev = grp->vlan_devices[i]; + vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -617,7 +639,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_DOWN: /* Put all VLANs for this dev in the down state too. */ for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { - vlandev = grp->vlan_devices[i]; + vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -632,7 +654,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_UP: /* Put all VLANs for this dev in the up state too. */ for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { - vlandev = grp->vlan_devices[i]; + vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -649,7 +671,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { int ret; - vlandev = grp->vlan_devices[i]; + vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 60aafb4a8ad..c976dd7e975 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -732,11 +732,12 @@ static int cipso_v4_map_lvl_hton(const struct cipso_v4_doi *doi_def, *net_lvl = host_lvl; return 0; case CIPSO_V4_MAP_STD: - if (host_lvl < doi_def->map.std->lvl.local_size) { + if (host_lvl < doi_def->map.std->lvl.local_size && + doi_def->map.std->lvl.local[host_lvl] < CIPSO_V4_INV_LVL) { *net_lvl = doi_def->map.std->lvl.local[host_lvl]; return 0; } - break; + return -EPERM; } return -EINVAL; @@ -771,7 +772,7 @@ static int cipso_v4_map_lvl_ntoh(const struct cipso_v4_doi *doi_def, *host_lvl = doi_def->map.std->lvl.cipso[net_lvl]; return 0; } - break; + return -EPERM; } return -EINVAL; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 606971645b3..51ca4383c38 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -934,7 +934,7 @@ static long unix_wait_for_peer(struct sock *other, long timeo) sched = !sock_flag(other, SOCK_DEAD) && !(other->sk_shutdown & RCV_SHUTDOWN) && - (skb_queue_len(&other->sk_receive_queue) > + (skb_queue_len(&other->sk_receive_queue) >= other->sk_max_ack_backlog); unix_state_runlock(other); @@ -1008,7 +1008,7 @@ restart: if (other->sk_state != TCP_LISTEN) goto out_unlock; - if (skb_queue_len(&other->sk_receive_queue) > + if (skb_queue_len(&other->sk_receive_queue) >= other->sk_max_ack_backlog) { err = -EAGAIN; if (!timeo) @@ -1381,7 +1381,7 @@ restart: } if (unix_peer(other) != sk && - (skb_queue_len(&other->sk_receive_queue) > + (skb_queue_len(&other->sk_receive_queue) >= other->sk_max_ack_backlog)) { if (!timeo) { err = -EAGAIN; |