1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-11-27 17:55:55 +02:00

get rid of linux 2.6.29

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@16883 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
nbd 2009-07-17 16:20:25 +00:00
parent 728cb5fb58
commit fb042825f8
131 changed files with 7 additions and 45677 deletions

View File

@ -23,7 +23,7 @@ JFFS2OPTS := --pad --big-endian --squash
SQUASHFS_OPTS := -be
endif
ifneq ($(CONFIG_LINUX_2_6_29)$(CONFIG_LINUX_2_6_30),)
ifneq ($(CONFIG_LINUX_2_6_30),)
USE_SQUASHFS4 := y
endif

View File

@ -25,9 +25,6 @@ endif
ifeq ($(LINUX_VERSION),2.6.28.10)
LINUX_KERNEL_MD5SUM:=c4efb2c494d749cb5de274f8ae41c3fa
endif
ifeq ($(LINUX_VERSION),2.6.29.6)
LINUX_KERNEL_MD5SUM:=7cd24826fd3c7b0f83d9f662731a7865
endif
ifeq ($(LINUX_VERSION),2.6.30.1)
LINUX_KERNEL_MD5SUM:=7da2e2e31f1c00f2673d2dc50de76b33
endif

View File

@ -45,7 +45,7 @@ endef
define KernelPackage/hostap
$(call KernelPackage/hostap/Default)
TITLE:=Host AP support for Prism2/2.5/3
DEPENDS:=@PCI_SUPPORT||PCMCIA_SUPPORT +!LINUX_2_6_29&&!LINUX_2_6_30:kmod-ieee80211 +LINUX_2_6_29||LINUX_2_6_30:kmod-lib80211 +wireless-tools
DEPENDS:=@PCI_SUPPORT||PCMCIA_SUPPORT +!LINUX_2_6_30:kmod-ieee80211 +LINUX_2_6_30:kmod-lib80211 +wireless-tools
KCONFIG:=CONFIG_HOSTAP CONFIG_HOSTAP_FIRMWARE=y CONFIG_HOSTAP_FIRMWARE_NVRAM=y
PROVIDES:=kmod-hostap
endef

View File

@ -289,7 +289,7 @@ define KernelPackage/tg3
TITLE:=Broadcom Tigon3 Gigabit Ethernet
FILES:=$(LINUX_DIR)/drivers/net/tg3.$(LINUX_KMOD_SUFFIX)
KCONFIG:=CONFIG_TIGON3
DEPENDS:=@LINUX_2_6 +LINUX_2_6_27||LINUX_2_6_28||LINUX_2_6_29||LINUX_2_6_30:kmod-libphy
DEPENDS:=@LINUX_2_6 +LINUX_2_6_27||LINUX_2_6_28||LINUX_2_6_30:kmod-libphy
SUBMENU:=$(NETWORK_DEVICES_MENU)
AUTOLOAD:=$(call AutoLoad,50,tg3)
endef

View File

@ -49,7 +49,7 @@ $(eval $(call KernelPackage,ieee80211))
define KernelPackage/lib80211
SUBMENU:=$(WIRELESS_MENU)
TITLE:=802.11 Networking stack
DEPENDS:=@LINUX_2_6_29||LINUX_2_6_30
DEPENDS:=@LINUX_2_6_30
KCONFIG:= \
CONFIG_LIB80211 \
CONFIG_LIB80211_CRYPT_WEP \
@ -87,7 +87,7 @@ endif
define KernelPackage/net-libipw
SUBMENU:=$(WIRELESS_MENU)
TITLE:=libipw for ipw2100 and ipw2200
DEPENDS:=@PCI_SUPPORT +kmod-crypto-arc4 +kmod-crypto-aes +kmod-crypto-michael-mic +kmod-lib80211 @LINUX_2_6_29||LINUX_2_6_30
DEPENDS:=@PCI_SUPPORT +kmod-crypto-arc4 +kmod-crypto-aes +kmod-crypto-michael-mic +kmod-lib80211 @LINUX_2_6_30
KCONFIG:=CONFIG_LIBIPW
FILES:=$(LINUX_DIR)/drivers/net/wireless/$(IPW_DIR)libipw.$(LINUX_KMOD_SUFFIX)
AUTOLOAD:=$(call AutoLoad,49,libipw)
@ -103,7 +103,7 @@ $(eval $(call KernelPackage,net-libipw))
define KernelPackage/net-ipw2100
SUBMENU:=$(WIRELESS_MENU)
TITLE:=Intel IPW2100 driver
DEPENDS:=@PCI_SUPPORT +!LINUX_2_6_29&&!LINUX_2_6_30:kmod-ieee80211 +LINUX_2_6_29||LINUX_2_6_30:kmod-net-libipw
DEPENDS:=@PCI_SUPPORT +!LINUX_2_6_30:kmod-ieee80211 +LINUX_2_6_30:kmod-net-libipw
KCONFIG:=CONFIG_IPW2100
FILES:=$(LINUX_DIR)/drivers/net/wireless/$(IPW_DIR)ipw2100.$(LINUX_KMOD_SUFFIX)
AUTOLOAD:=$(call AutoLoad,50,ipw2100)
@ -121,7 +121,7 @@ $(eval $(call KernelPackage,net-ipw2100))
define KernelPackage/net-ipw2200
SUBMENU:=$(WIRELESS_MENU)
TITLE:=Intel IPW2200 driver
DEPENDS:=@PCI_SUPPORT +!LINUX_2_6_29&&!LINUX_2_6_30:kmod-ieee80211 +LINUX_2_6_29||LINUX_2_6_30:kmod-net-libipw
DEPENDS:=@PCI_SUPPORT +!LINUX_2_6_30:kmod-ieee80211 +LINUX_2_6_30:kmod-net-libipw
KCONFIG:=CONFIG_IPW2200
FILES:=$(LINUX_DIR)/drivers/net/wireless/$(IPW_DIR)ipw2200.$(LINUX_KMOD_SUFFIX)
AUTOLOAD:=$(call AutoLoad,50,ipw2200)

View File

@ -1,219 +0,0 @@
CONFIG_32BIT=y
# CONFIG_64BIT is not set
CONFIG_ADM6996_PHY=y
CONFIG_AG71XX=y
CONFIG_AG71XX_AR8216_SUPPORT=y
# CONFIG_AG71XX_DEBUG is not set
# CONFIG_AR71XX_EARLY_SERIAL is not set
CONFIG_AR71XX_MACH_AP81=y
CONFIG_AR71XX_MACH_AP83=y
CONFIG_AR71XX_MACH_AW_NR580=y
CONFIG_AR71XX_MACH_GENERIC=y
CONFIG_AR71XX_MACH_MZK_W04NU=y
CONFIG_AR71XX_MACH_MZK_W300NH=y
CONFIG_AR71XX_MACH_PB42=y
CONFIG_AR71XX_MACH_PB44=y
CONFIG_AR71XX_MACH_RB_4XX=y
CONFIG_AR71XX_MACH_TEW_632BRP=y
CONFIG_AR71XX_MACH_TL_WR741ND=y
CONFIG_AR71XX_MACH_TL_WR941ND=y
CONFIG_AR71XX_MACH_UBNT=y
CONFIG_AR71XX_MACH_WNR2000=y
CONFIG_AR71XX_MACH_WP543=y
CONFIG_AR71XX_MACH_WRT160NL=y
CONFIG_AR71XX_MACH_WRT400N=y
CONFIG_AR71XX_WDT=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_ARCH_SUPPORTS_OPROFILE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ATHEROS_AR71XX=y
CONFIG_BASE_SMALL=0
# CONFIG_BCM47XX is not set
CONFIG_BITREVERSE=y
# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
CONFIG_CEVT_R4K=y
CONFIG_CEVT_R4K_LIB=y
CONFIG_CMDLINE="rootfstype=squashfs,yaffs,jffs2 noinitrd console=ttyS0,115200"
CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_CAVIUM_OCTEON is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_CPU_HAS_SYNC=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
# CONFIG_CPU_LOONGSON2 is not set
CONFIG_CPU_MIPS32=y
# CONFIG_CPU_MIPS32_R1 is not set
CONFIG_CPU_MIPS32_R2=y
# CONFIG_CPU_MIPS64_R1 is not set
# CONFIG_CPU_MIPS64_R2 is not set
CONFIG_CPU_MIPSR2=y
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R10000 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_R4300 is not set
# CONFIG_CPU_R4X00 is not set
# CONFIG_CPU_R5000 is not set
# CONFIG_CPU_R5432 is not set
# CONFIG_CPU_R5500 is not set
# CONFIG_CPU_R6000 is not set
# CONFIG_CPU_R8000 is not set
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_TX49XX is not set
# CONFIG_CPU_VR41XX is not set
CONFIG_CSRC_R4K=y
CONFIG_CSRC_R4K_LIB=y
# CONFIG_DCB is not set
CONFIG_DEVPORT=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_DM9000 is not set
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_EARLY_PRINTK=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_GPIO=y
# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
CONFIG_GPIOLIB=y
CONFIG_GPIO_PCF857X=y
CONFIG_GPIO_SYSFS=y
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_HAVE_IDE=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HW_HAS_PCI=y
# CONFIG_HW_RANDOM is not set
CONFIG_I2C=y
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_GPIO=y
CONFIG_ICPLUS_PHY=y
CONFIG_INITRAMFS_ROOT_GID=0
CONFIG_INITRAMFS_ROOT_UID=0
CONFIG_INITRAMFS_SOURCE="../../root"
CONFIG_IRQ_CPU=y
# CONFIG_ISDN is not set
# CONFIG_LEDS_GPIO is not set
# CONFIG_LEMOTE_FULONG is not set
# CONFIG_LIB80211 is not set
# CONFIG_M25PXX_USE_FAST_READ is not set
# CONFIG_MACH_ALCHEMY is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MACH_JAZZ is not set
# CONFIG_MACH_TX39XX is not set
# CONFIG_MACH_TX49XX is not set
# CONFIG_MACH_VR41XX is not set
CONFIG_MICREL_PHY=y
# CONFIG_MIKROTIK_RB532 is not set
CONFIG_MIPS=y
# CONFIG_MIPS_COBALT is not set
# CONFIG_MIPS_FPU_EMU is not set
CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_MIPS_MACHINE=y
# CONFIG_MIPS_MALTA is not set
CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_MT_SMTC is not set
# CONFIG_MIPS_SIM is not set
CONFIG_MISC_FILESYSTEMS=y
CONFIG_MTD_AR91XX_FLASH=y
# CONFIG_MTD_CFI is not set
# CONFIG_MTD_CFI_INTELEXT is not set
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_M25P80=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_RB4XX=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-2
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MYLOADER=y
# CONFIG_NATSEMI is not set
# CONFIG_NEC_MARKEINS is not set
CONFIG_NET_DSA=y
CONFIG_NET_DSA_MV88E6060=y
# CONFIG_NET_DSA_MV88E6123_61_65 is not set
# CONFIG_NET_DSA_MV88E6131 is not set
# CONFIG_NET_DSA_MV88E6XXX is not set
# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
# CONFIG_NET_DSA_TAG_DSA is not set
# CONFIG_NET_DSA_TAG_EDSA is not set
CONFIG_NET_DSA_TAG_TRAILER=y
# CONFIG_NET_SCH_DRR is not set
# CONFIG_NO_IOPORT is not set
# CONFIG_NXP_STB220 is not set
# CONFIG_NXP_STB225 is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
# CONFIG_PCI_STUB is not set
# CONFIG_PCSPKR_PLATFORM is not set
CONFIG_PHYLIB=y
# CONFIG_PMC_MSP is not set
# CONFIG_PMC_YOSEMITE is not set
# CONFIG_PNX8550_JBS is not set
# CONFIG_PNX8550_STB810 is not set
# CONFIG_PROBE_INITRD_HEADER is not set
CONFIG_PROM_EMU=y
CONFIG_SCHED_OMIT_FRAME_POINTER=y
# CONFIG_SCSI_DMA is not set
# CONFIG_SERIAL_8250_EXTENDED is not set
CONFIG_SERIAL_8250_NR_UARTS=1
CONFIG_SERIAL_8250_RUNTIME_UARTS=1
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP28 is not set
# CONFIG_SGI_IP32 is not set
# CONFIG_SIBYTE_BIGSUR is not set
# CONFIG_SIBYTE_CARMEL is not set
# CONFIG_SIBYTE_CRHINE is not set
# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SIBYTE_LITTLESUR is not set
# CONFIG_SIBYTE_RHONE is not set
# CONFIG_SIBYTE_SENTOSA is not set
# CONFIG_SIBYTE_SWARM is not set
# CONFIG_SLAB is not set
CONFIG_SLUB=y
CONFIG_SPI=y
CONFIG_SPI_AP83=y
CONFIG_SPI_AR71XX=y
CONFIG_SPI_BITBANG=y
CONFIG_SPI_GPIO=y
CONFIG_SPI_MASTER=y
CONFIG_SPI_PB44=y
# CONFIG_SPI_SPIDEV is not set
# CONFIG_SPI_VSC7385 is not set
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
CONFIG_SYS_HAS_CPU_MIPS32_R2=y
CONFIG_SYS_HAS_EARLY_PRINTK=y
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
# CONFIG_TC35815 is not set
CONFIG_TICK_ONESHOT=y
CONFIG_TRAD_SIGNALS=y
CONFIG_USB_SUPPORT=y
CONFIG_YAFFS_9BYTE_TAGS=y
CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED=y
CONFIG_YAFFS_AUTO_YAFFS2=y
# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
CONFIG_YAFFS_FS=y
CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
CONFIG_YAFFS_YAFFS1=y
CONFIG_YAFFS_YAFFS2=y
CONFIG_ZONE_DMA_FLAG=0

View File

@ -1,50 +0,0 @@
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -609,6 +609,13 @@ else
load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff81100000
endif
+#
+# Atheros AR71xx
+#
+core-$(CONFIG_ATHEROS_AR71XX) += arch/mips/ar71xx/
+cflags-$(CONFIG_ATHEROS_AR71XX) += -I$(srctree)/arch/mips/include/asm/mach-ar71xx
+load-$(CONFIG_ATHEROS_AR71XX) += 0xffffffff80060000
+
# temporary until string.h is fixed
cflags-y += -ffreestanding
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -22,6 +22,23 @@ choice
config MACH_ALCHEMY
bool "Alchemy processor based machines"
+config ATHEROS_AR71XX
+ bool "Atheros AR71xx based boards"
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select HW_HAS_PCI
+ select IRQ_CPU
+ select ARCH_REQUIRE_GPIOLIB
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_HAS_EARLY_PRINTK
+ select MIPS_MACHINE
+ help
+ Support for Atheros AR71xx based boards.
+
config BASLER_EXCITE
bool "Basler eXcite smart camera"
select CEVT_R4K
@@ -640,6 +657,7 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
endchoice
source "arch/mips/alchemy/Kconfig"
+source "arch/mips/ar71xx/Kconfig"
source "arch/mips/basler/excite/Kconfig"
source "arch/mips/jazz/Kconfig"
source "arch/mips/lasat/Kconfig"

View File

@ -1,10 +0,0 @@
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_PCI_VR41XX) += ops-vr41xx.o
obj-$(CONFIG_NEC_MARKEINS) += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o
obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o
obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
+obj-$(CONFIG_ATHEROS_AR71XX) += pci-ar71xx.o pci-ar724x.o
#
# These are still pretty much in the old state, watch, go blind.

View File

@ -1,58 +0,0 @@
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -81,6 +81,13 @@ config USB_EHCI_BIG_ENDIAN_DESC
depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX)
default y
+config USB_EHCI_AR71XX
+ bool "USB EHCI support for AR71xx"
+ depends on USB_EHCI_HCD && ATHEROS_AR71XX
+ default y
+ help
+ Support for Atheros AR71xx built-in EHCI controller
+
config USB_EHCI_FSL
bool "Support for Freescale on-chip EHCI USB controller"
depends on USB_EHCI_HCD && FSL_SOC
@@ -154,6 +161,13 @@ config USB_OHCI_HCD
To compile this driver as a module, choose M here: the
module will be called ohci-hcd.
+config USB_OHCI_AR71XX
+ bool "USB OHCI support for Atheros AR71xx"
+ depends on USB_OHCI_HCD && ATHEROS_AR71XX
+ default y
+ help
+ Support for Atheros AR71xx built-in OHCI controller
+
config USB_OHCI_HCD_PPC_SOC
bool "OHCI support for on-chip PPC USB controller"
depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1036,6 +1036,11 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ixp4xx_ehci_driver
#endif
+#ifdef CONFIG_USB_EHCI_AR71XX
+#include "ehci-ar71xx.c"
+#define PLATFORM_DRIVER ehci_ar71xx_driver
+#endif
+
#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
!defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER)
#error "missing bus glue for ehci-hcd"
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1080,6 +1080,11 @@ MODULE_LICENSE ("GPL");
#define TMIO_OHCI_DRIVER ohci_hcd_tmio_driver
#endif
+#ifdef CONFIG_USB_OHCI_AR71XX
+#include "ohci-ar71xx.c"
+#define PLATFORM_DRIVER ohci_hcd_ar71xx_driver
+#endif
+
#if !defined(PCI_DRIVER) && \
!defined(PLATFORM_DRIVER) && \
!defined(OF_PLATFORM_DRIVER) && \

View File

@ -1,26 +0,0 @@
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -53,6 +53,13 @@ if SPI_MASTER
comment "SPI Master Controller Drivers"
+config SPI_AR71XX
+ tristate "Atheros AR71xx SPI Controller"
+ depends on SPI_MASTER && ATHEROS_AR71XX
+ select SPI_BITBANG
+ help
+ This is the SPI contoller driver for Atheros AR71xx.
+
config SPI_ATMEL
tristate "Atmel SPI Controller"
depends on (ARCH_AT91 || AVR32)
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -11,6 +11,7 @@ endif
obj-$(CONFIG_SPI_MASTER) += spi.o
# SPI master controller drivers (bus)
+obj-$(CONFIG_SPI_AR71XX) += ar71xx_spi.o
obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o
obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o
obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o

View File

@ -1,21 +0,0 @@
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2068,6 +2068,8 @@ config ACENIC_OMIT_TIGON_I
The safe and default value for this is N.
+source drivers/net/ag71xx/Kconfig
+
config DL2K
tristate "DL2000/TC902x-based Gigabit Ethernet support"
depends on PCI
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -2,6 +2,7 @@
# Makefile for the Linux network (ethercard) device drivers.
#
+obj-$(CONFIG_AG71XX) += ag71xx/
obj-$(CONFIG_E1000) += e1000/
obj-$(CONFIG_E1000E) += e1000e/
obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/

View File

@ -1,26 +0,0 @@
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -766,6 +766,13 @@ config TXX9_WDT
help
Hardware driver for the built-in watchdog timer on TXx9 MIPS SoCs.
+config AR71XX_WDT
+ tristate "Atheros AR71xx Watchdog Timer"
+ depends on ATHEROS_AR71XX
+ help
+ Hardware driver for the built-in watchdog timer on the Atheros
+ AR71xx SoCs.
+
# PARISC Architecture
# POWERPC Architecture
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -107,6 +107,7 @@ obj-$(CONFIG_WDT_RM9K_GPI) += rm9k_wdt.o
obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
+obj-$(CONFIG_AR71XX_WDT) += ar71xx_wdt.o
# PARISC Architecture

View File

@ -1,26 +0,0 @@
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -268,6 +268,13 @@ config MTD_ALCHEMY
help
Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards
+config MTD_AR91XX_FLASH
+ tristate "Atheros AR91xx parallel flash support"
+ depends on ATHEROS_AR71XX
+ select MTD_COMPLEX_MAPPINGS
+ help
+ Parallel flash driver for the Atheros AR91xx based boards.
+
config MTD_DILNETPC
tristate "CFI Flash device mapped on DIL/Net PC"
depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_MTD_DBOX2) += dbox2-flash.
obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
obj-$(CONFIG_MTD_PCI) += pci.o
obj-$(CONFIG_MTD_ALCHEMY) += alchemy-flash.o
+obj-$(CONFIG_MTD_AR91XX_FLASH) += ar91xx_flash.o
obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
obj-$(CONFIG_MTD_EDB7312) += edb7312.o
obj-$(CONFIG_MTD_IMPA7) += impa7.o

View File

@ -1,13 +0,0 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -504,6 +504,10 @@ static struct flash_info __devinitdata m
{ "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, },
{ "at26df321", 0x1f4701, 0, 64 * 1024, 64, SECT_4K, },
+ /* PMC -- pm25x "blocks" are 32K, sectors are 4K */
+ { "pm25lv512", 0, 32 * 1024, 2, SECT_4K },
+ { "pm25lv010", 0, 32 * 1024, 4, SECT_4K },
+
/* Spansion -- single (large) sector size only, at least
* for the chips listed here (without boot sectors).
*/

View File

@ -1,24 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -104,6 +104,11 @@ config AR8216_PHY
tristate "Driver for Atheros AR8216 switches"
select SWCONFIG
+config MICREL_PHY
+ tristate "Drivers for Micrel/Kendin PHYs"
+ ---help---
+ Currently has a driver for the KSZ8041
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_IP175C_PHY) += ip175c.o
obj-$(CONFIG_AR8216_PHY) += ar8216.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
+obj-$(CONFIG_MICREL) += micrel.o
obj-$(CONFIG_FIXED_PHY) += fixed.o
obj-$(CONFIG_MDIO_BITBANG) += mdio-bitbang.o
obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o

View File

