mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-24 15:56:49 +00:00
kernel: remove kernel 3.6
kernel 3.6 is not used by any target any more, remove it. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> SVN-Revision: 41834
This commit is contained in:
parent
e7ece301fe
commit
009e36806b
@ -1,195 +0,0 @@
|
||||
CONFIG_ALIGNMENT_TRAP=y
|
||||
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
|
||||
CONFIG_ARCH_EP93XX=y
|
||||
CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
|
||||
CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y
|
||||
CONFIG_ARCH_NR_GPIO=0
|
||||
CONFIG_ARCH_REQUIRE_GPIOLIB=y
|
||||
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
|
||||
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
|
||||
CONFIG_ARCH_SUSPEND_POSSIBLE=y
|
||||
CONFIG_ARCH_USES_GETTIMEOFFSET=y
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ARM_AMBA=y
|
||||
# CONFIG_ARM_CPU_SUSPEND is not set
|
||||
CONFIG_ARM_L1_CACHE_SHIFT=5
|
||||
CONFIG_ARM_NR_BANKS=16
|
||||
CONFIG_ARM_PATCH_PHYS_VIRT=y
|
||||
# CONFIG_ARM_SP805_WATCHDOG is not set
|
||||
CONFIG_ARM_THUMB=y
|
||||
CONFIG_ARM_VIC=y
|
||||
CONFIG_ARM_VIC_NR=2
|
||||
# CONFIG_ARPD is not set
|
||||
# CONFIG_BLK_DEV_INITRD is not set
|
||||
# CONFIG_CACHE_L2X0 is not set
|
||||
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
|
||||
CONFIG_CLKDEV_LOOKUP=y
|
||||
CONFIG_CMDLINE="console=ttyAM0,57600 init=/etc/preinit"
|
||||
CONFIG_CMDLINE_FROM_BOOTLOADER=y
|
||||
CONFIG_CONSOLE_TRANSLATIONS=y
|
||||
CONFIG_CPU_32v4T=y
|
||||
CONFIG_CPU_ABRT_EV4T=y
|
||||
CONFIG_CPU_ARM920T=y
|
||||
CONFIG_CPU_CACHE_V4WT=y
|
||||
CONFIG_CPU_CACHE_VIVT=y
|
||||
CONFIG_CPU_COPY_V4WB=y
|
||||
CONFIG_CPU_CP15=y
|
||||
CONFIG_CPU_CP15_MMU=y
|
||||
# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
|
||||
# CONFIG_CPU_ICACHE_DISABLE is not set
|
||||
CONFIG_CPU_PABRT_LEGACY=y
|
||||
CONFIG_CPU_TLB_V4WBI=y
|
||||
CONFIG_CPU_USE_DOMAINS=y
|
||||
CONFIG_CRC7=y
|
||||
CONFIG_CRC_ITU_T=y
|
||||
CONFIG_CRUNCH=y
|
||||
# CONFIG_DEBUG_USER is not set
|
||||
CONFIG_DUMMY_CONSOLE=y
|
||||
CONFIG_ELF_CORE=y
|
||||
# CONFIG_ENABLE_WARN_DEPRECATED is not set
|
||||
CONFIG_EP93XX_EARLY_UART1=y
|
||||
# CONFIG_EP93XX_EARLY_UART2 is not set
|
||||
# CONFIG_EP93XX_EARLY_UART3 is not set
|
||||
CONFIG_EP93XX_ETH=y
|
||||
# CONFIG_EP93XX_PWM is not set
|
||||
CONFIG_EP93XX_SDCE0_PHYS_OFFSET=y
|
||||
# CONFIG_EP93XX_SDCE1_PHYS_OFFSET is not set
|
||||
# CONFIG_EP93XX_SDCE2_PHYS_OFFSET is not set
|
||||
# CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET is not set
|
||||
# CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET is not set
|
||||
CONFIG_EP93XX_WATCHDOG=y
|
||||
CONFIG_FONTS=y
|
||||
# CONFIG_FONT_10x18 is not set
|
||||
# CONFIG_FONT_6x11 is not set
|
||||
# CONFIG_FONT_7x14 is not set
|
||||
CONFIG_FONT_8x16=y
|
||||
CONFIG_FONT_8x8=y
|
||||
# CONFIG_FONT_ACORN_8x8 is not set
|
||||
# CONFIG_FONT_MINI_4x6 is not set
|
||||
# CONFIG_FONT_PEARL_8x8 is not set
|
||||
# CONFIG_FONT_SUN12x22 is not set
|
||||
# CONFIG_FONT_SUN8x16 is not set
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
|
||||
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
|
||||
CONFIG_FRAME_POINTER=y
|
||||
CONFIG_GENERIC_ATOMIC64=y
|
||||
CONFIG_GENERIC_BUG=y
|
||||
CONFIG_GENERIC_GPIO=y
|
||||
CONFIG_GENERIC_IRQ_SHOW=y
|
||||
CONFIG_GENERIC_PCI_IOMAP=y
|
||||
CONFIG_GPIOLIB=y
|
||||
CONFIG_GPIO_EP93XX=y
|
||||
CONFIG_GPIO_GENERIC=y
|
||||
# CONFIG_GPIO_PL061 is not set
|
||||
# CONFIG_HAMRADIO is not set
|
||||
CONFIG_HARDIRQS_SW_RESEND=y
|
||||
CONFIG_HAS_DMA=y
|
||||
CONFIG_HAS_IOMEM=y
|
||||
CONFIG_HAS_IOPORT=y
|
||||
CONFIG_HAVE_AOUT=y
|
||||
CONFIG_HAVE_ARCH_KGDB=y
|
||||
CONFIG_HAVE_ARCH_PFN_VALID=y
|
||||
CONFIG_HAVE_CLK=y
|
||||
CONFIG_HAVE_C_RECORDMCOUNT=y
|
||||
CONFIG_HAVE_DMA_API_DEBUG=y
|
||||
CONFIG_HAVE_DYNAMIC_FTRACE=y
|
||||
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
|
||||
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
|
||||
CONFIG_HAVE_FUNCTION_TRACER=y
|
||||
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
|
||||
CONFIG_HAVE_GENERIC_HARDIRQS=y
|
||||
CONFIG_HAVE_IRQ_WORK=y
|
||||
CONFIG_HAVE_KERNEL_GZIP=y
|
||||
CONFIG_HAVE_KERNEL_LZMA=y
|
||||
CONFIG_HAVE_KERNEL_LZO=y
|
||||
CONFIG_HAVE_KERNEL_XZ=y
|
||||
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
|
||||
CONFIG_HAVE_MEMBLOCK=y
|
||||
CONFIG_HAVE_OPROFILE=y
|
||||
CONFIG_HAVE_PERF_EVENTS=y
|
||||
CONFIG_HAVE_PROC_CPU=y
|
||||
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
|
||||
CONFIG_HAVE_SPARSE_IRQ=y
|
||||
CONFIG_HW_CONSOLE=y
|
||||
CONFIG_I2C=y
|
||||
CONFIG_I2C_ALGOBIT=y
|
||||
CONFIG_I2C_BOARDINFO=y
|
||||
CONFIG_I2C_CHARDEV=y
|
||||
CONFIG_IKCONFIG=y
|
||||
CONFIG_IKCONFIG_PROC=y
|
||||
CONFIG_INPUT=y
|
||||
# CONFIG_INPUT_MISC is not set
|
||||
CONFIG_INPUT_TOUCHSCREEN=y
|
||||
CONFIG_IRQ_DOMAIN=y
|
||||
CONFIG_KTIME_SCALAR=y
|
||||
CONFIG_LOGO=y
|
||||
CONFIG_LOGO_LINUX_CLUT224=y
|
||||
CONFIG_LOGO_LINUX_MONO=y
|
||||
CONFIG_LOGO_LINUX_VGA16=y
|
||||
CONFIG_LOG_BUF_SHIFT=16
|
||||
# CONFIG_MACH_EDB9302A is not set
|
||||
# CONFIG_MACH_EDB9307A is not set
|
||||
# CONFIG_MACH_EDB9315A is not set
|
||||
CONFIG_MACH_SIM_ONE=y
|
||||
# CONFIG_MACH_SNAPPER_CL15 is not set
|
||||
# CONFIG_MACH_VISION_EP9307 is not set
|
||||
# CONFIG_MFD_T7L66XB is not set
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_BLOCK=y
|
||||
CONFIG_MMC_SPI=y
|
||||
CONFIG_MODULE_FORCE_UNLOAD=y
|
||||
CONFIG_MTD_CFI_ADV_OPTIONS=y
|
||||
# CONFIG_MTD_CFI_GEOMETRY is not set
|
||||
CONFIG_MTD_CFI_STAA=y
|
||||
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
|
||||
CONFIG_MTD_PHYSMAP=y
|
||||
CONFIG_MTD_RAM=y
|
||||
CONFIG_MULTI_IRQ_HANDLER=y
|
||||
CONFIG_NEED_DMA_MAP_STATE=y
|
||||
CONFIG_NEED_MACH_MEMORY_H=y
|
||||
CONFIG_NEED_PER_CPU_KM=y
|
||||
CONFIG_PAGEFLAGS_EXTENDED=y
|
||||
CONFIG_PAGE_OFFSET=0xC0000000
|
||||
# CONFIG_PCI_SYSCALL is not set
|
||||
CONFIG_PERF_USE_VMALLOC=y
|
||||
# CONFIG_PREEMPT_RCU is not set
|
||||
# CONFIG_SCSI_DMA is not set
|
||||
# CONFIG_SERIAL_8250 is not set
|
||||
CONFIG_SERIAL_AMBA_PL010=y
|
||||
CONFIG_SERIAL_AMBA_PL010_CONSOLE=y
|
||||
# CONFIG_SERIAL_AMBA_PL011 is not set
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_BITBANG=y
|
||||
CONFIG_SPI_EP93XX=y
|
||||
CONFIG_SPI_MASTER=y
|
||||
CONFIG_SPLIT_PTLOCK_CPUS=999999
|
||||
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
|
||||
# CONFIG_TCP_CONG_ADVANCED is not set
|
||||
# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
|
||||
# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set
|
||||
# CONFIG_TOUCHSCREEN_BU21013 is not set
|
||||
# CONFIG_TOUCHSCREEN_DYNAPRO is not set
|
||||
# CONFIG_TOUCHSCREEN_EGALAX is not set
|
||||
# CONFIG_TOUCHSCREEN_EP93XX is not set
|
||||
# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
|
||||
# CONFIG_TOUCHSCREEN_MAX11801 is not set
|
||||
# CONFIG_TOUCHSCREEN_PIXCIR is not set
|
||||
# CONFIG_TOUCHSCREEN_ST1232 is not set
|
||||
# CONFIG_TOUCHSCREEN_TSC2005 is not set
|
||||
# CONFIG_TOUCHSCREEN_TSC_SERIO is not set
|
||||
CONFIG_UID16=y
|
||||
# CONFIG_USB_ARCH_HAS_EHCI is not set
|
||||
# CONFIG_USB_ARCH_HAS_XHCI is not set
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_VECTORS_BASE=0xffff0000
|
||||
CONFIG_VIDEO_OUTPUT_CONTROL=y
|
||||
CONFIG_VM_EVENT_COUNTERS=y
|
||||
CONFIG_VT=y
|
||||
CONFIG_VT_CONSOLE=y
|
||||
# CONFIG_VT_HW_CONSOLE_BINDING is not set
|
||||
CONFIG_XZ_DEC_ARM=y
|
||||
CONFIG_XZ_DEC_BCJ=y
|
||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||
CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||
CONFIG_ZONE_DMA_FLAG=0
|
@ -1,70 +0,0 @@
|
||||
This patch puts the EP93xx chip revision and unique ID into /proc/cpuinfo.
|
||||
This is necessary to be able to set a unique MAC address for DHCP purposes
|
||||
by adding a line to /etc/network/interfaces:
|
||||
|
||||
# Generate a unique locally-assigned MAC address from the CPU serial number
|
||||
pre-up ifconfig eth0 hw ether `sed -n 's/^Serial.* 000000/02/p' /proc/cpuinfo`
|
||||
|
||||
It uses the chip revision reading code in the ep93xx-chip-revision patch.
|
||||
|
||||
Really, this is wrong, since /proc/cpuinfo should report the revision and
|
||||
serial number of the ARM920T processor, while these are the rev and serial
|
||||
of the EP93xx SoC. In a future kernel (>2.6.34) there may be a new file
|
||||
/proc/socinfo for this information.
|
||||
|
||||
-martinwguy 14 May 2010
|
||||
|
||||
--- a/arch/arm/kernel/setup.c
|
||||
+++ b/arch/arm/kernel/setup.c
|
||||
@@ -56,6 +56,12 @@
|
||||
#include <asm/unwind.h>
|
||||
#include <asm/memblock.h>
|
||||
|
||||
+#if defined(CONFIG_ARCH_EP93XX)
|
||||
+#include <asm/io.h>
|
||||
+#include <mach/platform.h>
|
||||
+#include <mach/ep93xx-regs.h>
|
||||
+#endif
|
||||
+
|
||||
#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
|
||||
#include "compat.h"
|
||||
#endif
|
||||
@@ -1107,9 +1113,16 @@ static int c_show(struct seq_file *m, vo
|
||||
seq_puts(m, "\n");
|
||||
|
||||
seq_printf(m, "Hardware\t: %s\n", machine_name);
|
||||
+#if defined(CONFIG_ARCH_EP93XX)
|
||||
+ seq_printf(m, "Revision\t: %04x\n",
|
||||
+ ep93xx_chip_revision());
|
||||
+ seq_printf(m, "Serial\t\t: %016x\n",
|
||||
+ *((unsigned int *)EP93XX_SECURITY_UNIQID));
|
||||
+#else
|
||||
seq_printf(m, "Revision\t: %04x\n", system_rev);
|
||||
seq_printf(m, "Serial\t\t: %08x%08x\n",
|
||||
system_serial_high, system_serial_low);
|
||||
+#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/arch/arm/mach-ep93xx/soc.h
|
||||
+++ b/arch/arm/mach-ep93xx/soc.h
|
||||
@@ -82,8 +82,6 @@
|
||||
#define EP93XX_I2S_PHYS_BASE EP93XX_APB_PHYS(0x00020000)
|
||||
#define EP93XX_I2S_BASE EP93XX_APB_IOMEM(0x00020000)
|
||||
|
||||
-#define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000)
|
||||
-
|
||||
#define EP93XX_AAC_PHYS_BASE EP93XX_APB_PHYS(0x00080000)
|
||||
#define EP93XX_AAC_BASE EP93XX_APB_IOMEM(0x00080000)
|
||||
|
||||
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
|
||||
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
|
||||
@@ -38,4 +38,8 @@
|
||||
#define EP93XX_UART3_PHYS_BASE EP93XX_APB_PHYS(0x000e0000)
|
||||
#define EP93XX_UART3_BASE EP93XX_APB_IOMEM(0x000e0000)
|
||||
|
||||
+#define EP93XX_SECURITY_BASE EP93XX_APB_IOMEM(0x00030000)
|
||||
+#define EP93XX_SECURITY_REG(x) (EP93XX_SECURITY_BASE + (x))
|
||||
+#define EP93XX_SECURITY_UNIQID EP93XX_SECURITY_REG(0x2440)
|
||||
+
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,180 +0,0 @@
|
||||
This enables the mmc-over-spi driver for the Sim.One board, based on Mika's
|
||||
patch, which used a GPIO for chip select in stead of the default SFRMOUT pin.
|
||||
I've modified it to use the usual SFRMOUT; if you've modified your Sim.One
|
||||
board to use a GPIO instead, uncomment and modify
|
||||
// #define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO15
|
||||
in the source file.
|
||||
-martinwguy, 14 May 2010
|
||||
|
||||
From: Mika Westerberg <mika.westerberg@iki.fi>
|
||||
Date: Wed, 28 Apr 2010 08:42:46 +0300
|
||||
Subject: [PATCH] ep93xx: simone: added board specific SPI support for MMC/SD cards
|
||||
|
||||
This includes setting up EGPIOs 0 and 9 for card detection and chip select
|
||||
respectively.
|
||||
|
||||
--- a/arch/arm/mach-ep93xx/simone.c
|
||||
+++ b/arch/arm/mach-ep93xx/simone.c
|
||||
@@ -18,12 +18,17 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
+#include <linux/gpio.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-gpio.h>
|
||||
+#include <linux/mmc/host.h>
|
||||
+#include <linux/spi/spi.h>
|
||||
+#include <linux/spi/mmc_spi.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/fb.h>
|
||||
#include <mach/gpio-ep93xx.h>
|
||||
+#include <mach/ep93xx_spi.h>
|
||||
|
||||
#include <asm/hardware/vic.h>
|
||||
#include <asm/mach-types.h>
|
||||
@@ -41,6 +46,135 @@ static struct ep93xxfb_mach_info __initd
|
||||
.flags = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * GPIO lines used for MMC card detection.
|
||||
+ */
|
||||
+#define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0
|
||||
+
|
||||
+/*
|
||||
+ * If you have hacked your Sim.One to use a GPIO as SD card chip select
|
||||
+ * (SD pin 1), uncomment the following line.
|
||||
+ * The example, EGPIO15, is on TP17 near the CPU.
|
||||
+ */
|
||||
+// #define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO15
|
||||
+
|
||||
+/*
|
||||
+ * MMC SPI chip select GPIO handling. If you are using SFRMOUT (SFRM1) signal,
|
||||
+ * you can leave these empty and pass NULL as .controller_data.
|
||||
+ */
|
||||
+
|
||||
+#ifdef MMC_CHIP_SELECT_GPIO
|
||||
+static int simone_mmc_spi_setup(struct spi_device *spi)
|
||||
+{
|
||||
+ unsigned int gpio = MMC_CHIP_SELECT_GPIO;
|
||||
+ int err;
|
||||
+
|
||||
+ err = gpio_request(gpio, spi->modalias);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = gpio_direction_output(gpio, 1);
|
||||
+ if (err) {
|
||||
+ gpio_free(gpio);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void simone_mmc_spi_cleanup(struct spi_device *spi)
|
||||
+{
|
||||
+ unsigned int gpio = MMC_CHIP_SELECT_GPIO;
|
||||
+
|
||||
+ gpio_set_value(gpio, 1);
|
||||
+ gpio_direction_input(gpio);
|
||||
+ gpio_free(gpio);
|
||||
+}
|
||||
+
|
||||
+static void simone_mmc_spi_cs_control(struct spi_device *spi, int value)
|
||||
+{
|
||||
+ gpio_set_value(MMC_CHIP_SELECT_GPIO, value);
|
||||
+}
|
||||
+
|
||||
+static struct ep93xx_spi_chip_ops simone_mmc_spi_ops = {
|
||||
+ .setup = simone_mmc_spi_setup,
|
||||
+ .cleanup = simone_mmc_spi_cleanup,
|
||||
+ .cs_control = simone_mmc_spi_cs_control,
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
+ * MMC card detection GPIO setup.
|
||||
+ */
|
||||
+static int simone_mmc_spi_init(struct device *dev,
|
||||
+ irqreturn_t (*irq_handler)(int, void *), void *mmc)
|
||||
+{
|
||||
+ unsigned int gpio = MMC_CARD_DETECT_GPIO;
|
||||
+ int irq, err;
|
||||
+
|
||||
+ err = gpio_request(gpio, dev_name(dev));
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = gpio_direction_input(gpio);
|
||||
+ if (err)
|
||||
+ goto fail;
|
||||
+
|
||||
+ irq = gpio_to_irq(gpio);
|
||||
+ if (irq < 0)
|
||||
+ goto fail;
|
||||
+
|
||||
+ err = request_irq(irq, irq_handler, IRQF_TRIGGER_FALLING,
|
||||
+ "MMC card detect", mmc);
|
||||
+ if (err)
|
||||
+ goto fail;
|
||||
+
|
||||
+ printk(KERN_INFO "%s: using irq %d for MMC card detection\n",
|
||||
+ dev_name(dev), irq);
|
||||
+
|
||||
+ return 0;
|
||||
+fail:
|
||||
+ gpio_free(gpio);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static void simone_mmc_spi_exit(struct device *dev, void *mmc)
|
||||
+{
|
||||
+ unsigned int gpio = MMC_CARD_DETECT_GPIO;
|
||||
+
|
||||
+ free_irq(gpio_to_irq(gpio), mmc);
|
||||
+ gpio_free(gpio);
|
||||
+}
|
||||
+
|
||||
+static struct mmc_spi_platform_data simone_mmc_spi_data = {
|
||||
+ .init = simone_mmc_spi_init,
|
||||
+ .exit = simone_mmc_spi_exit,
|
||||
+ .detect_delay = 500,
|
||||
+ .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
|
||||
+};
|
||||
+
|
||||
+static struct spi_board_info simone_spi_devices[] __initdata = {
|
||||
+ {
|
||||
+ .modalias = "mmc_spi",
|
||||
+#ifdef MMC_CHIP_SELECT_GPIO
|
||||
+ .controller_data = &simone_mmc_spi_ops,
|
||||
+#endif
|
||||
+ .platform_data = &simone_mmc_spi_data,
|
||||
+ /*
|
||||
+ * We use 10 MHz even though the maximum is 3.7 MHz. The driver
|
||||
+ * will limit it automatically to max. frequency.
|
||||
+ */
|
||||
+ .max_speed_hz = 10 * 1000 * 1000,
|
||||
+ .bus_num = 0,
|
||||
+ .chip_select = 0,
|
||||
+ .mode = SPI_MODE_3,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct ep93xx_spi_info simone_spi_info __initdata = {
|
||||
+ .num_chipselect = ARRAY_SIZE(simone_spi_devices),
|
||||
+};
|
||||
+
|
||||
static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = {
|
||||
.sda_pin = EP93XX_GPIO_LINE_EEDAT,
|
||||
.sda_is_open_drain = 0,
|
||||
@@ -75,6 +209,8 @@ static void __init simone_init_machine(v
|
||||
ep93xx_register_fb(&simone_fb_info);
|
||||
ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
|
||||
ARRAY_SIZE(simone_i2c_board_info));
|
||||
+ ep93xx_register_spi(&simone_spi_info, simone_spi_devices,
|
||||
+ ARRAY_SIZE(simone_spi_devices));
|
||||
simone_register_audio();
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,36 +0,0 @@
|
||||
From 86e4cb35f2260374df4139c2352afe7fe247cb60 Mon Sep 17 00:00:00 2001
|
||||
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
Date: Mon, 6 Aug 2012 18:06:53 -0700
|
||||
Subject: [PATCH] usb: host: ehci-platform: BUG_ON() to WARN_ON() on probe
|
||||
|
||||
Commit 86e4cb35f2260374df4139c2352afe7fe247cb60 upstream.
|
||||
|
||||
usb_ehci_pdata is certainly required in ehci-platform driver.
|
||||
This patch avoids using BUG_ON() from driver,
|
||||
and return from probe with WARN_ON() if pdata was NULL.
|
||||
|
||||
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
Acked-by: Alan Stern <stern@rowland.harvard.edu>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/ehci-platform.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/usb/host/ehci-platform.c
|
||||
+++ b/drivers/usb/host/ehci-platform.c
|
||||
@@ -82,10 +82,14 @@ static int __devinit ehci_platform_probe
|
||||
{
|
||||
struct usb_hcd *hcd;
|
||||
struct resource *res_mem;
|
||||
+ struct usb_ehci_pdata *pdata = dev->dev.platform_data;
|
||||
int irq;
|
||||
int err = -ENOMEM;
|
||||
|
||||
- BUG_ON(!dev->dev.platform_data);
|
||||
+ if (!pdata) {
|
||||
+ WARN_ON(1);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
|
||||
if (usb_disabled())
|
||||
return -ENODEV;
|
@ -1,36 +0,0 @@
|
||||
From b6dd245c4594482d46507a0bfd100439be367952 Mon Sep 17 00:00:00 2001
|
||||
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
Date: Mon, 6 Aug 2012 18:07:30 -0700
|
||||
Subject: [PATCH] usb: host: ohci-platform: BUG_ON() to WARN_ON() on probe
|
||||
|
||||
Commit b6dd245c4594482d46507a0bfd100439be367952 upstream.
|
||||
|
||||
usb_ohci_pdata is certainly required in ohci-platform driver.
|
||||
This patch avoids using BUG_ON() from driver,
|
||||
and return from probe with WARN_ON() if pdata was NULL.
|
||||
|
||||
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
Acked-by: Alan Stern <stern@rowland.harvard.edu>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/ohci-platform.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/usb/host/ohci-platform.c
|
||||
+++ b/drivers/usb/host/ohci-platform.c
|
||||
@@ -83,10 +83,14 @@ static int __devinit ohci_platform_probe
|
||||
{
|
||||
struct usb_hcd *hcd;
|
||||
struct resource *res_mem;
|
||||
+ struct usb_ohci_pdata *pdata = dev->dev.platform_data;
|
||||
int irq;
|
||||
int err = -ENOMEM;
|
||||
|
||||
- BUG_ON(!dev->dev.platform_data);
|
||||
+ if (!pdata) {
|
||||
+ WARN_ON(1);
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
|
||||
if (usb_disabled())
|
||||
return -ENODEV;
|
@ -1,119 +0,0 @@
|
||||
From 04216bedafb1b3992a6c2b7f1518281d2ba5fc7b Mon Sep 17 00:00:00 2001
|
||||
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
Date: Mon, 6 Aug 2012 18:08:39 -0700
|
||||
Subject: [PATCH] usb: host: ehci-platform: add platform specific power callback
|
||||
|
||||
Commit 04216bedafb1b3992a6c2b7f1518281d2ba5fc7b upstream.
|
||||
|
||||
This patch enables to call platform specific power callback function.
|
||||
|
||||
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
Acked-by: Alan Stern <stern@rowland.harvard.edu>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/ehci-platform.c | 40 +++++++++++++++++++++++++++++++++++---
|
||||
include/linux/usb/ehci_pdriver.h | 8 ++++++++
|
||||
2 files changed, 45 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/ehci-platform.c
|
||||
+++ b/drivers/usb/host/ehci-platform.c
|
||||
@@ -105,10 +105,18 @@ static int __devinit ehci_platform_probe
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
+ if (pdata->power_on) {
|
||||
+ err = pdata->power_on(dev);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
|
||||
dev_name(&dev->dev));
|
||||
- if (!hcd)
|
||||
- return -ENOMEM;
|
||||
+ if (!hcd) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_power;
|
||||
+ }
|
||||
|
||||
hcd->rsrc_start = res_mem->start;
|
||||
hcd->rsrc_len = resource_size(res_mem);
|
||||
@@ -136,12 +144,17 @@ err_release_region:
|
||||
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||
err_put_hcd:
|
||||
usb_put_hcd(hcd);
|
||||
+err_power:
|
||||
+ if (pdata->power_off)
|
||||
+ pdata->power_off(dev);
|
||||
+
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devexit ehci_platform_remove(struct platform_device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = platform_get_drvdata(dev);
|
||||
+ struct usb_ehci_pdata *pdata = dev->dev.platform_data;
|
||||
|
||||
usb_remove_hcd(hcd);
|
||||
iounmap(hcd->regs);
|
||||
@@ -149,6 +162,9 @@ static int __devexit ehci_platform_remov
|
||||
usb_put_hcd(hcd);
|
||||
platform_set_drvdata(dev, NULL);
|
||||
|
||||
+ if (pdata->power_off)
|
||||
+ pdata->power_off(dev);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -157,14 +173,32 @@ static int __devexit ehci_platform_remov
|
||||
static int ehci_platform_suspend(struct device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
+ struct usb_ehci_pdata *pdata = dev->platform_data;
|
||||
+ struct platform_device *pdev =
|
||||
+ container_of(dev, struct platform_device, dev);
|
||||
bool do_wakeup = device_may_wakeup(dev);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ehci_suspend(hcd, do_wakeup);
|
||||
|
||||
- return ehci_suspend(hcd, do_wakeup);
|
||||
+ if (pdata->power_suspend)
|
||||
+ pdata->power_suspend(pdev);
|
||||
+
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int ehci_platform_resume(struct device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
+ struct usb_ehci_pdata *pdata = dev->platform_data;
|
||||
+ struct platform_device *pdev =
|
||||
+ container_of(dev, struct platform_device, dev);
|
||||
+
|
||||
+ if (pdata->power_on) {
|
||||
+ int err = pdata->power_on(pdev);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ }
|
||||
|
||||
ehci_resume(hcd, false);
|
||||
return 0;
|
||||
--- a/include/linux/usb/ehci_pdriver.h
|
||||
+++ b/include/linux/usb/ehci_pdriver.h
|
||||
@@ -41,6 +41,14 @@ struct usb_ehci_pdata {
|
||||
unsigned big_endian_mmio:1;
|
||||
unsigned port_power_on:1;
|
||||
unsigned port_power_off:1;
|
||||
+
|
||||
+ /* Turn on all power and clocks */
|
||||
+ int (*power_on)(struct platform_device *pdev);
|
||||
+ /* Turn off all power and clocks */
|
||||
+ void (*power_off)(struct platform_device *pdev);
|
||||
+ /* Turn on only VBUS suspend power and hotplug detection,
|
||||
+ * turn off everything else */
|
||||
+ void (*power_suspend)(struct platform_device *pdev);
|
||||
};
|
||||
|
||||
#endif /* __USB_CORE_EHCI_PDRIVER_H */
|
@ -1,114 +0,0 @@
|
||||
From e4d37aeb373a5edceecc1dadc76fabbe8bc18e44 Mon Sep 17 00:00:00 2001
|
||||
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
Date: Mon, 6 Aug 2012 18:09:10 -0700
|
||||
Subject: [PATCH] usb: host: ohci-platform: add platform specific power callback
|
||||
|
||||
Commit e4d37aeb373a5edceecc1dadc76fabbe8bc18e44 upstream.
|
||||
|
||||
This patch enables to call platform specific power callback function.
|
||||
|
||||
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||
Acked-by: Alan Stern <stern@rowland.harvard.edu>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/usb/host/ohci-platform.c | 36 ++++++++++++++++++++++++++++++++++--
|
||||
include/linux/usb/ohci_pdriver.h | 8 ++++++++
|
||||
2 files changed, 42 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/usb/host/ohci-platform.c
|
||||
+++ b/drivers/usb/host/ohci-platform.c
|
||||
@@ -107,10 +107,18 @@ static int __devinit ohci_platform_probe
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
+ if (pdata->power_on) {
|
||||
+ err = pdata->power_on(dev);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev,
|
||||
dev_name(&dev->dev));
|
||||
- if (!hcd)
|
||||
- return -ENOMEM;
|
||||
+ if (!hcd) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_power;
|
||||
+ }
|
||||
|
||||
hcd->rsrc_start = res_mem->start;
|
||||
hcd->rsrc_len = resource_size(res_mem);
|
||||
@@ -138,12 +146,17 @@ err_release_region:
|
||||
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||
err_put_hcd:
|
||||
usb_put_hcd(hcd);
|
||||
+err_power:
|
||||
+ if (pdata->power_off)
|
||||
+ pdata->power_off(dev);
|
||||
+
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devexit ohci_platform_remove(struct platform_device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = platform_get_drvdata(dev);
|
||||
+ struct usb_ohci_pdata *pdata = dev->dev.platform_data;
|
||||
|
||||
usb_remove_hcd(hcd);
|
||||
iounmap(hcd->regs);
|
||||
@@ -151,6 +164,9 @@ static int __devexit ohci_platform_remov
|
||||
usb_put_hcd(hcd);
|
||||
platform_set_drvdata(dev, NULL);
|
||||
|
||||
+ if (pdata->power_off)
|
||||
+ pdata->power_off(dev);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -158,12 +174,28 @@ static int __devexit ohci_platform_remov
|
||||
|
||||
static int ohci_platform_suspend(struct device *dev)
|
||||
{
|
||||
+ struct usb_ohci_pdata *pdata = dev->platform_data;
|
||||
+ struct platform_device *pdev =
|
||||
+ container_of(dev, struct platform_device, dev);
|
||||
+
|
||||
+ if (pdata->power_suspend)
|
||||
+ pdata->power_suspend(pdev);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ohci_platform_resume(struct device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
+ struct usb_ohci_pdata *pdata = dev->platform_data;
|
||||
+ struct platform_device *pdev =
|
||||
+ container_of(dev, struct platform_device, dev);
|
||||
+
|
||||
+ if (pdata->power_on) {
|
||||
+ int err = pdata->power_on(pdev);
|
||||
+ if (err < 0)
|
||||
+ return err;
|
||||
+ }
|
||||
|
||||
ohci_finish_controller_resume(hcd);
|
||||
return 0;
|
||||
--- a/include/linux/usb/ohci_pdriver.h
|
||||
+++ b/include/linux/usb/ohci_pdriver.h
|
||||
@@ -33,6 +33,14 @@ struct usb_ohci_pdata {
|
||||
unsigned big_endian_desc:1;
|
||||
unsigned big_endian_mmio:1;
|
||||
unsigned no_big_frame_no:1;
|
||||
+
|
||||
+ /* Turn on all power and clocks */
|
||||
+ int (*power_on)(struct platform_device *pdev);
|
||||
+ /* Turn off all power and clocks */
|
||||
+ void (*power_off)(struct platform_device *pdev);
|
||||
+ /* Turn on only VBUS suspend power and hotplug detection,
|
||||
+ * turn off everything else */
|
||||
+ void (*power_suspend)(struct platform_device *pdev);
|
||||
};
|
||||
|
||||
#endif /* __USB_CORE_OHCI_PDRIVER_H */
|
@ -1,40 +0,0 @@
|
||||
From 35e57e1b49a351aa804dab6010cd46ae6112a541 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
|
||||
Date: Wed, 21 Aug 2013 01:43:07 -0700
|
||||
Subject: [PATCH 1/2] hso: Earlier catch of error condition
|
||||
|
||||
There is no need to get an interface specification if we know it's the
|
||||
wrong one.
|
||||
|
||||
Signed-off-by: Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
|
||||
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/usb/hso.c | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/usb/hso.c
|
||||
+++ b/drivers/net/usb/hso.c
|
||||
@@ -2908,6 +2908,11 @@ static int hso_probe(struct usb_interfac
|
||||
struct hso_shared_int *shared_int;
|
||||
struct hso_device *tmp_dev = NULL;
|
||||
|
||||
+ if (interface->cur_altsetting->desc.bInterfaceClass != 0xFF) {
|
||||
+ dev_err(&interface->dev, "Not our interface\n");
|
||||
+ return -ENODEV;
|
||||
+ }
|
||||
+
|
||||
if_num = interface->altsetting->desc.bInterfaceNumber;
|
||||
|
||||
/* Get the interface/port specification from either driver_info or from
|
||||
@@ -2917,10 +2922,6 @@ static int hso_probe(struct usb_interfac
|
||||
else
|
||||
port_spec = hso_get_config_data(interface);
|
||||
|
||||
- if (interface->cur_altsetting->desc.bInterfaceClass != 0xFF) {
|
||||
- dev_err(&interface->dev, "Not our interface\n");
|
||||
- return -ENODEV;
|
||||
- }
|
||||
/* Check if we need to switch to alt interfaces prior to port
|
||||
* configuration */
|
||||
if (interface->num_altsetting > 1)
|
@ -1,48 +0,0 @@
|
||||
From e75dc677ff8d06ffa61bef6fee436227ae5440c6 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
|
||||
Date: Wed, 21 Aug 2013 01:43:19 -0700
|
||||
Subject: [PATCH 2/2] hso: Fix stack corruption on some architectures
|
||||
|
||||
As Sergei Shtylyov explained in the #mipslinux IRC channel:
|
||||
[Mon 2013-08-19 12:28:21 PM PDT] <headless> guys, are you sure it's not "DMA off stack" case?
|
||||
[Mon 2013-08-19 12:28:35 PM PDT] <headless> it's a known stack corruptor on non-coherent arches
|
||||
[Mon 2013-08-19 12:31:48 PM PDT] <DonkeyHotei> headless: for usb/ehci?
|
||||
[Mon 2013-08-19 12:34:11 PM PDT] <DonkeyHotei> headless: explain
|
||||
[Mon 2013-08-19 12:35:38 PM PDT] <headless> usb_control_msg() (or other such func) should not use buffer on stack. DMA from/to stack is prohibited
|
||||
[Mon 2013-08-19 12:35:58 PM PDT] <headless> and EHCI uses DMA on control xfers (as well as all the others)
|
||||
|
||||
Signed-off-by: Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
|
||||
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/usb/hso.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/usb/hso.c
|
||||
+++ b/drivers/net/usb/hso.c
|
||||
@@ -2838,13 +2838,16 @@ exit:
|
||||
static int hso_get_config_data(struct usb_interface *interface)
|
||||
{
|
||||
struct usb_device *usbdev = interface_to_usbdev(interface);
|
||||
- u8 config_data[17];
|
||||
+ u8 *config_data = kmalloc(17, GFP_KERNEL);
|
||||
u32 if_num = interface->altsetting->desc.bInterfaceNumber;
|
||||
s32 result;
|
||||
|
||||
+ if (!config_data)
|
||||
+ return -ENOMEM;
|
||||
if (usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
|
||||
0x86, 0xC0, 0, 0, config_data, 17,
|
||||
USB_CTRL_SET_TIMEOUT) != 0x11) {
|
||||
+ kfree(config_data);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@@ -2895,6 +2898,7 @@ static int hso_get_config_data(struct us
|
||||
if (config_data[16] & 0x1)
|
||||
result |= HSO_INFO_CRC_BUG;
|
||||
|
||||
+ kfree(config_data);
|
||||
return result;
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
--- a/drivers/mtd/devices/m25p80.c
|
||||
+++ b/drivers/mtd/devices/m25p80.c
|
||||
@@ -642,6 +642,10 @@ static const struct spi_device_id m25p_i
|
||||
/* Everspin */
|
||||
{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2) },
|
||||
|
||||
+ /* GigaDevice */
|
||||
+ { "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, SECT_4K) },
|
||||
+ { "gd25q64", INFO(0xc84017, 0, 64 * 1024, 128, SECT_4K) },
|
||||
+
|
||||
/* Intel/Numonyx -- xxxs33b */
|
||||
{ "160s33b", INFO(0x898911, 0, 64 * 1024, 32, 0) },
|
||||
{ "320s33b", INFO(0x898912, 0, 64 * 1024, 64, 0) },
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,36 +0,0 @@
|
||||
--- a/drivers/net/usb/hso.c
|
||||
+++ b/drivers/net/usb/hso.c
|
||||
@@ -468,8 +468,10 @@ static const struct usb_device_id hso_id
|
||||
{USB_DEVICE(0x0af0, 0x8400)},
|
||||
{USB_DEVICE(0x0af0, 0x8600)},
|
||||
{USB_DEVICE(0x0af0, 0x8800)},
|
||||
- {USB_DEVICE(0x0af0, 0x8900)},
|
||||
- {USB_DEVICE(0x0af0, 0x9000)},
|
||||
+ {USB_DEVICE(0x0af0, 0x8900)}, /* GTM 67xx */
|
||||
+ {USB_DEVICE(0x0af0, 0x9000)}, /* GTM 66xx */
|
||||
+ {USB_DEVICE(0x0af0, 0x9200)}, /* GTM 67xxWFS */
|
||||
+ {USB_DEVICE(0x0af0, 0x9300)}, /* GTM 66xxWFS */
|
||||
{USB_DEVICE(0x0af0, 0xd035)},
|
||||
{USB_DEVICE(0x0af0, 0xd055)},
|
||||
{USB_DEVICE(0x0af0, 0xd155)},
|
||||
--- a/drivers/usb/storage/unusual_devs.h
|
||||
+++ b/drivers/usb/storage/unusual_devs.h
|
||||
@@ -1237,6 +1237,18 @@ UNUSUAL_DEV( 0x0af0, 0x8304, 0x0000, 0x0
|
||||
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
0 ),
|
||||
|
||||
+UNUSUAL_DEV( 0x0af0, 0x9200, 0x0000, 0x0000,
|
||||
+ "Option",
|
||||
+ "Globetrotter 67xxWFS SD-Card",
|
||||
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
+ 0 ),
|
||||
+
|
||||
+UNUSUAL_DEV( 0x0af0, 0x9300, 0x0000, 0x0000,
|
||||
+ "Option",
|
||||
+ "Globetrotter 66xxWFS SD-Card",
|
||||
+ USB_SC_DEVICE, USB_PR_DEVICE, NULL,
|
||||
+ 0 ),
|
||||
+
|
||||
UNUSUAL_DEV( 0x0af0, 0xc100, 0x0000, 0x0000,
|
||||
"Option",
|
||||
"GI 070x SD-Card",
|
@ -1,61 +0,0 @@
|
||||
From patchwork Mon Aug 6 21:04:43 2012
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: [net-next] tcp: ecn: dont delay ACKS after CE
|
||||
Date: Mon, 06 Aug 2012 11:04:43 -0000
|
||||
From: Eric Dumazet <eric.dumazet@gmail.com>
|
||||
X-Patchwork-Id: 175453
|
||||
Message-Id: <1344287083.26674.83.camel@edumazet-glaptop>
|
||||
To: David Miller <davem@davemloft.net>
|
||||
Cc: netdev <netdev@vger.kernel.org>,
|
||||
Neal Cardwell <ncardwell@google.com>
|
||||
|
||||
From: Eric Dumazet <edumazet@google.com>
|
||||
|
||||
While playing with CoDel and ECN marking, I discovered a
|
||||
non optimal behavior of receiver of CE (Congestion Encountered)
|
||||
segments.
|
||||
|
||||
In pathological cases, sender has reduced its cwnd to low values,
|
||||
and receiver delays its ACK (by 40 ms).
|
||||
|
||||
While RFC 3168 6.1.3 (The TCP Receiver) doesn't explicitly recommend
|
||||
to send immediate ACKS, we believe its better to not delay ACKS, because
|
||||
a CE segment should give same signal than a dropped segment, and its
|
||||
quite important to reduce RTT to give ECE/CWR signals as fast as
|
||||
possible.
|
||||
|
||||
Note we already call tcp_enter_quickack_mode() from TCP_ECN_check_ce()
|
||||
if we receive a retransmit, for the same reason.
|
||||
|
||||
Signed-off-by: Eric Dumazet <edumazet@google.com>
|
||||
Cc: Neal Cardwell <ncardwell@google.com>
|
||||
Acked-by: Neal Cardwell <ncardwell@google.com>
|
||||
|
||||
---
|
||||
net/ipv4/tcp_input.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
|
||||
|
||||
--
|
||||
To unsubscribe from this list: send the line "unsubscribe netdev" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
|
||||
--- a/net/ipv4/tcp_input.c
|
||||
+++ b/net/ipv4/tcp_input.c
|
||||
@@ -237,7 +237,11 @@ static inline void TCP_ECN_check_ce(stru
|
||||
tcp_enter_quickack_mode((struct sock *)tp);
|
||||
break;
|
||||
case INET_ECN_CE:
|
||||
- tp->ecn_flags |= TCP_ECN_DEMAND_CWR;
|
||||
+ if (!(tp->ecn_flags & TCP_ECN_DEMAND_CWR)) {
|
||||
+ /* Better not delay acks, sender can have a very low cwnd */
|
||||
+ tcp_enter_quickack_mode((struct sock *)tp);
|
||||
+ tp->ecn_flags |= TCP_ECN_DEMAND_CWR;
|
||||
+ }
|
||||
/* fallinto */
|
||||
default:
|
||||
tp->ecn_flags |= TCP_ECN_SEEN;
|
@ -1,10 +0,0 @@
|
||||
--- a/arch/arm/boot/compressed/decompress.c
|
||||
+++ b/arch/arm/boot/compressed/decompress.c
|
||||
@@ -47,6 +47,7 @@ extern void error(char *);
|
||||
#ifdef CONFIG_KERNEL_XZ
|
||||
#define memmove memmove
|
||||
#define memcpy memcpy
|
||||
+extern char * strstr(const char *, const char *);
|
||||
#include "../../../../lib/decompress_unxz.c"
|
||||
#endif
|
||||
|
@ -1,66 +0,0 @@
|
||||
From 0db3db45f5bd6df4bdc03bbd5dec672e16164c4e Mon Sep 17 00:00:00 2001
|
||||
From: Florian Fainelli <florian@openwrt.org>
|
||||
Date: Mon, 12 Nov 2012 12:31:55 +0100
|
||||
Subject: [PATCH] MIPS: decompressor: fix build failure on memcpy() in
|
||||
decompress.c
|
||||
|
||||
The decompress.c file includes linux/kernel.h which causes the following
|
||||
inclusion chain to be pulled:
|
||||
linux/kernel.h ->
|
||||
linux/dynamic_debug.h ->
|
||||
linux/string.h ->
|
||||
asm/string.h
|
||||
|
||||
We end up having a the GCC builtin + architecture specific memcpy() expanding
|
||||
into this:
|
||||
|
||||
void *({ size_t __len = (size_t n); void *__ret; if
|
||||
(__builtin_constant_p(size_t n) && __len >= 64) __ret = memcpy((void *dest),
|
||||
(const void *src), __len); else __ret = __builtin_memcpy((void *dest), (const
|
||||
void *src), __len); __ret; })
|
||||
{
|
||||
[memcpy implementation in decompress.c starts here]
|
||||
int i;
|
||||
const char *s = src;
|
||||
char *d = dest;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
d[i] = s[i];
|
||||
return dest;
|
||||
}
|
||||
|
||||
raising the following compilation error:
|
||||
arch/mips/boot/compressed/decompress.c:46:8: error: expected identifier or '('
|
||||
before '{' token
|
||||
|
||||
There are at least three possibilities to fix this issue:
|
||||
|
||||
1) define _LINUX_STRING_H_ at the beginning of decompress.c to prevent
|
||||
further linux/string.h definitions and declarations from being used, and add
|
||||
an explicit strstr() declaration for linux/dynamic_debug.h
|
||||
|
||||
2) remove the inclusion of linux/kernel.h because we actually use no definition
|
||||
or declaration from this header file
|
||||
|
||||
3) undefine memcpy or re-define memcpy to memcpy thus resulting in picking up
|
||||
the local memcpy() implementation to this compilation unit
|
||||
|
||||
This patch uses the second option which is the less intrusive one.
|
||||
|
||||
Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
---
|
||||
arch/mips/boot/compressed/decompress.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
--- a/arch/mips/boot/compressed/decompress.c
|
||||
+++ b/arch/mips/boot/compressed/decompress.c
|
||||
@@ -10,9 +10,7 @@
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
-
|
||||
#include <linux/types.h>
|
||||
-#include <linux/kernel.h>
|
||||
|
||||
#include <asm/addrspace.h>
|
||||
|
@ -1,174 +0,0 @@
|
||||
commit 01ffc0a7f1c1801a2354719dedbc32aff45b987d
|
||||
Author: David Woodhouse <dwmw2@infradead.org>
|
||||
Date: Sat Nov 24 12:11:21 2012 +0000
|
||||
|
||||
8139cp: re-enable interrupts after tx timeout
|
||||
|
||||
Recovery doesn't work too well if we leave interrupts disabled...
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Acked-by: Francois Romieu <romieu@fr.zoreil.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
commit 871f0d4c153e1258d4becf306eca6761bf38b629
|
||||
Author: David Woodhouse <dwmw2@infradead.org>
|
||||
Date: Thu Nov 22 03:16:58 2012 +0000
|
||||
|
||||
8139cp: enable bql
|
||||
|
||||
This adds support for byte queue limits on RTL8139C+
|
||||
|
||||
Tested on real hardware.
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Acked-By: Dave Täht <dave.taht@bufferbloat.net>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
commit a9dbe40fc10cea2efe6e1ff9e03c62dd7579c5ba
|
||||
Author: David Woodhouse <dwmw2@infradead.org>
|
||||
Date: Wed Nov 21 10:27:19 2012 +0000
|
||||
|
||||
8139cp: set ring address after enabling C+ mode
|
||||
|
||||
This fixes (for me) a regression introduced by commit b01af457 ("8139cp:
|
||||
set ring address before enabling receiver"). That commit configured the
|
||||
descriptor ring addresses earlier in the initialisation sequence, in
|
||||
order to avoid the possibility of triggering stray DMA before the
|
||||
correct address had been set up.
|
||||
|
||||
Unfortunately, it seems that the hardware will scribble garbage into the
|
||||
TxRingAddr registers when we enable "plus mode" Tx in the CpCmd
|
||||
register. Observed on a Traverse Geos router board.
|
||||
|
||||
To deal with this, while not reintroducing the problem which led to the
|
||||
original commit, we augment cp_start_hw() to write to the CpCmd register
|
||||
*first*, then set the descriptor ring addresses, and then finally to
|
||||
enable Rx and Tx in the original 8139 Cmd register. The datasheet
|
||||
actually indicates that we should enable Tx/Rx in the Cmd register
|
||||
*before* configuring the descriptor addresses, but that would appear to
|
||||
re-introduce the problem that the offending commit b01af457 was trying
|
||||
to solve. And this variant appears to work fine on real hardware.
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Cc: stable@kernel.org [3.5+]
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
--- a/drivers/net/ethernet/realtek/8139cp.c
|
||||
+++ b/drivers/net/ethernet/realtek/8139cp.c
|
||||
@@ -648,6 +648,7 @@ static void cp_tx (struct cp_private *cp
|
||||
{
|
||||
unsigned tx_head = cp->tx_head;
|
||||
unsigned tx_tail = cp->tx_tail;
|
||||
+ unsigned bytes_compl = 0, pkts_compl = 0;
|
||||
|
||||
while (tx_tail != tx_head) {
|
||||
struct cp_desc *txd = cp->tx_ring + tx_tail;
|
||||
@@ -666,6 +667,9 @@ static void cp_tx (struct cp_private *cp
|
||||
le32_to_cpu(txd->opts1) & 0xffff,
|
||||
PCI_DMA_TODEVICE);
|
||||
|
||||
+ bytes_compl += skb->len;
|
||||
+ pkts_compl++;
|
||||
+
|
||||
if (status & LastFrag) {
|
||||
if (status & (TxError | TxFIFOUnder)) {
|
||||
netif_dbg(cp, tx_err, cp->dev,
|
||||
@@ -697,6 +701,7 @@ static void cp_tx (struct cp_private *cp
|
||||
|
||||
cp->tx_tail = tx_tail;
|
||||
|
||||
+ netdev_completed_queue(cp->dev, pkts_compl, bytes_compl);
|
||||
if (TX_BUFFS_AVAIL(cp) > (MAX_SKB_FRAGS + 1))
|
||||
netif_wake_queue(cp->dev);
|
||||
}
|
||||
@@ -843,6 +848,8 @@ static netdev_tx_t cp_start_xmit (struct
|
||||
wmb();
|
||||
}
|
||||
cp->tx_head = entry;
|
||||
+
|
||||
+ netdev_sent_queue(dev, skb->len);
|
||||
netif_dbg(cp, tx_queued, cp->dev, "tx queued, slot %d, skblen %d\n",
|
||||
entry, skb->len);
|
||||
if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1))
|
||||
@@ -937,6 +944,8 @@ static void cp_stop_hw (struct cp_privat
|
||||
|
||||
cp->rx_tail = 0;
|
||||
cp->tx_head = cp->tx_tail = 0;
|
||||
+
|
||||
+ netdev_reset_queue(cp->dev);
|
||||
}
|
||||
|
||||
static void cp_reset_hw (struct cp_private *cp)
|
||||
@@ -957,8 +966,38 @@ static void cp_reset_hw (struct cp_priva
|
||||
|
||||
static inline void cp_start_hw (struct cp_private *cp)
|
||||
{
|
||||
+ dma_addr_t ring_dma;
|
||||
+
|
||||
cpw16(CpCmd, cp->cpcmd);
|
||||
+
|
||||
+ /*
|
||||
+ * These (at least TxRingAddr) need to be configured after the
|
||||
+ * corresponding bits in CpCmd are enabled. Datasheet v1.6 §6.33
|
||||
+ * (C+ Command Register) recommends that these and more be configured
|
||||
+ * *after* the [RT]xEnable bits in CpCmd are set. And on some hardware
|
||||
+ * it's been observed that the TxRingAddr is actually reset to garbage
|
||||
+ * when C+ mode Tx is enabled in CpCmd.
|
||||
+ */
|
||||
+ cpw32_f(HiTxRingAddr, 0);
|
||||
+ cpw32_f(HiTxRingAddr + 4, 0);
|
||||
+
|
||||
+ ring_dma = cp->ring_dma;
|
||||
+ cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
|
||||
+ cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
+
|
||||
+ ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
|
||||
+ cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
|
||||
+ cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
+
|
||||
+ /*
|
||||
+ * Strictly speaking, the datasheet says this should be enabled
|
||||
+ * *before* setting the descriptor addresses. But what, then, would
|
||||
+ * prevent it from doing DMA to random unconfigured addresses?
|
||||
+ * This variant appears to work fine.
|
||||
+ */
|
||||
cpw8(Cmd, RxOn | TxOn);
|
||||
+
|
||||
+ netdev_reset_queue(cp->dev);
|
||||
}
|
||||
|
||||
static void cp_enable_irq(struct cp_private *cp)
|
||||
@@ -969,7 +1008,6 @@ static void cp_enable_irq(struct cp_priv
|
||||
static void cp_init_hw (struct cp_private *cp)
|
||||
{
|
||||
struct net_device *dev = cp->dev;
|
||||
- dma_addr_t ring_dma;
|
||||
|
||||
cp_reset_hw(cp);
|
||||
|
||||
@@ -992,17 +1030,6 @@ static void cp_init_hw (struct cp_privat
|
||||
|
||||
cpw8(Config5, cpr8(Config5) & PMEStatus);
|
||||
|
||||
- cpw32_f(HiTxRingAddr, 0);
|
||||
- cpw32_f(HiTxRingAddr + 4, 0);
|
||||
-
|
||||
- ring_dma = cp->ring_dma;
|
||||
- cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
|
||||
- cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
-
|
||||
- ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
|
||||
- cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
|
||||
- cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
|
||||
-
|
||||
cpw16(MultiIntr, 0);
|
||||
|
||||
cpw8_f(Cfg9346, Cfg9346_Lock);
|
||||
@@ -1192,6 +1219,7 @@ static void cp_tx_timeout(struct net_dev
|
||||
cp_clean_rings(cp);
|
||||
rc = cp_init_rings(cp);
|
||||
cp_start_hw(cp);
|
||||
+ cp_enable_irq(cp);
|
||||
|
||||
netif_wake_queue(dev);
|
||||
|
@ -1,35 +0,0 @@
|
||||
From 7b45f21c2e42f265f6fd469e43857e98e2fdf01c Mon Sep 17 00:00:00 2001
|
||||
From: Irina Tirdea <irina.tirdea@intel.com>
|
||||
Date: Sat, 8 Sep 2012 03:43:21 +0300
|
||||
Subject: [PATCH] perf tools: replace mkostemp with mkstemp
|
||||
|
||||
The mkostemp function is only available in glibc. This leads to compile
|
||||
error in Android, since bionic is derived from BSD.
|
||||
|
||||
Replacing mkostemp with mkstemp. mkstemp is available on both glibc and
|
||||
bionic.
|
||||
|
||||
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
|
||||
Cc: David Ahern <dsahern@gmail.com>
|
||||
Cc: Ingo Molnar <mingo@redhat.com>
|
||||
Cc: Namhyung Kim <namhyung.kim@lge.com>
|
||||
Cc: Paul Mackerras <paulus@samba.org>
|
||||
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
|
||||
Cc: Steven Rostedt <rostedt@goodmis.org>
|
||||
Link: http://lkml.kernel.org/r/1347065004-15306-10-git-send-email-irina.tirdea@intel.com
|
||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
---
|
||||
tools/perf/util/dso-test-data.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/tools/perf/util/dso-test-data.c
|
||||
+++ b/tools/perf/util/dso-test-data.c
|
||||
@@ -23,7 +23,7 @@ static char *test_file(int size)
|
||||
int fd, i;
|
||||
unsigned char *buf;
|
||||
|
||||
- fd = mkostemp(templ, O_CREAT|O_WRONLY|O_TRUNC);
|
||||
+ fd = mkstemp(templ);
|
||||
|
||||
buf = malloc(size);
|
||||
if (!buf) {
|
@ -1,27 +0,0 @@
|
||||
From 031d8ad2c3cee85c515e551fc8c0054bdedb7b8b Mon Sep 17 00:00:00 2001
|
||||
From: Florian Fainelli <florian@openwrt.org>
|
||||
Date: Thu, 13 Dec 2012 18:02:11 +0100
|
||||
Subject: [PATCH] x86: fix perf build with uclibc toolchains
|
||||
|
||||
libio.h is not provided by uClibc, in order to be able to test the
|
||||
definition of __UCLIBC__ we need to include stdlib.h, which also
|
||||
includes stddef.h, providing the definition of 'NULL'
|
||||
|
||||
Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
---
|
||||
tools/perf/arch/x86/util/dwarf-regs.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/tools/perf/arch/x86/util/dwarf-regs.c
|
||||
+++ b/tools/perf/arch/x86/util/dwarf-regs.c
|
||||
@@ -20,7 +20,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
+#include <stdlib.h>
|
||||
+#ifndef __UCLIBC__
|
||||
#include <libio.h>
|
||||
+#endif
|
||||
#include <dwarf-regs.h>
|
||||
|
||||
/*
|
@ -1,27 +0,0 @@
|
||||
From 6e601a53566d84e1ffd25e7b6fe0b6894ffd79c0 Mon Sep 17 00:00:00 2001
|
||||
From: Mathias Krause <minipli@googlemail.com>
|
||||
Date: Sat, 23 Feb 2013 01:13:47 +0000
|
||||
Subject: sock_diag: Fix out-of-bounds access to sock_diag_handlers[]
|
||||
|
||||
Userland can send a netlink message requesting SOCK_DIAG_BY_FAMILY
|
||||
with a family greater or equal then AF_MAX -- the array size of
|
||||
sock_diag_handlers[]. The current code does not test for this
|
||||
condition therefore is vulnerable to an out-of-bound access opening
|
||||
doors for a privilege escalation.
|
||||
|
||||
Signed-off-by: Mathias Krause <minipli@googlemail.com>
|
||||
Acked-by: Eric Dumazet <edumazet@google.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
--- a/net/core/sock_diag.c
|
||||
+++ b/net/core/sock_diag.c
|
||||
@@ -121,6 +121,9 @@ static int __sock_diag_rcv_msg(struct sk
|
||||
if (nlmsg_len(nlh) < sizeof(*req))
|
||||
return -EINVAL;
|
||||
|
||||
+ if (req->sdiag_family >= AF_MAX)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
hndl = sock_diag_lock_handler(req->sdiag_family);
|
||||
if (hndl == NULL)
|
||||
err = -ENOENT;
|
File diff suppressed because it is too large
Load Diff
@ -1,41 +0,0 @@
|
||||
--- a/drivers/usb/host/ehci-hcd.c
|
||||
+++ b/drivers/usb/host/ehci-hcd.c
|
||||
@@ -645,7 +645,7 @@ static int ehci_run (struct usb_hcd *hcd
|
||||
"USB %x.%x started, EHCI %x.%02x%s\n",
|
||||
((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
|
||||
temp >> 8, temp & 0xff,
|
||||
- ignore_oc ? ", overcurrent ignored" : "");
|
||||
+ (ignore_oc || ehci->ignore_oc) ? ", overcurrent ignored" : "");
|
||||
|
||||
ehci_writel(ehci, INTR_MASK,
|
||||
&ehci->regs->intr_enable); /* Turn On Interrupts */
|
||||
--- a/drivers/usb/host/ehci-hub.c
|
||||
+++ b/drivers/usb/host/ehci-hub.c
|
||||
@@ -585,7 +585,7 @@ ehci_hub_status_data (struct usb_hcd *hc
|
||||
* always set, seem to clear PORT_OCC and PORT_CSC when writing to
|
||||
* PORT_POWER; that's surprising, but maybe within-spec.
|
||||
*/
|
||||
- if (!ignore_oc)
|
||||
+ if (!ignore_oc && !ehci->ignore_oc)
|
||||
mask = PORT_CSC | PORT_PEC | PORT_OCC;
|
||||
else
|
||||
mask = PORT_CSC | PORT_PEC;
|
||||
@@ -804,7 +804,7 @@ static int ehci_hub_control (
|
||||
if (temp & PORT_PEC)
|
||||
status |= USB_PORT_STAT_C_ENABLE << 16;
|
||||
|
||||
- if ((temp & PORT_OCC) && !ignore_oc){
|
||||
+ if ((temp & PORT_OCC) && (!ignore_oc && !ehci->ignore_oc)){
|
||||
status |= USB_PORT_STAT_C_OVERCURRENT << 16;
|
||||
|
||||
/*
|
||||
--- a/drivers/usb/host/ehci.h
|
||||
+++ b/drivers/usb/host/ehci.h
|
||||
@@ -197,6 +197,7 @@ struct ehci_hcd { /* one per controlle
|
||||
unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/
|
||||
unsigned has_synopsys_hc_bug:1; /* Synopsys HC */
|
||||
unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */
|
||||
+ unsigned ignore_oc:1;
|
||||
|
||||
/* required for usb32 quirk */
|
||||
#define OHCI_CTRL_HCFS (3 << 6)
|
@ -1,10 +0,0 @@
|
||||
--- a/include/linux/mtd/physmap.h
|
||||
+++ b/include/linux/mtd/physmap.h
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
+#include <linux/platform_device.h>
|
||||
|
||||
struct map_info;
|
||||
struct platform_device;
|
@ -1,900 +0,0 @@
|
||||
commit d7d3d8f1ee4435e32bc6c93187798b7e2e3170a9
|
||||
Author: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Date: Thu Nov 29 23:28:30 2012 +0000
|
||||
|
||||
solos-pci: remove list_vccs() debugging function
|
||||
|
||||
No idea why we've gone so long dumping a list of VCCs with vci==0 on
|
||||
every ->open() call...
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
|
||||
commit c93967bfd3a3dffa759a3f28370167bf3cdbc3d0
|
||||
Author: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Date: Thu Nov 29 23:27:20 2012 +0000
|
||||
|
||||
solos-pci: use GFP_KERNEL where possible, not GFP_ATOMIC
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
|
||||
commit ad6999e17ae4f7b99f6d28f425ae970acb115347
|
||||
Author: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Date: Thu Nov 29 23:15:30 2012 +0000
|
||||
|
||||
solos-pci: clean up pclose() function
|
||||
|
||||
- Flush pending TX skbs from the queue rather than waiting for them all to
|
||||
complete (suggested by Krzysztof Mazur <krzysiek@podlesie.net>).
|
||||
- Clear ATM_VF_ADDR only when the PKT_PCLOSE packet has been submitted.
|
||||
- Don't clear ATM_VF_READY at all — vcc_destroy_socket() does that for us.
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
|
||||
commit 2547e97f29d6d69d567947d5ef90b6b4fbcaf565
|
||||
Author: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Date: Wed Nov 28 10:15:05 2012 +0000
|
||||
|
||||
pppoatm: optimise PPP channel wakeups after sock_owned_by_user()
|
||||
|
||||
We don't need to schedule the wakeup tasklet on *every* unlock; only if we
|
||||
actually blocked the channel in the first place.
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Acked-by: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
|
||||
commit 990b0884a2e9668c08e9daa4d70a54d65329cb6f
|
||||
Author: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Date: Wed Nov 28 09:08:04 2012 +0100
|
||||
|
||||
br2684: allow assign only on a connected socket
|
||||
|
||||
The br2684 does not check if used vcc is in connected state,
|
||||
causing potential Oops in pppoatm_send() when vcc->send() is called
|
||||
on not fully connected socket.
|
||||
|
||||
Now br2684 can be assigned only on connected sockets; otherwise
|
||||
-EINVAL error is returned.
|
||||
|
||||
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
|
||||
commit f49b6da01f0abebb17f6241473d53018d923f6b0
|
||||
Author: Nathan Williams <nathan@traverse.com.au>
|
||||
Date: Tue Nov 27 17:34:09 2012 +1100
|
||||
|
||||
solos-pci: Fix leak of skb received for unknown vcc
|
||||
|
||||
... and ensure that the next skb is set up for RX in the DMA case.
|
||||
|
||||
Signed-off-by: Nathan Williams <nathan@traverse.com.au>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
|
||||
commit a61d37ff4a555886c4ebe31d2c6d893afb6f4d3c
|
||||
Author: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Date: Wed Nov 28 00:46:45 2012 +0000
|
||||
|
||||
br2684: fix module_put() race
|
||||
|
||||
The br2684 code used module_put() during unassignment from vcc with
|
||||
hope that we have BKL. This assumption is no longer true.
|
||||
|
||||
Now owner field in atmvcc is used to move this module_put()
|
||||
to vcc_destroy_socket().
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Acked-by: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
|
||||
commit c52f40629884ddc62c7af445fd5d620fdb466fb2
|
||||
Author: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Date: Wed Nov 28 00:05:52 2012 +0000
|
||||
|
||||
pppoatm: fix missing wakeup in pppoatm_send()
|
||||
|
||||
Now that we can return zero from pppoatm_send() for reasons *other* than
|
||||
the queue being full, that means we can't depend on a subsequent call to
|
||||
pppoatm_pop() waking the queue, and we might leave it stalled
|
||||
indefinitely.
|
||||
|
||||
Use the ->release_cb() callback to wake the queue after the sock is
|
||||
unlocked.
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Acked-by: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
|
||||
commit 35826e7372fe39b7db7930eda0267c82d68d1a4c
|
||||
Author: David Woodhouse <dwmw2@infradead.org>
|
||||
Date: Tue Nov 27 23:28:36 2012 +0000
|
||||
|
||||
br2684: don't send frames on not-ready vcc
|
||||
|
||||
Avoid submitting packets to a vcc which is being closed. Things go badly
|
||||
wrong when the ->pop method gets later called after everything's been
|
||||
torn down.
|
||||
|
||||
Use the ATM socket lock for synchronisation with vcc_destroy_socket(),
|
||||
which clears the ATM_VF_READY bit under the same lock. Otherwise, we
|
||||
could end up submitting a packet to the device driver even after its
|
||||
->ops->close method has been called. And it could call the vcc's ->pop
|
||||
method after the protocol has been shut down. Which leads to a panic.
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Acked-by: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
|
||||
commit 7f940dde65de4a707f3dd723bb6ce9de90ca1eab
|
||||
Author: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Date: Wed Nov 28 00:03:11 2012 +0000
|
||||
|
||||
atm: add release_cb() callback to vcc
|
||||
|
||||
The immediate use case for this is that it will allow us to ensure that a
|
||||
pppoatm queue is woken after it has to drop a packet due to the sock being
|
||||
locked.
|
||||
|
||||
Note that 'release_cb' is called when the socket is *unlocked*. This is
|
||||
not to be confused with vcc_release() — which probably ought to be called
|
||||
vcc_close().
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Acked-by: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
|
||||
commit def1b2f9083f84d0a77730e537c76429914d17c1
|
||||
Author: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Date: Tue Nov 27 23:49:24 2012 +0000
|
||||
|
||||
solos-pci: wait for pending TX to complete when releasing vcc
|
||||
|
||||
We should no longer be calling the old pop routine for the vcc, after
|
||||
vcc_release() has completed. Make sure we wait for any pending TX skbs
|
||||
to complete, by waiting for our own PKT_PCLOSE control skb to be sent.
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
|
||||
commit 397ff16dce53888ec693b3718640be2560204751
|
||||
Author: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Date: Tue Nov 6 23:17:02 2012 +0100
|
||||
|
||||
pppoatm: do not inline pppoatm_may_send()
|
||||
|
||||
The pppoatm_may_send() is quite heavy and it's called three times
|
||||
in pppoatm_send() and inlining costs more than 200 bytes of code
|
||||
(more than 10% of total pppoatm driver code size).
|
||||
|
||||
add/remove: 1/0 grow/shrink: 0/1 up/down: 132/-367 (-235)
|
||||
function old new delta
|
||||
pppoatm_may_send - 132 +132
|
||||
pppoatm_send 900 533 -367
|
||||
|
||||
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
|
||||
commit 071d93931a75dc1f82f0baa9959613af81c5a032
|
||||
Author: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Date: Sat Nov 10 23:33:19 2012 +0100
|
||||
|
||||
pppoatm: drop frames to not-ready vcc
|
||||
|
||||
The vcc_destroy_socket() closes vcc before the protocol is detached
|
||||
from vcc by calling vcc->push() with NULL skb. This leaves some time
|
||||
window, where the protocol may call vcc->send() on closed vcc
|
||||
and crash.
|
||||
|
||||
Now pppoatm_send(), like vcc_sendmsg(), checks for vcc flags that
|
||||
indicate that vcc is not ready. If the vcc is not ready we just
|
||||
drop frame. Queueing frames is much more complicated because we
|
||||
don't have callbacks that inform us about vcc flags changes.
|
||||
|
||||
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
|
||||
commit 3ac108006fd7f20cb8fc8ea2287f1497bcda00a1
|
||||
Author: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Date: Tue Nov 6 23:17:00 2012 +0100
|
||||
|
||||
pppoatm: take ATM socket lock in pppoatm_send()
|
||||
|
||||
The pppoatm_send() does not take any lock that will prevent concurrent
|
||||
vcc_sendmsg(). This causes two problems:
|
||||
|
||||
- there is no locking between checking the send queue size
|
||||
with atm_may_send() and incrementing sk_wmem_alloc,
|
||||
and the real queue size can be a little higher than sk_sndbuf
|
||||
|
||||
- the vcc->sendmsg() can be called concurrently. I'm not sure
|
||||
if it's allowed. Some drivers (eni, nicstar, ...) seem
|
||||
to assume it will never happen.
|
||||
|
||||
Now pppoatm_send() takes ATM socket lock, the same that is used
|
||||
in vcc_sendmsg() and other ATM socket functions. The pppoatm_send()
|
||||
is called with BH disabled, so bh_lock_sock() is used instead
|
||||
of lock_sock().
|
||||
|
||||
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Cc: Chas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
|
||||
commit e41faed9cde1acce657f75a0b19a1787e9850d3f
|
||||
Author: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Date: Tue Nov 6 23:16:59 2012 +0100
|
||||
|
||||
pppoatm: fix module_put() race
|
||||
|
||||
The pppoatm used module_put() during unassignment from vcc with
|
||||
hope that we have BKL. This assumption is no longer true.
|
||||
|
||||
Now owner field in atmvcc is used to move this module_put()
|
||||
to vcc_destroy_socket().
|
||||
|
||||
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
|
||||
commit 3b1a914595f3f9beb9e38ff3ddc7bdafa092ba22
|
||||
Author: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Date: Tue Nov 6 23:16:58 2012 +0100
|
||||
|
||||
pppoatm: allow assign only on a connected socket
|
||||
|
||||
The pppoatm does not check if used vcc is in connected state,
|
||||
causing an Oops in pppoatm_send() when vcc->send() is called
|
||||
on not fully connected socket.
|
||||
|
||||
Now pppoatm can be assigned only on connected sockets; otherwise
|
||||
-EINVAL error is returned.
|
||||
|
||||
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Cc: Chas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
|
||||
commit ec809bd817dfa1905283468e4c813684ed4efe78
|
||||
Author: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Date: Tue Nov 6 23:16:57 2012 +0100
|
||||
|
||||
atm: add owner of push() callback to atmvcc
|
||||
|
||||
The atm is using atmvcc->push(vcc, NULL) callback to notify protocol
|
||||
that vcc will be closed and protocol must detach from it. This callback
|
||||
is usually used by protocol to decrement module usage count by module_put(),
|
||||
but it leaves small window then module is still used after module_put().
|
||||
|
||||
Now the owner of push() callback is kept in atmvcc and
|
||||
module_put(atmvcc->owner) is called after the protocol is detached from vcc.
|
||||
|
||||
Signed-off-by: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Acked-by: Chas Williams <chas@cmf.nrl.navy.mil>
|
||||
|
||||
commit ae088d663beebb3cad0e7abaac67ee61a7c578d5
|
||||
Author: David Woodhouse <dwmw2@infradead.org>
|
||||
Date: Sun Nov 25 12:06:52 2012 +0000
|
||||
|
||||
atm: br2684: Fix excessive queue bloat
|
||||
|
||||
There's really no excuse for an additional wmem_default of buffering
|
||||
between the netdev queue and the ATM device. Two packets (one in-flight,
|
||||
and one ready to send) ought to be fine. It's not as if it should take
|
||||
long to get another from the netdev queue when we need it.
|
||||
|
||||
If necessary we can make the queue space configurable later, but I don't
|
||||
think it's likely to be necessary.
|
||||
|
||||
cf. commit 9d02daf754238adac48fa075ee79e7edd3d79ed3 (pppoatm: Fix
|
||||
excessive queue bloat) which did something very similar for PPPoATM.
|
||||
|
||||
Note that there is a tremendously unlikely race condition which may
|
||||
result in qspace temporarily going negative. If a CPU running the
|
||||
br2684_pop() function goes off into the weeds for a long period of time
|
||||
after incrementing qspace to 1, but before calling netdev_wake_queue()...
|
||||
and another CPU ends up calling br2684_start_xmit() and *stopping* the
|
||||
queue again before the first CPU comes back, the netdev queue could
|
||||
end up being woken when qspace has already reached zero.
|
||||
|
||||
An alternative approach to coping with this race would be to check in
|
||||
br2684_start_xmit() for qspace==0 and return NETDEV_TX_BUSY, but just
|
||||
using '> 0' and '< 1' for comparison instead of '== 0' and '!= 0' is
|
||||
simpler. It just warranted a mention of *why* we do it that way...
|
||||
|
||||
Move the call to atmvcc->send() to happen *after* the accounting and
|
||||
potentially stopping the netdev queue, in br2684_xmit_vcc(). This matters
|
||||
if the ->send() call suffers an immediate failure, because it'll call
|
||||
br2684_pop() with the offending skb before returning. We want that to
|
||||
happen *after* we've done the initial accounting for the packet in
|
||||
question. Also make it return an appropriate success/failure indication
|
||||
while we're at it.
|
||||
|
||||
Tested by running 'ping -l 1000 bottomless.aaisp.net.uk' from within my
|
||||
network, with only a single PPPoE-over-BR2684 link running. And after
|
||||
setting txqueuelen on the nas0 interface to something low (5, in fact).
|
||||
Before the patch, we'd see about 15 packets being queued and a resulting
|
||||
latency of ~56ms being reached. After the patch, we see only about 8,
|
||||
which is fairly much what we expect. And a max latency of ~36ms. On this
|
||||
OpenWRT box, wmem_default is 163840.
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Reviewed-by: Krzysztof Mazur <krzysiek@podlesie.net>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
--- a/drivers/atm/solos-pci.c
|
||||
+++ b/drivers/atm/solos-pci.c
|
||||
@@ -92,6 +92,7 @@ struct pkt_hdr {
|
||||
};
|
||||
|
||||
struct solos_skb_cb {
|
||||
+ struct completion c;
|
||||
struct atm_vcc *vcc;
|
||||
uint32_t dma_addr;
|
||||
};
|
||||
@@ -164,7 +165,6 @@ static void fpga_queue(struct solos_card
|
||||
static uint32_t fpga_tx(struct solos_card *);
|
||||
static irqreturn_t solos_irq(int irq, void *dev_id);
|
||||
static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
|
||||
-static int list_vccs(int vci);
|
||||
static int atm_init(struct solos_card *, struct device *);
|
||||
static void atm_remove(struct solos_card *);
|
||||
static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
|
||||
@@ -710,7 +710,8 @@ void solos_bh(unsigned long card_arg)
|
||||
dev_warn(&card->dev->dev, "Received packet for unknown VPI.VCI %d.%d on port %d\n",
|
||||
le16_to_cpu(header->vpi), le16_to_cpu(header->vci),
|
||||
port);
|
||||
- continue;
|
||||
+ dev_kfree_skb_any(skb);
|
||||
+ break;
|
||||
}
|
||||
atm_charge(vcc, skb->truesize);
|
||||
vcc->push(vcc, skb);
|
||||
@@ -790,44 +791,6 @@ static struct atm_vcc *find_vcc(struct a
|
||||
return vcc;
|
||||
}
|
||||
|
||||
-static int list_vccs(int vci)
|
||||
-{
|
||||
- struct hlist_head *head;
|
||||
- struct atm_vcc *vcc;
|
||||
- struct hlist_node *node;
|
||||
- struct sock *s;
|
||||
- int num_found = 0;
|
||||
- int i;
|
||||
-
|
||||
- read_lock(&vcc_sklist_lock);
|
||||
- if (vci != 0){
|
||||
- head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];
|
||||
- sk_for_each(s, node, head) {
|
||||
- num_found ++;
|
||||
- vcc = atm_sk(s);
|
||||
- printk(KERN_DEBUG "Device: %d Vpi: %d Vci: %d\n",
|
||||
- vcc->dev->number,
|
||||
- vcc->vpi,
|
||||
- vcc->vci);
|
||||
- }
|
||||
- } else {
|
||||
- for(i = 0; i < VCC_HTABLE_SIZE; i++){
|
||||
- head = &vcc_hash[i];
|
||||
- sk_for_each(s, node, head) {
|
||||
- num_found ++;
|
||||
- vcc = atm_sk(s);
|
||||
- printk(KERN_DEBUG "Device: %d Vpi: %d Vci: %d\n",
|
||||
- vcc->dev->number,
|
||||
- vcc->vpi,
|
||||
- vcc->vci);
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- read_unlock(&vcc_sklist_lock);
|
||||
- return num_found;
|
||||
-}
|
||||
-
|
||||
-
|
||||
static int popen(struct atm_vcc *vcc)
|
||||
{
|
||||
struct solos_card *card = vcc->dev->dev_data;
|
||||
@@ -840,7 +803,7 @@ static int popen(struct atm_vcc *vcc)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
|
||||
+ skb = alloc_skb(sizeof(*header), GFP_KERNEL);
|
||||
if (!skb) {
|
||||
if (net_ratelimit())
|
||||
dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n");
|
||||
@@ -857,8 +820,6 @@ static int popen(struct atm_vcc *vcc)
|
||||
|
||||
set_bit(ATM_VF_ADDR, &vcc->flags);
|
||||
set_bit(ATM_VF_READY, &vcc->flags);
|
||||
- list_vccs(0);
|
||||
-
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -866,10 +827,21 @@ static int popen(struct atm_vcc *vcc)
|
||||
static void pclose(struct atm_vcc *vcc)
|
||||
{
|
||||
struct solos_card *card = vcc->dev->dev_data;
|
||||
- struct sk_buff *skb;
|
||||
+ unsigned char port = SOLOS_CHAN(vcc->dev);
|
||||
+ struct sk_buff *skb, *tmpskb;
|
||||
struct pkt_hdr *header;
|
||||
|
||||
- skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
|
||||
+ /* Remove any yet-to-be-transmitted packets from the pending queue */
|
||||
+ spin_lock(&card->tx_queue_lock);
|
||||
+ skb_queue_walk_safe(&card->tx_queue[port], skb, tmpskb) {
|
||||
+ if (SKB_CB(skb)->vcc == vcc) {
|
||||
+ skb_unlink(skb, &card->tx_queue[port]);
|
||||
+ solos_pop(vcc, skb);
|
||||
+ }
|
||||
+ }
|
||||
+ spin_unlock(&card->tx_queue_lock);
|
||||
+
|
||||
+ skb = alloc_skb(sizeof(*header), GFP_KERNEL);
|
||||
if (!skb) {
|
||||
dev_warn(&card->dev->dev, "Failed to allocate sk_buff in pclose()\n");
|
||||
return;
|
||||
@@ -881,15 +853,21 @@ static void pclose(struct atm_vcc *vcc)
|
||||
header->vci = cpu_to_le16(vcc->vci);
|
||||
header->type = cpu_to_le16(PKT_PCLOSE);
|
||||
|
||||
- fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, NULL);
|
||||
+ init_completion(&SKB_CB(skb)->c);
|
||||
|
||||
- clear_bit(ATM_VF_ADDR, &vcc->flags);
|
||||
- clear_bit(ATM_VF_READY, &vcc->flags);
|
||||
+ fpga_queue(card, port, skb, NULL);
|
||||
+
|
||||
+ if (!wait_for_completion_timeout(&SKB_CB(skb)->c, 5 * HZ))
|
||||
+ dev_warn(&card->dev->dev, "Timeout waiting for VCC close on port %d\n",
|
||||
+ port);
|
||||
|
||||
/* Hold up vcc_destroy_socket() (our caller) until solos_bh() in the
|
||||
tasklet has finished processing any incoming packets (and, more to
|
||||
the point, using the vcc pointer). */
|
||||
tasklet_unlock_wait(&card->tlet);
|
||||
+
|
||||
+ clear_bit(ATM_VF_ADDR, &vcc->flags);
|
||||
+
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1011,9 +989,12 @@ static uint32_t fpga_tx(struct solos_car
|
||||
if (vcc) {
|
||||
atomic_inc(&vcc->stats->tx);
|
||||
solos_pop(vcc, oldskb);
|
||||
- } else
|
||||
+ } else {
|
||||
+ struct pkt_hdr *header = (void *)oldskb->data;
|
||||
+ if (le16_to_cpu(header->type) == PKT_PCLOSE)
|
||||
+ complete(&SKB_CB(oldskb)->c);
|
||||
dev_kfree_skb_irq(oldskb);
|
||||
-
|
||||
+ }
|
||||
}
|
||||
}
|
||||
/* For non-DMA TX, write the 'TX start' bit for all four ports simultaneously */
|
||||
@@ -1248,7 +1229,7 @@ static int atm_init(struct solos_card *c
|
||||
card->atmdev[i]->phy_data = (void *)(unsigned long)i;
|
||||
atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_FOUND);
|
||||
|
||||
- skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
|
||||
+ skb = alloc_skb(sizeof(*header), GFP_KERNEL);
|
||||
if (!skb) {
|
||||
dev_warn(&card->dev->dev, "Failed to allocate sk_buff in atm_init()\n");
|
||||
continue;
|
||||
@@ -1345,6 +1326,8 @@ static struct pci_driver fpga_driver = {
|
||||
|
||||
static int __init solos_pci_init(void)
|
||||
{
|
||||
+ BUILD_BUG_ON(sizeof(struct solos_skb_cb) > sizeof(((struct sk_buff *)0)->cb));
|
||||
+
|
||||
printk(KERN_INFO "Solos PCI Driver Version %s\n", VERSION);
|
||||
return pci_register_driver(&fpga_driver);
|
||||
}
|
||||
--- a/include/linux/atmdev.h
|
||||
+++ b/include/linux/atmdev.h
|
||||
@@ -308,6 +308,7 @@ struct atm_vcc {
|
||||
struct atm_dev *dev; /* device back pointer */
|
||||
struct atm_qos qos; /* QOS */
|
||||
struct atm_sap sap; /* SAP */
|
||||
+ void (*release_cb)(struct atm_vcc *vcc); /* release_sock callback */
|
||||
void (*push)(struct atm_vcc *vcc,struct sk_buff *skb);
|
||||
void (*pop)(struct atm_vcc *vcc,struct sk_buff *skb); /* optional */
|
||||
int (*push_oam)(struct atm_vcc *vcc,void *cell);
|
||||
@@ -315,6 +316,7 @@ struct atm_vcc {
|
||||
void *dev_data; /* per-device data */
|
||||
void *proto_data; /* per-protocol data */
|
||||
struct k_atm_aal_stats *stats; /* pointer to AAL stats group */
|
||||
+ struct module *owner; /* owner of ->push function */
|
||||
/* SVC part --- may move later ------------------------------------- */
|
||||
short itf; /* interface number */
|
||||
struct sockaddr_atmsvc local;
|
||||
--- a/net/atm/br2684.c
|
||||
+++ b/net/atm/br2684.c
|
||||
@@ -68,12 +68,15 @@ struct br2684_vcc {
|
||||
/* keep old push, pop functions for chaining */
|
||||
void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb);
|
||||
void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb);
|
||||
+ void (*old_release_cb)(struct atm_vcc *vcc);
|
||||
+ struct module *old_owner;
|
||||
enum br2684_encaps encaps;
|
||||
struct list_head brvccs;
|
||||
#ifdef CONFIG_ATM_BR2684_IPFILTER
|
||||
struct br2684_filter filter;
|
||||
#endif /* CONFIG_ATM_BR2684_IPFILTER */
|
||||
unsigned int copies_needed, copies_failed;
|
||||
+ atomic_t qspace;
|
||||
};
|
||||
|
||||
struct br2684_dev {
|
||||
@@ -181,18 +184,15 @@ static struct notifier_block atm_dev_not
|
||||
static void br2684_pop(struct atm_vcc *vcc, struct sk_buff *skb)
|
||||
{
|
||||
struct br2684_vcc *brvcc = BR2684_VCC(vcc);
|
||||
- struct net_device *net_dev = skb->dev;
|
||||
|
||||
- pr_debug("(vcc %p ; net_dev %p )\n", vcc, net_dev);
|
||||
+ pr_debug("(vcc %p ; net_dev %p )\n", vcc, brvcc->device);
|
||||
brvcc->old_pop(vcc, skb);
|
||||
|
||||
- if (!net_dev)
|
||||
- return;
|
||||
-
|
||||
- if (atm_may_send(vcc, 0))
|
||||
- netif_wake_queue(net_dev);
|
||||
-
|
||||
+ /* If the queue space just went up from zero, wake */
|
||||
+ if (atomic_inc_return(&brvcc->qspace) == 1)
|
||||
+ netif_wake_queue(brvcc->device);
|
||||
}
|
||||
+
|
||||
/*
|
||||
* Send a packet out a particular vcc. Not to useful right now, but paves
|
||||
* the way for multiple vcc's per itf. Returns true if we can send,
|
||||
@@ -256,16 +256,30 @@ static int br2684_xmit_vcc(struct sk_buf
|
||||
ATM_SKB(skb)->atm_options = atmvcc->atm_options;
|
||||
dev->stats.tx_packets++;
|
||||
dev->stats.tx_bytes += skb->len;
|
||||
- atmvcc->send(atmvcc, skb);
|
||||
|
||||
- if (!atm_may_send(atmvcc, 0)) {
|
||||
+ if (atomic_dec_return(&brvcc->qspace) < 1) {
|
||||
+ /* No more please! */
|
||||
netif_stop_queue(brvcc->device);
|
||||
- /*check for race with br2684_pop*/
|
||||
- if (atm_may_send(atmvcc, 0))
|
||||
- netif_start_queue(brvcc->device);
|
||||
+ /* We might have raced with br2684_pop() */
|
||||
+ if (unlikely(atomic_read(&brvcc->qspace) > 0))
|
||||
+ netif_wake_queue(brvcc->device);
|
||||
}
|
||||
|
||||
- return 1;
|
||||
+ /* If this fails immediately, the skb will be freed and br2684_pop()
|
||||
+ will wake the queue if appropriate. Just return an error so that
|
||||
+ the stats are updated correctly */
|
||||
+ return !atmvcc->send(atmvcc, skb);
|
||||
+}
|
||||
+
|
||||
+static void br2684_release_cb(struct atm_vcc *atmvcc)
|
||||
+{
|
||||
+ struct br2684_vcc *brvcc = BR2684_VCC(atmvcc);
|
||||
+
|
||||
+ if (atomic_read(&brvcc->qspace) > 0)
|
||||
+ netif_wake_queue(brvcc->device);
|
||||
+
|
||||
+ if (brvcc->old_release_cb)
|
||||
+ brvcc->old_release_cb(atmvcc);
|
||||
}
|
||||
|
||||
static inline struct br2684_vcc *pick_outgoing_vcc(const struct sk_buff *skb,
|
||||
@@ -279,6 +293,8 @@ static netdev_tx_t br2684_start_xmit(str
|
||||
{
|
||||
struct br2684_dev *brdev = BRPRIV(dev);
|
||||
struct br2684_vcc *brvcc;
|
||||
+ struct atm_vcc *atmvcc;
|
||||
+ netdev_tx_t ret = NETDEV_TX_OK;
|
||||
|
||||
pr_debug("skb_dst(skb)=%p\n", skb_dst(skb));
|
||||
read_lock(&devs_lock);
|
||||
@@ -289,9 +305,26 @@ static netdev_tx_t br2684_start_xmit(str
|
||||
dev->stats.tx_carrier_errors++;
|
||||
/* netif_stop_queue(dev); */
|
||||
dev_kfree_skb(skb);
|
||||
- read_unlock(&devs_lock);
|
||||
- return NETDEV_TX_OK;
|
||||
+ goto out_devs;
|
||||
}
|
||||
+ atmvcc = brvcc->atmvcc;
|
||||
+
|
||||
+ bh_lock_sock(sk_atm(atmvcc));
|
||||
+
|
||||
+ if (test_bit(ATM_VF_RELEASED, &atmvcc->flags) ||
|
||||
+ test_bit(ATM_VF_CLOSE, &atmvcc->flags) ||
|
||||
+ !test_bit(ATM_VF_READY, &atmvcc->flags)) {
|
||||
+ dev->stats.tx_dropped++;
|
||||
+ dev_kfree_skb(skb);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (sock_owned_by_user(sk_atm(atmvcc))) {
|
||||
+ netif_stop_queue(brvcc->device);
|
||||
+ ret = NETDEV_TX_BUSY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
if (!br2684_xmit_vcc(skb, dev, brvcc)) {
|
||||
/*
|
||||
* We should probably use netif_*_queue() here, but that
|
||||
@@ -303,8 +336,11 @@ static netdev_tx_t br2684_start_xmit(str
|
||||
dev->stats.tx_errors++;
|
||||
dev->stats.tx_fifo_errors++;
|
||||
}
|
||||
+ out:
|
||||
+ bh_unlock_sock(sk_atm(atmvcc));
|
||||
+ out_devs:
|
||||
read_unlock(&devs_lock);
|
||||
- return NETDEV_TX_OK;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -377,9 +413,10 @@ static void br2684_close_vcc(struct br26
|
||||
list_del(&brvcc->brvccs);
|
||||
write_unlock_irq(&devs_lock);
|
||||
brvcc->atmvcc->user_back = NULL; /* what about vcc->recvq ??? */
|
||||
+ brvcc->atmvcc->release_cb = brvcc->old_release_cb;
|
||||
brvcc->old_push(brvcc->atmvcc, NULL); /* pass on the bad news */
|
||||
+ module_put(brvcc->old_owner);
|
||||
kfree(brvcc);
|
||||
- module_put(THIS_MODULE);
|
||||
}
|
||||
|
||||
/* when AAL5 PDU comes in: */
|
||||
@@ -504,6 +541,13 @@ static int br2684_regvcc(struct atm_vcc
|
||||
brvcc = kzalloc(sizeof(struct br2684_vcc), GFP_KERNEL);
|
||||
if (!brvcc)
|
||||
return -ENOMEM;
|
||||
+ /*
|
||||
+ * Allow two packets in the ATM queue. One actually being sent, and one
|
||||
+ * for the ATM 'TX done' handler to send. It shouldn't take long to get
|
||||
+ * the next one from the netdev queue, when we need it. More than that
|
||||
+ * would be bufferbloat.
|
||||
+ */
|
||||
+ atomic_set(&brvcc->qspace, 2);
|
||||
write_lock_irq(&devs_lock);
|
||||
net_dev = br2684_find_dev(&be.ifspec);
|
||||
if (net_dev == NULL) {
|
||||
@@ -546,9 +590,13 @@ static int br2684_regvcc(struct atm_vcc
|
||||
brvcc->encaps = (enum br2684_encaps)be.encaps;
|
||||
brvcc->old_push = atmvcc->push;
|
||||
brvcc->old_pop = atmvcc->pop;
|
||||
+ brvcc->old_release_cb = atmvcc->release_cb;
|
||||
+ brvcc->old_owner = atmvcc->owner;
|
||||
barrier();
|
||||
atmvcc->push = br2684_push;
|
||||
atmvcc->pop = br2684_pop;
|
||||
+ atmvcc->release_cb = br2684_release_cb;
|
||||
+ atmvcc->owner = THIS_MODULE;
|
||||
|
||||
/* initialize netdev carrier state */
|
||||
if (atmvcc->dev->signal == ATM_PHY_SIG_LOST)
|
||||
@@ -687,10 +735,13 @@ static int br2684_ioctl(struct socket *s
|
||||
return -ENOIOCTLCMD;
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
- if (cmd == ATM_SETBACKEND)
|
||||
+ if (cmd == ATM_SETBACKEND) {
|
||||
+ if (sock->state != SS_CONNECTED)
|
||||
+ return -EINVAL;
|
||||
return br2684_regvcc(atmvcc, argp);
|
||||
- else
|
||||
+ } else {
|
||||
return br2684_create(argp);
|
||||
+ }
|
||||
#ifdef CONFIG_ATM_BR2684_IPFILTER
|
||||
case BR2684_SETFILT:
|
||||
if (atmvcc->push != br2684_push)
|
||||
--- a/net/atm/common.c
|
||||
+++ b/net/atm/common.c
|
||||
@@ -126,10 +126,19 @@ static void vcc_write_space(struct sock
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
+static void vcc_release_cb(struct sock *sk)
|
||||
+{
|
||||
+ struct atm_vcc *vcc = atm_sk(sk);
|
||||
+
|
||||
+ if (vcc->release_cb)
|
||||
+ vcc->release_cb(vcc);
|
||||
+}
|
||||
+
|
||||
static struct proto vcc_proto = {
|
||||
.name = "VCC",
|
||||
.owner = THIS_MODULE,
|
||||
.obj_size = sizeof(struct atm_vcc),
|
||||
+ .release_cb = vcc_release_cb,
|
||||
};
|
||||
|
||||
int vcc_create(struct net *net, struct socket *sock, int protocol, int family)
|
||||
@@ -156,7 +165,9 @@ int vcc_create(struct net *net, struct s
|
||||
atomic_set(&sk->sk_rmem_alloc, 0);
|
||||
vcc->push = NULL;
|
||||
vcc->pop = NULL;
|
||||
+ vcc->owner = NULL;
|
||||
vcc->push_oam = NULL;
|
||||
+ vcc->release_cb = NULL;
|
||||
vcc->vpi = vcc->vci = 0; /* no VCI/VPI yet */
|
||||
vcc->atm_options = vcc->aal_options = 0;
|
||||
sk->sk_destruct = vcc_sock_destruct;
|
||||
@@ -175,6 +186,7 @@ static void vcc_destroy_socket(struct so
|
||||
vcc->dev->ops->close(vcc);
|
||||
if (vcc->push)
|
||||
vcc->push(vcc, NULL); /* atmarpd has no push */
|
||||
+ module_put(vcc->owner);
|
||||
|
||||
while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
|
||||
atm_return(vcc, skb->truesize);
|
||||
--- a/net/atm/pppoatm.c
|
||||
+++ b/net/atm/pppoatm.c
|
||||
@@ -60,6 +60,8 @@ struct pppoatm_vcc {
|
||||
struct atm_vcc *atmvcc; /* VCC descriptor */
|
||||
void (*old_push)(struct atm_vcc *, struct sk_buff *);
|
||||
void (*old_pop)(struct atm_vcc *, struct sk_buff *);
|
||||
+ void (*old_release_cb)(struct atm_vcc *);
|
||||
+ struct module *old_owner;
|
||||
/* keep old push/pop for detaching */
|
||||
enum pppoatm_encaps encaps;
|
||||
atomic_t inflight;
|
||||
@@ -107,6 +109,24 @@ static void pppoatm_wakeup_sender(unsign
|
||||
ppp_output_wakeup((struct ppp_channel *) arg);
|
||||
}
|
||||
|
||||
+static void pppoatm_release_cb(struct atm_vcc *atmvcc)
|
||||
+{
|
||||
+ struct pppoatm_vcc *pvcc = atmvcc_to_pvcc(atmvcc);
|
||||
+
|
||||
+ /*
|
||||
+ * As in pppoatm_pop(), it's safe to clear the BLOCKED bit here because
|
||||
+ * the wakeup *can't* race with pppoatm_send(). They both hold the PPP
|
||||
+ * channel's ->downl lock. And the potential race with *setting* it,
|
||||
+ * which leads to the double-check dance in pppoatm_may_send(), doesn't
|
||||
+ * exist here. In the sock_owned_by_user() case in pppoatm_send(), we
|
||||
+ * set the BLOCKED bit while the socket is still locked. We know that
|
||||
+ * ->release_cb() can't be called until that's done.
|
||||
+ */
|
||||
+ if (test_and_clear_bit(BLOCKED, &pvcc->blocked))
|
||||
+ tasklet_schedule(&pvcc->wakeup_tasklet);
|
||||
+ if (pvcc->old_release_cb)
|
||||
+ pvcc->old_release_cb(atmvcc);
|
||||
+}
|
||||
/*
|
||||
* This gets called every time the ATM card has finished sending our
|
||||
* skb. The ->old_pop will take care up normal atm flow control,
|
||||
@@ -151,12 +171,11 @@ static void pppoatm_unassign_vcc(struct
|
||||
pvcc = atmvcc_to_pvcc(atmvcc);
|
||||
atmvcc->push = pvcc->old_push;
|
||||
atmvcc->pop = pvcc->old_pop;
|
||||
+ atmvcc->release_cb = pvcc->old_release_cb;
|
||||
tasklet_kill(&pvcc->wakeup_tasklet);
|
||||
ppp_unregister_channel(&pvcc->chan);
|
||||
atmvcc->user_back = NULL;
|
||||
kfree(pvcc);
|
||||
- /* Gee, I hope we have the big kernel lock here... */
|
||||
- module_put(THIS_MODULE);
|
||||
}
|
||||
|
||||
/* Called when an AAL5 PDU comes in */
|
||||
@@ -165,9 +184,13 @@ static void pppoatm_push(struct atm_vcc
|
||||
struct pppoatm_vcc *pvcc = atmvcc_to_pvcc(atmvcc);
|
||||
pr_debug("\n");
|
||||
if (skb == NULL) { /* VCC was closed */
|
||||
+ struct module *module;
|
||||
+
|
||||
pr_debug("removing ATMPPP VCC %p\n", pvcc);
|
||||
+ module = pvcc->old_owner;
|
||||
pppoatm_unassign_vcc(atmvcc);
|
||||
atmvcc->push(atmvcc, NULL); /* Pass along bad news */
|
||||
+ module_put(module);
|
||||
return;
|
||||
}
|
||||
atm_return(atmvcc, skb->truesize);
|
||||
@@ -211,7 +234,7 @@ error:
|
||||
ppp_input_error(&pvcc->chan, 0);
|
||||
}
|
||||
|
||||
-static inline int pppoatm_may_send(struct pppoatm_vcc *pvcc, int size)
|
||||
+static int pppoatm_may_send(struct pppoatm_vcc *pvcc, int size)
|
||||
{
|
||||
/*
|
||||
* It's not clear that we need to bother with using atm_may_send()
|
||||
@@ -269,10 +292,33 @@ static inline int pppoatm_may_send(struc
|
||||
static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
|
||||
{
|
||||
struct pppoatm_vcc *pvcc = chan_to_pvcc(chan);
|
||||
+ struct atm_vcc *vcc;
|
||||
+ int ret;
|
||||
+
|
||||
ATM_SKB(skb)->vcc = pvcc->atmvcc;
|
||||
pr_debug("(skb=0x%p, vcc=0x%p)\n", skb, pvcc->atmvcc);
|
||||
if (skb->data[0] == '\0' && (pvcc->flags & SC_COMP_PROT))
|
||||
(void) skb_pull(skb, 1);
|
||||
+
|
||||
+ vcc = ATM_SKB(skb)->vcc;
|
||||
+ bh_lock_sock(sk_atm(vcc));
|
||||
+ if (sock_owned_by_user(sk_atm(vcc))) {
|
||||
+ /*
|
||||
+ * Needs to happen (and be flushed, hence test_and_) before we unlock
|
||||
+ * the socket. It needs to be seen by the time our ->release_cb gets
|
||||
+ * called.
|
||||
+ */
|
||||
+ test_and_set_bit(BLOCKED, &pvcc->blocked);
|
||||
+ goto nospace;
|
||||
+ }
|
||||
+ if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
|
||||
+ test_bit(ATM_VF_CLOSE, &vcc->flags) ||
|
||||
+ !test_bit(ATM_VF_READY, &vcc->flags)) {
|
||||
+ bh_unlock_sock(sk_atm(vcc));
|
||||
+ kfree_skb(skb);
|
||||
+ return DROP_PACKET;
|
||||
+ }
|
||||
+
|
||||
switch (pvcc->encaps) { /* LLC encapsulation needed */
|
||||
case e_llc:
|
||||
if (skb_headroom(skb) < LLC_LEN) {
|
||||
@@ -285,8 +331,10 @@ static int pppoatm_send(struct ppp_chann
|
||||
}
|
||||
consume_skb(skb);
|
||||
skb = n;
|
||||
- if (skb == NULL)
|
||||
+ if (skb == NULL) {
|
||||
+ bh_unlock_sock(sk_atm(vcc));
|
||||
return DROP_PACKET;
|
||||
+ }
|
||||
} else if (!pppoatm_may_send(pvcc, skb->truesize))
|
||||
goto nospace;
|
||||
memcpy(skb_push(skb, LLC_LEN), pppllc, LLC_LEN);
|
||||
@@ -296,6 +344,7 @@ static int pppoatm_send(struct ppp_chann
|
||||
goto nospace;
|
||||
break;
|
||||
case e_autodetect:
|
||||
+ bh_unlock_sock(sk_atm(vcc));
|
||||
pr_debug("Trying to send without setting encaps!\n");
|
||||
kfree_skb(skb);
|
||||
return 1;
|
||||
@@ -305,9 +354,12 @@ static int pppoatm_send(struct ppp_chann
|
||||
ATM_SKB(skb)->atm_options = ATM_SKB(skb)->vcc->atm_options;
|
||||
pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n",
|
||||
skb, ATM_SKB(skb)->vcc, ATM_SKB(skb)->vcc->dev);
|
||||
- return ATM_SKB(skb)->vcc->send(ATM_SKB(skb)->vcc, skb)
|
||||
+ ret = ATM_SKB(skb)->vcc->send(ATM_SKB(skb)->vcc, skb)
|
||||
? DROP_PACKET : 1;
|
||||
+ bh_unlock_sock(sk_atm(vcc));
|
||||
+ return ret;
|
||||
nospace:
|
||||
+ bh_unlock_sock(sk_atm(vcc));
|
||||
/*
|
||||
* We don't have space to send this SKB now, but we might have
|
||||
* already applied SC_COMP_PROT compression, so may need to undo
|
||||
@@ -362,6 +414,8 @@ static int pppoatm_assign_vcc(struct atm
|
||||
atomic_set(&pvcc->inflight, NONE_INFLIGHT);
|
||||
pvcc->old_push = atmvcc->push;
|
||||
pvcc->old_pop = atmvcc->pop;
|
||||
+ pvcc->old_owner = atmvcc->owner;
|
||||
+ pvcc->old_release_cb = atmvcc->release_cb;
|
||||
pvcc->encaps = (enum pppoatm_encaps) be.encaps;
|
||||
pvcc->chan.private = pvcc;
|
||||
pvcc->chan.ops = &pppoatm_ops;
|
||||
@@ -377,7 +431,9 @@ static int pppoatm_assign_vcc(struct atm
|
||||
atmvcc->user_back = pvcc;
|
||||
atmvcc->push = pppoatm_push;
|
||||
atmvcc->pop = pppoatm_pop;
|
||||
+ atmvcc->release_cb = pppoatm_release_cb;
|
||||
__module_get(THIS_MODULE);
|
||||
+ atmvcc->owner = THIS_MODULE;
|
||||
|
||||
/* re-process everything received between connection setup and
|
||||
backend setup */
|
||||
@@ -406,6 +462,8 @@ static int pppoatm_ioctl(struct socket *
|
||||
return -ENOIOCTLCMD;
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
+ if (sock->state != SS_CONNECTED)
|
||||
+ return -EINVAL;
|
||||
return pppoatm_assign_vcc(atmvcc, argp);
|
||||
}
|
||||
case PPPIOCGCHAN:
|
@ -1,417 +0,0 @@
|
||||
commit 152a2a8b5e1d4cbe91a7c66f1028db15164a3766
|
||||
Author: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Date: Wed Dec 19 11:01:21 2012 +0000
|
||||
|
||||
solos-pci: ensure all TX packets are aligned to 4 bytes
|
||||
|
||||
The FPGA can't handled unaligned DMA (yet). So copy into an aligned buffer,
|
||||
if skb->data isn't suitably aligned.
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
commit 13af816469db3449c072afbae6c4c1bd9ccecccb
|
||||
Author: Nathan Williams <nathan@traverse.com.au>
|
||||
Date: Wed Dec 19 11:01:20 2012 +0000
|
||||
|
||||
solos-pci: add firmware upgrade support for new models
|
||||
|
||||
Signed-off-by: Nathan Williams <nathan@traverse.com.au>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
commit 7fbdadb5e951e4f0c0fc991ff5f50295568786e6
|
||||
Author: Nathan Williams <nathan@traverse.com.au>
|
||||
Date: Wed Dec 19 11:01:19 2012 +0000
|
||||
|
||||
solos-pci: remove superfluous debug output
|
||||
|
||||
Signed-off-by: Nathan Williams <nathan@traverse.com.au>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
commit f9baad02e7411d9f38d5ebe1a1cdcde4ceec100d
|
||||
Author: Nathan Williams <nathan@traverse.com.au>
|
||||
Date: Wed Dec 19 11:01:18 2012 +0000
|
||||
|
||||
solos-pci: add GPIO support for newer versions on Geos board
|
||||
|
||||
dwmw2: Tidy up a little, simpler matching on which GPIO is being accessed,
|
||||
only register on newer boards, register under PCI device instead of
|
||||
duplicating them under each ATM device.
|
||||
|
||||
Signed-off-by: Nathan Williams <nathan@traverse.com.au>
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
commit cae49ede00ec3d0cda290b03fee55b72b49efc11
|
||||
Author: David Woodhouse <dwmw2@infradead.org>
|
||||
Date: Tue Dec 11 14:57:14 2012 +0000
|
||||
|
||||
solos-pci: fix double-free of TX skb in DMA mode
|
||||
|
||||
We weren't clearing card->tx_skb[port] when processing the TX done interrupt.
|
||||
If there wasn't another skb ready to transmit immediately, this led to a
|
||||
double-free because we'd free it *again* next time we did have a packet to
|
||||
send.
|
||||
|
||||
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
|
||||
Cc: stable@kernel.org
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
==
|
||||
There is a typo here so we do a double lock instead of an unlock.
|
||||
|
||||
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
---
|
||||
Only needed in linux-next. Introduced in f9baad02e7411d9 [14/17]
|
||||
solos-pci: add GPIO support for newer versions on Geos board
|
||||
|
||||
|
||||
--- a/drivers/atm/solos-pci.c
|
||||
+++ b/drivers/atm/solos-pci.c
|
||||
@@ -42,7 +42,8 @@
|
||||
#include <linux/swab.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
-#define VERSION "0.07"
|
||||
+#define VERSION "1.04"
|
||||
+#define DRIVER_VERSION 0x01
|
||||
#define PTAG "solos-pci"
|
||||
|
||||
#define CONFIG_RAM_SIZE 128
|
||||
@@ -56,16 +57,21 @@
|
||||
#define FLASH_BUSY 0x60
|
||||
#define FPGA_MODE 0x5C
|
||||
#define FLASH_MODE 0x58
|
||||
+#define GPIO_STATUS 0x54
|
||||
+#define DRIVER_VER 0x50
|
||||
#define TX_DMA_ADDR(port) (0x40 + (4 * (port)))
|
||||
#define RX_DMA_ADDR(port) (0x30 + (4 * (port)))
|
||||
|
||||
#define DATA_RAM_SIZE 32768
|
||||
#define BUF_SIZE 2048
|
||||
#define OLD_BUF_SIZE 4096 /* For FPGA versions <= 2*/
|
||||
-#define FPGA_PAGE 528 /* FPGA flash page size*/
|
||||
-#define SOLOS_PAGE 512 /* Solos flash page size*/
|
||||
-#define FPGA_BLOCK (FPGA_PAGE * 8) /* FPGA flash block size*/
|
||||
-#define SOLOS_BLOCK (SOLOS_PAGE * 8) /* Solos flash block size*/
|
||||
+/* Old boards use ATMEL AD45DB161D flash */
|
||||
+#define ATMEL_FPGA_PAGE 528 /* FPGA flash page size*/
|
||||
+#define ATMEL_SOLOS_PAGE 512 /* Solos flash page size*/
|
||||
+#define ATMEL_FPGA_BLOCK (ATMEL_FPGA_PAGE * 8) /* FPGA block size*/
|
||||
+#define ATMEL_SOLOS_BLOCK (ATMEL_SOLOS_PAGE * 8) /* Solos block size*/
|
||||
+/* Current boards use M25P/M25PE SPI flash */
|
||||
+#define SPI_FLASH_BLOCK (256 * 64)
|
||||
|
||||
#define RX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2)
|
||||
#define TX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2 + (card->buffer_size))
|
||||
@@ -123,11 +129,14 @@ struct solos_card {
|
||||
struct sk_buff_head cli_queue[4];
|
||||
struct sk_buff *tx_skb[4];
|
||||
struct sk_buff *rx_skb[4];
|
||||
+ unsigned char *dma_bounce;
|
||||
wait_queue_head_t param_wq;
|
||||
wait_queue_head_t fw_wq;
|
||||
int using_dma;
|
||||
+ int dma_alignment;
|
||||
int fpga_version;
|
||||
int buffer_size;
|
||||
+ int atmel_flash;
|
||||
};
|
||||
|
||||
|
||||
@@ -452,7 +461,6 @@ static ssize_t console_show(struct devic
|
||||
|
||||
len = skb->len;
|
||||
memcpy(buf, skb->data, len);
|
||||
- dev_dbg(&card->dev->dev, "len: %d\n", len);
|
||||
|
||||
kfree_skb(skb);
|
||||
return len;
|
||||
@@ -499,6 +507,78 @@ static ssize_t console_store(struct devi
|
||||
return err?:count;
|
||||
}
|
||||
|
||||
+struct geos_gpio_attr {
|
||||
+ struct device_attribute attr;
|
||||
+ int offset;
|
||||
+};
|
||||
+
|
||||
+#define SOLOS_GPIO_ATTR(_name, _mode, _show, _store, _offset) \
|
||||
+ struct geos_gpio_attr gpio_attr_##_name = { \
|
||||
+ .attr = __ATTR(_name, _mode, _show, _store), \
|
||||
+ .offset = _offset }
|
||||
+
|
||||
+static ssize_t geos_gpio_store(struct device *dev, struct device_attribute *attr,
|
||||
+ const char *buf, size_t count)
|
||||
+{
|
||||
+ struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
|
||||
+ struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
|
||||
+ struct solos_card *card = pci_get_drvdata(pdev);
|
||||
+ uint32_t data32;
|
||||
+
|
||||
+ if (count != 1 && (count != 2 || buf[1] != '\n'))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ spin_lock_irq(&card->param_queue_lock);
|
||||
+ data32 = ioread32(card->config_regs + GPIO_STATUS);
|
||||
+ if (buf[0] == '1') {
|
||||
+ data32 |= 1 << gattr->offset;
|
||||
+ iowrite32(data32, card->config_regs + GPIO_STATUS);
|
||||
+ } else if (buf[0] == '0') {
|
||||
+ data32 &= ~(1 << gattr->offset);
|
||||
+ iowrite32(data32, card->config_regs + GPIO_STATUS);
|
||||
+ } else {
|
||||
+ count = -EINVAL;
|
||||
+ }
|
||||
+ spin_unlock_irq(&card->param_queue_lock);
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static ssize_t geos_gpio_show(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
|
||||
+ struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
|
||||
+ struct solos_card *card = pci_get_drvdata(pdev);
|
||||
+ uint32_t data32;
|
||||
+
|
||||
+ data32 = ioread32(card->config_regs + GPIO_STATUS);
|
||||
+ data32 = (data32 >> gattr->offset) & 1;
|
||||
+
|
||||
+ return sprintf(buf, "%d\n", data32);
|
||||
+}
|
||||
+
|
||||
+static ssize_t hardware_show(struct device *dev, struct device_attribute *attr,
|
||||
+ char *buf)
|
||||
+{
|
||||
+ struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
|
||||
+ struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
|
||||
+ struct solos_card *card = pci_get_drvdata(pdev);
|
||||
+ uint32_t data32;
|
||||
+
|
||||
+ data32 = ioread32(card->config_regs + GPIO_STATUS);
|
||||
+ switch (gattr->offset) {
|
||||
+ case 0:
|
||||
+ /* HardwareVersion */
|
||||
+ data32 = data32 & 0x1F;
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ /* HardwareVariant */
|
||||
+ data32 = (data32 >> 5) & 0x0F;
|
||||
+ break;
|
||||
+ }
|
||||
+ return sprintf(buf, "%d\n", data32);
|
||||
+}
|
||||
+
|
||||
static DEVICE_ATTR(console, 0644, console_show, console_store);
|
||||
|
||||
|
||||
@@ -507,6 +587,14 @@ static DEVICE_ATTR(console, 0644, consol
|
||||
|
||||
#include "solos-attrlist.c"
|
||||
|
||||
+static SOLOS_GPIO_ATTR(GPIO1, 0644, geos_gpio_show, geos_gpio_store, 9);
|
||||
+static SOLOS_GPIO_ATTR(GPIO2, 0644, geos_gpio_show, geos_gpio_store, 10);
|
||||
+static SOLOS_GPIO_ATTR(GPIO3, 0644, geos_gpio_show, geos_gpio_store, 11);
|
||||
+static SOLOS_GPIO_ATTR(GPIO4, 0644, geos_gpio_show, geos_gpio_store, 12);
|
||||
+static SOLOS_GPIO_ATTR(GPIO5, 0644, geos_gpio_show, geos_gpio_store, 13);
|
||||
+static SOLOS_GPIO_ATTR(PushButton, 0444, geos_gpio_show, NULL, 14);
|
||||
+static SOLOS_GPIO_ATTR(HardwareVersion, 0444, hardware_show, NULL, 0);
|
||||
+static SOLOS_GPIO_ATTR(HardwareVariant, 0444, hardware_show, NULL, 1);
|
||||
#undef SOLOS_ATTR_RO
|
||||
#undef SOLOS_ATTR_RW
|
||||
|
||||
@@ -523,6 +611,23 @@ static struct attribute_group solos_attr
|
||||
.name = "parameters",
|
||||
};
|
||||
|
||||
+static struct attribute *gpio_attrs[] = {
|
||||
+ &gpio_attr_GPIO1.attr.attr,
|
||||
+ &gpio_attr_GPIO2.attr.attr,
|
||||
+ &gpio_attr_GPIO3.attr.attr,
|
||||
+ &gpio_attr_GPIO4.attr.attr,
|
||||
+ &gpio_attr_GPIO5.attr.attr,
|
||||
+ &gpio_attr_PushButton.attr.attr,
|
||||
+ &gpio_attr_HardwareVersion.attr.attr,
|
||||
+ &gpio_attr_HardwareVariant.attr.attr,
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static struct attribute_group gpio_attr_group = {
|
||||
+ .attrs = gpio_attrs,
|
||||
+ .name = "gpio",
|
||||
+};
|
||||
+
|
||||
static int flash_upgrade(struct solos_card *card, int chip)
|
||||
{
|
||||
const struct firmware *fw;
|
||||
@@ -534,16 +639,25 @@ static int flash_upgrade(struct solos_ca
|
||||
switch (chip) {
|
||||
case 0:
|
||||
fw_name = "solos-FPGA.bin";
|
||||
- blocksize = FPGA_BLOCK;
|
||||
+ if (card->atmel_flash)
|
||||
+ blocksize = ATMEL_FPGA_BLOCK;
|
||||
+ else
|
||||
+ blocksize = SPI_FLASH_BLOCK;
|
||||
break;
|
||||
case 1:
|
||||
fw_name = "solos-Firmware.bin";
|
||||
- blocksize = SOLOS_BLOCK;
|
||||
+ if (card->atmel_flash)
|
||||
+ blocksize = ATMEL_SOLOS_BLOCK;
|
||||
+ else
|
||||
+ blocksize = SPI_FLASH_BLOCK;
|
||||
break;
|
||||
case 2:
|
||||
if (card->fpga_version > LEGACY_BUFFERS){
|
||||
fw_name = "solos-db-FPGA.bin";
|
||||
- blocksize = FPGA_BLOCK;
|
||||
+ if (card->atmel_flash)
|
||||
+ blocksize = ATMEL_FPGA_BLOCK;
|
||||
+ else
|
||||
+ blocksize = SPI_FLASH_BLOCK;
|
||||
} else {
|
||||
dev_info(&card->dev->dev, "FPGA version doesn't support"
|
||||
" daughter board upgrades\n");
|
||||
@@ -553,7 +667,10 @@ static int flash_upgrade(struct solos_ca
|
||||
case 3:
|
||||
if (card->fpga_version > LEGACY_BUFFERS){
|
||||
fw_name = "solos-Firmware.bin";
|
||||
- blocksize = SOLOS_BLOCK;
|
||||
+ if (card->atmel_flash)
|
||||
+ blocksize = ATMEL_SOLOS_BLOCK;
|
||||
+ else
|
||||
+ blocksize = SPI_FLASH_BLOCK;
|
||||
} else {
|
||||
dev_info(&card->dev->dev, "FPGA version doesn't support"
|
||||
" daughter board upgrades\n");
|
||||
@@ -569,6 +686,9 @@ static int flash_upgrade(struct solos_ca
|
||||
|
||||
dev_info(&card->dev->dev, "Flash upgrade starting\n");
|
||||
|
||||
+ /* New FPGAs require driver version before permitting flash upgrades */
|
||||
+ iowrite32(DRIVER_VERSION, card->config_regs + DRIVER_VER);
|
||||
+
|
||||
numblocks = fw->size / blocksize;
|
||||
dev_info(&card->dev->dev, "Firmware size: %zd\n", fw->size);
|
||||
dev_info(&card->dev->dev, "Number of blocks: %d\n", numblocks);
|
||||
@@ -598,9 +718,13 @@ static int flash_upgrade(struct solos_ca
|
||||
/* dev_info(&card->dev->dev, "Set FPGA Flash mode to Block Write\n"); */
|
||||
iowrite32(((chip * 2) + 1), card->config_regs + FLASH_MODE);
|
||||
|
||||
- /* Copy block to buffer, swapping each 16 bits */
|
||||
+ /* Copy block to buffer, swapping each 16 bits for Atmel flash */
|
||||
for(i = 0; i < blocksize; i += 4) {
|
||||
- uint32_t word = swahb32p((uint32_t *)(fw->data + offset + i));
|
||||
+ uint32_t word;
|
||||
+ if (card->atmel_flash)
|
||||
+ word = swahb32p((uint32_t *)(fw->data + offset + i));
|
||||
+ else
|
||||
+ word = *(uint32_t *)(fw->data + offset + i);
|
||||
if(card->fpga_version > LEGACY_BUFFERS)
|
||||
iowrite32(word, FLASH_BUF + i);
|
||||
else
|
||||
@@ -945,10 +1069,11 @@ static uint32_t fpga_tx(struct solos_car
|
||||
for (port = 0; tx_pending; tx_pending >>= 1, port++) {
|
||||
if (tx_pending & 1) {
|
||||
struct sk_buff *oldskb = card->tx_skb[port];
|
||||
- if (oldskb)
|
||||
+ if (oldskb) {
|
||||
pci_unmap_single(card->dev, SKB_CB(oldskb)->dma_addr,
|
||||
oldskb->len, PCI_DMA_TODEVICE);
|
||||
-
|
||||
+ card->tx_skb[port] = NULL;
|
||||
+ }
|
||||
spin_lock(&card->tx_queue_lock);
|
||||
skb = skb_dequeue(&card->tx_queue[port]);
|
||||
if (!skb)
|
||||
@@ -960,7 +1085,12 @@ static uint32_t fpga_tx(struct solos_car
|
||||
tx_started |= 1 << port;
|
||||
oldskb = skb; /* We're done with this skb already */
|
||||
} else if (skb && card->using_dma) {
|
||||
- SKB_CB(skb)->dma_addr = pci_map_single(card->dev, skb->data,
|
||||
+ unsigned char *data = skb->data;
|
||||
+ if ((unsigned long)data & card->dma_alignment) {
|
||||
+ data = card->dma_bounce + (BUF_SIZE * port);
|
||||
+ memcpy(data, skb->data, skb->len);
|
||||
+ }
|
||||
+ SKB_CB(skb)->dma_addr = pci_map_single(card->dev, data,
|
||||
skb->len, PCI_DMA_TODEVICE);
|
||||
card->tx_skb[port] = skb;
|
||||
iowrite32(SKB_CB(skb)->dma_addr,
|
||||
@@ -1134,18 +1264,33 @@ static int fpga_probe(struct pci_dev *de
|
||||
db_fpga_upgrade = db_firmware_upgrade = 0;
|
||||
}
|
||||
|
||||
+ /* Stopped using Atmel flash after 0.03-38 */
|
||||
+ if (fpga_ver < 39)
|
||||
+ card->atmel_flash = 1;
|
||||
+ else
|
||||
+ card->atmel_flash = 0;
|
||||
+
|
||||
+ data32 = ioread32(card->config_regs + PORTS);
|
||||
+ card->nr_ports = (data32 & 0x000000FF);
|
||||
+
|
||||
if (card->fpga_version >= DMA_SUPPORTED) {
|
||||
pci_set_master(dev);
|
||||
card->using_dma = 1;
|
||||
+ if (1) { /* All known FPGA versions so far */
|
||||
+ card->dma_alignment = 3;
|
||||
+ card->dma_bounce = kmalloc(card->nr_ports * BUF_SIZE, GFP_KERNEL);
|
||||
+ if (!card->dma_bounce) {
|
||||
+ dev_warn(&card->dev->dev, "Failed to allocate DMA bounce buffers\n");
|
||||
+ /* Fallback to MMIO doesn't work */
|
||||
+ goto out_unmap_both;
|
||||
+ }
|
||||
+ }
|
||||
} else {
|
||||
card->using_dma = 0;
|
||||
/* Set RX empty flag for all ports */
|
||||
iowrite32(0xF0, card->config_regs + FLAGS_ADDR);
|
||||
}
|
||||
|
||||
- data32 = ioread32(card->config_regs + PORTS);
|
||||
- card->nr_ports = (data32 & 0x000000FF);
|
||||
-
|
||||
pci_set_drvdata(dev, card);
|
||||
|
||||
tasklet_init(&card->tlet, solos_bh, (unsigned long)card);
|
||||
@@ -1180,6 +1325,10 @@ static int fpga_probe(struct pci_dev *de
|
||||
if (err)
|
||||
goto out_free_irq;
|
||||
|
||||
+ if (card->fpga_version >= DMA_SUPPORTED &&
|
||||
+ sysfs_create_group(&card->dev->dev.kobj, &gpio_attr_group))
|
||||
+ dev_err(&card->dev->dev, "Could not register parameter group for GPIOs\n");
|
||||
+
|
||||
return 0;
|
||||
|
||||
out_free_irq:
|
||||
@@ -1188,6 +1337,7 @@ static int fpga_probe(struct pci_dev *de
|
||||
tasklet_kill(&card->tlet);
|
||||
|
||||
out_unmap_both:
|
||||
+ kfree(card->dma_bounce);
|
||||
pci_set_drvdata(dev, NULL);
|
||||
pci_iounmap(dev, card->buffers);
|
||||
out_unmap_config:
|
||||
@@ -1290,11 +1440,16 @@ static void fpga_remove(struct pci_dev *
|
||||
iowrite32(1, card->config_regs + FPGA_MODE);
|
||||
(void)ioread32(card->config_regs + FPGA_MODE);
|
||||
|
||||
+ if (card->fpga_version >= DMA_SUPPORTED)
|
||||
+ sysfs_remove_group(&card->dev->dev.kobj, &gpio_attr_group);
|
||||
+
|
||||
atm_remove(card);
|
||||
|
||||
free_irq(dev->irq, card);
|
||||
tasklet_kill(&card->tlet);
|
||||
|
||||
+ kfree(card->dma_bounce);
|
||||
+
|
||||
/* Release device from reset */
|
||||
iowrite32(0, card->config_regs + FPGA_MODE);
|
||||
(void)ioread32(card->config_regs + FPGA_MODE);
|
@ -1,11 +0,0 @@
|
||||
--- a/scripts/setlocalversion
|
||||
+++ b/scripts/setlocalversion
|
||||
@@ -167,7 +167,7 @@ else
|
||||
# annotated or signed tagged state (as git describe only
|
||||
# looks at signed or annotated tags - git tag -a/-s) and
|
||||
# LOCALVERSION= is not specified
|
||||
- if test "${LOCALVERSION+set}" != "set"; then
|
||||
+ if test "${CONFIG_LOCALVERSION+set}" != "set"; then
|
||||
scm=$(scm_version --short)
|
||||
res="$res${scm:++}"
|
||||
fi
|
@ -1,14 +0,0 @@
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -556,9 +556,9 @@ endif # $(dot-config)
|
||||
all: vmlinux
|
||||
|
||||
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
|
||||
-KBUILD_CFLAGS += -Os
|
||||
+KBUILD_CFLAGS += -Os $(EXTRA_OPTIMIZATION)
|
||||
else
|
||||
-KBUILD_CFLAGS += -O2
|
||||
+KBUILD_CFLAGS += -O2 -fno-reorder-blocks -fno-tree-ch $(EXTRA_OPTIMIZATION)
|
||||
endif
|
||||
|
||||
include $(srctree)/arch/$(SRCARCH)/Makefile
|
@ -1,11 +0,0 @@
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -369,7 +369,7 @@ KBUILD_CFLAGS_KERNEL :=
|
||||
KBUILD_AFLAGS := -D__ASSEMBLY__
|
||||
KBUILD_AFLAGS_MODULE := -DMODULE
|
||||
KBUILD_CFLAGS_MODULE := -DMODULE
|
||||
-KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds
|
||||
+KBUILD_LDFLAGS_MODULE = -T $(srctree)/scripts/module-common.lds $(if $(CONFIG_PROFILING),,-s)
|
||||
|
||||
# Read KERNELRELEASE from include/config/kernel.release (if it exists)
|
||||
KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
|
File diff suppressed because it is too large
Load Diff
@ -1,17 +0,0 @@
|
||||
--- a/include/linux/stddef.h
|
||||
+++ b/include/linux/stddef.h
|
||||
@@ -12,6 +12,7 @@ enum {
|
||||
false = 0,
|
||||
true = 1
|
||||
};
|
||||
+#endif /* __KERNEL__ */
|
||||
|
||||
#undef offsetof
|
||||
#ifdef __compiler_offsetof
|
||||
@@ -19,6 +20,5 @@ enum {
|
||||
#else
|
||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
||||
#endif
|
||||
-#endif /* __KERNEL__ */
|
||||
|
||||
#endif
|
@ -1,53 +0,0 @@
|
||||
--- a/tools/include/tools/be_byteshift.h
|
||||
+++ b/tools/include/tools/be_byteshift.h
|
||||
@@ -1,7 +1,11 @@
|
||||
#ifndef _TOOLS_BE_BYTESHIFT_H
|
||||
#define _TOOLS_BE_BYTESHIFT_H
|
||||
|
||||
+#ifdef __linux__
|
||||
#include <linux/types.h>
|
||||
+#else
|
||||
+#include "linux_types.h"
|
||||
+#endif
|
||||
|
||||
static inline __u16 __get_unaligned_be16(const __u8 *p)
|
||||
{
|
||||
--- a/tools/include/tools/le_byteshift.h
|
||||
+++ b/tools/include/tools/le_byteshift.h
|
||||
@@ -1,7 +1,11 @@
|
||||
#ifndef _TOOLS_LE_BYTESHIFT_H
|
||||
#define _TOOLS_LE_BYTESHIFT_H
|
||||
|
||||
+#ifdef __linux__
|
||||
#include <linux/types.h>
|
||||
+#else
|
||||
+#include "linux_types.h"
|
||||
+#endif
|
||||
|
||||
static inline __u16 __get_unaligned_le16(const __u8 *p)
|
||||
{
|
||||
--- /dev/null
|
||||
+++ b/tools/include/tools/linux_types.h
|
||||
@@ -0,0 +1,22 @@
|
||||
+#ifndef __LINUX_TYPES_H
|
||||
+#define __LINUX_TYPES_H
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+typedef uint8_t __u8;
|
||||
+typedef uint8_t __be8;
|
||||
+typedef uint8_t __le8;
|
||||
+
|
||||
+typedef uint16_t __u16;
|
||||
+typedef uint16_t __be16;
|
||||
+typedef uint16_t __le16;
|
||||
+
|
||||
+typedef uint32_t __u32;
|
||||
+typedef uint32_t __be32;
|
||||
+typedef uint32_t __le32;
|
||||
+
|
||||
+typedef uint64_t __u64;
|
||||
+typedef uint64_t __be64;
|
||||
+typedef uint64_t __le64;
|
||||
+
|
||||
+#endif
|
@ -1,91 +0,0 @@
|
||||
--- a/include/asm-generic/vmlinux.lds.h
|
||||
+++ b/include/asm-generic/vmlinux.lds.h
|
||||
@@ -52,6 +52,18 @@
|
||||
#define LOAD_OFFSET 0
|
||||
#endif
|
||||
|
||||
+#ifndef SYMTAB_KEEP_STR
|
||||
+#define SYMTAB_KEEP *(SORT(___ksymtab+*))
|
||||
+#define SYMTAB_KEEP_GPL *(SORT(___ksymtab_gpl+*))
|
||||
+#define SYMTAB_KEEP_STR *(__ksymtab_strings+*)
|
||||
+#endif
|
||||
+
|
||||
+#ifndef SYMTAB_DISCARD
|
||||
+#define SYMTAB_DISCARD
|
||||
+#define SYMTAB_DISCARD_GPL
|
||||
+#define SYMTAB_DISCARD_STR
|
||||
+#endif
|
||||
+
|
||||
#ifndef SYMBOL_PREFIX
|
||||
#define VMLINUX_SYMBOL(sym) sym
|
||||
#else
|
||||
@@ -276,14 +288,14 @@
|
||||
/* Kernel symbol table: Normal symbols */ \
|
||||
__ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \
|
||||
VMLINUX_SYMBOL(__start___ksymtab) = .; \
|
||||
- *(SORT(___ksymtab+*)) \
|
||||
+ SYMTAB_KEEP \
|
||||
VMLINUX_SYMBOL(__stop___ksymtab) = .; \
|
||||
} \
|
||||
\
|
||||
/* Kernel symbol table: GPL-only symbols */ \
|
||||
__ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \
|
||||
VMLINUX_SYMBOL(__start___ksymtab_gpl) = .; \
|
||||
- *(SORT(___ksymtab_gpl+*)) \
|
||||
+ SYMTAB_KEEP_GPL \
|
||||
VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \
|
||||
} \
|
||||
\
|
||||
@@ -345,7 +357,7 @@
|
||||
\
|
||||
/* Kernel symbol table: strings */ \
|
||||
__ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
|
||||
- *(__ksymtab_strings) \
|
||||
+ SYMTAB_KEEP_STR \
|
||||
} \
|
||||
\
|
||||
/* __*init sections */ \
|
||||
@@ -670,6 +682,9 @@
|
||||
EXIT_TEXT \
|
||||
EXIT_DATA \
|
||||
EXIT_CALL \
|
||||
+ SYMTAB_DISCARD \
|
||||
+ SYMTAB_DISCARD_GPL \
|
||||
+ SYMTAB_DISCARD_STR \
|
||||
*(.discard) \
|
||||
*(.discard.*) \
|
||||
}
|
||||
--- a/include/linux/export.h
|
||||
+++ b/include/linux/export.h
|
||||
@@ -45,12 +45,19 @@ extern struct module __this_module;
|
||||
#define __CRC_SYMBOL(sym, sec)
|
||||
#endif
|
||||
|
||||
+#ifdef MODULE
|
||||
+#define __EXPORT_SUFFIX(sym)
|
||||
+#else
|
||||
+#define __EXPORT_SUFFIX(sym) "+" #sym
|
||||
+#endif
|
||||
+
|
||||
/* For every exported symbol, place a struct in the __ksymtab section */
|
||||
#define __EXPORT_SYMBOL(sym, sec) \
|
||||
extern typeof(sym) sym; \
|
||||
__CRC_SYMBOL(sym, sec) \
|
||||
static const char __kstrtab_##sym[] \
|
||||
- __attribute__((section("__ksymtab_strings"), aligned(1))) \
|
||||
+ __attribute__((section("__ksymtab_strings" \
|
||||
+ __EXPORT_SUFFIX(sym)), aligned(1))) \
|
||||
= MODULE_SYMBOL_PREFIX #sym; \
|
||||
static const struct kernel_symbol __ksymtab_##sym \
|
||||
__used \
|
||||
--- a/scripts/Makefile.build
|
||||
+++ b/scripts/Makefile.build
|
||||
@@ -348,7 +348,7 @@ targets += $(extra-y) $(MAKECMDGOALS) $(
|
||||
# Linker scripts preprocessor (.lds.S -> .lds)
|
||||
# ---------------------------------------------------------------------------
|
||||
quiet_cmd_cpp_lds_S = LDS $@
|
||||
- cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -C -U$(ARCH) \
|
||||
+ cmd_cpp_lds_S = $(CPP) $(EXTRA_LDSFLAGS) $(cpp_flags) -P -C -U$(ARCH) \
|
||||
-D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
|
||||
|
||||
$(obj)/%.lds: $(src)/%.lds.S FORCE
|
@ -1,54 +0,0 @@
|
||||
--- a/scripts/Makefile.lib
|
||||
+++ b/scripts/Makefile.lib
|
||||
@@ -296,7 +296,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^)
|
||||
|
||||
quiet_cmd_lzma = LZMA $@
|
||||
cmd_lzma = (cat $(filter-out FORCE,$^) | \
|
||||
- lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
|
||||
+ lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
|
||||
(rm -f $@ ; false)
|
||||
|
||||
quiet_cmd_lzo = LZO $@
|
||||
--- a/scripts/gen_initramfs_list.sh
|
||||
+++ b/scripts/gen_initramfs_list.sh
|
||||
@@ -226,7 +226,7 @@ cpio_list=
|
||||
output="/dev/stdout"
|
||||
output_file=""
|
||||
is_cpio_compressed=
|
||||
-compr="gzip -n -9 -f"
|
||||
+compr="gzip -n -9 -f -"
|
||||
|
||||
arg="$1"
|
||||
case "$arg" in
|
||||
@@ -240,9 +240,9 @@ case "$arg" in
|
||||
output_file="$1"
|
||||
cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)"
|
||||
output=${cpio_list}
|
||||
- echo "$output_file" | grep -q "\.gz$" && compr="gzip -n -9 -f"
|
||||
- echo "$output_file" | grep -q "\.bz2$" && compr="bzip2 -9 -f"
|
||||
- echo "$output_file" | grep -q "\.lzma$" && compr="lzma -9 -f"
|
||||
+ echo "$output_file" | grep -q "\.gz$" && compr="gzip -n -9 -f -"
|
||||
+ echo "$output_file" | grep -q "\.bz2$" && compr="bzip2 -9 -f -"
|
||||
+ echo "$output_file" | grep -q "\.lzma$" && compr="lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so"
|
||||
echo "$output_file" | grep -q "\.xz$" && \
|
||||
compr="xz --check=crc32 --lzma2=dict=1MiB"
|
||||
echo "$output_file" | grep -q "\.lzo$" && compr="lzop -9 -f"
|
||||
@@ -303,7 +303,7 @@ if [ ! -z ${output_file} ]; then
|
||||
if [ "${is_cpio_compressed}" = "compressed" ]; then
|
||||
cat ${cpio_tfile} > ${output_file}
|
||||
else
|
||||
- (cat ${cpio_tfile} | ${compr} - > ${output_file}) \
|
||||
+ (cat ${cpio_tfile} | ${compr} > ${output_file}) \
|
||||
|| (rm -f ${output_file} ; false)
|
||||
fi
|
||||
[ -z ${cpio_file} ] && rm ${cpio_tfile}
|
||||
--- a/lib/decompress.c
|
||||
+++ b/lib/decompress.c
|
||||
@@ -40,6 +40,7 @@ static const struct compress_format {
|
||||
{ {037, 0236}, "gzip", gunzip },
|
||||
{ {0x42, 0x5a}, "bzip2", bunzip2 },
|
||||
{ {0x5d, 0x00}, "lzma", unlzma },
|
||||
+ { {0x6d, 0x00}, "lzma-openwrt", unlzma },
|
||||
{ {0xfd, 0x37}, "xz", unxz },
|
||||
{ {0x89, 0x4c}, "lzo", unlzo },
|
||||
{ {0, 0}, NULL, NULL }
|
@ -1,18 +0,0 @@
|
||||
--- a/net/netfilter/Kconfig
|
||||
+++ b/net/netfilter/Kconfig
|
||||
@@ -191,7 +191,6 @@ config NF_CONNTRACK_FTP
|
||||
|
||||
config NF_CONNTRACK_H323
|
||||
tristate "H.323 protocol support"
|
||||
- depends on (IPV6 || IPV6=n)
|
||||
depends on NETFILTER_ADVANCED
|
||||
help
|
||||
H.323 is a VoIP signalling protocol from ITU-T. As one of the most
|
||||
@@ -693,7 +692,6 @@ config NETFILTER_XT_TARGET_SECMARK
|
||||
|
||||
config NETFILTER_XT_TARGET_TCPMSS
|
||||
tristate '"TCPMSS" target support'
|
||||
- depends on (IPV6 || IPV6=n)
|
||||
default m if NETFILTER_ADVANCED=n
|
||||
---help---
|
||||
This option adds a `TCPMSS' target, which allows you to alter the
|
@ -1,18 +0,0 @@
|
||||
--- a/sound/core/Kconfig
|
||||
+++ b/sound/core/Kconfig
|
||||
@@ -7,13 +7,13 @@ config SND_PCM
|
||||
select SND_TIMER
|
||||
|
||||
config SND_HWDEP
|
||||
- tristate
|
||||
+ tristate "Sound hardware support"
|
||||
|
||||
config SND_RAWMIDI
|
||||
tristate
|
||||
|
||||
config SND_COMPRESS_OFFLOAD
|
||||
- tristate
|
||||
+ tristate "Compression offloading support"
|
||||
|
||||
# To be effective this also requires INPUT - users should say:
|
||||
# select SND_JACK if INPUT=y || INPUT=SND
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/crypto/Kconfig
|
||||
+++ b/drivers/crypto/Kconfig
|
||||
@@ -164,6 +164,7 @@ config CRYPTO_DEV_MV_CESA
|
||||
depends on PLAT_ORION
|
||||
select CRYPTO_ALGAPI
|
||||
select CRYPTO_AES
|
||||
+ select CRYPTO_HASH2
|
||||
select CRYPTO_BLKCIPHER2
|
||||
select CRYPTO_HASH
|
||||
help
|
@ -1,29 +0,0 @@
|
||||
--- a/drivers/ssb/Kconfig
|
||||
+++ b/drivers/ssb/Kconfig
|
||||
@@ -29,6 +29,7 @@ config SSB_SPROM
|
||||
config SSB_BLOCKIO
|
||||
bool
|
||||
depends on SSB
|
||||
+ default y
|
||||
|
||||
config SSB_PCIHOST_POSSIBLE
|
||||
bool
|
||||
@@ -49,7 +50,7 @@ config SSB_PCIHOST
|
||||
config SSB_B43_PCI_BRIDGE
|
||||
bool
|
||||
depends on SSB_PCIHOST
|
||||
- default n
|
||||
+ default y
|
||||
|
||||
config SSB_PCMCIAHOST_POSSIBLE
|
||||
bool
|
||||
--- a/drivers/bcma/Kconfig
|
||||
+++ b/drivers/bcma/Kconfig
|
||||
@@ -17,6 +17,7 @@ config BCMA
|
||||
config BCMA_BLOCKIO
|
||||
bool
|
||||
depends on BCMA
|
||||
+ default y
|
||||
|
||||
config BCMA_HOST_PCI_POSSIBLE
|
||||
bool
|
@ -1,23 +0,0 @@
|
||||
--- a/lib/Kconfig
|
||||
+++ b/lib/Kconfig
|
||||
@@ -277,16 +277,16 @@ config BCH_CONST_T
|
||||
# Textsearch support is select'ed if needed
|
||||
#
|
||||
config TEXTSEARCH
|
||||
- boolean
|
||||
+ boolean "Textsearch support"
|
||||
|
||||
config TEXTSEARCH_KMP
|
||||
- tristate
|
||||
+ tristate "Textsearch KMP"
|
||||
|
||||
config TEXTSEARCH_BM
|
||||
- tristate
|
||||
+ tristate "Textsearch BM"
|
||||
|
||||
config TEXTSEARCH_FSM
|
||||
- tristate
|
||||
+ tristate "Textsearch FSM"
|
||||
|
||||
config BTREE
|
||||
boolean
|
@ -1,19 +0,0 @@
|
||||
--- a/net/wireless/Kconfig
|
||||
+++ b/net/wireless/Kconfig
|
||||
@@ -150,13 +150,13 @@ config LIB80211
|
||||
you want this built into your kernel.
|
||||
|
||||
config LIB80211_CRYPT_WEP
|
||||
- tristate
|
||||
+ tristate "LIB80211_CRYPT_WEP"
|
||||
|
||||
config LIB80211_CRYPT_CCMP
|
||||
- tristate
|
||||
+ tristate "LIB80211_CRYPT_CCMP"
|
||||
|
||||
config LIB80211_CRYPT_TKIP
|
||||
- tristate
|
||||
+ tristate "LIB80211_CRYPT_TKIP"
|
||||
|
||||
config LIB80211_DEBUG
|
||||
bool "lib80211 debugging messages"
|
@ -1,47 +0,0 @@
|
||||
--- a/crypto/Kconfig
|
||||
+++ b/crypto/Kconfig
|
||||
@@ -31,7 +31,7 @@ config CRYPTO_FIPS
|
||||
this is.
|
||||
|
||||
config CRYPTO_ALGAPI
|
||||
- tristate
|
||||
+ tristate "ALGAPI"
|
||||
select CRYPTO_ALGAPI2
|
||||
help
|
||||
This option provides the API for cryptographic algorithms.
|
||||
@@ -40,7 +40,7 @@ config CRYPTO_ALGAPI2
|
||||
tristate
|
||||
|
||||
config CRYPTO_AEAD
|
||||
- tristate
|
||||
+ tristate "AEAD"
|
||||
select CRYPTO_AEAD2
|
||||
select CRYPTO_ALGAPI
|
||||
|
||||
@@ -49,7 +49,7 @@ config CRYPTO_AEAD2
|
||||
select CRYPTO_ALGAPI2
|
||||
|
||||
config CRYPTO_BLKCIPHER
|
||||
- tristate
|
||||
+ tristate "BLKCIPHER"
|
||||
select CRYPTO_BLKCIPHER2
|
||||
select CRYPTO_ALGAPI
|
||||
|
||||
@@ -60,7 +60,7 @@ config CRYPTO_BLKCIPHER2
|
||||
select CRYPTO_WORKQUEUE
|
||||
|
||||
config CRYPTO_HASH
|
||||
- tristate
|
||||
+ tristate "HASH"
|
||||
select CRYPTO_HASH2
|
||||
select CRYPTO_ALGAPI
|
||||
|
||||
@@ -69,7 +69,7 @@ config CRYPTO_HASH2
|
||||
select CRYPTO_ALGAPI2
|
||||
|
||||
config CRYPTO_RNG
|
||||
- tristate
|
||||
+ tristate "RNG"
|
||||
select CRYPTO_RNG2
|
||||
select CRYPTO_ALGAPI
|
||||
|
@ -1,22 +0,0 @@
|
||||
--- a/net/wireless/Kconfig
|
||||
+++ b/net/wireless/Kconfig
|
||||
@@ -1,5 +1,5 @@
|
||||
config WIRELESS_EXT
|
||||
- bool
|
||||
+ bool "Wireless extensions"
|
||||
|
||||
config WEXT_CORE
|
||||
def_bool y
|
||||
@@ -11,10 +11,10 @@ config WEXT_PROC
|
||||
depends on WEXT_CORE
|
||||
|
||||
config WEXT_SPY
|
||||
- bool
|
||||
+ bool "WEXT_SPY"
|
||||
|
||||
config WEXT_PRIV
|
||||
- bool
|
||||
+ bool "WEXT_PRIV"
|
||||
|
||||
config CFG80211
|
||||
tristate "cfg80211 - wireless configuration API"
|
@ -1,11 +0,0 @@
|
||||
--- a/net/netfilter/Kconfig
|
||||
+++ b/net/netfilter/Kconfig
|
||||
@@ -2,7 +2,7 @@ menu "Core Netfilter Configuration"
|
||||
depends on NET && INET && NETFILTER
|
||||
|
||||
config NETFILTER_NETLINK
|
||||
- tristate
|
||||
+ tristate "Netfilter NFNETLINK interface"
|
||||
|
||||
config NETFILTER_NETLINK_ACCT
|
||||
tristate "Netfilter NFACCT over NFNETLINK interface"
|
@ -1,23 +0,0 @@
|
||||
--- a/lib/Kconfig
|
||||
+++ b/lib/Kconfig
|
||||
@@ -175,16 +175,16 @@ config AUDIT_GENERIC
|
||||
# compression support is select'ed if needed
|
||||
#
|
||||
config ZLIB_INFLATE
|
||||
- tristate
|
||||
+ tristate "ZLIB inflate support"
|
||||
|
||||
config ZLIB_DEFLATE
|
||||
- tristate
|
||||
+ tristate "ZLIB deflate support"
|
||||
|
||||
config LZO_COMPRESS
|
||||
- tristate
|
||||
+ tristate "LZO compress support"
|
||||
|
||||
config LZO_DECOMPRESS
|
||||
- tristate
|
||||
+ tristate "LZO decompress support"
|
||||
|
||||
source "lib/xz/Kconfig"
|
||||
|
@ -1,219 +0,0 @@
|
||||
--- a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h
|
||||
+++ /dev/null
|
||||
@@ -1,96 +0,0 @@
|
||||
-#ifndef __BCM963XX_TAG_H
|
||||
-#define __BCM963XX_TAG_H
|
||||
-
|
||||
-#define TAGVER_LEN 4 /* Length of Tag Version */
|
||||
-#define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */
|
||||
-#define SIG1_LEN 20 /* Company Signature 1 Length */
|
||||
-#define SIG2_LEN 14 /* Company Signature 2 Length */
|
||||
-#define BOARDID_LEN 16 /* Length of BoardId */
|
||||
-#define ENDIANFLAG_LEN 2 /* Endian Flag Length */
|
||||
-#define CHIPID_LEN 6 /* Chip Id Length */
|
||||
-#define IMAGE_LEN 10 /* Length of Length Field */
|
||||
-#define ADDRESS_LEN 12 /* Length of Address field */
|
||||
-#define DUALFLAG_LEN 2 /* Dual Image flag Length */
|
||||
-#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */
|
||||
-#define RSASIG_LEN 20 /* Length of RSA Signature in tag */
|
||||
-#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */
|
||||
-#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */
|
||||
-#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */
|
||||
-#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */
|
||||
-
|
||||
-#define NUM_PIRELLI 2
|
||||
-#define IMAGETAG_CRC_START 0xFFFFFFFF
|
||||
-
|
||||
-#define PIRELLI_BOARDS { \
|
||||
- "AGPF-S0", \
|
||||
- "DWV-S0", \
|
||||
-}
|
||||
-
|
||||
-/*
|
||||
- * The broadcom firmware assumes the rootfs starts the image,
|
||||
- * therefore uses the rootfs start (flash_image_address)
|
||||
- * to determine where to flash the image. Since we have the kernel first
|
||||
- * we have to give it the kernel address, but the crc uses the length
|
||||
- * associated with this address (root_length), which is added to the kernel
|
||||
- * length (kernel_length) to determine the length of image to flash and thus
|
||||
- * needs to be rootfs + deadcode (jffs2 EOF marker)
|
||||
-*/
|
||||
-
|
||||
-struct bcm_tag {
|
||||
- /* 0-3: Version of the image tag */
|
||||
- char tag_version[TAGVER_LEN];
|
||||
- /* 4-23: Company Line 1 */
|
||||
- char sig_1[SIG1_LEN];
|
||||
- /* 24-37: Company Line 2 */
|
||||
- char sig_2[SIG2_LEN];
|
||||
- /* 38-43: Chip this image is for */
|
||||
- char chip_id[CHIPID_LEN];
|
||||
- /* 44-59: Board name */
|
||||
- char board_id[BOARDID_LEN];
|
||||
- /* 60-61: Map endianness -- 1 BE 0 LE */
|
||||
- char big_endian[ENDIANFLAG_LEN];
|
||||
- /* 62-71: Total length of image */
|
||||
- char total_length[IMAGE_LEN];
|
||||
- /* 72-83: Address in memory of CFE */
|
||||
- char cfe__address[ADDRESS_LEN];
|
||||
- /* 84-93: Size of CFE */
|
||||
- char cfe_length[IMAGE_LEN];
|
||||
- /* 94-105: Address in memory of image start
|
||||
- * (kernel for OpenWRT, rootfs for stock firmware)
|
||||
- */
|
||||
- char flash_image_start[ADDRESS_LEN];
|
||||
- /* 106-115: Size of rootfs */
|
||||
- char root_length[IMAGE_LEN];
|
||||
- /* 116-127: Address in memory of kernel */
|
||||
- char kernel_address[ADDRESS_LEN];
|
||||
- /* 128-137: Size of kernel */
|
||||
- char kernel_length[IMAGE_LEN];
|
||||
- /* 138-139: Unused at the moment */
|
||||
- char dual_image[DUALFLAG_LEN];
|
||||
- /* 140-141: Unused at the moment */
|
||||
- char inactive_flag[INACTIVEFLAG_LEN];
|
||||
- /* 142-161: RSA Signature (not used; some vendors may use this) */
|
||||
- char rsa_signature[RSASIG_LEN];
|
||||
- /* 162-191: Compilation and related information (not used in OpenWrt) */
|
||||
- char information1[TAGINFO1_LEN];
|
||||
- /* 192-195: Version flash layout */
|
||||
- char flash_layout_ver[FLASHLAYOUTVER_LEN];
|
||||
- /* 196-199: kernel+rootfs CRC32 */
|
||||
- __u32 fskernel_crc;
|
||||
- /* 200-215: Unused except on Alice Gate where is is information */
|
||||
- char information2[TAGINFO2_LEN];
|
||||
- /* 216-219: CRC32 of image less imagetag (kernel for Alice Gate) */
|
||||
- __u32 image_crc;
|
||||
- /* 220-223: CRC32 of rootfs partition */
|
||||
- __u32 rootfs_crc;
|
||||
- /* 224-227: CRC32 of kernel partition */
|
||||
- __u32 kernel_crc;
|
||||
- /* 228-235: Unused at present */
|
||||
- char reserved1[8];
|
||||
- /* 236-239: CRC32 of header excluding last 20 bytes */
|
||||
- __u32 header_crc;
|
||||
- /* 240-255: Unused at present */
|
||||
- char reserved2[16];
|
||||
-};
|
||||
-
|
||||
-#endif /* __BCM63XX_TAG_H */
|
||||
--- a/drivers/mtd/bcm63xxpart.c
|
||||
+++ b/drivers/mtd/bcm63xxpart.c
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
||||
-#include <asm/mach-bcm63xx/bcm963xx_tag.h>
|
||||
+#include <linux/bcm963xx_tag.h>
|
||||
#include <asm/mach-bcm63xx/board_bcm963xx.h>
|
||||
|
||||
#define BCM63XX_EXTENDED_SIZE 0xBFC00000 /* Extended flash address */
|
||||
--- a/include/linux/Kbuild
|
||||
+++ b/include/linux/Kbuild
|
||||
@@ -78,6 +78,7 @@ header-y += blk_types.h
|
||||
header-y += blkpg.h
|
||||
header-y += blktrace_api.h
|
||||
header-y += bpqether.h
|
||||
+header-y += bcm963xx_tag.h
|
||||
header-y += bsg.h
|
||||
header-y += can.h
|
||||
header-y += capability.h
|
||||
--- /dev/null
|
||||
+++ b/include/linux/bcm963xx_tag.h
|
||||
@@ -0,0 +1,96 @@
|
||||
+#ifndef __BCM963XX_TAG_H
|
||||
+#define __BCM963XX_TAG_H
|
||||
+
|
||||
+#define TAGVER_LEN 4 /* Length of Tag Version */
|
||||
+#define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */
|
||||
+#define SIG1_LEN 20 /* Company Signature 1 Length */
|
||||
+#define SIG2_LEN 14 /* Company Signature 2 Length */
|
||||
+#define BOARDID_LEN 16 /* Length of BoardId */
|
||||
+#define ENDIANFLAG_LEN 2 /* Endian Flag Length */
|
||||
+#define CHIPID_LEN 6 /* Chip Id Length */
|
||||
+#define IMAGE_LEN 10 /* Length of Length Field */
|
||||
+#define ADDRESS_LEN 12 /* Length of Address field */
|
||||
+#define DUALFLAG_LEN 2 /* Dual Image flag Length */
|
||||
+#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */
|
||||
+#define RSASIG_LEN 20 /* Length of RSA Signature in tag */
|
||||
+#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */
|
||||
+#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */
|
||||
+#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */
|
||||
+#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */
|
||||
+
|
||||
+#define NUM_PIRELLI 2
|
||||
+#define IMAGETAG_CRC_START 0xFFFFFFFF
|
||||
+
|
||||
+#define PIRELLI_BOARDS { \
|
||||
+ "AGPF-S0", \
|
||||
+ "DWV-S0", \
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * The broadcom firmware assumes the rootfs starts the image,
|
||||
+ * therefore uses the rootfs start (flash_image_address)
|
||||
+ * to determine where to flash the image. Since we have the kernel first
|
||||
+ * we have to give it the kernel address, but the crc uses the length
|
||||
+ * associated with this address (root_length), which is added to the kernel
|
||||
+ * length (kernel_length) to determine the length of image to flash and thus
|
||||
+ * needs to be rootfs + deadcode (jffs2 EOF marker)
|
||||
+*/
|
||||
+
|
||||
+struct bcm_tag {
|
||||
+ /* 0-3: Version of the image tag */
|
||||
+ char tag_version[TAGVER_LEN];
|
||||
+ /* 4-23: Company Line 1 */
|
||||
+ char sig_1[SIG1_LEN];
|
||||
+ /* 24-37: Company Line 2 */
|
||||
+ char sig_2[SIG2_LEN];
|
||||
+ /* 38-43: Chip this image is for */
|
||||
+ char chip_id[CHIPID_LEN];
|
||||
+ /* 44-59: Board name */
|
||||
+ char board_id[BOARDID_LEN];
|
||||
+ /* 60-61: Map endianness -- 1 BE 0 LE */
|
||||
+ char big_endian[ENDIANFLAG_LEN];
|
||||
+ /* 62-71: Total length of image */
|
||||
+ char total_length[IMAGE_LEN];
|
||||
+ /* 72-83: Address in memory of CFE */
|
||||
+ char cfe__address[ADDRESS_LEN];
|
||||
+ /* 84-93: Size of CFE */
|
||||
+ char cfe_length[IMAGE_LEN];
|
||||
+ /* 94-105: Address in memory of image start
|
||||
+ * (kernel for OpenWRT, rootfs for stock firmware)
|
||||
+ */
|
||||
+ char flash_image_start[ADDRESS_LEN];
|
||||
+ /* 106-115: Size of rootfs */
|
||||
+ char root_length[IMAGE_LEN];
|
||||
+ /* 116-127: Address in memory of kernel */
|
||||
+ char kernel_address[ADDRESS_LEN];
|
||||
+ /* 128-137: Size of kernel */
|
||||
+ char kernel_length[IMAGE_LEN];
|
||||
+ /* 138-139: Unused at the moment */
|
||||
+ char dual_image[DUALFLAG_LEN];
|
||||
+ /* 140-141: Unused at the moment */
|
||||
+ char inactive_flag[INACTIVEFLAG_LEN];
|
||||
+ /* 142-161: RSA Signature (not used; some vendors may use this) */
|
||||
+ char rsa_signature[RSASIG_LEN];
|
||||
+ /* 162-191: Compilation and related information (not used in OpenWrt) */
|
||||
+ char information1[TAGINFO1_LEN];
|
||||
+ /* 192-195: Version flash layout */
|
||||
+ char flash_layout_ver[FLASHLAYOUTVER_LEN];
|
||||
+ /* 196-199: kernel+rootfs CRC32 */
|
||||
+ __u32 fskernel_crc;
|
||||
+ /* 200-215: Unused except on Alice Gate where is is information */
|
||||
+ char information2[TAGINFO2_LEN];
|
||||
+ /* 216-219: CRC32 of image less imagetag (kernel for Alice Gate) */
|
||||
+ __u32 image_crc;
|
||||
+ /* 220-223: CRC32 of rootfs partition */
|
||||
+ __u32 rootfs_crc;
|
||||
+ /* 224-227: CRC32 of kernel partition */
|
||||
+ __u32 kernel_crc;
|
||||
+ /* 228-235: Unused at present */
|
||||
+ char reserved1[8];
|
||||
+ /* 236-239: CRC32 of header excluding last 20 bytes */
|
||||
+ __u32 header_crc;
|
||||
+ /* 240-255: Unused at present */
|
||||
+ char reserved2[16];
|
||||
+};
|
||||
+
|
||||
+#endif /* __BCM63XX_TAG_H */
|
@ -1,67 +0,0 @@
|
||||
--- a/drivers/base/regmap/Kconfig
|
||||
+++ b/drivers/base/regmap/Kconfig
|
||||
@@ -3,19 +3,21 @@
|
||||
# subsystems should select the appropriate symbols.
|
||||
|
||||
config REGMAP
|
||||
- default y if (REGMAP_I2C || REGMAP_SPI)
|
||||
select LZO_COMPRESS
|
||||
select LZO_DECOMPRESS
|
||||
select IRQ_DOMAIN if REGMAP_IRQ
|
||||
- bool
|
||||
+ tristate
|
||||
|
||||
config REGMAP_I2C
|
||||
+ select REGMAP
|
||||
tristate
|
||||
|
||||
config REGMAP_SPI
|
||||
+ select REGMAP
|
||||
tristate
|
||||
|
||||
config REGMAP_MMIO
|
||||
+ select REGMAP
|
||||
tristate
|
||||
|
||||
config REGMAP_IRQ
|
||||
--- a/include/linux/regmap.h
|
||||
+++ b/include/linux/regmap.h
|
||||
@@ -43,7 +43,7 @@ struct reg_default {
|
||||
unsigned int def;
|
||||
};
|
||||
|
||||
-#ifdef CONFIG_REGMAP
|
||||
+#if IS_ENABLED(CONFIG_REGMAP)
|
||||
|
||||
enum regmap_endian {
|
||||
/* Unspecified -> 0 -> Backwards compatible default */
|
||||
--- a/drivers/base/regmap/Makefile
|
||||
+++ b/drivers/base/regmap/Makefile
|
||||
@@ -1,6 +1,8 @@
|
||||
-obj-$(CONFIG_REGMAP) += regmap.o regcache.o
|
||||
-obj-$(CONFIG_REGMAP) += regcache-rbtree.o regcache-lzo.o
|
||||
-obj-$(CONFIG_DEBUG_FS) += regmap-debugfs.o
|
||||
+regmap-core-objs = regmap.o regcache.o regcache-rbtree.o regcache-lzo.o
|
||||
+ifdef CONFIG_DEBUG_FS
|
||||
+regmap-core-objs += regmap-debugfs.o
|
||||
+endif
|
||||
+obj-$(CONFIG_REGMAP) += regmap-core.o
|
||||
obj-$(CONFIG_REGMAP_I2C) += regmap-i2c.o
|
||||
obj-$(CONFIG_REGMAP_SPI) += regmap-spi.o
|
||||
obj-$(CONFIG_REGMAP_MMIO) += regmap-mmio.o
|
||||
--- a/drivers/base/regmap/regmap.c
|
||||
+++ b/drivers/base/regmap/regmap.c
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/export.h>
|
||||
+#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/rbtree.h>
|
||||
@@ -1418,3 +1419,5 @@ static int __init regmap_initcall(void)
|
||||
return 0;
|
||||
}
|
||||
postcore_initcall(regmap_initcall);
|
||||
+
|
||||
+MODULE_LICENSE("GPL");
|
@ -1,39 +0,0 @@
|
||||
From: Mark Miller <mark@mirell.org>
|
||||
|
||||
This exposes the CONFIG_BOOT_RAW symbol in Kconfig. This is needed on
|
||||
certain Broadcom chipsets running CFE in order to load the kernel.
|
||||
|
||||
Signed-off-by: Mark Miller <mark@mirell.org>
|
||||
Acked-by: Rob Landley <rob@landley.net>
|
||||
---
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -894,9 +894,6 @@ config ARC
|
||||
config ARCH_MAY_HAVE_PC_FDC
|
||||
bool
|
||||
|
||||
-config BOOT_RAW
|
||||
- bool
|
||||
-
|
||||
config CEVT_BCM1480
|
||||
bool
|
||||
|
||||
@@ -2367,6 +2364,18 @@ config USE_OF
|
||||
help
|
||||
Include support for flattened device tree machine descriptions.
|
||||
|
||||
+config BOOT_RAW
|
||||
+ bool "Enable the kernel to be executed from the load address"
|
||||
+ default n
|
||||
+ help
|
||||
+ Allow the kernel to be executed from the load address for
|
||||
+ bootloaders which cannot read the ELF format. This places
|
||||
+ a jump to start_kernel at the load address.
|
||||
+
|
||||
+ If unsure, say N.
|
||||
+
|
||||
+
|
||||
+
|
||||
endmenu
|
||||
|
||||
config LOCKDEP_SUPPORT
|
@ -1,28 +0,0 @@
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -993,6 +993,10 @@ config SYNC_R4K
|
||||
config MIPS_MACHINE
|
||||
def_bool n
|
||||
|
||||
+config IMAGE_CMDLINE_HACK
|
||||
+ bool "OpenWrt specific image command line hack"
|
||||
+ default n
|
||||
+
|
||||
config NO_IOPORT
|
||||
def_bool n
|
||||
|
||||
--- a/arch/mips/kernel/head.S
|
||||
+++ b/arch/mips/kernel/head.S
|
||||
@@ -141,6 +141,12 @@ FEXPORT(__kernel_entry)
|
||||
j kernel_entry
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_IMAGE_CMDLINE_HACK
|
||||
+ .ascii "CMDLINE:"
|
||||
+EXPORT(__image_cmdline)
|
||||
+ .fill 0x400
|
||||
+#endif /* CONFIG_IMAGE_CMDLINE_HACK */
|
||||
+
|
||||
__REF
|
||||
|
||||
NESTED(kernel_entry, 16, sp) # kernel entry point
|
@ -1,11 +0,0 @@
|
||||
--- a/arch/mips/Makefile
|
||||
+++ b/arch/mips/Makefile
|
||||
@@ -87,7 +87,7 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin
|
||||
# machines may also. Since BFD is incredibly buggy with respect to
|
||||
# crossformat linking we rely on the elf2ecoff tool for format conversion.
|
||||
#
|
||||
-cflags-y += -G 0 -mno-abicalls -fno-pic -pipe
|
||||
+cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely
|
||||
cflags-y += -msoft-float
|
||||
LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
|
||||
KBUILD_AFLAGS_MODULE += -mlong-calls
|
@ -1,11 +0,0 @@
|
||||
--- a/arch/mips/kernel/machine_kexec.c
|
||||
+++ b/arch/mips/kernel/machine_kexec.c
|
||||
@@ -52,7 +52,7 @@ machine_kexec(struct kimage *image)
|
||||
reboot_code_buffer =
|
||||
(unsigned long)page_address(image->control_code_page);
|
||||
|
||||
- kexec_start_address = image->start;
|
||||
+ kexec_start_address = (unsigned long) phys_to_virt(image->start);
|
||||
kexec_indirection_page =
|
||||
(unsigned long) phys_to_virt(image->head & PAGE_MASK);
|
||||
|
@ -1,160 +0,0 @@
|
||||
MIPS: allow disabling the kernel FPU emulator
|
||||
|
||||
This patch allows turning off the in-kernel Algorithmics
|
||||
FPU emulator support, which allows one to save a couple of
|
||||
precious blocks on an embedded system.
|
||||
|
||||
Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||||
--
|
||||
--- a/arch/mips/Kconfig
|
||||
+++ b/arch/mips/Kconfig
|
||||
@@ -978,6 +978,17 @@ config I8259
|
||||
config MIPS_BONITO64
|
||||
bool
|
||||
|
||||
+config MIPS_FPU_EMU
|
||||
+ bool "Enable FPU emulation"
|
||||
+ default y
|
||||
+ help
|
||||
+ This option allows building a kernel with or without the Algorithmics
|
||||
+ FPU emulator enabled. Turning off this option results in a kernel which
|
||||
+ does not catch floating operations exceptions. Make sure that your toolchain
|
||||
+ is configured to enable software floating point emulation in that case.
|
||||
+
|
||||
+ If unsure say Y here.
|
||||
+
|
||||
config MIPS_MSC
|
||||
bool
|
||||
|
||||
--- a/arch/mips/math-emu/Makefile
|
||||
+++ b/arch/mips/math-emu/Makefile
|
||||
@@ -2,11 +2,13 @@
|
||||
# Makefile for the Linux/MIPS kernel FPU emulation.
|
||||
#
|
||||
|
||||
-obj-y := cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
|
||||
+obj-y := kernel_linkage.o dsemul.o cp1emu.o
|
||||
+
|
||||
+obj-$(CONFIG_MIPS_FPU_EMU) += ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
|
||||
ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \
|
||||
dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \
|
||||
dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \
|
||||
sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \
|
||||
sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \
|
||||
- dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o
|
||||
+ dp_sqrt.o sp_sqrt.o
|
||||
|
||||
--- a/arch/mips/math-emu/cp1emu.c
|
||||
+++ b/arch/mips/math-emu/cp1emu.c
|
||||
@@ -58,7 +58,11 @@
|
||||
#define __mips 4
|
||||
|
||||
/* Function which emulates a floating point instruction. */
|
||||
+#ifdef CONFIG_DEBUG_FS
|
||||
+DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
|
||||
+#endif
|
||||
|
||||
+#ifdef CONFIG_MIPS_FPU_EMU
|
||||
static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
|
||||
mips_instruction);
|
||||
|
||||
@@ -69,10 +73,6 @@ static int fpux_emu(struct pt_regs *,
|
||||
|
||||
/* Further private data for which no space exists in mips_fpu_struct */
|
||||
|
||||
-#ifdef CONFIG_DEBUG_FS
|
||||
-DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
|
||||
-#endif
|
||||
-
|
||||
/* Control registers */
|
||||
|
||||
#define FPCREG_RID 0 /* $0 = revision id */
|
||||
@@ -1360,7 +1360,6 @@ int fpu_emulator_cop1Handler(struct pt_r
|
||||
|
||||
return sig;
|
||||
}
|
||||
-
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
static int fpuemu_stat_get(void *data, u64 *val)
|
||||
@@ -1409,4 +1408,11 @@ static int __init debugfs_fpuemu(void)
|
||||
return 0;
|
||||
}
|
||||
__initcall(debugfs_fpuemu);
|
||||
-#endif
|
||||
+#endif /* CONFIG_DEBUGFS */
|
||||
+#else
|
||||
+int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
|
||||
+ int has_fpu)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif /* CONFIG_MIPS_FPU_EMU */
|
||||
--- a/arch/mips/math-emu/dsemul.c
|
||||
+++ b/arch/mips/math-emu/dsemul.c
|
||||
@@ -108,6 +108,7 @@ int mips_dsemul(struct pt_regs *regs, mi
|
||||
return SIGILL; /* force out of emulation loop */
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_MIPS_FPU_EMU
|
||||
int do_dsemulret(struct pt_regs *xcp)
|
||||
{
|
||||
struct emuframe __user *fr;
|
||||
@@ -164,3 +165,9 @@ int do_dsemulret(struct pt_regs *xcp)
|
||||
|
||||
return 1;
|
||||
}
|
||||
+#else
|
||||
+int do_dsemulret(struct pt_regs *xcp)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif /* CONFIG_MIPS_FPU_EMU */
|
||||
--- a/arch/mips/math-emu/kernel_linkage.c
|
||||
+++ b/arch/mips/math-emu/kernel_linkage.c
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#define SIGNALLING_NAN 0x7ff800007ff80000LL
|
||||
|
||||
+#ifdef CONFIG_MIPS_FPU_EMU
|
||||
void fpu_emulator_init_fpu(void)
|
||||
{
|
||||
static int first = 1;
|
||||
@@ -112,4 +113,36 @@ int fpu_emulator_restore_context32(struc
|
||||
|
||||
return err;
|
||||
}
|
||||
-#endif
|
||||
+#endif /* CONFIG_64BIT */
|
||||
+#else
|
||||
+
|
||||
+void fpu_emulator_init_fpu(void)
|
||||
+{
|
||||
+ printk(KERN_INFO "FPU emulator disabled, make sure your toolchain"
|
||||
+ "was compiled with software floating point support (soft-float)\n");
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+int fpu_emulator_save_context(struct sigcontext __user *sc)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int fpu_emulator_restore_context(struct sigcontext __user *sc)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int fpu_emulator_save_context32(struct sigcontext32 __user *sc)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int fpu_emulator_restore_context32(struct sigcontext32 __user *sc)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#ifdef CONFIG_64BIT
|
||||
+#endif /* CONFIG_64BIT */
|
||||
+#endif /* CONFIG_MIPS_FPU_EMU */
|
@ -1,371 +0,0 @@
|
||||
--- a/arch/mips/Makefile
|
||||
+++ b/arch/mips/Makefile
|
||||
@@ -90,8 +90,8 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin
|
||||
cflags-y += -G 0 -mno-abicalls -fno-pic -pipe -mno-branch-likely
|
||||
cflags-y += -msoft-float
|
||||
LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
|
||||
-KBUILD_AFLAGS_MODULE += -mlong-calls
|
||||
-KBUILD_CFLAGS_MODULE += -mlong-calls
|
||||
+KBUILD_AFLAGS_MODULE += -mno-long-calls
|
||||
+KBUILD_CFLAGS_MODULE += -mno-long-calls
|
||||
|
||||
cflags-y += -ffreestanding
|
||||
|
||||
--- a/arch/mips/include/asm/module.h
|
||||
+++ b/arch/mips/include/asm/module.h
|
||||
@@ -11,6 +11,11 @@ struct mod_arch_specific {
|
||||
const struct exception_table_entry *dbe_start;
|
||||
const struct exception_table_entry *dbe_end;
|
||||
struct mips_hi16 *r_mips_hi16_list;
|
||||
+
|
||||
+ void *phys_plt_tbl;
|
||||
+ void *virt_plt_tbl;
|
||||
+ unsigned int phys_plt_offset;
|
||||
+ unsigned int virt_plt_offset;
|
||||
};
|
||||
|
||||
typedef uint8_t Elf64_Byte; /* Type for a 8-bit quantity. */
|
||||
--- a/arch/mips/kernel/module.c
|
||||
+++ b/arch/mips/kernel/module.c
|
||||
@@ -42,14 +42,219 @@ struct mips_hi16 {
|
||||
static LIST_HEAD(dbe_list);
|
||||
static DEFINE_SPINLOCK(dbe_lock);
|
||||
|
||||
-#ifdef MODULE_START
|
||||
+/*
|
||||
+ * Get the potential max trampolines size required of the init and
|
||||
+ * non-init sections. Only used if we cannot find enough contiguous
|
||||
+ * physically mapped memory to put the module into.
|
||||
+ */
|
||||
+static unsigned int
|
||||
+get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
|
||||
+ const char *secstrings, unsigned int symindex, bool is_init)
|
||||
+{
|
||||
+ unsigned long ret = 0;
|
||||
+ unsigned int i, j;
|
||||
+ Elf_Sym *syms;
|
||||
+
|
||||
+ /* Everything marked ALLOC (this includes the exported symbols) */
|
||||
+ for (i = 1; i < hdr->e_shnum; ++i) {
|
||||
+ unsigned int info = sechdrs[i].sh_info;
|
||||
+
|
||||
+ if (sechdrs[i].sh_type != SHT_REL
|
||||
+ && sechdrs[i].sh_type != SHT_RELA)
|
||||
+ continue;
|
||||
+
|
||||
+ /* Not a valid relocation section? */
|
||||
+ if (info >= hdr->e_shnum)
|
||||
+ continue;
|
||||
+
|
||||
+ /* Don't bother with non-allocated sections */
|
||||
+ if (!(sechdrs[info].sh_flags & SHF_ALLOC))
|
||||
+ continue;
|
||||
+
|
||||
+ /* If it's called *.init*, and we're not init, we're
|
||||
+ not interested */
|
||||
+ if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0)
|
||||
+ != is_init)
|
||||
+ continue;
|
||||
+
|
||||
+ syms = (Elf_Sym *) sechdrs[symindex].sh_addr;
|
||||
+ if (sechdrs[i].sh_type == SHT_REL) {
|
||||
+ Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr;
|
||||
+ unsigned int size = sechdrs[i].sh_size / sizeof(*rel);
|
||||
+
|
||||
+ for (j = 0; j < size; ++j) {
|
||||
+ Elf_Sym *sym;
|
||||
+
|
||||
+ if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26)
|
||||
+ continue;
|
||||
+
|
||||
+ sym = syms + ELF_MIPS_R_SYM(rel[j]);
|
||||
+ if (!is_init && sym->st_shndx != SHN_UNDEF)
|
||||
+ continue;
|
||||
+
|
||||
+ ret += 4 * sizeof(int);
|
||||
+ }
|
||||
+ } else {
|
||||
+ Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr;
|
||||
+ unsigned int size = sechdrs[i].sh_size / sizeof(*rela);
|
||||
+
|
||||
+ for (j = 0; j < size; ++j) {
|
||||
+ Elf_Sym *sym;
|
||||
+
|
||||
+ if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26)
|
||||
+ continue;
|
||||
+
|
||||
+ sym = syms + ELF_MIPS_R_SYM(rela[j]);
|
||||
+ if (!is_init && sym->st_shndx != SHN_UNDEF)
|
||||
+ continue;
|
||||
+
|
||||
+ ret += 4 * sizeof(int);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+#ifndef MODULE_START
|
||||
+static void *alloc_phys(unsigned long size)
|
||||
+{
|
||||
+ unsigned order;
|
||||
+ struct page *page;
|
||||
+ struct page *p;
|
||||
+
|
||||
+ size = PAGE_ALIGN(size);
|
||||
+ order = get_order(size);
|
||||
+
|
||||
+ page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN |
|
||||
+ __GFP_THISNODE, order);
|
||||
+ if (!page)
|
||||
+ return NULL;
|
||||
+
|
||||
+ split_page(page, order);
|
||||
+
|
||||
+ for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p)
|
||||
+ __free_page(p);
|
||||
+
|
||||
+ return page_address(page);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+static void free_phys(void *ptr, unsigned long size)
|
||||
+{
|
||||
+ struct page *page;
|
||||
+ struct page *end;
|
||||
+
|
||||
+ page = virt_to_page(ptr);
|
||||
+ end = page + (PAGE_ALIGN(size) >> PAGE_SHIFT);
|
||||
+
|
||||
+ for (; page < end; ++page)
|
||||
+ __free_page(page);
|
||||
+}
|
||||
+
|
||||
+
|
||||
void *module_alloc(unsigned long size)
|
||||
{
|
||||
+#ifdef MODULE_START
|
||||
return __vmalloc_node_range(size, 1, MODULE_START, MODULE_END,
|
||||
GFP_KERNEL, PAGE_KERNEL, -1,
|
||||
__builtin_return_address(0));
|
||||
+#else
|
||||
+ void *ptr;
|
||||
+
|
||||
+ if (size == 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ ptr = alloc_phys(size);
|
||||
+
|
||||
+ /* If we failed to allocate physically contiguous memory,
|
||||
+ * fall back to regular vmalloc. The module loader code will
|
||||
+ * create jump tables to handle long jumps */
|
||||
+ if (!ptr)
|
||||
+ return vmalloc(size);
|
||||
+
|
||||
+ return ptr;
|
||||
+#endif
|
||||
}
|
||||
+
|
||||
+static inline bool is_phys_addr(void *ptr)
|
||||
+{
|
||||
+#ifdef CONFIG_64BIT
|
||||
+ return (KSEGX((unsigned long)ptr) == CKSEG0);
|
||||
+#else
|
||||
+ return (KSEGX(ptr) == KSEG0);
|
||||
#endif
|
||||
+}
|
||||
+
|
||||
+/* Free memory returned from module_alloc */
|
||||
+void module_free(struct module *mod, void *module_region)
|
||||
+{
|
||||
+ if (is_phys_addr(module_region)) {
|
||||
+ if (mod->module_init == module_region)
|
||||
+ free_phys(module_region, mod->init_size);
|
||||
+ else if (mod->module_core == module_region)
|
||||
+ free_phys(module_region, mod->core_size);
|
||||
+ else
|
||||
+ BUG();
|
||||
+ } else {
|
||||
+ vfree(module_region);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void *__module_alloc(int size, bool phys)
|
||||
+{
|
||||
+ void *ptr;
|
||||
+
|
||||
+ if (phys)
|
||||
+ ptr = kmalloc(size, GFP_KERNEL);
|
||||
+ else
|
||||
+ ptr = vmalloc(size);
|
||||
+ return ptr;
|
||||
+}
|
||||
+
|
||||
+static void __module_free(void *ptr)
|
||||
+{
|
||||
+ if (is_phys_addr(ptr))
|
||||
+ kfree(ptr);
|
||||
+ else
|
||||
+ vfree(ptr);
|
||||
+}
|
||||
+
|
||||
+int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
|
||||
+ char *secstrings, struct module *mod)
|
||||
+{
|
||||
+ unsigned int symindex = 0;
|
||||
+ unsigned int core_size, init_size;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 1; i < hdr->e_shnum; i++)
|
||||
+ if (sechdrs[i].sh_type == SHT_SYMTAB)
|
||||
+ symindex = i;
|
||||
+
|
||||
+ core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false);
|
||||
+ init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true);
|
||||
+
|
||||
+ mod->arch.phys_plt_offset = 0;
|
||||
+ mod->arch.virt_plt_offset = 0;
|
||||
+ mod->arch.phys_plt_tbl = NULL;
|
||||
+ mod->arch.virt_plt_tbl = NULL;
|
||||
+
|
||||
+ if ((core_size + init_size) == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1);
|
||||
+ if (!mod->arch.phys_plt_tbl)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0);
|
||||
+ if (!mod->arch.virt_plt_tbl) {
|
||||
+ __module_free(mod->arch.phys_plt_tbl);
|
||||
+ mod->arch.phys_plt_tbl = NULL;
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
static int apply_r_mips_none(struct module *me, u32 *location, Elf_Addr v)
|
||||
{
|
||||
@@ -70,28 +275,36 @@ static int apply_r_mips_32_rela(struct m
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
|
||||
+static Elf_Addr add_plt_entry_to(unsigned *plt_offset,
|
||||
+ void *start, Elf_Addr v)
|
||||
{
|
||||
- if (v % 4) {
|
||||
- pr_err("module %s: dangerous R_MIPS_26 REL relocation\n",
|
||||
- me->name);
|
||||
- return -ENOEXEC;
|
||||
- }
|
||||
+ unsigned *tramp = start + *plt_offset;
|
||||
+ *plt_offset += 4 * sizeof(int);
|
||||
|
||||
- if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
|
||||
- printk(KERN_ERR
|
||||
- "module %s: relocation overflow\n",
|
||||
- me->name);
|
||||
- return -ENOEXEC;
|
||||
- }
|
||||
+ /* adjust carry for addiu */
|
||||
+ if (v & 0x00008000)
|
||||
+ v += 0x10000;
|
||||
|
||||
- *location = (*location & ~0x03ffffff) |
|
||||
- ((*location + (v >> 2)) & 0x03ffffff);
|
||||
+ tramp[0] = 0x3c190000 | (v >> 16); /* lui t9, hi16 */
|
||||
+ tramp[1] = 0x27390000 | (v & 0xffff); /* addiu t9, t9, lo16 */
|
||||
+ tramp[2] = 0x03200008; /* jr t9 */
|
||||
+ tramp[3] = 0x00000000; /* nop */
|
||||
|
||||
- return 0;
|
||||
+ return (Elf_Addr) tramp;
|
||||
}
|
||||
|
||||
-static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
|
||||
+static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v)
|
||||
+{
|
||||
+ if (is_phys_addr(location))
|
||||
+ return add_plt_entry_to(&me->arch.phys_plt_offset,
|
||||
+ me->arch.phys_plt_tbl, v);
|
||||
+ else
|
||||
+ return add_plt_entry_to(&me->arch.virt_plt_offset,
|
||||
+ me->arch.virt_plt_tbl, v);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static int set_r_mips_26(struct module *me, u32 *location, u32 ofs, Elf_Addr v)
|
||||
{
|
||||
if (v % 4) {
|
||||
pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n",
|
||||
@@ -100,17 +313,31 @@ static int apply_r_mips_26_rela(struct m
|
||||
}
|
||||
|
||||
if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
|
||||
- printk(KERN_ERR
|
||||
+ v = add_plt_entry(me, location, v + (ofs << 2));
|
||||
+ if (!v) {
|
||||
+ printk(KERN_ERR
|
||||
"module %s: relocation overflow\n",
|
||||
me->name);
|
||||
- return -ENOEXEC;
|
||||
+ return -ENOEXEC;
|
||||
+ }
|
||||
+ ofs = 0;
|
||||
}
|
||||
|
||||
- *location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
|
||||
+ *location = (*location & ~0x03ffffff) | ((ofs + (v >> 2)) & 0x03ffffff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
|
||||
+{
|
||||
+ return set_r_mips_26(me, location, *location & 0x03ffffff, v);
|
||||
+}
|
||||
+
|
||||
+static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
|
||||
+{
|
||||
+ return set_r_mips_26(me, location, 0, v);
|
||||
+}
|
||||
+
|
||||
static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
|
||||
{
|
||||
struct mips_hi16 *n;
|
||||
@@ -405,11 +632,32 @@ int module_finalize(const Elf_Ehdr *hdr,
|
||||
list_add(&me->arch.dbe_list, &dbe_list);
|
||||
spin_unlock_irq(&dbe_lock);
|
||||
}
|
||||
+
|
||||
+ /* Get rid of the fixup trampoline if we're running the module
|
||||
+ * from physically mapped address space */
|
||||
+ if (me->arch.phys_plt_offset == 0) {
|
||||
+ __module_free(me->arch.phys_plt_tbl);
|
||||
+ me->arch.phys_plt_tbl = NULL;
|
||||
+ }
|
||||
+ if (me->arch.virt_plt_offset == 0) {
|
||||
+ __module_free(me->arch.virt_plt_tbl);
|
||||
+ me->arch.virt_plt_tbl = NULL;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
void module_arch_cleanup(struct module *mod)
|
||||
{
|
||||
+ if (mod->arch.phys_plt_tbl) {
|
||||
+ __module_free(mod->arch.phys_plt_tbl);
|
||||
+ mod->arch.phys_plt_tbl = NULL;
|
||||
+ }
|
||||
+ if (mod->arch.virt_plt_tbl) {
|
||||
+ __module_free(mod->arch.virt_plt_tbl);
|
||||
+ mod->arch.virt_plt_tbl = NULL;
|
||||
+ }
|
||||
+
|
||||
spin_lock_irq(&dbe_lock);
|
||||
list_del(&mod->arch.dbe_list);
|
||||
spin_unlock_irq(&dbe_lock);
|
@ -1,83 +0,0 @@
|
||||
--- a/arch/mips/include/asm/string.h
|
||||
+++ b/arch/mips/include/asm/string.h
|
||||
@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__
|
||||
|
||||
#define __HAVE_ARCH_MEMSET
|
||||
extern void *memset(void *__s, int __c, size_t __count);
|
||||
+#define memset(__s, __c, len) \
|
||||
+({ \
|
||||
+ size_t __len = (len); \
|
||||
+ void *__ret; \
|
||||
+ if (__builtin_constant_p(len) && __len >= 64) \
|
||||
+ __ret = memset((__s), (__c), __len); \
|
||||
+ else \
|
||||
+ __ret = __builtin_memset((__s), (__c), __len); \
|
||||
+ __ret; \
|
||||
+})
|
||||
|
||||
#define __HAVE_ARCH_MEMCPY
|
||||
extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
|
||||
+#define memcpy(dst, src, len) \
|
||||
+({ \
|
||||
+ size_t __len = (len); \
|
||||
+ void *__ret; \
|
||||
+ if (__builtin_constant_p(len) && __len >= 64) \
|
||||
+ __ret = memcpy((dst), (src), __len); \
|
||||
+ else \
|
||||
+ __ret = __builtin_memcpy((dst), (src), __len); \
|
||||
+ __ret; \
|
||||
+})
|
||||
|
||||
#define __HAVE_ARCH_MEMMOVE
|
||||
extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
|
||||
+#define memmove(dst, src, len) \
|
||||
+({ \
|
||||
+ size_t __len = (len); \
|
||||
+ void *__ret; \
|
||||
+ if (__builtin_constant_p(len) && __len >= 64) \
|
||||
+ __ret = memmove((dst), (src), __len); \
|
||||
+ else \
|
||||
+ __ret = __builtin_memmove((dst), (src), __len); \
|
||||
+ __ret; \
|
||||
+})
|
||||
+
|
||||
+#define __HAVE_ARCH_MEMCMP
|
||||
+#define memcmp(src1, src2, len) __builtin_memcmp((src1), (src2), (len))
|
||||
|
||||
#endif /* _ASM_STRING_H */
|
||||
--- a/arch/mips/lib/Makefile
|
||||
+++ b/arch/mips/lib/Makefile
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
lib-y += csum_partial.o delay.o memcpy.o memset.o \
|
||||
- strlen_user.o strncpy_user.o strnlen_user.o uncached.o
|
||||
+ strlen_user.o strncpy_user.o strnlen_user.o uncached.o memcmp.o
|
||||
|
||||
obj-y += iomap.o
|
||||
obj-$(CONFIG_PCI) += iomap-pci.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/lib/memcmp.c
|
||||
@@ -0,0 +1,22 @@
|
||||
+/*
|
||||
+ * copied from linux/lib/string.c
|
||||
+ *
|
||||
+ * Copyright (C) 1991, 1992 Linus Torvalds
|
||||
+ */
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/string.h>
|
||||
+
|
||||
+#undef memcmp
|
||||
+int memcmp(const void *cs, const void *ct, size_t count)
|
||||
+{
|
||||
+ const unsigned char *su1, *su2;
|
||||
+ int res = 0;
|
||||
+
|
||||
+ for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
|
||||
+ if ((res = *su1 - *su2) != 0)
|
||||
+ break;
|
||||
+ return res;
|
||||
+}
|
||||
+EXPORT_SYMBOL(memcmp);
|
||||
+
|
@ -1,17 +0,0 @@
|
||||
--- a/arch/mips/kernel/cpu-probe.c
|
||||
+++ b/arch/mips/kernel/cpu-probe.c
|
||||
@@ -833,10 +833,13 @@ static inline void cpu_probe_mips(struct
|
||||
__cpu_name[cpu] = "MIPS 20Kc";
|
||||
break;
|
||||
case PRID_IMP_24K:
|
||||
- case PRID_IMP_24KE:
|
||||
c->cputype = CPU_24K;
|
||||
__cpu_name[cpu] = "MIPS 24Kc";
|
||||
break;
|
||||
+ case PRID_IMP_24KE:
|
||||
+ c->cputype = CPU_24K;
|
||||
+ __cpu_name[cpu] = "MIPS 24KEc";
|
||||
+ break;
|
||||
case PRID_IMP_25KF:
|
||||
c->cputype = CPU_25KF;
|
||||
__cpu_name[cpu] = "MIPS 25Kc";
|
@ -1,32 +0,0 @@
|
||||
--- a/arch/mips/mm/cache.c
|
||||
+++ b/arch/mips/mm/cache.c
|
||||
@@ -39,6 +39,7 @@ void (*__flush_kernel_vmap_range)(unsign
|
||||
void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size);
|
||||
|
||||
EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range);
|
||||
+EXPORT_SYMBOL(__flush_cache_all);
|
||||
|
||||
/* MIPS specific cache operations */
|
||||
void (*flush_cache_sigtramp)(unsigned long addr);
|
||||
--- a/fs/fuse/dev.c
|
||||
+++ b/fs/fuse/dev.c
|
||||
@@ -19,6 +19,9 @@
|
||||
#include <linux/pipe_fs_i.h>
|
||||
#include <linux/swap.h>
|
||||
#include <linux/splice.h>
|
||||
+#ifdef CONFIG_MIPS
|
||||
+#include <asm/cacheflush.h>
|
||||
+#endif
|
||||
|
||||
MODULE_ALIAS_MISCDEV(FUSE_MINOR);
|
||||
MODULE_ALIAS("devname:fuse");
|
||||
@@ -655,6 +658,9 @@ static int fuse_copy_fill(struct fuse_co
|
||||
static int fuse_copy_do(struct fuse_copy_state *cs, void **val, unsigned *size)
|
||||
{
|
||||
unsigned ncpy = min(*size, cs->len);
|
||||
+#ifdef CONFIG_MIPS
|
||||
+ __flush_cache_all();
|
||||
+#endif
|
||||
if (val) {
|
||||
if (cs->write)
|
||||
memcpy(cs->buf, *val, ncpy);
|
@ -1,13 +0,0 @@
|
||||
--- a/arch/arm/kernel/module.c
|
||||
+++ b/arch/arm/kernel/module.c
|
||||
@@ -81,6 +81,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
+ if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) &&
|
||||
+ ELF_ST_BIND(sym->st_info) == STB_WEAK)
|
||||
+ continue;
|
||||
+
|
||||
loc = dstsec->sh_addr + rel->r_offset;
|
||||
|
||||
switch (ELF32_R_TYPE(rel->r_info)) {
|
@ -1,31 +0,0 @@
|
||||
Upstream doesn't optimize the kernel and bootwrappers for ppc44x because
|
||||
they still want to support gcc 3.3 -- well, we don't.
|
||||
|
||||
--- a/arch/powerpc/Makefile
|
||||
+++ b/arch/powerpc/Makefile
|
||||
@@ -119,7 +119,8 @@ ifeq ($(CONFIG_FUNCTION_TRACER),y)
|
||||
KBUILD_CFLAGS += -mno-sched-epilog
|
||||
endif
|
||||
|
||||
-cpu-as-$(CONFIG_4xx) += -Wa,-m405
|
||||
+cpu-as-$(CONFIG_40x) += -Wa,-m405
|
||||
+cpu-as-$(CONFIG_44x) += -Wa,-m440
|
||||
cpu-as-$(CONFIG_ALTIVEC) += -Wa,-maltivec
|
||||
cpu-as-$(CONFIG_E500) += -Wa,-me500
|
||||
cpu-as-$(CONFIG_E200) += -Wa,-me200
|
||||
--- a/arch/powerpc/boot/Makefile
|
||||
+++ b/arch/powerpc/boot/Makefile
|
||||
@@ -38,10 +38,10 @@ BOOTCFLAGS += -I$(obj) -I$(srctree)/$(ob
|
||||
DTC_FLAGS ?= -p 1024
|
||||
|
||||
$(obj)/4xx.o: BOOTCFLAGS += -mcpu=405
|
||||
-$(obj)/ebony.o: BOOTCFLAGS += -mcpu=405
|
||||
+$(obj)/ebony.o: BOOTCFLAGS += -mcpu=440
|
||||
$(obj)/cuboot-hotfoot.o: BOOTCFLAGS += -mcpu=405
|
||||
-$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405
|
||||
-$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405
|
||||
+$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=440
|
||||
+$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=440
|
||||
$(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405
|
||||
$(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
|
||||
$(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405
|
@ -1,10 +0,0 @@
|
||||
--- a/arch/powerpc/Makefile
|
||||
+++ b/arch/powerpc/Makefile
|
||||
@@ -86,7 +86,6 @@ CPP = $(CC) -E $(KBUILD_CFLAGS)
|
||||
|
||||
CHECKFLAGS += -m$(CONFIG_WORD_SIZE) -D__powerpc__ -D__powerpc$(CONFIG_WORD_SIZE)__
|
||||
|
||||
-KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
|
||||
|
||||
# No AltiVec or VSX instructions when building kernel
|
||||
KBUILD_CFLAGS += $(call cc-option,-mno-altivec)
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/crypto/amcc/crypto4xx_core.c
|
||||
+++ b/drivers/crypto/amcc/crypto4xx_core.c
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
+#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/spinlock_types.h>
|
||||
#include <linux/random.h>
|
@ -1,616 +0,0 @@
|
||||
From eee16330c9de9adf7880cce9f1d32e13f89706bb Mon Sep 17 00:00:00 2001
|
||||
From: Wu Zhangjin <wuzhangjin@gmail.com>
|
||||
Date: Tue, 11 Jan 2011 13:16:47 +0000
|
||||
Subject: MIPS: Add crash and kdump support
|
||||
|
||||
From: http://patchwork.linux-mips.org/patch/1025/
|
||||
|
||||
Hello folks,
|
||||
|
||||
Please find here MIPS crash and kdump patches.
|
||||
This is patch set of 3 patches:
|
||||
1. generic MIPS changes (kernel);
|
||||
2. MIPS Cavium Octeon board kexec/kdump code (kernel);
|
||||
3. Kexec user space MIPS changes.
|
||||
|
||||
Patches were tested on the latest linux-mips@ git kernel and the latest
|
||||
kexec-tools git on Cavium Octeon 50xx board.
|
||||
|
||||
I also made the same code working on RMI XLR/XLS boards for both
|
||||
mips32 and mips64 kernels.
|
||||
|
||||
Best regards,
|
||||
Maxim Uvarov.
|
||||
|
||||
------
|
||||
[ Zhangjin: Several trivial building failure has been fixed.
|
||||
|
||||
Note: the 2nd patch can not be cleanly applied, but may be a good
|
||||
reference for the other board development:
|
||||
|
||||
+ MIPS Cavium Octeon board kexec,kdump support
|
||||
http://patchwork.linux-mips.org/patch/1026/
|
||||
|
||||
And the 3rd patch has already been merged into the mainline kexec-tools:
|
||||
|
||||
+ some kexec MIPS improvements
|
||||
http://patchwork.linux-mips.org/patch/1027/
|
||||
|
||||
kexec-tools is available here:
|
||||
|
||||
+ http://horms.net/projects/kexec/
|
||||
git://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git
|
||||
]
|
||||
Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
|
||||
---
|
||||
(limited to 'arch/mips/kernel')
|
||||
|
||||
--- a/arch/mips/kernel/Makefile
|
||||
+++ b/arch/mips/kernel/Makefile
|
||||
@@ -97,7 +97,8 @@ obj-$(CONFIG_I8253) += i8253.o
|
||||
|
||||
obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o
|
||||
|
||||
-obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
|
||||
+obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o
|
||||
+obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
obj-$(CONFIG_SPINLOCK_TEST) += spinlock_test.o
|
||||
obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/kernel/crash.c
|
||||
@@ -0,0 +1,75 @@
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/smp.h>
|
||||
+#include <linux/reboot.h>
|
||||
+#include <linux/kexec.h>
|
||||
+#include <linux/bootmem.h>
|
||||
+#include <linux/crash_dump.h>
|
||||
+#include <linux/delay.h>
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/irq.h>
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/sched.h>
|
||||
+
|
||||
+#ifdef CONFIG_CRASH_DUMP
|
||||
+unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
|
||||
+#endif
|
||||
+
|
||||
+/* This keeps a track of which one is crashing cpu. */
|
||||
+int crashing_cpu = -1;
|
||||
+static cpumask_t cpus_in_crash = CPU_MASK_NONE;
|
||||
+
|
||||
+#ifdef CONFIG_SMP
|
||||
+void crash_shutdown_secondary(void *ignore)
|
||||
+{
|
||||
+ struct pt_regs *regs;
|
||||
+ int cpu = smp_processor_id();
|
||||
+
|
||||
+ regs = task_pt_regs(current);
|
||||
+
|
||||
+ if (!cpu_online(cpu))
|
||||
+ return;
|
||||
+
|
||||
+ local_irq_disable();
|
||||
+ if (!cpu_isset(cpu, cpus_in_crash))
|
||||
+ crash_save_cpu(regs, cpu);
|
||||
+ cpu_set(cpu, cpus_in_crash);
|
||||
+
|
||||
+ while (!atomic_read(&kexec_ready_to_reboot))
|
||||
+ cpu_relax();
|
||||
+ relocated_kexec_smp_wait(NULL);
|
||||
+ /* NOTREACHED */
|
||||
+}
|
||||
+
|
||||
+static void crash_kexec_prepare_cpus(void)
|
||||
+{
|
||||
+ unsigned int msecs;
|
||||
+
|
||||
+ unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */
|
||||
+
|
||||
+ dump_send_ipi(crash_shutdown_secondary);
|
||||
+ smp_wmb();
|
||||
+
|
||||
+ /*
|
||||
+ * The crash CPU sends an IPI and wait for other CPUs to
|
||||
+ * respond. Delay of at least 10 seconds.
|
||||
+ */
|
||||
+ printk(KERN_EMERG "Sending IPI to other cpus...\n");
|
||||
+ msecs = 10000;
|
||||
+ while ((cpus_weight(cpus_in_crash) < ncpus) && (--msecs > 0)) {
|
||||
+ cpu_relax();
|
||||
+ mdelay(1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+#else
|
||||
+static void crash_kexec_prepare_cpus(void) {}
|
||||
+#endif
|
||||
+
|
||||
+void default_machine_crash_shutdown(struct pt_regs *regs)
|
||||
+{
|
||||
+ local_irq_disable();
|
||||
+ crashing_cpu = smp_processor_id();
|
||||
+ crash_save_cpu(regs, crashing_cpu);
|
||||
+ crash_kexec_prepare_cpus();
|
||||
+ cpu_set(crashing_cpu, cpus_in_crash);
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/kernel/crash_dump.c
|
||||
@@ -0,0 +1,86 @@
|
||||
+#include <linux/highmem.h>
|
||||
+#include <linux/bootmem.h>
|
||||
+#include <linux/crash_dump.h>
|
||||
+#include <asm/uaccess.h>
|
||||
+
|
||||
+#ifdef CONFIG_PROC_VMCORE
|
||||
+static int __init parse_elfcorehdr(char *p)
|
||||
+{
|
||||
+ if (p)
|
||||
+ elfcorehdr_addr = memparse(p, &p);
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("elfcorehdr=", parse_elfcorehdr);
|
||||
+#endif
|
||||
+
|
||||
+static int __init parse_savemaxmem(char *p)
|
||||
+{
|
||||
+ if (p)
|
||||
+ saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+__setup("savemaxmem=", parse_savemaxmem);
|
||||
+
|
||||
+
|
||||
+static void *kdump_buf_page;
|
||||
+
|
||||
+/**
|
||||
+ * copy_oldmem_page - copy one page from "oldmem"
|
||||
+ * @pfn: page frame number to be copied
|
||||
+ * @buf: target memory address for the copy; this can be in kernel address
|
||||
+ * space or user address space (see @userbuf)
|
||||
+ * @csize: number of bytes to copy
|
||||
+ * @offset: offset in bytes into the page (based on pfn) to begin the copy
|
||||
+ * @userbuf: if set, @buf is in user address space, use copy_to_user(),
|
||||
+ * otherwise @buf is in kernel address space, use memcpy().
|
||||
+ *
|
||||
+ * Copy a page from "oldmem". For this page, there is no pte mapped
|
||||
+ * in the current kernel.
|
||||
+ *
|
||||
+ * Calling copy_to_user() in atomic context is not desirable. Hence first
|
||||
+ * copying the data to a pre-allocated kernel page and then copying to user
|
||||
+ * space in non-atomic context.
|
||||
+ */
|
||||
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
|
||||
+ size_t csize, unsigned long offset, int userbuf)
|
||||
+{
|
||||
+ void *vaddr;
|
||||
+
|
||||
+ if (!csize)
|
||||
+ return 0;
|
||||
+
|
||||
+ vaddr = kmap_atomic_pfn(pfn, KM_PTE0);
|
||||
+
|
||||
+ if (!userbuf) {
|
||||
+ memcpy(buf, (vaddr + offset), csize);
|
||||
+ kunmap_atomic(vaddr, KM_PTE0);
|
||||
+ } else {
|
||||
+ if (!kdump_buf_page) {
|
||||
+ printk(KERN_WARNING "Kdump: Kdump buffer page not"
|
||||
+ " allocated\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ copy_page(kdump_buf_page, vaddr);
|
||||
+ kunmap_atomic(vaddr, KM_PTE0);
|
||||
+ if (copy_to_user(buf, (kdump_buf_page + offset), csize))
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+
|
||||
+ return csize;
|
||||
+}
|
||||
+
|
||||
+static int __init kdump_buf_page_init(void)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
+ if (!kdump_buf_page) {
|
||||
+ printk(KERN_WARNING "Kdump: Failed to allocate kdump buffer"
|
||||
+ " page\n");
|
||||
+ ret = -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+arch_initcall(kdump_buf_page_init);
|
||||
--- a/arch/mips/kernel/machine_kexec.c
|
||||
+++ b/arch/mips/kernel/machine_kexec.c
|
||||
@@ -19,9 +19,19 @@ extern const size_t relocate_new_kernel_
|
||||
extern unsigned long kexec_start_address;
|
||||
extern unsigned long kexec_indirection_page;
|
||||
|
||||
+int (*_machine_kexec_prepare)(struct kimage *) = NULL;
|
||||
+void (*_machine_kexec_shutdown)(void) = NULL;
|
||||
+void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL;
|
||||
+#ifdef CONFIG_SMP
|
||||
+void (*relocated_kexec_smp_wait) (void *);
|
||||
+atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
|
||||
+#endif
|
||||
+
|
||||
int
|
||||
machine_kexec_prepare(struct kimage *kimage)
|
||||
{
|
||||
+ if (_machine_kexec_prepare)
|
||||
+ return _machine_kexec_prepare(kimage);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -33,11 +43,17 @@ machine_kexec_cleanup(struct kimage *kim
|
||||
void
|
||||
machine_shutdown(void)
|
||||
{
|
||||
+ if (_machine_kexec_shutdown)
|
||||
+ _machine_kexec_shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
machine_crash_shutdown(struct pt_regs *regs)
|
||||
{
|
||||
+ if (_machine_crash_shutdown)
|
||||
+ _machine_crash_shutdown(regs);
|
||||
+ else
|
||||
+ default_machine_crash_shutdown(regs);
|
||||
}
|
||||
|
||||
typedef void (*noretfun_t)(void) __attribute__((noreturn));
|
||||
@@ -52,7 +68,9 @@ machine_kexec(struct kimage *image)
|
||||
reboot_code_buffer =
|
||||
(unsigned long)page_address(image->control_code_page);
|
||||
|
||||
- kexec_start_address = (unsigned long) phys_to_virt(image->start);
|
||||
+ kexec_start_address =
|
||||
+ (unsigned long) phys_to_virt(image->start);
|
||||
+
|
||||
kexec_indirection_page =
|
||||
(unsigned long) phys_to_virt(image->head & PAGE_MASK);
|
||||
|
||||
@@ -63,7 +81,7 @@ machine_kexec(struct kimage *image)
|
||||
* The generic kexec code builds a page list with physical
|
||||
* addresses. they are directly accessible through KSEG0 (or
|
||||
* CKSEG0 or XPHYS if on 64bit system), hence the
|
||||
- * pys_to_virt() call.
|
||||
+ * phys_to_virt() call.
|
||||
*/
|
||||
for (ptr = &image->head; (entry = *ptr) && !(entry &IND_DONE);
|
||||
ptr = (entry & IND_INDIRECTION) ?
|
||||
@@ -81,5 +99,13 @@ machine_kexec(struct kimage *image)
|
||||
printk("Will call new kernel at %08lx\n", image->start);
|
||||
printk("Bye ...\n");
|
||||
__flush_cache_all();
|
||||
+#ifdef CONFIG_SMP
|
||||
+ /* All secondary cpus now may jump to kexec_wait cycle */
|
||||
+ relocated_kexec_smp_wait = reboot_code_buffer +
|
||||
+ (void *)(kexec_smp_wait - relocate_new_kernel);
|
||||
+ smp_wmb();
|
||||
+ atomic_set(&kexec_ready_to_reboot, 1);
|
||||
+#endif
|
||||
((noretfun_t) reboot_code_buffer)();
|
||||
}
|
||||
+
|
||||
--- a/arch/mips/kernel/relocate_kernel.S
|
||||
+++ b/arch/mips/kernel/relocate_kernel.S
|
||||
@@ -15,6 +15,11 @@
|
||||
#include <asm/addrspace.h>
|
||||
|
||||
LEAF(relocate_new_kernel)
|
||||
+ PTR_L a0, arg0
|
||||
+ PTR_L a1, arg1
|
||||
+ PTR_L a2, arg2
|
||||
+ PTR_L a3, arg3
|
||||
+
|
||||
PTR_L s0, kexec_indirection_page
|
||||
PTR_L s1, kexec_start_address
|
||||
|
||||
@@ -26,7 +31,6 @@ process_entry:
|
||||
and s3, s2, 0x1
|
||||
beq s3, zero, 1f
|
||||
and s4, s2, ~0x1 /* store destination addr in s4 */
|
||||
- move a0, s4
|
||||
b process_entry
|
||||
|
||||
1:
|
||||
@@ -60,23 +64,100 @@ copy_word:
|
||||
b process_entry
|
||||
|
||||
done:
|
||||
+#ifdef CONFIG_SMP
|
||||
+ /* kexec_flag reset is signal to other CPUs what kernel
|
||||
+ was moved to it's location. Note - we need relocated address
|
||||
+ of kexec_flag. */
|
||||
+
|
||||
+ bal 1f
|
||||
+ 1: move t1,ra;
|
||||
+ PTR_LA t2,1b
|
||||
+ PTR_LA t0,kexec_flag
|
||||
+ PTR_SUB t0,t0,t2;
|
||||
+ PTR_ADD t0,t1,t0;
|
||||
+ LONG_S zero,(t0)
|
||||
+#endif
|
||||
+
|
||||
+ sync
|
||||
/* jump to kexec_start_address */
|
||||
j s1
|
||||
END(relocate_new_kernel)
|
||||
|
||||
-kexec_start_address:
|
||||
- EXPORT(kexec_start_address)
|
||||
+#ifdef CONFIG_SMP
|
||||
+/*
|
||||
+ * Other CPUs should wait until code is relocated and
|
||||
+ * then start at entry (?) point.
|
||||
+ */
|
||||
+LEAF(kexec_smp_wait)
|
||||
+ PTR_L a0, s_arg0
|
||||
+ PTR_L a1, s_arg1
|
||||
+ PTR_L a2, s_arg2
|
||||
+ PTR_L a3, s_arg3
|
||||
+ PTR_L s1, kexec_start_address
|
||||
+
|
||||
+ /* Non-relocated address works for args and kexec_start_address ( old
|
||||
+ * kernel is not overwritten). But we need relocated address of
|
||||
+ * kexec_flag.
|
||||
+ */
|
||||
+
|
||||
+ bal 1f
|
||||
+1: move t1,ra;
|
||||
+ PTR_LA t2,1b
|
||||
+ PTR_LA t0,kexec_flag
|
||||
+ PTR_SUB t0,t0,t2;
|
||||
+ PTR_ADD t0,t1,t0;
|
||||
+
|
||||
+1: LONG_L s0, (t0)
|
||||
+ bne s0, zero,1b
|
||||
+
|
||||
+ sync
|
||||
+ j s1
|
||||
+ END(kexec_smp_wait)
|
||||
+#endif
|
||||
+
|
||||
+#ifdef __mips64
|
||||
+ /* all PTR's must be aligned to 8 byte in 64-bit mode */
|
||||
+ .align 3
|
||||
+#endif
|
||||
+
|
||||
+/* All parameters to new kernel are passed in registers a0-a3.
|
||||
+ * kexec_args[0..3] are uses to prepare register values.
|
||||
+ */
|
||||
+
|
||||
+EXPORT(kexec_args)
|
||||
+arg0: PTR 0x0
|
||||
+arg1: PTR 0x0
|
||||
+arg2: PTR 0x0
|
||||
+arg3: PTR 0x0
|
||||
+ .size kexec_args,PTRSIZE*4
|
||||
+
|
||||
+#ifdef CONFIG_SMP
|
||||
+/*
|
||||
+ * Secondary CPUs may have different kernel parameters in
|
||||
+ * their registers a0-a3. secondary_kexec_args[0..3] are used
|
||||
+ * to prepare register values.
|
||||
+ */
|
||||
+EXPORT(secondary_kexec_args)
|
||||
+s_arg0: PTR 0x0
|
||||
+s_arg1: PTR 0x0
|
||||
+s_arg2: PTR 0x0
|
||||
+s_arg3: PTR 0x0
|
||||
+ .size secondary_kexec_args,PTRSIZE*4
|
||||
+kexec_flag:
|
||||
+ LONG 0x1
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+EXPORT(kexec_start_address)
|
||||
PTR 0x0
|
||||
.size kexec_start_address, PTRSIZE
|
||||
|
||||
-kexec_indirection_page:
|
||||
- EXPORT(kexec_indirection_page)
|
||||
+EXPORT(kexec_indirection_page)
|
||||
PTR 0
|
||||
.size kexec_indirection_page, PTRSIZE
|
||||
|
||||
relocate_new_kernel_end:
|
||||
|
||||
-relocate_new_kernel_size:
|
||||
- EXPORT(relocate_new_kernel_size)
|
||||
+EXPORT(relocate_new_kernel_size)
|
||||
PTR relocate_new_kernel_end - relocate_new_kernel
|
||||
.size relocate_new_kernel_size, PTRSIZE
|
||||
--- a/arch/mips/kernel/setup.c
|
||||
+++ b/arch/mips/kernel/setup.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/console.h>
|
||||
#include <linux/pfn.h>
|
||||
#include <linux/debugfs.h>
|
||||
+#include <linux/kexec.h>
|
||||
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/bootinfo.h>
|
||||
@@ -522,12 +523,62 @@ static void __init arch_mem_init(char **
|
||||
}
|
||||
|
||||
bootmem_init();
|
||||
+#ifdef CONFIG_KEXEC
|
||||
+ if (crashk_res.start != crashk_res.end)
|
||||
+ reserve_bootmem(crashk_res.start,
|
||||
+ crashk_res.end - crashk_res.start + 1,
|
||||
+ BOOTMEM_DEFAULT);
|
||||
+#endif
|
||||
device_tree_init();
|
||||
sparse_init();
|
||||
plat_swiotlb_setup();
|
||||
paging_init();
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KEXEC
|
||||
+static inline unsigned long long get_total_mem(void)
|
||||
+{
|
||||
+ unsigned long long total;
|
||||
+ total = max_pfn - min_low_pfn;
|
||||
+ return total << PAGE_SHIFT;
|
||||
+}
|
||||
+
|
||||
+static void __init mips_parse_crashkernel(void)
|
||||
+{
|
||||
+ unsigned long long total_mem;
|
||||
+ unsigned long long crash_size, crash_base;
|
||||
+ int ret;
|
||||
+
|
||||
+ total_mem = get_total_mem();
|
||||
+ ret = parse_crashkernel(boot_command_line, total_mem,
|
||||
+ &crash_size, &crash_base);
|
||||
+ if (ret != 0 || crash_size <= 0)
|
||||
+ return;
|
||||
+
|
||||
+ crashk_res.start = crash_base;
|
||||
+ crashk_res.end = crash_base + crash_size - 1;
|
||||
+}
|
||||
+static void __init request_crashkernel(struct resource *res)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = request_resource(res, &crashk_res);
|
||||
+ if (!ret)
|
||||
+ printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
|
||||
+ "for crashkernel\n",
|
||||
+ (unsigned long)((crashk_res.end -
|
||||
+ crashk_res.start + 1) >> 20),
|
||||
+ (unsigned long)(crashk_res.start >> 20));
|
||||
+}
|
||||
+#else
|
||||
+static void __init mips_parse_crashkernel(void)
|
||||
+{
|
||||
+}
|
||||
+static void __init request_crashkernel(struct resource *res)
|
||||
+{
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static void __init resource_init(void)
|
||||
{
|
||||
int i;
|
||||
@@ -543,6 +594,8 @@ static void __init resource_init(void)
|
||||
/*
|
||||
* Request address space for all standard RAM.
|
||||
*/
|
||||
+ mips_parse_crashkernel();
|
||||
+
|
||||
for (i = 0; i < boot_mem_map.nr_map; i++) {
|
||||
struct resource *res;
|
||||
unsigned long start, end;
|
||||
@@ -579,6 +632,7 @@ static void __init resource_init(void)
|
||||
*/
|
||||
request_resource(res, &code_resource);
|
||||
request_resource(res, &data_resource);
|
||||
+ request_crashkernel(res);
|
||||
}
|
||||
}
|
||||
|
||||
--- a/arch/mips/kernel/smp.c
|
||||
+++ b/arch/mips/kernel/smp.c
|
||||
@@ -386,3 +386,21 @@ void flush_tlb_one(unsigned long vaddr)
|
||||
|
||||
EXPORT_SYMBOL(flush_tlb_page);
|
||||
EXPORT_SYMBOL(flush_tlb_one);
|
||||
+
|
||||
+#if defined(CONFIG_KEXEC)
|
||||
+void (*dump_ipi_function_ptr)(void *) = NULL;
|
||||
+void dump_send_ipi(void (*dump_ipi_callback)(void *))
|
||||
+{
|
||||
+ int i;
|
||||
+ int cpu = smp_processor_id();
|
||||
+
|
||||
+ dump_ipi_function_ptr = dump_ipi_callback;
|
||||
+ smp_mb();
|
||||
+ for_each_online_cpu(i)
|
||||
+ if (i != cpu)
|
||||
+ core_send_ipi(i, SMP_DUMP);
|
||||
+
|
||||
+}
|
||||
+EXPORT_SYMBOL(dump_send_ipi);
|
||||
+#endif
|
||||
+
|
||||
--- a/arch/mips/include/asm/kexec.h
|
||||
+++ b/arch/mips/include/asm/kexec.h
|
||||
@@ -9,22 +9,45 @@
|
||||
#ifndef _MIPS_KEXEC
|
||||
# define _MIPS_KEXEC
|
||||
|
||||
+#include <asm/stacktrace.h>
|
||||
+
|
||||
+extern unsigned long long elfcorehdr_addr;
|
||||
+
|
||||
/* Maximum physical address we can use pages from */
|
||||
#define KEXEC_SOURCE_MEMORY_LIMIT (0x20000000)
|
||||
/* Maximum address we can reach in physical address mode */
|
||||
#define KEXEC_DESTINATION_MEMORY_LIMIT (0x20000000)
|
||||
/* Maximum address we can use for the control code buffer */
|
||||
#define KEXEC_CONTROL_MEMORY_LIMIT (0x20000000)
|
||||
-
|
||||
-#define KEXEC_CONTROL_PAGE_SIZE 4096
|
||||
+/* Reserve 3*4096 bytes for board-specific info */
|
||||
+#define KEXEC_CONTROL_PAGE_SIZE (4096 + 3*4096)
|
||||
|
||||
/* The native architecture */
|
||||
#define KEXEC_ARCH KEXEC_ARCH_MIPS
|
||||
+#define MAX_NOTE_BYTES 1024
|
||||
|
||||
static inline void crash_setup_regs(struct pt_regs *newregs,
|
||||
- struct pt_regs *oldregs)
|
||||
+ struct pt_regs *oldregs)
|
||||
{
|
||||
- /* Dummy implementation for now */
|
||||
+ if (oldregs)
|
||||
+ memcpy(newregs, oldregs, sizeof(*newregs));
|
||||
+ else
|
||||
+ prepare_frametrace(newregs);
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_KEXEC
|
||||
+struct kimage;
|
||||
+extern unsigned long kexec_args[4];
|
||||
+extern int (*_machine_kexec_prepare)(struct kimage *);
|
||||
+extern void (*_machine_kexec_shutdown)(void);
|
||||
+extern void (*_machine_crash_shutdown)(struct pt_regs *regs);
|
||||
+extern void default_machine_crash_shutdown(struct pt_regs *regs);
|
||||
+#ifdef CONFIG_SMP
|
||||
+extern const unsigned char kexec_smp_wait[];
|
||||
+extern unsigned long secondary_kexec_args[4];
|
||||
+extern void (*relocated_kexec_smp_wait) (void *);
|
||||
+extern atomic_t kexec_ready_to_reboot;
|
||||
+#endif
|
||||
+#endif
|
||||
+
|
||||
#endif /* !_MIPS_KEXEC */
|
||||
--- a/arch/mips/include/asm/smp.h
|
||||
+++ b/arch/mips/include/asm/smp.h
|
||||
@@ -40,6 +40,8 @@ extern int __cpu_logical_map[NR_CPUS];
|
||||
#define SMP_CALL_FUNCTION 0x2
|
||||
/* Octeon - Tell another core to flush its icache */
|
||||
#define SMP_ICACHE_FLUSH 0x4
|
||||
+/* Used by kexec crashdump to save all cpu's state */
|
||||
+#define SMP_DUMP 0x8
|
||||
|
||||
extern volatile cpumask_t cpu_callin_map;
|
||||
|
||||
@@ -91,4 +93,9 @@ static inline void arch_send_call_functi
|
||||
mp_ops->send_ipi_mask(mask, SMP_CALL_FUNCTION);
|
||||
}
|
||||
|
||||
+extern void core_send_ipi(int cpu, unsigned int action);
|
||||
+#if defined(CONFIG_KEXEC)
|
||||
+extern void (*dump_ipi_function_ptr)(void *);
|
||||
+void dump_send_ipi(void (*dump_ipi_callback)(void *));
|
||||
+#endif
|
||||
#endif /* __ASM_SMP_H */
|
@ -1,157 +0,0 @@
|
||||
From 03cd81fbca6b91317ec1a7b3b3c09fb8d08f83a6 Mon Sep 17 00:00:00 2001
|
||||
From: Wu Zhangjin <wuzhangjin@gmail.com>
|
||||
Date: Tue, 11 Jan 2011 18:42:08 +0000
|
||||
Subject: MIPS: Kexec: Enhance the support
|
||||
|
||||
Changes:
|
||||
o Print more information in machine_kexec() for debugging
|
||||
E.g. with this information, the kexec_start_address has been found
|
||||
it was wrong with 64bit kernel / o32 kexec-tools. Which must be
|
||||
fixed later.
|
||||
o Link relocate_kernel.S to a section for future extension
|
||||
This allows more functions can be added for the kexec relocation
|
||||
part even written in C. to add code into that section, you just need
|
||||
to mark your function or data with __kexec or
|
||||
__attribute__((__section__(".__kexec.relocate")))
|
||||
|
||||
TODO:
|
||||
|
||||
1. Make 64bit kernel / o32|n32|64 kexec-tools works
|
||||
|
||||
Fix the user-space kexec-tools, seems the tool only work for 32bit
|
||||
machine. So, we need to add 64bit support for it. The address of the
|
||||
entry point(kexec_start_address) is wrong and make the "kexec -e" fail.
|
||||
the real entry point must be read from the new kernel image by the
|
||||
user-space kexec-tools, otherwise, it will not work. The above 64bit
|
||||
support tested is 64bit kernel with o32 user-space kexec-tools. The root
|
||||
cause may be the different definition of virt_to_phys() and
|
||||
phys_to_virt() in the kexec-tools and kernel space for 64bit system /
|
||||
o32 kernel.
|
||||
|
||||
Ref: http://www.linux-mips.org/archives/linux-mips/2009-08/msg00149.html
|
||||
|
||||
2. Pass the arguments from kexec-tools to the new kernel image
|
||||
|
||||
Please refer to: "MIPS: Loongson: Kexec: Pass parameters to new kernel"
|
||||
|
||||
Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
|
||||
---
|
||||
--- a/arch/mips/include/asm/kexec.h
|
||||
+++ b/arch/mips/include/asm/kexec.h
|
||||
@@ -36,6 +36,16 @@ static inline void crash_setup_regs(stru
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KEXEC
|
||||
+
|
||||
+#define __kexec __attribute__((__section__(".__kexec.relocate")))
|
||||
+
|
||||
+/* The linker tells us where the relocate_new_kernel part is. */
|
||||
+extern const unsigned char __start___kexec_relocate;
|
||||
+extern const unsigned char __end___kexec_relocate;
|
||||
+
|
||||
+extern unsigned long kexec_start_address;
|
||||
+extern unsigned long kexec_indirection_page;
|
||||
+
|
||||
struct kimage;
|
||||
extern unsigned long kexec_args[4];
|
||||
extern int (*_machine_kexec_prepare)(struct kimage *);
|
||||
--- a/arch/mips/kernel/machine_kexec.c
|
||||
+++ b/arch/mips/kernel/machine_kexec.c
|
||||
@@ -14,10 +14,6 @@
|
||||
#include <asm/page.h>
|
||||
|
||||
extern const unsigned char relocate_new_kernel[];
|
||||
-extern const size_t relocate_new_kernel_size;
|
||||
-
|
||||
-extern unsigned long kexec_start_address;
|
||||
-extern unsigned long kexec_indirection_page;
|
||||
|
||||
int (*_machine_kexec_prepare)(struct kimage *) = NULL;
|
||||
void (*_machine_kexec_shutdown)(void) = NULL;
|
||||
@@ -61,21 +57,34 @@ typedef void (*noretfun_t)(void) __attri
|
||||
void
|
||||
machine_kexec(struct kimage *image)
|
||||
{
|
||||
+ unsigned long kexec_relocate_size;
|
||||
unsigned long reboot_code_buffer;
|
||||
unsigned long entry;
|
||||
unsigned long *ptr;
|
||||
|
||||
+ kexec_relocate_size = (unsigned long)(&__end___kexec_relocate) -
|
||||
+ (unsigned long)(&__start___kexec_relocate);
|
||||
+ pr_info("kexec_relocate_size = %lu\n", kexec_relocate_size);
|
||||
+
|
||||
reboot_code_buffer =
|
||||
(unsigned long)page_address(image->control_code_page);
|
||||
+ pr_info("reboot_code_buffer = %p\n", (void *)reboot_code_buffer);
|
||||
|
||||
kexec_start_address =
|
||||
(unsigned long) phys_to_virt(image->start);
|
||||
+ pr_info("kexec_start_address(entry point of new kernel) = %p\n",
|
||||
+ (void *)kexec_start_address);
|
||||
|
||||
kexec_indirection_page =
|
||||
(unsigned long) phys_to_virt(image->head & PAGE_MASK);
|
||||
+ pr_info("kexec_indirection_page = %p\n",
|
||||
+ (void *)kexec_indirection_page);
|
||||
|
||||
- memcpy((void*)reboot_code_buffer, relocate_new_kernel,
|
||||
- relocate_new_kernel_size);
|
||||
+ memcpy((void *)reboot_code_buffer, &__start___kexec_relocate,
|
||||
+ kexec_relocate_size);
|
||||
+
|
||||
+ pr_info("Copy kexec_relocate section from %p to reboot_code_buffer: %p\n",
|
||||
+ &__start___kexec_relocate, (void *)reboot_code_buffer);
|
||||
|
||||
/*
|
||||
* The generic kexec code builds a page list with physical
|
||||
@@ -96,8 +105,8 @@ machine_kexec(struct kimage *image)
|
||||
*/
|
||||
local_irq_disable();
|
||||
|
||||
- printk("Will call new kernel at %08lx\n", image->start);
|
||||
- printk("Bye ...\n");
|
||||
+ pr_info("Will call new kernel at %p\n", (void *)kexec_start_address);
|
||||
+ pr_info("Bye ...\n");
|
||||
__flush_cache_all();
|
||||
#ifdef CONFIG_SMP
|
||||
/* All secondary cpus now may jump to kexec_wait cycle */
|
||||
@@ -108,4 +117,3 @@ machine_kexec(struct kimage *image)
|
||||
#endif
|
||||
((noretfun_t) reboot_code_buffer)();
|
||||
}
|
||||
-
|
||||
--- a/arch/mips/kernel/relocate_kernel.S
|
||||
+++ b/arch/mips/kernel/relocate_kernel.S
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <asm/stackframe.h>
|
||||
#include <asm/addrspace.h>
|
||||
|
||||
+ .section .kexec.relocate, "ax"
|
||||
+
|
||||
LEAF(relocate_new_kernel)
|
||||
PTR_L a0, arg0
|
||||
PTR_L a1, arg1
|
||||
@@ -155,9 +157,3 @@ EXPORT(kexec_start_address)
|
||||
EXPORT(kexec_indirection_page)
|
||||
PTR 0
|
||||
.size kexec_indirection_page, PTRSIZE
|
||||
-
|
||||
-relocate_new_kernel_end:
|
||||
-
|
||||
-EXPORT(relocate_new_kernel_size)
|
||||
- PTR relocate_new_kernel_end - relocate_new_kernel
|
||||
- .size relocate_new_kernel_size, PTRSIZE
|
||||
--- a/arch/mips/kernel/vmlinux.lds.S
|
||||
+++ b/arch/mips/kernel/vmlinux.lds.S
|
||||
@@ -51,6 +51,10 @@ SECTIONS
|
||||
*(.text.*)
|
||||
*(.fixup)
|
||||
*(.gnu.warning)
|
||||
+ __start___kexec_relocate = .;
|
||||
+ KEEP(*(.kexec.relocate))
|
||||
+ KEEP(*(.__kexec.relocate))
|
||||
+ __end___kexec_relocate = .;
|
||||
} :text = 0
|
||||
_etext = .; /* End of text section */
|
||||
|
@ -1,52 +0,0 @@
|
||||
From 49d07a29653b1f2c6ae273b3d8fe93d981f43004 Mon Sep 17 00:00:00 2001
|
||||
From: Wu Zhangjin <wuzhangjin@gmail.com>
|
||||
Date: Wed, 12 Jan 2011 20:59:32 +0000
|
||||
Subject: MIPS: Kexec: Init the arguments for the new kernel image
|
||||
|
||||
Whenever the kexec-tools pass the command lines to the new kernel image,
|
||||
init the arguments as the ones for the 1st kernel image. This fixed the
|
||||
booting failure of Kexec on YeeLoong.
|
||||
|
||||
Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
|
||||
---
|
||||
--- a/arch/mips/kernel/machine_kexec.c
|
||||
+++ b/arch/mips/kernel/machine_kexec.c
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
+#include <asm/bootinfo.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
@@ -23,9 +24,30 @@ void (*relocated_kexec_smp_wait) (void *
|
||||
atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
|
||||
#endif
|
||||
|
||||
+static void machine_kexec_init_args(void)
|
||||
+{
|
||||
+ kexec_args[0] = fw_arg0;
|
||||
+ kexec_args[1] = fw_arg1;
|
||||
+ kexec_args[2] = fw_arg2;
|
||||
+ kexec_args[3] = fw_arg3;
|
||||
+
|
||||
+ pr_info("kexec_args[0] (argc): %lu\n", kexec_args[0]);
|
||||
+ pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]);
|
||||
+ pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]);
|
||||
+ pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]);
|
||||
+}
|
||||
+
|
||||
int
|
||||
machine_kexec_prepare(struct kimage *kimage)
|
||||
{
|
||||
+ /*
|
||||
+ * Whenever arguments passed from kexec-tools, Init the arguments as
|
||||
+ * the original ones to avoid booting failure.
|
||||
+ *
|
||||
+ * This can be overrided by _machine_kexec_prepare().
|
||||
+ */
|
||||
+ machine_kexec_init_args();
|
||||
+
|
||||
if (_machine_kexec_prepare)
|
||||
return _machine_kexec_prepare(kimage);
|
||||
return 0;
|
@ -1,88 +0,0 @@
|
||||
From 240c76841b26f1b09aaced33414ee1d08b6454cf Mon Sep 17 00:00:00 2001
|
||||
From: Wu Zhangjin <wuzhangjin@gmail.com>
|
||||
Date: Sat, 15 Jan 2011 12:46:03 +0000
|
||||
Subject: MIPS: Get kernel parameters from kexec-tools
|
||||
|
||||
Before, we simply use the command lines from the original bootloader,
|
||||
but it is not convenient. Now, we accept the kernel parameters from the
|
||||
--command-line or --append option of the kexec-tools. But If not
|
||||
--command-line or --apend option indicated, will fall back to use the
|
||||
ones from the original bootloader.
|
||||
|
||||
Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
|
||||
---
|
||||
--- a/arch/mips/kernel/machine_kexec.c
|
||||
+++ b/arch/mips/kernel/machine_kexec.c
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <asm/bootinfo.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/page.h>
|
||||
+#include <asm/uaccess.h>
|
||||
|
||||
extern const unsigned char relocate_new_kernel[];
|
||||
|
||||
@@ -37,6 +38,56 @@ static void machine_kexec_init_args(void
|
||||
pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]);
|
||||
}
|
||||
|
||||
+#define ARGV_MAX_ARGS (COMMAND_LINE_SIZE / 15)
|
||||
+
|
||||
+int machine_kexec_pass_args(struct kimage *image)
|
||||
+{
|
||||
+ int i, argc = 0;
|
||||
+ char *bootloader = "kexec";
|
||||
+ int *kexec_argv = (int *)kexec_args[1];
|
||||
+
|
||||
+ for (i = 0; i < image->nr_segments; i++) {
|
||||
+ if (!strncmp(bootloader, (char *)image->segment[i].buf,
|
||||
+ strlen(bootloader))) {
|
||||
+ /*
|
||||
+ * convert command line string to array
|
||||
+ * of parameters (as bootloader does).
|
||||
+ */
|
||||
+ /*
|
||||
+ * Note: we do treat the 1st string "kexec" as an
|
||||
+ * argument ;-) so, argc here is 1.
|
||||
+ */
|
||||
+ char *str = (char *)image->segment[i].buf;
|
||||
+ char *ptr = strchr(str, ' ');
|
||||
+ char *kbuf = (char *)kexec_argv[0];
|
||||
+ /* Whenever --command-line or --append used, "kexec" is copied */
|
||||
+ argc = 1;
|
||||
+ /* Parse the offset */
|
||||
+ while (ptr && (ARGV_MAX_ARGS > argc)) {
|
||||
+ *ptr = '\0';
|
||||
+ if (ptr[1] != ' ' && ptr[1] != '\0') {
|
||||
+ int offt = (int)(ptr - str + 1);
|
||||
+ kexec_argv[argc] = (int)kbuf + offt;
|
||||
+ argc++;
|
||||
+ }
|
||||
+ ptr = strchr(ptr + 1, ' ');
|
||||
+ }
|
||||
+ if (argc > 1) {
|
||||
+ /* Copy to kernel space */
|
||||
+ copy_from_user(kbuf, (char *)image->segment[i].buf, image->segment[i].bufsz);
|
||||
+ fw_arg0 = kexec_args[0] = argc;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ pr_info("argc = %lu\n", kexec_args[0]);
|
||||
+ for (i = 0; i < kexec_args[0]; i++)
|
||||
+ pr_info("argv[%d] = %p, %s\n", i, (char *)kexec_argv[i], (char *)kexec_argv[i]);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int
|
||||
machine_kexec_prepare(struct kimage *kimage)
|
||||
{
|
||||
@@ -47,6 +98,7 @@ machine_kexec_prepare(struct kimage *kim
|
||||
* This can be overrided by _machine_kexec_prepare().
|
||||
*/
|
||||
machine_kexec_init_args();
|
||||
+ machine_kexec_pass_args(kimage);
|
||||
|
||||
if (_machine_kexec_prepare)
|
||||
return _machine_kexec_prepare(kimage);
|
@ -1,83 +0,0 @@
|
||||
From 4aded085fa0057a9a1e1dcec631f950307360c1f Mon Sep 17 00:00:00 2001
|
||||
From: Wu Zhangjin <wuzhangjin@gmail.com>
|
||||
Date: Tue, 11 Jan 2011 13:46:19 +0000
|
||||
Subject: MIPS: Fix compiling failure of relocate_kernel.S
|
||||
|
||||
The following errors is fixed with the help of <asm/asm_nosec.h>. for
|
||||
this file need to put different symbols in the same section, the
|
||||
original LEAF, NESTED and EXPORT (without explicit section indication)
|
||||
must be used, <asm/asm_nosec.h> does it.
|
||||
|
||||
arch/mips/kernel/relocate_kernel.S: Assembler messages:
|
||||
arch/mips/kernel/relocate_kernel.S:162: Error: operation combines symbols in different segments
|
||||
|
||||
Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
|
||||
---
|
||||
(limited to 'arch/mips/kernel')
|
||||
|
||||
--- a/arch/mips/kernel/relocate_kernel.S
|
||||
+++ b/arch/mips/kernel/relocate_kernel.S
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <asm/asm.h>
|
||||
+#include <asm/asm_nosec.h>
|
||||
#include <asm/asmmacro.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/page.h>
|
||||
--- /dev/null
|
||||
+++ b/arch/mips/include/asm/asm_nosec.h
|
||||
@@ -0,0 +1,53 @@
|
||||
+/*
|
||||
+ * 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) 1995, 1996, 1997, 1999, 2001 by Ralf Baechle
|
||||
+ * Copyright (C) 1999 by Silicon Graphics, Inc.
|
||||
+ * Copyright (C) 2001 MIPS Technologies, Inc.
|
||||
+ * Copyright (C) 2002 Maciej W. Rozycki
|
||||
+ * Copyright (C) 2010 Wu Zhangjin <wuzhangjin@gmail.com>
|
||||
+ *
|
||||
+ * Derive from <asm/asm.h>
|
||||
+ *
|
||||
+ * Override the macros without -ffunction-sections and -fdata-sections support.
|
||||
+ * If several functions or data must be put in the same section, please include
|
||||
+ * this header file after the <asm/asm.h> to override the generic definition.
|
||||
+ */
|
||||
+
|
||||
+#ifndef __ASM_ASM_NOSEC_H
|
||||
+#define __ASM_ASM_NOSEC_H
|
||||
+
|
||||
+#undef LEAF
|
||||
+#undef NESTED
|
||||
+#undef EXPORT
|
||||
+
|
||||
+/*
|
||||
+ * LEAF - declare leaf routine
|
||||
+ */
|
||||
+#define LEAF(symbol) \
|
||||
+ .globl symbol; \
|
||||
+ .align 2; \
|
||||
+ .type symbol, @function; \
|
||||
+ .ent symbol, 0; \
|
||||
+symbol: .frame sp, 0, ra
|
||||
+
|
||||
+/*
|
||||
+ * NESTED - declare nested routine entry point
|
||||
+ */
|
||||
+#define NESTED(symbol, framesize, rpc) \
|
||||
+ .globl symbol; \
|
||||
+ .align 2; \
|
||||
+ .type symbol, @function; \
|
||||
+ .ent symbol, 0; \
|
||||
+symbol: .frame sp, framesize, rpc
|
||||
+
|
||||
+/*
|
||||
+ * EXPORT - export definition of symbol
|
||||
+ */
|
||||
+#define EXPORT(symbol) \
|
||||
+ .globl symbol; \
|
||||
+symbol:
|
||||
+
|
||||
+#endif /* __ASM_ASM_NOSEC_H */
|
@ -1,186 +0,0 @@
|
||||
--- a/arch/mips/kernel/machine_kexec.c
|
||||
+++ b/arch/mips/kernel/machine_kexec.c
|
||||
@@ -25,67 +25,104 @@ void (*relocated_kexec_smp_wait) (void *
|
||||
atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
|
||||
#endif
|
||||
|
||||
-static void machine_kexec_init_args(void)
|
||||
+#define KEXEC_MIPS_ARGV_BUF_SIZE COMMAND_LINE_SIZE
|
||||
+#define KEXEC_MIPS_ARGV_MAX_ARGS (COMMAND_LINE_SIZE / 15)
|
||||
+
|
||||
+char kexec_argv_buf[KEXEC_MIPS_ARGV_BUF_SIZE] __kexec;
|
||||
+char *kexec_argv[KEXEC_MIPS_ARGV_MAX_ARGS] __kexec;
|
||||
+
|
||||
+static void
|
||||
+machine_kexec_print_args(void)
|
||||
{
|
||||
- kexec_args[0] = fw_arg0;
|
||||
- kexec_args[1] = fw_arg1;
|
||||
- kexec_args[2] = fw_arg2;
|
||||
- kexec_args[3] = fw_arg3;
|
||||
+ int i;
|
||||
|
||||
pr_info("kexec_args[0] (argc): %lu\n", kexec_args[0]);
|
||||
pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]);
|
||||
pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]);
|
||||
pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]);
|
||||
-}
|
||||
|
||||
-#define ARGV_MAX_ARGS (COMMAND_LINE_SIZE / 15)
|
||||
+ for (i = 0; i < kexec_args[0]; i++)
|
||||
+ pr_info("kexec_argv[%d] = %p, %s\n", i,
|
||||
+ (char *)kexec_argv[i], (char *)kexec_argv[i]);
|
||||
+}
|
||||
|
||||
-int machine_kexec_pass_args(struct kimage *image)
|
||||
+static void
|
||||
+machine_kexec_init_argv(struct kimage *image)
|
||||
{
|
||||
- int i, argc = 0;
|
||||
- char *bootloader = "kexec";
|
||||
- int *kexec_argv = (int *)kexec_args[1];
|
||||
+ void __user *buf = NULL;
|
||||
+ size_t bufsz;
|
||||
+ size_t size;
|
||||
+ int i;
|
||||
|
||||
+ bufsz = 0;
|
||||
for (i = 0; i < image->nr_segments; i++) {
|
||||
- if (!strncmp(bootloader, (char *)image->segment[i].buf,
|
||||
- strlen(bootloader))) {
|
||||
- /*
|
||||
- * convert command line string to array
|
||||
- * of parameters (as bootloader does).
|
||||
- */
|
||||
- /*
|
||||
- * Note: we do treat the 1st string "kexec" as an
|
||||
- * argument ;-) so, argc here is 1.
|
||||
- */
|
||||
- char *str = (char *)image->segment[i].buf;
|
||||
- char *ptr = strchr(str, ' ');
|
||||
- char *kbuf = (char *)kexec_argv[0];
|
||||
- /* Whenever --command-line or --append used, "kexec" is copied */
|
||||
- argc = 1;
|
||||
- /* Parse the offset */
|
||||
- while (ptr && (ARGV_MAX_ARGS > argc)) {
|
||||
- *ptr = '\0';
|
||||
- if (ptr[1] != ' ' && ptr[1] != '\0') {
|
||||
- int offt = (int)(ptr - str + 1);
|
||||
- kexec_argv[argc] = (int)kbuf + offt;
|
||||
- argc++;
|
||||
- }
|
||||
- ptr = strchr(ptr + 1, ' ');
|
||||
- }
|
||||
- if (argc > 1) {
|
||||
- /* Copy to kernel space */
|
||||
- copy_from_user(kbuf, (char *)image->segment[i].buf, image->segment[i].bufsz);
|
||||
- fw_arg0 = kexec_args[0] = argc;
|
||||
- }
|
||||
- break;
|
||||
+ struct kexec_segment *seg;
|
||||
+
|
||||
+ seg = &image->segment[i];
|
||||
+ if (seg->bufsz < 6)
|
||||
+ continue;
|
||||
+
|
||||
+ if (strncmp((char *) seg->buf, "kexec", 5))
|
||||
+ continue;
|
||||
+
|
||||
+ /* don't copy "kexec" */
|
||||
+ buf = seg->buf + 5;
|
||||
+ bufsz = seg->bufsz - 5;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!buf)
|
||||
+ return;
|
||||
+
|
||||
+ size = KEXEC_MIPS_ARGV_BUF_SIZE - 1;
|
||||
+ size = min(size, bufsz);
|
||||
+ if (size < bufsz)
|
||||
+ pr_warn("kexec command line truncated to %zd bytes\n", size);
|
||||
+
|
||||
+ /* Copy to kernel space */
|
||||
+ copy_from_user(kexec_argv_buf, buf, size);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+machine_kexec_parse_argv(struct kimage *image)
|
||||
+{
|
||||
+ char *reboot_code_buffer;
|
||||
+ int reloc_delta;
|
||||
+ char *ptr;
|
||||
+ int argc;
|
||||
+ int i;
|
||||
+
|
||||
+ ptr = kexec_argv_buf;
|
||||
+ argc = 0;
|
||||
+
|
||||
+ /*
|
||||
+ * convert command line string to array of parameters
|
||||
+ * (as bootloader does).
|
||||
+ */
|
||||
+ while (ptr && *ptr && (KEXEC_MIPS_ARGV_MAX_ARGS > argc)) {
|
||||
+ if (*ptr == ' ') {
|
||||
+ *ptr++ = '\0';
|
||||
+ continue;
|
||||
}
|
||||
+
|
||||
+ kexec_argv[argc++] = ptr;
|
||||
+ ptr = strchr(ptr, ' ');
|
||||
}
|
||||
|
||||
- pr_info("argc = %lu\n", kexec_args[0]);
|
||||
- for (i = 0; i < kexec_args[0]; i++)
|
||||
- pr_info("argv[%d] = %p, %s\n", i, (char *)kexec_argv[i], (char *)kexec_argv[i]);
|
||||
+ if (!argc)
|
||||
+ return;
|
||||
|
||||
- return 0;
|
||||
+ kexec_args[0] = argc;
|
||||
+ kexec_args[1] = (unsigned long)kexec_argv;
|
||||
+ kexec_args[2] = 0;
|
||||
+ kexec_args[3] = 0;
|
||||
+
|
||||
+ reboot_code_buffer = page_address(image->control_code_page);
|
||||
+ reloc_delta = reboot_code_buffer - (char *) &__start___kexec_relocate;
|
||||
+
|
||||
+ kexec_args[1] += reloc_delta;
|
||||
+ for (i = 0; i < argc; i++)
|
||||
+ kexec_argv[i] += reloc_delta;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -97,8 +134,14 @@ machine_kexec_prepare(struct kimage *kim
|
||||
*
|
||||
* This can be overrided by _machine_kexec_prepare().
|
||||
*/
|
||||
- machine_kexec_init_args();
|
||||
- machine_kexec_pass_args(kimage);
|
||||
+
|
||||
+ kexec_args[0] = fw_arg0;
|
||||
+ kexec_args[1] = fw_arg1;
|
||||
+ kexec_args[2] = fw_arg2;
|
||||
+ kexec_args[3] = fw_arg3;
|
||||
+
|
||||
+ machine_kexec_init_argv(kimage);
|
||||
+ machine_kexec_parse_argv(kimage);
|
||||
|
||||
if (_machine_kexec_prepare)
|
||||
return _machine_kexec_prepare(kimage);
|
||||
@@ -154,11 +197,13 @@ machine_kexec(struct kimage *image)
|
||||
pr_info("kexec_indirection_page = %p\n",
|
||||
(void *)kexec_indirection_page);
|
||||
|
||||
+ pr_info("Copy kexec_relocate section from %p to reboot_code_buffer: %p\n",
|
||||
+ &__start___kexec_relocate, (void *)reboot_code_buffer);
|
||||
+
|
||||
memcpy((void *)reboot_code_buffer, &__start___kexec_relocate,
|
||||
kexec_relocate_size);
|
||||
|
||||
- pr_info("Copy kexec_relocate section from %p to reboot_code_buffer: %p\n",
|
||||
- &__start___kexec_relocate, (void *)reboot_code_buffer);
|
||||
+ machine_kexec_print_args();
|
||||
|
||||
/*
|
||||
* The generic kexec code builds a page list with physical
|
@ -1,20 +0,0 @@
|
||||
--- a/kernel/module.c
|
||||
+++ b/kernel/module.c
|
||||
@@ -2358,12 +2358,15 @@ static void dynamic_debug_remove(struct
|
||||
|
||||
void * __weak module_alloc(unsigned long size)
|
||||
{
|
||||
- return size == 0 ? NULL : vmalloc_exec(size);
|
||||
+ return vmalloc_exec(size);
|
||||
}
|
||||
|
||||
static void *module_alloc_update_bounds(unsigned long size)
|
||||
{
|
||||
- void *ret = module_alloc(size);
|
||||
+ void *ret = NULL;
|
||||
+
|
||||
+ if (size)
|
||||
+ ret = module_alloc(size);
|
||||
|
||||
if (ret) {
|
||||
mutex_lock(&module_mutex);
|
@ -1,327 +0,0 @@
|
||||
--- a/drivers/mtd/Kconfig
|
||||
+++ b/drivers/mtd/Kconfig
|
||||
@@ -23,6 +23,14 @@ config MTD_TESTS
|
||||
WARNING: some of the tests will ERASE entire MTD device which they
|
||||
test. Do not use these tests unless you really know what you do.
|
||||
|
||||
+config MTD_ROOTFS_ROOT_DEV
|
||||
+ bool "Automatically set 'rootfs' partition to be root filesystem"
|
||||
+ default y
|
||||
+
|
||||
+config MTD_ROOTFS_SPLIT
|
||||
+ bool "Automatically split 'rootfs' partition for squashfs"
|
||||
+ default y
|
||||
+
|
||||
config MTD_REDBOOT_PARTS
|
||||
tristate "RedBoot partition table parsing"
|
||||
---help---
|
||||
--- a/drivers/mtd/mtdpart.c
|
||||
+++ b/drivers/mtd/mtdpart.c
|
||||
@@ -29,6 +29,8 @@
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
+#include <linux/root_dev.h>
|
||||
+#include <linux/magic.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#include "mtdcore.h"
|
||||
@@ -50,7 +52,7 @@ struct mtd_part {
|
||||
* the pointer to that structure with this macro.
|
||||
*/
|
||||
#define PART(x) ((struct mtd_part *)(x))
|
||||
-
|
||||
+#define IS_PART(mtd) (mtd->_read == part_read)
|
||||
|
||||
/*
|
||||
* MTD methods which simply translate the effective address and pass through
|
||||
@@ -613,6 +615,155 @@ int mtd_del_partition(struct mtd_info *m
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mtd_del_partition);
|
||||
|
||||
+#ifdef CONFIG_MTD_ROOTFS_SPLIT
|
||||
+#define ROOTFS_SPLIT_NAME "rootfs_data"
|
||||
+#define ROOTFS_REMOVED_NAME "<removed>"
|
||||
+
|
||||
+struct squashfs_super_block {
|
||||
+ __le32 s_magic;
|
||||
+ __le32 pad0[9];
|
||||
+ __le64 bytes_used;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static int split_squashfs(struct mtd_info *master, int offset, int *split_offset)
|
||||
+{
|
||||
+ struct squashfs_super_block sb;
|
||||
+ int len, ret;
|
||||
+
|
||||
+ ret = mtd_read(master, offset, sizeof(sb), &len, (void *) &sb);
|
||||
+ if (ret || (len != sizeof(sb))) {
|
||||
+ printk(KERN_ALERT "split_squashfs: error occured while reading "
|
||||
+ "from \"%s\"\n", master->name);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (SQUASHFS_MAGIC != le32_to_cpu(sb.s_magic) ) {
|
||||
+ printk(KERN_ALERT "split_squashfs: no squashfs found in \"%s\"\n",
|
||||
+ master->name);
|
||||
+ *split_offset = 0;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (le64_to_cpu((sb.bytes_used)) <= 0) {
|
||||
+ printk(KERN_ALERT "split_squashfs: squashfs is empty in \"%s\"\n",
|
||||
+ master->name);
|
||||
+ *split_offset = 0;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ len = (u32) le64_to_cpu(sb.bytes_used);
|
||||
+ len += (offset & 0x000fffff);
|
||||
+ len += (master->erasesize - 1);
|
||||
+ len &= ~(master->erasesize - 1);
|
||||
+ len -= (offset & 0x000fffff);
|
||||
+ *split_offset = offset + len;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int split_rootfs_data(struct mtd_info *master, struct mtd_info *rpart, const struct mtd_partition *part)
|
||||
+{
|
||||
+ struct mtd_partition *dpart;
|
||||
+ struct mtd_part *slave = NULL;
|
||||
+ struct mtd_part *spart;
|
||||
+ int ret, split_offset = 0;
|
||||
+
|
||||
+ spart = PART(rpart);
|
||||
+ ret = split_squashfs(master, spart->offset, &split_offset);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (split_offset <= 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ dpart = kmalloc(sizeof(*part)+sizeof(ROOTFS_SPLIT_NAME)+1, GFP_KERNEL);
|
||||
+ if (dpart == NULL) {
|
||||
+ printk(KERN_INFO "split_squashfs: no memory for partition \"%s\"\n",
|
||||
+ ROOTFS_SPLIT_NAME);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(dpart, part, sizeof(*part));
|
||||
+ dpart->name = (unsigned char *)&dpart[1];
|
||||
+ strcpy(dpart->name, ROOTFS_SPLIT_NAME);
|
||||
+
|
||||
+ dpart->size = rpart->size - (split_offset - spart->offset);
|
||||
+ dpart->offset = split_offset;
|
||||
+
|
||||
+ if (dpart == NULL)
|
||||
+ return 1;
|
||||
+
|
||||
+ printk(KERN_INFO "mtd: partition \"%s\" created automatically, ofs=%llX, len=%llX \n",
|
||||
+ ROOTFS_SPLIT_NAME, dpart->offset, dpart->size);
|
||||
+
|
||||
+ slave = allocate_partition(master, dpart, 0, split_offset);
|
||||
+ if (IS_ERR(slave))
|
||||
+ return PTR_ERR(slave);
|
||||
+ mutex_lock(&mtd_partitions_mutex);
|
||||
+ list_add(&slave->list, &mtd_partitions);
|
||||
+ mutex_unlock(&mtd_partitions_mutex);
|
||||
+
|
||||
+ add_mtd_device(&slave->mtd);
|
||||
+
|
||||
+ rpart->split = &slave->mtd;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int refresh_rootfs_split(struct mtd_info *mtd)
|
||||
+{
|
||||
+ struct mtd_partition tpart;
|
||||
+ struct mtd_part *part;
|
||||
+ char *name;
|
||||
+ //int index = 0;
|
||||
+ int offset, size;
|
||||
+ int ret;
|
||||
+
|
||||
+ part = PART(mtd);
|
||||
+
|
||||
+ /* check for the new squashfs offset first */
|
||||
+ ret = split_squashfs(part->master, part->offset, &offset);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if ((offset > 0) && !mtd->split) {
|
||||
+ printk(KERN_INFO "%s: creating new split partition for \"%s\"\n", __func__, mtd->name);
|
||||
+ /* if we don't have a rootfs split partition, create a new one */
|
||||
+ tpart.name = (char *) mtd->name;
|
||||
+ tpart.size = mtd->size;
|
||||
+ tpart.offset = part->offset;
|
||||
+
|
||||
+ return split_rootfs_data(part->master, &part->mtd, &tpart);
|
||||
+ } else if ((offset > 0) && mtd->split) {
|
||||
+ /* update the offsets of the existing partition */
|
||||
+ size = mtd->size + part->offset - offset;
|
||||
+
|
||||
+ part = PART(mtd->split);
|
||||
+ part->offset = offset;
|
||||
+ part->mtd.size = size;
|
||||
+ printk(KERN_INFO "%s: %s partition \"" ROOTFS_SPLIT_NAME "\", offset: 0x%06x (0x%06x)\n",
|
||||
+ __func__, (!strcmp(part->mtd.name, ROOTFS_SPLIT_NAME) ? "updating" : "creating"),
|
||||
+ (u32) part->offset, (u32) part->mtd.size);
|
||||
+ name = kmalloc(sizeof(ROOTFS_SPLIT_NAME) + 1, GFP_KERNEL);
|
||||
+ strcpy(name, ROOTFS_SPLIT_NAME);
|
||||
+ part->mtd.name = name;
|
||||
+ } else if ((offset <= 0) && mtd->split) {
|
||||
+ printk(KERN_INFO "%s: removing partition \"%s\"\n", __func__, mtd->split->name);
|
||||
+
|
||||
+ /* mark existing partition as removed */
|
||||
+ part = PART(mtd->split);
|
||||
+ name = kmalloc(sizeof(ROOTFS_SPLIT_NAME) + 1, GFP_KERNEL);
|
||||
+ strcpy(name, ROOTFS_REMOVED_NAME);
|
||||
+ part->mtd.name = name;
|
||||
+ part->offset = 0;
|
||||
+ part->mtd.size = 0;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif /* CONFIG_MTD_ROOTFS_SPLIT */
|
||||
+
|
||||
/*
|
||||
* This function, given a master MTD object and a partition table, creates
|
||||
* and registers slave MTD objects which are bound to the master according to
|
||||
@@ -629,6 +780,9 @@ int add_mtd_partitions(struct mtd_info *
|
||||
struct mtd_part *slave;
|
||||
uint64_t cur_offset = 0;
|
||||
int i;
|
||||
+#ifdef CONFIG_MTD_ROOTFS_SPLIT
|
||||
+ int ret;
|
||||
+#endif
|
||||
|
||||
printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
|
||||
|
||||
@@ -643,12 +797,53 @@ int add_mtd_partitions(struct mtd_info *
|
||||
|
||||
add_mtd_device(&slave->mtd);
|
||||
|
||||
+ if (!strcmp(parts[i].name, "rootfs")) {
|
||||
+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
|
||||
+ if (ROOT_DEV == 0) {
|
||||
+ printk(KERN_NOTICE "mtd: partition \"rootfs\" "
|
||||
+ "set to be root filesystem\n");
|
||||
+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, slave->mtd.index);
|
||||
+ }
|
||||
+#endif
|
||||
+#ifdef CONFIG_MTD_ROOTFS_SPLIT
|
||||
+ ret = split_rootfs_data(master, &slave->mtd, &parts[i]);
|
||||
+ /* if (ret == 0)
|
||||
+ * j++; */
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
cur_offset = slave->offset + slave->mtd.size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int mtd_device_refresh(struct mtd_info *mtd)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (IS_PART(mtd)) {
|
||||
+ struct mtd_part *part;
|
||||
+ struct mtd_info *master;
|
||||
+
|
||||
+ part = PART(mtd);
|
||||
+ master = part->master;
|
||||
+ if (master->refresh_device)
|
||||
+ ret = master->refresh_device(master);
|
||||
+ }
|
||||
+
|
||||
+ if (!ret && mtd->refresh_device)
|
||||
+ ret = mtd->refresh_device(mtd);
|
||||
+
|
||||
+#ifdef CONFIG_MTD_ROOTFS_SPLIT
|
||||
+ if (!ret && IS_PART(mtd) && !strcmp(mtd->name, "rootfs"))
|
||||
+ refresh_rootfs_split(mtd);
|
||||
+#endif
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(mtd_device_refresh);
|
||||
+
|
||||
static DEFINE_SPINLOCK(part_parser_lock);
|
||||
static LIST_HEAD(part_parsers);
|
||||
|
||||
--- a/drivers/mtd/mtdchar.c
|
||||
+++ b/drivers/mtd/mtdchar.c
|
||||
@@ -1012,6 +1012,12 @@ static int mtdchar_ioctl(struct file *fi
|
||||
break;
|
||||
}
|
||||
|
||||
+ case MTDREFRESH:
|
||||
+ {
|
||||
+ ret = mtd_device_refresh(mtd);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
default:
|
||||
ret = -ENOTTY;
|
||||
}
|
||||
--- a/include/linux/mtd/mtd.h
|
||||
+++ b/include/linux/mtd/mtd.h
|
||||
@@ -114,6 +114,7 @@ struct nand_ecclayout {
|
||||
|
||||
struct module; /* only needed for owner field in mtd_info */
|
||||
|
||||
+struct mtd_info;
|
||||
struct mtd_info {
|
||||
u_char type;
|
||||
uint32_t flags;
|
||||
@@ -226,6 +227,9 @@ struct mtd_info {
|
||||
int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
|
||||
int (*_suspend) (struct mtd_info *mtd);
|
||||
void (*_resume) (struct mtd_info *mtd);
|
||||
+ int (*refresh_device)(struct mtd_info *mtd);
|
||||
+ struct mtd_info *split;
|
||||
+
|
||||
/*
|
||||
* If the driver is something smart, like UBI, it may need to maintain
|
||||
* its own reference counting. The below functions are only for driver.
|
||||
@@ -375,6 +379,7 @@ extern int mtd_device_parse_register(str
|
||||
int defnr_parts);
|
||||
#define mtd_device_register(master, parts, nr_parts) \
|
||||
mtd_device_parse_register(master, NULL, NULL, parts, nr_parts)
|
||||
+extern int mtd_device_refresh(struct mtd_info *master);
|
||||
extern int mtd_device_unregister(struct mtd_info *master);
|
||||
extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
|
||||
extern int __get_mtd_device(struct mtd_info *mtd);
|
||||
--- a/include/linux/mtd/partitions.h
|
||||
+++ b/include/linux/mtd/partitions.h
|
||||
@@ -36,12 +36,14 @@
|
||||
* erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
|
||||
*/
|
||||
|
||||
+struct mtd_partition;
|
||||
struct mtd_partition {
|
||||
char *name; /* identifier string */
|
||||
uint64_t size; /* partition size */
|
||||
uint64_t offset; /* offset within the master MTD space */
|
||||
uint32_t mask_flags; /* master MTD flags to mask out for this partition */
|
||||
struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only) */
|
||||
+ int (*refresh_partition)(struct mtd_info *);
|
||||
};
|
||||
|
||||
#define MTDPART_OFS_RETAIN (-3)
|
||||
--- a/include/mtd/mtd-abi.h
|
||||
+++ b/include/mtd/mtd-abi.h
|
||||
@@ -202,6 +202,7 @@ struct otp_info {
|
||||
* without OOB, e.g., NOR flash.
|
||||
*/
|
||||
#define MEMWRITE _IOWR('M', 24, struct mtd_write_req)
|
||||
+#define MTDREFRESH _IO('M', 50)
|
||||
|
||||
/*
|
||||
* Obsolete legacy interface. Keep it in order not to break userspace
|
@ -1,146 +0,0 @@
|
||||
--- a/drivers/mtd/mtdpart.c
|
||||
+++ b/drivers/mtd/mtdpart.c
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#include "mtdcore.h"
|
||||
|
||||
+#define MTD_ERASE_PARTIAL 0x8000 /* partition only covers parts of an erase block */
|
||||
+
|
||||
/* Our partition linked list */
|
||||
static LIST_HEAD(mtd_partitions);
|
||||
static DEFINE_MUTEX(mtd_partitions_mutex);
|
||||
@@ -230,13 +232,61 @@ static int part_erase(struct mtd_info *m
|
||||
struct mtd_part *part = PART(mtd);
|
||||
int ret;
|
||||
|
||||
+
|
||||
+ instr->partial_start = false;
|
||||
+ if (mtd->flags & MTD_ERASE_PARTIAL) {
|
||||
+ size_t readlen = 0;
|
||||
+ u64 mtd_ofs;
|
||||
+
|
||||
+ instr->erase_buf = kmalloc(part->master->erasesize, GFP_ATOMIC);
|
||||
+ if (!instr->erase_buf)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ mtd_ofs = part->offset + instr->addr;
|
||||
+ instr->erase_buf_ofs = do_div(mtd_ofs, part->master->erasesize);
|
||||
+
|
||||
+ if (instr->erase_buf_ofs > 0) {
|
||||
+ instr->addr -= instr->erase_buf_ofs;
|
||||
+ ret = mtd_read(part->master,
|
||||
+ instr->addr + part->offset,
|
||||
+ part->master->erasesize,
|
||||
+ &readlen, instr->erase_buf);
|
||||
+
|
||||
+ instr->len += instr->erase_buf_ofs;
|
||||
+ instr->partial_start = true;
|
||||
+ } else {
|
||||
+ mtd_ofs = part->offset + part->mtd.size;
|
||||
+ instr->erase_buf_ofs = part->master->erasesize -
|
||||
+ do_div(mtd_ofs, part->master->erasesize);
|
||||
+
|
||||
+ if (instr->erase_buf_ofs > 0) {
|
||||
+ instr->len += instr->erase_buf_ofs;
|
||||
+ ret = mtd_read(part->master,
|
||||
+ part->offset + instr->addr +
|
||||
+ instr->len - part->master->erasesize,
|
||||
+ part->master->erasesize, &readlen,
|
||||
+ instr->erase_buf);
|
||||
+ } else {
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ if (ret < 0) {
|
||||
+ kfree(instr->erase_buf);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
instr->addr += part->offset;
|
||||
ret = part->master->_erase(part->master, instr);
|
||||
if (ret) {
|
||||
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
||||
instr->fail_addr -= part->offset;
|
||||
instr->addr -= part->offset;
|
||||
+ if (mtd->flags & MTD_ERASE_PARTIAL)
|
||||
+ kfree(instr->erase_buf);
|
||||
}
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -244,7 +294,25 @@ void mtd_erase_callback(struct erase_inf
|
||||
{
|
||||
if (instr->mtd->_erase == part_erase) {
|
||||
struct mtd_part *part = PART(instr->mtd);
|
||||
+ size_t wrlen = 0;
|
||||
|
||||
+ if (instr->mtd->flags & MTD_ERASE_PARTIAL) {
|
||||
+ if (instr->partial_start) {
|
||||
+ part->master->_write(part->master,
|
||||
+ instr->addr, instr->erase_buf_ofs,
|
||||
+ &wrlen, instr->erase_buf);
|
||||
+ instr->addr += instr->erase_buf_ofs;
|
||||
+ } else {
|
||||
+ instr->len -= instr->erase_buf_ofs;
|
||||
+ part->master->_write(part->master,
|
||||
+ instr->addr + instr->len,
|
||||
+ instr->erase_buf_ofs, &wrlen,
|
||||
+ instr->erase_buf +
|
||||
+ part->master->erasesize -
|
||||
+ instr->erase_buf_ofs);
|
||||
+ }
|
||||
+ kfree(instr->erase_buf);
|
||||
+ }
|
||||
if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
|
||||
instr->fail_addr -= part->offset;
|
||||
instr->addr -= part->offset;
|
||||
@@ -504,18 +572,24 @@ static struct mtd_part *allocate_partiti
|
||||
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
||||
mtd_mod_by_eb(slave->offset, &slave->mtd)) {
|
||||
/* Doesn't start on a boundary of major erase size */
|
||||
- /* FIXME: Let it be writable if it is on a boundary of
|
||||
- * _minor_ erase size though */
|
||||
- slave->mtd.flags &= ~MTD_WRITEABLE;
|
||||
- printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
|
||||
- part->name);
|
||||
+ slave->mtd.flags |= MTD_ERASE_PARTIAL;
|
||||
+ if (((u32) slave->mtd.size) > master->erasesize)
|
||||
+ slave->mtd.flags &= ~MTD_WRITEABLE;
|
||||
+ else
|
||||
+ slave->mtd.erasesize = slave->mtd.size;
|
||||
}
|
||||
if ((slave->mtd.flags & MTD_WRITEABLE) &&
|
||||
- mtd_mod_by_eb(slave->mtd.size, &slave->mtd)) {
|
||||
- slave->mtd.flags &= ~MTD_WRITEABLE;
|
||||
- printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
|
||||
- part->name);
|
||||
+ mtd_mod_by_eb(slave->offset + slave->mtd.size, &slave->mtd)) {
|
||||
+ slave->mtd.flags |= MTD_ERASE_PARTIAL;
|
||||
+
|
||||
+ if ((u32) slave->mtd.size > master->erasesize)
|
||||
+ slave->mtd.flags &= ~MTD_WRITEABLE;
|
||||
+ else
|
||||
+ slave->mtd.erasesize = slave->mtd.size;
|
||||
}
|
||||
+ if ((slave->mtd.flags & (MTD_ERASE_PARTIAL|MTD_WRITEABLE)) == MTD_ERASE_PARTIAL)
|
||||
+ printk(KERN_WARNING"mtd: partition \"%s\" must either start or end on erase block boundary or be smaller than an erase block -- forcing read-only\n",
|
||||
+ part->name);
|
||||
|
||||
slave->mtd.ecclayout = master->ecclayout;
|
||||
slave->mtd.ecc_strength = master->ecc_strength;
|
||||
--- a/include/linux/mtd/mtd.h
|
||||
+++ b/include/linux/mtd/mtd.h
|
||||
@@ -58,6 +58,10 @@ struct erase_info {
|
||||
u_long priv;
|
||||
u_char state;
|
||||
struct erase_info *next;
|
||||
+
|
||||
+ u8 *erase_buf;
|
||||
+ u32 erase_buf_ofs;
|
||||
+ bool partial_start;
|
||||
};
|
||||
|
||||
struct mtd_erase_region_info {
|
@ -1,18 +0,0 @@
|
||||
--- a/include/linux/mtd/partitions.h
|
||||
+++ b/include/linux/mtd/partitions.h
|
||||
@@ -35,6 +35,7 @@
|
||||
* Note: writeable partitions require their size and offset be
|
||||
* erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
|
||||
*/
|
||||
+struct mtd_info;
|
||||
|
||||
struct mtd_partition;
|
||||
struct mtd_partition {
|
||||
@@ -52,7 +53,6 @@ struct mtd_partition {
|
||||
#define MTDPART_SIZ_FULL (0)
|
||||
|
||||
|
||||
-struct mtd_info;
|
||||
struct device_node;
|
||||
|
||||
/**
|
@ -1,30 +0,0 @@
|
||||
--- a/drivers/mtd/redboot.c
|
||||
+++ b/drivers/mtd/redboot.c
|
||||
@@ -265,14 +265,21 @@ static int parse_redboot_partitions(stru
|
||||
#endif
|
||||
names += strlen(names)+1;
|
||||
|
||||
-#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
|
||||
if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) {
|
||||
- i++;
|
||||
- parts[i].offset = parts[i-1].size + parts[i-1].offset;
|
||||
- parts[i].size = fl->next->img->flash_base - parts[i].offset;
|
||||
- parts[i].name = nullname;
|
||||
- }
|
||||
+ if (!strcmp(parts[i].name, "rootfs")) {
|
||||
+ parts[i].size = fl->next->img->flash_base;
|
||||
+ parts[i].size &= ~(master->erasesize - 1);
|
||||
+ parts[i].size -= parts[i].offset;
|
||||
+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
|
||||
+ nrparts--;
|
||||
+ } else {
|
||||
+ i++;
|
||||
+ parts[i].offset = parts[i-1].size + parts[i-1].offset;
|
||||
+ parts[i].size = fl->next->img->flash_base - parts[i].offset;
|
||||
+ parts[i].name = nullname;
|
||||
#endif
|
||||
+ }
|
||||
+ }
|
||||
tmp_fl = fl;
|
||||
fl = fl->next;
|
||||
kfree(tmp_fl);
|
@ -1,35 +0,0 @@
|
||||
--- a/drivers/mtd/Kconfig
|
||||
+++ b/drivers/mtd/Kconfig
|
||||
@@ -156,6 +156,22 @@ config MTD_BCM63XX_PARTS
|
||||
This provides partions parsing for BCM63xx devices with CFE
|
||||
bootloaders.
|
||||
|
||||
+config MTD_MYLOADER_PARTS
|
||||
+ tristate "MyLoader partition parsing"
|
||||
+ depends on ADM5120 || ATHEROS_AR231X || ATHEROS_AR71XX || ATH79
|
||||
+ ---help---
|
||||
+ MyLoader is a bootloader which allows the user to define partitions
|
||||
+ in flash devices, by putting a table in the second erase block
|
||||
+ on the device, similar to a partition table. This table gives the
|
||||
+ offsets and lengths of the user defined partitions.
|
||||
+
|
||||
+ If you need code which can detect and parse these tables, and
|
||||
+ register MTD 'partitions' corresponding to each image detected,
|
||||
+ enable this option.
|
||||
+
|
||||
+ You will still need the parsing functions to be called by the driver
|
||||
+ for your particular device. It won't happen automatically.
|
||||
+
|
||||
comment "User Modules And Translation Layers"
|
||||
|
||||
config MTD_CHAR
|
||||
--- a/drivers/mtd/Makefile
|
||||
+++ b/drivers/mtd/Makefile
|
||||
@@ -12,6 +12,7 @@ obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdli
|
||||
obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
|
||||
obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
|
||||
obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
|
||||
+obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
|
||||
|
||||
# 'Users' - code which presents functionality to userspace.
|
||||
obj-$(CONFIG_MTD_CHAR) += mtdchar.o
|
@ -1,116 +0,0 @@
|
||||
--- a/drivers/mtd/devices/block2mtd.c
|
||||
+++ b/drivers/mtd/devices/block2mtd.c
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
+#include <linux/mtd/partitions.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/slab.h>
|
||||
@@ -208,11 +209,12 @@ static void block2mtd_free_device(struct
|
||||
|
||||
|
||||
/* FIXME: ensure that mtd->size % erase_size == 0 */
|
||||
-static struct block2mtd_dev *add_device(char *devname, int erase_size)
|
||||
+static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname)
|
||||
{
|
||||
const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
|
||||
struct block_device *bdev;
|
||||
struct block2mtd_dev *dev;
|
||||
+ struct mtd_partition *part;
|
||||
char *name;
|
||||
|
||||
if (!devname)
|
||||
@@ -251,13 +253,16 @@ static struct block2mtd_dev *add_device(
|
||||
|
||||
/* Setup the MTD structure */
|
||||
/* make the name contain the block device in */
|
||||
- name = kasprintf(GFP_KERNEL, "block2mtd: %s", devname);
|
||||
+ if (!mtdname)
|
||||
+ mtdname = devname;
|
||||
+ name = kmalloc(strlen(mtdname) + 1, GFP_KERNEL);
|
||||
if (!name)
|
||||
goto devinit_err;
|
||||
|
||||
+ strcpy(name, mtdname);
|
||||
dev->mtd.name = name;
|
||||
|
||||
- dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
|
||||
+ dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK & ~(erase_size - 1);
|
||||
dev->mtd.erasesize = erase_size;
|
||||
dev->mtd.writesize = 1;
|
||||
dev->mtd.writebufsize = PAGE_SIZE;
|
||||
@@ -270,14 +275,17 @@ static struct block2mtd_dev *add_device(
|
||||
dev->mtd.priv = dev;
|
||||
dev->mtd.owner = THIS_MODULE;
|
||||
|
||||
- if (mtd_device_register(&dev->mtd, NULL, 0)) {
|
||||
+ part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);
|
||||
+ part->name = name;
|
||||
+ part->offset = 0;
|
||||
+ part->size = dev->mtd.size;
|
||||
+ if (mtd_device_register(&dev->mtd, part, 1)) {
|
||||
/* Device didn't get added, so free the entry */
|
||||
goto devinit_err;
|
||||
}
|
||||
list_add(&dev->list, &blkmtd_device_list);
|
||||
INFO("mtd%d: [%s] erase_size = %dKiB [%d]", dev->mtd.index,
|
||||
- dev->mtd.name + strlen("block2mtd: "),
|
||||
- dev->mtd.erasesize >> 10, dev->mtd.erasesize);
|
||||
+ mtdname, dev->mtd.erasesize >> 10, dev->mtd.erasesize);
|
||||
return dev;
|
||||
|
||||
devinit_err:
|
||||
@@ -350,9 +358,9 @@ static char block2mtd_paramline[80 + 12]
|
||||
|
||||
static int block2mtd_setup2(const char *val)
|
||||
{
|
||||
- char buf[80 + 12]; /* 80 for device, 12 for erase size */
|
||||
+ char buf[80 + 12 + 80]; /* 80 for device, 12 for erase size, 80 for name */
|
||||
char *str = buf;
|
||||
- char *token[2];
|
||||
+ char *token[3];
|
||||
char *name;
|
||||
size_t erase_size = PAGE_SIZE;
|
||||
int i, ret;
|
||||
@@ -363,7 +371,7 @@ static int block2mtd_setup2(const char *
|
||||
strcpy(str, val);
|
||||
kill_final_newline(str);
|
||||
|
||||
- for (i = 0; i < 2; i++)
|
||||
+ for (i = 0; i < 3; i++)
|
||||
token[i] = strsep(&str, ",");
|
||||
|
||||
if (str)
|
||||
@@ -382,8 +390,10 @@ static int block2mtd_setup2(const char *
|
||||
parse_err("illegal erase size");
|
||||
}
|
||||
}
|
||||
+ if (token[2] && (strlen(token[2]) + 1 > 80))
|
||||
+ parse_err("mtd device name too long");
|
||||
|
||||
- add_device(name, erase_size);
|
||||
+ add_device(name, erase_size, token[2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -417,7 +427,7 @@ static int block2mtd_setup(const char *v
|
||||
|
||||
|
||||
module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200);
|
||||
-MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\"");
|
||||
+MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>[,<name>]]\"");
|
||||
|
||||
static int __init block2mtd_init(void)
|
||||
{
|
||||
--- a/block/partition-generic.c
|
||||
+++ b/block/partition-generic.c
|
||||
@@ -548,6 +548,7 @@ int invalidate_partitions(struct gendisk
|
||||
|
||||
return 0;
|
||||
}
|
||||
+EXPORT_SYMBOL(rescan_partitions);
|
||||
|
||||
unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p)
|
||||
{
|
@ -1,269 +0,0 @@
|
||||
--- a/drivers/mtd/devices/block2mtd.c
|
||||
+++ b/drivers/mtd/devices/block2mtd.c
|
||||
@@ -29,6 +29,8 @@ struct block2mtd_dev {
|
||||
struct block_device *blkdev;
|
||||
struct mtd_info mtd;
|
||||
struct mutex write_mutex;
|
||||
+ rwlock_t bdev_mutex;
|
||||
+ char devname[0];
|
||||
};
|
||||
|
||||
|
||||
@@ -79,6 +81,12 @@ static int block2mtd_erase(struct mtd_in
|
||||
size_t len = instr->len;
|
||||
int err;
|
||||
|
||||
+ read_lock(&dev->bdev_mutex);
|
||||
+ if (!dev->blkdev) {
|
||||
+ err = -EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
instr->state = MTD_ERASING;
|
||||
mutex_lock(&dev->write_mutex);
|
||||
err = _block2mtd_erase(dev, from, len);
|
||||
@@ -90,6 +98,10 @@ static int block2mtd_erase(struct mtd_in
|
||||
instr->state = MTD_ERASE_DONE;
|
||||
|
||||
mtd_erase_callback(instr);
|
||||
+
|
||||
+done:
|
||||
+ read_unlock(&dev->bdev_mutex);
|
||||
+
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -101,7 +113,13 @@ static int block2mtd_read(struct mtd_inf
|
||||
struct page *page;
|
||||
int index = from >> PAGE_SHIFT;
|
||||
int offset = from & (PAGE_SIZE-1);
|
||||
- int cpylen;
|
||||
+ int cpylen, err = 0;
|
||||
+
|
||||
+ read_lock(&dev->bdev_mutex);
|
||||
+ if (!dev->blkdev || (from > mtd->size)) {
|
||||
+ err = -EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
|
||||
while (len) {
|
||||
if ((offset + len) > PAGE_SIZE)
|
||||
@@ -111,8 +129,10 @@ static int block2mtd_read(struct mtd_inf
|
||||
len = len - cpylen;
|
||||
|
||||
page = page_read(dev->blkdev->bd_inode->i_mapping, index);
|
||||
- if (IS_ERR(page))
|
||||
- return PTR_ERR(page);
|
||||
+ if (IS_ERR(page)) {
|
||||
+ err = PTR_ERR(page);
|
||||
+ goto done;
|
||||
+ }
|
||||
|
||||
memcpy(buf, page_address(page) + offset, cpylen);
|
||||
page_cache_release(page);
|
||||
@@ -123,7 +143,10 @@ static int block2mtd_read(struct mtd_inf
|
||||
offset = 0;
|
||||
index++;
|
||||
}
|
||||
- return 0;
|
||||
+
|
||||
+done:
|
||||
+ read_unlock(&dev->bdev_mutex);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -171,13 +194,22 @@ static int block2mtd_write(struct mtd_in
|
||||
size_t *retlen, const u_char *buf)
|
||||
{
|
||||
struct block2mtd_dev *dev = mtd->priv;
|
||||
- int err;
|
||||
+ int err = 0;
|
||||
+
|
||||
+ read_lock(&dev->bdev_mutex);
|
||||
+ if (!dev->blkdev) {
|
||||
+ err = -EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
|
||||
mutex_lock(&dev->write_mutex);
|
||||
err = _block2mtd_write(dev, buf, to, len, retlen);
|
||||
mutex_unlock(&dev->write_mutex);
|
||||
if (err > 0)
|
||||
err = 0;
|
||||
+
|
||||
+done:
|
||||
+ read_unlock(&dev->bdev_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -186,33 +218,110 @@ static int block2mtd_write(struct mtd_in
|
||||
static void block2mtd_sync(struct mtd_info *mtd)
|
||||
{
|
||||
struct block2mtd_dev *dev = mtd->priv;
|
||||
+ read_lock(&dev->bdev_mutex);
|
||||
+ if (dev->blkdev)
|
||||
sync_blockdev(dev->blkdev);
|
||||
+ read_unlock(&dev->bdev_mutex);
|
||||
+
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+static int _open_bdev(struct block2mtd_dev *dev)
|
||||
+{
|
||||
+ const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
|
||||
+ struct block_device *bdev;
|
||||
+
|
||||
+ /* Get a handle on the device */
|
||||
+ bdev = blkdev_get_by_path(dev->devname, mode, dev);
|
||||
+#ifndef MODULE
|
||||
+ if (IS_ERR(bdev)) {
|
||||
+ dev_t devt;
|
||||
+
|
||||
+ /* We might not have rootfs mounted at this point. Try
|
||||
+ to resolve the device name by other means. */
|
||||
+
|
||||
+ devt = name_to_dev_t(dev->devname);
|
||||
+ if (devt)
|
||||
+ bdev = blkdev_get_by_dev(devt, mode, dev);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ if (IS_ERR(bdev)) {
|
||||
+ ERROR("error: cannot open device %s", dev->devname);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ dev->blkdev = bdev;
|
||||
+
|
||||
+ if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
|
||||
+ ERROR("attempting to use an MTD device as a block device");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void _close_bdev(struct block2mtd_dev *dev)
|
||||
+{
|
||||
+ struct block_device *bdev;
|
||||
+
|
||||
+ if (!dev->blkdev)
|
||||
+ return;
|
||||
+
|
||||
+ bdev = dev->blkdev;
|
||||
+ invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, 0, -1);
|
||||
+ blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
|
||||
+ dev->blkdev = NULL;
|
||||
+}
|
||||
+
|
||||
static void block2mtd_free_device(struct block2mtd_dev *dev)
|
||||
{
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
kfree(dev->mtd.name);
|
||||
-
|
||||
- if (dev->blkdev) {
|
||||
- invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
|
||||
- 0, -1);
|
||||
- blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
|
||||
- }
|
||||
-
|
||||
+ _close_bdev(dev);
|
||||
kfree(dev);
|
||||
}
|
||||
|
||||
|
||||
-/* FIXME: ensure that mtd->size % erase_size == 0 */
|
||||
-static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname)
|
||||
+static int block2mtd_refresh(struct mtd_info *mtd)
|
||||
{
|
||||
- const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
|
||||
+ struct block2mtd_dev *dev = mtd->priv;
|
||||
struct block_device *bdev;
|
||||
+ dev_t devt;
|
||||
+ int err = 0;
|
||||
+
|
||||
+ /* no other mtd function can run at this point */
|
||||
+ write_lock(&dev->bdev_mutex);
|
||||
+
|
||||
+ /* get the device number for the whole disk */
|
||||
+ devt = MKDEV(MAJOR(dev->blkdev->bd_dev), 0);
|
||||
+
|
||||
+ /* close the old block device */
|
||||
+ _close_bdev(dev);
|
||||
+
|
||||
+ /* open the whole disk, issue a partition rescan, then */
|
||||
+ bdev = blkdev_get_by_dev(devt, FMODE_WRITE | FMODE_READ, mtd);
|
||||
+ if (!bdev || !bdev->bd_disk)
|
||||
+ err = -EINVAL;
|
||||
+#ifndef CONFIG_MTD_BLOCK2MTD_MODULE
|
||||
+ else
|
||||
+ err = rescan_partitions(bdev->bd_disk, bdev);
|
||||
+#endif
|
||||
+ if (bdev)
|
||||
+ blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
|
||||
+
|
||||
+ /* try to open the partition block device again */
|
||||
+ _open_bdev(dev);
|
||||
+ write_unlock(&dev->bdev_mutex);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+/* FIXME: ensure that mtd->size % erase_size == 0 */
|
||||
+static struct block2mtd_dev *add_device(char *devname, int erase_size, char *mtdname)
|
||||
+{
|
||||
struct block2mtd_dev *dev;
|
||||
struct mtd_partition *part;
|
||||
char *name;
|
||||
@@ -220,36 +329,17 @@ static struct block2mtd_dev *add_device(
|
||||
if (!devname)
|
||||
return NULL;
|
||||
|
||||
- dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL);
|
||||
+ dev = kzalloc(sizeof(struct block2mtd_dev) + strlen(devname) + 1, GFP_KERNEL);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
|
||||
- /* Get a handle on the device */
|
||||
- bdev = blkdev_get_by_path(devname, mode, dev);
|
||||
-#ifndef MODULE
|
||||
- if (IS_ERR(bdev)) {
|
||||
-
|
||||
- /* We might not have rootfs mounted at this point. Try
|
||||
- to resolve the device name by other means. */
|
||||
-
|
||||
- dev_t devt = name_to_dev_t(devname);
|
||||
- if (devt)
|
||||
- bdev = blkdev_get_by_dev(devt, mode, dev);
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
- if (IS_ERR(bdev)) {
|
||||
- ERROR("error: cannot open device %s", devname);
|
||||
- goto devinit_err;
|
||||
- }
|
||||
- dev->blkdev = bdev;
|
||||
+ strcpy(dev->devname, devname);
|
||||
|
||||
- if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
|
||||
- ERROR("attempting to use an MTD device as a block device");
|
||||
+ if (_open_bdev(dev))
|
||||
goto devinit_err;
|
||||
- }
|
||||
|
||||
mutex_init(&dev->write_mutex);
|
||||
+ rwlock_init(&dev->bdev_mutex);
|
||||
|
||||
/* Setup the MTD structure */
|
||||
/* make the name contain the block device in */
|
||||
@@ -274,6 +364,7 @@ static struct block2mtd_dev *add_device(
|
||||
dev->mtd._read = block2mtd_read;
|
||||
dev->mtd.priv = dev;
|
||||
dev->mtd.owner = THIS_MODULE;
|
||||
+ dev->mtd.refresh_device = block2mtd_refresh;
|
||||
|
||||
part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);
|
||||
part->name = name;
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/mtd/devices/block2mtd.c
|
||||
+++ b/drivers/mtd/devices/block2mtd.c
|
||||
@@ -241,6 +241,7 @@ static int _open_bdev(struct block2mtd_d
|
||||
/* We might not have rootfs mounted at this point. Try
|
||||
to resolve the device name by other means. */
|
||||
|
||||
+ wait_for_device_probe();
|
||||
devt = name_to_dev_t(dev->devname);
|
||||
if (devt)
|
||||
bdev = blkdev_get_by_dev(devt, mode, dev);
|
@ -1,37 +0,0 @@
|
||||
---
|
||||
drivers/mtd/nand/plat_nand.c | 13 ++++++++++++-
|
||||
include/linux/mtd/nand.h | 1 +
|
||||
2 files changed, 13 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/include/linux/mtd/nand.h
|
||||
+++ b/include/linux/mtd/nand.h
|
||||
@@ -622,6 +622,7 @@ struct platform_nand_chip {
|
||||
unsigned int options;
|
||||
unsigned int bbt_options;
|
||||
const char **part_probe_types;
|
||||
+ int (*chip_fixup)(struct mtd_info *mtd);
|
||||
};
|
||||
|
||||
/* Keep gcc happy */
|
||||
--- a/drivers/mtd/nand/plat_nand.c
|
||||
+++ b/drivers/mtd/nand/plat_nand.c
|
||||
@@ -98,7 +98,18 @@ static int __devinit plat_nand_probe(str
|
||||
}
|
||||
|
||||
/* Scan to find existence of the device */
|
||||
- if (nand_scan(&data->mtd, pdata->chip.nr_chips)) {
|
||||
+ if (nand_scan_ident(&data->mtd, pdata->chip.nr_chips, NULL)) {
|
||||
+ err = -ENXIO;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (pdata->chip.chip_fixup) {
|
||||
+ err = pdata->chip.chip_fixup(&data->mtd);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (nand_scan_tail(&data->mtd)) {
|
||||
err = -ENXIO;
|
||||
goto out;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
--- a/drivers/mtd/nand/nand_ecc.c
|
||||
+++ b/drivers/mtd/nand/nand_ecc.c
|
||||
@@ -507,8 +507,7 @@ int __nand_correct_data(unsigned char *b
|
||||
if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1)
|
||||
return 1; /* error in ECC data; no action needed */
|
||||
|
||||
- printk(KERN_ERR "uncorrectable error : ");
|
||||
- return -1;
|
||||
+ return -EBADMSG;
|
||||
}
|
||||
EXPORT_SYMBOL(__nand_correct_data);
|
||||
|
@ -1,11 +0,0 @@
|
||||
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
@@ -700,7 +700,7 @@ static int get_chip(struct map_info *map
|
||||
return 0;
|
||||
|
||||
case FL_ERASING:
|
||||
- if (!cfip || !(cfip->EraseSuspend & (0x1|0x2)) ||
|
||||
+ if (1 /* no suspend */ || !cfip || !(cfip->EraseSuspend & (0x1|0x2)) ||
|
||||
!(mode == FL_READY || mode == FL_POINT ||
|
||||
(mode == FL_WRITING && (cfip->EraseSuspend & 0x2))))
|
||||
goto sleep;
|
@ -1,39 +0,0 @@
|
||||
--- a/drivers/mtd/devices/m25p80.c
|
||||
+++ b/drivers/mtd/devices/m25p80.c
|
||||
@@ -45,6 +45,7 @@
|
||||
#define OPCODE_BE_4K 0x20 /* Erase 4KiB block */
|
||||
#define OPCODE_BE_32K 0x52 /* Erase 32KiB block */
|
||||
#define OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */
|
||||
+#define OPCODE_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips*/
|
||||
#define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */
|
||||
#define OPCODE_RDID 0x9f /* Read JEDEC ID */
|
||||
|
||||
@@ -594,6 +595,7 @@ struct flash_info {
|
||||
u16 flags;
|
||||
#define SECT_4K 0x01 /* OPCODE_BE_4K works uniformly */
|
||||
#define M25P_NO_ERASE 0x02 /* No erase command needed */
|
||||
+#define SECT_4K_PMC 0x04 /* OPCODE_BE_4K_PMC works uniformly */
|
||||
};
|
||||
|
||||
#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \
|
||||
@@ -663,6 +665,10 @@ static const struct spi_device_id m25p_i
|
||||
{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
|
||||
{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
|
||||
|
||||
+ /* PMC -- pm25x "blocks" are 32K, sectors are 4K */
|
||||
+ { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
|
||||
+ { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) },
|
||||
+
|
||||
/* Spansion -- single (large) sector size only, at least
|
||||
* for the chips listed here (without boot sectors).
|
||||
*/
|
||||
@@ -899,6 +905,9 @@ static int __devinit m25p_probe(struct s
|
||||
if (info->flags & SECT_4K) {
|
||||
flash->erase_opcode = OPCODE_BE_4K;
|
||||
flash->mtd.erasesize = 4096;
|
||||
+ } else if (info->flags & SECT_4K_PMC) {
|
||||
+ flash->erase_opcode = OPCODE_BE_4K_PMC;
|
||||
+ flash->mtd.erasesize = 4096;
|
||||
} else {
|
||||
flash->erase_opcode = OPCODE_SE;
|
||||
flash->mtd.erasesize = info->sector_size;
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/mtd/devices/m25p80.c
|
||||
+++ b/drivers/mtd/devices/m25p80.c
|
||||
@@ -743,6 +743,7 @@ static const struct spi_device_id m25p_i
|
||||
{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
|
||||
{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
|
||||
{ "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) },
|
||||
+ { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
|
||||
|
||||
/* Catalyst / On Semiconductor -- non-JEDEC */
|
||||
{ "cat25c11", CAT25_INFO( 16, 8, 16, 1) },
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/mtd/devices/m25p80.c
|
||||
+++ b/drivers/mtd/devices/m25p80.c
|
||||
@@ -668,6 +668,7 @@ static const struct spi_device_id m25p_i
|
||||
/* PMC -- pm25x "blocks" are 32K, sectors are 4K */
|
||||
{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
|
||||
{ "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) },
|
||||
+ { "pm25lq032", INFO(0x7F9D46, 0, 64 * 1024, 64, SECT_4K) },
|
||||
|
||||
/* Spansion -- single (large) sector size only, at least
|
||||
* for the chips listed here (without boot sectors).
|
@ -1,18 +0,0 @@
|
||||
From: George Kashperko <george@znau.edu.ua>
|
||||
|
||||
Issue map read after Write Buffer Load command to ensure chip is ready
|
||||
to receive data.
|
||||
Signed-off-by: George Kashperko <george@znau.edu.ua>
|
||||
---
|
||||
drivers/mtd/chips/cfi_cmdset_0002.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
|
||||
@@ -1413,6 +1413,7 @@ static int __xipram do_write_buffer(stru
|
||||
|
||||
/* Write Buffer Load */
|
||||
map_write(map, CMD(0x25), cmd_adr);
|
||||
+ (void) map_read(map, cmd_adr);
|
||||
|
||||
chip->state = FL_WRITING_TO_BUFFER;
|
||||
|
@ -1,41 +0,0 @@
|
||||
--- a/drivers/mtd/devices/Kconfig
|
||||
+++ b/drivers/mtd/devices/Kconfig
|
||||
@@ -110,6 +110,14 @@ config MTD_SPEAR_SMI
|
||||
help
|
||||
This enable SNOR support on SPEAR platforms using SMI controller
|
||||
|
||||
+config M25PXX_PREFER_SMALL_SECTOR_ERASE
|
||||
+ bool "Prefer small sector erase"
|
||||
+ depends on MTD_M25P80
|
||||
+ default y
|
||||
+ help
|
||||
+ This option enables use of the small erase sectors if that is
|
||||
+ supported by the flash chip.
|
||||
+
|
||||
config MTD_SST25L
|
||||
tristate "Support SST25L (non JEDEC) SPI Flash chips"
|
||||
depends on SPI_MASTER
|
||||
--- a/drivers/mtd/devices/m25p80.c
|
||||
+++ b/drivers/mtd/devices/m25p80.c
|
||||
@@ -84,6 +84,12 @@
|
||||
|
||||
#define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16)
|
||||
|
||||
+#ifdef CONFIG_M25PXX_PREFER_SMALL_SECTOR_ERASE
|
||||
+#define PREFER_SMALL_SECTOR_ERASE 1
|
||||
+#else
|
||||
+#define PREFER_SMALL_SECTOR_ERASE 0
|
||||
+#endif
|
||||
+
|
||||
/****************************************************************************/
|
||||
|
||||
struct m25p {
|
||||
@@ -904,7 +910,7 @@ static int __devinit m25p_probe(struct s
|
||||
flash->mtd._write = m25p80_write;
|
||||
|
||||
/* prefer "small sector" erase if possible */
|
||||
- if (info->flags & SECT_4K) {
|
||||
+ if (PREFER_SMALL_SECTOR_ERASE && (info->flags & SECT_4K)) {
|
||||
flash->erase_opcode = OPCODE_BE_4K;
|
||||
flash->mtd.erasesize = 4096;
|
||||
} else if (info->flags & SECT_4K_PMC) {
|
@ -1,10 +0,0 @@
|
||||
--- a/drivers/mtd/devices/m25p80.c
|
||||
+++ b/drivers/mtd/devices/m25p80.c
|
||||
@@ -646,6 +646,7 @@ static const struct spi_device_id m25p_i
|
||||
{ "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) },
|
||||
{ "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) },
|
||||
{ "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
|
||||
+ { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
|
||||
|
||||
/* Everspin */
|
||||
{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2) },
|
@ -1,18 +0,0 @@
|
||||
--- a/drivers/mtd/mtdpart.c
|
||||
+++ b/drivers/mtd/mtdpart.c
|
||||
@@ -330,7 +330,14 @@ static int part_lock(struct mtd_info *mt
|
||||
static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
||||
{
|
||||
struct mtd_part *part = PART(mtd);
|
||||
- return part->master->_unlock(part->master, ofs + part->offset, len);
|
||||
+
|
||||
+ ofs += part->offset;
|
||||
+ if (mtd->flags & MTD_ERASE_PARTIAL) {
|
||||
+ /* round up len to next erasesize and round down offset to prev block */
|
||||
+ len = (mtd_div_by_eb(len, part->master) + 1) * part->master->erasesize;
|
||||
+ ofs &= ~(part->master->erasesize - 1);
|
||||
+ }
|
||||
+ return part->master->_unlock(part->master, ofs, len);
|
||||
}
|
||||
|
||||
static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
|
@ -1,25 +0,0 @@
|
||||
From f31b7c0efa255dd17a5f584022a319387f09b0d8 Mon Sep 17 00:00:00 2001
|
||||
From: Jonas Gorski <jonas.gorski@gmail.com>
|
||||
Date: Tue, 12 Apr 2011 19:55:41 +0200
|
||||
Subject: [PATCH] squashfs: update xz compressor options struct.
|
||||
|
||||
Update the xz compressor options struct to match the squashfs userspace
|
||||
one.
|
||||
---
|
||||
fs/squashfs/xz_wrapper.c | 4 +++-
|
||||
1 files changed, 3 insertions(+), 1 deletions(-)
|
||||
|
||||
--- a/fs/squashfs/xz_wrapper.c
|
||||
+++ b/fs/squashfs/xz_wrapper.c
|
||||
@@ -39,8 +39,10 @@ struct squashfs_xz {
|
||||
};
|
||||
|
||||
struct comp_opts {
|
||||
- __le32 dictionary_size;
|
||||
__le32 flags;
|
||||
+ __le16 bit_opts;
|
||||
+ __le16 fb;
|
||||
+ __le32 dictionary_size;
|
||||
};
|
||||
|
||||
static void *squashfs_xz_init(struct squashfs_sb_info *msblk, void *buff,
|
File diff suppressed because it is too large
Load Diff
@ -1,485 +0,0 @@
|
||||
--- a/include/linux/lzma/LzmaDec.h
|
||||
+++ b/include/linux/lzma/LzmaDec.h
|
||||
@@ -31,14 +31,6 @@ typedef struct _CLzmaProps
|
||||
UInt32 dicSize;
|
||||
} CLzmaProps;
|
||||
|
||||
-/* LzmaProps_Decode - decodes properties
|
||||
-Returns:
|
||||
- SZ_OK
|
||||
- SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
-*/
|
||||
-
|
||||
-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
|
||||
-
|
||||
|
||||
/* ---------- LZMA Decoder state ---------- */
|
||||
|
||||
@@ -70,8 +62,6 @@ typedef struct
|
||||
|
||||
#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
|
||||
|
||||
-void LzmaDec_Init(CLzmaDec *p);
|
||||
-
|
||||
/* There are two types of LZMA streams:
|
||||
0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
|
||||
1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
|
||||
@@ -108,97 +98,6 @@ typedef enum
|
||||
|
||||
/* ELzmaStatus is used only as output value for function call */
|
||||
|
||||
-
|
||||
-/* ---------- Interfaces ---------- */
|
||||
-
|
||||
-/* There are 3 levels of interfaces:
|
||||
- 1) Dictionary Interface
|
||||
- 2) Buffer Interface
|
||||
- 3) One Call Interface
|
||||
- You can select any of these interfaces, but don't mix functions from different
|
||||
- groups for same object. */
|
||||
-
|
||||
-
|
||||
-/* There are two variants to allocate state for Dictionary Interface:
|
||||
- 1) LzmaDec_Allocate / LzmaDec_Free
|
||||
- 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
|
||||
- You can use variant 2, if you set dictionary buffer manually.
|
||||
- For Buffer Interface you must always use variant 1.
|
||||
-
|
||||
-LzmaDec_Allocate* can return:
|
||||
- SZ_OK
|
||||
- SZ_ERROR_MEM - Memory allocation error
|
||||
- SZ_ERROR_UNSUPPORTED - Unsupported properties
|
||||
-*/
|
||||
-
|
||||
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
|
||||
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
|
||||
-
|
||||
-SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
|
||||
-void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
|
||||
-
|
||||
-/* ---------- Dictionary Interface ---------- */
|
||||
-
|
||||
-/* You can use it, if you want to eliminate the overhead for data copying from
|
||||
- dictionary to some other external buffer.
|
||||
- You must work with CLzmaDec variables directly in this interface.
|
||||
-
|
||||
- STEPS:
|
||||
- LzmaDec_Constr()
|
||||
- LzmaDec_Allocate()
|
||||
- for (each new stream)
|
||||
- {
|
||||
- LzmaDec_Init()
|
||||
- while (it needs more decompression)
|
||||
- {
|
||||
- LzmaDec_DecodeToDic()
|
||||
- use data from CLzmaDec::dic and update CLzmaDec::dicPos
|
||||
- }
|
||||
- }
|
||||
- LzmaDec_Free()
|
||||
-*/
|
||||
-
|
||||
-/* LzmaDec_DecodeToDic
|
||||
-
|
||||
- The decoding to internal dictionary buffer (CLzmaDec::dic).
|
||||
- You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
|
||||
-
|
||||
-finishMode:
|
||||
- It has meaning only if the decoding reaches output limit (dicLimit).
|
||||
- LZMA_FINISH_ANY - Decode just dicLimit bytes.
|
||||
- LZMA_FINISH_END - Stream must be finished after dicLimit.
|
||||
-
|
||||
-Returns:
|
||||
- SZ_OK
|
||||
- status:
|
||||
- LZMA_STATUS_FINISHED_WITH_MARK
|
||||
- LZMA_STATUS_NOT_FINISHED
|
||||
- LZMA_STATUS_NEEDS_MORE_INPUT
|
||||
- LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
|
||||
- SZ_ERROR_DATA - Data error
|
||||
-*/
|
||||
-
|
||||
-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
|
||||
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
-
|
||||
-
|
||||
-/* ---------- Buffer Interface ---------- */
|
||||
-
|
||||
-/* It's zlib-like interface.
|
||||
- See LzmaDec_DecodeToDic description for information about STEPS and return results,
|
||||
- but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
|
||||
- to work with CLzmaDec variables manually.
|
||||
-
|
||||
-finishMode:
|
||||
- It has meaning only if the decoding reaches output limit (*destLen).
|
||||
- LZMA_FINISH_ANY - Decode just destLen bytes.
|
||||
- LZMA_FINISH_END - Stream must be finished after (*destLen).
|
||||
-*/
|
||||
-
|
||||
-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
|
||||
- const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
|
||||
-
|
||||
-
|
||||
/* ---------- One Call Interface ---------- */
|
||||
|
||||
/* LzmaDecode
|
||||
--- a/lib/lzma/LzmaDec.c
|
||||
+++ b/lib/lzma/LzmaDec.c
|
||||
@@ -682,7 +682,7 @@ static void LzmaDec_InitRc(CLzmaDec *p,
|
||||
p->needFlush = 0;
|
||||
}
|
||||
|
||||
-void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
||||
+static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
|
||||
{
|
||||
p->needFlush = 1;
|
||||
p->remainLen = 0;
|
||||
@@ -698,7 +698,7 @@ void LzmaDec_InitDicAndState(CLzmaDec *p
|
||||
p->needInitState = 1;
|
||||
}
|
||||
|
||||
-void LzmaDec_Init(CLzmaDec *p)
|
||||
+static void LzmaDec_Init(CLzmaDec *p)
|
||||
{
|
||||
p->dicPos = 0;
|
||||
LzmaDec_InitDicAndState(p, True, True);
|
||||
@@ -716,7 +716,7 @@ static void LzmaDec_InitStateReal(CLzmaD
|
||||
p->needInitState = 0;
|
||||
}
|
||||
|
||||
-SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
|
||||
+static SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
|
||||
ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT inSize = *srcLen;
|
||||
@@ -837,7 +837,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, Si
|
||||
return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
|
||||
}
|
||||
|
||||
-SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
+static __maybe_unused SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
|
||||
{
|
||||
SizeT outSize = *destLen;
|
||||
SizeT inSize = *srcLen;
|
||||
@@ -877,7 +877,7 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, By
|
||||
}
|
||||
}
|
||||
|
||||
-void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
|
||||
+static void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->probs);
|
||||
p->probs = 0;
|
||||
@@ -889,13 +889,13 @@ static void LzmaDec_FreeDict(CLzmaDec *p
|
||||
p->dic = 0;
|
||||
}
|
||||
|
||||
-void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
|
||||
+static void __maybe_unused LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
|
||||
{
|
||||
LzmaDec_FreeProbs(p, alloc);
|
||||
LzmaDec_FreeDict(p, alloc);
|
||||
}
|
||||
|
||||
-SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
|
||||
+static SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
|
||||
{
|
||||
UInt32 dicSize;
|
||||
Byte d;
|
||||
@@ -935,7 +935,7 @@ static SRes LzmaDec_AllocateProbs2(CLzma
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
-SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
|
||||
+static SRes __maybe_unused LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
|
||||
{
|
||||
CLzmaProps propNew;
|
||||
RINOK(LzmaProps_Decode(&propNew, props, propsSize));
|
||||
@@ -944,7 +944,7 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p,
|
||||
return SZ_OK;
|
||||
}
|
||||
|
||||
-SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
|
||||
+static SRes __maybe_unused LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
|
||||
{
|
||||
CLzmaProps propNew;
|
||||
SizeT dicBufSize;
|
||||
--- a/include/linux/lzma/LzmaEnc.h
|
||||
+++ b/include/linux/lzma/LzmaEnc.h
|
||||
@@ -31,9 +31,6 @@ typedef struct _CLzmaEncProps
|
||||
} CLzmaEncProps;
|
||||
|
||||
void LzmaEncProps_Init(CLzmaEncProps *p);
|
||||
-void LzmaEncProps_Normalize(CLzmaEncProps *p);
|
||||
-UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
|
||||
-
|
||||
|
||||
/* ---------- CLzmaEncHandle Interface ---------- */
|
||||
|
||||
@@ -53,26 +50,9 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc *
|
||||
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
|
||||
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
|
||||
-SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
|
||||
- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
|
||||
-/* ---------- One Call Interface ---------- */
|
||||
-
|
||||
-/* LzmaEncode
|
||||
-Return code:
|
||||
- SZ_OK - OK
|
||||
- SZ_ERROR_MEM - Memory allocation error
|
||||
- SZ_ERROR_PARAM - Incorrect paramater
|
||||
- SZ_ERROR_OUTPUT_EOF - output buffer overflow
|
||||
- SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
|
||||
-*/
|
||||
-
|
||||
-SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
- const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||
- ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
|
||||
-
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
--- a/lib/lzma/LzmaEnc.c
|
||||
+++ b/lib/lzma/LzmaEnc.c
|
||||
@@ -53,7 +53,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p)
|
||||
p->writeEndMark = 0;
|
||||
}
|
||||
|
||||
-void LzmaEncProps_Normalize(CLzmaEncProps *p)
|
||||
+static void LzmaEncProps_Normalize(CLzmaEncProps *p)
|
||||
{
|
||||
int level = p->level;
|
||||
if (level < 0) level = 5;
|
||||
@@ -76,7 +76,7 @@ void LzmaEncProps_Normalize(CLzmaEncProp
|
||||
#endif
|
||||
}
|
||||
|
||||
-UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
|
||||
+static UInt32 __maybe_unused LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
|
||||
{
|
||||
CLzmaEncProps props = *props2;
|
||||
LzmaEncProps_Normalize(&props);
|
||||
@@ -93,7 +93,7 @@ UInt32 LzmaEncProps_GetDictSize(const CL
|
||||
|
||||
#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
|
||||
|
||||
-UInt32 GetPosSlot1(UInt32 pos)
|
||||
+static UInt32 GetPosSlot1(UInt32 pos)
|
||||
{
|
||||
UInt32 res;
|
||||
BSR2_RET(pos, res);
|
||||
@@ -107,7 +107,7 @@ UInt32 GetPosSlot1(UInt32 pos)
|
||||
#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
|
||||
#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
|
||||
|
||||
-void LzmaEnc_FastPosInit(Byte *g_FastPos)
|
||||
+static void LzmaEnc_FastPosInit(Byte *g_FastPos)
|
||||
{
|
||||
int c = 2, slotFast;
|
||||
g_FastPos[0] = 0;
|
||||
@@ -339,7 +339,7 @@ typedef struct
|
||||
CSaveState saveState;
|
||||
} CLzmaEnc;
|
||||
|
||||
-void LzmaEnc_SaveState(CLzmaEncHandle pp)
|
||||
+static void __maybe_unused LzmaEnc_SaveState(CLzmaEncHandle pp)
|
||||
{
|
||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||
CSaveState *dest = &p->saveState;
|
||||
@@ -365,7 +365,7 @@ void LzmaEnc_SaveState(CLzmaEncHandle pp
|
||||
memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
|
||||
}
|
||||
|
||||
-void LzmaEnc_RestoreState(CLzmaEncHandle pp)
|
||||
+static void __maybe_unused LzmaEnc_RestoreState(CLzmaEncHandle pp)
|
||||
{
|
||||
CLzmaEnc *dest = (CLzmaEnc *)pp;
|
||||
const CSaveState *p = &dest->saveState;
|
||||
@@ -600,7 +600,7 @@ static void LitEnc_EncodeMatched(CRangeE
|
||||
while (symbol < 0x10000);
|
||||
}
|
||||
|
||||
-void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
|
||||
+static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
|
||||
@@ -1676,7 +1676,7 @@ static void FillDistancesPrices(CLzmaEnc
|
||||
p->matchPriceCount = 0;
|
||||
}
|
||||
|
||||
-void LzmaEnc_Construct(CLzmaEnc *p)
|
||||
+static void LzmaEnc_Construct(CLzmaEnc *p)
|
||||
{
|
||||
RangeEnc_Construct(&p->rc);
|
||||
MatchFinder_Construct(&p->matchFinderBase);
|
||||
@@ -1709,7 +1709,7 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc *
|
||||
return p;
|
||||
}
|
||||
|
||||
-void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
|
||||
+static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
|
||||
{
|
||||
alloc->Free(alloc, p->litProbs);
|
||||
alloc->Free(alloc, p->saveState.litProbs);
|
||||
@@ -2074,7 +2074,7 @@ SRes LzmaEnc_MemPrepare(CLzmaEncHandle p
|
||||
return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
|
||||
}
|
||||
|
||||
-void LzmaEnc_Finish(CLzmaEncHandle pp)
|
||||
+static void LzmaEnc_Finish(CLzmaEncHandle pp)
|
||||
{
|
||||
#ifndef _7ZIP_ST
|
||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||
@@ -2108,7 +2108,7 @@ static size_t MyWrite(void *pp, const vo
|
||||
}
|
||||
|
||||
|
||||
-UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
|
||||
+static UInt32 __maybe_unused LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
|
||||
{
|
||||
const CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||
return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
|
||||
@@ -2120,7 +2120,7 @@ const Byte *LzmaEnc_GetCurBuf(CLzmaEncHa
|
||||
return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
|
||||
}
|
||||
|
||||
-SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
|
||||
+static SRes __maybe_unused LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
|
||||
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
|
||||
{
|
||||
CLzmaEnc *p = (CLzmaEnc *)pp;
|
||||
@@ -2248,7 +2248,7 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp
|
||||
return res;
|
||||
}
|
||||
|
||||
-SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
+static __maybe_unused SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
|
||||
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
|
||||
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
|
||||
{
|
||||
--- a/include/linux/lzma/LzFind.h
|
||||
+++ b/include/linux/lzma/LzFind.h
|
||||
@@ -55,11 +55,6 @@ typedef struct _CMatchFinder
|
||||
|
||||
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
|
||||
|
||||
-int MatchFinder_NeedMove(CMatchFinder *p);
|
||||
-Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
|
||||
-void MatchFinder_MoveBlock(CMatchFinder *p);
|
||||
-void MatchFinder_ReadIfRequired(CMatchFinder *p);
|
||||
-
|
||||
void MatchFinder_Construct(CMatchFinder *p);
|
||||
|
||||
/* Conditions:
|
||||
@@ -70,12 +65,6 @@ int MatchFinder_Create(CMatchFinder *p,
|
||||
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
|
||||
ISzAlloc *alloc);
|
||||
void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
|
||||
-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
|
||||
-void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
|
||||
-
|
||||
-UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
|
||||
- UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
|
||||
- UInt32 *distances, UInt32 maxLen);
|
||||
|
||||
/*
|
||||
Conditions:
|
||||
@@ -102,12 +91,6 @@ typedef struct _IMatchFinder
|
||||
|
||||
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
|
||||
|
||||
-void MatchFinder_Init(CMatchFinder *p);
|
||||
-UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||
-UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
|
||||
-void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||
-void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
|
||||
-
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
--- a/lib/lzma/LzFind.c
|
||||
+++ b/lib/lzma/LzFind.c
|
||||
@@ -42,12 +42,12 @@ static int LzInWindow_Create(CMatchFinde
|
||||
return (p->bufferBase != 0);
|
||||
}
|
||||
|
||||
-Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
|
||||
-Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
|
||||
+static Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
|
||||
+static Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
|
||||
|
||||
-UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
|
||||
+static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
|
||||
|
||||
-void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
|
||||
+static void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
|
||||
{
|
||||
p->posLimit -= subValue;
|
||||
p->pos -= subValue;
|
||||
@@ -268,7 +268,7 @@ static void MatchFinder_SetLimits(CMatch
|
||||
p->posLimit = p->pos + limit;
|
||||
}
|
||||
|
||||
-void MatchFinder_Init(CMatchFinder *p)
|
||||
+static void MatchFinder_Init(CMatchFinder *p)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < p->hashSizeSum; i++)
|
||||
@@ -287,7 +287,7 @@ static UInt32 MatchFinder_GetSubValue(CM
|
||||
return (p->pos - p->historySize - 1) & kNormalizeMask;
|
||||
}
|
||||
|
||||
-void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
|
||||
+static void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < numItems; i++)
|
||||
@@ -350,7 +350,7 @@ static UInt32 * Hc_GetMatchesSpec(UInt32
|
||||
}
|
||||
}
|
||||
|
||||
-UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
+static UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
|
||||
UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
|
||||
UInt32 *distances, UInt32 maxLen)
|
||||
{
|
||||
@@ -492,7 +492,7 @@ static UInt32 Bt2_MatchFinder_GetMatches
|
||||
GET_MATCHES_FOOTER(offset, 1)
|
||||
}
|
||||
|
||||
-UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
+static __maybe_unused UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 offset;
|
||||
GET_MATCHES_HEADER(3)
|
||||
@@ -632,7 +632,7 @@ static UInt32 Hc4_MatchFinder_GetMatches
|
||||
MOVE_POS_RET
|
||||
}
|
||||
|
||||
-UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
+static __maybe_unused UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
|
||||
{
|
||||
UInt32 offset;
|
||||
GET_MATCHES_HEADER(3)
|
||||
@@ -657,7 +657,7 @@ static void Bt2_MatchFinder_Skip(CMatchF
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
-void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
+static __maybe_unused void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -718,7 +718,7 @@ static void Hc4_MatchFinder_Skip(CMatchF
|
||||
while (--num != 0);
|
||||
}
|
||||
|
||||
-void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
+static __maybe_unused void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
|
||||
{
|
||||
do
|
||||
{
|
@ -1,53 +0,0 @@
|
||||
--- a/fs/jffs2/build.c
|
||||
+++ b/fs/jffs2/build.c
|
||||
@@ -114,6 +114,16 @@ static int jffs2_build_filesystem(struct
|
||||
dbg_fsbuild("scanned flash completely\n");
|
||||
jffs2_dbg_dump_block_lists_nolock(c);
|
||||
|
||||
+ if (c->flags & (1 << 7)) {
|
||||
+ printk("%s(): unlocking the mtd device... ", __func__);
|
||||
+ mtd_unlock(c->mtd, 0, c->mtd->size);
|
||||
+ printk("done.\n");
|
||||
+
|
||||
+ printk("%s(): erasing all blocks after the end marker... ", __func__);
|
||||
+ jffs2_erase_pending_blocks(c, -1);
|
||||
+ printk("done.\n");
|
||||
+ }
|
||||
+
|
||||
dbg_fsbuild("pass 1 starting\n");
|
||||
c->flags |= JFFS2_SB_FLAG_BUILDING;
|
||||
/* Now scan the directory tree, increasing nlink according to every dirent found. */
|
||||
--- a/fs/jffs2/scan.c
|
||||
+++ b/fs/jffs2/scan.c
|
||||
@@ -148,8 +148,11 @@ int jffs2_scan_medium(struct jffs2_sb_in
|
||||
/* reset summary info for next eraseblock scan */
|
||||
jffs2_sum_reset_collected(s);
|
||||
|
||||
- ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
|
||||
- buf_size, s);
|
||||
+ if (c->flags & (1 << 7))
|
||||
+ ret = BLK_STATE_ALLFF;
|
||||
+ else
|
||||
+ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
|
||||
+ buf_size, s);
|
||||
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@@ -556,6 +559,17 @@ static int jffs2_scan_eraseblock (struct
|
||||
return err;
|
||||
}
|
||||
|
||||
+ if ((buf[0] == 0xde) &&
|
||||
+ (buf[1] == 0xad) &&
|
||||
+ (buf[2] == 0xc0) &&
|
||||
+ (buf[3] == 0xde)) {
|
||||
+ /* end of filesystem. erase everything after this point */
|
||||
+ printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset);
|
||||
+ c->flags |= (1 << 7);
|
||||
+
|
||||
+ return BLK_STATE_ALLFF;
|
||||
+ }
|
||||
+
|
||||
/* We temporarily use 'ofs' as a pointer into the buffer/jeb */
|
||||
ofs = 0;
|
||||
max_ofs = EMPTY_SCAN_SIZE(c->sector_size);
|
@ -1,146 +0,0 @@
|
||||
--- a/crypto/Kconfig
|
||||
+++ b/crypto/Kconfig
|
||||
@@ -1008,6 +1008,13 @@ config CRYPTO_LZO
|
||||
help
|
||||
This is the LZO algorithm.
|
||||
|
||||
+config CRYPTO_XZ
|
||||
+ tristate "XZ compression algorithm"
|
||||
+ select CRYPTO_ALGAPI
|
||||
+ select XZ_DEC
|
||||
+ help
|
||||
+ This is the XZ algorithm. Only decompression is supported for now.
|
||||
+
|
||||
comment "Random Number Generation"
|
||||
|
||||
config CRYPTO_ANSI_CPRNG
|
||||
--- a/crypto/Makefile
|
||||
+++ b/crypto/Makefile
|
||||
@@ -82,6 +82,7 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += mich
|
||||
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
|
||||
obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
|
||||
obj-$(CONFIG_CRYPTO_LZO) += lzo.o
|
||||
+obj-$(CONFIG_CRYPTO_XZ) += xz.o
|
||||
obj-$(CONFIG_CRYPTO_RNG2) += rng.o
|
||||
obj-$(CONFIG_CRYPTO_RNG2) += krng.o
|
||||
obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o
|
||||
--- /dev/null
|
||||
+++ b/crypto/xz.c
|
||||
@@ -0,0 +1,117 @@
|
||||
+/*
|
||||
+ * Cryptographic API.
|
||||
+ *
|
||||
+ * XZ decompression support.
|
||||
+ *
|
||||
+ * Copyright (c) 2012 Gabor Juhos <juhosg@openwrt.org>
|
||||
+ *
|
||||
+ * 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.
|
||||
+ *
|
||||
+ */
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/crypto.h>
|
||||
+#include <linux/xz.h>
|
||||
+#include <linux/interrupt.h>
|
||||
+#include <linux/mm.h>
|
||||
+#include <linux/net.h>
|
||||
+
|
||||
+struct xz_comp_ctx {
|
||||
+ struct xz_dec *decomp_state;
|
||||
+ struct xz_buf decomp_buf;
|
||||
+};
|
||||
+
|
||||
+static int crypto_xz_decomp_init(struct xz_comp_ctx *ctx)
|
||||
+{
|
||||
+ ctx->decomp_state = xz_dec_init(XZ_SINGLE, 0);
|
||||
+ if (!ctx->decomp_state)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void crypto_xz_decomp_exit(struct xz_comp_ctx *ctx)
|
||||
+{
|
||||
+ xz_dec_end(ctx->decomp_state);
|
||||
+}
|
||||
+
|
||||
+static int crypto_xz_init(struct crypto_tfm *tfm)
|
||||
+{
|
||||
+ struct xz_comp_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
+
|
||||
+ return crypto_xz_decomp_init(ctx);
|
||||
+}
|
||||
+
|
||||
+static void crypto_xz_exit(struct crypto_tfm *tfm)
|
||||
+{
|
||||
+ struct xz_comp_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
+
|
||||
+ crypto_xz_decomp_exit(ctx);
|
||||
+}
|
||||
+
|
||||
+static int crypto_xz_compress(struct crypto_tfm *tfm, const u8 *src,
|
||||
+ unsigned int slen, u8 *dst, unsigned int *dlen)
|
||||
+{
|
||||
+ return -EOPNOTSUPP;
|
||||
+}
|
||||
+
|
||||
+static int crypto_xz_decompress(struct crypto_tfm *tfm, const u8 *src,
|
||||
+ unsigned int slen, u8 *dst, unsigned int *dlen)
|
||||
+{
|
||||
+ struct xz_comp_ctx *dctx = crypto_tfm_ctx(tfm);
|
||||
+ struct xz_buf *xz_buf = &dctx->decomp_buf;
|
||||
+ int ret;
|
||||
+
|
||||
+ memset(xz_buf, '\0', sizeof(struct xz_buf));
|
||||
+
|
||||
+ xz_buf->in = (u8 *) src;
|
||||
+ xz_buf->in_pos = 0;
|
||||
+ xz_buf->in_size = slen;
|
||||
+ xz_buf->out = (u8 *) dst;
|
||||
+ xz_buf->out_pos = 0;
|
||||
+ xz_buf->out_size = *dlen;
|
||||
+
|
||||
+ ret = xz_dec_run(dctx->decomp_state, xz_buf);
|
||||
+ if (ret != XZ_STREAM_END) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ *dlen = xz_buf->out_pos;
|
||||
+ ret = 0;
|
||||
+
|
||||
+out:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static struct crypto_alg crypto_xz_alg = {
|
||||
+ .cra_name = "xz",
|
||||
+ .cra_flags = CRYPTO_ALG_TYPE_COMPRESS,
|
||||
+ .cra_ctxsize = sizeof(struct xz_comp_ctx),
|
||||
+ .cra_module = THIS_MODULE,
|
||||
+ .cra_list = LIST_HEAD_INIT(crypto_xz_alg.cra_list),
|
||||
+ .cra_init = crypto_xz_init,
|
||||
+ .cra_exit = crypto_xz_exit,
|
||||
+ .cra_u = { .compress = {
|
||||
+ .coa_compress = crypto_xz_compress,
|
||||
+ .coa_decompress = crypto_xz_decompress } }
|
||||
+};
|
||||
+
|
||||
+static int __init crypto_xz_mod_init(void)
|
||||
+{
|
||||
+ return crypto_register_alg(&crypto_xz_alg);
|
||||
+}
|
||||
+
|
||||
+static void __exit crypto_xz_mod_exit(void)
|
||||
+{
|
||||
+ crypto_unregister_alg(&crypto_xz_alg);
|
||||
+}
|
||||
+
|
||||
+module_init(crypto_xz_mod_init);
|
||||
+module_exit(crypto_xz_mod_exit);
|
||||
+
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
+MODULE_DESCRIPTION("Crypto XZ decompression support");
|
||||
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
|
@ -1,92 +0,0 @@
|
||||
--- a/fs/ubifs/Kconfig
|
||||
+++ b/fs/ubifs/Kconfig
|
||||
@@ -5,8 +5,10 @@ config UBIFS_FS
|
||||
select CRYPTO if UBIFS_FS_ADVANCED_COMPR
|
||||
select CRYPTO if UBIFS_FS_LZO
|
||||
select CRYPTO if UBIFS_FS_ZLIB
|
||||
+ select CRYPTO if UBIFS_FS_XZ
|
||||
select CRYPTO_LZO if UBIFS_FS_LZO
|
||||
select CRYPTO_DEFLATE if UBIFS_FS_ZLIB
|
||||
+ select CRYPTO_XZ if UBIFS_FS_XZ
|
||||
depends on MTD_UBI
|
||||
help
|
||||
UBIFS is a file system for flash devices which works on top of UBI.
|
||||
@@ -35,3 +37,12 @@ config UBIFS_FS_ZLIB
|
||||
default y
|
||||
help
|
||||
Zlib compresses better than LZO but it is slower. Say 'Y' if unsure.
|
||||
+
|
||||
+config UBIFS_FS_XZ
|
||||
+ bool "XZ decompression support" if UBIFS_FS_ADVANCED_COMPR
|
||||
+ depends on UBIFS_FS
|
||||
+ default y
|
||||
+ help
|
||||
+ XZ compresses better the ZLIB but it is slower..
|
||||
+ Say 'Y' if unsure.
|
||||
+
|
||||
--- a/fs/ubifs/compress.c
|
||||
+++ b/fs/ubifs/compress.c
|
||||
@@ -71,6 +71,24 @@ static struct ubifs_compressor zlib_comp
|
||||
};
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_UBIFS_FS_XZ
|
||||
+static DEFINE_MUTEX(xz_enc_mutex);
|
||||
+static DEFINE_MUTEX(xz_dec_mutex);
|
||||
+
|
||||
+static struct ubifs_compressor xz_compr = {
|
||||
+ .compr_type = UBIFS_COMPR_XZ,
|
||||
+ .comp_mutex = &xz_enc_mutex,
|
||||
+ .decomp_mutex = &xz_dec_mutex,
|
||||
+ .name = "xz",
|
||||
+ .capi_name = "xz",
|
||||
+};
|
||||
+#else
|
||||
+static struct ubifs_compressor xz_compr = {
|
||||
+ .compr_type = UBIFS_COMPR_XZ,
|
||||
+ .name = "xz",
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
/* All UBIFS compressors */
|
||||
struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];
|
||||
|
||||
@@ -233,9 +251,15 @@ int __init ubifs_compressors_init(void)
|
||||
if (err)
|
||||
goto out_lzo;
|
||||
|
||||
+ err = compr_init(&xz_compr);
|
||||
+ if (err)
|
||||
+ goto out_zlib;
|
||||
+
|
||||
ubifs_compressors[UBIFS_COMPR_NONE] = &none_compr;
|
||||
return 0;
|
||||
|
||||
+out_zlib:
|
||||
+ compr_exit(&zlib_compr);
|
||||
out_lzo:
|
||||
compr_exit(&lzo_compr);
|
||||
return err;
|
||||
@@ -248,4 +272,5 @@ void ubifs_compressors_exit(void)
|
||||
{
|
||||
compr_exit(&lzo_compr);
|
||||
compr_exit(&zlib_compr);
|
||||
+ compr_exit(&xz_compr);
|
||||
}
|
||||
--- a/fs/ubifs/ubifs-media.h
|
||||
+++ b/fs/ubifs/ubifs-media.h
|
||||
@@ -332,12 +332,14 @@ enum {
|
||||
* UBIFS_COMPR_NONE: no compression
|
||||
* UBIFS_COMPR_LZO: LZO compression
|
||||
* UBIFS_COMPR_ZLIB: ZLIB compression
|
||||
+ * UBIFS_COMPR_XZ: XZ compression
|
||||
* UBIFS_COMPR_TYPES_CNT: count of supported compression types
|
||||
*/
|
||||
enum {
|
||||
UBIFS_COMPR_NONE,
|
||||
UBIFS_COMPR_LZO,
|
||||
UBIFS_COMPR_ZLIB,
|
||||
+ UBIFS_COMPR_XZ,
|
||||
UBIFS_COMPR_TYPES_CNT,
|
||||
};
|
||||
|
@ -1,65 +0,0 @@
|
||||
--- a/fs/ubifs/file.c
|
||||
+++ b/fs/ubifs/file.c
|
||||
@@ -1573,6 +1573,10 @@ const struct inode_operations ubifs_syml
|
||||
.follow_link = ubifs_follow_link,
|
||||
.setattr = ubifs_setattr,
|
||||
.getattr = ubifs_getattr,
|
||||
+ .setxattr = ubifs_setxattr,
|
||||
+ .getxattr = ubifs_getxattr,
|
||||
+ .listxattr = ubifs_listxattr,
|
||||
+ .removexattr = ubifs_removexattr,
|
||||
};
|
||||
|
||||
const struct file_operations ubifs_file_operations = {
|
||||
--- a/fs/ubifs/journal.c
|
||||
+++ b/fs/ubifs/journal.c
|
||||
@@ -553,7 +553,8 @@ int ubifs_jnl_update(struct ubifs_info *
|
||||
|
||||
dbg_jnl("ino %lu, dent '%.*s', data len %d in dir ino %lu",
|
||||
inode->i_ino, nm->len, nm->name, ui->data_len, dir->i_ino);
|
||||
- ubifs_assert(dir_ui->data_len == 0);
|
||||
+ if (!xent)
|
||||
+ ubifs_assert(dir_ui->data_len == 0);
|
||||
ubifs_assert(mutex_is_locked(&dir_ui->ui_mutex));
|
||||
|
||||
dlen = UBIFS_DENT_NODE_SZ + nm->len + 1;
|
||||
@@ -573,6 +574,13 @@ int ubifs_jnl_update(struct ubifs_info *
|
||||
aligned_dlen = ALIGN(dlen, 8);
|
||||
aligned_ilen = ALIGN(ilen, 8);
|
||||
len = aligned_dlen + aligned_ilen + UBIFS_INO_NODE_SZ;
|
||||
+ if (xent) {
|
||||
+ /*
|
||||
+ * Make sure to account for dir_ui->data_len in
|
||||
+ * length calculation in case there is extended attribute.
|
||||
+ */
|
||||
+ len += dir_ui->data_len;
|
||||
+ }
|
||||
dent = kmalloc(len, GFP_NOFS);
|
||||
if (!dent)
|
||||
return -ENOMEM;
|
||||
@@ -649,7 +657,8 @@ int ubifs_jnl_update(struct ubifs_info *
|
||||
|
||||
ino_key_init(c, &ino_key, dir->i_ino);
|
||||
ino_offs += aligned_ilen;
|
||||
- err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs, UBIFS_INO_NODE_SZ);
|
||||
+ err = ubifs_tnc_add(c, &ino_key, lnum, ino_offs,
|
||||
+ UBIFS_INO_NODE_SZ + dir_ui->data_len);
|
||||
if (err)
|
||||
goto out_ro;
|
||||
|
||||
--- a/fs/ubifs/xattr.c
|
||||
+++ b/fs/ubifs/xattr.c
|
||||
@@ -209,12 +209,12 @@ static int change_xattr(struct ubifs_inf
|
||||
goto out_free;
|
||||
}
|
||||
inode->i_size = ui->ui_size = size;
|
||||
- ui->data_len = size;
|
||||
|
||||
mutex_lock(&host_ui->ui_mutex);
|
||||
host->i_ctime = ubifs_current_time(host);
|
||||
host_ui->xattr_size -= CALC_XATTR_BYTES(ui->data_len);
|
||||
host_ui->xattr_size += CALC_XATTR_BYTES(size);
|
||||
+ ui->data_len = size;
|
||||
|
||||
/*
|
||||
* It is important to write the host inode after the xattr inode
|
File diff suppressed because it is too large
Load Diff
@ -1,108 +0,0 @@
|
||||
--- a/include/linux/netfilter/xt_layer7.h
|
||||
+++ b/include/linux/netfilter/xt_layer7.h
|
||||
@@ -8,6 +8,7 @@ struct xt_layer7_info {
|
||||
char protocol[MAX_PROTOCOL_LEN];
|
||||
char pattern[MAX_PATTERN_LEN];
|
||||
u_int8_t invert;
|
||||
+ u_int8_t pkt;
|
||||
};
|
||||
|
||||
#endif /* _XT_LAYER7_H */
|
||||
--- a/net/netfilter/xt_layer7.c
|
||||
+++ b/net/netfilter/xt_layer7.c
|
||||
@@ -314,33 +314,35 @@ static int match_no_append(struct nf_con
|
||||
}
|
||||
|
||||
/* add the new app data to the conntrack. Return number of bytes added. */
|
||||
-static int add_data(struct nf_conn * master_conntrack,
|
||||
- char * app_data, int appdatalen)
|
||||
+static int add_datastr(char *target, int offset, char *app_data, int len)
|
||||
{
|
||||
int length = 0, i;
|
||||
- int oldlength = master_conntrack->layer7.app_data_len;
|
||||
-
|
||||
- /* This is a fix for a race condition by Deti Fliegl. However, I'm not
|
||||
- clear on whether the race condition exists or whether this really
|
||||
- fixes it. I might just be being dense... Anyway, if it's not really
|
||||
- a fix, all it does is waste a very small amount of time. */
|
||||
- if(!master_conntrack->layer7.app_data) return 0;
|
||||
+ if (!target) return 0;
|
||||
|
||||
/* Strip nulls. Make everything lower case (our regex lib doesn't
|
||||
do case insensitivity). Add it to the end of the current data. */
|
||||
- for(i = 0; i < maxdatalen-oldlength-1 &&
|
||||
- i < appdatalen; i++) {
|
||||
+ for(i = 0; i < maxdatalen-offset-1 && i < len; i++) {
|
||||
if(app_data[i] != '\0') {
|
||||
/* the kernel version of tolower mungs 'upper ascii' */
|
||||
- master_conntrack->layer7.app_data[length+oldlength] =
|
||||
+ target[length+offset] =
|
||||
isascii(app_data[i])?
|
||||
tolower(app_data[i]) : app_data[i];
|
||||
length++;
|
||||
}
|
||||
}
|
||||
+ target[length+offset] = '\0';
|
||||
+
|
||||
+ return length;
|
||||
+}
|
||||
+
|
||||
+/* add the new app data to the conntrack. Return number of bytes added. */
|
||||
+static int add_data(struct nf_conn * master_conntrack,
|
||||
+ char * app_data, int appdatalen)
|
||||
+{
|
||||
+ int length;
|
||||
|
||||
- master_conntrack->layer7.app_data[length+oldlength] = '\0';
|
||||
- master_conntrack->layer7.app_data_len = length + oldlength;
|
||||
+ length = add_datastr(master_conntrack->layer7.app_data, master_conntrack->layer7.app_data_len, app_data, appdatalen);
|
||||
+ master_conntrack->layer7.app_data_len += length;
|
||||
|
||||
return length;
|
||||
}
|
||||
@@ -438,7 +440,7 @@ match(const struct sk_buff *skbin,
|
||||
|
||||
enum ip_conntrack_info master_ctinfo, ctinfo;
|
||||
struct nf_conn *master_conntrack, *conntrack;
|
||||
- unsigned char * app_data;
|
||||
+ unsigned char *app_data, *tmp_data;
|
||||
unsigned int pattern_result, appdatalen;
|
||||
regexp * comppattern;
|
||||
|
||||
@@ -466,8 +468,8 @@ match(const struct sk_buff *skbin,
|
||||
master_conntrack = master_ct(master_conntrack);
|
||||
|
||||
/* if we've classified it or seen too many packets */
|
||||
- if(total_acct_packets(master_conntrack) > num_packets ||
|
||||
- master_conntrack->layer7.app_proto) {
|
||||
+ if(!info->pkt && (total_acct_packets(master_conntrack) > num_packets ||
|
||||
+ master_conntrack->layer7.app_proto)) {
|
||||
|
||||
pattern_result = match_no_append(conntrack, master_conntrack,
|
||||
ctinfo, master_ctinfo, info);
|
||||
@@ -500,6 +502,25 @@ match(const struct sk_buff *skbin,
|
||||
/* the return value gets checked later, when we're ready to use it */
|
||||
comppattern = compile_and_cache(info->pattern, info->protocol);
|
||||
|
||||
+ if (info->pkt) {
|
||||
+ tmp_data = kmalloc(maxdatalen, GFP_ATOMIC);
|
||||
+ if(!tmp_data){
|
||||
+ if (net_ratelimit())
|
||||
+ printk(KERN_ERR "layer7: out of memory in match, bailing.\n");
|
||||
+ return info->invert;
|
||||
+ }
|
||||
+
|
||||
+ tmp_data[0] = '\0';
|
||||
+ add_datastr(tmp_data, 0, app_data, appdatalen);
|
||||
+ pattern_result = ((comppattern && regexec(comppattern, tmp_data)) ? 1 : 0);
|
||||
+
|
||||
+ kfree(tmp_data);
|
||||
+ tmp_data = NULL;
|
||||
+ spin_unlock_bh(&l7_lock);
|
||||
+
|
||||
+ return (pattern_result ^ info->invert);
|
||||
+ }
|
||||
+
|
||||
/* On the first packet of a connection, allocate space for app data */
|
||||
if(total_acct_packets(master_conntrack) == 1 && !skb->cb[0] &&
|
||||
!master_conntrack->layer7.app_data){
|
@ -1,51 +0,0 @@
|
||||
--- a/net/netfilter/xt_layer7.c
|
||||
+++ b/net/netfilter/xt_layer7.c
|
||||
@@ -415,7 +415,9 @@ static int layer7_write_proc(struct file
|
||||
}
|
||||
|
||||
static bool
|
||||
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
|
||||
+match(const struct sk_buff *skbin, struct xt_action_param *par)
|
||||
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
|
||||
match(const struct sk_buff *skbin, const struct xt_match_param *par)
|
||||
#else
|
||||
match(const struct sk_buff *skbin,
|
||||
@@ -597,14 +599,19 @@ match(const struct sk_buff *skbin,
|
||||
}
|
||||
|
||||
// load nf_conntrack_ipv4
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
|
||||
+static int
|
||||
+#else
|
||||
+static bool
|
||||
+#endif
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
|
||||
-static bool check(const struct xt_mtchk_param *par)
|
||||
+check(const struct xt_mtchk_param *par)
|
||||
{
|
||||
if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
|
||||
printk(KERN_WARNING "can't load conntrack support for "
|
||||
"proto=%d\n", par->match->family);
|
||||
#else
|
||||
-static bool check(const char *tablename, const void *inf,
|
||||
+check(const char *tablename, const void *inf,
|
||||
const struct xt_match *match, void *matchinfo,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
@@ -612,9 +619,15 @@ static bool check(const char *tablename,
|
||||
printk(KERN_WARNING "can't load conntrack support for "
|
||||
"proto=%d\n", match->family);
|
||||
#endif
|
||||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ return 0;
|
||||
+#else
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
+#endif
|
||||
}
|
||||
|
||||
|
@ -1,61 +0,0 @@
|
||||
--- a/net/netfilter/Kconfig
|
||||
+++ b/net/netfilter/Kconfig
|
||||
@@ -923,6 +923,27 @@ config NETFILTER_XT_MATCH_IPVS
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
+config NETFILTER_XT_MATCH_LAYER7
|
||||
+ tristate '"layer7" match support'
|
||||
+ depends on EXPERIMENTAL
|
||||
+ depends on NETFILTER_XTABLES
|
||||
+ depends on NETFILTER_ADVANCED
|
||||
+ depends on NF_CONNTRACK
|
||||
+ help
|
||||
+ Say Y if you want to be able to classify connections (and their
|
||||
+ packets) based on regular expression matching of their application
|
||||
+ layer data. This is one way to classify applications such as
|
||||
+ peer-to-peer filesharing systems that do not always use the same
|
||||
+ port.
|
||||
+
|
||||
+ To compile it as a module, choose M here. If unsure, say N.
|
||||
+
|
||||
+config NETFILTER_XT_MATCH_LAYER7_DEBUG
|
||||
+ bool 'Layer 7 debugging output'
|
||||
+ depends on NETFILTER_XT_MATCH_LAYER7
|
||||
+ help
|
||||
+ Say Y to get lots of debugging output.
|
||||
+
|
||||
config NETFILTER_XT_MATCH_LENGTH
|
||||
tristate '"length" match support'
|
||||
depends on NETFILTER_ADVANCED
|
||||
@@ -1119,26 +1140,11 @@ config NETFILTER_XT_MATCH_STATE
|
||||
|
||||
To compile it as a module, choose M here. If unsure, say N.
|
||||
|
||||
-config NETFILTER_XT_MATCH_LAYER7
|
||||
- tristate '"layer7" match support'
|
||||
- depends on NETFILTER_XTABLES
|
||||
- depends on EXPERIMENTAL && (IP_NF_CONNTRACK || NF_CONNTRACK)
|
||||
- depends on NETFILTER_ADVANCED
|
||||
- help
|
||||
- Say Y if you want to be able to classify connections (and their
|
||||
- packets) based on regular expression matching of their application
|
||||
- layer data. This is one way to classify applications such as
|
||||
- peer-to-peer filesharing systems that do not always use the same
|
||||
- port.
|
||||
-
|
||||
- To compile it as a module, choose M here. If unsure, say N.
|
||||
-
|
||||
config NETFILTER_XT_MATCH_LAYER7_DEBUG
|
||||
- bool 'Layer 7 debugging output'
|
||||
- depends on NETFILTER_XT_MATCH_LAYER7
|
||||
- help
|
||||
- Say Y to get lots of debugging output.
|
||||
-
|
||||
+ bool 'Layer 7 debugging output'
|
||||
+ depends on NETFILTER_XT_MATCH_LAYER7
|
||||
+ help
|
||||
+ Say Y to get lots of debugging output.
|
||||
|
||||
config NETFILTER_XT_MATCH_STATISTIC
|
||||
tristate '"statistic" match support'
|
@ -1,46 +0,0 @@
|
||||
--- a/net/netfilter/nf_conntrack_standalone.c
|
||||
+++ b/net/netfilter/nf_conntrack_standalone.c
|
||||
@@ -267,10 +267,34 @@ static int ct_open(struct inode *inode,
|
||||
sizeof(struct ct_iter_state));
|
||||
}
|
||||
|
||||
+static int kill_all(struct nf_conn *i, void *data)
|
||||
+{
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static ssize_t ct_file_write(struct file *file, const char __user *buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ struct seq_file *seq = file->private_data;
|
||||
+ struct net *net = seq_file_net(seq);
|
||||
+
|
||||
+ if (count) {
|
||||
+ char c;
|
||||
+
|
||||
+ if (get_user(c, buf))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ if (c == 'f')
|
||||
+ nf_ct_iterate_cleanup(net, kill_all, NULL);
|
||||
+ }
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
static const struct file_operations ct_file_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = ct_open,
|
||||
.read = seq_read,
|
||||
+ .write = ct_file_write,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release_net,
|
||||
};
|
||||
@@ -372,7 +396,7 @@ static int nf_conntrack_standalone_init_
|
||||
{
|
||||
struct proc_dir_entry *pde;
|
||||
|
||||
- pde = proc_net_fops_create(net, "nf_conntrack", 0440, &ct_file_ops);
|
||||
+ pde = proc_net_fops_create(net, "nf_conntrack", 0660, &ct_file_ops);
|
||||
if (!pde)
|
||||
goto out_nf_conntrack;
|
||||
|
@ -1,93 +0,0 @@
|
||||
--- a/include/linux/netfilter_ipv4/ip_tables.h
|
||||
+++ b/include/linux/netfilter_ipv4/ip_tables.h
|
||||
@@ -93,6 +93,7 @@ struct ipt_ip {
|
||||
#define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */
|
||||
#define IPT_F_GOTO 0x02 /* Set if jump is a goto */
|
||||
#define IPT_F_MASK 0x03 /* All possible flag bits mask. */
|
||||
+#define IPT_F_NO_DEF_MATCH 0x80 /* Internal: no default match rules present */
|
||||
|
||||
/* Values for "inv" field in struct ipt_ip. */
|
||||
#define IPT_INV_VIA_IN 0x01 /* Invert the sense of IN IFACE. */
|
||||
--- a/net/ipv4/netfilter/ip_tables.c
|
||||
+++ b/net/ipv4/netfilter/ip_tables.c
|
||||
@@ -81,6 +81,9 @@ ip_packet_match(const struct iphdr *ip,
|
||||
|
||||
#define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg)))
|
||||
|
||||
+ if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
|
||||
+ return true;
|
||||
+
|
||||
if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
|
||||
IPT_INV_SRCIP) ||
|
||||
FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
|
||||
@@ -134,6 +137,29 @@ ip_packet_match(const struct iphdr *ip,
|
||||
return true;
|
||||
}
|
||||
|
||||
+static void
|
||||
+ip_checkdefault(struct ipt_ip *ip)
|
||||
+{
|
||||
+ static const char iface_mask[IFNAMSIZ] = {};
|
||||
+
|
||||
+ if (ip->invflags || ip->flags & IPT_F_FRAG)
|
||||
+ return;
|
||||
+
|
||||
+ if (memcmp(ip->iniface_mask, iface_mask, IFNAMSIZ) != 0)
|
||||
+ return;
|
||||
+
|
||||
+ if (memcmp(ip->outiface_mask, iface_mask, IFNAMSIZ) != 0)
|
||||
+ return;
|
||||
+
|
||||
+ if (ip->smsk.s_addr || ip->dmsk.s_addr)
|
||||
+ return;
|
||||
+
|
||||
+ if (ip->proto)
|
||||
+ return;
|
||||
+
|
||||
+ ip->flags |= IPT_F_NO_DEF_MATCH;
|
||||
+}
|
||||
+
|
||||
static bool
|
||||
ip_checkentry(const struct ipt_ip *ip)
|
||||
{
|
||||
@@ -560,7 +586,7 @@ static void cleanup_match(struct xt_entr
|
||||
}
|
||||
|
||||
static int
|
||||
-check_entry(const struct ipt_entry *e, const char *name)
|
||||
+check_entry(struct ipt_entry *e, const char *name)
|
||||
{
|
||||
const struct xt_entry_target *t;
|
||||
|
||||
@@ -569,6 +595,8 @@ check_entry(const struct ipt_entry *e, c
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ ip_checkdefault(&e->ip);
|
||||
+
|
||||
if (e->target_offset + sizeof(struct xt_entry_target) >
|
||||
e->next_offset)
|
||||
return -EINVAL;
|
||||
@@ -930,6 +958,7 @@ copy_entries_to_user(unsigned int total_
|
||||
const struct xt_table_info *private = table->private;
|
||||
int ret = 0;
|
||||
const void *loc_cpu_entry;
|
||||
+ u8 flags;
|
||||
|
||||
counters = alloc_counters(table);
|
||||
if (IS_ERR(counters))
|
||||
@@ -960,6 +989,14 @@ copy_entries_to_user(unsigned int total_
|
||||
ret = -EFAULT;
|
||||
goto free_counters;
|
||||
}
|
||||
+
|
||||
+ flags = e->ip.flags & IPT_F_MASK;
|
||||
+ if (copy_to_user(userptr + off
|
||||
+ + offsetof(struct ipt_entry, ip.flags),
|
||||
+ &flags, sizeof(flags)) != 0) {
|
||||
+ ret = -EFAULT;
|
||||
+ goto free_counters;
|
||||
+ }
|
||||
|
||||
for (i = sizeof(struct ipt_entry);
|
||||
i < e->target_offset;
|
@ -1,81 +0,0 @@
|
||||
--- a/net/ipv4/netfilter/ip_tables.c
|
||||
+++ b/net/ipv4/netfilter/ip_tables.c
|
||||
@@ -309,6 +309,33 @@ struct ipt_entry *ipt_next_entry(const s
|
||||
return (void *)entry + entry->next_offset;
|
||||
}
|
||||
|
||||
+static bool
|
||||
+ipt_handle_default_rule(struct ipt_entry *e, unsigned int *verdict)
|
||||
+{
|
||||
+ struct xt_entry_target *t;
|
||||
+ struct xt_standard_target *st;
|
||||
+
|
||||
+ if (e->target_offset != sizeof(struct ipt_entry))
|
||||
+ return false;
|
||||
+
|
||||
+ if (!(e->ip.flags & IPT_F_NO_DEF_MATCH))
|
||||
+ return false;
|
||||
+
|
||||
+ t = ipt_get_target(e);
|
||||
+ if (t->u.kernel.target->target)
|
||||
+ return false;
|
||||
+
|
||||
+ st = (struct xt_standard_target *) t;
|
||||
+ if (st->verdict == XT_RETURN)
|
||||
+ return false;
|
||||
+
|
||||
+ if (st->verdict >= 0)
|
||||
+ return false;
|
||||
+
|
||||
+ *verdict = (unsigned)(-st->verdict) - 1;
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
/* Returns one of the generic firewall policies, like NF_ACCEPT. */
|
||||
unsigned int
|
||||
ipt_do_table(struct sk_buff *skb,
|
||||
@@ -333,6 +360,25 @@ ipt_do_table(struct sk_buff *skb,
|
||||
ip = ip_hdr(skb);
|
||||
indev = in ? in->name : nulldevname;
|
||||
outdev = out ? out->name : nulldevname;
|
||||
+
|
||||
+ IP_NF_ASSERT(table->valid_hooks & (1 << hook));
|
||||
+ local_bh_disable();
|
||||
+ addend = xt_write_recseq_begin();
|
||||
+ private = table->private;
|
||||
+ cpu = smp_processor_id();
|
||||
+ table_base = private->entries[cpu];
|
||||
+ jumpstack = (struct ipt_entry **)private->jumpstack[cpu];
|
||||
+ stackptr = per_cpu_ptr(private->stackptr, cpu);
|
||||
+ origptr = *stackptr;
|
||||
+
|
||||
+ e = get_entry(table_base, private->hook_entry[hook]);
|
||||
+ if (ipt_handle_default_rule(e, &verdict)) {
|
||||
+ ADD_COUNTER(e->counters, skb->len, 1);
|
||||
+ xt_write_recseq_end(addend);
|
||||
+ local_bh_enable();
|
||||
+ return verdict;
|
||||
+ }
|
||||
+
|
||||
/* We handle fragments by dealing with the first fragment as
|
||||
* if it was a normal packet. All other fragments are treated
|
||||
* normally, except that they will NEVER match rules that ask
|
||||
@@ -347,18 +393,6 @@ ipt_do_table(struct sk_buff *skb,
|
||||
acpar.family = NFPROTO_IPV4;
|
||||
acpar.hooknum = hook;
|
||||
|
||||
- IP_NF_ASSERT(table->valid_hooks & (1 << hook));
|
||||
- local_bh_disable();
|
||||
- addend = xt_write_recseq_begin();
|
||||
- private = table->private;
|
||||
- cpu = smp_processor_id();
|
||||
- table_base = private->entries[cpu];
|
||||
- jumpstack = (struct ipt_entry **)private->jumpstack[cpu];
|
||||
- stackptr = per_cpu_ptr(private->stackptr, cpu);
|
||||
- origptr = *stackptr;
|
||||
-
|
||||
- e = get_entry(table_base, private->hook_entry[hook]);
|
||||
-
|
||||
pr_debug("Entering %s(hook %u); sp at %u (UF %p)\n",
|
||||
table->name, hook, origptr,
|
||||
get_entry(table_base, private->underflow[hook]));
|
@ -1,16 +0,0 @@
|
||||
--- a/net/ipv4/netfilter/ip_tables.c
|
||||
+++ b/net/ipv4/netfilter/ip_tables.c
|
||||
@@ -84,9 +84,11 @@ ip_packet_match(const struct iphdr *ip,
|
||||
if (ipinfo->flags & IPT_F_NO_DEF_MATCH)
|
||||
return true;
|
||||
|
||||
- if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
|
||||
+ if (FWINV(ipinfo->smsk.s_addr &&
|
||||
+ (ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
|
||||
IPT_INV_SRCIP) ||
|
||||
- FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
|
||||
+ FWINV(ipinfo->dmsk.s_addr &&
|
||||
+ (ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
|
||||
IPT_INV_DSTIP)) {
|
||||
dprintf("Source or dest mismatch.\n");
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user