@ -1,22 +0,0 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -712,12 +712,17 @@ static int __devinit m25p_probe(struct s
struct mtd_partition *parts = NULL;
int nr_parts = 0;
+ static const char *part_probes[] = {
#ifdef CONFIG_MTD_CMDLINE_PARTS
- static const char *part_probes[] = { "cmdlinepart", NULL, };
+ "cmdlinepart",
+#endif
+#ifdef CONFIG_MTD_MYLOADER_PARTS
+ "MyLoader",
+#endif
+ NULL, };
nr_parts = parse_mtd_partitions(&flash->mtd,
part_probes, &parts, 0);
-#endif
if (nr_parts <= 0 && data && data->parts) {
parts = data->parts;

View File

@ -1,13 +0,0 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -504,6 +504,10 @@ static struct flash_info __devinitdata m
{ "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, },
{ "at26df321", 0x1f4701, 0, 64 * 1024, 64, SECT_4K, },
+ /* EON -- en25pxx */
+ { "en25p32", 0x1c2016, 0, 64 * 1024, 64, },
+ { "en25p64", 0x1c2017, 0, 64 * 1024, 128, },
+
/* PMC -- pm25x "blocks" are 32K, sectors are 4K */
{ "pm25lv512", 0, 32 * 1024, 2, SECT_4K },
{ "pm25lv010", 0, 32 * 1024, 4, SECT_4K },

View File

@ -1,12 +0,0 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -723,6 +723,9 @@ static int __devinit m25p_probe(struct s
#ifdef CONFIG_MTD_MYLOADER_PARTS
"MyLoader",
#endif
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+ "RedBoot",
+#endif
NULL, };
nr_parts = parse_mtd_partitions(&flash->mtd,

View File

@ -1,14 +0,0 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -508,6 +508,11 @@ static struct flash_info __devinitdata m
{ "en25p32", 0x1c2016, 0, 64 * 1024, 64, },
{ "en25p64", 0x1c2017, 0, 64 * 1024, 128, },
+ /* Macronix -- mx25lxxx */
+ { "mx25l32", 0xc22016, 0, 64 * 1024, 64, },
+ { "mx25l64", 0xc22017, 0, 64 * 1024, 128, },
+ { "mx25l128", 0xc22018, 0, 64 * 1024, 256, },
+
/* PMC -- pm25x "blocks" are 32K, sectors are 4K */
{ "pm25lv512", 0, 32 * 1024, 2, SECT_4K },
{ "pm25lv010", 0, 32 * 1024, 4, SECT_4K },

View File

@ -1,14 +0,0 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -513,6 +513,11 @@ static struct flash_info __devinitdata m
{ "mx25l64", 0xc22017, 0, 64 * 1024, 128, },
{ "mx25l128", 0xc22018, 0, 64 * 1024, 256, },
+ /* Numonyx -- xxxs33b */
+ { "160s33b", 0x898911, 0, 64 * 1024, 64, },
+ { "320s33b", 0x898912, 0, 64 * 1024, 128, },
+ { "640s33b", 0x898913, 0, 64 * 1024, 256, },
+
/* PMC -- pm25x "blocks" are 32K, sectors are 4K */
{ "pm25lv512", 0, 32 * 1024, 2, SECT_4K },
{ "pm25lv010", 0, 32 * 1024, 4, SECT_4K },

View File

@ -1,29 +0,0 @@
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -159,6 +159,7 @@
#define SST39LF800 0x2781
#define SST39LF160 0x2782
#define SST39VF1601 0x234b
+#define SST39VF6401B 0x236d
#define SST39LF512 0x00D4
#define SST39LF010 0x00D5
#define SST39LF020 0x00D6
@@ -1502,6 +1503,18 @@ static const struct amd_flash_info jedec
ERASEINFO(0x10000,64),
}
}, {
+ .mfr_id = MANUFACTURER_SST,
+ .dev_id = SST39VF6401B,
+ .name = "SST 39VF6401B",
+ .devtypes = CFI_DEVICETYPE_X16,
+ .uaddr = MTD_UADDR_0xAAAA_0x5555,
+ .dev_size = SIZE_8MiB,
+ .cmd_set = P_ID_AMD_STD,
+ .nr_regions = 1,
+ .regions = {
+ ERASEINFO(0x10000,128)
+ }
+ }, {
.mfr_id = MANUFACTURER_ST,
.dev_id = M29F800AB,
.name = "ST M29F800AB",

View File

@ -1,20 +0,0 @@
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -1568,7 +1568,7 @@ static int __xipram do_erase_chip(struct
chip->erase_suspended = 0;
}
- if (chip_ready(map, adr))
+ if (chip_good(map, adr, map_word_ff(map)))
break;
if (time_after(jiffies, timeo)) {
@@ -1656,7 +1656,7 @@ static int __xipram do_erase_oneblock(st
chip->erase_suspended = 0;
}
- if (chip_ready(map, adr)) {
+ if (chip_good(map, adr, map_word_ff(map))) {
xip_enable(map, chip, adr);
break;
}

View File

@ -1,22 +0,0 @@
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -1082,6 +1082,9 @@ static void end_unlink_async (struct ehc
ehci->reclaim = NULL;
start_unlink_async (ehci, next);
}
+
+ if (ehci->has_synopsys_hc_bug)
+ writel((u32)ehci->async->qh_dma, &ehci->regs->async_next);
}
/* makes sure the async qh will become idle */
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -125,6 +125,7 @@ struct ehci_hcd { /* one per controlle
unsigned big_endian_mmio:1;
unsigned big_endian_desc:1;
unsigned has_amcc_usb23:1;
+ unsigned has_synopsys_hc_bug:1; /* Synopsys HC */
/* required for usb32 quirk */
#define OHCI_CTRL_HCFS (3 << 6)

View File

@ -1,54 +0,0 @@
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -60,31 +60,32 @@ static int parse_redboot_partitions(stru
static char nullstring[] = "unallocated";
#endif
+ buf = vmalloc(master->erasesize);
+ if (!buf)
+ return -ENOMEM;
+
+ restart:
if ( directory < 0 ) {
offset = master->size + directory * master->erasesize;
- while (master->block_isbad &&
+ while (master->block_isbad &&
master->block_isbad(master, offset)) {
if (!offset) {
nogood:
printk(KERN_NOTICE "Failed to find a non-bad block to check for RedBoot partition table\n");
+ vfree(buf);
return -EIO;
}
offset -= master->erasesize;
}
} else {
offset = directory * master->erasesize;
- while (master->block_isbad &&
+ while (master->block_isbad &&
master->block_isbad(master, offset)) {
offset += master->erasesize;
if (offset == master->size)
goto nogood;
}
}
- buf = vmalloc(master->erasesize);
-
- if (!buf)
- return -ENOMEM;
-
printk(KERN_NOTICE "Searching for RedBoot partition table in %s at offset 0x%lx\n",
master->name, offset);
@@ -156,6 +157,11 @@ static int parse_redboot_partitions(stru
}
if (i == numslots) {
/* Didn't find it */
+ if (offset + master->erasesize < master->size) {
+ /* not at the end of the flash yet, maybe next block :) */
+ directory++;
+ goto restart;
+ }
printk(KERN_NOTICE "No RedBoot partition table detected in %s\n",
master->name);
ret = 0;

View File

@ -1,21 +0,0 @@
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -427,4 +427,8 @@ config MTD_NAND_SH_FLCTL
Several Renesas SuperH CPU has FLCTL. This option enables support
for NAND Flash using FLCTL. This driver support SH7723.
+config MTD_NAND_RB4XX
+ tristate "NAND flash driver for RouterBoard 4xx series"
+ depends on MTD_NAND && ATHEROS_AR71XX
+
endif # MTD_NAND
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) +=
obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o
obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o
obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
+obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o
obj-$(CONFIG_MTD_ALAUDA) += alauda.o
obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o
obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o

View File

@ -1,27 +0,0 @@
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -11,6 +11,7 @@ endif
obj-$(CONFIG_SPI_MASTER) += spi.o
# SPI master controller drivers (bus)
+obj-$(CONFIG_SPI_AP83) += ap83_spi.o
obj-$(CONFIG_SPI_AR71XX) += ar71xx_spi.o
obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o
obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -53,6 +53,14 @@ if SPI_MASTER
comment "SPI Master Controller Drivers"
+config SPI_AP83
+ tristate "Atheros AP83 specific SPI Controller"
+ depends on SPI_MASTER && AR71XX_MACH_AP83
+ select SPI_BITBANG
+ help
+ This is a specific SPI controller driver for the Atheros AP83
+ reference board.
+
config SPI_AR71XX
tristate "Atheros AR71xx SPI Controller"
depends on SPI_MASTER && ATHEROS_AR71XX

View File

@ -1,24 +0,0 @@
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -272,6 +272,11 @@ config SPI_TLE62X0
sysfs interface, with each line presented as a kind of GPIO
exposing both switch control and diagnostic feedback.
+config SPI_VSC7385
+ tristate "Vitesse VSC7385 ethernet switch driver"
+ help
+ SPI driver for the Vitesse VSC7385 ethernet switch.
+
#
# Add new SPI protocol masters in alphabetical order above this line
#
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.
# SPI protocol drivers (device/link on bus)
obj-$(CONFIG_SPI_SPIDEV) += spidev.o
+obj-$(CONFIG_SPI_VSC7385) += spi_vsc7385.o
obj-$(CONFIG_SPI_TLE62X0) += tle62x0.o
# ... add above this line ...

View File

@ -1,27 +0,0 @@
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -68,6 +68,14 @@ config SPI_AR71XX
help
This is the SPI contoller driver for Atheros AR71xx.
+config SPI_PB44
+ tristate "Atheros PB44 board specific SPI controller"
+ depends on SPI_MASTER && AR71XX_MACH_PB44
+ select SPI_BITBANG
+ help
+ This is a specific SPI controller driver for the Atheros PB44
+ reference board.
+
config SPI_ATMEL
tristate "Atmel SPI Controller"
depends on (ARCH_AT91 || AVR32)
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_SPI_GPIO) += spi_gpio.o
obj-$(CONFIG_SPI_GPIO_OLD) += spi_gpio_old.o
obj-$(CONFIG_SPI_IMX) += spi_imx.o
obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o
+obj-$(CONFIG_SPI_PB44) += pb44_spi.o
obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o
obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o
obj-$(CONFIG_SPI_OMAP24XX) += omap2_mcspi.o

View File

@ -1,22 +0,0 @@
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -171,6 +171,7 @@ endif
#
libs-$(CONFIG_ARC) += arch/mips/fw/arc/
libs-$(CONFIG_CFE) += arch/mips/fw/cfe/
+libs-$(CONFIG_MYLOADER) += arch/mips/fw/myloader/
libs-$(CONFIG_SNIPROM) += arch/mips/fw/sni/
libs-y += arch/mips/fw/lib/
libs-$(CONFIG_SIBYTE_CFE) += arch/mips/sibyte/cfe/
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -836,6 +836,9 @@ config MIPS_NILE4
config MIPS_DISABLE_OBSOLETE_IDE
bool
+config MYLOADER
+ bool
+
config SYNC_R4K
bool

View File

@ -1,10 +0,0 @@
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -36,6 +36,7 @@ config ATHEROS_AR71XX
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_HAS_EARLY_PRINTK
select MIPS_MACHINE
+ select PROM_EMU
help
Support for Atheros AR71xx based boards.

View File

@ -1,38 +0,0 @@
--- a/drivers/net/ag71xx/ag71xx_main.c
+++ b/drivers/net/ag71xx/ag71xx_main.c
@@ -561,7 +561,7 @@ static void ag71xx_oom_timer_handler(uns
struct net_device *dev = (struct net_device *) data;
struct ag71xx *ag = netdev_priv(dev);
- netif_rx_schedule(dev, &ag->napi);
+ netif_rx_schedule(&ag->napi);
}
static void ag71xx_tx_timeout(struct net_device *dev)
@@ -717,7 +717,7 @@ static int ag71xx_poll(struct napi_struc
DBG("%s: disable polling mode, done=%d, limit=%d\n",
dev->name, done, limit);
- netif_rx_complete(dev, napi);
+ netif_rx_complete(napi);
/* enable interrupts */
spin_lock_irqsave(&ag->lock, flags);
@@ -736,7 +736,7 @@ static int ag71xx_poll(struct napi_struc
printk(KERN_DEBUG "%s: out of memory\n", dev->name);
mod_timer(&ag->oom_timer, jiffies + AG71XX_OOM_REFILL);
- netif_rx_complete(dev, napi);
+ netif_rx_complete(napi);
return 0;
}
@@ -766,7 +766,7 @@ static irqreturn_t ag71xx_interrupt(int
if (likely(status & AG71XX_INT_POLL)) {
ag71xx_int_disable(ag, AG71XX_INT_POLL);
DBG("%s: enable polling mode\n", dev->name);
- netif_rx_schedule(dev, &ag->napi);
+ netif_rx_schedule(&ag->napi);
}
return IRQ_HANDLED;

View File

@ -1,29 +0,0 @@
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -48,6 +48,7 @@
#include <asm/types.h>
#include <asm/stacktrace.h>
#include <asm/irq.h>
+#include <asm/time.h>
extern void check_wait(void);
extern asmlinkage void r4k_wait(void);
@@ -1541,6 +1542,8 @@ void __cpuinit per_cpu_trap_init(void)
*/
if (cpu_has_mips_r2) {
cp0_compare_irq = (read_c0_intctl() >> 29) & 7;
+ if (get_c0_compare_irq)
+ cp0_compare_irq = get_c0_compare_irq();
cp0_perfcount_irq = (read_c0_intctl() >> 26) & 7;
if (cp0_perfcount_irq == cp0_compare_irq)
cp0_perfcount_irq = -1;
--- a/arch/mips/include/asm/time.h
+++ b/arch/mips/include/asm/time.h
@@ -52,6 +52,7 @@ extern int (*perf_irq)(void);
*/
#ifdef CONFIG_CEVT_R4K_LIB
extern unsigned int __weak get_c0_compare_int(void);
+extern unsigned int __weak get_c0_compare_irq(void);
extern int r4k_clockevent_init(void);
#endif

View File

@ -1,56 +0,0 @@
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -15,6 +15,22 @@
#include <asm/cevt-r4k.h>
/*
+ * Compare interrupt can be routed and latched outside the core,
+ * so a single execution hazard barrier may not be enough to give
+ * it time to clear as seen in the Cause register. 4 time the
+ * pipeline depth seems reasonably conservative, and empirically
+ * works better in configurations with high CPU/bus clock ratios.
+ */
+
+#define compare_change_hazard() \
+ do { \
+ irq_disable_hazard(); \
+ irq_disable_hazard(); \
+ irq_disable_hazard(); \
+ irq_disable_hazard(); \
+ } while (0)
+
+/*
* The SMTC Kernel for the 34K, 1004K, et. al. replaces several
* of these routines with SMTC-specific variants.
*/
@@ -30,6 +46,7 @@ static int mips_next_event(unsigned long
cnt = read_c0_count();
cnt += delta;
write_c0_compare(cnt);
+ compare_change_hazard();
res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
return res;
}
@@ -99,22 +116,6 @@ static int c0_compare_int_pending(void)
return (read_c0_cause() >> cp0_compare_irq) & 0x100;
}
-/*
- * Compare interrupt can be routed and latched outside the core,
- * so a single execution hazard barrier may not be enough to give
- * it time to clear as seen in the Cause register. 4 time the
- * pipeline depth seems reasonably conservative, and empirically
- * works better in configurations with high CPU/bus clock ratios.
- */
-
-#define compare_change_hazard() \
- do { \
- irq_disable_hazard(); \
- irq_disable_hazard(); \
- irq_disable_hazard(); \
- irq_disable_hazard(); \
- } while (0)
-
int c0_compare_int_usable(void)
{
unsigned int delta;

File diff suppressed because it is too large Load Diff

View File

@ -1,201 +0,0 @@
/*
* character device wrapper for generic gpio layer
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
*
* Feedback, Bugs... blogic@openwrt.org
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/atomic.h>
#include <linux/init.h>
#include <linux/genhd.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/gpio_dev.h>
#define DRVNAME "gpiodev"
#define DEVNAME "gpio"
static int dev_major;
static unsigned int gpio_access_mask;
static struct class *gpiodev_class;
/* Counter is 1, if the device is not opened and zero (or less) if opened. */
static atomic_t gpio_open_cnt = ATOMIC_INIT(1);
static int
gpio_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
{
int retval = 0;
if (((1 << arg) & gpio_access_mask) != (1 << arg))
{
retval = -EINVAL;
goto out;
}
switch (cmd)
{
case GPIO_GET:
retval = gpio_get_value(arg);
break;
case GPIO_SET:
gpio_set_value(arg, 1);
break;
case GPIO_CLEAR:
gpio_set_value(arg, 0);
break;
case GPIO_DIR_IN:
gpio_direction_input(arg);
break;
case GPIO_DIR_OUT:
gpio_direction_output(arg, 0);
break;
default:
retval = -EINVAL;
break;
}
out:
return retval;
}
static int
gpio_open(struct inode *inode, struct file *file)
{
int result = 0;
unsigned int dev_minor = MINOR(inode->i_rdev);
if (dev_minor != 0)
{
printk(KERN_ERR DRVNAME ": trying to access unknown minor device -> %d\n", dev_minor);
result = -ENODEV;
goto out;
}
/* FIXME: We should really allow multiple applications to open the device
* at the same time, as long as the apps access different IO pins.
* The generic gpio-registration functions can be used for that.
* Two new IOCTLs have to be introduced for that. Need to check userspace
* compatibility first. --mb */
if (!atomic_dec_and_test(&gpio_open_cnt)) {
atomic_inc(&gpio_open_cnt);
printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor);
result = -EBUSY;
goto out;
}
out:
return result;
}
static int
gpio_close(struct inode * inode, struct file * file)
{
smp_mb__before_atomic_inc();
atomic_inc(&gpio_open_cnt);
return 0;
}
struct file_operations gpio_fops = {
ioctl: gpio_ioctl,
open: gpio_open,
release: gpio_close
};
static int
gpio_probe(struct platform_device *dev)
{
int result = 0;
dev_major = register_chrdev(0, DEVNAME, &gpio_fops);
if (!dev_major)
{
printk(KERN_ERR DRVNAME ": Error whilst opening %s \n", DEVNAME);
result = -ENODEV;
goto out;
}
gpiodev_class = class_create(THIS_MODULE, DRVNAME);
device_create(gpiodev_class, NULL, MKDEV(dev_major, 0), dev, DEVNAME);
printk(KERN_INFO DRVNAME ": gpio device registered with major %d\n", dev_major);
if (dev->num_resources != 1)
{
printk(KERN_ERR DRVNAME ": device may only have 1 resource\n");
result = -ENODEV;
goto out;
}
gpio_access_mask = dev->resource[0].start;
printk(KERN_INFO DRVNAME ": gpio platform device registered with access mask %08X\n", gpio_access_mask);
out:
return result;
}
static int
gpio_remove(struct platform_device *dev)
{
unregister_chrdev(dev_major, DEVNAME);
return 0;
}
static struct
platform_driver gpio_driver = {
.probe = gpio_probe,
.remove = gpio_remove,
.driver = {
.name = "GPIODEV",
.owner = THIS_MODULE,
},
};
static int __init
gpio_mod_init(void)
{
int ret = platform_driver_register(&gpio_driver);
if (ret)
printk(KERN_INFO DRVNAME ": Error registering platfom driver!");
return ret;
}
static void __exit
gpio_mod_exit(void)
{
platform_driver_unregister(&gpio_driver);
}
module_init (gpio_mod_init);
module_exit (gpio_mod_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("John Crispin / OpenWrt");
MODULE_DESCRIPTION("Character device for for generic gpio api");

View File

@ -1,209 +0,0 @@
/*
* Driver for buttons on GPIO lines not capable of generating interrupts
*
* Copyright (C) 2007,2008 Gabor Juhos <juhosg at openwrt.org>
*
* This file was based on: /drivers/input/misc/cobalt_btns.c
* Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
*
* also was based on: /drivers/input/keyboard/gpio_keys.c
* Copyright 2005 Phil Blundell
*
* 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/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/gpio_buttons.h>
#include <asm/gpio.h>
#define DRV_NAME "gpio-buttons"
#define DRV_VERSION "0.1.1"
#define PFX DRV_NAME ": "
struct gpio_buttons_dev {
struct input_polled_dev *poll_dev;
struct gpio_buttons_platform_data *pdata;
};
static void gpio_buttons_poll(struct input_polled_dev *dev)
{
struct gpio_buttons_dev *bdev = dev->private;
struct gpio_buttons_platform_data *pdata = bdev->pdata;
struct input_dev *input = dev->input;
int i;
for (i = 0; i < bdev->pdata->nbuttons; i++) {
struct gpio_button *button = &pdata->buttons[i];
unsigned int type = button->type ?: EV_KEY;
int state;
state = gpio_get_value(button->gpio) ? 1 : 0;
state ^= button->active_low;
if (state) {
button->count++;
} else {
if (button->count >= button->threshold) {
input_event(input, type, button->code, 1);
input_sync(input);
}
button->count = 0;
}
if (button->count == button->threshold) {
input_event(input, type, button->code, 0);
input_sync(input);
}
}
}
static int __devinit gpio_buttons_probe(struct platform_device *pdev)
{
struct gpio_buttons_platform_data *pdata = pdev->dev.platform_data;
struct gpio_buttons_dev *bdev;
struct input_polled_dev *poll_dev;
struct input_dev *input;
int error, i;
if (!pdata)
return -ENXIO;
bdev = kzalloc(sizeof(*bdev), GFP_KERNEL);
if (!bdev) {
printk(KERN_ERR DRV_NAME "no memory for device\n");
return -ENOMEM;
}
poll_dev = input_allocate_polled_device();
if (!poll_dev) {
printk(KERN_ERR DRV_NAME "no memory for polled device\n");
error = -ENOMEM;
goto err_free_bdev;
}
poll_dev->private = bdev;
poll_dev->poll = gpio_buttons_poll;
poll_dev->poll_interval = pdata->poll_interval;
input = poll_dev->input;
input->evbit[0] = BIT(EV_KEY);
input->name = pdev->name;
input->phys = "gpio-buttons/input0";
input->dev.parent = &pdev->dev;
input->id.bustype = BUS_HOST;
input->id.vendor = 0x0001;
input->id.product = 0x0001;
input->id.version = 0x0100;
for (i = 0; i < pdata->nbuttons; i++) {
struct gpio_button *button = &pdata->buttons[i];
unsigned int gpio = button->gpio;
unsigned int type = button->type ?: EV_KEY;
error = gpio_request(gpio, button->desc ?
button->desc : DRV_NAME);
if (error) {
printk(KERN_ERR PFX "unable to claim gpio %u, "
"error %d\n", gpio, error);
goto err_free_gpio;
}
error = gpio_direction_input(gpio);
if (error) {
printk(KERN_ERR PFX "unable to set direction on "
"gpio %u, error %d\n", gpio, error);
goto err_free_gpio;
}
input_set_capability(input, type, button->code);
button->count = 0;
}
bdev->poll_dev = poll_dev;
bdev->pdata = pdata;
platform_set_drvdata(pdev, bdev);
error = input_register_polled_device(poll_dev);
if (error) {
printk(KERN_ERR PFX "unable to register polled device, "
"error %d\n", error);
goto err_free_gpio;
}
return 0;
err_free_gpio:
for (i = i - 1; i >= 0; i--)
gpio_free(pdata->buttons[i].gpio);
input_free_polled_device(poll_dev);
err_free_bdev:
kfree(bdev);
platform_set_drvdata(pdev, NULL);
return error;
}
static int __devexit gpio_buttons_remove(struct platform_device *pdev)
{
struct gpio_buttons_dev *bdev = platform_get_drvdata(pdev);
struct gpio_buttons_platform_data *pdata = bdev->pdata;
int i;
input_unregister_polled_device(bdev->poll_dev);
for (i = 0; i < pdata->nbuttons; i++)
gpio_free(pdata->buttons[i].gpio);
input_free_polled_device(bdev->poll_dev);
kfree(bdev);
platform_set_drvdata(pdev, NULL);
return 0;
}
static struct platform_driver gpio_buttons_driver = {
.probe = gpio_buttons_probe,
.remove = __devexit_p(gpio_buttons_remove),
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
},
};
static int __init gpio_buttons_init(void)
{
printk(KERN_INFO DRV_NAME " driver version " DRV_VERSION "\n");
return platform_driver_register(&gpio_buttons_driver);
}
static void __exit gpio_buttons_exit(void)
{
platform_driver_unregister(&gpio_buttons_driver);
}
module_init(gpio_buttons_init);
module_exit(gpio_buttons_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>");
MODULE_VERSION(DRV_VERSION);
MODULE_DESCRIPTION("Polled buttons driver for CPU GPIOs");

View File

@ -1,172 +0,0 @@
/*
* LEDs driver for PCEngines ALIX 2/3 series
*
* Copyright (C) 2007 Petr Liebman
*
* Based on leds-wrap.c
*
* 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/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/err.h>
#include <asm/io.h>
#define DRVNAME "alix-led"
#define ALIX_LED1_PORT (0x6100)
#define ALIX_LED1_ON (1<<22)
#define ALIX_LED1_OFF (1<<6)
#define ALIX_LED2_PORT (0x6180)
#define ALIX_LED2_ON (1<<25)
#define ALIX_LED2_OFF (1<<9)
#define ALIX_LED3_PORT (0x6180)
#define ALIX_LED3_ON (1<<27)
#define ALIX_LED3_OFF (1<<11)
static struct platform_device *pdev;
static void alix_led_set_1(struct led_classdev *led_cdev,
enum led_brightness value)
{
if (value)
outl(ALIX_LED1_ON, ALIX_LED1_PORT);
else
outl(ALIX_LED1_OFF, ALIX_LED1_PORT);
}
static void alix_led_set_2(struct led_classdev *led_cdev,
enum led_brightness value)
{
if (value)
outl(ALIX_LED2_ON, ALIX_LED2_PORT);
else
outl(ALIX_LED2_OFF, ALIX_LED2_PORT);
}
static void alix_led_set_3(struct led_classdev *led_cdev,
enum led_brightness value)
{
if (value)
outl(ALIX_LED3_ON, ALIX_LED3_PORT);
else
outl(ALIX_LED3_OFF, ALIX_LED3_PORT);
}
static struct led_classdev alix_led_1 = {
.name = "alix:1",
.brightness_set = alix_led_set_1,
};
static struct led_classdev alix_led_2 = {
.name = "alix:2",
.brightness_set = alix_led_set_2,
};
static struct led_classdev alix_led_3 = {
.name = "alix:3",
.brightness_set = alix_led_set_3,
};
#ifdef CONFIG_PM
static int alix_led_suspend(struct platform_device *dev,
pm_message_t state)
{
led_classdev_suspend(&alix_led_1);
led_classdev_suspend(&alix_led_2);
led_classdev_suspend(&alix_led_3);
return 0;
}
static int alix_led_resume(struct platform_device *dev)
{
led_classdev_resume(&alix_led_1);
led_classdev_resume(&alix_led_2);
led_classdev_resume(&alix_led_3);
return 0;
}
#else
#define alix_led_suspend NULL
#define alix_led_resume NULL
#endif
static int alix_led_probe(struct platform_device *pdev)
{
int ret;
ret = led_classdev_register(&pdev->dev, &alix_led_1);
if (ret >= 0)
{
ret = led_classdev_register(&pdev->dev, &alix_led_2);
if (ret >= 0)
{
ret = led_classdev_register(&pdev->dev, &alix_led_3);
if (ret < 0)
led_classdev_unregister(&alix_led_2);
}
if (ret < 0)
led_classdev_unregister(&alix_led_1);
}
return ret;
}
static int alix_led_remove(struct platform_device *pdev)
{
led_classdev_unregister(&alix_led_1);
led_classdev_unregister(&alix_led_2);
led_classdev_unregister(&alix_led_3);
return 0;
}
static struct platform_driver alix_led_driver = {
.probe = alix_led_probe,
.remove = alix_led_remove,
.suspend = alix_led_suspend,
.resume = alix_led_resume,
.driver = {
.name = DRVNAME,
.owner = THIS_MODULE,
},
};
static int __init alix_led_init(void)
{
int ret;
ret = platform_driver_register(&alix_led_driver);
if (ret < 0)
goto out;
pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
if (IS_ERR(pdev)) {
ret = PTR_ERR(pdev);
platform_driver_unregister(&alix_led_driver);
goto out;
}
out:
return ret;
}
static void __exit alix_led_exit(void)
{
platform_device_unregister(pdev);
platform_driver_unregister(&alix_led_driver);
}
module_init(alix_led_init);
module_exit(alix_led_exit);
MODULE_AUTHOR("Petr Liebman");
MODULE_DESCRIPTION("PCEngines ALIX LED driver");
MODULE_LICENSE("GPL");

View File

@ -1,365 +0,0 @@
/*
* LED Morse Trigger
*
* Copyright (C) 2007 Gabor Juhos <juhosg at openwrt.org>
*
* This file was based on: drivers/led/ledtrig-timer.c
* Copyright 2005-2006 Openedhand Ltd.
* Author: Richard Purdie <rpurdie@openedhand.com>
*
* also based on the patch '[PATCH] 2.5.59 morse code panics' posted
* in the LKML by Tomas Szepe at Thu, 30 Jan 2003
* Copyright (C) 2002 Andrew Rodland <arodland@noln.com>
* Copyright (C) 2003 Tomas Szepe <szepe@pinerecords.com>
*
* 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/kernel.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/sysdev.h>
#include <linux/timer.h>
#include <linux/ctype.h>
#include <linux/leds.h>
#include "leds.h"
#define MORSE_DELAY_BASE (HZ/2)
#define MORSE_STATE_BLINK_START 0
#define MORSE_STATE_BLINK_STOP 1
#define MORSE_DIT_LEN 1
#define MORSE_DAH_LEN 3
#define MORSE_SPACE_LEN 7
struct morse_trig_data {
unsigned long delay;
char *msg;
unsigned char morse;
unsigned char state;
char *msgpos;
struct timer_list timer;
};
const unsigned char morsetable[] = {
0122, 0, 0310, 0, 0, 0163, /* "#$%&' */
055, 0155, 0, 0, 0163, 0141, 0152, 0051, /* ()*+,-./ */
077, 076, 074, 070, 060, 040, 041, 043, 047, 057, /* 0-9 */
0107, 0125, 0, 0061, 0, 0114, 0, /* :;<=>?@ */
006, 021, 025, 011, 002, 024, 013, 020, 004, /* A-I */
036, 015, 022, 007, 005, 017, 026, 033, 012, /* J-R */
010, 003, 014, 030, 016, 031, 035, 023, /* S-Z */
0, 0, 0, 0, 0154 /* [\]^_ */
};
static inline unsigned char tomorse(char c) {
if (c >= 'a' && c <= 'z')
c = c - 'a' + 'A';
if (c >= '"' && c <= '_') {
return morsetable[c - '"'];
} else
return 0;
}
static inline unsigned long dit_len(struct morse_trig_data *morse_data)
{
return MORSE_DIT_LEN*morse_data->delay;
}
static inline unsigned long dah_len(struct morse_trig_data *morse_data)
{
return MORSE_DAH_LEN*morse_data->delay;
}
static inline unsigned long space_len(struct morse_trig_data *morse_data)
{
return MORSE_SPACE_LEN*morse_data->delay;
}
static void morse_timer_function(unsigned long data)
{
struct led_classdev *led_cdev = (struct led_classdev *)data;
struct morse_trig_data *morse_data = led_cdev->trigger_data;
unsigned long brightness = LED_OFF;
unsigned long delay = 0;
if (!morse_data->msg)
goto set_led;
switch (morse_data->state) {
case MORSE_STATE_BLINK_START:
/* Starting a new blink. We have a valid code in morse. */
delay = (morse_data->morse & 001) ? dah_len(morse_data):
dit_len(morse_data);
brightness = LED_FULL;
morse_data->state = MORSE_STATE_BLINK_STOP;
morse_data->morse >>= 1;
break;
case MORSE_STATE_BLINK_STOP:
/* Coming off of a blink. */
morse_data->state = MORSE_STATE_BLINK_START;
if (morse_data->morse > 1) {
/* Not done yet, just a one-dit pause. */
delay = dit_len(morse_data);
break;
}
/* Get a new char, figure out how much space. */
/* First time through */
if (!morse_data->msgpos)
morse_data->msgpos = (char *)morse_data->msg;
if (!*morse_data->msgpos) {
/* Repeating */
morse_data->msgpos = (char *)morse_data->msg;
delay = space_len(morse_data);
} else {
/* Inter-letter space */
delay = dah_len(morse_data);
}
if (!(morse_data->morse = tomorse(*morse_data->msgpos))) {
delay = space_len(morse_data);
/* And get us back here */
morse_data->state = MORSE_STATE_BLINK_STOP;
}
morse_data->msgpos++;
break;
}
mod_timer(&morse_data->timer, jiffies + msecs_to_jiffies(delay));
set_led:
led_set_brightness(led_cdev, brightness);
}
static ssize_t _morse_delay_show(struct led_classdev *led_cdev, char *buf)
{
struct morse_trig_data *morse_data = led_cdev->trigger_data;
sprintf(buf, "%lu\n", morse_data->delay);
return strlen(buf) + 1;
}
static ssize_t _morse_delay_store(struct led_classdev *led_cdev,
const char *buf, size_t size)
{
struct morse_trig_data *morse_data = led_cdev->trigger_data;
char *after;
unsigned long state = simple_strtoul(buf, &after, 10);
size_t count = after - buf;
int ret = -EINVAL;
if (*after && isspace(*after))
count++;
if (count == size) {
morse_data->delay = state;
mod_timer(&morse_data->timer, jiffies + 1);
ret = count;
}
return ret;
}
static ssize_t _morse_msg_show(struct led_classdev *led_cdev, char *buf)
{
struct morse_trig_data *morse_data = led_cdev->trigger_data;
if (!morse_data->msg)
sprintf(buf, "<none>\n");
else
sprintf(buf, "%s\n", morse_data->msg);
return strlen(buf) + 1;
}
static ssize_t _morse_msg_store(struct led_classdev *led_cdev,
const char *buf, size_t size)
{
struct morse_trig_data *morse_data = led_cdev->trigger_data;
char *m;
m = kmalloc(size, GFP_KERNEL);
if (!m)
return -ENOMEM;
memcpy(m,buf,size);
m[size]='\0';
if (morse_data->msg)
kfree(morse_data->msg);
morse_data->msg = m;
morse_data->msgpos = NULL;
morse_data->state = MORSE_STATE_BLINK_STOP;
mod_timer(&morse_data->timer, jiffies + 1);
return size;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
static ssize_t morse_delay_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
return _morse_delay_show(led_cdev, buf);
}
static ssize_t morse_delay_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
return _morse_delay_store(led_cdev, buf, size);
}
static ssize_t morse_msg_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
return _morse_msg_show(led_cdev, buf);
}
static ssize_t morse_msg_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
return _morse_msg_store(led_cdev, buf, size);
}
static DEVICE_ATTR(delay, 0644, morse_delay_show, morse_delay_store);
static DEVICE_ATTR(message, 0644, morse_msg_show, morse_msg_store);
#define led_device_create_file(leddev, attr) \
device_create_file(leddev->dev, &dev_attr_ ## attr)
#define led_device_remove_file(leddev, attr) \
device_remove_file(leddev->dev, &dev_attr_ ## attr)
#else
static ssize_t morse_delay_show(struct class_device *dev, char *buf)
{
struct led_classdev *led_cdev = class_get_devdata(dev);
return _morse_delay_show(led_cdev, buf);
}
static ssize_t morse_delay_store(struct class_device *dev, const char *buf,
size_t size)
{
struct led_classdev *led_cdev = class_get_devdata(dev);
return _morse_delay_store(led_cdev, buf, size);
}
static ssize_t morse_msg_show(struct class_device *dev, char *buf)
{
struct led_classdev *led_cdev = class_get_devdata(dev);
return _morse_msg_show(led_cdev, buf);
}
static ssize_t morse_msg_store(struct class_device *dev, const char *buf,
size_t size)
{
struct led_classdev *led_cdev = class_get_devdata(dev);
return _morse_msg_store(led_cdev, buf, size);
}
static CLASS_DEVICE_ATTR(delay, 0644, morse_delay_show, morse_delay_store);
static CLASS_DEVICE_ATTR(message, 0644, morse_msg_show, morse_msg_store);
#define led_device_create_file(leddev, attr) \
class_device_create_file(leddev->class_dev, &class_device_attr_ ## attr)
#define led_device_remove_file(leddev, attr) \
class_device_remove_file(leddev->class_dev, &class_device_attr_ ## attr)
#endif
static void morse_trig_activate(struct led_classdev *led_cdev)
{
struct morse_trig_data *morse_data;
int rc;
morse_data = kzalloc(sizeof(*morse_data), GFP_KERNEL);
if (!morse_data)
return;
morse_data->delay = MORSE_DELAY_BASE;
init_timer(&morse_data->timer);
morse_data->timer.function = morse_timer_function;
morse_data->timer.data = (unsigned long)led_cdev;
rc = led_device_create_file(led_cdev, delay);
if (rc) goto err;
rc = led_device_create_file(led_cdev, message);
if (rc) goto err_delay;
led_cdev->trigger_data = morse_data;
return;
err_delay:
led_device_remove_file(led_cdev, delay);
err:
kfree(morse_data);
}
static void morse_trig_deactivate(struct led_classdev *led_cdev)
{
struct morse_trig_data *morse_data = led_cdev->trigger_data;
if (!morse_data)
return;
led_device_remove_file(led_cdev, message);
led_device_remove_file(led_cdev, delay);
del_timer_sync(&morse_data->timer);
if (morse_data->msg)
kfree(morse_data->msg);
kfree(morse_data);
}
static struct led_trigger morse_led_trigger = {
.name = "morse",
.activate = morse_trig_activate,
.deactivate = morse_trig_deactivate,
};
static int __init morse_trig_init(void)
{
return led_trigger_register(&morse_led_trigger);
}
static void __exit morse_trig_exit(void)
{
led_trigger_unregister(&morse_led_trigger);
}
module_init(morse_trig_init);
module_exit(morse_trig_exit);
MODULE_AUTHOR("Gabor Juhos <juhosg at openwrt.org>");
MODULE_DESCRIPTION("Morse LED trigger");
MODULE_LICENSE("GPL");

View File

@ -1,451 +0,0 @@
/*
* LED Kernel Netdev Trigger
*
* Toggles the LED to reflect the link and traffic state of a named net device
*
* Copyright 2007 Oliver Jowett <oliver@opencloud.com>
*
* Derived from ledtrig-timer.c which is:
* Copyright 2005-2006 Openedhand Ltd.
* Author: Richard Purdie <rpurdie@openedhand.com>
*
* 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/module.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/sysdev.h>
#include <linux/netdevice.h>
#include <linux/timer.h>
#include <linux/ctype.h>
#include <linux/leds.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
#include <net/net_namespace.h>
#endif
#include "leds.h"
/*
* Configurable sysfs attributes:
*
* device_name - network device name to monitor
*
* interval - duration of LED blink, in milliseconds
*
* mode - either "none" (LED is off) or a space separated list of one or more of:
* link: LED's normal state reflects whether the link is up (has carrier) or not
* tx: LED blinks on transmitted data
* rx: LED blinks on receive data
*
* Some suggestions:
*
* Simple link status LED:
* $ echo netdev >someled/trigger
* $ echo eth0 >someled/device_name
* $ echo link >someled/mode
*
* Ethernet-style link/activity LED:
* $ echo netdev >someled/trigger
* $ echo eth0 >someled/device_name
* $ echo "link tx rx" >someled/mode
*
* Modem-style tx/rx LEDs:
* $ echo netdev >led1/trigger
* $ echo ppp0 >led1/device_name
* $ echo tx >led1/mode
* $ echo netdev >led2/trigger
* $ echo ppp0 >led2/device_name
* $ echo rx >led2/mode
*
*/
#define MODE_LINK 1
#define MODE_TX 2
#define MODE_RX 4
struct led_netdev_data {
rwlock_t lock;
struct timer_list timer;
struct notifier_block notifier;
struct led_classdev *led_cdev;
struct net_device *net_dev;
char device_name[IFNAMSIZ];
unsigned interval;
unsigned mode;
unsigned link_up;
unsigned last_activity;
};
static void set_baseline_state(struct led_netdev_data *trigger_data)
{
if ((trigger_data->mode & MODE_LINK) != 0 && trigger_data->link_up)
led_set_brightness(trigger_data->led_cdev, LED_FULL);
else
led_set_brightness(trigger_data->led_cdev, LED_OFF);
if ((trigger_data->mode & (MODE_TX | MODE_RX)) != 0 && trigger_data->link_up)
mod_timer(&trigger_data->timer, jiffies + trigger_data->interval);
else
del_timer(&trigger_data->timer);
}
static ssize_t led_device_name_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct led_netdev_data *trigger_data = led_cdev->trigger_data;
read_lock(&trigger_data->lock);
sprintf(buf, "%s\n", trigger_data->device_name);
read_unlock(&trigger_data->lock);
return strlen(buf) + 1;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
extern struct net init_net;
#endif
static ssize_t led_device_name_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct led_netdev_data *trigger_data = led_cdev->trigger_data;
if (size < 0 || size >= IFNAMSIZ)
return -EINVAL;
write_lock(&trigger_data->lock);
strcpy(trigger_data->device_name, buf);
if (size > 0 && trigger_data->device_name[size-1] == '\n')
trigger_data->device_name[size-1] = 0;
if (trigger_data->device_name[0] != 0) {
/* check for existing device to update from */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
trigger_data->net_dev = dev_get_by_name(&init_net, trigger_data->device_name);
#else
trigger_data->net_dev = dev_get_by_name(trigger_data->device_name);
#endif
if (trigger_data->net_dev != NULL)
trigger_data->link_up = (dev_get_flags(trigger_data->net_dev) & IFF_LOWER_UP) != 0;
set_baseline_state(trigger_data); /* updates LEDs, may start timers */
}
write_unlock(&trigger_data->lock);
return size;
}
static DEVICE_ATTR(device_name, 0644, led_device_name_show, led_device_name_store);
static ssize_t led_mode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct led_netdev_data *trigger_data = led_cdev->trigger_data;
read_lock(&trigger_data->lock);
if (trigger_data->mode == 0) {
strcpy(buf, "none\n");
} else {
if (trigger_data->mode & MODE_LINK)
strcat(buf, "link ");
if (trigger_data->mode & MODE_TX)
strcat(buf, "tx ");
if (trigger_data->mode & MODE_RX)
strcat(buf, "rx ");
strcat(buf, "\n");
}
read_unlock(&trigger_data->lock);
return strlen(buf)+1;
}
static ssize_t led_mode_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct led_netdev_data *trigger_data = led_cdev->trigger_data;
char copybuf[1024];
int new_mode = -1;
char *p, *token;
/* take a copy since we don't want to trash the inbound buffer when using strsep */
strncpy(copybuf, buf, sizeof(copybuf));
copybuf[1023] = 0;
p = copybuf;
while ((token = strsep(&p, " \t\n")) != NULL) {
if (!*token)
continue;
if (new_mode == -1)
new_mode = 0;
if (!strcmp(token, "none"))
new_mode = 0;
else if (!strcmp(token, "tx"))
new_mode |= MODE_TX;
else if (!strcmp(token, "rx"))
new_mode |= MODE_RX;
else if (!strcmp(token, "link"))
new_mode |= MODE_LINK;
else
return -EINVAL;
}
if (new_mode == -1)
return -EINVAL;
write_lock(&trigger_data->lock);
trigger_data->mode = new_mode;
set_baseline_state(trigger_data);
write_unlock(&trigger_data->lock);
return size;
}
static DEVICE_ATTR(mode, 0644, led_mode_show, led_mode_store);
static ssize_t led_interval_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct led_netdev_data *trigger_data = led_cdev->trigger_data;
read_lock(&trigger_data->lock);
sprintf(buf, "%u\n", jiffies_to_msecs(trigger_data->interval));
read_unlock(&trigger_data->lock);
return strlen(buf) + 1;
}
static ssize_t led_interval_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
struct led_netdev_data *trigger_data = led_cdev->trigger_data;
int ret = -EINVAL;
char *after;
unsigned long value = simple_strtoul(buf, &after, 10);
size_t count = after - buf;
if (*after && isspace(*after))
count++;
/* impose some basic bounds on the timer interval */
if (count == size && value >= 5 && value <= 10000) {
write_lock(&trigger_data->lock);
trigger_data->interval = msecs_to_jiffies(value);
set_baseline_state(trigger_data); // resets timer
write_unlock(&trigger_data->lock);
ret = count;
}
return ret;
}
static DEVICE_ATTR(interval, 0644, led_interval_show, led_interval_store);
static int netdev_trig_notify(struct notifier_block *nb,
unsigned long evt,
void *dv)
{
struct net_device *dev = dv;
struct led_netdev_data *trigger_data = container_of(nb, struct led_netdev_data, notifier);
if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER)
return NOTIFY_DONE;
write_lock(&trigger_data->lock);
if (strcmp(dev->name, trigger_data->device_name))
goto done;
if (evt == NETDEV_REGISTER) {
if (trigger_data->net_dev != NULL)
dev_put(trigger_data->net_dev);
dev_hold(dev);
trigger_data->net_dev = dev;
trigger_data->link_up = 0;
goto done;
}
if (evt == NETDEV_UNREGISTER && trigger_data->net_dev != NULL) {
dev_put(trigger_data->net_dev);
trigger_data->net_dev = NULL;
goto done;
}
/* UP / DOWN / CHANGE */
trigger_data->link_up = (evt != NETDEV_DOWN && netif_carrier_ok(dev));
set_baseline_state(trigger_data);
done:
write_unlock(&trigger_data->lock);
return NOTIFY_DONE;
}
/* here's the real work! */
static void netdev_trig_timer(unsigned long arg)
{
struct led_netdev_data *trigger_data = (struct led_netdev_data *)arg;
struct net_device_stats *dev_stats;
unsigned new_activity;
write_lock(&trigger_data->lock);
if (!trigger_data->link_up || !trigger_data->net_dev || (trigger_data->mode & (MODE_TX | MODE_RX)) == 0) {
/* we don't need to do timer work, just reflect link state. */
led_set_brightness(trigger_data->led_cdev, ((trigger_data->mode & MODE_LINK) != 0 && trigger_data->link_up) ? LED_FULL : LED_OFF);
goto no_restart;
}
dev_stats = trigger_data->net_dev->get_stats(trigger_data->net_dev);
new_activity =
((trigger_data->mode & MODE_TX) ? dev_stats->tx_packets : 0) +
((trigger_data->mode & MODE_RX) ? dev_stats->rx_packets : 0);
if (trigger_data->mode & MODE_LINK) {
/* base state is ON (link present) */
/* if there's no link, we don't get this far and the LED is off */
/* OFF -> ON always */
/* ON -> OFF on activity */
if (trigger_data->led_cdev->brightness == LED_OFF) {
led_set_brightness(trigger_data->led_cdev, LED_FULL);
} else if (trigger_data->last_activity != new_activity) {
led_set_brightness(trigger_data->led_cdev, LED_OFF);
}
} else {
/* base state is OFF */
/* ON -> OFF always */
/* OFF -> ON on activity */
if (trigger_data->led_cdev->brightness == LED_FULL) {
led_set_brightness(trigger_data->led_cdev, LED_OFF);
} else if (trigger_data->last_activity != new_activity) {
led_set_brightness(trigger_data->led_cdev, LED_FULL);
}
}
trigger_data->last_activity = new_activity;
mod_timer(&trigger_data->timer, jiffies + trigger_data->interval);
no_restart:
write_unlock(&trigger_data->lock);
}
static void netdev_trig_activate(struct led_classdev *led_cdev)
{
struct led_netdev_data *trigger_data;
int rc;
trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL);
if (!trigger_data)
return;
rwlock_init(&trigger_data->lock);
trigger_data->notifier.notifier_call = netdev_trig_notify;
trigger_data->notifier.priority = 10;
setup_timer(&trigger_data->timer, netdev_trig_timer, (unsigned long) trigger_data);
trigger_data->led_cdev = led_cdev;
trigger_data->net_dev = NULL;
trigger_data->device_name[0] = 0;
trigger_data->mode = 0;
trigger_data->interval = msecs_to_jiffies(50);
trigger_data->link_up = 0;
trigger_data->last_activity = 0;
led_cdev->trigger_data = trigger_data;
rc = device_create_file(led_cdev->dev, &dev_attr_device_name);
if (rc)
goto err_out;
rc = device_create_file(led_cdev->dev, &dev_attr_mode);
if (rc)
goto err_out_device_name;
rc = device_create_file(led_cdev->dev, &dev_attr_interval);
if (rc)
goto err_out_mode;
register_netdevice_notifier(&trigger_data->notifier);
return;
err_out_mode:
device_remove_file(led_cdev->dev, &dev_attr_mode);
err_out_device_name:
device_remove_file(led_cdev->dev, &dev_attr_device_name);
err_out:
led_cdev->trigger_data = NULL;
kfree(trigger_data);
}
static void netdev_trig_deactivate(struct led_classdev *led_cdev)
{
struct led_netdev_data *trigger_data = led_cdev->trigger_data;
if (trigger_data) {
unregister_netdevice_notifier(&trigger_data->notifier);
device_remove_file(led_cdev->dev, &dev_attr_device_name);
device_remove_file(led_cdev->dev, &dev_attr_mode);
device_remove_file(led_cdev->dev, &dev_attr_interval);
write_lock(&trigger_data->lock);
if (trigger_data->net_dev) {
dev_put(trigger_data->net_dev);
trigger_data->net_dev = NULL;
}
write_unlock(&trigger_data->lock);
del_timer_sync(&trigger_data->timer);
kfree(trigger_data);
}
}
static struct led_trigger netdev_led_trigger = {
.name = "netdev",
.activate = netdev_trig_activate,
.deactivate = netdev_trig_deactivate,
};
static int __init netdev_trig_init(void)
{
return led_trigger_register(&netdev_led_trigger);
}
static void __exit netdev_trig_exit(void)
{
led_trigger_unregister(&netdev_led_trigger);
}
module_init(netdev_trig_init);
module_exit(netdev_trig_exit);
MODULE_AUTHOR("Oliver Jowett <oliver@opencloud.com>");
MODULE_DESCRIPTION("Netdev LED trigger");
MODULE_LICENSE("GPL");

View File

@ -1,35 +0,0 @@
/*
* Definitions for the GPIO buttons interface driver
*
* Copyright (C) 2007,2008 Gabor Juhos <juhosg at openwrt.org>
*
* This file was based on: /include/linux/gpio_keys.h
* The original gpio_keys.h seems not to have a license.
*
* 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.
*
*/
#ifndef _GPIO_BUTTONS_H_
#define _GPIO_BUTTONS_H_
struct gpio_button {
int gpio; /* GPIO line number */
int active_low;
char *desc; /* button description */
int type; /* input event type (EV_KEY, EV_SW) */
int code; /* input event code (KEY_*, SW_*) */
int count;
int threshold; /* count threshold */
};
struct gpio_buttons_platform_data {
struct gpio_button *buttons;
int nbuttons; /* number of buttons */
int poll_interval; /* polling interval */
};
#endif /* _GPIO_BUTTONS_H_ */

View File

@ -1,11 +0,0 @@
#ifndef _GPIODEV_H__
#define _GPIODEV_H__
#define IOC_GPIODEV_MAGIC 'B'
#define GPIO_GET _IO(IOC_GPIODEV_MAGIC, 10)
#define GPIO_SET _IO(IOC_GPIODEV_MAGIC, 11)
#define GPIO_CLEAR _IO(IOC_GPIODEV_MAGIC, 12)
#define GPIO_DIR_IN _IO(IOC_GPIODEV_MAGIC, 13)
#define GPIO_DIR_OUT _IO(IOC_GPIODEV_MAGIC, 14)
#endif

View File

@ -1,12 +0,0 @@
--- a/Makefile
+++ b/Makefile
@@ -560,6 +560,9 @@ endif
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
CHECKFLAGS += $(NOSTDINC_FLAGS)
+# improve gcc optimization
+CFLAGS += $(call cc-option,-funit-at-a-time,)
+
# warn about C99 declaration after statement
KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)

View File

@ -1,11 +0,0 @@
--- a/arch/mips/include/asm/system.h
+++ b/arch/mips/include/asm/system.h
@@ -187,7 +187,7 @@ extern __u64 __xchg_u64_unsupported_on_3
if something tries to do an invalid xchg(). */
extern void __xchg_called_with_bad_pointer(void);
-static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+static __always_inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
switch (size) {
case 4:

View File

@ -1,36 +0,0 @@
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -51,6 +51,7 @@
#define SST49LF040B 0x0050
#define SST49LF008A 0x005a
#define AT49BV6416 0x00d6
+#define MANUFACTURER_SAMSUNG 0x00ec
static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
@@ -375,12 +376,19 @@ struct mtd_info *cfi_cmdset_0002(struct
if (extp->MajorVersion != '1' ||
(extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
- printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query "
- "version %c.%c.\n", extp->MajorVersion,
- extp->MinorVersion);
- kfree(extp);
- kfree(mtd);
- return NULL;
+ if (cfi->mfr == MANUFACTURER_SAMSUNG &&
+ (extp->MajorVersion == '3' && extp->MinorVersion == '3')) {
+ printk(KERN_NOTICE " Newer Samsung flash detected, "
+ "should be compatibile with Amd/Fujitsu.\n");
+ }
+ else {
+ printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query "
+ "version %c.%c.\n", extp->MajorVersion,
+ extp->MinorVersion);
+ kfree(extp);
+ kfree(mtd);
+ return NULL;
+ }
}
/* Install our own private info structure */

View File

@ -1,11 +0,0 @@
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -121,6 +121,8 @@
#endif
.endm
+ j kernel_entry
+ nop
#ifndef CONFIG_NO_EXCEPT_FILL
/*
* Reserved space for exception handlers.

View File

@ -1,157 +0,0 @@
--- /dev/null
+++ b/include/asm-mips/mips_machine.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 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.
+ *
+ */
+
+#ifndef __ASM_MIPS_MACHINE_H
+#define __ASM_MIPS_MACHINE_H
+
+#include <linux/init.h>
+#include <linux/list.h>
+
+#define MIPS_MACHINE_NAME_LEN 64
+
+struct mips_machine {
+ unsigned long mach_type;
+ void (*mach_setup)(void);
+ unsigned char mach_name[MIPS_MACHINE_NAME_LEN];
+ struct list_head list;
+};
+
+void mips_machine_register(struct mips_machine *) __init;
+void mips_machine_setup(unsigned long machtype) __init;
+
+extern unsigned char mips_machine_name[MIPS_MACHINE_NAME_LEN];
+
+#define MIPS_MACHINE(_type, _name, _setup) \
+static struct mips_machine machine_##_type __initdata = \
+{ \
+ .mach_type = _type, \
+ .mach_name = _name, \
+ .mach_setup = _setup, \
+}; \
+ \
+static int __init register_machine_##_type(void) \
+{ \
+ mips_machine_register(&machine_##_type); \
+ return 0; \
+} \
+ \
+pure_initcall(register_machine_##_type)
+
+#endif /* __ASM_MIPS_MACHINE_H */
+
--- /dev/null
+++ b/arch/mips/kernel/mips_machine.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008 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 <asm/mips_machine.h>
+#include <asm/bootinfo.h>
+
+static struct list_head mips_machines __initdata =
+ LIST_HEAD_INIT(mips_machines);
+
+unsigned char mips_machine_name[MIPS_MACHINE_NAME_LEN] = "Unknown";
+
+static struct mips_machine * __init mips_machine_find(unsigned long machtype)
+{
+ struct list_head *this;
+
+ list_for_each(this, &mips_machines) {
+ struct mips_machine *mach;
+
+ mach = list_entry(this, struct mips_machine, list);
+ if (mach->mach_type == machtype)
+ return mach;
+ }
+
+ return NULL;
+}
+
+void __init mips_machine_register(struct mips_machine *mach)
+{
+ list_add_tail(&mach->list, &mips_machines);
+}
+
+void __init mips_machine_setup(unsigned long machtype)
+{
+ struct mips_machine *mach;
+
+ mach = mips_machine_find(machtype);
+ if (!mach) {
+ printk(KERN_ALERT "MIPS: no machine registered for "
+ "machtype %lu\n", machtype);
+ return;
+ }
+
+ if (mach->mach_name[0])
+ strncpy(mips_machine_name, mach->mach_name,
+ MIPS_MACHINE_NAME_LEN);
+
+ printk(KERN_INFO "MIPS: machine is %s\n", mips_machine_name);
+
+ if (mach->mach_setup)
+ mach->mach_setup();
+}
+
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_GPIO_TXX9) += gpio_txx9.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+obj-$(CONFIG_MIPS_MACHINE) += mips_machine.o
CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -810,6 +810,9 @@ config MIPS_DISABLE_OBSOLETE_IDE
config SYNC_R4K
bool
+config MIPS_MACHINE
+ def_bool n
+
config NO_IOPORT
def_bool n
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -14,6 +14,7 @@
#include <asm/cpu-features.h>
#include <asm/mipsregs.h>
#include <asm/processor.h>
+#include <asm/mips_machine.h>
unsigned int vced_count, vcei_count;
@@ -33,8 +34,12 @@ static int show_cpuinfo(struct seq_file
/*
* For the first processor also print the system type
*/
- if (n == 0)
+ if (n == 0) {
seq_printf(m, "system type\t\t: %s\n", get_system_type());
+#ifdef CONFIG_MIPS_MACHINE
+ seq_printf(m, "machine\t\t\t: %s\n", mips_machine_name);
+#endif
+ }
seq_printf(m, "processor\t\t: %ld\n", n);
sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n",

View File

@ -1,50 +0,0 @@
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -812,6 +812,9 @@ config SYNC_R4K
config MIPS_MACHINE
def_bool n
+
+config PROM_EMU
+ def_bool n
config NO_IOPORT
def_bool n
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -143,6 +143,15 @@ FEXPORT(__kernel_entry)
j kernel_entry
#endif
+#ifdef CONFIG_PROM_EMU
+EXPORT(prom_emu_argv)
+ .word 0
+ .word prom_emu_cmdline
+ .ascii "CMDLINE:"
+EXPORT(prom_emu_cmdline)
+ .fill 0x400
+#endif
+
__REF
NESTED(kernel_entry, 16, sp) # kernel entry point
@@ -183,6 +192,19 @@ NESTED(kernel_entry, 16, sp) # kernel
LONG_S zero, (t0)
bne t0, t1, 1b
+#ifdef CONFIG_PROM_EMU
+ PTR_LA t0, prom_emu_cmdline
+ LONG_L t1, 0(t0)
+ beqz t1, 1f
+
+ li a0, 2
+ PTR_LA a1, prom_emu_argv
+ move a2, zero
+ move a3, zero
+
+1:
+#endif /* CONFIG_PROM_EMU */
+
LONG_S a0, fw_arg0 # firmware arguments
LONG_S a1, fw_arg1
LONG_S a2, fw_arg2

View File

@ -1,171 +0,0 @@
From: Ralf Baechle <ralf@linux-mips.org>
Date: Thu, 30 Apr 2009 16:14:56 +0000 (+0200)
Subject: MIPS: Rewrite <asm/div64.h> to work with gcc 4.4.0.
X-Git-Url: http://www.linux-mips.org/git?p=linux.git;a=commitdiff_plain;h=a1b68289997030df64cba8478d5767fe10e42a58
MIPS: Rewrite <asm/div64.h> to work with gcc 4.4.0.
The inline assembler used on 32-bit kernels was using the "h" constraint
which was considered dangerous and removed for gcc 4.4.0.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
---
--- a/arch/mips/include/asm/div64.h
+++ b/arch/mips/include/asm/div64.h
@@ -6,105 +6,63 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
-#ifndef _ASM_DIV64_H
-#define _ASM_DIV64_H
+#ifndef __ASM_DIV64_H
+#define __ASM_DIV64_H
-#include <linux/types.h>
+#include <asm-generic/div64.h>
-#if (_MIPS_SZLONG == 32)
+#if BITS_PER_LONG == 64
-#include <asm/compiler.h>
+#include <linux/types.h>
/*
* No traps on overflows for any of these...
*/
-#define do_div64_32(res, high, low, base) ({ \
- unsigned long __quot32, __mod32; \
- unsigned long __cf, __tmp, __tmp2, __i; \
- \
- __asm__(".set push\n\t" \
- ".set noat\n\t" \
- ".set noreorder\n\t" \
- "move %2, $0\n\t" \
- "move %3, $0\n\t" \
- "b 1f\n\t" \
- " li %4, 0x21\n" \
- "0:\n\t" \
- "sll $1, %0, 0x1\n\t" \
- "srl %3, %0, 0x1f\n\t" \
- "or %0, $1, %5\n\t" \
- "sll %1, %1, 0x1\n\t" \
- "sll %2, %2, 0x1\n" \
- "1:\n\t" \
- "bnez %3, 2f\n\t" \
- " sltu %5, %0, %z6\n\t" \
- "bnez %5, 3f\n" \
- "2:\n\t" \
- " addiu %4, %4, -1\n\t" \
- "subu %0, %0, %z6\n\t" \
- "addiu %2, %2, 1\n" \
- "3:\n\t" \
- "bnez %4, 0b\n\t" \
- " srl %5, %1, 0x1f\n\t" \
- ".set pop" \
- : "=&r" (__mod32), "=&r" (__tmp), \
- "=&r" (__quot32), "=&r" (__cf), \
- "=&r" (__i), "=&r" (__tmp2) \
- : "Jr" (base), "0" (high), "1" (low)); \
- \
- (res) = __quot32; \
- __mod32; })
-
-#define do_div(n, base) ({ \
- unsigned long long __quot; \
- unsigned long __mod; \
- unsigned long long __div; \
- unsigned long __upper, __low, __high, __base; \
- \
- __div = (n); \
- __base = (base); \
- \
- __high = __div >> 32; \
- __low = __div; \
- __upper = __high; \
- \
- if (__high) \
- __asm__("divu $0, %z2, %z3" \
- : "=h" (__upper), "=l" (__high) \
- : "Jr" (__high), "Jr" (__base) \
- : GCC_REG_ACCUM); \
- \
- __mod = do_div64_32(__low, __upper, __low, __base); \
- \
- __quot = __high; \
- __quot = __quot << 32 | __low; \
- (n) = __quot; \
- __mod; })
-
-#endif /* (_MIPS_SZLONG == 32) */
-
-#if (_MIPS_SZLONG == 64)
-
-/*
- * Hey, we're already 64-bit, no
- * need to play games..
- */
-#define do_div(n, base) ({ \
- unsigned long __quot; \
- unsigned int __mod; \
- unsigned long __div; \
- unsigned int __base; \
- \
- __div = (n); \
- __base = (base); \
- \
- __mod = __div % __base; \
- __quot = __div / __base; \
- \
- (n) = __quot; \
- __mod; })
+#define __div64_32(n, base) \
+({ \
+ unsigned long __cf, __tmp, __tmp2, __i; \
+ unsigned long __quot32, __mod32; \
+ unsigned long __high, __low; \
+ unsigned long long __n; \
+ \
+ __high = *__n >> 32; \
+ __low = __n; \
+ __asm__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " .set noreorder \n" \
+ " move %2, $0 \n" \
+ " move %3, $0 \n" \
+ " b 1f \n" \
+ " li %4, 0x21 \n" \
+ "0: \n" \
+ " sll $1, %0, 0x1 \n" \
+ " srl %3, %0, 0x1f \n" \
+ " or %0, $1, %5 \n" \
+ " sll %1, %1, 0x1 \n" \
+ " sll %2, %2, 0x1 \n" \
+ "1: \n" \
+ " bnez %3, 2f \n" \
+ " sltu %5, %0, %z6 \n" \
+ " bnez %5, 3f \n" \
+ "2: \n" \
+ " addiu %4, %4, -1 \n" \
+ " subu %0, %0, %z6 \n" \
+ " addiu %2, %2, 1 \n" \
+ "3: \n" \
+ " bnez %4, 0b\n\t" \
+ " srl %5, %1, 0x1f\n\t" \
+ " .set pop" \
+ : "=&r" (__mod32), "=&r" (__tmp), \
+ "=&r" (__quot32), "=&r" (__cf), \
+ "=&r" (__i), "=&r" (__tmp2) \
+ : "Jr" (base), "0" (__high), "1" (__low)); \
+ \
+ (__n) = __quot32; \
+ __mod32; \
+})
-#endif /* (_MIPS_SZLONG == 64) */
+#endif /* BITS_PER_LONG == 64 */
-#endif /* _ASM_DIV64_H */
+#endif /* __ASM_DIV64_H */

View File

@ -1,40 +0,0 @@
When init is started it is SIGNAL_UNKILLABLE. If it were to get an
address error, we would try to send it SIGBUS, but it would be ignored
and the faulting instruction restarted. This results in an endless
loop.
We need to use force_sig() instead so it will actually die and give us
some useful information.
Reported-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
---
arch/mips/kernel/unaligned.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
--- a/arch/mips/kernel/unaligned.c
+++ b/arch/mips/kernel/unaligned.c
@@ -482,19 +482,19 @@ fault:
return;
die_if_kernel("Unhandled kernel unaligned access", regs);
- send_sig(SIGSEGV, current, 1);
+ force_sig(SIGSEGV, current);
return;
sigbus:
die_if_kernel("Unhandled kernel unaligned access", regs);
- send_sig(SIGBUS, current, 1);
+ force_sig(SIGBUS, current);
return;
sigill:
die_if_kernel("Unhandled kernel unaligned access or invalid instruction", regs);
- send_sig(SIGILL, current, 1);
+ force_sig(SIGILL, current);
}
asmlinkage void do_ade(struct pt_regs *regs)

View File

@ -1,152 +0,0 @@
From: Wu Zhangjin <wuzj@lemote.com>
the gcc 4.4 support for MIPS mostly refer to this PATCH:
http://www.nabble.com/-PATCH--MIPS:-Handle-removal-of-%27h%27-constraint-in-GCC-4.4-td22192768.html
but have been tuned a little.
because only gcc 4.4 have loongson-specific support, so, we need to
choose the suitable -march argument for gcc <= 4.3 and gcc >= 4.4, and
we also need to consider use -march=loongson2e and -march=loongson2f for
loongson2e and loongson2f respectively. this is handled by adding two
new kernel options: CPU_LOONGSON2E and CPU_LOONGSON2F(thanks for the
solutin provided by ZhangLe).
I have tested it on FuLoong(2f) in 32bit and 64bit with gcc-4.4 and
gcc-4.3. so, basically, it works.
Signed-off-by: Wu Zhangjin <wuzhangjin@gmail.com>
---
arch/mips/Makefile | 9 +++++-
arch/mips/include/asm/compiler.h | 10 ++++++
arch/mips/include/asm/delay.h | 58 +++++++++++++++++++++++++------------
3 files changed, 57 insertions(+), 20 deletions(-)
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -119,7 +119,14 @@ cflags-$(CONFIG_CPU_R4300) += -march=r43
cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap
cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap
cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap
-cflags-$(CONFIG_CPU_LOONGSON2) += -march=r4600 -Wa,--trap
+
+# only gcc >= 4.4 have the loongson-specific support
+cflags-$(CONFIG_CPU_LOONGSON2) += -Wa,--trap
+cflags-$(CONFIG_CPU_LOONGSON2E) += $(shell if [ $(call cc-version) -lt 0440 ] ; then \
+ echo $(call cc-option,-march=r4600); else echo $(call cc-option,-march=loongson2e); fi ;)
+cflags-$(CONFIG_CPU_LOONGSON2F) += $(shell if [ $(call cc-version) -lt 0440 ] ; then \
+ echo $(call cc-option,-march=r4600); else echo $(call cc-option,-march=loongson2f); fi ;)
+
cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
-Wa,-mips32 -Wa,--trap
cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
--- a/arch/mips/include/asm/compiler.h
+++ b/arch/mips/include/asm/compiler.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2004, 2007 Maciej W. Rozycki
+ * Copyright (C) 2009 Wu Zhangjin, wuzj@lemote.com
*
* 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
@@ -16,4 +17,13 @@
#define GCC_REG_ACCUM "accum"
#endif
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
+#define GCC_NO_H_CONSTRAINT
+#ifdef CONFIG_64BIT
+typedef unsigned int uintx_t __attribute__((mode(TI)));
+#else
+typedef u64 uintx_t;
+#endif
+#endif
+
#endif /* _ASM_COMPILER_H */
--- a/arch/mips/include/asm/delay.h
+++ b/arch/mips/include/asm/delay.h
@@ -7,6 +7,7 @@
* Copyright (C) 1995 - 2000, 01, 03 by Ralf Baechle
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
* Copyright (C) 2007 Maciej W. Rozycki
+ * Copyright (C) 2009 Wu Zhangjin, wuzj@lemote.com
*/
#ifndef _ASM_DELAY_H
#define _ASM_DELAY_H
@@ -48,6 +49,43 @@ static inline void __delay(unsigned long
: "0" (loops), "r" (1));
}
+/*
+ * convert usecs to loops
+ *
+ * handle removal of 'h' constraint in GCC 4.4
+ */
+
+#ifndef GCC_NO_H_CONSTRAINT /* gcc <= 4.3 */
+static inline unsigned long __usecs_to_loops(unsigned long usecs,
+ unsigned long lpj)
+{
+ unsigned long hi, lo;
+
+ if (sizeof(long) == 4)
+ __asm__("multu\t%2, %3"
+ : "=h" (usecs), "=l" (lo)
+ : "r" (usecs), "r" (lpj)
+ : GCC_REG_ACCUM);
+ else if (sizeof(long) == 8 && !R4000_WAR)
+ __asm__("dmultu\t%2, %3"
+ : "=h" (usecs), "=l" (lo)
+ : "r" (usecs), "r" (lpj)
+ : GCC_REG_ACCUM);
+ else if (sizeof(long) == 8 && R4000_WAR)
+ __asm__("dmultu\t%3, %4\n\tmfhi\t%0"
+ : "=r" (usecs), "=h" (hi), "=l" (lo)
+ : "r" (usecs), "r" (lpj)
+ : GCC_REG_ACCUM);
+
+ return usecs;
+}
+#else /* GCC_NO_H_CONSTRAINT, gcc >= 4.4 */
+static inline unsigned long __usecs_to_loops(unsigned long usecs,
+ unsigned long lpj)
+{
+ return ((uintx_t)usecs * lpj) >> BITS_PER_LONG;
+}
+#endif
/*
* Division by multiplication: you don't have to worry about
@@ -62,8 +100,6 @@ static inline void __delay(unsigned long
static inline void __udelay(unsigned long usecs, unsigned long lpj)
{
- unsigned long hi, lo;
-
/*
* The rates of 128 is rounded wrongly by the catchall case
* for 64-bit. Excessive precission? Probably ...
@@ -77,23 +113,7 @@ static inline void __udelay(unsigned lon
0x80000000ULL) >> 32);
#endif
- if (sizeof(long) == 4)
- __asm__("multu\t%2, %3"
- : "=h" (usecs), "=l" (lo)
- : "r" (usecs), "r" (lpj)
- : GCC_REG_ACCUM);
- else if (sizeof(long) == 8 && !R4000_WAR)
- __asm__("dmultu\t%2, %3"
- : "=h" (usecs), "=l" (lo)
- : "r" (usecs), "r" (lpj)
- : GCC_REG_ACCUM);
- else if (sizeof(long) == 8 && R4000_WAR)
- __asm__("dmultu\t%3, %4\n\tmfhi\t%0"
- : "=r" (usecs), "=h" (hi), "=l" (lo)
- : "r" (usecs), "r" (lpj)
- : GCC_REG_ACCUM);
-
- __delay(usecs);
+ __delay(__usecs_to_loops(usecs, lpj));
}
#define __udelay_val cpu_data[raw_smp_processor_id()].udelay_val

View File

@ -1,153 +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
@@ -798,6 +798,17 @@ config I8259
config MIPS_BONITO64
bool
+config MIPS_FPU_EMU
+ bool
+ default n
+ 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,12 +2,14 @@
# 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
EXTRA_CFLAGS += -Werror
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -56,6 +56,12 @@
#endif
#define __mips 4
+/* Further private data for which no space exists in mips_fpu_struct */
+
+struct mips_fpu_emulator_stats fpuemustats;
+
+#ifdef CONFIG_MIPS_FPU_EMU
+
/* Function which emulates a floating point instruction. */
static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
@@ -66,10 +72,6 @@ static int fpux_emu(struct pt_regs *,
struct mips_fpu_struct *, mips_instruction);
#endif
-/* Further private data for which no space exists in mips_fpu_struct */
-
-struct mips_fpu_emulator_stats fpuemustats;
-
/* Control registers */
#define FPCREG_RID 0 /* $0 = revision id */
@@ -1273,6 +1275,13 @@ int fpu_emulator_cop1Handler(struct pt_r
return sig;
}
+#else
+int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
+ int has_fpu)
+{
+ return 0;
+}
+#endif /* CONFIG_MIPS_FPU_EMU */
#ifdef CONFIG_DEBUG_FS
extern struct dentry *mips_debugfs_dir;
--- a/arch/mips/math-emu/dsemul.c
+++ b/arch/mips/math-emu/dsemul.c
@@ -109,6 +109,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;
@@ -165,3 +166,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,34 @@ int fpu_emulator_restore_context32(struc
return err;
}
-#endif
+#endif /* CONFIG_64BIT */
+#else
+
+void fpu_emulator_init_fpu(void)
+{
+ 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 */

View File

@ -1,42 +0,0 @@
From 819b4bda18d62b52d04789c4a8d4fc3fbf9ce242 Mon Sep 17 00:00:00 2001
From: Gabor Juhos <juhosg@openwrt.org>
Date: Mon, 13 Jul 2009 10:46:49 +0200
Subject: [PATCH] MIPS: fix loading of modules with unresolved weak symbols
Loading of modules with unresolved weak symbols fails on MIPS
since '88173507e4fc1e7ecd111b0565e8cba0cb7dae6d'.
Modules: handle symbols that have a zero value
The module subsystem cannot handle symbols that are zero. If symbols
are present that have a zero value then the module resolver prints out a
message that these symbols are unresolved.
We have to use IS_ERR_VALUE() to check that a symbol has been resolved
or not.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
arch/mips/kernel/module.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -303,7 +303,7 @@ int apply_relocate(Elf_Shdr *sechdrs, co
/* This is the symbol it is referring to */
sym = (Elf_Sym *)sechdrs[symindex].sh_addr
+ ELF_MIPS_R_SYM(rel[i]);
- if (!sym->st_value) {
+ if (IS_ERR_VALUE(sym->st_value)) {
/* Ignore unresolved weak symbol */
if (ELF_ST_BIND(sym->st_info) == STB_WEAK)
continue;
@@ -343,7 +343,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs
/* This is the symbol it is referring to */
sym = (Elf_Sym *)sechdrs[symindex].sh_addr
+ ELF_MIPS_R_SYM(rel[i]);
- if (!sym->st_value) {
+ if (IS_ERR_VALUE(sym->st_value)) {
/* Ignore unresolved weak symbol */
if (ELF_ST_BIND(sym->st_info) == STB_WEAK)
continue;

View File

@ -1,110 +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/buffer_head.h>
#include <linux/mutex.h>
#include <linux/mount.h>
@@ -232,10 +233,11 @@ 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)
{
struct block_device *bdev;
struct block2mtd_dev *dev;
+ struct mtd_partition *part;
char *name;
if (!devname)
@@ -273,17 +275,17 @@ static struct block2mtd_dev *add_device(
mutex_init(&dev->write_mutex);
- /* Setup the MTD structure */
- /* make the name contain the block device in */
- name = kmalloc(sizeof("block2mtd: ") + strlen(devname) + 1,
- GFP_KERNEL);
+ if (!mtdname)
+ mtdname = devname;
+
+ name = kmalloc(strlen(mtdname) + 1, GFP_KERNEL);
if (!name)
goto devinit_err;
- sprintf(name, "block2mtd: %s", devname);
+ 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.type = MTD_RAM;
@@ -296,14 +298,17 @@ static struct block2mtd_dev *add_device(
dev->mtd.priv = dev;
dev->mtd.owner = THIS_MODULE;
- if (add_mtd_device(&dev->mtd)) {
+ part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);
+ part->name = dev->mtd.name;
+ part->offset = 0;
+ part->size = dev->mtd.size;
+ if (add_mtd_partitions(&dev->mtd, part, 1)) {
/* Device didnt 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:
@@ -376,9 +381,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;
@@ -389,7 +394,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)
@@ -408,8 +413,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;
}
@@ -443,7 +450,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)
{

View File

@ -1,633 +0,0 @@
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -53,6 +53,16 @@ config MTD_TESTS
should normally be compiled as kernel modules. The modules perform
various checks and verifications when loaded.
+config MTD_ROOTFS_ROOT_DEV
+ bool "Automatically set 'rootfs' partition to be root filesystem"
+ depends on MTD_PARTITIONS
+ default y
+
+config MTD_ROOTFS_SPLIT
+ bool "Automatically split 'rootfs' partition for squashfs"
+ depends on MTD_PARTITIONS
+ default y
+
config MTD_REDBOOT_PARTS
tristate "RedBoot partition table parsing"
depends on MTD_PARTITIONS
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -18,6 +18,8 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/compatmac.h>
+#include <linux/root_dev.h>
+#include <linux/magic.h>
/* Our partition linked list */
static LIST_HEAD(mtd_partitions);
@@ -37,7 +39,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
@@ -489,6 +491,156 @@ out_register:
return slave;
}
+#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)
+{
+ char buf[512];
+ struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
+ int len, ret;
+
+ ret = master->read(master, offset, sizeof(*sb), &len, buf);
+ if (ret || (len != sizeof(*sb))) {
+ printk(KERN_ALERT "split_squashfs: error occured while reading "
+ "from \"%s\"\n", master->name);
+ return -EINVAL;
+ }
+
+ if (*((u32 *) buf) != SQUASHFS_MAGIC) {
+ printk(KERN_ALERT "split_squashfs: no squashfs found in \"%s\"\n",
+ master->name);
+ *split_offset = 0;
+ return 0;
+ }
+
+ if (sb->bytes_used <= 0) {
+ printk(KERN_ALERT "split_squashfs: squashfs is empty in \"%s\"\n",
+ master->name);
+ *split_offset = 0;
+ return 0;
+ }
+
+ len = (u32) 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,
+ int index)
+{
+ struct mtd_partition *dpart;
+ struct mtd_part *slave = NULL;
+ int split_offset = 0;
+ int ret;
+
+ ret = split_squashfs(master, part->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 -= split_offset - dpart->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 = add_one_partition(master, dpart, index, split_offset);
+ if (!slave) {
+ kfree(dpart);
+ return -ENOMEM;
+ }
+ 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;
+
+ /* find the index of the last partition */
+ if (!list_empty(&mtd_partitions))
+ index = list_first_entry(&mtd_partitions, struct mtd_part, list)->index + 1;
+
+ return split_rootfs_data(part->master, &part->mtd, &tpart, index);
+ } 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
@@ -502,14 +654,29 @@ int add_mtd_partitions(struct mtd_info *
{
struct mtd_part *slave;
uint64_t cur_offset = 0;
- int i;
+ int i, j, ret;
printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
- for (i = 0; i < nbparts; i++) {
- slave = add_one_partition(master, parts + i, i, cur_offset);
+ for (i = 0, j = 0; i < nbparts; i++) {
+ slave = add_one_partition(master, parts + i, j++, cur_offset);
if (!slave)
return -ENOMEM;
+
+ if (!strcmp(parts[i].name, "rootfs") && slave->registered) {
+#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], j);
+ if (ret == 0)
+ j++;
+#endif
+ }
cur_offset = slave->offset + slave->mtd.size;
}
@@ -517,6 +684,32 @@ int add_mtd_partitions(struct mtd_info *
}
EXPORT_SYMBOL(add_mtd_partitions);
+int refresh_mtd_partitions(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(refresh_mtd_partitions);
+
static DEFINE_SPINLOCK(part_parser_lock);
static LIST_HEAD(part_parsers);
--- 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];
};
@@ -81,6 +83,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);
@@ -93,6 +101,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;
}
@@ -104,10 +116,14 @@ 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;
+ }
- if (from > mtd->size)
- return -EINVAL;
if (from + len > mtd->size)
len = mtd->size - from;
@@ -122,10 +138,14 @@ static int block2mtd_read(struct mtd_inf
len = len - cpylen;
page = page_read(dev->blkdev->bd_inode->i_mapping, index);
- if (!page)
- return -ENOMEM;
- if (IS_ERR(page))
- return PTR_ERR(page);
+ if (!page) {
+ err = -ENOMEM;
+ goto done;
+ }
+ if (IS_ERR(page)) {
+ err = PTR_ERR(page);
+ goto done;
+ }
memcpy(buf, page_address(page) + offset, cpylen);
page_cache_release(page);
@@ -136,7 +156,10 @@ static int block2mtd_read(struct mtd_inf
offset = 0;
index++;
}
- return 0;
+
+done:
+ read_unlock(&dev->bdev_mutex);
+ return err;
}
@@ -188,12 +211,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;
+ }
if (!len)
- return 0;
- if (to >= mtd->size)
- return -ENOSPC;
+ goto done;
+
+ if (to >= mtd->size) {
+ err = -ENOSPC;
+ goto done;
+ }
+
if (to + len > mtd->size)
len = mtd->size - to;
@@ -202,6 +235,9 @@ static int block2mtd_write(struct mtd_in
mutex_unlock(&dev->write_mutex);
if (err > 0)
err = 0;
+
+done:
+ read_unlock(&dev->bdev_mutex);
return err;
}
@@ -210,52 +246,29 @@ static int block2mtd_write(struct mtd_in
static void block2mtd_sync(struct mtd_info *mtd)
{
struct block2mtd_dev *dev = mtd->priv;
- sync_blockdev(dev->blkdev);
- return;
-}
-
-
-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);
- close_bdev_exclusive(dev->blkdev, FMODE_READ|FMODE_WRITE);
- }
+ read_lock(&dev->bdev_mutex);
+ if (dev->blkdev)
+ sync_blockdev(dev->blkdev);
+ read_unlock(&dev->bdev_mutex);
- kfree(dev);
+ return;
}
-/* FIXME: ensure that mtd->size % erase_size == 0 */
-static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname)
+static int _open_bdev(struct block2mtd_dev *dev)
{
struct block_device *bdev;
- struct block2mtd_dev *dev;
- struct mtd_partition *part;
- char *name;
-
- if (!devname)
- return NULL;
-
- dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL);
- if (!dev)
- return NULL;
/* Get a handle on the device */
- bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, NULL);
+ bdev = open_bdev_exclusive(dev->devname, FMODE_READ|FMODE_WRITE, NULL);
#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);
+ dev_t devt = name_to_dev_t(dev->devname);
if (devt) {
bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ);
}
@@ -263,17 +276,97 @@ static struct block2mtd_dev *add_device(
#endif
if (IS_ERR(bdev)) {
- ERROR("error: cannot open device %s", devname);
- goto devinit_err;
+ 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");
- goto devinit_err;
+ 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);
+ close_bdev_exclusive(dev->blkdev, FMODE_READ|FMODE_WRITE);
+ dev->blkdev = NULL;
+}
+
+static void block2mtd_free_device(struct block2mtd_dev *dev)
+{
+ if (!dev)
+ return;
+
+ kfree(dev->mtd.name);
+ _close_bdev(dev);
+ kfree(dev);
+}
+
+
+static int block2mtd_refresh(struct mtd_info *mtd)
+{
+ 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 = open_by_devnum(devt, FMODE_WRITE | FMODE_READ);
+ if (!bdev || !bdev->bd_disk)
+ err = -EINVAL;
+ else {
+ err = rescan_partitions(bdev->bd_disk, bdev);
+ }
+ if (bdev)
+ close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE);
+
+ /* 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;
+
+ if (!devname)
+ return NULL;
+
+ dev = kzalloc(sizeof(struct block2mtd_dev) + strlen(devname) + 1, GFP_KERNEL);
+ if (!dev)
+ return NULL;
+
+ strcpy(dev->devname, devname);
+
+ if (_open_bdev(dev))
+ goto devinit_err;
+
mutex_init(&dev->write_mutex);
+ rwlock_init(&dev->bdev_mutex);
if (!mtdname)
mtdname = devname;
@@ -297,6 +390,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 = dev->mtd.name;
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -16,6 +16,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/compatmac.h>
+#include <linux/mtd/partitions.h>
#include <asm/uaccess.h>
@@ -773,6 +774,13 @@ static int mtd_ioctl(struct inode *inode
file->f_pos = 0;
break;
}
+#ifdef CONFIG_MTD_PARTITIONS
+ case MTDREFRESH:
+ {
+ ret = refresh_mtd_partitions(mtd);
+ break;
+ }
+#endif
default:
ret = -ENOTTY;
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -100,6 +100,7 @@ struct mtd_oob_ops {
uint8_t *oobbuf;
};
+struct mtd_info;
struct mtd_info {
u_char type;
uint32_t flags;
@@ -225,6 +226,9 @@ struct mtd_info {
struct module *owner;
int usecount;
+ 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.
* The driver may register its callbacks. These callbacks are not
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -34,6 +34,7 @@
* erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
*/
+struct mtd_partition;
struct mtd_partition {
char *name; /* identifier string */
uint64_t size; /* partition size */
@@ -41,6 +42,7 @@ struct mtd_partition {
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)*/
struct mtd_info **mtdp; /* pointer to store the MTD object */
+ int (*refresh_partition)(struct mtd_info *);
};
#define MTDPART_OFS_NXTBLK (-2)
@@ -50,6 +52,7 @@ struct mtd_partition {
int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
int del_mtd_partitions(struct mtd_info *);
+int refresh_mtd_partitions(struct mtd_info *);
/*
* Functions dealing with the various ways of partitioning the space
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -93,6 +93,7 @@ struct otp_info {
#define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout)
#define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats)
#define MTDFILEMODE _IO('M', 19)
+#define MTDREFRESH _IO('M', 23)
/*
* Obsolete legacy interface. Keep it in order not to break userspace

View File

@ -1,27 +0,0 @@
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -515,21 +515,21 @@ static int split_squashfs(struct mtd_inf
return -EINVAL;
}
- if (*((u32 *) buf) != SQUASHFS_MAGIC) {
+ 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 (sb->bytes_used <= 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) sb->bytes_used;
+ len = (u32) le64_to_cpu(sb->bytes_used);
len += (offset & 0x000fffff);
len += (master->erasesize - 1);
len &= ~(master->erasesize - 1);

View File

@ -1,30 +0,0 @@
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -249,14 +249,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);

View File

@ -1,60 +0,0 @@
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -11,6 +11,8 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#define BOARD_CONFIG_PART "boardconfig"
+
struct fis_image_desc {
unsigned char name[16]; // Null terminated name
uint32_t flash_base; // Address within FLASH of image
@@ -41,6 +43,7 @@ static int parse_redboot_partitions(stru
struct mtd_partition **pparts,
unsigned long fis_origin)
{
+ unsigned long max_offset = 0;
int nrparts = 0;
struct fis_image_desc *buf;
struct mtd_partition *parts;
@@ -209,14 +212,14 @@ static int parse_redboot_partitions(stru
}
}
#endif
- parts = kzalloc(sizeof(*parts)*nrparts + nulllen + namelen, GFP_KERNEL);
+ parts = kzalloc(sizeof(*parts) * (nrparts + 1) + nulllen + namelen + sizeof(BOARD_CONFIG_PART), GFP_KERNEL);
if (!parts) {
ret = -ENOMEM;
goto out;
}
- nullname = (char *)&parts[nrparts];
+ nullname = (char *)&parts[nrparts + 1];
#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
if (nulllen > 0) {
strcpy(nullname, nullstring);
@@ -235,6 +238,8 @@ static int parse_redboot_partitions(stru
}
#endif
for ( ; i<nrparts; i++) {
+ if(max_offset < buf[i].flash_base + buf[i].size)
+ max_offset = buf[i].flash_base + buf[i].size;
parts[i].size = fl->img->size;
parts[i].offset = fl->img->flash_base;
parts[i].name = names;
@@ -268,6 +273,14 @@ static int parse_redboot_partitions(stru
fl = fl->next;
kfree(tmp_fl);
}
+ if(master->size - max_offset >= master->erasesize)
+ {
+ parts[nrparts].size = master->size - max_offset;
+ parts[nrparts].offset = max_offset;
+ parts[nrparts].name = names;
+ strcpy(names, BOARD_CONFIG_PART);
+ nrparts++;
+ }
ret = nrparts;
*pparts = parts;
out:

View File

@ -1,32 +0,0 @@
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -574,6 +574,7 @@ struct platform_nand_chip {
int chip_delay;
unsigned int options;
const char **part_probe_types;
+ int (*chip_fixup)(struct mtd_info *mtd);
void *priv;
};
--- a/drivers/mtd/nand/plat_nand.c
+++ b/drivers/mtd/nand/plat_nand.c
@@ -71,7 +71,18 @@ static int __init plat_nand_probe(struct
platform_set_drvdata(pdev, data);
/* Scan to find existance of the device */
- if (nand_scan(&data->mtd, 1)) {
+ if (nand_scan_ident(&data->mtd, 1)) {
+ res = -ENXIO;
+ goto out;
+ }
+
+ if (pdata->chip.chip_fixup) {
+ res = pdata->chip.chip_fixup(&data->mtd);
+ if (res)
+ goto out;
+ }
+
+ if (nand_scan_tail(&data->mtd)) {
res = -ENXIO;
goto out;
}

View File

@ -1,35 +0,0 @@
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -180,6 +180,22 @@ config MTD_AR7_PARTS
---help---
TI AR7 partitioning support
+config MTD_MYLOADER_PARTS
+ tristate "MyLoader partition parsing"
+ depends on MTD_PARTITIONS && (ADM5120 || ATHEROS || ATHEROS_AR71XX)
+ ---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
@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdli
obj-$(CONFIG_MTD_AFS_PARTS) += afs.o
obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o
+obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
# 'Users' - code which presents functionality to userspace.
obj-$(CONFIG_MTD_CHAR) += mtdchar.o

View File

@ -1,11 +0,0 @@
--- a/drivers/mtd/myloader.c
+++ b/drivers/mtd/myloader.c
@@ -19,7 +19,7 @@
#include <linux/vmalloc.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
-#include <linux/byteorder/generic.h>
+#include <linux/byteorder.h>
#include <linux/myloader.h>
#define BLOCK_LEN_MIN 0x10000

View File

@ -1,12 +0,0 @@
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -492,8 +492,7 @@ int nand_correct_data(struct mtd_info *m
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);

View File

@ -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){

View File

@ -1,119 +0,0 @@
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -62,6 +62,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
@@ -88,6 +88,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,
@@ -147,13 +150,35 @@ ip_packet_match(const struct iphdr *ip,
return false;
}
+#undef FWINV
return true;
}
static bool
-ip_checkentry(const struct ipt_ip *ip)
+ip_checkentry(struct ipt_ip *ip)
{
- if (ip->flags & ~IPT_F_MASK) {
+#define FWINV(bool, invflg) ((bool) || (ip->invflags & (invflg)))
+
+ if (FWINV(ip->smsk.s_addr, IPT_INV_SRCIP) ||
+ FWINV(ip->dmsk.s_addr, IPT_INV_DSTIP))
+ goto has_match_rules;
+
+ if (FWINV(!!((const unsigned long *)ip->iniface_mask)[0],
+ IPT_INV_VIA_IN) ||
+ FWINV(!!((const unsigned long *)ip->outiface_mask)[0],
+ IPT_INV_VIA_OUT))
+ goto has_match_rules;
+
+ if (FWINV(ip->proto, IPT_INV_PROTO))
+ goto has_match_rules;
+
+ if (FWINV(ip->flags&IPT_F_FRAG, IPT_INV_FRAG))
+ goto has_match_rules;
+
+ ip->flags |= IPT_F_NO_DEF_MATCH;
+
+has_match_rules:
+ if (ip->flags & ~(IPT_F_MASK|IPT_F_NO_DEF_MATCH)) {
duprintf("Unknown flag bits set: %08X\n",
ip->flags & ~IPT_F_MASK);
return false;
@@ -163,6 +188,8 @@ ip_checkentry(const struct ipt_ip *ip)
ip->invflags & ~IPT_INV_MASK);
return false;
}
+
+#undef FWINV
return true;
}
@@ -210,7 +237,6 @@ unconditional(const struct ipt_ip *ip)
return 0;
return 1;
-#undef FWINV
}
#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
@@ -328,8 +354,27 @@ ipt_do_table(struct sk_buff *skb,
struct xt_match_param mtpar;
struct xt_target_param tgpar;
- /* Initialization */
ip = ip_hdr(skb);
+
+ read_lock_bh(&table->lock);
+ IP_NF_ASSERT(table->valid_hooks & (1 << hook));
+ private = table->private;
+ table_base = (void *)private->entries[smp_processor_id()];
+ e = get_entry(table_base, private->hook_entry[hook]);
+ if (e->target_offset <= sizeof(struct ipt_entry) &&
+ (e->ip.flags & IPT_F_NO_DEF_MATCH)) {
+ struct ipt_entry_target *t = ipt_get_target(e);
+ if (!t->u.kernel.target->target) {
+ int v = ((struct ipt_standard_target *)t)->verdict;
+ if ((v < 0) && (v != IPT_RETURN)) {
+ ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
+ read_unlock_bh(&table->lock);
+ return (unsigned)(-v) - 1;
+ }
+ }
+ }
+
+ /* Initialization */
datalen = skb->len - ip->ihl * 4;
indev = in ? in->name : nulldevname;
outdev = out ? out->name : nulldevname;
@@ -347,12 +392,6 @@ ipt_do_table(struct sk_buff *skb,
mtpar.family = tgpar.family = NFPROTO_IPV4;
tgpar.hooknum = hook;
- read_lock_bh(&table->lock);
- IP_NF_ASSERT(table->valid_hooks & (1 << hook));
- private = table->private;
- table_base = (void *)private->entries[smp_processor_id()];
- e = get_entry(table_base, private->hook_entry[hook]);
-
/* For return from builtin chain */
back = get_entry(table_base, private->underflow[hook]);

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +0,0 @@
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -160,7 +160,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
@@ -466,7 +465,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

View File

@ -1,793 +0,0 @@
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -182,8 +182,37 @@ struct tc_sfq_xstats
*
* The only reason for this is efficiency, it is possible
* to change these parameters in compile time.
+ *
+ * If you need to play with these values, use esfq instead.
*/
+/* ESFQ section */
+
+enum
+{
+ /* traditional */
+ TCA_SFQ_HASH_CLASSIC,
+ TCA_SFQ_HASH_DST,
+ TCA_SFQ_HASH_SRC,
+ TCA_SFQ_HASH_FWMARK,
+ /* conntrack */
+ TCA_SFQ_HASH_CTORIGDST,
+ TCA_SFQ_HASH_CTORIGSRC,
+ TCA_SFQ_HASH_CTREPLDST,
+ TCA_SFQ_HASH_CTREPLSRC,
+ TCA_SFQ_HASH_CTNATCHG,
+};
+
+struct tc_esfq_qopt
+{
+ unsigned quantum; /* Bytes per round allocated to flow */
+ int perturb_period; /* Period of hash perturbation */
+ __u32 limit; /* Maximal packets in queue */
+ unsigned divisor; /* Hash divisor */
+ unsigned flows; /* Maximal number of flows */
+ unsigned hash_kind; /* Hash function to use for flow identification */
+};
+
/* RED section */
enum
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -137,6 +137,37 @@ config NET_SCH_SFQ
To compile this code as a module, choose M here: the
module will be called sch_sfq.
+config NET_SCH_ESFQ
+ tristate "Enhanced Stochastic Fairness Queueing (ESFQ)"
+ ---help---
+ Say Y here if you want to use the Enhanced Stochastic Fairness
+ Queueing (ESFQ) packet scheduling algorithm for some of your network
+ devices or as a leaf discipline for a classful qdisc such as HTB or
+ CBQ (see the top of <file:net/sched/sch_esfq.c> for details and
+ references to the SFQ algorithm).
+
+ This is an enchanced SFQ version which allows you to control some
+ hardcoded values in the SFQ scheduler.
+
+ ESFQ also adds control of the hash function used to identify packet
+ flows. The original SFQ discipline hashes by connection; ESFQ add
+ several other hashing methods, such as by src IP or by dst IP, which
+ can be more fair to users in some networking situations.
+
+ To compile this code as a module, choose M here: the
+ module will be called sch_esfq.
+
+config NET_SCH_ESFQ_NFCT
+ bool "Connection Tracking Hash Types"
+ depends on NET_SCH_ESFQ && NF_CONNTRACK
+ ---help---
+ Say Y here to enable support for hashing based on netfilter connection
+ tracking information. This is useful for a router that is also using
+ NAT to connect privately-addressed hosts to the Internet. If you want
+ to provide fair distribution of upstream bandwidth, ESFQ must use
+ connection tracking information, since all outgoing packets will share
+ the same source address.
+
config NET_SCH_TEQL
tristate "True Link Equalizer (TEQL)"
---help---
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_NET_SCH_GRED) += sch_gred.o
obj-$(CONFIG_NET_SCH_INGRESS) += sch_ingress.o
obj-$(CONFIG_NET_SCH_DSMARK) += sch_dsmark.o
obj-$(CONFIG_NET_SCH_SFQ) += sch_sfq.o
+obj-$(CONFIG_NET_SCH_ESFQ) += sch_esfq.o
obj-$(CONFIG_NET_SCH_TBF) += sch_tbf.o
obj-$(CONFIG_NET_SCH_TEQL) += sch_teql.o
obj-$(CONFIG_NET_SCH_PRIO) += sch_prio.o
--- /dev/null
+++ b/net/sched/sch_esfq.c
@@ -0,0 +1,700 @@
+/*
+ * net/sched/sch_esfq.c Extended Stochastic Fairness Queueing discipline.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+ *
+ * Changes: Alexander Atanasov, <alex@ssi.bg>
+ * Added dynamic depth,limit,divisor,hash_kind options.
+ * Added dst and src hashes.
+ *
+ * Alexander Clouter, <alex@digriz.org.uk>
+ * Ported ESFQ to Linux 2.6.
+ *
+ * Corey Hickey, <bugfood-c@fatooh.org>
+ * Maintenance of the Linux 2.6 port.
+ * Added fwmark hash (thanks to Robert Kurjata).
+ * Added usage of jhash.
+ * Added conntrack support.
+ * Added ctnatchg hash (thanks to Ben Pfountz).
+ */
+
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <linux/bitops.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/jiffies.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/in.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/notifier.h>
+#include <linux/init.h>
+#include <net/ip.h>
+#include <net/netlink.h>
+#include <linux/ipv6.h>
+#include <net/route.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <net/pkt_sched.h>
+#include <linux/jhash.h>
+#include <net/netfilter/nf_conntrack.h>
+
+/* Stochastic Fairness Queuing algorithm.
+ For more comments look at sch_sfq.c.
+ The difference is that you can change limit, depth,
+ hash table size and choose alternate hash types.
+
+ classic: same as in sch_sfq.c
+ dst: destination IP address
+ src: source IP address
+ fwmark: netfilter mark value
+ ctorigdst: original destination IP address
+ ctorigsrc: original source IP address
+ ctrepldst: reply destination IP address
+ ctreplsrc: reply source IP
+
+*/
+
+#define ESFQ_HEAD 0
+#define ESFQ_TAIL 1
+
+/* This type should contain at least SFQ_DEPTH*2 values */
+typedef unsigned int esfq_index;
+
+struct esfq_head
+{
+ esfq_index next;
+ esfq_index prev;
+};
+
+struct esfq_sched_data
+{
+/* Parameters */
+ int perturb_period;
+ unsigned quantum; /* Allotment per round: MUST BE >= MTU */
+ int limit;
+ unsigned depth;
+ unsigned hash_divisor;
+ unsigned hash_kind;
+/* Variables */
+ struct timer_list perturb_timer;
+ int perturbation;
+ esfq_index tail; /* Index of current slot in round */
+ esfq_index max_depth; /* Maximal depth */
+
+ esfq_index *ht; /* Hash table */
+ esfq_index *next; /* Active slots link */
+ short *allot; /* Current allotment per slot */
+ unsigned short *hash; /* Hash value indexed by slots */
+ struct sk_buff_head *qs; /* Slot queue */
+ struct esfq_head *dep; /* Linked list of slots, indexed by depth */
+};
+
+/* This contains the info we will hash. */
+struct esfq_packet_info
+{
+ u32 proto; /* protocol or port */
+ u32 src; /* source from packet header */
+ u32 dst; /* destination from packet header */
+ u32 ctorigsrc; /* original source from conntrack */
+ u32 ctorigdst; /* original destination from conntrack */
+ u32 ctreplsrc; /* reply source from conntrack */
+ u32 ctrepldst; /* reply destination from conntrack */
+ u32 mark; /* netfilter mark (fwmark) */
+};
+
+static __inline__ unsigned esfq_jhash_1word(struct esfq_sched_data *q,u32 a)
+{
+ return jhash_1word(a, q->perturbation) & (q->hash_divisor-1);
+}
+
+static __inline__ unsigned esfq_jhash_2words(struct esfq_sched_data *q, u32 a, u32 b)
+{
+ return jhash_2words(a, b, q->perturbation) & (q->hash_divisor-1);
+}
+
+static __inline__ unsigned esfq_jhash_3words(struct esfq_sched_data *q, u32 a, u32 b, u32 c)
+{
+ return jhash_3words(a, b, c, q->perturbation) & (q->hash_divisor-1);
+}
+
+static unsigned esfq_hash(struct esfq_sched_data *q, struct sk_buff *skb)
+{
+ struct esfq_packet_info info;
+#ifdef CONFIG_NET_SCH_ESFQ_NFCT
+ enum ip_conntrack_info ctinfo;
+ struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
+#endif
+
+ switch (skb->protocol) {
+ case __constant_htons(ETH_P_IP):
+ {
+ struct iphdr *iph = ip_hdr(skb);
+ info.dst = iph->daddr;
+ info.src = iph->saddr;
+ if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
+ (iph->protocol == IPPROTO_TCP ||
+ iph->protocol == IPPROTO_UDP ||
+ iph->protocol == IPPROTO_SCTP ||
+ iph->protocol == IPPROTO_DCCP ||
+ iph->protocol == IPPROTO_ESP))
+ info.proto = *(((u32*)iph) + iph->ihl);
+ else
+ info.proto = iph->protocol;
+ break;
+ }
+ case __constant_htons(ETH_P_IPV6):
+ {
+ struct ipv6hdr *iph = ipv6_hdr(skb);
+ /* Hash ipv6 addresses into a u32. This isn't ideal,
+ * but the code is simple. */
+ info.dst = jhash2(iph->daddr.s6_addr32, 4, q->perturbation);
+ info.src = jhash2(iph->saddr.s6_addr32, 4, q->perturbation);
+ if (iph->nexthdr == IPPROTO_TCP ||
+ iph->nexthdr == IPPROTO_UDP ||
+ iph->nexthdr == IPPROTO_SCTP ||
+ iph->nexthdr == IPPROTO_DCCP ||
+ iph->nexthdr == IPPROTO_ESP)
+ info.proto = *(u32*)&iph[1];
+ else
+ info.proto = iph->nexthdr;
+ break;
+ }
+ default:
+ info.dst = (u32)(unsigned long)skb->dst;
+ info.src = (u32)(unsigned long)skb->sk;
+ info.proto = skb->protocol;
+ }
+
+ info.mark = skb->mark;
+
+#ifdef CONFIG_NET_SCH_ESFQ_NFCT
+ /* defaults if there is no conntrack info */
+ info.ctorigsrc = info.src;
+ info.ctorigdst = info.dst;
+ info.ctreplsrc = info.dst;
+ info.ctrepldst = info.src;
+ /* collect conntrack info */
+ if (ct && ct != &nf_conntrack_untracked) {
+ if (skb->protocol == __constant_htons(ETH_P_IP)) {
+ info.ctorigsrc = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip;
+ info.ctorigdst = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip;
+ info.ctreplsrc = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip;
+ info.ctrepldst = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip;
+ }
+ else if (skb->protocol == __constant_htons(ETH_P_IPV6)) {
+ /* Again, hash ipv6 addresses into a single u32. */
+ info.ctorigsrc = jhash2(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip6, 4, q->perturbation);
+ info.ctorigdst = jhash2(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip6, 4, q->perturbation);
+ info.ctreplsrc = jhash2(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip6, 4, q->perturbation);
+ info.ctrepldst = jhash2(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip6, 4, q->perturbation);
+ }
+
+ }
+#endif
+
+ switch(q->hash_kind) {
+ case TCA_SFQ_HASH_CLASSIC:
+ return esfq_jhash_3words(q, info.dst, info.src, info.proto);
+ case TCA_SFQ_HASH_DST:
+ return esfq_jhash_1word(q, info.dst);
+ case TCA_SFQ_HASH_SRC:
+ return esfq_jhash_1word(q, info.src);
+ case TCA_SFQ_HASH_FWMARK:
+ return esfq_jhash_1word(q, info.mark);
+#ifdef CONFIG_NET_SCH_ESFQ_NFCT
+ case TCA_SFQ_HASH_CTORIGDST:
+ return esfq_jhash_1word(q, info.ctorigdst);
+ case TCA_SFQ_HASH_CTORIGSRC:
+ return esfq_jhash_1word(q, info.ctorigsrc);
+ case TCA_SFQ_HASH_CTREPLDST:
+ return esfq_jhash_1word(q, info.ctrepldst);
+ case TCA_SFQ_HASH_CTREPLSRC:
+ return esfq_jhash_1word(q, info.ctreplsrc);
+ case TCA_SFQ_HASH_CTNATCHG:
+ {
+ if (info.ctorigdst == info.ctreplsrc)
+ return esfq_jhash_1word(q, info.ctorigsrc);
+ return esfq_jhash_1word(q, info.ctreplsrc);
+ }
+#endif
+ default:
+ if (net_ratelimit())
+ printk(KERN_WARNING "ESFQ: Unknown hash method. Falling back to classic.\n");
+ }
+ return esfq_jhash_3words(q, info.dst, info.src, info.proto);
+}
+
+static inline void esfq_link(struct esfq_sched_data *q, esfq_index x)
+{
+ esfq_index p, n;
+ int d = q->qs[x].qlen + q->depth;
+
+ p = d;
+ n = q->dep[d].next;
+ q->dep[x].next = n;
+ q->dep[x].prev = p;
+ q->dep[p].next = q->dep[n].prev = x;
+}
+
+static inline void esfq_dec(struct esfq_sched_data *q, esfq_index x)
+{
+ esfq_index p, n;
+
+ n = q->dep[x].next;
+ p = q->dep[x].prev;
+ q->dep[p].next = n;
+ q->dep[n].prev = p;
+
+ if (n == p && q->max_depth == q->qs[x].qlen + 1)
+ q->max_depth--;
+
+ esfq_link(q, x);
+}
+
+static inline void esfq_inc(struct esfq_sched_data *q, esfq_index x)
+{
+ esfq_index p, n;
+ int d;
+
+ n = q->dep[x].next;
+ p = q->dep[x].prev;
+ q->dep[p].next = n;
+ q->dep[n].prev = p;
+ d = q->qs[x].qlen;
+ if (q->max_depth < d)
+ q->max_depth = d;
+
+ esfq_link(q, x);
+}
+
+static unsigned int esfq_drop(struct Qdisc *sch)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ esfq_index d = q->max_depth;
+ struct sk_buff *skb;
+ unsigned int len;
+
+ /* Queue is full! Find the longest slot and
+ drop a packet from it */
+
+ if (d > 1) {
+ esfq_index x = q->dep[d+q->depth].next;
+ skb = q->qs[x].prev;
+ len = skb->len;
+ __skb_unlink(skb, &q->qs[x]);
+ kfree_skb(skb);
+ esfq_dec(q, x);
+ sch->q.qlen--;
+ sch->qstats.drops++;
+ sch->qstats.backlog -= len;
+ return len;
+ }
+
+ if (d == 1) {
+ /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */
+ d = q->next[q->tail];
+ q->next[q->tail] = q->next[d];
+ q->allot[q->next[d]] += q->quantum;
+ skb = q->qs[d].prev;
+ len = skb->len;
+ __skb_unlink(skb, &q->qs[d]);
+ kfree_skb(skb);
+ esfq_dec(q, d);
+ sch->q.qlen--;
+ q->ht[q->hash[d]] = q->depth;
+ sch->qstats.drops++;
+ sch->qstats.backlog -= len;
+ return len;
+ }
+
+ return 0;
+}
+
+static void esfq_q_enqueue(struct sk_buff *skb, struct esfq_sched_data *q, unsigned int end)
+{
+ unsigned hash = esfq_hash(q, skb);
+ unsigned depth = q->depth;
+ esfq_index x;
+
+ x = q->ht[hash];
+ if (x == depth) {
+ q->ht[hash] = x = q->dep[depth].next;
+ q->hash[x] = hash;
+ }
+
+ if (end == ESFQ_TAIL)
+ __skb_queue_tail(&q->qs[x], skb);
+ else
+ __skb_queue_head(&q->qs[x], skb);
+
+ esfq_inc(q, x);
+ if (q->qs[x].qlen == 1) { /* The flow is new */
+ if (q->tail == depth) { /* It is the first flow */
+ q->tail = x;
+ q->next[x] = x;
+ q->allot[x] = q->quantum;
+ } else {
+ q->next[x] = q->next[q->tail];
+ q->next[q->tail] = x;
+ q->tail = x;
+ }
+ }
+}
+
+static int esfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ esfq_q_enqueue(skb, q, ESFQ_TAIL);
+ sch->qstats.backlog += skb->len;
+ if (++sch->q.qlen < q->limit-1) {
+ sch->bstats.bytes += skb->len;
+ sch->bstats.packets++;
+ return 0;
+ }
+
+ sch->qstats.drops++;
+ esfq_drop(sch);
+ return NET_XMIT_CN;
+}
+
+static struct sk_buff *esfq_peek(struct Qdisc* sch)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ esfq_index a;
+
+ /* No active slots */
+ if (q->tail == q->depth)
+ return NULL;
+
+ a = q->next[q->tail];
+ return skb_peek(&q->qs[a]);
+}
+
+static struct sk_buff *esfq_q_dequeue(struct esfq_sched_data *q)
+{
+ struct sk_buff *skb;
+ unsigned depth = q->depth;
+ esfq_index a, old_a;
+
+ /* No active slots */
+ if (q->tail == depth)
+ return NULL;
+
+ a = old_a = q->next[q->tail];
+
+ /* Grab packet */
+ skb = __skb_dequeue(&q->qs[a]);
+ esfq_dec(q, a);
+
+ /* Is the slot empty? */
+ if (q->qs[a].qlen == 0) {
+ q->ht[q->hash[a]] = depth;
+ a = q->next[a];
+ if (a == old_a) {
+ q->tail = depth;
+ return skb;
+ }
+ q->next[q->tail] = a;
+ q->allot[a] += q->quantum;
+ } else if ((q->allot[a] -= skb->len) <= 0) {
+ q->tail = a;
+ a = q->next[a];
+ q->allot[a] += q->quantum;
+ }
+
+ return skb;
+}
+
+static struct sk_buff *esfq_dequeue(struct Qdisc* sch)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ struct sk_buff *skb;
+
+ skb = esfq_q_dequeue(q);
+ if (skb == NULL)
+ return NULL;
+ sch->q.qlen--;
+ sch->qstats.backlog -= skb->len;
+ return skb;
+}
+
+static void esfq_q_destroy(struct esfq_sched_data *q)
+{
+ del_timer(&q->perturb_timer);
+ if(q->ht)
+ kfree(q->ht);
+ if(q->dep)
+ kfree(q->dep);
+ if(q->next)
+ kfree(q->next);
+ if(q->allot)
+ kfree(q->allot);
+ if(q->hash)
+ kfree(q->hash);
+ if(q->qs)
+ kfree(q->qs);
+}
+
+static void esfq_destroy(struct Qdisc *sch)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ esfq_q_destroy(q);
+}
+
+
+static void esfq_reset(struct Qdisc* sch)
+{
+ struct sk_buff *skb;
+
+ while ((skb = esfq_dequeue(sch)) != NULL)
+ kfree_skb(skb);
+}
+
+static void esfq_perturbation(unsigned long arg)
+{
+ struct Qdisc *sch = (struct Qdisc*)arg;
+ struct esfq_sched_data *q = qdisc_priv(sch);
+
+ q->perturbation = net_random()&0x1F;
+
+ if (q->perturb_period) {
+ q->perturb_timer.expires = jiffies + q->perturb_period;
+ add_timer(&q->perturb_timer);
+ }
+}
+
+static unsigned int esfq_check_hash(unsigned int kind)
+{
+ switch (kind) {
+ case TCA_SFQ_HASH_CTORIGDST:
+ case TCA_SFQ_HASH_CTORIGSRC:
+ case TCA_SFQ_HASH_CTREPLDST:
+ case TCA_SFQ_HASH_CTREPLSRC:
+ case TCA_SFQ_HASH_CTNATCHG:
+#ifndef CONFIG_NET_SCH_ESFQ_NFCT
+ {
+ if (net_ratelimit())
+ printk(KERN_WARNING "ESFQ: Conntrack hash types disabled in kernel config. Falling back to classic.\n");
+ return TCA_SFQ_HASH_CLASSIC;
+ }
+#endif
+ case TCA_SFQ_HASH_CLASSIC:
+ case TCA_SFQ_HASH_DST:
+ case TCA_SFQ_HASH_SRC:
+ case TCA_SFQ_HASH_FWMARK:
+ return kind;
+ default:
+ {
+ if (net_ratelimit())
+ printk(KERN_WARNING "ESFQ: Unknown hash type. Falling back to classic.\n");
+ return TCA_SFQ_HASH_CLASSIC;
+ }
+ }
+}
+
+static int esfq_q_init(struct esfq_sched_data *q, struct nlattr *opt)
+{
+ struct tc_esfq_qopt *ctl = nla_data(opt);
+ esfq_index p = ~0U/2;
+ int i;
+
+ if (opt && opt->nla_len < nla_attr_size(sizeof(*ctl)))
+ return -EINVAL;
+
+ q->perturbation = 0;
+ q->hash_kind = TCA_SFQ_HASH_CLASSIC;
+ q->max_depth = 0;
+ if (opt == NULL) {
+ q->perturb_period = 0;
+ q->hash_divisor = 1024;
+ q->tail = q->limit = q->depth = 128;
+
+ } else {
+ struct tc_esfq_qopt *ctl = nla_data(opt);
+ if (ctl->quantum)
+ q->quantum = ctl->quantum;
+ q->perturb_period = ctl->perturb_period*HZ;
+ q->hash_divisor = ctl->divisor ? : 1024;
+ q->tail = q->limit = q->depth = ctl->flows ? : 128;
+
+ if ( q->depth > p - 1 )
+ return -EINVAL;
+
+ if (ctl->limit)
+ q->limit = min_t(u32, ctl->limit, q->depth);
+
+ if (ctl->hash_kind) {
+ q->hash_kind = esfq_check_hash(ctl->hash_kind);
+ }
+ }
+
+ q->ht = kmalloc(q->hash_divisor*sizeof(esfq_index), GFP_KERNEL);
+ if (!q->ht)
+ goto err_case;
+ q->dep = kmalloc((1+q->depth*2)*sizeof(struct esfq_head), GFP_KERNEL);
+ if (!q->dep)
+ goto err_case;
+ q->next = kmalloc(q->depth*sizeof(esfq_index), GFP_KERNEL);
+ if (!q->next)
+ goto err_case;
+ q->allot = kmalloc(q->depth*sizeof(short), GFP_KERNEL);
+ if (!q->allot)
+ goto err_case;
+ q->hash = kmalloc(q->depth*sizeof(unsigned short), GFP_KERNEL);
+ if (!q->hash)
+ goto err_case;
+ q->qs = kmalloc(q->depth*sizeof(struct sk_buff_head), GFP_KERNEL);
+ if (!q->qs)
+ goto err_case;
+
+ for (i=0; i< q->hash_divisor; i++)
+ q->ht[i] = q->depth;
+ for (i=0; i<q->depth; i++) {
+ skb_queue_head_init(&q->qs[i]);
+ q->dep[i+q->depth].next = i+q->depth;
+ q->dep[i+q->depth].prev = i+q->depth;
+ }
+
+ for (i=0; i<q->depth; i++)
+ esfq_link(q, i);
+ return 0;
+err_case:
+ esfq_q_destroy(q);
+ return -ENOBUFS;
+}
+
+static int esfq_init(struct Qdisc *sch, struct nlattr *opt)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ int err;
+
+ q->quantum = psched_mtu(qdisc_dev(sch)); /* default */
+ if ((err = esfq_q_init(q, opt)))
+ return err;
+
+ init_timer(&q->perturb_timer);
+ q->perturb_timer.data = (unsigned long)sch;
+ q->perturb_timer.function = esfq_perturbation;
+ if (q->perturb_period) {
+ q->perturb_timer.expires = jiffies + q->perturb_period;
+ add_timer(&q->perturb_timer);
+ }
+
+ return 0;
+}
+
+static int esfq_change(struct Qdisc *sch, struct nlattr *opt)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ struct esfq_sched_data new;
+ struct sk_buff *skb;
+ int err;
+
+ /* set up new queue */
+ memset(&new, 0, sizeof(struct esfq_sched_data));
+ new.quantum = psched_mtu(qdisc_dev(sch)); /* default */
+ if ((err = esfq_q_init(&new, opt)))
+ return err;
+
+ /* copy all packets from the old queue to the new queue */
+ sch_tree_lock(sch);
+ while ((skb = esfq_q_dequeue(q)) != NULL)
+ esfq_q_enqueue(skb, &new, ESFQ_TAIL);
+
+ /* clean up the old queue */
+ esfq_q_destroy(q);
+
+ /* copy elements of the new queue into the old queue */
+ q->perturb_period = new.perturb_period;
+ q->quantum = new.quantum;
+ q->limit = new.limit;
+ q->depth = new.depth;
+ q->hash_divisor = new.hash_divisor;
+ q->hash_kind = new.hash_kind;
+ q->tail = new.tail;
+ q->max_depth = new.max_depth;
+ q->ht = new.ht;
+ q->dep = new.dep;
+ q->next = new.next;
+ q->allot = new.allot;
+ q->hash = new.hash;
+ q->qs = new.qs;
+
+ /* finish up */
+ if (q->perturb_period) {
+ q->perturb_timer.expires = jiffies + q->perturb_period;
+ add_timer(&q->perturb_timer);
+ } else {
+ q->perturbation = 0;
+ }
+ sch_tree_unlock(sch);
+ return 0;
+}
+
+static int esfq_dump(struct Qdisc *sch, struct sk_buff *skb)
+{
+ struct esfq_sched_data *q = qdisc_priv(sch);
+ unsigned char *b = skb_tail_pointer(skb);
+ struct tc_esfq_qopt opt;
+
+ opt.quantum = q->quantum;
+ opt.perturb_period = q->perturb_period/HZ;
+
+ opt.limit = q->limit;
+ opt.divisor = q->hash_divisor;
+ opt.flows = q->depth;
+ opt.hash_kind = q->hash_kind;
+
+ NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+
+ return skb->len;
+
+nla_put_failure:
+ nlmsg_trim(skb, b);
+ return -1;
+}
+
+static struct Qdisc_ops esfq_qdisc_ops =
+{
+ .next = NULL,
+ .cl_ops = NULL,
+ .id = "esfq",
+ .priv_size = sizeof(struct esfq_sched_data),
+ .enqueue = esfq_enqueue,
+ .dequeue = esfq_dequeue,
+ .peek = esfq_peek,
+ .drop = esfq_drop,
+ .init = esfq_init,
+ .reset = esfq_reset,
+ .destroy = esfq_destroy,
+ .change = esfq_change,
+ .dump = esfq_dump,
+ .owner = THIS_MODULE,
+};
+
+static int __init esfq_module_init(void)
+{
+ return register_qdisc(&esfq_qdisc_ops);
+}
+static void __exit esfq_module_exit(void)
+{
+ unregister_qdisc(&esfq_qdisc_ops);
+}
+module_init(esfq_module_init)
+module_exit(esfq_module_exit)
+MODULE_LICENSE("GPL");

View File

@ -1,227 +0,0 @@
--- a/include/linux/jhash.h
+++ b/include/linux/jhash.h
@@ -3,80 +3,95 @@
/* jhash.h: Jenkins hash support.
*
- * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net)
+ * Copyright (C) 2006. Bob Jenkins (bob_jenkins@burtleburtle.net)
*
* http://burtleburtle.net/bob/hash/
*
* These are the credits from Bob's sources:
*
- * lookup2.c, by Bob Jenkins, December 1996, Public Domain.
- * hash(), hash2(), hash3, and mix() are externally useful functions.
- * Routines to test the hash are included if SELF_TEST is defined.
- * You can use this free for any purpose. It has no warranty.
+ * lookup3.c, by Bob Jenkins, May 2006, Public Domain.
*
- * Copyright (C) 2003 David S. Miller (davem@redhat.com)
+ * These are functions for producing 32-bit hashes for hash table lookup.
+ * hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
+ * are externally useful functions. Routines to test the hash are included
+ * if SELF_TEST is defined. You can use this free for any purpose. It's in
+ * the public domain. It has no warranty.
+ *
+ * Copyright (C) 2009 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu)
*
* I've modified Bob's hash to be useful in the Linux kernel, and
- * any bugs present are surely my fault. -DaveM
+ * any bugs present are my fault. Jozsef
*/
-/* NOTE: Arguments are modified. */
-#define __jhash_mix(a, b, c) \
+#define __rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
+
+/* __jhash_mix - mix 3 32-bit values reversibly. */
+#define __jhash_mix(a,b,c) \
+{ \
+ a -= c; a ^= __rot(c, 4); c += b; \
+ b -= a; b ^= __rot(a, 6); a += c; \
+ c -= b; c ^= __rot(b, 8); b += a; \
+ a -= c; a ^= __rot(c,16); c += b; \
+ b -= a; b ^= __rot(a,19); a += c; \
+ c -= b; c ^= __rot(b, 4); b += a; \
+}
+
+/* __jhash_final - final mixing of 3 32-bit values (a,b,c) into c */
+#define __jhash_final(a,b,c) \
{ \
- a -= b; a -= c; a ^= (c>>13); \
- b -= c; b -= a; b ^= (a<<8); \
- c -= a; c -= b; c ^= (b>>13); \
- a -= b; a -= c; a ^= (c>>12); \
- b -= c; b -= a; b ^= (a<<16); \
- c -= a; c -= b; c ^= (b>>5); \
- a -= b; a -= c; a ^= (c>>3); \
- b -= c; b -= a; b ^= (a<<10); \
- c -= a; c -= b; c ^= (b>>15); \
+ c ^= b; c -= __rot(b,14); \
+ a ^= c; a -= __rot(c,11); \
+ b ^= a; b -= __rot(a,25); \
+ c ^= b; c -= __rot(b,16); \
+ a ^= c; a -= __rot(c,4); \
+ b ^= a; b -= __rot(a,14); \
+ c ^= b; c -= __rot(b,24); \
}
-/* The golden ration: an arbitrary value */
-#define JHASH_GOLDEN_RATIO 0x9e3779b9
+/* An arbitrary initial parameter */
+#define JHASH_GOLDEN_RATIO 0xdeadbeef
/* The most generic version, hashes an arbitrary sequence
* of bytes. No alignment or length assumptions are made about
- * the input key.
+ * the input key. The result depends on endianness.
*/
static inline u32 jhash(const void *key, u32 length, u32 initval)
{
- u32 a, b, c, len;
+ u32 a,b,c;
const u8 *k = key;
- len = length;
- a = b = JHASH_GOLDEN_RATIO;
- c = initval;
-
- while (len >= 12) {
- a += (k[0] +((u32)k[1]<<8) +((u32)k[2]<<16) +((u32)k[3]<<24));
- b += (k[4] +((u32)k[5]<<8) +((u32)k[6]<<16) +((u32)k[7]<<24));
- c += (k[8] +((u32)k[9]<<8) +((u32)k[10]<<16)+((u32)k[11]<<24));
-
- __jhash_mix(a,b,c);
+ /* Set up the internal state */
+ a = b = c = JHASH_GOLDEN_RATIO + length + initval;
+ /* all but the last block: affect some 32 bits of (a,b,c) */
+ while (length > 12) {
+ a += (k[0] + ((u32)k[1]<<8) + ((u32)k[2]<<16) + ((u32)k[3]<<24));
+ b += (k[4] + ((u32)k[5]<<8) + ((u32)k[6]<<16) + ((u32)k[7]<<24));
+ c += (k[8] + ((u32)k[9]<<8) + ((u32)k[10]<<16) + ((u32)k[11]<<24));
+ __jhash_mix(a, b, c);
+ length -= 12;
k += 12;
- len -= 12;
}
- c += length;
- switch (len) {
- case 11: c += ((u32)k[10]<<24);
- case 10: c += ((u32)k[9]<<16);
- case 9 : c += ((u32)k[8]<<8);
- case 8 : b += ((u32)k[7]<<24);
- case 7 : b += ((u32)k[6]<<16);
- case 6 : b += ((u32)k[5]<<8);
+ /* last block: affect all 32 bits of (c) */
+ /* all the case statements fall through */
+ switch (length) {
+ case 12: c += (u32)k[11]<<24;
+ case 11: c += (u32)k[10]<<16;
+ case 10: c += (u32)k[9]<<8;
+ case 9 : c += k[8];
+ case 8 : b += (u32)k[7]<<24;
+ case 7 : b += (u32)k[6]<<16;
+ case 6 : b += (u32)k[5]<<8;
case 5 : b += k[4];
- case 4 : a += ((u32)k[3]<<24);
- case 3 : a += ((u32)k[2]<<16);
- case 2 : a += ((u32)k[1]<<8);
+ case 4 : a += (u32)k[3]<<24;
+ case 3 : a += (u32)k[2]<<16;
+ case 2 : a += (u32)k[1]<<8;
case 1 : a += k[0];
- };
-
- __jhash_mix(a,b,c);
+ __jhash_final(a, b, c);
+ case 0 :
+ break;
+ }
return c;
}
@@ -86,58 +101,57 @@ static inline u32 jhash(const void *key,
*/
static inline u32 jhash2(const u32 *k, u32 length, u32 initval)
{
- u32 a, b, c, len;
+ u32 a, b, c;
- a = b = JHASH_GOLDEN_RATIO;
- c = initval;
- len = length;
+ /* Set up the internal state */
+ a = b = c = JHASH_GOLDEN_RATIO + (length<<2) + initval;
- while (len >= 3) {
+ /* handle most of the key */
+ while (length > 3) {
a += k[0];
b += k[1];
c += k[2];
__jhash_mix(a, b, c);
- k += 3; len -= 3;
+ length -= 3;
+ k += 3;
}
- c += length * 4;
-
- switch (len) {
- case 2 : b += k[1];
- case 1 : a += k[0];
- };
-
- __jhash_mix(a,b,c);
+ /* handle the last 3 u32's */
+ /* all the case statements fall through */
+ switch (length) {
+ case 3: c += k[2];
+ case 2: b += k[1];
+ case 1: a += k[0];
+ __jhash_final(a, b, c);
+ case 0: /* case 0: nothing left to add */
+ break;
+ }
return c;
}
-
/* A special ultra-optimized versions that knows they are hashing exactly
* 3, 2 or 1 word(s).
- *
- * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally
- * done at the end is not done here.
*/
static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)
{
- a += JHASH_GOLDEN_RATIO;
- b += JHASH_GOLDEN_RATIO;
- c += initval;
+ a += JHASH_GOLDEN_RATIO + initval;
+ b += JHASH_GOLDEN_RATIO + initval;
+ c += JHASH_GOLDEN_RATIO + initval;
- __jhash_mix(a, b, c);
+ __jhash_final(a, b, c);
return c;
}
static inline u32 jhash_2words(u32 a, u32 b, u32 initval)
{
- return jhash_3words(a, b, 0, initval);
+ return jhash_3words(0, a, b, initval);
}
static inline u32 jhash_1word(u32 a, u32 initval)
{
- return jhash_3words(a, 0, 0, initval);
+ return jhash_3words(0, 0, a, initval);
}
#endif /* _LINUX_JHASH_H */

View File

@ -1,12 +0,0 @@
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -609,6 +609,9 @@ else
load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff81100000
endif
+# temporary until string.h is fixed
+cflags-y += -ffreestanding
+
cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
drivers-$(CONFIG_PCI) += arch/mips/pci/

View File

@ -1,13 +0,0 @@
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -115,8 +115,8 @@ int kmem_ptr_validate(struct kmem_cache
* to do various tricks to work around compiler limitations in order to
* ensure proper constant folding.
*/
-#define KMALLOC_SHIFT_HIGH ((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \
- (MAX_ORDER + PAGE_SHIFT - 1) : 25)
+#define KMALLOC_SHIFT_HIGH ((MAX_ORDER + PAGE_SHIFT - 1) <= 17 ? \
+ (MAX_ORDER + PAGE_SHIFT - 1) : 17)
#define KMALLOC_MAX_SIZE (1UL << KMALLOC_SHIFT_HIGH)
#define KMALLOC_MAX_ORDER (KMALLOC_SHIFT_HIGH - PAGE_SHIFT)

View File

@ -1,132 +0,0 @@
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -111,6 +111,17 @@ 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__);
+ if (c->mtd->unlock)
+ c->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
@@ -72,7 +72,7 @@ static int file_dirty(struct jffs2_sb_in
return ret;
if ((ret = jffs2_scan_dirty_space(c, jeb, jeb->free_size)))
return ret;
- /* Turned wasted size into dirty, since we apparently
+ /* Turned wasted size into dirty, since we apparently
think it's recoverable now. */
jeb->dirty_size += jeb->wasted_size;
c->dirty_size += jeb->wasted_size;
@@ -144,8 +144,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;
@@ -400,7 +403,7 @@ static int jffs2_scan_xref_node(struct j
if (!ref)
return -ENOMEM;
- /* BEFORE jffs2_build_xattr_subsystem() called,
+ /* BEFORE jffs2_build_xattr_subsystem() called,
* and AFTER xattr_ref is marked as a dead xref,
* ref->xid is used to store 32bit xid, xd is not used
* ref->ino is used to store 32bit inode-number, ic is not used
@@ -473,7 +476,7 @@ static int jffs2_scan_eraseblock (struct
struct jffs2_sum_marker *sm;
void *sumptr = NULL;
uint32_t sumlen;
-
+
if (!buf_size) {
/* XIP case. Just look, point at the summary if it's there */
sm = (void *)buf + c->sector_size - sizeof(*sm);
@@ -489,9 +492,9 @@ static int jffs2_scan_eraseblock (struct
buf_len = sizeof(*sm);
/* Read as much as we want into the _end_ of the preallocated buffer */
- err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len,
+ err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len,
jeb->offset + c->sector_size - buf_len,
- buf_len);
+ buf_len);
if (err)
return err;
@@ -510,9 +513,9 @@ static int jffs2_scan_eraseblock (struct
}
if (buf_len < sumlen) {
/* Need to read more so that the entire summary node is present */
- err = jffs2_fill_scan_buf(c, sumptr,
+ err = jffs2_fill_scan_buf(c, sumptr,
jeb->offset + c->sector_size - sumlen,
- sumlen - buf_len);
+ sumlen - buf_len);
if (err)
return err;
}
@@ -525,7 +528,7 @@ static int jffs2_scan_eraseblock (struct
if (buf_size && sumlen > buf_size)
kfree(sumptr);
- /* If it returns with a real error, bail.
+ /* If it returns with a real error, bail.
If it returns positive, that's a block classification
(i.e. BLK_STATE_xxx) so return that too.
If it returns zero, fall through to full scan. */
@@ -546,6 +549,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;
@@ -671,7 +685,7 @@ scan_more:
scan_end = buf_len;
goto more_empty;
}
-
+
/* See how much more there is to read in this eraseblock... */
buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
if (!buf_len) {
@@ -907,7 +921,7 @@ scan_more:
D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x, wasted 0x%08x\n",
jeb->offset,jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size, jeb->wasted_size));
-
+
/* mark_node_obsolete can add to wasted !! */
if (jeb->wasted_size) {
jeb->dirty_size += jeb->wasted_size;

View File

@ -1,56 +0,0 @@
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1306,11 +1306,18 @@ static inline int skb_network_offset(con
*
* Various parts of the networking layer expect at least 16 bytes of
* headroom, you should not reduce this.
+ *
+ * This has been changed to 64 to acommodate for routing between ethernet
+ * and wireless, but only for new allocations
*/
#ifndef NET_SKB_PAD
#define NET_SKB_PAD 16
#endif
+#ifndef NET_SKB_PAD_ALLOC
+#define NET_SKB_PAD_ALLOC 64
+#endif
+
extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
@@ -1400,9 +1407,9 @@ static inline void __skb_queue_purge(str
static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
gfp_t gfp_mask)
{
- struct sk_buff *skb = alloc_skb(length + NET_SKB_PAD, gfp_mask);
+ struct sk_buff *skb = alloc_skb(length + NET_SKB_PAD_ALLOC, gfp_mask);
if (likely(skb))
- skb_reserve(skb, NET_SKB_PAD);
+ skb_reserve(skb, NET_SKB_PAD_ALLOC);
return skb;
}
@@ -1475,7 +1482,7 @@ static inline int __skb_cow(struct sk_bu
delta = headroom - skb_headroom(skb);
if (delta || cloned)
- return pskb_expand_head(skb, ALIGN(delta, NET_SKB_PAD), 0,
+ return pskb_expand_head(skb, ALIGN(delta, NET_SKB_PAD_ALLOC), 0,
GFP_ATOMIC);
return 0;
}
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -320,9 +320,9 @@ struct sk_buff *__netdev_alloc_skb(struc
int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
struct sk_buff *skb;
- skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node);
+ skb = __alloc_skb(length + NET_SKB_PAD_ALLOC, gfp_mask, 0, node);
if (likely(skb)) {
- skb_reserve(skb, NET_SKB_PAD);
+ skb_reserve(skb, NET_SKB_PAD_ALLOC);
skb->dev = dev;
}
return skb;

View File

@ -1,9 +0,0 @@
--- /dev/null
+++ b/include/asm-powerpc/segment.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_SEGMENT_H
+#define _ASM_SEGMENT_H
+
+/* Only here because we have some old header files that expect it.. */
+
+#endif /* _ASM_SEGMENT_H */

View File

@ -1,42 +0,0 @@
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1889,7 +1889,7 @@ static const struct rtl_cfg_info {
.hw_start = rtl_hw_start_8169,
.region = 1,
.align = 0,
- .intr_event = SYSErr | LinkChg | RxOverflow |
+ .intr_event = LinkChg | RxOverflow |
RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
.napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
.features = RTL_FEATURE_GMII
@@ -1898,7 +1898,7 @@ static const struct rtl_cfg_info {
.hw_start = rtl_hw_start_8168,
.region = 2,
.align = 8,
- .intr_event = SYSErr | LinkChg | RxOverflow |
+ .intr_event = LinkChg | RxOverflow |
TxErr | TxOK | RxOK | RxErr,
.napi_event = TxErr | TxOK | RxOK | RxOverflow,
.features = RTL_FEATURE_GMII | RTL_FEATURE_MSI
@@ -1907,7 +1907,7 @@ static const struct rtl_cfg_info {
.hw_start = rtl_hw_start_8101,
.region = 2,
.align = 8,
- .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout |
+ .intr_event = LinkChg | RxOverflow | PCSTimeout |
RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
.napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
.features = RTL_FEATURE_MSI
@@ -3576,10 +3576,12 @@ static irqreturn_t rtl8169_interrupt(int
break;
}
+#if 0
if (unlikely(status & SYSErr)) {
rtl8169_pcierr_interrupt(dev);
break;
}
+#endif
if (status & LinkChg)
rtl8169_check_link_status(dev, tp, ioaddr);

File diff suppressed because it is too large Load Diff

View File

@ -1,143 +0,0 @@
--- a/fs/mini_fo/main.c
+++ b/fs/mini_fo/main.c
@@ -79,6 +79,7 @@ mini_fo_tri_interpose(dentry_t *hidden_d
* of the new inode's fields
*/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
/*
* original: inode = iget(sb, hidden_inode->i_ino);
*/
@@ -87,6 +88,13 @@ mini_fo_tri_interpose(dentry_t *hidden_d
err = -EACCES; /* should be impossible??? */
goto out;
}
+#else
+ inode = mini_fo_iget(sb, iunique(sb, 25));
+ if (IS_ERR(inode)) {
+ err = PTR_ERR(inode);
+ goto out;
+ }
+#endif
/*
* interpose the inode if not already interposed
@@ -184,9 +192,9 @@ mini_fo_parse_options(super_block_t *sb,
hidden_root = ERR_PTR(err);
goto out;
}
- hidden_root = nd.dentry;
- stopd(sb)->base_dir_dentry = nd.dentry;
- stopd(sb)->hidden_mnt = nd.mnt;
+ hidden_root = nd_get_dentry(&nd);
+ stopd(sb)->base_dir_dentry = nd_get_dentry(&nd);
+ stopd(sb)->hidden_mnt = nd_get_mnt(&nd);
} else if(!strncmp("sto=", options, 4)) {
/* parse the storage dir */
@@ -204,9 +212,9 @@ mini_fo_parse_options(super_block_t *sb,
hidden_root2 = ERR_PTR(err);
goto out;
}
- hidden_root2 = nd2.dentry;
- stopd(sb)->storage_dir_dentry = nd2.dentry;
- stopd(sb)->hidden_mnt2 = nd2.mnt;
+ hidden_root2 = nd_get_dentry(&nd2);
+ stopd(sb)->storage_dir_dentry = nd_get_dentry(&nd2);
+ stopd(sb)->hidden_mnt2 = nd_get_mnt(&nd2);
stohs2(sb) = hidden_root2->d_sb;
/* validate storage dir, this is done in
--- a/fs/mini_fo/mini_fo.h
+++ b/fs/mini_fo/mini_fo.h
@@ -302,6 +302,10 @@ extern int mini_fo_tri_interpose(dentry_
extern int mini_fo_cp_cont(dentry_t *tgt_dentry, struct vfsmount *tgt_mnt,
dentry_t *src_dentry, struct vfsmount *src_mnt);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
+extern struct inode *mini_fo_iget(struct super_block *sb, unsigned long ino);
+#endif
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd);
@@ -501,6 +505,29 @@ static inline void double_unlock(struct
#endif /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */
#endif /* __KERNEL__ */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
+static inline dentry_t *nd_get_dentry(struct nameidata *nd)
+{
+ return (nd->path.dentry);
+}
+
+static inline struct vfsmount *nd_get_mnt(struct nameidata *nd)
+{
+ return (nd->path.mnt);
+}
+#else
+static inline dentry_t *nd_get_dentry(struct nameidata *nd)
+{
+ return (nd->dentry);
+}
+
+static inline struct vfsmount *nd_get_mnt(struct nameidata *nd)
+{
+ return (nd->mnt);
+}
+#endif
+
/*
* Definitions for user and kernel code
*/
--- a/fs/mini_fo/super.c
+++ b/fs/mini_fo/super.c
@@ -262,10 +262,31 @@ mini_fo_umount_begin(super_block_t *sb)
}
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
+struct inode *
+mini_fo_iget(struct super_block *sb, unsigned long ino)
+{
+ struct inode *inode;
+
+ inode = iget_locked(sb, ino);
+ if (!inode)
+ return ERR_PTR(-ENOMEM);
+
+ if (!(inode->i_state & I_NEW))
+ return inode;
+
+ mini_fo_read_inode(inode);
+
+ unlock_new_inode(inode);
+ return inode;
+}
+#endif /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) */
struct super_operations mini_fo_sops =
{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
read_inode: mini_fo_read_inode,
+#endif
#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA)
write_inode: mini_fo_write_inode,
#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
--- a/fs/mini_fo/aux.c
+++ b/fs/mini_fo/aux.c
@@ -164,11 +164,11 @@ dentry_t *bpath_walk(super_block_t *sb,
err = vfs_path_lookup(mnt->mnt_root, mnt, bpath+1, 0, &nd);
/* validate */
- if (err || !nd.dentry || !nd.dentry->d_inode) {
+ if (err || !nd_get_dentry(&nd) || !nd_get_dentry(&nd)->d_inode) {
printk(KERN_CRIT "mini_fo: bpath_walk: path_walk failed.\n");
return NULL;
}
- return nd.dentry;
+ return nd_get_dentry(&nd);
}

View File

@ -1,66 +0,0 @@
--- a/fs/mini_fo/meta.c
+++ b/fs/mini_fo/meta.c
@@ -442,6 +442,11 @@ int meta_write_d_entry(dentry_t *dentry,
S_IRUSR | S_IWUSR);
#endif
}
+
+ /* $%& err, is this correct? */
+ meta_mnt = stopd(dentry->d_inode->i_sb)->hidden_mnt2;
+ mntget(meta_mnt);
+
/* open META-file for writing */
meta_file = dentry_open(meta_dentry, meta_mnt, 0x1);
if(!meta_file || IS_ERR(meta_file)) {
@@ -535,6 +540,11 @@ int meta_write_r_entry(dentry_t *dentry,
meta_dentry, S_IRUSR | S_IWUSR);
#endif
}
+
+ /* $%& err, is this correct? */
+ meta_mnt = stopd(dentry->d_inode->i_sb)->hidden_mnt2;
+ mntget(meta_mnt);
+
/* open META-file for writing */
meta_file = dentry_open(meta_dentry, meta_mnt, 0x1);
if(!meta_file || IS_ERR(meta_file)) {
@@ -671,14 +681,16 @@ int meta_sync_d_list(dentry_t *dentry, i
}
}
+ /* $%& err, is this correct? */
+ meta_mnt = stopd(dentry->d_inode->i_sb)->hidden_mnt2;
+ mntget(meta_mnt);
+
/* open META-file for writing */
meta_file = dentry_open(meta_dentry, meta_mnt, 0x1);
if(!meta_file || IS_ERR(meta_file)) {
printk(KERN_CRIT "mini_fo: meta_sync_d_list: \
ERROR opening meta file.\n");
- /* we don't mntget so we dont't mntput (for now)
- * mntput(meta_mnt);
- */
+ mntput(meta_mnt);
dput(meta_dentry);
err = -1;
goto out;
@@ -811,14 +823,16 @@ int meta_sync_r_list(dentry_t *dentry, i
}
}
+ /* $%& err, is this correct? */
+ meta_mnt = stopd(dentry->d_inode->i_sb)->hidden_mnt2;
+ mntget(meta_mnt);
+
/* open META-file for writing */
meta_file = dentry_open(meta_dentry, meta_mnt, 0x1);
if(!meta_file || IS_ERR(meta_file)) {
printk(KERN_CRIT "mini_fo: meta_sync_r_list: \
ERROR opening meta file.\n");
- /* we don't mntget so we dont't mntput (for now)
- * mntput(meta_mnt);
- */
+ mntput(meta_mnt);
dput(meta_dentry);
err = -1;
goto out;

View File

@ -1,37 +0,0 @@
--- a/fs/mini_fo/super.c
+++ b/fs/mini_fo/super.c
@@ -84,6 +84,7 @@ mini_fo_write_inode(inode_t *inode, int
#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
STATIC void
mini_fo_put_inode(inode_t *inode)
{
@@ -99,6 +100,7 @@ mini_fo_put_inode(inode_t *inode)
if (atomic_read(&inode->i_count) == 1)
inode->i_nlink = 0;
}
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) */
#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA)
@@ -238,7 +240,7 @@ mini_fo_clear_inode(inode_t *inode)
* dies.
*/
STATIC void
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26))
mini_fo_umount_begin(struct vfsmount *mnt, int flags)
{
struct vfsmount *hidden_mnt;
@@ -290,7 +292,9 @@ struct super_operations mini_fo_sops =
#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA)
write_inode: mini_fo_write_inode,
#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
put_inode: mini_fo_put_inode,
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) */
#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA)
delete_inode: mini_fo_delete_inode,
#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */

View File

@ -1,41 +0,0 @@
--- a/fs/mini_fo/inode.c
+++ b/fs/mini_fo/inode.c
@@ -439,7 +439,7 @@ mini_fo_symlink(inode_t *dir, dentry_t *
int err=0;
dentry_t *hidden_sto_dentry;
dentry_t *hidden_sto_dir_dentry;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
umode_t mode;
#endif
@@ -466,7 +466,7 @@ mini_fo_symlink(inode_t *dir, dentry_t *
down(&hidden_sto_dir_dentry->d_inode->i_sem);
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
mode = S_IALLUGO;
err = vfs_symlink(hidden_sto_dir_dentry->d_inode,
hidden_sto_dentry, symname, mode);
@@ -1128,7 +1128,7 @@ void mini_fo_put_link(struct dentry *den
#endif
STATIC int
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
mini_fo_permission(inode_t *inode, int mask, struct nameidata *nd)
#else
mini_fo_permission(inode_t *inode, int mask)
@@ -1150,8 +1150,9 @@ mini_fo_permission(inode_t *inode, int m
* if (err)
* goto out;
*/
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+ err = inode_permission(hidden_inode, mask);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
err = permission(hidden_inode, mask, nd);
#else
err = permission(hidden_inode, mask);

View File

@ -1,96 +0,0 @@
--- a/fs/mini_fo/aux.c
+++ b/fs/mini_fo/aux.c
@@ -236,7 +236,7 @@ int mini_fo_cp_cont(dentry_t *tgt_dentry
mntget(src_mnt);
/* open file write only */
- tgt_file = dentry_open(tgt_dentry, tgt_mnt, 0x1);
+ tgt_file = dentry_open(tgt_dentry, tgt_mnt, 0x1, current_cred());
if(!tgt_file || IS_ERR(tgt_file)) {
printk(KERN_CRIT "mini_fo_cp_cont: ERROR opening target file.\n");
err = PTR_ERR(tgt_file);
@@ -244,7 +244,7 @@ int mini_fo_cp_cont(dentry_t *tgt_dentry
}
/* open file read only */
- src_file = dentry_open(src_dentry, src_mnt, 0x0);
+ src_file = dentry_open(src_dentry, src_mnt, 0x0, current_cred());
if(!src_file || IS_ERR(src_file)) {
printk(KERN_CRIT "mini_fo_cp_cont: ERROR opening source file.\n");
err = PTR_ERR(src_file);
--- a/fs/mini_fo/file.c
+++ b/fs/mini_fo/file.c
@@ -437,7 +437,7 @@ mini_fo_open(inode_t *inode, file_t *fil
mntget(stopd(inode->i_sb)->hidden_mnt);
hidden_file = dentry_open(hidden_dentry,
stopd(inode->i_sb)->hidden_mnt,
- hidden_flags);
+ hidden_flags, file->f_cred);
if (IS_ERR(hidden_file)) {
err = PTR_ERR(hidden_file);
dput(hidden_dentry);
@@ -479,7 +479,7 @@ mini_fo_open(inode_t *inode, file_t *fil
mntget(stopd(inode->i_sb)->hidden_mnt);
hidden_file = dentry_open(hidden_dentry,
stopd(inode->i_sb)->hidden_mnt,
- hidden_flags);
+ hidden_flags, file->f_cred);
if (IS_ERR(hidden_file)) {
err = PTR_ERR(hidden_file);
dput(hidden_dentry);
@@ -512,7 +512,7 @@ mini_fo_open(inode_t *inode, file_t *fil
mntget(stopd(inode->i_sb)->hidden_mnt2);
hidden_sto_file = dentry_open(hidden_sto_dentry,
stopd(inode->i_sb)->hidden_mnt2,
- hidden_flags);
+ hidden_flags, file->f_cred);
/* dentry_open dputs the dentry if it fails */
if (IS_ERR(hidden_sto_file)) {
--- a/fs/mini_fo/meta.c
+++ b/fs/mini_fo/meta.c
@@ -56,7 +56,7 @@ int meta_build_lists(dentry_t *dentry)
/* open META-file for reading */
- meta_file = dentry_open(meta_dentry, meta_mnt, 0x0);
+ meta_file = dentry_open(meta_dentry, meta_mnt, 0x0, current_cred());
if(!meta_file || IS_ERR(meta_file)) {
printk(KERN_CRIT "mini_fo: meta_build_lists: \
ERROR opening META file.\n");
@@ -448,7 +448,7 @@ int meta_write_d_entry(dentry_t *dentry,
mntget(meta_mnt);
/* open META-file for writing */
- meta_file = dentry_open(meta_dentry, meta_mnt, 0x1);
+ meta_file = dentry_open(meta_dentry, meta_mnt, 0x1, current_cred());
if(!meta_file || IS_ERR(meta_file)) {
printk(KERN_CRIT "mini_fo: meta_write_d_entry: \
ERROR opening meta file.\n");
@@ -546,7 +546,7 @@ int meta_write_r_entry(dentry_t *dentry,
mntget(meta_mnt);
/* open META-file for writing */
- meta_file = dentry_open(meta_dentry, meta_mnt, 0x1);
+ meta_file = dentry_open(meta_dentry, meta_mnt, 0x1, current_cred());
if(!meta_file || IS_ERR(meta_file)) {
printk(KERN_CRIT "mini_fo: meta_write_r_entry: \
ERROR opening meta file.\n");
@@ -686,7 +686,7 @@ int meta_sync_d_list(dentry_t *dentry, i
mntget(meta_mnt);
/* open META-file for writing */
- meta_file = dentry_open(meta_dentry, meta_mnt, 0x1);
+ meta_file = dentry_open(meta_dentry, meta_mnt, 0x1, current_cred());
if(!meta_file || IS_ERR(meta_file)) {
printk(KERN_CRIT "mini_fo: meta_sync_d_list: \
ERROR opening meta file.\n");
@@ -828,7 +828,7 @@ int meta_sync_r_list(dentry_t *dentry, i
mntget(meta_mnt);
/* open META-file for writing */
- meta_file = dentry_open(meta_dentry, meta_mnt, 0x1);
+ meta_file = dentry_open(meta_dentry, meta_mnt, 0x1, current_cred());
if(!meta_file || IS_ERR(meta_file)) {
printk(KERN_CRIT "mini_fo: meta_sync_r_list: \
ERROR opening meta file.\n");

View File

@ -1,42 +0,0 @@
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -29,7 +29,8 @@ u64 uevent_seqnum;
char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH;
static DEFINE_SPINLOCK(sequence_lock);
#if defined(CONFIG_NET)
-static struct sock *uevent_sock;
+struct sock *uevent_sock = NULL;
+EXPORT_SYMBOL_GPL(uevent_sock);
#endif
/* the strings here must match the enum in include/linux/kobject.h */
@@ -42,6 +43,18 @@ static const char *kobject_actions[] = {
[KOBJ_OFFLINE] = "offline",
};
+u64 uevent_next_seqnum(void)
+{
+ u64 seq;
+
+ spin_lock(&sequence_lock);
+ seq = ++uevent_seqnum;
+ spin_unlock(&sequence_lock);
+
+ return seq;
+}
+EXPORT_SYMBOL_GPL(uevent_next_seqnum);
+
/**
* kobject_action_type - translate action string to numeric type
*
@@ -194,9 +207,7 @@ int kobject_uevent_env(struct kobject *k
kobj->state_remove_uevent_sent = 1;
/* we will send an event, so request a new sequence number */
- spin_lock(&sequence_lock);
- seq = ++uevent_seqnum;
- spin_unlock(&sequence_lock);
+ seq = uevent_next_seqnum();
retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)seq);
if (retval)
goto exit;

View File

@ -1,11 +0,0 @@
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -7,7 +7,7 @@ config SND_PCM
select SND_TIMER
config SND_HWDEP
- tristate
+ tristate "Sound hardware support"
config SND_RAWMIDI
tristate

View File

@ -1,11 +0,0 @@
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1211,7 +1211,7 @@ static unsigned long vma_dump_size(struc
if (FILTER(ELF_HEADERS) &&
vma->vm_pgoff == 0 && (vma->vm_flags & VM_READ)) {
u32 __user *header = (u32 __user *) vma->vm_start;
- u32 word;
+ u32 word = 0;
mm_segment_t fs = get_fs();
/*
* Doing it this way gets the constant folded by GCC.

View File

@ -1,132 +0,0 @@
This patch allows the user to specify desired packet types (outgoing,
broadcast, unicast, etc.) on packet sockets via setsockopt.
This can reduce the load in situations where only a limited number
of packet types are necessary
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
--- a/include/linux/if_packet.h
+++ b/include/linux/if_packet.h
@@ -31,6 +31,8 @@ struct sockaddr_ll
/* These ones are invisible by user level */
#define PACKET_LOOPBACK 5 /* MC/BRD frame looped back */
#define PACKET_FASTROUTE 6 /* Fastrouted frame */
+#define PACKET_MASK_ANY 0xffffffff /* mask for packet type bits */
+
/* Packet socket options */
@@ -46,6 +48,7 @@ struct sockaddr_ll
#define PACKET_VERSION 10
#define PACKET_HDRLEN 11
#define PACKET_RESERVE 12
+#define PACKET_RECV_TYPE 13
struct tpacket_stats
{
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -192,6 +192,7 @@ struct packet_sock {
unsigned int tp_hdrlen;
unsigned int tp_reserve;
#endif
+ unsigned int pkt_type;
};
struct packet_skb_cb {
@@ -282,6 +283,7 @@ static int packet_rcv_spkt(struct sk_buf
{
struct sock *sk;
struct sockaddr_pkt *spkt;
+ struct packet_sock *po;
/*
* When we registered the protocol we saved the socket in the data
@@ -289,6 +291,7 @@ static int packet_rcv_spkt(struct sk_buf
*/
sk = pt->af_packet_priv;
+ po = pkt_sk(sk);
/*
* Yank back the headers [hope the device set this
@@ -301,7 +304,7 @@ static int packet_rcv_spkt(struct sk_buf
* so that this procedure is noop.
*/
- if (skb->pkt_type == PACKET_LOOPBACK)
+ if (!(po->pkt_type & (1 << skb->pkt_type)))
goto out;
if (dev_net(dev) != sock_net(sk))
@@ -486,12 +489,12 @@ static int packet_rcv(struct sk_buff *sk
int skb_len = skb->len;
unsigned int snaplen, res;
- if (skb->pkt_type == PACKET_LOOPBACK)
- goto drop;
-
sk = pt->af_packet_priv;
po = pkt_sk(sk);
+ if (!(po->pkt_type & (1 << skb->pkt_type)))
+ goto drop;
+
if (dev_net(dev) != sock_net(sk))
goto drop;
@@ -608,12 +611,12 @@ static int tpacket_rcv(struct sk_buff *s
struct timeval tv;
struct timespec ts;
- if (skb->pkt_type == PACKET_LOOPBACK)
- goto drop;
-
sk = pt->af_packet_priv;
po = pkt_sk(sk);
+ if (!(po->pkt_type & (1 << skb->pkt_type)))
+ goto drop;
+
if (dev_net(dev) != sock_net(sk))
goto drop;
@@ -1073,6 +1076,7 @@ static int packet_create(struct net *net
spin_lock_init(&po->bind_lock);
mutex_init(&po->pg_vec_lock);
po->prot_hook.func = packet_rcv;
+ po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK);
if (sock->type == SOCK_PACKET)
po->prot_hook.func = packet_rcv_spkt;
@@ -1413,6 +1417,16 @@ packet_setsockopt(struct socket *sock, i
ret = packet_mc_drop(sk, &mreq);
return ret;
}
+ case PACKET_RECV_TYPE:
+ {
+ unsigned int val;
+ if (optlen != sizeof(val))
+ return -EINVAL;
+ if (copy_from_user(&val, optval, sizeof(val)))
+ return -EFAULT;
+ po->pkt_type = val & ~PACKET_LOOPBACK;
+ return 0;
+ }
#ifdef CONFIG_PACKET_MMAP
case PACKET_RX_RING:
@@ -1544,6 +1558,13 @@ static int packet_getsockopt(struct sock
data = &val;
break;
+ case PACKET_RECV_TYPE:
+ if (len > sizeof(unsigned int))
+ len = sizeof(unsigned int);
+ val = po->pkt_type;
+
+ data = &val;
+ break;
#ifdef CONFIG_PACKET_MMAP
case PACKET_VERSION:
if (len > sizeof(int))

View File

@ -1,20 +0,0 @@
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -812,7 +812,7 @@ static int pppoe_sendmsg(struct kiocb *i
goto end;
- skb = sock_wmalloc(sk, total_len + dev->hard_header_len + 32,
+ skb = sock_wmalloc(sk, total_len + dev->hard_header_len + 32 + NET_SKB_PAD,
0, GFP_KERNEL);
if (!skb) {
error = -ENOMEM;
@@ -820,7 +820,7 @@ static int pppoe_sendmsg(struct kiocb *i
}
/* Reserve space for headers. */
- skb_reserve(skb, dev->hard_header_len);
+ skb_reserve(skb, dev->hard_header_len + NET_SKB_PAD);
skb_reset_network_header(skb);
skb->dev = dev;

View File

@ -1,18 +0,0 @@
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -223,4 +223,8 @@ config LEDS_TRIGGER_DEFAULT_ON
This allows LEDs to be initialised in the ON state.
If unsure, say Y.
+config LEDS_TRIGGER_MORSE
+ tristate "LED Morse Trigger"
+ depends on LEDS_TRIGGERS
+
endif # NEW_LEDS
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -31,3 +31,4 @@ obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += l
obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
+obj-$(CONFIG_LEDS_TRIGGER_MORSE) += ledtrig-morse.o

View File

@ -1,21 +0,0 @@
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -227,4 +227,11 @@ config LEDS_TRIGGER_MORSE
tristate "LED Morse Trigger"
depends on LEDS_TRIGGERS
+config LEDS_TRIGGER_NETDEV
+ tristate "LED Netdev Trigger"
+ depends on LEDS_TRIGGERS
+ help
+ This allows LEDs to be controlled by network device activity.
+ If unsure, say Y.
+
endif # NEW_LEDS
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -32,3 +32,4 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) +=
obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
obj-$(CONFIG_LEDS_TRIGGER_MORSE) += ledtrig-morse.o
+obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o

View File

@ -1,30 +0,0 @@
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -227,4 +227,20 @@ config INPUT_PCF50633_PMU
Say Y to include support for delivering PMU events via input
layer on NXP PCF50633.
+config INPUT_GPIO_BUTTONS
+ tristate "Polled GPIO buttons interface"
+ depends on GENERIC_GPIO
+ select INPUT_POLLDEV
+ help
+ This driver implements support for buttons connected
+ to GPIO pins of various CPUs (and some other chips).
+
+ Say Y here if your device has buttons connected
+ directly to such GPIO pins. Your board-specific
+ setup logic must also provide a platform device,
+ with configuration data saying which GPIOs are used.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gpio-buttons.
+
endif
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_APANEL) += apanel.o
obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o
+obj-$(CONFIG_INPUT_GPIO_BUTTONS) += gpio_buttons.o

View File

@ -1,26 +0,0 @@
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -1016,6 +1016,13 @@ config CS5535_GPIO
If compiled as a module, it will be called cs5535_gpio.
+config GPIO_DEVICE
+ tristate "GPIO device support"
+ depends on GENERIC_GPIO
+ help
+ Say Y to enable Linux GPIO device support. This allows control of
+ GPIO pins using a character device
+
config GPIO_VR41XX
tristate "NEC VR4100 series General-purpose I/O Unit support"
depends on CPU_VR41XX
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -94,6 +94,7 @@ obj-$(CONFIG_SCx200_GPIO) += scx200_gpio
obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o
obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o
obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o
+obj-$(CONFIG_GPIO_DEVICE) += gpio_dev.o
obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o
obj-$(CONFIG_GPIO_TB0219) += tb0219.o
obj-$(CONFIG_TELCLOCK) += tlclk.o

View File

@ -1,134 +0,0 @@
Subject: [PATCH 2/3] I2C: at24: add kernel interface for reading/writing EEPROM
Date: Monday 25 August 2008
From: Kevin Hilman <khilman@deeprootsystems.com>
To: davinci-linux-open-source@linux.davincidsp.com
This patch adds an interface by which other kernel code can read/write
detected EEPROM.
The platform code registers a 'setup' callback with the
at24_platform_data. When the at24 driver detects an EEPROM, it fills
out the read and write functions of at24_iface and calls the setup
callback. The platform code can then use the read/write functions in
the at24_iface struct for reading and writing the EEPROM.
Original idea, review and updates by David Brownell <david-b@pacbell.net>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
drivers/i2c/chips/at24.c | 42 +++++++++++++++++++++++++++++++++++-------
include/linux/i2c/at24.h | 10 ++++++++++
2 files changed, 45 insertions(+), 7 deletions(-)
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -53,6 +53,7 @@
struct at24_data {
struct at24_platform_data chip;
+ struct at24_iface iface;
bool use_smbus;
/*
@@ -264,13 +265,6 @@ static ssize_t at24_bin_read(struct kobj
/*
- * REVISIT: export at24_bin{read,write}() to let other kernel code use
- * eeprom data. For example, it might hold a board's Ethernet address, or
- * board-specific calibration data generated on the manufacturing floor.
- */
-
-
-/*
* Note that if the hardware write-protect pin is pulled high, the whole
* chip is normally write protected. But there are plenty of product
* variants here, including OTP fuses and partial chip protect.
@@ -386,6 +380,30 @@ static ssize_t at24_bin_write(struct kob
/*-------------------------------------------------------------------------*/
+/*
+ * This lets other kernel code access the eeprom data. For example, it
+ * might hold a board's Ethernet address, or board-specific calibration
+ * data generated on the manufacturing floor.
+ */
+
+static ssize_t at24_iface_read(struct at24_iface *iface, char *buf,
+ off_t offset, size_t count)
+{
+ struct at24_data *at24 = container_of(iface, struct at24_data, iface);
+
+ return at24_eeprom_read(at24, buf, offset, count);
+}
+
+static ssize_t at24_iface_write(struct at24_iface *iface, char *buf,
+ off_t offset, size_t count)
+{
+ struct at24_data *at24 = container_of(iface, struct at24_data, iface);
+
+ return at24_eeprom_write(at24, buf, offset, count);
+}
+
+/*-------------------------------------------------------------------------*/
+
static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct at24_platform_data chip;
@@ -413,6 +431,9 @@ static int at24_probe(struct i2c_client
* is recommended anyhow.
*/
chip.page_size = 1;
+
+ chip.setup = NULL;
+ chip.context = NULL;
}
if (!is_power_of_2(chip.byte_len))
@@ -449,6 +470,9 @@ static int at24_probe(struct i2c_client
goto err_out;
}
+ at24->iface.read = at24_iface_read;
+ at24->iface.write = at24_iface_write;
+
mutex_init(&at24->lock);
at24->use_smbus = use_smbus;
at24->chip = chip;
@@ -520,6 +544,10 @@ static int at24_probe(struct i2c_client
at24->write_max,
use_smbus ? ", use_smbus" : "");
+ /* export data to kernel code */
+ if (chip.setup)
+ chip.setup(&at24->iface, chip.context);
+
return 0;
err_clients:
--- a/include/linux/i2c/at24.h
+++ b/include/linux/i2c/at24.h
@@ -15,6 +15,13 @@
* is bigger than what the chip actually supports!
*/
+struct at24_iface {
+ ssize_t (*read)(struct at24_iface *, char *buf, off_t offset,
+ size_t count);
+ ssize_t (*write)(struct at24_iface *, char *buf, off_t offset,
+ size_t count);
+};
+
struct at24_platform_data {
u32 byte_len; /* size (sum of all addr) */
u16 page_size; /* for writes */
@@ -23,6 +30,9 @@ struct at24_platform_data {
#define AT24_FLAG_READONLY 0x40 /* sysfs-entry will be read-only */
#define AT24_FLAG_IRUGO 0x20 /* sysfs-entry will be world-readable */
#define AT24_FLAG_TAKE8ADDR 0x10 /* take always 8 addresses (24c00) */
+
+ int (*setup)(struct at24_iface *, void *context);
+ void *context;
};
#endif /* _LINUX_AT24_H */

View File

@ -1,17 +0,0 @@
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -223,6 +223,7 @@ source "fs/qnx4/Kconfig"
source "fs/romfs/Kconfig"
source "fs/sysv/Kconfig"
source "fs/ufs/Kconfig"
+source "fs/yaffs2/Kconfig"
endif # MISC_FILESYSTEMS
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -125,3 +125,4 @@ obj-$(CONFIG_DEBUG_FS) += debugfs/
obj-$(CONFIG_OCFS2_FS) += ocfs2/
obj-$(CONFIG_BTRFS_FS) += btrfs/
obj-$(CONFIG_GFS2_FS) += gfs2/
+obj-$(CONFIG_YAFFS_FS) += yaffs2/

View File

@ -1,83 +0,0 @@
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -299,6 +299,50 @@ int phy_ethtool_gset(struct phy_device *
}
EXPORT_SYMBOL(phy_ethtool_gset);
+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr)
+{
+ u32 cmd;
+ int tmp;
+ struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+ struct ethtool_value edata = { ETHTOOL_GLINK };
+
+ if (get_user(cmd, (u32 *) useraddr))
+ return -EFAULT;
+
+ switch (cmd) {
+ case ETHTOOL_GSET:
+ phy_ethtool_gset(phydev, &ecmd);
+ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
+ return -EFAULT;
+ return 0;
+
+ case ETHTOOL_SSET:
+ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
+ return -EFAULT;
+ return phy_ethtool_sset(phydev, &ecmd);
+
+ case ETHTOOL_NWAY_RST:
+ /* if autoneg is off, it's an error */
+ tmp = phy_read(phydev, MII_BMCR);
+ if (tmp & BMCR_ANENABLE) {
+ tmp |= (BMCR_ANRESTART);
+ phy_write(phydev, MII_BMCR, tmp);
+ return 0;
+ }
+ return -EINVAL;
+
+ case ETHTOOL_GLINK:
+ edata.data = (phy_read(phydev,
+ MII_BMSR) & BMSR_LSTATUS) ? 1 : 0;
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+ }
+
+ return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(phy_ethtool_ioctl);
+
/**
* phy_mii_ioctl - generic PHY MII ioctl interface
* @phydev: the phy_device struct
@@ -355,8 +399,8 @@ int phy_mii_ioctl(struct phy_device *phy
}
phy_write(phydev, mii_data->reg_num, val);
-
- if (mii_data->reg_num == MII_BMCR
+
+ if (mii_data->reg_num == MII_BMCR
&& val & BMCR_RESET
&& phydev->drv->config_init) {
phy_scan_fixups(phydev);
@@ -476,7 +520,7 @@ static void phy_force_reduction(struct p
int idx;
idx = phy_find_setting(phydev->speed, phydev->duplex);
-
+
idx++;
idx = phy_find_valid(idx, phydev->supported);
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -478,6 +478,7 @@ void phy_start_machine(struct phy_device
void phy_stop_machine(struct phy_device *phydev);
int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr);
int phy_mii_ioctl(struct phy_device *phydev,
struct mii_ioctl_data *mii_data, int cmd);
int phy_start_interrupts(struct phy_device *phydev);

View File

@ -1,24 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -82,6 +82,11 @@ config LSI_ET1011C_PHY
---help---
Supports the LSI ET1011C PHY.
+config ADM6996_PHY
+ tristate "Driver for ADM6996 switches"
+ ---help---
+ Currently supports the ADM6996F switch
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_SMSC_PHY) += smsc.o
obj-$(CONFIG_VITESSE_PHY) += vitesse.o
obj-$(CONFIG_BROADCOM_PHY) += broadcom.o
obj-$(CONFIG_ICPLUS_PHY) += icplus.o
+obj-$(CONFIG_ADM6996_PHY) += adm6996.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o

View File

@ -1,63 +0,0 @@
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -143,6 +143,18 @@ int phy_scan_fixups(struct phy_device *p
}
EXPORT_SYMBOL(phy_scan_fixups);
+static int generic_receive_skb(struct sk_buff *skb)
+{
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ return netif_receive_skb(skb);
+}
+
+static int generic_rx(struct sk_buff *skb)
+{
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ return netif_rx(skb);
+}
+
struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
{
struct phy_device *dev;
@@ -168,6 +180,8 @@ struct phy_device* phy_device_create(str
dev->bus = bus;
dev->state = PHY_DOWN;
+ dev->netif_receive_skb = &generic_receive_skb;
+ dev->netif_rx = &generic_rx;
mutex_init(&dev->lock);
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -326,6 +326,20 @@ struct phy_device {
void (*adjust_link)(struct net_device *dev);
void (*adjust_state)(struct net_device *dev);
+
+ /*
+ * By default these point to the original functions
+ * with the same name. adding them to the phy_device
+ * allows the phy driver to override them for packet
+ * mangling if the ethernet driver supports it
+ * This is required to support some really horrible
+ * switches such as the Marvell 88E6060
+ */
+ int (*netif_receive_skb)(struct sk_buff *skb);
+ int (*netif_rx)(struct sk_buff *skb);
+
+ /* alignment offset for packets */
+ int pkt_align;
};
#define to_phy_device(d) container_of(d, struct phy_device, dev)
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -747,6 +747,7 @@ struct net_device
void *ax25_ptr; /* AX.25 specific data */
struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data,
assign before registering */
+ void *phy_ptr; /* PHY device specific data */
/*
* Cache line mostly used on receive path (including eth_type_trans())

View File

@ -1,25 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -13,6 +13,12 @@ menuconfig PHYLIB
if PHYLIB
+config SWCONFIG
+ tristate "Switch configuration API"
+ ---help---
+ Switch configuration API using netlink. This allows
+ you to configure the VLAN features of certain switches.
+
comment "MII PHY device drivers"
config MARVELL_PHY
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -3,6 +3,7 @@
libphy-objs := phy.o phy_device.o mdio_bus.o
obj-$(CONFIG_PHYLIB) += libphy.o
+obj-$(CONFIG_SWCONFIG) += swconfig.o
obj-$(CONFIG_MARVELL_PHY) += marvell.o
obj-$(CONFIG_DAVICOM_PHY) += davicom.o
obj-$(CONFIG_CICADA_PHY) += cicada.o

View File

@ -1,22 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -93,6 +93,9 @@ config ADM6996_PHY
---help---
Currently supports the ADM6996F switch
+config MVSWITCH_PHY
+ tristate "Driver for Marvell 88E6060 switches"
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_VITESSE_PHY) += vitesse.o
obj-$(CONFIG_BROADCOM_PHY) += broadcom.o
obj-$(CONFIG_ICPLUS_PHY) += icplus.o
obj-$(CONFIG_ADM6996_PHY) += adm6996.o
+obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o

View File

@ -1,23 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -96,6 +96,10 @@ config ADM6996_PHY
config MVSWITCH_PHY
tristate "Driver for Marvell 88E6060 switches"
+config IP175C_PHY
+ tristate "Driver for IC+ IP175C/IP178C switches"
+ select SWCONFIG
+
config FIXED_PHY
bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB=y
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_BROADCOM_PHY) += broadcom.o
obj-$(CONFIG_ICPLUS_PHY) += icplus.o
obj-$(CONFIG_ADM6996_PHY) += adm6996.o
obj-$(CONFIG_MVSWITCH_PHY) += mvswitch.o
+obj-$(CONFIG_IP175C_PHY) += ip175c.o
obj-$(CONFIG_REALTEK_PHY) += realtek.o
obj-$(CONFIG_LSI_ET1011C_PHY) += et1011c.o
obj-$(CONFIG_FIXED_PHY) += fixed.o

Some files were not shown because too many files have changed in this diff Show More